mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into isInMultiLineComment
This commit is contained in:
+2
-1
@@ -57,4 +57,5 @@ internal/
|
||||
!tests/cases/projects/NodeModulesSearch/**/*
|
||||
!tests/baselines/reference/project/nodeModules*/**/*
|
||||
.idea
|
||||
yarn.lock
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
@@ -248,4 +248,23 @@ rdosanjh <me@rajdeep.io> # Raj Dosanjh
|
||||
gdh1995 <gdh1995@qq.com> # Dahan Gong
|
||||
cedvdb <cedvandenbosch@gmail.com> # @cedvdb
|
||||
kpreisser <kpreisser@users.noreply.github.com> # K. Preißer
|
||||
e-cloud <saintscott119@gmail.com> # @e-cloud
|
||||
e-cloud <saintscott119@gmail.com> # @e-cloud
|
||||
Andrew Casey <amcasey@users.noreply.github.com> Andrew Casey <andrew.casey@microsoft.com>
|
||||
Andrew Stegmaier <andrew.stegmaier@gmail.com>
|
||||
Benny Neugebauer <bn@bennyn.de>
|
||||
Blaine Bublitz <blaine.bublitz@gmail.com>
|
||||
Charles Pierce <cpierce.grad@gmail.com>
|
||||
Daniel Król <daniel@krol.me>
|
||||
Diogo Franco (Kovensky) <diogomfranco@gmail.com>
|
||||
Donald Pipowitch <pipo@senaeh.de>
|
||||
Halasi Tamás <trusted.tomato@gmail.com>
|
||||
Ika <ikatyang@gmail.com>
|
||||
Joe Chung <joechung@microsoft.com>
|
||||
Kate Miháliková <kate@katemihalikova.cz>
|
||||
Mohsen Azimi <mazimi@lyft.com>
|
||||
Noel Varanda <ncwvaranda@gmail.com>
|
||||
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>
|
||||
@@ -16,9 +16,6 @@ matrix:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.1
|
||||
- release-2.2
|
||||
- release-2.3
|
||||
|
||||
install:
|
||||
- npm uninstall typescript --no-save
|
||||
|
||||
+19
@@ -15,7 +15,9 @@ TypeScript is authored by:
|
||||
* Anders Hejlsberg
|
||||
* Andreas Martin
|
||||
* Andrej Baran
|
||||
* Andrew Casey
|
||||
* Andrew Ochsner
|
||||
* Andrew Stegmaier
|
||||
* Andrew Z Allen
|
||||
* András Parditka
|
||||
* Andy Hanson
|
||||
@@ -31,7 +33,9 @@ TypeScript is authored by:
|
||||
* Ben Duffield
|
||||
* Ben Mosher
|
||||
* Benjamin Bock
|
||||
* Benny Neugebauer
|
||||
* Bill Ticehurst
|
||||
* Blaine Bublitz
|
||||
* Blake Embrey
|
||||
* @bootstraponline
|
||||
* Bowden Kelly
|
||||
@@ -39,6 +43,7 @@ TypeScript is authored by:
|
||||
* Bryan Forbes
|
||||
* Caitlin Potter
|
||||
* @cedvdb
|
||||
* Charles Pierce
|
||||
* Charly POLY
|
||||
* Chris Bubernak
|
||||
* Christophe Vidal
|
||||
@@ -52,6 +57,7 @@ TypeScript is authored by:
|
||||
* Dan Corder
|
||||
* Dan Quirk
|
||||
* Daniel Hollocher
|
||||
* Daniel Król
|
||||
* Daniel Lehenbauer
|
||||
* Daniel Rosenwasser
|
||||
* David Kmenta
|
||||
@@ -60,9 +66,11 @@ TypeScript is authored by:
|
||||
* David Souther
|
||||
* Denis Nedelyaev
|
||||
* Dick van den Brink
|
||||
* Diogo Franco (Kovensky)
|
||||
* Dirk Bäumer
|
||||
* Dirk Holtwick
|
||||
* Dom Chen
|
||||
* Donald Pipowitch
|
||||
* Doug Ilijev
|
||||
* @e-cloud
|
||||
* Elisée Maurer
|
||||
@@ -89,12 +97,14 @@ TypeScript is authored by:
|
||||
* Guilherme Oenning
|
||||
* Guillaume Salles
|
||||
* Guy Bedford
|
||||
* Halasi Tamás
|
||||
* Harald Niesche
|
||||
* Hendrik Liebau
|
||||
* Herrington Darkholme
|
||||
* Homa Wong
|
||||
* Iain Monro
|
||||
* Igor Novozhilov
|
||||
* Ika
|
||||
* Ingvar Stepanyan
|
||||
* Isiah Meadows
|
||||
* Ivo Gabe de Wolff
|
||||
@@ -111,6 +121,7 @@ TypeScript is authored by:
|
||||
* Jeffrey Morlan
|
||||
* Jesse Schalken
|
||||
* Jiri Tobisek
|
||||
* Joe Chung
|
||||
* Joel Day
|
||||
* Joey Wilson
|
||||
* Johannes Rieken
|
||||
@@ -131,6 +142,7 @@ TypeScript is authored by:
|
||||
* K. Preißer
|
||||
* Kagami Sascha Rosylight
|
||||
* Kanchalai Tanglertsampan
|
||||
* Kate Miháliková
|
||||
* Keith Mashinter
|
||||
* Ken Howard
|
||||
* Kenji Imamula
|
||||
@@ -159,6 +171,7 @@ TypeScript is authored by:
|
||||
* Mike Busyrev
|
||||
* Mine Starks
|
||||
* Mohamed Hegazy
|
||||
* Mohsen Azimi
|
||||
* Myles Megyesi
|
||||
* Natalie Coley
|
||||
* Nathan Shively-Sanders
|
||||
@@ -166,6 +179,7 @@ TypeScript is authored by:
|
||||
* Nicolas Henry
|
||||
* Nima Zahedi
|
||||
* Noah Chen
|
||||
* Noel Varanda
|
||||
* Noj Vek
|
||||
* Oleg Mihailik
|
||||
* Oleksandr Chekhovskyi
|
||||
@@ -186,6 +200,7 @@ TypeScript is authored by:
|
||||
* Punya Biswal
|
||||
* Rado Kirov
|
||||
* Raj Dosanjh
|
||||
* Reiner Dolp
|
||||
* Richard Karmazín
|
||||
* Richard Knoll
|
||||
* Richard Sentino
|
||||
@@ -213,6 +228,7 @@ TypeScript is authored by:
|
||||
* Sudheesh Singanamalla
|
||||
* Sébastien Arod
|
||||
* @T18970237136
|
||||
* @t_
|
||||
* Tarik Ozket
|
||||
* Tetsuharu Ohzeki
|
||||
* Thomas Loubiou
|
||||
@@ -225,13 +241,16 @@ TypeScript is authored by:
|
||||
* togru
|
||||
* Tomas Grubliauskas
|
||||
* Torben Fitschen
|
||||
* @TravCav
|
||||
* TruongSinh Tran-Nguyen
|
||||
* Vadi Taslim
|
||||
* Vidar Tonaas Fauske
|
||||
* Viktor Zozulyak
|
||||
* Vilic Vane
|
||||
* Vladimir Kurchatkin
|
||||
* Vladimir Matveev
|
||||
* Wesley Wigham
|
||||
* William Orr
|
||||
* York Yao
|
||||
* @yortus
|
||||
* Yuichi Nukiyama
|
||||
|
||||
+82
-61
@@ -28,7 +28,6 @@ import minimist = require("minimist");
|
||||
import browserify = require("browserify");
|
||||
import through2 = require("through2");
|
||||
import merge2 = require("merge2");
|
||||
import intoStream = require("into-stream");
|
||||
import * as os from "os";
|
||||
import fold = require("travis-fold");
|
||||
const gulp = helpMaker(originalGulp);
|
||||
@@ -39,25 +38,25 @@ Error.stackTraceLimit = 1000;
|
||||
|
||||
const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
boolean: ["debug", "inspect", "light", "colors", "lint", "soft"],
|
||||
string: ["browser", "tests", "host", "reporter", "stackTraceLimit"],
|
||||
string: ["browser", "tests", "host", "reporter", "stackTraceLimit", "timeout"],
|
||||
alias: {
|
||||
b: "browser",
|
||||
d: "debug",
|
||||
t: "tests",
|
||||
test: "tests",
|
||||
d: "debug", "debug-brk": "debug",
|
||||
i: "inspect", "inspect-brk": "inspect",
|
||||
t: "tests", test: "tests",
|
||||
r: "reporter",
|
||||
color: "colors",
|
||||
f: "files",
|
||||
file: "files",
|
||||
c: "colors", color: "colors",
|
||||
f: "files", file: "files",
|
||||
w: "workers",
|
||||
},
|
||||
default: {
|
||||
soft: false,
|
||||
colors: process.env.colors || process.env.color || true,
|
||||
debug: process.env.debug || process.env.d,
|
||||
inspect: process.env.inspect,
|
||||
debug: process.env.debug || process.env["debug-brk"] || process.env.d,
|
||||
inspect: process.env.inspect || process.env["inspect-brk"] || process.env.i,
|
||||
host: process.env.TYPESCRIPT_HOST || process.env.host || "node",
|
||||
browser: process.env.browser || process.env.b || "IE",
|
||||
timeout: process.env.timeout || 40000,
|
||||
tests: process.env.test || process.env.tests || process.env.t,
|
||||
light: process.env.light || false,
|
||||
reporter: process.env.reporter || process.env.r,
|
||||
@@ -256,14 +255,8 @@ function needsUpdate(source: string | string[], dest: string | string[]): boolea
|
||||
return true;
|
||||
}
|
||||
|
||||
// Doing tsconfig inheritance manually. https://github.com/ivogabe/gulp-typescript/issues/459
|
||||
const tsconfigBase = JSON.parse(fs.readFileSync("src/tsconfig-base.json", "utf-8")).compilerOptions;
|
||||
|
||||
function getCompilerSettings(base: tsc.Settings, useBuiltCompiler?: boolean): tsc.Settings {
|
||||
const copy: tsc.Settings = {};
|
||||
for (const key in tsconfigBase) {
|
||||
copy[key] = tsconfigBase[key];
|
||||
}
|
||||
for (const key in base) {
|
||||
copy[key] = base[key];
|
||||
}
|
||||
@@ -300,7 +293,7 @@ gulp.task("configure-nightly", "Runs scripts/configureNightly.ts to prepare a bu
|
||||
exec(host, [configureNightlyJs, packageJson, versionFile], done, done);
|
||||
});
|
||||
gulp.task("publish-nightly", "Runs `npm publish --tag next` to create a new nightly build on npm", ["LKG"], () => {
|
||||
return runSequence("clean", "useDebugMode", "runtests", (done) => {
|
||||
return runSequence("clean", "useDebugMode", "runtests-parallel", (done) => {
|
||||
exec("npm", ["publish", "--tag", "next"], done, done);
|
||||
});
|
||||
});
|
||||
@@ -561,7 +554,7 @@ gulp.task(run, /*help*/ false, [servicesFile], () => {
|
||||
.pipe(newer(run))
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(testProject())
|
||||
.pipe(sourcemaps.write(".", { includeContent: false, sourceRoot: "../../" }))
|
||||
.pipe(sourcemaps.write(".", { includeContent: false, sourceRoot: "." }))
|
||||
.pipe(gulp.dest("src/harness"));
|
||||
});
|
||||
|
||||
@@ -594,11 +587,11 @@ function restoreSavedNodeEnv() {
|
||||
process.env.NODE_ENV = savedNodeEnv;
|
||||
}
|
||||
|
||||
let testTimeout = 40000;
|
||||
function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: (e?: any) => void) {
|
||||
const lintFlag = cmdLineOptions["lint"];
|
||||
cleanTestDirs((err) => {
|
||||
if (err) { console.error(err); failWithStatus(err, 1); }
|
||||
let testTimeout = cmdLineOptions["timeout"];
|
||||
const debug = cmdLineOptions["debug"];
|
||||
const inspect = cmdLineOptions["inspect"];
|
||||
const tests = cmdLineOptions["tests"];
|
||||
@@ -637,12 +630,6 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
const args = [];
|
||||
if (inspect) {
|
||||
args.push("--inspect");
|
||||
}
|
||||
if (inspect || debug) {
|
||||
args.push("--debug-brk");
|
||||
}
|
||||
args.push("-R", reporter);
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
@@ -653,7 +640,15 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
else {
|
||||
args.push("--no-colors");
|
||||
}
|
||||
args.push("-t", testTimeout);
|
||||
if (inspect) {
|
||||
args.unshift("--inspect-brk");
|
||||
}
|
||||
else if (debug) {
|
||||
args.unshift("--debug-brk");
|
||||
}
|
||||
else {
|
||||
args.push("-t", testTimeout);
|
||||
}
|
||||
args.push(run);
|
||||
setNodeEnvToDevelopment();
|
||||
exec(mocha, args, lintThenFinish, function(e, status) {
|
||||
@@ -673,7 +668,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
}
|
||||
args.push(run);
|
||||
setNodeEnvToDevelopment();
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: colors === " --no-colors " }, function(err) {
|
||||
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) {
|
||||
@@ -741,50 +736,75 @@ gulp.task(nodeServerOutFile, /*help*/ false, [servicesFile], () => {
|
||||
|
||||
import convertMap = require("convert-source-map");
|
||||
import sorcery = require("sorcery");
|
||||
declare module "convert-source-map" {
|
||||
export function fromSource(source: string, largeSource?: boolean): SourceMapConverter;
|
||||
}
|
||||
import Vinyl = require("vinyl");
|
||||
|
||||
const bundlePath = path.resolve("built/local/bundle.js");
|
||||
|
||||
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => {
|
||||
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: "../../built/local/bundle.js" }, /*useBuiltCompiler*/ true));
|
||||
return testProject.src()
|
||||
.pipe(newer("built/local/bundle.js"))
|
||||
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: bundlePath, inlineSourceMap: true }, /*useBuiltCompiler*/ true));
|
||||
let originalMap: any;
|
||||
let prebundledContent: string;
|
||||
browserify(testProject.src()
|
||||
.pipe(newer(bundlePath))
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(testProject())
|
||||
.pipe(through2.obj((file, enc, next) => {
|
||||
const originalMap = file.sourceMap;
|
||||
const prebundledContent = file.contents.toString();
|
||||
if (originalMap) {
|
||||
throw new Error("Should only recieve one file!");
|
||||
}
|
||||
console.log(`Saving sourcemaps for ${file.path}`);
|
||||
originalMap = file.sourceMap;
|
||||
prebundledContent = file.contents.toString();
|
||||
// Make paths absolute to help sorcery deal with all the terrible paths being thrown around
|
||||
originalMap.sources = originalMap.sources.map(s => path.resolve(path.join("src/harness", s)));
|
||||
// intoStream (below) makes browserify think the input file is named this, so this is what it puts in the sourcemap
|
||||
// browserify names input files this when they are streamed in, so this is what it puts in the sourcemap
|
||||
originalMap.file = "built/local/_stream_0.js";
|
||||
|
||||
browserify(intoStream(file.contents), { debug: true })
|
||||
.bundle((err, res) => {
|
||||
// assumes file.contents is a Buffer
|
||||
const maps = JSON.parse(convertMap.fromSource(res.toString(), /*largeSource*/ true).toJSON());
|
||||
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)
|
||||
file.contents = new Buffer(convertMap.removeComments(res.toString()));
|
||||
const chain = sorcery.loadSync("built/local/bundle.js", {
|
||||
content: {
|
||||
"built/local/_stream_0.js": prebundledContent,
|
||||
"built/local/bundle.js": file.contents.toString()
|
||||
},
|
||||
sourcemaps: {
|
||||
"built/local/_stream_0.js": originalMap,
|
||||
"built/local/bundle.js": maps,
|
||||
"node_modules/source-map-support/source-map-support.js": undefined,
|
||||
}
|
||||
});
|
||||
const finalMap = chain.apply();
|
||||
file.sourceMap = finalMap;
|
||||
next(/*err*/ undefined, file);
|
||||
});
|
||||
next(/*err*/ undefined, file.contents);
|
||||
}))
|
||||
.pipe(sourcemaps.write(".", { includeContent: false }))
|
||||
.pipe(gulp.dest("src/harness"));
|
||||
.on("error", err => {
|
||||
return done(err);
|
||||
}), { debug: true, basedir: __dirname }) // Attach error handler to inner stream
|
||||
.bundle((err, contents) => {
|
||||
if (err) {
|
||||
if (err.message.match(/Cannot find module '.*_stream_0.js'/)) {
|
||||
return done(); // Browserify errors when we pass in no files when `newer` filters the input, we should count that as a success, though
|
||||
}
|
||||
return done(err);
|
||||
}
|
||||
const stringContent = contents.toString();
|
||||
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();
|
||||
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)
|
||||
file.contents = new Buffer(convertMap.removeComments(stringContent));
|
||||
const chain = sorcery.loadSync(bundlePath, {
|
||||
content: {
|
||||
"built/local/_stream_0.js": prebundledContent,
|
||||
[bundlePath]: stringContent
|
||||
},
|
||||
sourcemaps: {
|
||||
"built/local/_stream_0.js": originalMap,
|
||||
[bundlePath]: maps,
|
||||
"node_modules/source-map-support/source-map-support.js": undefined,
|
||||
}
|
||||
});
|
||||
const finalMap = chain.apply();
|
||||
file.sourceMap = finalMap;
|
||||
|
||||
const stream = through2.obj((file, enc, callback) => {
|
||||
return callback(/*err*/ undefined, file);
|
||||
});
|
||||
stream.pipe(sourcemaps.write(".", { includeContent: false }))
|
||||
.pipe(gulp.dest("."))
|
||||
.on("end", done)
|
||||
.on("error", done);
|
||||
stream.write(file);
|
||||
stream.end();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -838,6 +858,7 @@ gulp.task("runtests-browser", "Runs the tests using the built run.js file like '
|
||||
});
|
||||
|
||||
gulp.task("generate-code-coverage", "Generates code coverage data via istanbul", ["tests"], (done) => {
|
||||
const testTimeout = cmdLineOptions["timeout"];
|
||||
exec("istanbul", ["cover", "node_modules/mocha/bin/_mocha", "--", "-R", "min", "-t", testTimeout.toString(), run], done, done);
|
||||
});
|
||||
|
||||
|
||||
+29
-17
@@ -25,6 +25,8 @@ var LKGDirectory = "lib/";
|
||||
var copyright = "CopyrightNotice.txt";
|
||||
var thirdParty = "ThirdPartyNoticeText.txt";
|
||||
|
||||
var defaultTestTimeout = 40000;
|
||||
|
||||
// add node_modules to path so we don't need global modules, prefer the modules by adding them first
|
||||
var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter;
|
||||
if (process.env.path !== undefined) {
|
||||
@@ -74,6 +76,10 @@ function measure(marker) {
|
||||
console.log("travis_time:end:" + marker.id + ":start=" + toNs(marker.stamp) + ",finish=" + toNs(total) + ",duration=" + toNs(diff) + "\r");
|
||||
}
|
||||
|
||||
function removeConstModifierFromEnumDeclarations(text) {
|
||||
return text.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
|
||||
}
|
||||
|
||||
var compilerSources = filesFromConfig("./src/compiler/tsconfig.json");
|
||||
var servicesSources = filesFromConfig("./src/services/tsconfig.json");
|
||||
var cancellationTokenSources = filesFromConfig(path.join(serverDirectory, "cancellationToken/tsconfig.json"));
|
||||
@@ -132,6 +138,7 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"telemetry.ts",
|
||||
"transform.ts",
|
||||
"customTransforms.ts",
|
||||
"programMissingFiles.ts",
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
@@ -280,7 +287,7 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
|
||||
var startCompileTime = mark();
|
||||
opts = opts || {};
|
||||
var compilerPath = useBuiltCompiler ? builtLocalCompiler : LKGCompiler;
|
||||
var options = "--noImplicitAny --noImplicitThis --noEmitOnError --types "
|
||||
var options = "--noImplicitAny --noImplicitThis --alwaysStrict --noEmitOnError --types "
|
||||
if (opts.types) {
|
||||
options += opts.types.join(",");
|
||||
}
|
||||
@@ -498,7 +505,7 @@ task("configure-nightly", [configureNightlyJs], function () {
|
||||
}, { async: true });
|
||||
|
||||
desc("Configure, build, test, and publish the nightly release.");
|
||||
task("publish-nightly", ["configure-nightly", "LKG", "clean", "setDebugMode", "runtests"], function () {
|
||||
task("publish-nightly", ["configure-nightly", "LKG", "clean", "setDebugMode", "runtests-parallel"], function () {
|
||||
var cmd = "npm publish --tag next";
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
@@ -551,7 +558,7 @@ compileFile(servicesFile, servicesSources, [builtLocalDirectory, copyright].conc
|
||||
// Stanalone/web definition file using global 'ts' namespace
|
||||
jake.cpR(standaloneDefinitionsFile, nodeDefinitionsFile, { silent: true });
|
||||
var definitionFileContents = fs.readFileSync(nodeDefinitionsFile).toString();
|
||||
definitionFileContents = definitionFileContents.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
|
||||
definitionFileContents = removeConstModifierFromEnumDeclarations(definitionFileContents)
|
||||
fs.writeFileSync(standaloneDefinitionsFile, definitionFileContents);
|
||||
|
||||
// Official node package definition file, pointed to by 'typings' in package.json
|
||||
@@ -611,6 +618,7 @@ compileFile(
|
||||
fs.readFileSync(tsserverLibraryDefinitionFile).toString() +
|
||||
"\r\nexport = ts;" +
|
||||
"\r\nexport as namespace ts;";
|
||||
tsserverLibraryDefinitionFileContents = removeConstModifierFromEnumDeclarations(tsserverLibraryDefinitionFileContents);
|
||||
|
||||
fs.writeFileSync(tsserverLibraryDefinitionFile, tsserverLibraryDefinitionFileContents);
|
||||
});
|
||||
@@ -800,9 +808,10 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
cleanTestDirs();
|
||||
}
|
||||
|
||||
var debug = process.env.debug || process.env.d;
|
||||
var inspect = process.env.inspect;
|
||||
tests = process.env.test || process.env.tests || process.env.t;
|
||||
var debug = process.env.debug || process.env["debug-brk"] || process.env.d;
|
||||
var inspect = process.env.inspect || process.env["inspect-brk"] || process.env.i;
|
||||
var testTimeout = process.env.timeout || defaultTestTimeout;
|
||||
var tests = process.env.test || process.env.tests || process.env.t;
|
||||
var light = process.env.light || false;
|
||||
var stackTraceLimit = process.env.stackTraceLimit;
|
||||
var testConfigFile = 'test.config';
|
||||
@@ -820,7 +829,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
} while (fs.existsSync(taskConfigsFolder));
|
||||
fs.mkdirSync(taskConfigsFolder);
|
||||
|
||||
workerCount = process.env.workerCount || os.cpus().length;
|
||||
workerCount = process.env.workerCount || process.env.p || os.cpus().length;
|
||||
}
|
||||
|
||||
if (tests || light || taskConfigsFolder) {
|
||||
@@ -831,7 +840,8 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
testTimeout = 800000;
|
||||
}
|
||||
|
||||
var colors = process.env.colors || process.env.color || true;
|
||||
var colorsFlag = process.env.color || process.env.colors;
|
||||
var colors = colorsFlag !== "false" && colorsFlag !== "0";
|
||||
var reporter = process.env.reporter || process.env.r || defaultReporter;
|
||||
var bail = process.env.bail || process.env.b;
|
||||
var lintFlag = process.env.lint !== 'false';
|
||||
@@ -841,12 +851,6 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
if (!runInParallel) {
|
||||
var startTime = mark();
|
||||
var args = [];
|
||||
if (inspect) {
|
||||
args.push("--inspect");
|
||||
}
|
||||
if (inspect || debug) {
|
||||
args.push("--debug-brk");
|
||||
}
|
||||
args.push("-R", reporter);
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
@@ -860,7 +864,15 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
if (bail) {
|
||||
args.push("--bail");
|
||||
}
|
||||
args.push("-t", testTimeout);
|
||||
if (inspect) {
|
||||
args.unshift("--inspect-brk");
|
||||
}
|
||||
else if (debug) {
|
||||
args.unshift("--debug-brk");
|
||||
}
|
||||
else {
|
||||
args.push("-t", testTimeout);
|
||||
}
|
||||
args.push(run);
|
||||
|
||||
var cmd = "mocha " + args.join(" ");
|
||||
@@ -925,7 +937,6 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
}
|
||||
}
|
||||
|
||||
var testTimeout = 20000;
|
||||
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
|
||||
task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], function () {
|
||||
runConsoleTests('min', /*runInParallel*/ true);
|
||||
@@ -938,6 +949,7 @@ task("runtests", ["build-rules", "tests", builtLocalDirectory], function() {
|
||||
|
||||
desc("Generates code coverage data via instanbul");
|
||||
task("generate-code-coverage", ["tests", builtLocalDirectory], function () {
|
||||
var testTimeout = process.env.timeout || defaultTestTimeout;
|
||||
var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run;
|
||||
console.log(cmd);
|
||||
exec(cmd);
|
||||
@@ -949,7 +961,7 @@ var nodeServerInFile = "tests/webTestServer.ts";
|
||||
compileFile(nodeServerOutFile, [nodeServerInFile], [builtLocalDirectory, tscFile], [], /*useBuiltCompiler:*/ true, { noOutFile: true, lib: "es6" });
|
||||
|
||||
desc("Runs browserify on run.js to produce a file suitable for running tests in the browser");
|
||||
task("browserify", ["tests", builtLocalDirectory, nodeServerOutFile], function() {
|
||||
task("browserify", ["tests", run, builtLocalDirectory, nodeServerOutFile], function() {
|
||||
var cmd = 'browserify built/local/run.js -t ./scripts/browserify-optional -d -o built/local/bundle.js';
|
||||
exec(cmd);
|
||||
}, { async: true });
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
[](https://gitter.im/Microsoft/TypeScript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
[TypeScript](http://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](http://www.typescriptlang.org/Playground), and stay up to date via [our blog](https://blogs.msdn.microsoft.com/typescript) and [Twitter account](https://twitter.com/typescriptlang).
|
||||
[TypeScript](https://www.typescriptlang.org/) is a language for application-scale JavaScript. TypeScript adds optional types, classes, and modules to JavaScript. TypeScript supports tools for large-scale JavaScript applications for any browser, for any host, on any OS. TypeScript compiles to readable, standards-based JavaScript. Try it out at the [playground](https://www.typescriptlang.org/play/), and stay up to date via [our blog](https://blogs.msdn.microsoft.com/typescript) and [Twitter account](https://twitter.com/typescriptlang).
|
||||
|
||||
## Installing
|
||||
|
||||
@@ -27,8 +27,8 @@ npm install -g typescript@next
|
||||
There are many ways to [contribute](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md) to TypeScript.
|
||||
* [Submit bugs](https://github.com/Microsoft/TypeScript/issues) and help us verify fixes as they are checked in.
|
||||
* Review the [source code changes](https://github.com/Microsoft/TypeScript/pulls).
|
||||
* Engage with other TypeScript users and developers on [StackOverflow](http://stackoverflow.com/questions/tagged/typescript).
|
||||
* Join the [#typescript](http://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.
|
||||
* Engage with other TypeScript users and developers on [StackOverflow](https://stackoverflow.com/questions/tagged/typescript).
|
||||
* Join the [#typescript](https://twitter.com/#!/search/realtime/%23typescript) discussion on Twitter.
|
||||
* [Contribute bug fixes](https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md).
|
||||
* Read the language specification ([docx](https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.docx?raw=true),
|
||||
[pdf](https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.pdf?raw=true), [md](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)).
|
||||
@@ -39,14 +39,14 @@ with any additional questions or comments.
|
||||
|
||||
## Documentation
|
||||
|
||||
* [Quick tutorial](http://www.typescriptlang.org/docs/tutorial.html)
|
||||
* [Programming handbook](http://www.typescriptlang.org/docs/handbook/basic-types.html)
|
||||
* [Quick tutorial](https://www.typescriptlang.org/docs/tutorial.html)
|
||||
* [Programming handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html)
|
||||
* [Language specification](https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md)
|
||||
* [Homepage](http://www.typescriptlang.org/)
|
||||
* [Homepage](https://www.typescriptlang.org/)
|
||||
|
||||
## Building
|
||||
|
||||
In order to build the TypeScript compiler, ensure that you have [Git](http://git-scm.com/downloads) and [Node.js](http://nodejs.org/) installed.
|
||||
In order to build the TypeScript compiler, ensure that you have [Git](https://git-scm.com/downloads) and [Node.js](https://nodejs.org/) installed.
|
||||
|
||||
Clone a copy of the repo:
|
||||
|
||||
|
||||
+2
-2
@@ -2,13 +2,13 @@
|
||||
<!-- QUESTIONS: This is not a general support forum! Ask Qs at http://stackoverflow.com/questions/tagged/typescript -->
|
||||
<!-- SUGGESTIONS: See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md -->
|
||||
|
||||
**TypeScript Version:** 2.2.1 / nightly (2.2.0-dev.201xxxxx)
|
||||
**TypeScript Version:** 2.4.0 / nightly (2.5.0-dev.201xxxxx)
|
||||
|
||||
**Code**
|
||||
|
||||
```ts
|
||||
// A *self-contained* demonstration of the problem follows...
|
||||
|
||||
// Test this by running `tsc` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.
|
||||
```
|
||||
|
||||
**Expected behavior:**
|
||||
|
||||
@@ -69,5 +69,3 @@ function createCancellationToken(args) {
|
||||
}
|
||||
}
|
||||
module.exports = createCancellationToken;
|
||||
|
||||
//# sourceMappingURL=cancellationToken.js.map
|
||||
|
||||
Vendored
+4346
-4803
File diff suppressed because it is too large
Load Diff
Vendored
+4200
-4452
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
@@ -21,8 +21,8 @@ and limitations under the License.
|
||||
/// <reference path="lib.es2015.core.d.ts" />
|
||||
/// <reference path="lib.es2015.collection.d.ts" />
|
||||
/// <reference path="lib.es2015.generator.d.ts" />
|
||||
/// <reference path="lib.es2015.iterable.d.ts" />
|
||||
/// <reference path="lib.es2015.promise.d.ts" />
|
||||
/// <reference path="lib.es2015.iterable.d.ts" />
|
||||
/// <reference path="lib.es2015.proxy.d.ts" />
|
||||
/// <reference path="lib.es2015.reflect.d.ts" />
|
||||
/// <reference path="lib.es2015.symbol.d.ts" />
|
||||
|
||||
Vendored
+4200
-6276
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
@@ -22,4 +22,4 @@ and limitations under the License.
|
||||
/// <reference path="lib.es2017.object.d.ts" />
|
||||
/// <reference path="lib.es2017.sharedmemory.d.ts" />
|
||||
/// <reference path="lib.es2017.string.d.ts" />
|
||||
/// <reference path="lib.es2017.intl.d.ts" />
|
||||
/// <reference path="lib.es2017.intl.d.ts" />
|
||||
|
||||
Vendored
+4200
-6275
File diff suppressed because it is too large
Load Diff
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
type DateTimeFormatPartTypes = "day" | "dayPeriod" | "era" | "hour" | "literal" | "minute" | "month" | "second" | "timeZoneName" | "weekday" | "year";
|
||||
|
||||
interface DateTimeFormatPart {
|
||||
type: DateTimeFormatPartTypes;
|
||||
value: string;
|
||||
}
|
||||
|
||||
interface DateTimeFormat {
|
||||
formatToParts(date?: Date | number): DateTimeFormatPart[];
|
||||
}
|
||||
Vendored
+146
-351
File diff suppressed because it is too large
Load Diff
Vendored
+4346
-4803
File diff suppressed because it is too large
Load Diff
Vendored
+4200
-6276
File diff suppressed because it is too large
Load Diff
Vendored
+145
-134
@@ -20,7 +20,7 @@ and limitations under the License.
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// IE Worker APIs
|
||||
/// Worker APIs
|
||||
/////////////////////////////
|
||||
|
||||
interface Algorithm {
|
||||
@@ -28,16 +28,16 @@ interface Algorithm {
|
||||
}
|
||||
|
||||
interface CacheQueryOptions {
|
||||
ignoreSearch?: boolean;
|
||||
ignoreMethod?: boolean;
|
||||
ignoreVary?: boolean;
|
||||
cacheName?: string;
|
||||
ignoreMethod?: boolean;
|
||||
ignoreSearch?: boolean;
|
||||
ignoreVary?: boolean;
|
||||
}
|
||||
|
||||
interface CloseEventInit extends EventInit {
|
||||
wasClean?: boolean;
|
||||
code?: number;
|
||||
reason?: string;
|
||||
wasClean?: boolean;
|
||||
}
|
||||
|
||||
interface EventInit {
|
||||
@@ -69,16 +69,16 @@ interface MessageEventInit extends EventInit {
|
||||
channel?: string;
|
||||
data?: any;
|
||||
origin?: string;
|
||||
source?: any;
|
||||
ports?: MessagePort[];
|
||||
source?: any;
|
||||
}
|
||||
|
||||
interface NotificationOptions {
|
||||
dir?: NotificationDirection;
|
||||
lang?: string;
|
||||
body?: string;
|
||||
tag?: string;
|
||||
dir?: NotificationDirection;
|
||||
icon?: string;
|
||||
lang?: string;
|
||||
tag?: string;
|
||||
}
|
||||
|
||||
interface ObjectURLOptions {
|
||||
@@ -86,29 +86,29 @@ interface ObjectURLOptions {
|
||||
}
|
||||
|
||||
interface PushSubscriptionOptionsInit {
|
||||
userVisibleOnly?: boolean;
|
||||
applicationServerKey?: any;
|
||||
userVisibleOnly?: boolean;
|
||||
}
|
||||
|
||||
interface RequestInit {
|
||||
method?: string;
|
||||
headers?: any;
|
||||
body?: any;
|
||||
referrer?: string;
|
||||
referrerPolicy?: ReferrerPolicy;
|
||||
mode?: RequestMode;
|
||||
credentials?: RequestCredentials;
|
||||
cache?: RequestCache;
|
||||
redirect?: RequestRedirect;
|
||||
credentials?: RequestCredentials;
|
||||
headers?: any;
|
||||
integrity?: string;
|
||||
keepalive?: boolean;
|
||||
method?: string;
|
||||
mode?: RequestMode;
|
||||
redirect?: RequestRedirect;
|
||||
referrer?: string;
|
||||
referrerPolicy?: ReferrerPolicy;
|
||||
window?: any;
|
||||
}
|
||||
|
||||
interface ResponseInit {
|
||||
headers?: any;
|
||||
status?: number;
|
||||
statusText?: string;
|
||||
headers?: any;
|
||||
}
|
||||
|
||||
interface ClientQueryOptions {
|
||||
@@ -176,7 +176,7 @@ interface AudioBuffer {
|
||||
declare var AudioBuffer: {
|
||||
prototype: AudioBuffer;
|
||||
new(): AudioBuffer;
|
||||
}
|
||||
};
|
||||
|
||||
interface Blob {
|
||||
readonly size: number;
|
||||
@@ -189,7 +189,7 @@ interface Blob {
|
||||
declare var Blob: {
|
||||
prototype: Blob;
|
||||
new (blobParts?: any[], options?: BlobPropertyBag): Blob;
|
||||
}
|
||||
};
|
||||
|
||||
interface Cache {
|
||||
add(request: RequestInfo): Promise<void>;
|
||||
@@ -204,7 +204,7 @@ interface Cache {
|
||||
declare var Cache: {
|
||||
prototype: Cache;
|
||||
new(): Cache;
|
||||
}
|
||||
};
|
||||
|
||||
interface CacheStorage {
|
||||
delete(cacheName: string): Promise<boolean>;
|
||||
@@ -217,7 +217,7 @@ interface CacheStorage {
|
||||
declare var CacheStorage: {
|
||||
prototype: CacheStorage;
|
||||
new(): CacheStorage;
|
||||
}
|
||||
};
|
||||
|
||||
interface CloseEvent extends Event {
|
||||
readonly code: number;
|
||||
@@ -229,7 +229,7 @@ interface CloseEvent extends Event {
|
||||
declare var CloseEvent: {
|
||||
prototype: CloseEvent;
|
||||
new(typeArg: string, eventInitDict?: CloseEventInit): CloseEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface Console {
|
||||
assert(test?: boolean, message?: string, ...optionalParams: any[]): void;
|
||||
@@ -240,8 +240,8 @@ interface Console {
|
||||
dirxml(value: any): void;
|
||||
error(message?: any, ...optionalParams: any[]): void;
|
||||
exception(message?: string, ...optionalParams: any[]): void;
|
||||
group(groupTitle?: string): void;
|
||||
groupCollapsed(groupTitle?: string): void;
|
||||
group(groupTitle?: string, ...optionalParams: any[]): void;
|
||||
groupCollapsed(groupTitle?: string, ...optionalParams: any[]): void;
|
||||
groupEnd(): void;
|
||||
info(message?: any, ...optionalParams: any[]): void;
|
||||
log(message?: any, ...optionalParams: any[]): void;
|
||||
@@ -259,7 +259,7 @@ interface Console {
|
||||
declare var Console: {
|
||||
prototype: Console;
|
||||
new(): Console;
|
||||
}
|
||||
};
|
||||
|
||||
interface Coordinates {
|
||||
readonly accuracy: number;
|
||||
@@ -274,7 +274,7 @@ interface Coordinates {
|
||||
declare var Coordinates: {
|
||||
prototype: Coordinates;
|
||||
new(): Coordinates;
|
||||
}
|
||||
};
|
||||
|
||||
interface CryptoKey {
|
||||
readonly algorithm: KeyAlgorithm;
|
||||
@@ -286,7 +286,7 @@ interface CryptoKey {
|
||||
declare var CryptoKey: {
|
||||
prototype: CryptoKey;
|
||||
new(): CryptoKey;
|
||||
}
|
||||
};
|
||||
|
||||
interface DOMError {
|
||||
readonly name: string;
|
||||
@@ -296,7 +296,7 @@ interface DOMError {
|
||||
declare var DOMError: {
|
||||
prototype: DOMError;
|
||||
new(): DOMError;
|
||||
}
|
||||
};
|
||||
|
||||
interface DOMException {
|
||||
readonly code: number;
|
||||
@@ -316,10 +316,10 @@ interface DOMException {
|
||||
readonly INVALID_STATE_ERR: number;
|
||||
readonly NAMESPACE_ERR: number;
|
||||
readonly NETWORK_ERR: number;
|
||||
readonly NOT_FOUND_ERR: number;
|
||||
readonly NOT_SUPPORTED_ERR: number;
|
||||
readonly NO_DATA_ALLOWED_ERR: number;
|
||||
readonly NO_MODIFICATION_ALLOWED_ERR: number;
|
||||
readonly NOT_FOUND_ERR: number;
|
||||
readonly NOT_SUPPORTED_ERR: number;
|
||||
readonly PARSE_ERR: number;
|
||||
readonly QUOTA_EXCEEDED_ERR: number;
|
||||
readonly SECURITY_ERR: number;
|
||||
@@ -348,10 +348,10 @@ declare var DOMException: {
|
||||
readonly INVALID_STATE_ERR: number;
|
||||
readonly NAMESPACE_ERR: number;
|
||||
readonly NETWORK_ERR: number;
|
||||
readonly NOT_FOUND_ERR: number;
|
||||
readonly NOT_SUPPORTED_ERR: number;
|
||||
readonly NO_DATA_ALLOWED_ERR: number;
|
||||
readonly NO_MODIFICATION_ALLOWED_ERR: number;
|
||||
readonly NOT_FOUND_ERR: number;
|
||||
readonly NOT_SUPPORTED_ERR: number;
|
||||
readonly PARSE_ERR: number;
|
||||
readonly QUOTA_EXCEEDED_ERR: number;
|
||||
readonly SECURITY_ERR: number;
|
||||
@@ -362,7 +362,7 @@ declare var DOMException: {
|
||||
readonly URL_MISMATCH_ERR: number;
|
||||
readonly VALIDATION_ERR: number;
|
||||
readonly WRONG_DOCUMENT_ERR: number;
|
||||
}
|
||||
};
|
||||
|
||||
interface DOMStringList {
|
||||
readonly length: number;
|
||||
@@ -374,7 +374,7 @@ interface DOMStringList {
|
||||
declare var DOMStringList: {
|
||||
prototype: DOMStringList;
|
||||
new(): DOMStringList;
|
||||
}
|
||||
};
|
||||
|
||||
interface ErrorEvent extends Event {
|
||||
readonly colno: number;
|
||||
@@ -388,12 +388,12 @@ interface ErrorEvent extends Event {
|
||||
declare var ErrorEvent: {
|
||||
prototype: ErrorEvent;
|
||||
new(type: string, errorEventInitDict?: ErrorEventInit): ErrorEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface Event {
|
||||
readonly bubbles: boolean;
|
||||
cancelBubble: boolean;
|
||||
readonly cancelable: boolean;
|
||||
cancelBubble: boolean;
|
||||
readonly currentTarget: EventTarget;
|
||||
readonly defaultPrevented: boolean;
|
||||
readonly eventPhase: number;
|
||||
@@ -420,7 +420,7 @@ declare var Event: {
|
||||
readonly AT_TARGET: number;
|
||||
readonly BUBBLING_PHASE: number;
|
||||
readonly CAPTURING_PHASE: number;
|
||||
}
|
||||
};
|
||||
|
||||
interface EventTarget {
|
||||
addEventListener(type: string, listener?: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
@@ -431,7 +431,7 @@ interface EventTarget {
|
||||
declare var EventTarget: {
|
||||
prototype: EventTarget;
|
||||
new(): EventTarget;
|
||||
}
|
||||
};
|
||||
|
||||
interface File extends Blob {
|
||||
readonly lastModifiedDate: any;
|
||||
@@ -442,7 +442,7 @@ interface File extends Blob {
|
||||
declare var File: {
|
||||
prototype: File;
|
||||
new (parts: (ArrayBuffer | ArrayBufferView | Blob | string)[], filename: string, properties?: FilePropertyBag): File;
|
||||
}
|
||||
};
|
||||
|
||||
interface FileList {
|
||||
readonly length: number;
|
||||
@@ -453,7 +453,7 @@ interface FileList {
|
||||
declare var FileList: {
|
||||
prototype: FileList;
|
||||
new(): FileList;
|
||||
}
|
||||
};
|
||||
|
||||
interface FileReader extends EventTarget, MSBaseReader {
|
||||
readonly error: DOMError;
|
||||
@@ -468,8 +468,17 @@ interface FileReader extends EventTarget, MSBaseReader {
|
||||
declare var FileReader: {
|
||||
prototype: FileReader;
|
||||
new(): FileReader;
|
||||
};
|
||||
|
||||
interface FormData {
|
||||
append(name: string, value: string | Blob, fileName?: string): void;
|
||||
}
|
||||
|
||||
declare var FormData: {
|
||||
prototype: FormData;
|
||||
new(): FormData;
|
||||
};
|
||||
|
||||
interface Headers {
|
||||
append(name: string, value: string): void;
|
||||
delete(name: string): void;
|
||||
@@ -482,7 +491,7 @@ interface Headers {
|
||||
declare var Headers: {
|
||||
prototype: Headers;
|
||||
new(init?: any): Headers;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBCursor {
|
||||
readonly direction: IDBCursorDirection;
|
||||
@@ -506,7 +515,7 @@ declare var IDBCursor: {
|
||||
readonly NEXT_NO_DUPLICATE: string;
|
||||
readonly PREV: string;
|
||||
readonly PREV_NO_DUPLICATE: string;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBCursorWithValue extends IDBCursor {
|
||||
readonly value: any;
|
||||
@@ -515,7 +524,7 @@ interface IDBCursorWithValue extends IDBCursor {
|
||||
declare var IDBCursorWithValue: {
|
||||
prototype: IDBCursorWithValue;
|
||||
new(): IDBCursorWithValue;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBDatabaseEventMap {
|
||||
"abort": Event;
|
||||
@@ -532,7 +541,7 @@ interface IDBDatabase extends EventTarget {
|
||||
close(): void;
|
||||
createObjectStore(name: string, optionalParameters?: IDBObjectStoreParameters): IDBObjectStore;
|
||||
deleteObjectStore(name: string): void;
|
||||
transaction(storeNames: string | string[], mode?: string): IDBTransaction;
|
||||
transaction(storeNames: string | string[], mode?: IDBTransactionMode): IDBTransaction;
|
||||
addEventListener(type: "versionchange", listener: (ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
@@ -541,7 +550,7 @@ interface IDBDatabase extends EventTarget {
|
||||
declare var IDBDatabase: {
|
||||
prototype: IDBDatabase;
|
||||
new(): IDBDatabase;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBFactory {
|
||||
cmp(first: any, second: any): number;
|
||||
@@ -552,7 +561,7 @@ interface IDBFactory {
|
||||
declare var IDBFactory: {
|
||||
prototype: IDBFactory;
|
||||
new(): IDBFactory;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBIndex {
|
||||
keyPath: string | string[];
|
||||
@@ -563,14 +572,14 @@ interface IDBIndex {
|
||||
count(key?: IDBKeyRange | IDBValidKey): IDBRequest;
|
||||
get(key: IDBKeyRange | IDBValidKey): IDBRequest;
|
||||
getKey(key: IDBKeyRange | IDBValidKey): IDBRequest;
|
||||
openCursor(range?: IDBKeyRange | IDBValidKey, direction?: string): IDBRequest;
|
||||
openKeyCursor(range?: IDBKeyRange | IDBValidKey, direction?: string): IDBRequest;
|
||||
openCursor(range?: IDBKeyRange | IDBValidKey, direction?: IDBCursorDirection): IDBRequest;
|
||||
openKeyCursor(range?: IDBKeyRange | IDBValidKey, direction?: IDBCursorDirection): IDBRequest;
|
||||
}
|
||||
|
||||
declare var IDBIndex: {
|
||||
prototype: IDBIndex;
|
||||
new(): IDBIndex;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBKeyRange {
|
||||
readonly lower: any;
|
||||
@@ -586,7 +595,7 @@ declare var IDBKeyRange: {
|
||||
lowerBound(lower: any, open?: boolean): IDBKeyRange;
|
||||
only(value: any): IDBKeyRange;
|
||||
upperBound(upper: any, open?: boolean): IDBKeyRange;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBObjectStore {
|
||||
readonly indexNames: DOMStringList;
|
||||
@@ -602,14 +611,14 @@ interface IDBObjectStore {
|
||||
deleteIndex(indexName: string): void;
|
||||
get(key: any): IDBRequest;
|
||||
index(name: string): IDBIndex;
|
||||
openCursor(range?: IDBKeyRange | IDBValidKey, direction?: string): IDBRequest;
|
||||
openCursor(range?: IDBKeyRange | IDBValidKey, direction?: IDBCursorDirection): IDBRequest;
|
||||
put(value: any, key?: IDBKeyRange | IDBValidKey): IDBRequest;
|
||||
}
|
||||
|
||||
declare var IDBObjectStore: {
|
||||
prototype: IDBObjectStore;
|
||||
new(): IDBObjectStore;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBOpenDBRequestEventMap extends IDBRequestEventMap {
|
||||
"blocked": Event;
|
||||
@@ -626,7 +635,7 @@ interface IDBOpenDBRequest extends IDBRequest {
|
||||
declare var IDBOpenDBRequest: {
|
||||
prototype: IDBOpenDBRequest;
|
||||
new(): IDBOpenDBRequest;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBRequestEventMap {
|
||||
"error": Event;
|
||||
@@ -634,7 +643,7 @@ interface IDBRequestEventMap {
|
||||
}
|
||||
|
||||
interface IDBRequest extends EventTarget {
|
||||
readonly error: DOMError;
|
||||
readonly error: DOMException;
|
||||
onerror: (this: IDBRequest, ev: Event) => any;
|
||||
onsuccess: (this: IDBRequest, ev: Event) => any;
|
||||
readonly readyState: IDBRequestReadyState;
|
||||
@@ -648,7 +657,7 @@ interface IDBRequest extends EventTarget {
|
||||
declare var IDBRequest: {
|
||||
prototype: IDBRequest;
|
||||
new(): IDBRequest;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBTransactionEventMap {
|
||||
"abort": Event;
|
||||
@@ -658,7 +667,7 @@ interface IDBTransactionEventMap {
|
||||
|
||||
interface IDBTransaction extends EventTarget {
|
||||
readonly db: IDBDatabase;
|
||||
readonly error: DOMError;
|
||||
readonly error: DOMException;
|
||||
readonly mode: IDBTransactionMode;
|
||||
onabort: (this: IDBTransaction, ev: Event) => any;
|
||||
oncomplete: (this: IDBTransaction, ev: Event) => any;
|
||||
@@ -678,7 +687,7 @@ declare var IDBTransaction: {
|
||||
readonly READ_ONLY: string;
|
||||
readonly READ_WRITE: string;
|
||||
readonly VERSION_CHANGE: string;
|
||||
}
|
||||
};
|
||||
|
||||
interface IDBVersionChangeEvent extends Event {
|
||||
readonly newVersion: number | null;
|
||||
@@ -688,7 +697,7 @@ interface IDBVersionChangeEvent extends Event {
|
||||
declare var IDBVersionChangeEvent: {
|
||||
prototype: IDBVersionChangeEvent;
|
||||
new(): IDBVersionChangeEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface ImageData {
|
||||
data: Uint8ClampedArray;
|
||||
@@ -700,7 +709,7 @@ declare var ImageData: {
|
||||
prototype: ImageData;
|
||||
new(width: number, height: number): ImageData;
|
||||
new(array: Uint8ClampedArray, width: number, height: number): ImageData;
|
||||
}
|
||||
};
|
||||
|
||||
interface MessageChannel {
|
||||
readonly port1: MessagePort;
|
||||
@@ -710,7 +719,7 @@ interface MessageChannel {
|
||||
declare var MessageChannel: {
|
||||
prototype: MessageChannel;
|
||||
new(): MessageChannel;
|
||||
}
|
||||
};
|
||||
|
||||
interface MessageEvent extends Event {
|
||||
readonly data: any;
|
||||
@@ -723,7 +732,7 @@ interface MessageEvent extends Event {
|
||||
declare var MessageEvent: {
|
||||
prototype: MessageEvent;
|
||||
new(type: string, eventInitDict?: MessageEventInit): MessageEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface MessagePortEventMap {
|
||||
"message": MessageEvent;
|
||||
@@ -741,7 +750,7 @@ interface MessagePort extends EventTarget {
|
||||
declare var MessagePort: {
|
||||
prototype: MessagePort;
|
||||
new(): MessagePort;
|
||||
}
|
||||
};
|
||||
|
||||
interface NotificationEventMap {
|
||||
"click": Event;
|
||||
@@ -771,7 +780,7 @@ declare var Notification: {
|
||||
prototype: Notification;
|
||||
new(title: string, options?: NotificationOptions): Notification;
|
||||
requestPermission(callback?: NotificationPermissionCallback): Promise<NotificationPermission>;
|
||||
}
|
||||
};
|
||||
|
||||
interface Performance {
|
||||
readonly navigation: PerformanceNavigation;
|
||||
@@ -794,7 +803,7 @@ interface Performance {
|
||||
declare var Performance: {
|
||||
prototype: Performance;
|
||||
new(): Performance;
|
||||
}
|
||||
};
|
||||
|
||||
interface PerformanceNavigation {
|
||||
readonly redirectCount: number;
|
||||
@@ -813,18 +822,18 @@ declare var PerformanceNavigation: {
|
||||
readonly TYPE_NAVIGATE: number;
|
||||
readonly TYPE_RELOAD: number;
|
||||
readonly TYPE_RESERVED: number;
|
||||
}
|
||||
};
|
||||
|
||||
interface PerformanceTiming {
|
||||
readonly connectEnd: number;
|
||||
readonly connectStart: number;
|
||||
readonly domainLookupEnd: number;
|
||||
readonly domainLookupStart: number;
|
||||
readonly domComplete: number;
|
||||
readonly domContentLoadedEventEnd: number;
|
||||
readonly domContentLoadedEventStart: number;
|
||||
readonly domInteractive: number;
|
||||
readonly domLoading: number;
|
||||
readonly domainLookupEnd: number;
|
||||
readonly domainLookupStart: number;
|
||||
readonly fetchStart: number;
|
||||
readonly loadEventEnd: number;
|
||||
readonly loadEventStart: number;
|
||||
@@ -844,7 +853,7 @@ interface PerformanceTiming {
|
||||
declare var PerformanceTiming: {
|
||||
prototype: PerformanceTiming;
|
||||
new(): PerformanceTiming;
|
||||
}
|
||||
};
|
||||
|
||||
interface Position {
|
||||
readonly coords: Coordinates;
|
||||
@@ -854,7 +863,7 @@ interface Position {
|
||||
declare var Position: {
|
||||
prototype: Position;
|
||||
new(): Position;
|
||||
}
|
||||
};
|
||||
|
||||
interface PositionError {
|
||||
readonly code: number;
|
||||
@@ -871,7 +880,7 @@ declare var PositionError: {
|
||||
readonly PERMISSION_DENIED: number;
|
||||
readonly POSITION_UNAVAILABLE: number;
|
||||
readonly TIMEOUT: number;
|
||||
}
|
||||
};
|
||||
|
||||
interface ProgressEvent extends Event {
|
||||
readonly lengthComputable: boolean;
|
||||
@@ -883,7 +892,7 @@ interface ProgressEvent extends Event {
|
||||
declare var ProgressEvent: {
|
||||
prototype: ProgressEvent;
|
||||
new(type: string, eventInitDict?: ProgressEventInit): ProgressEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface PushManager {
|
||||
getSubscription(): Promise<PushSubscription>;
|
||||
@@ -894,7 +903,7 @@ interface PushManager {
|
||||
declare var PushManager: {
|
||||
prototype: PushManager;
|
||||
new(): PushManager;
|
||||
}
|
||||
};
|
||||
|
||||
interface PushSubscription {
|
||||
readonly endpoint: USVString;
|
||||
@@ -907,7 +916,7 @@ interface PushSubscription {
|
||||
declare var PushSubscription: {
|
||||
prototype: PushSubscription;
|
||||
new(): PushSubscription;
|
||||
}
|
||||
};
|
||||
|
||||
interface PushSubscriptionOptions {
|
||||
readonly applicationServerKey: ArrayBuffer | null;
|
||||
@@ -917,7 +926,7 @@ interface PushSubscriptionOptions {
|
||||
declare var PushSubscriptionOptions: {
|
||||
prototype: PushSubscriptionOptions;
|
||||
new(): PushSubscriptionOptions;
|
||||
}
|
||||
};
|
||||
|
||||
interface ReadableStream {
|
||||
readonly locked: boolean;
|
||||
@@ -928,7 +937,7 @@ interface ReadableStream {
|
||||
declare var ReadableStream: {
|
||||
prototype: ReadableStream;
|
||||
new(): ReadableStream;
|
||||
}
|
||||
};
|
||||
|
||||
interface ReadableStreamReader {
|
||||
cancel(): Promise<void>;
|
||||
@@ -939,7 +948,7 @@ interface ReadableStreamReader {
|
||||
declare var ReadableStreamReader: {
|
||||
prototype: ReadableStreamReader;
|
||||
new(): ReadableStreamReader;
|
||||
}
|
||||
};
|
||||
|
||||
interface Request extends Object, Body {
|
||||
readonly cache: RequestCache;
|
||||
@@ -961,7 +970,7 @@ interface Request extends Object, Body {
|
||||
declare var Request: {
|
||||
prototype: Request;
|
||||
new(input: Request | string, init?: RequestInit): Request;
|
||||
}
|
||||
};
|
||||
|
||||
interface Response extends Object, Body {
|
||||
readonly body: ReadableStream | null;
|
||||
@@ -977,7 +986,9 @@ interface Response extends Object, Body {
|
||||
declare var Response: {
|
||||
prototype: Response;
|
||||
new(body?: any, init?: ResponseInit): Response;
|
||||
}
|
||||
error: () => Response;
|
||||
redirect: (url: string, status?: number) => Response;
|
||||
};
|
||||
|
||||
interface ServiceWorkerEventMap extends AbstractWorkerEventMap {
|
||||
"statechange": Event;
|
||||
@@ -995,7 +1006,7 @@ interface ServiceWorker extends EventTarget, AbstractWorker {
|
||||
declare var ServiceWorker: {
|
||||
prototype: ServiceWorker;
|
||||
new(): ServiceWorker;
|
||||
}
|
||||
};
|
||||
|
||||
interface ServiceWorkerRegistrationEventMap {
|
||||
"updatefound": Event;
|
||||
@@ -1020,7 +1031,7 @@ interface ServiceWorkerRegistration extends EventTarget {
|
||||
declare var ServiceWorkerRegistration: {
|
||||
prototype: ServiceWorkerRegistration;
|
||||
new(): ServiceWorkerRegistration;
|
||||
}
|
||||
};
|
||||
|
||||
interface SyncManager {
|
||||
getTags(): any;
|
||||
@@ -1030,7 +1041,7 @@ interface SyncManager {
|
||||
declare var SyncManager: {
|
||||
prototype: SyncManager;
|
||||
new(): SyncManager;
|
||||
}
|
||||
};
|
||||
|
||||
interface URL {
|
||||
hash: string;
|
||||
@@ -1053,7 +1064,7 @@ declare var URL: {
|
||||
new(url: string, base?: string): URL;
|
||||
createObjectURL(object: any, options?: ObjectURLOptions): string;
|
||||
revokeObjectURL(url: string): void;
|
||||
}
|
||||
};
|
||||
|
||||
interface WebSocketEventMap {
|
||||
"close": CloseEvent;
|
||||
@@ -1090,7 +1101,7 @@ declare var WebSocket: {
|
||||
readonly CLOSING: number;
|
||||
readonly CONNECTING: number;
|
||||
readonly OPEN: number;
|
||||
}
|
||||
};
|
||||
|
||||
interface WorkerEventMap extends AbstractWorkerEventMap {
|
||||
"message": MessageEvent;
|
||||
@@ -1107,7 +1118,7 @@ interface Worker extends EventTarget, AbstractWorker {
|
||||
declare var Worker: {
|
||||
prototype: Worker;
|
||||
new(stringUrl: string): Worker;
|
||||
}
|
||||
};
|
||||
|
||||
interface XMLHttpRequestEventMap extends XMLHttpRequestEventTargetEventMap {
|
||||
"readystatechange": Event;
|
||||
@@ -1153,7 +1164,7 @@ declare var XMLHttpRequest: {
|
||||
readonly LOADING: number;
|
||||
readonly OPENED: number;
|
||||
readonly UNSENT: number;
|
||||
}
|
||||
};
|
||||
|
||||
interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget {
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
@@ -1163,7 +1174,7 @@ interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget {
|
||||
declare var XMLHttpRequestUpload: {
|
||||
prototype: XMLHttpRequestUpload;
|
||||
new(): XMLHttpRequestUpload;
|
||||
}
|
||||
};
|
||||
|
||||
interface AbstractWorkerEventMap {
|
||||
"error": ErrorEvent;
|
||||
@@ -1278,7 +1289,7 @@ interface Client {
|
||||
declare var Client: {
|
||||
prototype: Client;
|
||||
new(): Client;
|
||||
}
|
||||
};
|
||||
|
||||
interface Clients {
|
||||
claim(): Promise<void>;
|
||||
@@ -1290,7 +1301,7 @@ interface Clients {
|
||||
declare var Clients: {
|
||||
prototype: Clients;
|
||||
new(): Clients;
|
||||
}
|
||||
};
|
||||
|
||||
interface DedicatedWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap {
|
||||
"message": MessageEvent;
|
||||
@@ -1307,7 +1318,7 @@ interface DedicatedWorkerGlobalScope extends WorkerGlobalScope {
|
||||
declare var DedicatedWorkerGlobalScope: {
|
||||
prototype: DedicatedWorkerGlobalScope;
|
||||
new(): DedicatedWorkerGlobalScope;
|
||||
}
|
||||
};
|
||||
|
||||
interface ExtendableEvent extends Event {
|
||||
waitUntil(f: Promise<any>): void;
|
||||
@@ -1316,7 +1327,7 @@ interface ExtendableEvent extends Event {
|
||||
declare var ExtendableEvent: {
|
||||
prototype: ExtendableEvent;
|
||||
new(type: string, eventInitDict?: ExtendableEventInit): ExtendableEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface ExtendableMessageEvent extends ExtendableEvent {
|
||||
readonly data: any;
|
||||
@@ -1329,7 +1340,7 @@ interface ExtendableMessageEvent extends ExtendableEvent {
|
||||
declare var ExtendableMessageEvent: {
|
||||
prototype: ExtendableMessageEvent;
|
||||
new(type: string, eventInitDict?: ExtendableMessageEventInit): ExtendableMessageEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface FetchEvent extends ExtendableEvent {
|
||||
readonly clientId: string | null;
|
||||
@@ -1341,7 +1352,7 @@ interface FetchEvent extends ExtendableEvent {
|
||||
declare var FetchEvent: {
|
||||
prototype: FetchEvent;
|
||||
new(type: string, eventInitDict: FetchEventInit): FetchEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface FileReaderSync {
|
||||
readAsArrayBuffer(blob: Blob): any;
|
||||
@@ -1353,7 +1364,7 @@ interface FileReaderSync {
|
||||
declare var FileReaderSync: {
|
||||
prototype: FileReaderSync;
|
||||
new(): FileReaderSync;
|
||||
}
|
||||
};
|
||||
|
||||
interface NotificationEvent extends ExtendableEvent {
|
||||
readonly action: string;
|
||||
@@ -1363,7 +1374,7 @@ interface NotificationEvent extends ExtendableEvent {
|
||||
declare var NotificationEvent: {
|
||||
prototype: NotificationEvent;
|
||||
new(type: string, eventInitDict: NotificationEventInit): NotificationEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface PushEvent extends ExtendableEvent {
|
||||
readonly data: PushMessageData | null;
|
||||
@@ -1372,7 +1383,7 @@ interface PushEvent extends ExtendableEvent {
|
||||
declare var PushEvent: {
|
||||
prototype: PushEvent;
|
||||
new(type: string, eventInitDict?: PushEventInit): PushEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface PushMessageData {
|
||||
arrayBuffer(): ArrayBuffer;
|
||||
@@ -1384,7 +1395,7 @@ interface PushMessageData {
|
||||
declare var PushMessageData: {
|
||||
prototype: PushMessageData;
|
||||
new(): PushMessageData;
|
||||
}
|
||||
};
|
||||
|
||||
interface ServiceWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap {
|
||||
"activate": ExtendableEvent;
|
||||
@@ -1418,7 +1429,7 @@ interface ServiceWorkerGlobalScope extends WorkerGlobalScope {
|
||||
declare var ServiceWorkerGlobalScope: {
|
||||
prototype: ServiceWorkerGlobalScope;
|
||||
new(): ServiceWorkerGlobalScope;
|
||||
}
|
||||
};
|
||||
|
||||
interface SyncEvent extends ExtendableEvent {
|
||||
readonly lastChance: boolean;
|
||||
@@ -1428,7 +1439,7 @@ interface SyncEvent extends ExtendableEvent {
|
||||
declare var SyncEvent: {
|
||||
prototype: SyncEvent;
|
||||
new(type: string, init: SyncEventInit): SyncEvent;
|
||||
}
|
||||
};
|
||||
|
||||
interface WindowClient extends Client {
|
||||
readonly focused: boolean;
|
||||
@@ -1440,7 +1451,7 @@ interface WindowClient extends Client {
|
||||
declare var WindowClient: {
|
||||
prototype: WindowClient;
|
||||
new(): WindowClient;
|
||||
}
|
||||
};
|
||||
|
||||
interface WorkerGlobalScopeEventMap {
|
||||
"error": ErrorEvent;
|
||||
@@ -1463,7 +1474,7 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo
|
||||
declare var WorkerGlobalScope: {
|
||||
prototype: WorkerGlobalScope;
|
||||
new(): WorkerGlobalScope;
|
||||
}
|
||||
};
|
||||
|
||||
interface WorkerLocation {
|
||||
readonly hash: string;
|
||||
@@ -1481,7 +1492,7 @@ interface WorkerLocation {
|
||||
declare var WorkerLocation: {
|
||||
prototype: WorkerLocation;
|
||||
new(): WorkerLocation;
|
||||
}
|
||||
};
|
||||
|
||||
interface WorkerNavigator extends Object, NavigatorID, NavigatorOnLine, NavigatorBeacon, NavigatorConcurrentHardware {
|
||||
readonly hardwareConcurrency: number;
|
||||
@@ -1490,7 +1501,7 @@ interface WorkerNavigator extends Object, NavigatorID, NavigatorOnLine, Navigato
|
||||
declare var WorkerNavigator: {
|
||||
prototype: WorkerNavigator;
|
||||
new(): WorkerNavigator;
|
||||
}
|
||||
};
|
||||
|
||||
interface WorkerUtils extends Object, WindowBase64 {
|
||||
readonly indexedDB: IDBFactory;
|
||||
@@ -1533,38 +1544,38 @@ interface ImageBitmap {
|
||||
|
||||
interface URLSearchParams {
|
||||
/**
|
||||
* Appends a specified key/value pair as a new search parameter.
|
||||
*/
|
||||
* Appends a specified key/value pair as a new search parameter.
|
||||
*/
|
||||
append(name: string, value: string): void;
|
||||
/**
|
||||
* Deletes the given search parameter, and its associated value, from the list of all search parameters.
|
||||
*/
|
||||
* Deletes the given search parameter, and its associated value, from the list of all search parameters.
|
||||
*/
|
||||
delete(name: string): void;
|
||||
/**
|
||||
* Returns the first value associated to the given search parameter.
|
||||
*/
|
||||
* Returns the first value associated to the given search parameter.
|
||||
*/
|
||||
get(name: string): string | null;
|
||||
/**
|
||||
* Returns all the values association with a given search parameter.
|
||||
*/
|
||||
* Returns all the values association with a given search parameter.
|
||||
*/
|
||||
getAll(name: string): string[];
|
||||
/**
|
||||
* Returns a Boolean indicating if such a search parameter exists.
|
||||
*/
|
||||
* Returns a Boolean indicating if such a search parameter exists.
|
||||
*/
|
||||
has(name: string): boolean;
|
||||
/**
|
||||
* Sets the value associated to a given search parameter to the given value. If there were several values, delete the others.
|
||||
*/
|
||||
* Sets the value associated to a given search parameter to the given value. If there were several values, delete the others.
|
||||
*/
|
||||
set(name: string, value: string): void;
|
||||
}
|
||||
|
||||
declare var URLSearchParams: {
|
||||
prototype: URLSearchParams;
|
||||
/**
|
||||
* Constructor returning a URLSearchParams object.
|
||||
*/
|
||||
* Constructor returning a URLSearchParams object.
|
||||
*/
|
||||
new (init?: string | URLSearchParams): URLSearchParams;
|
||||
}
|
||||
};
|
||||
|
||||
interface BlobPropertyBag {
|
||||
type?: string;
|
||||
@@ -1771,8 +1782,23 @@ interface AddEventListenerOptions extends EventListenerOptions {
|
||||
|
||||
declare type EventListenerOrEventListenerObject = EventListener | EventListenerObject;
|
||||
|
||||
interface DecodeErrorCallback {
|
||||
(error: DOMException): void;
|
||||
}
|
||||
interface DecodeSuccessCallback {
|
||||
(decodedData: AudioBuffer): void;
|
||||
}
|
||||
interface ErrorEventHandler {
|
||||
(message: string, filename?: string, lineno?: number, colno?: number, error?:Error): void;
|
||||
(message: string, filename?: string, lineno?: number, colno?: number, error?: Error): void;
|
||||
}
|
||||
interface ForEachCallback {
|
||||
(keyId: any, status: MediaKeyStatus): void;
|
||||
}
|
||||
interface FunctionStringCallback {
|
||||
(data: string): void;
|
||||
}
|
||||
interface NotificationPermissionCallback {
|
||||
(permission: NotificationPermission): void;
|
||||
}
|
||||
interface PositionCallback {
|
||||
(position: Position): void;
|
||||
@@ -1780,21 +1806,6 @@ interface PositionCallback {
|
||||
interface PositionErrorCallback {
|
||||
(error: PositionError): void;
|
||||
}
|
||||
interface DecodeSuccessCallback {
|
||||
(decodedData: AudioBuffer): void;
|
||||
}
|
||||
interface DecodeErrorCallback {
|
||||
(error: DOMException): void;
|
||||
}
|
||||
interface FunctionStringCallback {
|
||||
(data: string): void;
|
||||
}
|
||||
interface ForEachCallback {
|
||||
(keyId: any, status: MediaKeyStatus): void;
|
||||
}
|
||||
interface NotificationPermissionCallback {
|
||||
(permission: NotificationPermission): void;
|
||||
}
|
||||
declare var onmessage: (this: DedicatedWorkerGlobalScope, ev: MessageEvent) => any;
|
||||
declare function close(): void;
|
||||
declare function postMessage(message: any, transfer?: any[]): void;
|
||||
|
||||
Vendored
+180
-95
@@ -2,51 +2,53 @@
|
||||
* Declaration module describing the TypeScript Server protocol
|
||||
*/
|
||||
declare namespace ts.server.protocol {
|
||||
namespace CommandTypes {
|
||||
type Brace = "brace";
|
||||
type BraceCompletion = "braceCompletion";
|
||||
type Change = "change";
|
||||
type Close = "close";
|
||||
type Completions = "completions";
|
||||
type CompletionDetails = "completionEntryDetails";
|
||||
type CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList";
|
||||
type CompileOnSaveEmitFile = "compileOnSaveEmitFile";
|
||||
type Configure = "configure";
|
||||
type Definition = "definition";
|
||||
type Implementation = "implementation";
|
||||
type Exit = "exit";
|
||||
type Format = "format";
|
||||
type Formatonkey = "formatonkey";
|
||||
type Geterr = "geterr";
|
||||
type GeterrForProject = "geterrForProject";
|
||||
type SemanticDiagnosticsSync = "semanticDiagnosticsSync";
|
||||
type SyntacticDiagnosticsSync = "syntacticDiagnosticsSync";
|
||||
type NavBar = "navbar";
|
||||
type Navto = "navto";
|
||||
type NavTree = "navtree";
|
||||
type NavTreeFull = "navtree-full";
|
||||
type Occurrences = "occurrences";
|
||||
type DocumentHighlights = "documentHighlights";
|
||||
type Open = "open";
|
||||
type Quickinfo = "quickinfo";
|
||||
type References = "references";
|
||||
type Reload = "reload";
|
||||
type Rename = "rename";
|
||||
type Saveto = "saveto";
|
||||
type SignatureHelp = "signatureHelp";
|
||||
type TypeDefinition = "typeDefinition";
|
||||
type ProjectInfo = "projectInfo";
|
||||
type ReloadProjects = "reloadProjects";
|
||||
type Unknown = "unknown";
|
||||
type OpenExternalProject = "openExternalProject";
|
||||
type OpenExternalProjects = "openExternalProjects";
|
||||
type CloseExternalProject = "closeExternalProject";
|
||||
type TodoComments = "todoComments";
|
||||
type Indentation = "indentation";
|
||||
type DocCommentTemplate = "docCommentTemplate";
|
||||
type CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects";
|
||||
type GetCodeFixes = "getCodeFixes";
|
||||
type GetSupportedCodeFixes = "getSupportedCodeFixes";
|
||||
const enum CommandTypes {
|
||||
Brace = "brace",
|
||||
BraceCompletion = "braceCompletion",
|
||||
Change = "change",
|
||||
Close = "close",
|
||||
Completions = "completions",
|
||||
CompletionDetails = "completionEntryDetails",
|
||||
CompileOnSaveAffectedFileList = "compileOnSaveAffectedFileList",
|
||||
CompileOnSaveEmitFile = "compileOnSaveEmitFile",
|
||||
Configure = "configure",
|
||||
Definition = "definition",
|
||||
Implementation = "implementation",
|
||||
Exit = "exit",
|
||||
Format = "format",
|
||||
Formatonkey = "formatonkey",
|
||||
Geterr = "geterr",
|
||||
GeterrForProject = "geterrForProject",
|
||||
SemanticDiagnosticsSync = "semanticDiagnosticsSync",
|
||||
SyntacticDiagnosticsSync = "syntacticDiagnosticsSync",
|
||||
NavBar = "navbar",
|
||||
Navto = "navto",
|
||||
NavTree = "navtree",
|
||||
NavTreeFull = "navtree-full",
|
||||
Occurrences = "occurrences",
|
||||
DocumentHighlights = "documentHighlights",
|
||||
Open = "open",
|
||||
Quickinfo = "quickinfo",
|
||||
References = "references",
|
||||
Reload = "reload",
|
||||
Rename = "rename",
|
||||
Saveto = "saveto",
|
||||
SignatureHelp = "signatureHelp",
|
||||
TypeDefinition = "typeDefinition",
|
||||
ProjectInfo = "projectInfo",
|
||||
ReloadProjects = "reloadProjects",
|
||||
Unknown = "unknown",
|
||||
OpenExternalProject = "openExternalProject",
|
||||
OpenExternalProjects = "openExternalProjects",
|
||||
CloseExternalProject = "closeExternalProject",
|
||||
TodoComments = "todoComments",
|
||||
Indentation = "indentation",
|
||||
DocCommentTemplate = "docCommentTemplate",
|
||||
CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects",
|
||||
GetCodeFixes = "getCodeFixes",
|
||||
GetSupportedCodeFixes = "getSupportedCodeFixes",
|
||||
GetApplicableRefactors = "getApplicableRefactors",
|
||||
GetEditsForRefactor = "getEditsForRefactor",
|
||||
}
|
||||
/**
|
||||
* A TypeScript Server message
|
||||
@@ -287,6 +289,85 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
offset: number;
|
||||
}
|
||||
type FileLocationOrRangeRequestArgs = FileLocationRequestArgs | FileRangeRequestArgs;
|
||||
/**
|
||||
* Request refactorings at a given position or selection area.
|
||||
*/
|
||||
interface GetApplicableRefactorsRequest extends Request {
|
||||
command: CommandTypes.GetApplicableRefactors;
|
||||
arguments: GetApplicableRefactorsRequestArgs;
|
||||
}
|
||||
type GetApplicableRefactorsRequestArgs = FileLocationOrRangeRequestArgs;
|
||||
/**
|
||||
* Response is a list of available refactorings.
|
||||
* Each refactoring exposes one or more "Actions"; a user selects one action to invoke a refactoring
|
||||
*/
|
||||
interface GetApplicableRefactorsResponse extends Response {
|
||||
body?: ApplicableRefactorInfo[];
|
||||
}
|
||||
/**
|
||||
* A set of one or more available refactoring actions, grouped under a parent refactoring.
|
||||
*/
|
||||
interface ApplicableRefactorInfo {
|
||||
/**
|
||||
* The programmatic name of the refactoring
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* A description of this refactoring category to show to the user.
|
||||
* If the refactoring gets inlined (see below), this text will not be visible.
|
||||
*/
|
||||
description: string;
|
||||
/**
|
||||
* Inlineable refactorings can have their actions hoisted out to the top level
|
||||
* of a context menu. Non-inlineanable refactorings should always be shown inside
|
||||
* their parent grouping.
|
||||
*
|
||||
* If not specified, this value is assumed to be 'true'
|
||||
*/
|
||||
inlineable?: boolean;
|
||||
actions: RefactorActionInfo[];
|
||||
}
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
type RefactorActionInfo = {
|
||||
/**
|
||||
* The programmatic name of the refactoring action
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* A description of this refactoring action to show to the user.
|
||||
* If the parent refactoring is inlined away, this will be the only text shown,
|
||||
* so this description should make sense by itself if the parent is inlineable=true
|
||||
*/
|
||||
description: string;
|
||||
};
|
||||
interface GetEditsForRefactorRequest extends Request {
|
||||
command: CommandTypes.GetEditsForRefactor;
|
||||
arguments: GetEditsForRefactorRequestArgs;
|
||||
}
|
||||
/**
|
||||
* Request the edits that a particular refactoring action produces.
|
||||
* Callers must specify the name of the refactor and the name of the action.
|
||||
*/
|
||||
type GetEditsForRefactorRequestArgs = FileLocationOrRangeRequestArgs & {
|
||||
refactor: string;
|
||||
action: string;
|
||||
};
|
||||
interface GetEditsForRefactorResponse extends Response {
|
||||
body?: RefactorEditInfo;
|
||||
}
|
||||
type RefactorEditInfo = {
|
||||
edits: FileCodeEdits[];
|
||||
/**
|
||||
* An optional location where the editor should start a rename operation once
|
||||
* the refactoring edits have been applied
|
||||
*/
|
||||
renameLocation?: Location;
|
||||
renameFilename?: string;
|
||||
};
|
||||
/**
|
||||
* Request for the available codefixes at a specific position.
|
||||
*/
|
||||
@@ -294,10 +375,7 @@ declare namespace ts.server.protocol {
|
||||
command: CommandTypes.GetCodeFixes;
|
||||
arguments: CodeFixRequestArgs;
|
||||
}
|
||||
/**
|
||||
* Instances of this interface specify errorcodes on a specific location in a sourcefile.
|
||||
*/
|
||||
interface CodeFixRequestArgs extends FileRequestArgs {
|
||||
interface FileRangeRequestArgs extends FileRequestArgs {
|
||||
/**
|
||||
* The line number for the request (1-based).
|
||||
*/
|
||||
@@ -314,6 +392,11 @@ declare namespace ts.server.protocol {
|
||||
* The character offset (on the line) for the request (1-based).
|
||||
*/
|
||||
endOffset: number;
|
||||
}
|
||||
/**
|
||||
* Instances of this interface specify errorcodes on a specific location in a sourcefile.
|
||||
*/
|
||||
interface CodeFixRequestArgs extends FileRangeRequestArgs {
|
||||
/**
|
||||
* Errorcodes we want to get the fixes for.
|
||||
*/
|
||||
@@ -394,7 +477,7 @@ declare namespace ts.server.protocol {
|
||||
command: CommandTypes.Implementation;
|
||||
}
|
||||
/**
|
||||
* Location in source code expressed as (one-based) line and character offset.
|
||||
* Location in source code expressed as (one-based) line and (one-based) column offset.
|
||||
*/
|
||||
interface Location {
|
||||
line: number;
|
||||
@@ -488,10 +571,9 @@ declare namespace ts.server.protocol {
|
||||
}
|
||||
/**
|
||||
* Span augmented with extra information that denotes the kind of the highlighting to be used for span.
|
||||
* Kind is taken from HighlightSpanKind type.
|
||||
*/
|
||||
interface HighlightSpan extends TextSpan {
|
||||
kind: string;
|
||||
kind: HighlightSpanKind;
|
||||
}
|
||||
/**
|
||||
* Represents a set of highligh spans for a give name
|
||||
@@ -609,7 +691,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The items's kind (such as 'className' or 'parameterName' or plain 'text').
|
||||
*/
|
||||
kind: string;
|
||||
kind: ScriptElementKind;
|
||||
/**
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
@@ -957,7 +1039,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The symbol's kind (such as 'className' or 'parameterName' or plain 'text').
|
||||
*/
|
||||
kind: string;
|
||||
kind: ScriptElementKind;
|
||||
/**
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
@@ -1143,7 +1225,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The symbol's kind (such as 'className' or 'parameterName').
|
||||
*/
|
||||
kind: string;
|
||||
kind: ScriptElementKind;
|
||||
/**
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
@@ -1170,7 +1252,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The symbol's kind (such as 'className' or 'parameterName').
|
||||
*/
|
||||
kind: string;
|
||||
kind: ScriptElementKind;
|
||||
/**
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
@@ -1417,6 +1499,12 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
source?: string;
|
||||
}
|
||||
interface DiagnosticWithFileName extends Diagnostic {
|
||||
/**
|
||||
* Name of the file the diagnostic is in
|
||||
*/
|
||||
fileName: string;
|
||||
}
|
||||
interface DiagnosticEventBody {
|
||||
/**
|
||||
* The file for which diagnostic information is reported.
|
||||
@@ -1446,7 +1534,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* An arry of diagnostic information items for the found config file.
|
||||
*/
|
||||
diagnostics: Diagnostic[];
|
||||
diagnostics: DiagnosticWithFileName[];
|
||||
}
|
||||
/**
|
||||
* Event message for "configFileDiag" event type.
|
||||
@@ -1563,7 +1651,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The symbol's kind (such as 'className' or 'parameterName').
|
||||
*/
|
||||
kind: string;
|
||||
kind: ScriptElementKind;
|
||||
/**
|
||||
* exact, substring, or prefix.
|
||||
*/
|
||||
@@ -1596,7 +1684,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* Kind of symbol's container symbol (if any).
|
||||
*/
|
||||
containerKind?: string;
|
||||
containerKind?: ScriptElementKind;
|
||||
}
|
||||
/**
|
||||
* Navto response message. Body is an array of navto items. Each
|
||||
@@ -1660,7 +1748,7 @@ declare namespace ts.server.protocol {
|
||||
/**
|
||||
* The symbol's kind (such as 'className' or 'parameterName').
|
||||
*/
|
||||
kind: string;
|
||||
kind: ScriptElementKind;
|
||||
/**
|
||||
* Optional modifiers for the kind (such as 'public').
|
||||
*/
|
||||
@@ -1681,7 +1769,7 @@ declare namespace ts.server.protocol {
|
||||
/** protocol.NavigationTree is identical to ts.NavigationTree, except using protocol.TextSpan instead of ts.TextSpan */
|
||||
interface NavigationTree {
|
||||
text: string;
|
||||
kind: string;
|
||||
kind: ScriptElementKind;
|
||||
kindModifiers: string;
|
||||
spans: TextSpan[];
|
||||
childItems?: NavigationTree[];
|
||||
@@ -1756,12 +1844,11 @@ declare namespace ts.server.protocol {
|
||||
interface NavTreeResponse extends Response {
|
||||
body?: NavigationTree;
|
||||
}
|
||||
namespace IndentStyle {
|
||||
type None = "None";
|
||||
type Block = "Block";
|
||||
type Smart = "Smart";
|
||||
const enum IndentStyle {
|
||||
None = "None",
|
||||
Block = "Block",
|
||||
Smart = "Smart",
|
||||
}
|
||||
type IndentStyle = IndentStyle.None | IndentStyle.Block | IndentStyle.Smart;
|
||||
interface EditorSettings {
|
||||
baseIndentSize?: number;
|
||||
indentSize?: number;
|
||||
@@ -1782,6 +1869,7 @@ declare namespace ts.server.protocol {
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
insertSpaceAfterTypeAssertion?: boolean;
|
||||
insertSpaceBeforeFunctionParenthesis?: boolean;
|
||||
placeOpenBraceOnNewLineForFunctions?: boolean;
|
||||
placeOpenBraceOnNewLineForControlBlocks?: boolean;
|
||||
@@ -1854,40 +1942,35 @@ declare namespace ts.server.protocol {
|
||||
typeRoots?: string[];
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
}
|
||||
namespace JsxEmit {
|
||||
type None = "None";
|
||||
type Preserve = "Preserve";
|
||||
type ReactNative = "ReactNative";
|
||||
type React = "React";
|
||||
const enum JsxEmit {
|
||||
None = "None",
|
||||
Preserve = "Preserve",
|
||||
ReactNative = "ReactNative",
|
||||
React = "React",
|
||||
}
|
||||
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.ReactNative;
|
||||
namespace ModuleKind {
|
||||
type None = "None";
|
||||
type CommonJS = "CommonJS";
|
||||
type AMD = "AMD";
|
||||
type UMD = "UMD";
|
||||
type System = "System";
|
||||
type ES6 = "ES6";
|
||||
type ES2015 = "ES2015";
|
||||
const enum ModuleKind {
|
||||
None = "None",
|
||||
CommonJS = "CommonJS",
|
||||
AMD = "AMD",
|
||||
UMD = "UMD",
|
||||
System = "System",
|
||||
ES6 = "ES6",
|
||||
ES2015 = "ES2015",
|
||||
}
|
||||
type ModuleKind = ModuleKind.None | ModuleKind.CommonJS | ModuleKind.AMD | ModuleKind.UMD | ModuleKind.System | ModuleKind.ES6 | ModuleKind.ES2015;
|
||||
namespace ModuleResolutionKind {
|
||||
type Classic = "Classic";
|
||||
type Node = "Node";
|
||||
const enum ModuleResolutionKind {
|
||||
Classic = "Classic",
|
||||
Node = "Node",
|
||||
}
|
||||
type ModuleResolutionKind = ModuleResolutionKind.Classic | ModuleResolutionKind.Node;
|
||||
namespace NewLineKind {
|
||||
type Crlf = "Crlf";
|
||||
type Lf = "Lf";
|
||||
const enum NewLineKind {
|
||||
Crlf = "Crlf",
|
||||
Lf = "Lf",
|
||||
}
|
||||
type NewLineKind = NewLineKind.Crlf | NewLineKind.Lf;
|
||||
namespace ScriptTarget {
|
||||
type ES3 = "ES3";
|
||||
type ES5 = "ES5";
|
||||
type ES6 = "ES6";
|
||||
type ES2015 = "ES2015";
|
||||
const enum ScriptTarget {
|
||||
ES3 = "ES3",
|
||||
ES5 = "ES5",
|
||||
ES6 = "ES6",
|
||||
ES2015 = "ES2015",
|
||||
}
|
||||
type ScriptTarget = ScriptTarget.ES3 | ScriptTarget.ES5 | ScriptTarget.ES6 | ScriptTarget.ES2015;
|
||||
}
|
||||
declare namespace ts.server.protocol {
|
||||
|
||||
@@ -1943,6 +2026,8 @@ declare namespace ts.server.protocol {
|
||||
}
|
||||
declare namespace ts {
|
||||
// these types are empty stubs for types from services and should not be used directly
|
||||
export type HighlightSpanKind = never;
|
||||
export type ScriptElementKind = never;
|
||||
export type ScriptKind = never;
|
||||
export type IndentStyle = never;
|
||||
export type JsxEmit = never;
|
||||
|
||||
+32264
-31871
File diff suppressed because it is too large
Load Diff
+34381
-32033
File diff suppressed because it is too large
Load Diff
Vendored
+939
-685
File diff suppressed because it is too large
Load Diff
+37069
-34736
File diff suppressed because it is too large
Load Diff
Vendored
+803
-446
File diff suppressed because it is too large
Load Diff
+40242
-37611
File diff suppressed because it is too large
Load Diff
Vendored
+803
-446
File diff suppressed because it is too large
Load Diff
+40242
-37611
File diff suppressed because it is too large
Load Diff
+11502
-2323
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,7 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
"use strict";
|
||||
if (process.argv.length < 3) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
+3
-4
@@ -2,7 +2,7 @@
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "http://typescriptlang.org/",
|
||||
"version": "2.4.0",
|
||||
"version": "2.5.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
@@ -34,7 +34,7 @@
|
||||
"@types/convert-source-map": "latest",
|
||||
"@types/del": "latest",
|
||||
"@types/glob": "latest",
|
||||
"@types/gulp": "latest",
|
||||
"@types/gulp": "3.X",
|
||||
"@types/gulp-concat": "latest",
|
||||
"@types/gulp-help": "latest",
|
||||
"@types/gulp-newer": "latest",
|
||||
@@ -52,7 +52,7 @@
|
||||
"chai": "latest",
|
||||
"convert-source-map": "latest",
|
||||
"del": "latest",
|
||||
"gulp": "latest",
|
||||
"gulp": "3.X",
|
||||
"gulp-clone": "latest",
|
||||
"gulp-concat": "latest",
|
||||
"gulp-help": "latest",
|
||||
@@ -60,7 +60,6 @@
|
||||
"gulp-newer": "latest",
|
||||
"gulp-sourcemaps": "latest",
|
||||
"gulp-typescript": "latest",
|
||||
"into-stream": "latest",
|
||||
"istanbul": "latest",
|
||||
"jake": "latest",
|
||||
"merge2": "latest",
|
||||
|
||||
@@ -113,7 +113,7 @@ class DeclarationsWalker {
|
||||
}
|
||||
}
|
||||
|
||||
function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string): string {
|
||||
function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptServicesDts: string) {
|
||||
const options = { target: ts.ScriptTarget.ES5, declaration: true, noResolve: true, types: <string[]>[], stripInternal: true };
|
||||
|
||||
/**
|
||||
@@ -163,14 +163,17 @@ function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string)
|
||||
protocolDts += "\nimport protocol = ts.server.protocol;";
|
||||
protocolDts += "\nexport = protocol;";
|
||||
protocolDts += "\nexport as namespace protocol;";
|
||||
|
||||
// do sanity check and try to compile generated text as standalone program
|
||||
const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
|
||||
const diagnostics = [...sanityCheckProgram.getSyntacticDiagnostics(), ...sanityCheckProgram.getSemanticDiagnostics(), ...sanityCheckProgram.getGlobalDiagnostics()];
|
||||
|
||||
ts.sys.writeFile(outputFile, protocolDts);
|
||||
|
||||
if (diagnostics.length) {
|
||||
const flattenedDiagnostics = diagnostics.map(d => `${ts.flattenDiagnosticMessageText(d.messageText, "\n")} at ${d.file.fileName} line ${d.start}`).join("\n");
|
||||
throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
|
||||
}
|
||||
return protocolDts;
|
||||
}
|
||||
|
||||
if (process.argv.length < 5) {
|
||||
@@ -181,5 +184,4 @@ if (process.argv.length < 5) {
|
||||
const protocolTs = process.argv[2];
|
||||
const typeScriptServicesDts = process.argv[3];
|
||||
const outputFile = process.argv[4];
|
||||
const generatedProtocolDts = generateProtocolFile(protocolTs, typeScriptServicesDts);
|
||||
ts.sys.writeFile(outputFile, generatedProtocolDts);
|
||||
writeProtocolFile(outputFile, protocolTs, typeScriptServicesDts);
|
||||
|
||||
+34
-24
@@ -19,47 +19,57 @@ function main(): void {
|
||||
|
||||
// Acquire the version from the package.json file and modify it appropriately.
|
||||
const packageJsonFilePath = ts.normalizePath(sys.args[0]);
|
||||
const packageJsonContents = sys.readFile(packageJsonFilePath);
|
||||
const packageJsonValue: PackageJson = JSON.parse(packageJsonContents);
|
||||
const packageJsonValue: PackageJson = JSON.parse(sys.readFile(packageJsonFilePath));
|
||||
|
||||
const nightlyVersion = getNightlyVersionString(packageJsonValue.version);
|
||||
|
||||
// Modify the package.json structure
|
||||
packageJsonValue.version = nightlyVersion;
|
||||
const { majorMinor, patch } = parsePackageJsonVersion(packageJsonValue.version);
|
||||
const nightlyPatch = getNightlyPatch(patch);
|
||||
|
||||
// Acquire and modify the source file that exposes the version string.
|
||||
const tsFilePath = ts.normalizePath(sys.args[1]);
|
||||
const tsFileContents = sys.readFile(tsFilePath);
|
||||
const versionAssignmentRegExp = /export\s+const\s+version\s+=\s+".*";/;
|
||||
const modifiedTsFileContents = tsFileContents.replace(versionAssignmentRegExp, `export const version = "${nightlyVersion}";`);
|
||||
const tsFileContents = ts.sys.readFile(tsFilePath);
|
||||
const modifiedTsFileContents = updateTsFile(tsFilePath, tsFileContents, majorMinor, patch, nightlyPatch);
|
||||
|
||||
// Ensure we are actually changing something - the user probably wants to know that the update failed.
|
||||
if (tsFileContents === modifiedTsFileContents) {
|
||||
let err = `\n '${tsFilePath}' was not updated while configuring for a nightly publish.\n `;
|
||||
|
||||
if (tsFileContents.match(versionAssignmentRegExp)) {
|
||||
err += `Ensure that you have not already run this script; otherwise, erase your changes using 'git checkout -- "${tsFilePath}"'.`;
|
||||
}
|
||||
else {
|
||||
err += `The file seems to no longer have a string matching '${versionAssignmentRegExp}'.`;
|
||||
}
|
||||
|
||||
err += `Ensure that you have not already run this script; otherwise, erase your changes using 'git checkout -- "${tsFilePath}"'.`;
|
||||
throw err + "\n";
|
||||
}
|
||||
|
||||
// Finally write the changes to disk.
|
||||
// Modify the package.json structure
|
||||
packageJsonValue.version = `${majorMinor}.${nightlyPatch}`;
|
||||
sys.writeFile(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4))
|
||||
sys.writeFile(tsFilePath, modifiedTsFileContents);
|
||||
}
|
||||
|
||||
function getNightlyVersionString(versionString: string): string {
|
||||
// If the version string already contains "-nightly",
|
||||
// then get the base string and update based on that.
|
||||
const dashNightlyPos = versionString.indexOf("-dev");
|
||||
if (dashNightlyPos >= 0) {
|
||||
versionString = versionString.slice(0, dashNightlyPos);
|
||||
function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: string, patch: string, nightlyPatch: string): string {
|
||||
const majorMinorRgx = /export const versionMajorMinor = "(\d+\.\d+)"/;
|
||||
const majorMinorMatch = majorMinorRgx.exec(tsFileContents);
|
||||
ts.Debug.assert(majorMinorMatch !== null, "", () => `The file seems to no longer have a string matching '${majorMinorRgx}'.`);
|
||||
const parsedMajorMinor = majorMinorMatch[1];
|
||||
ts.Debug.assert(parsedMajorMinor === majorMinor, "versionMajorMinor does not match.", () => `${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`);
|
||||
|
||||
const versionRgx = /export const version = `\$\{versionMajorMinor\}\.(\d)`;/;
|
||||
const patchMatch = versionRgx.exec(tsFileContents);
|
||||
ts.Debug.assert(patchMatch !== null, "The file seems to no longer have a string matching", () => versionRgx.toString());
|
||||
const parsedPatch = patchMatch[1];
|
||||
if (parsedPatch !== patch) {
|
||||
throw new Error(`patch does not match. ${tsFilePath}: '${parsedPatch}; package.json: '${patch}'`);
|
||||
}
|
||||
|
||||
return tsFileContents.replace(versionRgx, `export const version = \`\${versionMajorMinor}.${nightlyPatch}\`;`);
|
||||
}
|
||||
|
||||
function parsePackageJsonVersion(versionString: string): { majorMinor: string, patch: string } {
|
||||
const versionRgx = /(\d+\.\d+)\.(\d+)($|\-)/;
|
||||
const match = versionString.match(versionRgx);
|
||||
ts.Debug.assert(match !== null, "package.json 'version' should match", () => versionRgx.toString());
|
||||
return { majorMinor: match[1], patch: match[2] };
|
||||
}
|
||||
|
||||
/** e.g. 0-dev.20170707 */
|
||||
function getNightlyPatch(plainPatch: string): string {
|
||||
// We're going to append a representation of the current time at the end of the current version.
|
||||
// String.prototype.toISOString() returns a 24-character string formatted as 'YYYY-MM-DDTHH:mm:ss.sssZ',
|
||||
// but we'd prefer to just remove separators and limit ourselves to YYYYMMDD.
|
||||
@@ -67,7 +77,7 @@ function getNightlyVersionString(versionString: string): string {
|
||||
const now = new Date();
|
||||
const timeStr = now.toISOString().replace(/:|T|\.|-/g, "").slice(0, 8);
|
||||
|
||||
return `${versionString}-dev.${timeStr}`;
|
||||
return `${plainPatch}-dev.${timeStr}`;
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -72,6 +72,7 @@ function runTests(taskConfigsFolder, run, options, cb) {
|
||||
current: undefined,
|
||||
start: undefined,
|
||||
end: undefined,
|
||||
catastrophicError: "",
|
||||
failures: []
|
||||
};
|
||||
partitions[index] = partition;
|
||||
@@ -86,9 +87,20 @@ function runTests(taskConfigsFolder, run, options, cb) {
|
||||
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();
|
||||
@@ -153,15 +165,17 @@ function runTests(taskConfigsFolder, run, options, cb) {
|
||||
}
|
||||
}
|
||||
|
||||
function onexit() {
|
||||
function onexit(code) {
|
||||
if (partition.end === undefined) {
|
||||
partition.end = Date.now();
|
||||
}
|
||||
|
||||
partition.duration = partition.end - partition.start;
|
||||
var summaryColor = partition.failed ? "fail" : "green";
|
||||
var summarySymbol = partition.failed ? Base.symbols.err : Base.symbols.ok;
|
||||
var summaryTests = (partition.passed === partition.tests ? partition.passed : partition.passed + "/" + partition.tests) + " passing";
|
||||
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;
|
||||
@@ -198,12 +212,34 @@ function runTests(taskConfigsFolder, run, options, cb) {
|
||||
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));
|
||||
@@ -223,6 +259,9 @@ function runTests(taskConfigsFolder, run, options, cb) {
|
||||
reporter.epilogue();
|
||||
}
|
||||
|
||||
if (catastrophicError !== "") {
|
||||
return cb(new Error(catastrophicError));
|
||||
}
|
||||
if (stats.failures) {
|
||||
return cb(new Error("Test failures reported: " + stats.failures));
|
||||
}
|
||||
|
||||
@@ -6,9 +6,7 @@ interface DiagnosticDetails {
|
||||
isEarly?: boolean;
|
||||
}
|
||||
|
||||
interface InputDiagnosticMessageTable {
|
||||
[msg: string]: DiagnosticDetails;
|
||||
}
|
||||
type InputDiagnosticMessageTable = ts.Map<DiagnosticDetails>;
|
||||
|
||||
function main(): void {
|
||||
var sys = ts.sys;
|
||||
@@ -28,101 +26,66 @@ function main(): void {
|
||||
var inputFilePath = sys.args[0].replace(/\\/g, "/");
|
||||
var inputStr = sys.readFile(inputFilePath);
|
||||
|
||||
var diagnosticMessages: InputDiagnosticMessageTable = JSON.parse(inputStr);
|
||||
var diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr);
|
||||
// Check that there are no duplicates.
|
||||
const seenNames = ts.createMap<true>();
|
||||
for (const name of Object.keys(diagnosticMessagesJson)) {
|
||||
if (seenNames.has(name))
|
||||
throw new Error(`Name ${name} appears twice`);
|
||||
seenNames.set(name, true);
|
||||
}
|
||||
|
||||
var names = Utilities.getObjectKeys(diagnosticMessages);
|
||||
var nameMap = buildUniqueNameMap(names);
|
||||
const diagnosticMessages: InputDiagnosticMessageTable = ts.createMapFromTemplate(diagnosticMessagesJson);
|
||||
|
||||
var infoFileOutput = buildInfoFileOutput(diagnosticMessages, nameMap);
|
||||
checkForUniqueCodes(names, diagnosticMessages);
|
||||
var infoFileOutput = buildInfoFileOutput(diagnosticMessages);
|
||||
checkForUniqueCodes(diagnosticMessages);
|
||||
writeFile("diagnosticInformationMap.generated.ts", infoFileOutput);
|
||||
|
||||
var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages, nameMap);
|
||||
var messageOutput = buildDiagnosticMessageOutput(diagnosticMessages);
|
||||
writeFile("diagnosticMessages.generated.json", messageOutput);
|
||||
}
|
||||
|
||||
function checkForUniqueCodes(messages: string[], diagnosticTable: InputDiagnosticMessageTable) {
|
||||
const originalMessageForCode: string[] = [];
|
||||
let numConflicts = 0;
|
||||
|
||||
for (const currentMessage of messages) {
|
||||
const code = diagnosticTable[currentMessage].code;
|
||||
|
||||
if (code in originalMessageForCode) {
|
||||
const originalMessage = originalMessageForCode[code];
|
||||
ts.sys.write("\x1b[91m"); // High intensity red.
|
||||
ts.sys.write("Error");
|
||||
ts.sys.write("\x1b[0m"); // Reset formatting.
|
||||
ts.sys.write(`: Diagnostic code '${code}' conflicts between "${originalMessage}" and "${currentMessage}".`);
|
||||
ts.sys.write(ts.sys.newLine + ts.sys.newLine);
|
||||
|
||||
numConflicts++;
|
||||
}
|
||||
else {
|
||||
originalMessageForCode[code] = currentMessage;
|
||||
}
|
||||
}
|
||||
|
||||
if (numConflicts > 0) {
|
||||
throw new Error(`Found ${numConflicts} conflict(s) in diagnostic codes.`);
|
||||
}
|
||||
function checkForUniqueCodes(diagnosticTable: InputDiagnosticMessageTable) {
|
||||
const allCodes: { [key: number]: true | undefined } = [];
|
||||
diagnosticTable.forEach(({ code }) => {
|
||||
if (allCodes[code])
|
||||
throw new Error(`Diagnostic code ${code} appears more than once.`);
|
||||
allCodes[code] = true;
|
||||
});
|
||||
}
|
||||
|
||||
function buildUniqueNameMap(names: string[]): ts.Map<string> {
|
||||
var nameMap = ts.createMap<string>();
|
||||
|
||||
var uniqueNames = NameGenerator.ensureUniqueness(names, /* isCaseSensitive */ false, /* isFixed */ undefined);
|
||||
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
nameMap.set(names[i], uniqueNames[i]);
|
||||
}
|
||||
|
||||
return nameMap;
|
||||
}
|
||||
|
||||
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: ts.Map<string>): string {
|
||||
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable): string {
|
||||
var result =
|
||||
'// <auto-generated />\r\n' +
|
||||
'/// <reference path="types.ts" />\r\n' +
|
||||
'/* @internal */\r\n' +
|
||||
'namespace ts {\r\n' +
|
||||
" function diag(code: number, category: DiagnosticCategory, key: string, message: string): DiagnosticMessage {\r\n" +
|
||||
" return { code, category, key, message };\r\n" +
|
||||
" }\r\n" +
|
||||
' export const Diagnostics = {\r\n';
|
||||
var names = Utilities.getObjectKeys(messageTable);
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
var name = names[i];
|
||||
var diagnosticDetails = messageTable[name];
|
||||
var propName = convertPropertyName(nameMap.get(name));
|
||||
|
||||
result +=
|
||||
' ' + propName +
|
||||
': { code: ' + diagnosticDetails.code +
|
||||
', category: DiagnosticCategory.' + diagnosticDetails.category +
|
||||
', key: "' + createKey(propName, diagnosticDetails.code) + '"' +
|
||||
', message: "' + name.replace(/[\"]/g, '\\"') + '"' +
|
||||
' },\r\n';
|
||||
}
|
||||
messageTable.forEach(({ code, category }, name) => {
|
||||
const propName = convertPropertyName(name);
|
||||
result += ` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}),\r\n`;
|
||||
});
|
||||
|
||||
result += ' };\r\n}';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable, nameMap: ts.Map<string>): string {
|
||||
var result =
|
||||
'{';
|
||||
var names = Utilities.getObjectKeys(messageTable);
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
var name = names[i];
|
||||
var diagnosticDetails = messageTable[name];
|
||||
var propName = convertPropertyName(nameMap.get(name));
|
||||
function buildDiagnosticMessageOutput(messageTable: InputDiagnosticMessageTable): string {
|
||||
let result = '{';
|
||||
messageTable.forEach(({ code }, name) => {
|
||||
const propName = convertPropertyName(name);
|
||||
result += `\r\n "${createKey(propName, code)}" : "${name.replace(/[\"]/g, '\\"')}",`;
|
||||
});
|
||||
|
||||
result += '\r\n "' + createKey(propName, diagnosticDetails.code) + '"' + ' : "' + name.replace(/[\"]/g, '\\"') + '"';
|
||||
if (i !== names.length - 1) {
|
||||
result += ',';
|
||||
}
|
||||
}
|
||||
// Shave trailing comma, then add newline and ending brace
|
||||
result = result.slice(0, result.length - 1) + '\r\n}';
|
||||
|
||||
result += '\r\n}';
|
||||
// Assert that we generated valid JSON
|
||||
JSON.parse(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -139,7 +102,6 @@ function convertPropertyName(origName: string): string {
|
||||
return /\w/.test(char) ? char : "_";
|
||||
}).join("");
|
||||
|
||||
|
||||
// get rid of all multi-underscores
|
||||
result = result.replace(/_+/g, "_");
|
||||
|
||||
@@ -152,93 +114,4 @@ function convertPropertyName(origName: string): string {
|
||||
return result;
|
||||
}
|
||||
|
||||
module NameGenerator {
|
||||
export function ensureUniqueness(names: string[], isCaseSensitive: boolean, isFixed?: boolean[]): string[]{
|
||||
if (!isFixed) {
|
||||
isFixed = names.map(() => false)
|
||||
}
|
||||
|
||||
var names = names.slice();
|
||||
ensureUniquenessInPlace(names, isCaseSensitive, isFixed);
|
||||
return names;
|
||||
}
|
||||
|
||||
function ensureUniquenessInPlace(names: string[], isCaseSensitive: boolean, isFixed: boolean[]): void {
|
||||
for (var i = 0; i < names.length; i++) {
|
||||
var name = names[i];
|
||||
var collisionIndices = Utilities.collectMatchingIndices(name, names, isCaseSensitive);
|
||||
|
||||
// We will always have one "collision" because getCollisionIndices returns the index of name itself as well;
|
||||
// so if we only have one collision, then there are no issues.
|
||||
if (collisionIndices.length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
handleCollisions(name, names, isFixed, collisionIndices, isCaseSensitive);
|
||||
}
|
||||
}
|
||||
|
||||
function handleCollisions(name: string, proposedNames: string[], isFixed: boolean[], collisionIndices: number[], isCaseSensitive: boolean): void {
|
||||
var suffix = 1;
|
||||
|
||||
for (var i = 0; i < collisionIndices.length; i++) {
|
||||
var collisionIndex = collisionIndices[i];
|
||||
|
||||
if (isFixed[collisionIndex]) {
|
||||
// can't do anything about this name.
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
var newName = name + suffix;
|
||||
suffix++;
|
||||
|
||||
// Check if we've synthesized a unique name, and if so
|
||||
// replace the conflicting name with the new one.
|
||||
if (!proposedNames.some(name => Utilities.stringEquals(name, newName, isCaseSensitive))) {
|
||||
proposedNames[collisionIndex] = newName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module Utilities {
|
||||
/// Return a list of all indices where a string occurs.
|
||||
export function collectMatchingIndices(name: string, proposedNames: string[], isCaseSensitive: boolean): number[] {
|
||||
var matchingIndices: number[] = [];
|
||||
|
||||
for (var i = 0; i < proposedNames.length; i++) {
|
||||
if (stringEquals(name, proposedNames[i], isCaseSensitive)) {
|
||||
matchingIndices.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
return matchingIndices;
|
||||
}
|
||||
|
||||
export function stringEquals(s1: string, s2: string, caseSensitive: boolean): boolean {
|
||||
if (caseSensitive) {
|
||||
s1 = s1.toLowerCase();
|
||||
s2 = s2.toLowerCase();
|
||||
}
|
||||
|
||||
return s1 == s2;
|
||||
}
|
||||
|
||||
// Like Object.keys
|
||||
export function getObjectKeys(obj: any): string[] {
|
||||
var result: string[] = [];
|
||||
|
||||
for (var name in obj) {
|
||||
if (obj.hasOwnProperty(name)) {
|
||||
result.push(name);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -27,7 +27,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
|
||||
/** Skip certain function/method names whose parameter names are not informative. */
|
||||
function shouldIgnoreCalledExpression(expression: ts.Expression): boolean {
|
||||
if (expression.kind === ts.SyntaxKind.PropertyAccessExpression) {
|
||||
const methodName = (expression as ts.PropertyAccessExpression).name.text;
|
||||
const methodName = (expression as ts.PropertyAccessExpression).name.text as string;
|
||||
if (methodName.indexOf("set") === 0) {
|
||||
return true;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
|
||||
}
|
||||
}
|
||||
else if (expression.kind === ts.SyntaxKind.Identifier) {
|
||||
const functionName = (expression as ts.Identifier).text;
|
||||
const functionName = (expression as ts.Identifier).text as string;
|
||||
if (functionName.indexOf("set") === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
|
||||
ts.forEachChild(node, recur);
|
||||
}
|
||||
|
||||
function check(types: ts.TypeNode[]): void {
|
||||
function check(types: ReadonlyArray<ts.TypeNode>): void {
|
||||
let expectedStart = types[0].end + 2; // space, | or &
|
||||
for (let i = 1; i < types.length; i++) {
|
||||
const currentType = types[i];
|
||||
|
||||
Vendored
-8
@@ -13,13 +13,5 @@ declare module "gulp-insert" {
|
||||
export function transform(cb: (contents: string, file: {path: string, relative: string}) => string): NodeJS.ReadWriteStream; // file is a vinyl file
|
||||
}
|
||||
|
||||
declare module "into-stream" {
|
||||
function IntoStream(content: string | Buffer | (string | Buffer)[]): NodeJS.ReadableStream;
|
||||
namespace IntoStream {
|
||||
export function obj(content: any): NodeJS.ReadableStream
|
||||
}
|
||||
export = IntoStream;
|
||||
}
|
||||
|
||||
declare module "sorcery";
|
||||
declare module "travis-fold";
|
||||
|
||||
+142
-153
@@ -10,7 +10,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
interface ActiveLabel {
|
||||
name: string;
|
||||
name: __String;
|
||||
breakTarget: FlowLabel;
|
||||
continueTarget: FlowLabel;
|
||||
referenced: boolean;
|
||||
@@ -132,8 +132,9 @@ namespace ts {
|
||||
let inStrictMode: boolean;
|
||||
|
||||
let symbolCount = 0;
|
||||
let Symbol: { new (flags: SymbolFlags, name: string): Symbol };
|
||||
let classifiableNames: Map<string>;
|
||||
|
||||
let Symbol: { new (flags: SymbolFlags, name: __String): Symbol };
|
||||
let classifiableNames: UnderscoreEscapedMap<true>;
|
||||
|
||||
const unreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
|
||||
const reportedUnreachableFlow: FlowNode = { flags: FlowFlags.Unreachable };
|
||||
@@ -147,7 +148,7 @@ namespace ts {
|
||||
options = opts;
|
||||
languageVersion = getEmitScriptTarget(options);
|
||||
inStrictMode = bindInStrictMode(file, opts);
|
||||
classifiableNames = createMap<string>();
|
||||
classifiableNames = createUnderscoreEscapedMap<true>();
|
||||
symbolCount = 0;
|
||||
skipTransformFlagAggregation = file.isDeclarationFile;
|
||||
|
||||
@@ -191,7 +192,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createSymbol(flags: SymbolFlags, name: string): Symbol {
|
||||
function createSymbol(flags: SymbolFlags, name: __String): Symbol {
|
||||
symbolCount++;
|
||||
return new Symbol(flags, name);
|
||||
}
|
||||
@@ -207,11 +208,11 @@ namespace ts {
|
||||
symbol.declarations.push(node);
|
||||
|
||||
if (symbolFlags & SymbolFlags.HasExports && !symbol.exports) {
|
||||
symbol.exports = createMap<Symbol>();
|
||||
symbol.exports = createSymbolTable();
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.HasMembers && !symbol.members) {
|
||||
symbol.members = createMap<Symbol>();
|
||||
symbol.members = createSymbolTable();
|
||||
}
|
||||
|
||||
if (symbolFlags & SymbolFlags.Value) {
|
||||
@@ -226,67 +227,68 @@ namespace ts {
|
||||
|
||||
// Should not be called on a declaration with a computed property name,
|
||||
// unless it is a well known Symbol.
|
||||
function getDeclarationName(node: Declaration): string {
|
||||
function getDeclarationName(node: Declaration): __String {
|
||||
const name = getNameOfDeclaration(node);
|
||||
if (name) {
|
||||
if (isAmbientModule(node)) {
|
||||
return isGlobalScopeAugmentation(<ModuleDeclaration>node) ? "__global" : `"${(<LiteralExpression>name).text}"`;
|
||||
const moduleName = getTextOfIdentifierOrLiteral(<Identifier | LiteralExpression>name);
|
||||
return (isGlobalScopeAugmentation(<ModuleDeclaration>node) ? "__global" : `"${moduleName}"`) as __String;
|
||||
}
|
||||
if (name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const nameExpression = (<ComputedPropertyName>name).expression;
|
||||
// treat computed property names where expression is string/numeric literal as just string/numeric literal
|
||||
if (isStringOrNumericLiteral(nameExpression)) {
|
||||
return nameExpression.text;
|
||||
return escapeLeadingUnderscores(nameExpression.text);
|
||||
}
|
||||
|
||||
Debug.assert(isWellKnownSymbolSyntactically(nameExpression));
|
||||
return getPropertyNameForKnownSymbolName((<PropertyAccessExpression>nameExpression).name.text);
|
||||
return getPropertyNameForKnownSymbolName(unescapeLeadingUnderscores((<PropertyAccessExpression>nameExpression).name.escapedText));
|
||||
}
|
||||
return (<Identifier | LiteralExpression>name).text;
|
||||
return getEscapedTextOfIdentifierOrLiteral(<Identifier | LiteralExpression>name);
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Constructor:
|
||||
return "__constructor";
|
||||
return InternalSymbolName.Constructor;
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.CallSignature:
|
||||
return "__call";
|
||||
return InternalSymbolName.Call;
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
return "__new";
|
||||
return InternalSymbolName.New;
|
||||
case SyntaxKind.IndexSignature:
|
||||
return "__index";
|
||||
return InternalSymbolName.Index;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
return "__export";
|
||||
return InternalSymbolName.ExportStar;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return (<ExportAssignment>node).isExportEquals ? "export=" : "default";
|
||||
return (<ExportAssignment>node).isExportEquals ? InternalSymbolName.ExportEquals : InternalSymbolName.Default;
|
||||
case SyntaxKind.BinaryExpression:
|
||||
if (getSpecialPropertyAssignmentKind(node as BinaryExpression) === SpecialPropertyAssignmentKind.ModuleExports) {
|
||||
// module.exports = ...
|
||||
return "export=";
|
||||
return InternalSymbolName.ExportEquals;
|
||||
}
|
||||
Debug.fail("Unknown binary declaration kind");
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return hasModifier(node, ModifierFlags.Default) ? "default" : undefined;
|
||||
return (hasModifier(node, ModifierFlags.Default) ? InternalSymbolName.Default : undefined);
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
return isJSDocConstructSignature(node) ? "__new" : "__call";
|
||||
return (isJSDocConstructSignature(node) ? InternalSymbolName.New : InternalSymbolName.Call);
|
||||
case SyntaxKind.Parameter:
|
||||
// Parameters with names are handled at the top of this function. Parameters
|
||||
// without names can only come from JSDocFunctionTypes.
|
||||
Debug.assert(node.parent.kind === SyntaxKind.JSDocFunctionType);
|
||||
const functionType = <JSDocFunctionType>node.parent;
|
||||
const index = indexOf(functionType.parameters, node);
|
||||
return "arg" + index;
|
||||
return "arg" + index as __String;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
const parentNode = node.parent && node.parent.parent;
|
||||
let nameFromParentNode: string;
|
||||
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 (nameIdentifier.kind === SyntaxKind.Identifier) {
|
||||
nameFromParentNode = (<Identifier>nameIdentifier).text;
|
||||
if (isIdentifier(nameIdentifier)) {
|
||||
nameFromParentNode = nameIdentifier.escapedText;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -295,7 +297,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getDisplayName(node: Declaration): string {
|
||||
return (node as NamedDeclaration).name ? declarationNameToString((node as NamedDeclaration).name) : getDeclarationName(node);
|
||||
return (node as NamedDeclaration).name ? declarationNameToString((node as NamedDeclaration).name) : unescapeLeadingUnderscores(getDeclarationName(node));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -306,17 +308,17 @@ namespace ts {
|
||||
* @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
|
||||
* @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
|
||||
*/
|
||||
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags): Symbol {
|
||||
function declareSymbol(symbolTable: SymbolTable, parent: Symbol, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags, isReplaceableByMethod?: boolean): Symbol {
|
||||
Debug.assert(!hasDynamicName(node));
|
||||
|
||||
const isDefaultExport = hasModifier(node, ModifierFlags.Default);
|
||||
|
||||
// The exported symbol for an export default function/class node is always named "default"
|
||||
const name = isDefaultExport && parent ? "default" : getDeclarationName(node);
|
||||
const name = isDefaultExport && parent ? InternalSymbolName.Default : getDeclarationName(node);
|
||||
|
||||
let symbol: Symbol;
|
||||
if (name === undefined) {
|
||||
symbol = createSymbol(SymbolFlags.None, "__missing");
|
||||
symbol = createSymbol(SymbolFlags.None, InternalSymbolName.Missing);
|
||||
}
|
||||
else {
|
||||
// Check and see if the symbol table already has a symbol with this name. If not,
|
||||
@@ -343,15 +345,20 @@ namespace ts {
|
||||
// you have multiple 'vars' with the same name in the same container). In this case
|
||||
// just add this node into the declarations list of the symbol.
|
||||
symbol = symbolTable.get(name);
|
||||
|
||||
if (includes & SymbolFlags.Classifiable) {
|
||||
classifiableNames.set(name, true);
|
||||
}
|
||||
|
||||
if (!symbol) {
|
||||
symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name));
|
||||
if (isReplaceableByMethod) symbol.isReplaceableByMethod = true;
|
||||
}
|
||||
|
||||
if (name && (includes & SymbolFlags.Classifiable)) {
|
||||
classifiableNames.set(name, name);
|
||||
else if (isReplaceableByMethod && !symbol.isReplaceableByMethod) {
|
||||
// A symbol already exists, so don't add this as a declaration.
|
||||
return symbol;
|
||||
}
|
||||
|
||||
if (symbol.flags & excludes) {
|
||||
else if (symbol.flags & excludes) {
|
||||
if (symbol.isReplaceableByMethod) {
|
||||
// Javascript constructor-declared symbols can be discarded in favor of
|
||||
// prototype symbols like methods.
|
||||
@@ -414,9 +421,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue,
|
||||
// ExportType, or ExportContainer flag, and an associated export symbol with all the correct flags set
|
||||
// on it. There are 2 main reasons:
|
||||
// Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue flag,
|
||||
// and an associated export symbol with all the correct flags set on it. There are 2 main reasons:
|
||||
//
|
||||
// 1. We treat locals and exports of the same name as mutually exclusive within a container.
|
||||
// That means the binder will issue a Duplicate Identifier error if you mix locals and exports
|
||||
@@ -436,10 +442,7 @@ namespace ts {
|
||||
(node as JSDocTypedefTag).name.kind === SyntaxKind.Identifier &&
|
||||
((node as JSDocTypedefTag).name as Identifier).isInJSDocNamespace;
|
||||
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypedefInJSDocNamespace) {
|
||||
const exportKind =
|
||||
(symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
|
||||
(symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
|
||||
(symbolFlags & SymbolFlags.Namespace ? SymbolFlags.ExportNamespace : 0);
|
||||
const exportKind = symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0;
|
||||
const local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes);
|
||||
local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
node.localSymbol = local;
|
||||
@@ -481,7 +484,7 @@ namespace ts {
|
||||
if (containerFlags & ContainerFlags.IsContainer) {
|
||||
container = blockScopeContainer = node;
|
||||
if (containerFlags & ContainerFlags.HasLocals) {
|
||||
container.locals = createMap<Symbol>();
|
||||
container.locals = createSymbolTable();
|
||||
}
|
||||
addToContainerChain(container);
|
||||
}
|
||||
@@ -595,7 +598,19 @@ 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.
|
||||
forEach(node.jsDoc, bind);
|
||||
if (node.jsDoc) {
|
||||
if (isInJavaScriptFile(node)) {
|
||||
for (const j of node.jsDoc) {
|
||||
bind(j);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const j of node.jsDoc) {
|
||||
setParentPointers(node, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (checkUnreachable(node)) {
|
||||
bindEachChild(node);
|
||||
return;
|
||||
@@ -612,7 +627,7 @@ namespace ts {
|
||||
break;
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
bindForInOrForOfStatement(<ForInStatement | ForOfStatement>node);
|
||||
bindForInOrForOfStatement(<ForInOrOfStatement>node);
|
||||
break;
|
||||
case SyntaxKind.IfStatement:
|
||||
bindIfStatement(<IfStatement>node);
|
||||
@@ -950,7 +965,7 @@ namespace ts {
|
||||
currentFlow = finishFlowLabel(postLoopLabel);
|
||||
}
|
||||
|
||||
function bindForInOrForOfStatement(node: ForInStatement | ForOfStatement): void {
|
||||
function bindForInOrForOfStatement(node: ForInOrOfStatement): void {
|
||||
const preLoopLabel = createLoopLabel();
|
||||
const postLoopLabel = createBranchLabel();
|
||||
addAntecedent(preLoopLabel, currentFlow);
|
||||
@@ -994,7 +1009,7 @@ namespace ts {
|
||||
currentFlow = unreachableFlow;
|
||||
}
|
||||
|
||||
function findActiveLabel(name: string) {
|
||||
function findActiveLabel(name: __String) {
|
||||
if (activeLabels) {
|
||||
for (const label of activeLabels) {
|
||||
if (label.name === name) {
|
||||
@@ -1016,7 +1031,7 @@ namespace ts {
|
||||
function bindBreakOrContinueStatement(node: BreakOrContinueStatement): void {
|
||||
bind(node.label);
|
||||
if (node.label) {
|
||||
const activeLabel = findActiveLabel(node.label.text);
|
||||
const activeLabel = findActiveLabel(node.label.escapedText);
|
||||
if (activeLabel) {
|
||||
activeLabel.referenced = true;
|
||||
bindBreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget);
|
||||
@@ -1157,8 +1172,8 @@ namespace ts {
|
||||
bindEach(node.statements);
|
||||
}
|
||||
|
||||
function pushActiveLabel(name: string, breakTarget: FlowLabel, continueTarget: FlowLabel): ActiveLabel {
|
||||
const activeLabel = {
|
||||
function pushActiveLabel(name: __String, breakTarget: FlowLabel, continueTarget: FlowLabel): ActiveLabel {
|
||||
const activeLabel: ActiveLabel = {
|
||||
name,
|
||||
breakTarget,
|
||||
continueTarget,
|
||||
@@ -1177,7 +1192,7 @@ namespace ts {
|
||||
const postStatementLabel = createBranchLabel();
|
||||
bind(node.label);
|
||||
addAntecedent(preStatementLabel, currentFlow);
|
||||
const activeLabel = pushActiveLabel(node.label.text, postStatementLabel, preStatementLabel);
|
||||
const activeLabel = pushActiveLabel(node.label.escapedText, postStatementLabel, preStatementLabel);
|
||||
bind(node.statement);
|
||||
popActiveLabel();
|
||||
if (!activeLabel.referenced && !options.allowUnusedLabels) {
|
||||
@@ -1317,7 +1332,7 @@ namespace ts {
|
||||
function bindInitializedVariableFlow(node: VariableDeclaration | ArrayBindingElement) {
|
||||
const name = !isOmittedExpression(node) ? node.name : undefined;
|
||||
if (isBindingPattern(name)) {
|
||||
for (const child of <ArrayBindingElement[]>name.elements) {
|
||||
for (const child of name.elements) {
|
||||
bindInitializedVariableFlow(child);
|
||||
}
|
||||
}
|
||||
@@ -1328,7 +1343,7 @@ namespace ts {
|
||||
|
||||
function bindVariableDeclarationFlow(node: VariableDeclaration) {
|
||||
bindEachChild(node);
|
||||
if (node.initializer || node.parent.parent.kind === SyntaxKind.ForInStatement || node.parent.parent.kind === SyntaxKind.ForOfStatement) {
|
||||
if (node.initializer || isForInOrOfStatement(node.parent.parent)) {
|
||||
bindInitializedVariableFlow(node);
|
||||
}
|
||||
}
|
||||
@@ -1385,14 +1400,12 @@ namespace ts {
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return ContainerFlags.IsContainer;
|
||||
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
return ContainerFlags.IsContainer | ContainerFlags.IsInterface;
|
||||
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.MappedType:
|
||||
@@ -1412,9 +1425,10 @@ namespace ts {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
return ContainerFlags.IsContainer | ContainerFlags.IsControlFlowContainer | ContainerFlags.HasLocals | ContainerFlags.IsFunctionLike;
|
||||
|
||||
@@ -1490,10 +1504,9 @@ namespace ts {
|
||||
return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes);
|
||||
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.JsxAttributes:
|
||||
// Interface/Object-types always have their children added to the 'members' of
|
||||
// their container. They are only accessible through an instance of their
|
||||
@@ -1521,7 +1534,7 @@ namespace ts {
|
||||
// All the children of these container types are never visible through another
|
||||
// symbol (i.e. through another symbol's 'exports' or 'members'). Instead,
|
||||
// they're only accessed 'lexically' (i.e. from code that exists underneath
|
||||
// their container in the tree. To accomplish this, we simply add their declared
|
||||
// their container in the tree). To accomplish this, we simply add their declared
|
||||
// symbol to the 'locals' of the container. These symbols can then be found as
|
||||
// the type checker walks up the containers, checking them for matching names.
|
||||
return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
@@ -1633,10 +1646,10 @@ namespace ts {
|
||||
const symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node));
|
||||
addDeclarationToSymbol(symbol, node, SymbolFlags.Signature);
|
||||
|
||||
const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type");
|
||||
const typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, InternalSymbolName.Type);
|
||||
addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral);
|
||||
typeLiteralSymbol.members = createMap<Symbol>();
|
||||
typeLiteralSymbol.members.set(symbol.name, symbol);
|
||||
typeLiteralSymbol.members = createSymbolTable();
|
||||
typeLiteralSymbol.members.set(symbol.escapedName, symbol);
|
||||
}
|
||||
|
||||
function bindObjectLiteralExpression(node: ObjectLiteralExpression) {
|
||||
@@ -1646,14 +1659,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (inStrictMode) {
|
||||
const seen = createMap<ElementKind>();
|
||||
const seen = createUnderscoreEscapedMap<ElementKind>();
|
||||
|
||||
for (const prop of node.properties) {
|
||||
if (prop.kind === SyntaxKind.SpreadAssignment || prop.name.kind !== SyntaxKind.Identifier) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const identifier = <Identifier>prop.name;
|
||||
const identifier = prop.name;
|
||||
|
||||
// ECMA-262 11.1.5 Object Initializer
|
||||
// If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true
|
||||
@@ -1667,9 +1680,9 @@ namespace ts {
|
||||
? ElementKind.Property
|
||||
: ElementKind.Accessor;
|
||||
|
||||
const existingKind = seen.get(identifier.text);
|
||||
const existingKind = seen.get(identifier.escapedText);
|
||||
if (!existingKind) {
|
||||
seen.set(identifier.text, currentKind);
|
||||
seen.set(identifier.escapedText, currentKind);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1681,18 +1694,18 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object");
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, InternalSymbolName.Object);
|
||||
}
|
||||
|
||||
function bindJsxAttributes(node: JsxAttributes) {
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__jsxAttributes");
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, InternalSymbolName.JSXAttributes);
|
||||
}
|
||||
|
||||
function bindJsxAttribute(node: JsxAttribute, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
|
||||
function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) {
|
||||
function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: __String) {
|
||||
const symbol = createSymbol(symbolFlags, name);
|
||||
addDeclarationToSymbol(symbol, node, symbolFlags);
|
||||
}
|
||||
@@ -1710,7 +1723,7 @@ namespace ts {
|
||||
// falls through
|
||||
default:
|
||||
if (!blockScopeContainer.locals) {
|
||||
blockScopeContainer.locals = createMap<Symbol>();
|
||||
blockScopeContainer.locals = createSymbolTable();
|
||||
addToContainerChain(blockScopeContainer);
|
||||
}
|
||||
declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes);
|
||||
@@ -1779,8 +1792,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isEvalOrArgumentsIdentifier(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.Identifier &&
|
||||
((<Identifier>node).text === "eval" || (<Identifier>node).text === "arguments");
|
||||
return isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments");
|
||||
}
|
||||
|
||||
function checkStrictModeEvalOrArguments(contextNode: Node, name: Node) {
|
||||
@@ -1791,7 +1803,7 @@ namespace ts {
|
||||
// otherwise report generic error message.
|
||||
const span = getErrorSpanForNode(file, name);
|
||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length,
|
||||
getStrictModeEvalOrArgumentsMessage(contextNode), identifier.text));
|
||||
getStrictModeEvalOrArgumentsMessage(contextNode), unescapeLeadingUnderscores(identifier.escapedText)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1883,10 +1895,6 @@ namespace ts {
|
||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
|
||||
}
|
||||
|
||||
function getDestructuringParameterName(node: Declaration) {
|
||||
return "__" + indexOf((<SignatureDeclaration>node.parent).parameters, node);
|
||||
}
|
||||
|
||||
function bind(node: Node): void {
|
||||
if (!node) {
|
||||
return;
|
||||
@@ -1903,7 +1911,7 @@ namespace ts {
|
||||
// Here the current node is "foo", which is a container, but the scope of "MyType" should
|
||||
// not be inside "foo". Therefore we always bind @typedef before bind the parent node,
|
||||
// and skip binding this tag later when binding all the other jsdoc tags.
|
||||
bindJSDocTypedefTagIfAny(node);
|
||||
if (isInJavaScriptFile(node)) bindJSDocTypedefTagIfAny(node);
|
||||
|
||||
// First we bind declaration nodes to a symbol if possible. We'll both create a symbol
|
||||
// and then potentially add the symbol to an appropriate symbol table. Possible
|
||||
@@ -1991,7 +1999,7 @@ namespace ts {
|
||||
// for typedef type names with namespaces, bind the new jsdoc type symbol here
|
||||
// because it requires all containing namespaces to be in effect, namely the
|
||||
// current "blockScopeContainer" needs to be set to its immediate namespace parent.
|
||||
if (isInJavaScriptFile(node) && (<Identifier>node).isInJSDocNamespace) {
|
||||
if ((<Identifier>node).isInJSDocNamespace) {
|
||||
let parentNode = node.parent;
|
||||
while (parentNode && parentNode.kind !== SyntaxKind.JSDocTypedefTag) {
|
||||
parentNode = parentNode.parent;
|
||||
@@ -2057,8 +2065,10 @@ namespace ts {
|
||||
case SyntaxKind.Parameter:
|
||||
return bindParameter(<ParameterDeclaration>node);
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return bindVariableDeclarationOrBindingElement(<VariableDeclaration>node);
|
||||
case SyntaxKind.BindingElement:
|
||||
return bindVariableDeclarationOrBindingElement(<VariableDeclaration | BindingElement>node);
|
||||
node.flowNode = currentFlow;
|
||||
return bindVariableDeclarationOrBindingElement(<BindingElement>node);
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
return bindPropertyWorker(node as PropertyDeclaration | PropertySignature);
|
||||
@@ -2068,22 +2078,6 @@ namespace ts {
|
||||
case SyntaxKind.EnumMember:
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.EnumMember, SymbolFlags.EnumMemberExcludes);
|
||||
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
let root = container;
|
||||
let hasRest = false;
|
||||
while (root.parent) {
|
||||
if (root.kind === SyntaxKind.ObjectLiteralExpression &&
|
||||
root.parent.kind === SyntaxKind.BinaryExpression &&
|
||||
(root.parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
(root.parent as BinaryExpression).left === root) {
|
||||
hasRest = true;
|
||||
break;
|
||||
}
|
||||
root = root.parent;
|
||||
}
|
||||
return;
|
||||
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
@@ -2105,11 +2099,13 @@ namespace ts {
|
||||
case SyntaxKind.SetAccessor:
|
||||
return bindPropertyOrMethodOrAccessor(<Declaration>node, SymbolFlags.SetAccessor, SymbolFlags.SetAccessorExcludes);
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
return bindFunctionOrConstructorType(<SignatureDeclaration>node);
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.MappedType:
|
||||
return bindAnonymousTypeWorker(node as TypeLiteralNode | MappedTypeNode);
|
||||
return bindAnonymousTypeWorker(node as TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral);
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return bindObjectLiteralExpression(<ObjectLiteralExpression>node);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
@@ -2136,7 +2132,6 @@ namespace ts {
|
||||
return bindEnumDeclaration(<EnumDeclaration>node);
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return bindModuleDeclaration(<ModuleDeclaration>node);
|
||||
|
||||
// Jsx-attributes
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return bindJsxAttributes(<JsxAttributes>node);
|
||||
@@ -2168,25 +2163,17 @@ namespace ts {
|
||||
case SyntaxKind.ModuleBlock:
|
||||
return updateStrictModeStatementList((<Block | ModuleBlock>node).statements);
|
||||
|
||||
default:
|
||||
if (isInJavaScriptFile(node)) return bindJSDocWorker(node);
|
||||
}
|
||||
}
|
||||
|
||||
function bindJSDocWorker(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JSDocRecordMember:
|
||||
return bindPropertyWorker(node as JSDocRecordMember);
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
if (node.parent.kind !== SyntaxKind.JSDocTypeLiteral) {
|
||||
break;
|
||||
}
|
||||
// falls through
|
||||
case SyntaxKind.JSDocPropertyTag:
|
||||
return declareSymbolAndAddToSymbolTable(node as JSDocPropertyTag,
|
||||
(node as JSDocPropertyTag).isBracketed || ((node as JSDocPropertyTag).typeExpression && (node as JSDocPropertyTag).typeExpression.type.kind === SyntaxKind.JSDocOptionalType) ?
|
||||
SymbolFlags.Property | SymbolFlags.Optional : SymbolFlags.Property,
|
||||
SymbolFlags.PropertyExcludes);
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
return bindFunctionOrConstructorType(<SignatureDeclaration>node);
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
return bindAnonymousTypeWorker(node as JSDocTypeLiteral | JSDocRecordType);
|
||||
const propTag = node as JSDocPropertyLikeTag;
|
||||
const flags = propTag.isBracketed || propTag.typeExpression.type.kind === SyntaxKind.JSDocOptionalType ?
|
||||
SymbolFlags.Property | SymbolFlags.Optional :
|
||||
SymbolFlags.Property;
|
||||
return declareSymbolAndAddToSymbolTable(propTag, flags, SymbolFlags.PropertyExcludes);
|
||||
case SyntaxKind.JSDocTypedefTag: {
|
||||
const { fullName } = node as JSDocTypedefTag;
|
||||
if (!fullName || fullName.kind === SyntaxKind.Identifier) {
|
||||
@@ -2201,8 +2188,8 @@ namespace ts {
|
||||
return bindPropertyOrMethodOrAccessor(node, SymbolFlags.Property | (node.questionToken ? SymbolFlags.Optional : SymbolFlags.None), SymbolFlags.PropertyExcludes);
|
||||
}
|
||||
|
||||
function bindAnonymousTypeWorker(node: TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral | JSDocRecordType) {
|
||||
return bindAnonymousDeclaration(<Declaration>node, SymbolFlags.TypeLiteral, "__type");
|
||||
function bindAnonymousTypeWorker(node: TypeLiteralNode | MappedTypeNode | JSDocTypeLiteral) {
|
||||
return bindAnonymousDeclaration(<Declaration>node, SymbolFlags.TypeLiteral, InternalSymbolName.Type);
|
||||
}
|
||||
|
||||
function checkTypePredicate(node: TypePredicateNode) {
|
||||
@@ -2224,7 +2211,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindSourceFileAsExternalModule() {
|
||||
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"`);
|
||||
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"` as __String);
|
||||
}
|
||||
|
||||
function bindExportAssignment(node: ExportAssignment | BinaryExpression) {
|
||||
@@ -2268,7 +2255,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
file.symbol.globalExports = file.symbol.globalExports || createMap<Symbol>();
|
||||
file.symbol.globalExports = file.symbol.globalExports || createSymbolTable();
|
||||
declareSymbol(file.symbol.globalExports, file.symbol, node, SymbolFlags.Alias, SymbolFlags.AliasExcludes);
|
||||
}
|
||||
|
||||
@@ -2302,7 +2289,7 @@ namespace ts {
|
||||
// When we create a property via 'exports.foo = bar', the 'exports.foo' property access
|
||||
// expression is the declaration
|
||||
setCommonJsModuleIndicator(node);
|
||||
declareSymbol(file.symbol.exports, file.symbol, <PropertyAccessExpression>node.left, SymbolFlags.Property | SymbolFlags.Export, SymbolFlags.None);
|
||||
declareSymbol(file.symbol.exports, file.symbol, <PropertyAccessExpression>node.left, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None);
|
||||
}
|
||||
|
||||
function isExportsOrModuleExportsOrAlias(node: Node): boolean {
|
||||
@@ -2312,21 +2299,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isNameOfExportsOrModuleExportsAliasDeclaration(node: Node) {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
const symbol = lookupSymbolForName((<Identifier>node).text);
|
||||
if (symbol && symbol.valueDeclaration && symbol.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
|
||||
const declaration = symbol.valueDeclaration as VariableDeclaration;
|
||||
if (declaration.initializer) {
|
||||
return isExportsOrModuleExportsOrAliasOrAssignemnt(declaration.initializer);
|
||||
}
|
||||
}
|
||||
if (isIdentifier(node)) {
|
||||
const symbol = lookupSymbolForName(node.escapedText);
|
||||
return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) &&
|
||||
symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isExportsOrModuleExportsOrAliasOrAssignemnt(node: Node): boolean {
|
||||
function isExportsOrModuleExportsOrAliasOrAssignment(node: Node): boolean {
|
||||
return isExportsOrModuleExportsOrAlias(node) ||
|
||||
(isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignemnt(node.left) || isExportsOrModuleExportsOrAliasOrAssignemnt(node.right)));
|
||||
(isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignment(node.left) || isExportsOrModuleExportsOrAliasOrAssignment(node.right)));
|
||||
}
|
||||
|
||||
function bindModuleExportsAssignment(node: BinaryExpression) {
|
||||
@@ -2343,7 +2326,7 @@ namespace ts {
|
||||
|
||||
// 'module.exports = expr' assignment
|
||||
setCommonJsModuleIndicator(node);
|
||||
declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.Property | SymbolFlags.Export | SymbolFlags.ValueModule, SymbolFlags.None);
|
||||
declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule, SymbolFlags.None);
|
||||
}
|
||||
|
||||
function bindThisPropertyAssignment(node: BinaryExpression) {
|
||||
@@ -2353,7 +2336,7 @@ namespace ts {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
// Declare a 'member' if the container is an ES5 class or ES6 constructor
|
||||
container.symbol.members = container.symbol.members || createMap<Symbol>();
|
||||
container.symbol.members = container.symbol.members || createSymbolTable();
|
||||
// It's acceptable for multiple 'this' assignments of the same identifier to occur
|
||||
declareSymbol(container.symbol.members, container.symbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property);
|
||||
break;
|
||||
@@ -2366,11 +2349,8 @@ namespace ts {
|
||||
// this.foo assignment in a JavaScript class
|
||||
// Bind this property to the containing class
|
||||
const containingClass = container.parent;
|
||||
const symbol = declareSymbol(hasModifier(container, ModifierFlags.Static) ? containingClass.symbol.exports : containingClass.symbol.members, containingClass.symbol, node, SymbolFlags.Property, SymbolFlags.None);
|
||||
if (symbol) {
|
||||
// symbols declared through 'this' property assignements can be overwritten by subsequent method declarations
|
||||
(symbol as Symbol).isReplaceableByMethod = true;
|
||||
}
|
||||
const symbolTable = hasModifier(container, ModifierFlags.Static) ? containingClass.symbol.exports : containingClass.symbol.members;
|
||||
declareSymbol(symbolTable, containingClass.symbol, node, SymbolFlags.Property, SymbolFlags.None, /*isReplaceableByMethod*/ true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2389,7 +2369,7 @@ namespace ts {
|
||||
constructorFunction.parent = classPrototype;
|
||||
classPrototype.parent = leftSideOfAssignment;
|
||||
|
||||
bindPropertyAssignment(constructorFunction.text, leftSideOfAssignment, /*isPrototypeProperty*/ true);
|
||||
bindPropertyAssignment(constructorFunction.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ true);
|
||||
}
|
||||
|
||||
function bindStaticPropertyAssignment(node: BinaryExpression) {
|
||||
@@ -2411,15 +2391,15 @@ namespace ts {
|
||||
bindExportsPropertyAssignment(node);
|
||||
}
|
||||
else {
|
||||
bindPropertyAssignment(target.text, leftSideOfAssignment, /*isPrototypeProperty*/ false);
|
||||
bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
function lookupSymbolForName(name: string) {
|
||||
function lookupSymbolForName(name: __String) {
|
||||
return (container.symbol && container.symbol.exports && container.symbol.exports.get(name)) || (container.locals && container.locals.get(name));
|
||||
}
|
||||
|
||||
function bindPropertyAssignment(functionName: string, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
|
||||
function bindPropertyAssignment(functionName: __String, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
|
||||
let targetSymbol = lookupSymbolForName(functionName);
|
||||
|
||||
if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
|
||||
@@ -2432,8 +2412,8 @@ namespace ts {
|
||||
|
||||
// Set up the members collection if it doesn't exist already
|
||||
const symbolTable = isPrototypeProperty ?
|
||||
(targetSymbol.members || (targetSymbol.members = createMap<Symbol>())) :
|
||||
(targetSymbol.exports || (targetSymbol.exports = createMap<Symbol>()));
|
||||
(targetSymbol.members || (targetSymbol.members = createSymbolTable())) :
|
||||
(targetSymbol.exports || (targetSymbol.exports = createSymbolTable()));
|
||||
|
||||
// Declare the method/property
|
||||
declareSymbol(symbolTable, targetSymbol, propertyAccessExpression, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
@@ -2452,11 +2432,11 @@ namespace ts {
|
||||
bindBlockScopedDeclaration(node, SymbolFlags.Class, SymbolFlags.ClassExcludes);
|
||||
}
|
||||
else {
|
||||
const bindingName = node.name ? node.name.text : "__class";
|
||||
const bindingName = node.name ? node.name.escapedText : InternalSymbolName.Class;
|
||||
bindAnonymousDeclaration(node, SymbolFlags.Class, bindingName);
|
||||
// Add name of class expression into the map for semantic classifier
|
||||
if (node.name) {
|
||||
classifiableNames.set(node.name.text, node.name.text);
|
||||
classifiableNames.set(node.name.escapedText, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2471,15 +2451,15 @@ namespace ts {
|
||||
// Note: we check for this here because this class may be merging into a module. The
|
||||
// module might have an exported variable called 'prototype'. We can't allow that as
|
||||
// that would clash with the built-in 'prototype' for the class.
|
||||
const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype");
|
||||
const symbolExport = symbol.exports.get(prototypeSymbol.name);
|
||||
const prototypeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Prototype, "prototype" as __String);
|
||||
const symbolExport = symbol.exports.get(prototypeSymbol.escapedName);
|
||||
if (symbolExport) {
|
||||
if (node.name) {
|
||||
node.name.parent = node;
|
||||
}
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, prototypeSymbol.name));
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], Diagnostics.Duplicate_identifier_0, unescapeLeadingUnderscores(prototypeSymbol.escapedName)));
|
||||
}
|
||||
symbol.exports.set(prototypeSymbol.name, prototypeSymbol);
|
||||
symbol.exports.set(prototypeSymbol.escapedName, prototypeSymbol);
|
||||
prototypeSymbol.parent = symbol;
|
||||
}
|
||||
|
||||
@@ -2524,7 +2504,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (isBindingPattern(node.name)) {
|
||||
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, getDestructuringParameterName(node));
|
||||
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, "__" + indexOf(node.parent.parameters, node) as __String);
|
||||
}
|
||||
else {
|
||||
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
|
||||
@@ -2565,7 +2545,7 @@ namespace ts {
|
||||
node.flowNode = currentFlow;
|
||||
}
|
||||
checkStrictModeFunctionName(node);
|
||||
const bindingName = node.name ? node.name.text : "__function";
|
||||
const bindingName = node.name ? node.name.escapedText : InternalSymbolName.Function;
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.Function, bindingName);
|
||||
}
|
||||
|
||||
@@ -2579,7 +2559,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
return hasDynamicName(node)
|
||||
? bindAnonymousDeclaration(node, symbolFlags, "__computed")
|
||||
? bindAnonymousDeclaration(node, symbolFlags, InternalSymbolName.Computed)
|
||||
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
|
||||
@@ -3600,4 +3580,13 @@ namespace ts {
|
||||
return TransformFlags.NodeExcludes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* "Binds" JSDoc nodes in TypeScript code.
|
||||
* Since we will never create symbols for JSDoc, we just set parent pointers instead.
|
||||
*/
|
||||
function setParentPointers(parent: Node, child: Node): void {
|
||||
child.parent = parent;
|
||||
forEachChild(child, (childsChild) => setParentPointers(child, childsChild));
|
||||
}
|
||||
}
|
||||
|
||||
+1431
-1195
File diff suppressed because it is too large
Load Diff
+706
-238
File diff suppressed because it is too large
Load Diff
+232
-186
@@ -2,8 +2,11 @@
|
||||
/// <reference path="performance.ts" />
|
||||
|
||||
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";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = "2.4.0";
|
||||
export const version = `${versionMajorMinor}.0`;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -46,13 +49,31 @@ namespace ts {
|
||||
return new MapCtr<T>();
|
||||
}
|
||||
|
||||
/** Create a new escaped identifier map. */
|
||||
export function createUnderscoreEscapedMap<T>(): UnderscoreEscapedMap<T> {
|
||||
return new MapCtr<T>() as UnderscoreEscapedMap<T>;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createSymbolTable(symbols?: ReadonlyArray<Symbol>): SymbolTable {
|
||||
const result = createMap<Symbol>() as SymbolTable;
|
||||
if (symbols) {
|
||||
for (const symbol of symbols) {
|
||||
result.set(symbol.escapedName, symbol);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function createMapFromTemplate<T>(template?: MapLike<T>): Map<T> {
|
||||
const map: Map<T> = new MapCtr<T>();
|
||||
|
||||
// Copies keys/values from template. Note that for..in will not throw if
|
||||
// template is undefined, and instead will just exit the loop.
|
||||
for (const key in template) if (hasOwnProperty.call(template, key)) {
|
||||
map.set(key, template[key]);
|
||||
for (const key in template) {
|
||||
if (hasOwnProperty.call(template, key)) {
|
||||
map.set(key, template[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
@@ -69,7 +90,7 @@ namespace ts {
|
||||
|
||||
class MapIterator<T, U extends (string | T | [string, T])> {
|
||||
private data: MapLike<T>;
|
||||
private keys: string[];
|
||||
private keys: ReadonlyArray<string>;
|
||||
private index = 0;
|
||||
private selector: (data: MapLike<T>, key: string) => U;
|
||||
constructor(data: MapLike<T>, selector: (data: MapLike<T>, key: string) => U) {
|
||||
@@ -143,54 +164,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function createFileMap<T>(keyMapper?: (key: string) => string): FileMap<T> {
|
||||
const files = createMap<T>();
|
||||
return {
|
||||
get,
|
||||
set,
|
||||
contains,
|
||||
remove,
|
||||
forEachValue: forEachValueInMap,
|
||||
getKeys,
|
||||
clear,
|
||||
};
|
||||
|
||||
function forEachValueInMap(f: (key: Path, value: T) => void) {
|
||||
files.forEach((file, key) => {
|
||||
f(<Path>key, file);
|
||||
});
|
||||
}
|
||||
|
||||
function getKeys() {
|
||||
return arrayFrom(files.keys()) as Path[];
|
||||
}
|
||||
|
||||
// path should already be well-formed so it does not need to be normalized
|
||||
function get(path: Path): T {
|
||||
return files.get(toKey(path));
|
||||
}
|
||||
|
||||
function set(path: Path, value: T) {
|
||||
files.set(toKey(path), value);
|
||||
}
|
||||
|
||||
function contains(path: Path) {
|
||||
return files.has(toKey(path));
|
||||
}
|
||||
|
||||
function remove(path: Path) {
|
||||
files.delete(toKey(path));
|
||||
}
|
||||
|
||||
function clear() {
|
||||
files.clear();
|
||||
}
|
||||
|
||||
function toKey(path: Path): string {
|
||||
return keyMapper ? keyMapper(path) : path;
|
||||
}
|
||||
}
|
||||
|
||||
export function toPath(fileName: string, basePath: string, getCanonicalFileName: (path: string) => string): Path {
|
||||
const nonCanonicalizedPath = isRootedDiskPath(fileName)
|
||||
? normalizePath(fileName)
|
||||
@@ -204,7 +177,7 @@ namespace ts {
|
||||
GreaterThan = 1
|
||||
}
|
||||
|
||||
export function length(array: any[]) {
|
||||
export function length(array: ReadonlyArray<any>) {
|
||||
return array ? array.length : 0;
|
||||
}
|
||||
|
||||
@@ -213,7 +186,7 @@ namespace ts {
|
||||
* returns a truthy value, then returns that value.
|
||||
* If no such value is found, the callback is applied to each element of array and undefined is returned.
|
||||
*/
|
||||
export function forEach<T, U>(array: T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
|
||||
export function forEach<T, U>(array: ReadonlyArray<T> | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const result = callback(array[i], i);
|
||||
@@ -246,14 +219,14 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function zipWith<T, U>(arrayA: T[], arrayB: U[], callback: (a: T, b: U, index: number) => void): void {
|
||||
export function zipWith<T, U>(arrayA: ReadonlyArray<T>, arrayB: ReadonlyArray<U>, callback: (a: T, b: U, index: number) => void): void {
|
||||
Debug.assert(arrayA.length === arrayB.length);
|
||||
for (let i = 0; i < arrayA.length; i++) {
|
||||
callback(arrayA[i], arrayB[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
export function zipToMap<T>(keys: string[], values: T[]): Map<T> {
|
||||
export function zipToMap<T>(keys: ReadonlyArray<string>, values: ReadonlyArray<T>): Map<T> {
|
||||
Debug.assert(keys.length === values.length);
|
||||
const map = createMap<T>();
|
||||
for (let i = 0; i < keys.length; ++i) {
|
||||
@@ -267,7 +240,7 @@ namespace ts {
|
||||
* returns a falsey value, then returns false.
|
||||
* If no such value is found, the callback is applied to each element of array and `true` is returned.
|
||||
*/
|
||||
export function every<T>(array: T[], callback: (element: T, index: number) => boolean): boolean {
|
||||
export function every<T>(array: ReadonlyArray<T>, callback: (element: T, index: number) => boolean): boolean {
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (!callback(array[i], i)) {
|
||||
@@ -280,7 +253,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Works like Array.prototype.find, returning `undefined` if no element satisfying the predicate is found. */
|
||||
export function find<T>(array: T[], predicate: (element: T, index: number) => boolean): T | undefined {
|
||||
export function find<T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => boolean): T | undefined {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const value = array[i];
|
||||
if (predicate(value, i)) {
|
||||
@@ -291,7 +264,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Works like Array.prototype.findIndex, returning `-1` if no element satisfying the predicate is found. */
|
||||
export function findIndex<T>(array: T[], predicate: (element: T, index: number) => boolean): number {
|
||||
export function findIndex<T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => boolean): number {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (predicate(array[i], i)) {
|
||||
return i;
|
||||
@@ -304,7 +277,7 @@ namespace ts {
|
||||
* Returns the first truthy result of `callback`, or else fails.
|
||||
* This is like `forEach`, but never returns undefined.
|
||||
*/
|
||||
export function findMap<T, U>(array: T[], callback: (element: T, index: number) => U | undefined): U {
|
||||
export function findMap<T, U>(array: ReadonlyArray<T>, callback: (element: T, index: number) => U | undefined): U {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const result = callback(array[i], i);
|
||||
if (result) {
|
||||
@@ -314,7 +287,7 @@ namespace ts {
|
||||
Debug.fail();
|
||||
}
|
||||
|
||||
export function contains<T>(array: T[], value: T): boolean {
|
||||
export function contains<T>(array: ReadonlyArray<T>, value: T): boolean {
|
||||
if (array) {
|
||||
for (const v of array) {
|
||||
if (v === value) {
|
||||
@@ -325,7 +298,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function indexOf<T>(array: T[], value: T): number {
|
||||
export function indexOf<T>(array: ReadonlyArray<T>, value: T): number {
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (array[i] === value) {
|
||||
@@ -336,7 +309,7 @@ namespace ts {
|
||||
return -1;
|
||||
}
|
||||
|
||||
export function indexOfAnyCharCode(text: string, charCodes: number[], start?: number): number {
|
||||
export function indexOfAnyCharCode(text: string, charCodes: ReadonlyArray<number>, start?: number): number {
|
||||
for (let i = start || 0; i < text.length; i++) {
|
||||
if (contains(charCodes, text.charCodeAt(i))) {
|
||||
return i;
|
||||
@@ -345,7 +318,7 @@ namespace ts {
|
||||
return -1;
|
||||
}
|
||||
|
||||
export function countWhere<T>(array: T[], predicate: (x: T, i: number) => boolean): number {
|
||||
export function countWhere<T>(array: ReadonlyArray<T>, predicate: (x: T, i: number) => boolean): number {
|
||||
let count = 0;
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
@@ -364,6 +337,8 @@ namespace ts {
|
||||
*/
|
||||
export function filter<T, U extends T>(array: T[], f: (x: T) => x is U): U[];
|
||||
export function filter<T>(array: T[], f: (x: T) => boolean): T[];
|
||||
export function filter<T, U extends T>(array: ReadonlyArray<T>, f: (x: T) => x is U): ReadonlyArray<U>;
|
||||
export function filter<T, U extends T>(array: ReadonlyArray<T>, f: (x: T) => boolean): ReadonlyArray<T>;
|
||||
export function filter<T>(array: T[], f: (x: T) => boolean): T[] {
|
||||
if (array) {
|
||||
const len = array.length;
|
||||
@@ -411,7 +386,11 @@ namespace ts {
|
||||
array.length = outIndex;
|
||||
}
|
||||
|
||||
export function map<T, U>(array: T[], f: (x: T, i: number) => U): U[] {
|
||||
export function clear(array: {}[]): void {
|
||||
array.length = 0;
|
||||
}
|
||||
|
||||
export function map<T, U>(array: ReadonlyArray<T>, f: (x: T, i: number) => U): U[] {
|
||||
let result: U[];
|
||||
if (array) {
|
||||
result = [];
|
||||
@@ -423,6 +402,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Maps from T to T and avoids allocation if all elements map to themselves
|
||||
export function sameMap<T>(array: T[], f: (x: T, i: number) => T): T[];
|
||||
export function sameMap<T>(array: ReadonlyArray<T>, f: (x: T, i: number) => T): ReadonlyArray<T>;
|
||||
export function sameMap<T>(array: T[], f: (x: T, i: number) => T): T[] {
|
||||
let result: T[];
|
||||
if (array) {
|
||||
@@ -448,7 +429,7 @@ namespace ts {
|
||||
*
|
||||
* @param array The array to flatten.
|
||||
*/
|
||||
export function flatten<T>(array: (T | T[])[]): T[] {
|
||||
export function flatten<T>(array: ReadonlyArray<T | ReadonlyArray<T>>): T[] {
|
||||
let result: T[];
|
||||
if (array) {
|
||||
result = [];
|
||||
@@ -473,7 +454,7 @@ namespace ts {
|
||||
* @param array The array to map.
|
||||
* @param mapfn The callback used to map the result into one or more values.
|
||||
*/
|
||||
export function flatMap<T, U>(array: T[] | undefined, mapfn: (x: T, i: number) => U | U[] | undefined): U[] | undefined {
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[] | undefined {
|
||||
let result: U[];
|
||||
if (array) {
|
||||
result = [];
|
||||
@@ -492,6 +473,17 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function flatMapIter<T, U>(iter: Iterator<T>, mapfn: (x: T) => U[] | undefined): U[] {
|
||||
const result: U[] = [];
|
||||
while (true) {
|
||||
const { value, done } = iter.next();
|
||||
if (done) break;
|
||||
const res = mapfn(value);
|
||||
if (res) result.push(...res);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps an array. If the mapped value is an array, it is spread into the result.
|
||||
* Avoids allocation if all elements map to themselves.
|
||||
@@ -499,6 +491,8 @@ namespace ts {
|
||||
* @param array The array to map.
|
||||
* @param mapfn The callback used to map the result into one or more values.
|
||||
*/
|
||||
export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | ReadonlyArray<T>): T[];
|
||||
export function sameFlatMap<T>(array: ReadonlyArray<T>, mapfn: (x: T, i: number) => T | ReadonlyArray<T>): ReadonlyArray<T>;
|
||||
export function sameFlatMap<T>(array: T[], mapfn: (x: T, i: number) => T | T[]): T[] {
|
||||
let result: T[];
|
||||
if (array) {
|
||||
@@ -521,8 +515,8 @@ namespace ts {
|
||||
return result || array;
|
||||
}
|
||||
|
||||
export function mapDefined<T>(array: ReadonlyArray<T>, mapFn: (x: T, i: number) => T | undefined): ReadonlyArray<T> {
|
||||
const result: T[] = [];
|
||||
export function mapDefined<T, U>(array: ReadonlyArray<T>, mapFn: (x: T, i: number) => U | undefined): U[] {
|
||||
const result: U[] = [];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const item = array[i];
|
||||
const mapped = mapFn(item, i);
|
||||
@@ -537,7 +531,7 @@ namespace ts {
|
||||
* Computes the first matching span of elements and returns a tuple of the first span
|
||||
* and the remaining elements.
|
||||
*/
|
||||
export function span<T>(array: T[], f: (x: T, i: number) => boolean): [T[], T[]] {
|
||||
export function span<T>(array: ReadonlyArray<T>, f: (x: T, i: number) => boolean): [T[], T[]] {
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (!f(array[i], i)) {
|
||||
@@ -557,7 +551,7 @@ namespace ts {
|
||||
* @param keyfn A callback used to select the key for an element.
|
||||
* @param mapfn A callback used to map a contiguous chunk of values to a single value.
|
||||
*/
|
||||
export function spanMap<T, K, U>(array: T[], keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K, start: number, end: number) => U): U[] {
|
||||
export function spanMap<T, K, U>(array: ReadonlyArray<T>, keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K, start: number, end: number) => U): U[] {
|
||||
let result: U[];
|
||||
if (array) {
|
||||
result = [];
|
||||
@@ -597,7 +591,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function mapEntries<T, U>(map: Map<T>, f: (key: string, value: T) => [string, U]): Map<U> {
|
||||
export function mapEntries<T, U>(map: ReadonlyMap<T>, f: (key: string, value: T) => [string, U]): Map<U> {
|
||||
if (!map) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -610,7 +604,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function some<T>(array: T[], predicate?: (value: T) => boolean): boolean {
|
||||
export function some<T>(array: ReadonlyArray<T>, predicate?: (value: T) => boolean): boolean {
|
||||
if (array) {
|
||||
if (predicate) {
|
||||
for (const v of array) {
|
||||
@@ -626,6 +620,8 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function concatenate<T>(array1: T[], array2: T[]): T[];
|
||||
export function concatenate<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>): ReadonlyArray<T>;
|
||||
export function concatenate<T>(array1: T[], array2: T[]): T[] {
|
||||
if (!some(array2)) return array1;
|
||||
if (!some(array1)) return array2;
|
||||
@@ -633,7 +629,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// TODO: fixme (N^2) - add optional comparer so collection can be sorted before deduplication.
|
||||
export function deduplicate<T>(array: T[], areEqual?: (a: T, b: T) => boolean): T[] {
|
||||
export function deduplicate<T>(array: ReadonlyArray<T>, areEqual?: (a: T, b: T) => boolean): T[] {
|
||||
let result: T[];
|
||||
if (array) {
|
||||
result = [];
|
||||
@@ -690,6 +686,8 @@ namespace ts {
|
||||
/**
|
||||
* Compacts an array, removing any falsey elements.
|
||||
*/
|
||||
export function compact<T>(array: T[]): T[];
|
||||
export function compact<T>(array: ReadonlyArray<T>): ReadonlyArray<T>;
|
||||
export function compact<T>(array: T[]): T[] {
|
||||
let result: T[];
|
||||
if (array) {
|
||||
@@ -713,7 +711,7 @@ namespace ts {
|
||||
* are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted
|
||||
* based on the provided comparer.
|
||||
*/
|
||||
export function relativeComplement<T>(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: (x: T, y: T) => Comparison = compareValues, offsetA = 0, offsetB = 0): T[] | undefined {
|
||||
export function relativeComplement<T>(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: Comparer<T> = compareValues, offsetA = 0, offsetB = 0): T[] | undefined {
|
||||
if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0) return arrayB;
|
||||
const result: T[] = [];
|
||||
outer: for (; offsetB < arrayB.length; offsetB++) {
|
||||
@@ -729,10 +727,11 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function sum(array: any[], prop: string): number {
|
||||
export function sum<T extends Record<K, number>, K extends string>(array: T[], prop: K): number {
|
||||
let result = 0;
|
||||
for (const v of array) {
|
||||
result += v[prop];
|
||||
// Note: we need the following type assertion because of GH #17069
|
||||
result += v[prop] as number;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -756,7 +755,7 @@ namespace ts {
|
||||
* Gets the actual offset into an array for a relative offset. Negative offsets indicate a
|
||||
* position offset from the end of the array.
|
||||
*/
|
||||
function toOffset(array: any[], offset: number) {
|
||||
function toOffset(array: ReadonlyArray<any>, offset: number) {
|
||||
return offset < 0 ? array.length + offset : offset;
|
||||
}
|
||||
|
||||
@@ -770,7 +769,7 @@ namespace ts {
|
||||
* @param start The offset in `from` at which to start copying values.
|
||||
* @param end The offset in `from` at which to stop copying values (non-inclusive).
|
||||
*/
|
||||
export function addRange<T>(to: T[] | undefined, from: T[] | undefined, start?: number, end?: number): T[] | undefined {
|
||||
export function addRange<T>(to: T[] | undefined, from: ReadonlyArray<T> | undefined, start?: number, end?: number): T[] | undefined {
|
||||
if (from === undefined) return to;
|
||||
if (to === undefined) return from.slice(start, end);
|
||||
start = start === undefined ? 0 : toOffset(from, start);
|
||||
@@ -787,14 +786,14 @@ namespace ts {
|
||||
/**
|
||||
* Stable sort of an array. Elements equal to each other maintain their relative position in the array.
|
||||
*/
|
||||
export function stableSort<T>(array: T[], comparer: (x: T, y: T) => Comparison = compareValues) {
|
||||
export function stableSort<T>(array: ReadonlyArray<T>, comparer: Comparer<T> = compareValues) {
|
||||
return array
|
||||
.map((_, i) => i) // create array of indices
|
||||
.sort((x, y) => comparer(array[x], array[y]) || compareValues(x, y)) // sort indices by value then position
|
||||
.map(i => array[i]); // get sorted array
|
||||
}
|
||||
|
||||
export function rangeEquals<T>(array1: T[], array2: T[], pos: number, end: number) {
|
||||
export function rangeEquals<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>, pos: number, end: number) {
|
||||
while (pos < end) {
|
||||
if (array1[pos] !== array2[pos]) {
|
||||
return false;
|
||||
@@ -808,7 +807,7 @@ namespace ts {
|
||||
* Returns the element at a specific offset in an array if non-empty, `undefined` otherwise.
|
||||
* A negative offset indicates the element should be retrieved from the end of the array.
|
||||
*/
|
||||
export function elementAt<T>(array: T[] | undefined, offset: number): T | undefined {
|
||||
export function elementAt<T>(array: ReadonlyArray<T> | undefined, offset: number): T | undefined {
|
||||
if (array) {
|
||||
offset = toOffset(array, offset);
|
||||
if (offset < array.length) {
|
||||
@@ -821,21 +820,21 @@ namespace ts {
|
||||
/**
|
||||
* Returns the first element of an array if non-empty, `undefined` otherwise.
|
||||
*/
|
||||
export function firstOrUndefined<T>(array: T[]): T | undefined {
|
||||
export function firstOrUndefined<T>(array: ReadonlyArray<T>): T | undefined {
|
||||
return elementAt(array, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element of an array if non-empty, `undefined` otherwise.
|
||||
*/
|
||||
export function lastOrUndefined<T>(array: T[]): T | undefined {
|
||||
export function lastOrUndefined<T>(array: ReadonlyArray<T>): T | undefined {
|
||||
return elementAt(array, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the only element of an array if it contains only one element, `undefined` otherwise.
|
||||
*/
|
||||
export function singleOrUndefined<T>(array: T[]): T | undefined {
|
||||
export function singleOrUndefined<T>(array: ReadonlyArray<T>): T | undefined {
|
||||
return array && array.length === 1
|
||||
? array[0]
|
||||
: undefined;
|
||||
@@ -845,18 +844,22 @@ namespace ts {
|
||||
* Returns the only element of an array if it contains only one element; otheriwse, returns the
|
||||
* array.
|
||||
*/
|
||||
export function singleOrMany<T>(array: T[]): T | T[];
|
||||
export function singleOrMany<T>(array: ReadonlyArray<T>): T | ReadonlyArray<T>;
|
||||
export function singleOrMany<T>(array: T[]): T | T[] {
|
||||
return array && array.length === 1
|
||||
? array[0]
|
||||
: array;
|
||||
}
|
||||
|
||||
export function replaceElement<T>(array: T[], index: number, value: T): T[] {
|
||||
export function replaceElement<T>(array: ReadonlyArray<T>, index: number, value: T): T[] {
|
||||
const result = array.slice(0);
|
||||
result[index] = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
export type Comparer<T> = (a: T, b: T) => Comparison;
|
||||
|
||||
/**
|
||||
* Performs a binary search, finding the index at which 'value' occurs in 'array'.
|
||||
* If no such index is found, returns the 2's-complement of first index at which
|
||||
@@ -864,7 +867,7 @@ namespace ts {
|
||||
* @param array A sorted array whose first element must be no larger than number
|
||||
* @param number The value to be searched for in the array.
|
||||
*/
|
||||
export function binarySearch<T>(array: T[], value: T, comparer?: (v1: T, v2: T) => number, offset?: number): number {
|
||||
export function binarySearch<T>(array: ReadonlyArray<T>, value: T, comparer?: Comparer<T>, offset?: number): number {
|
||||
if (!array || array.length === 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -893,8 +896,8 @@ namespace ts {
|
||||
return ~low;
|
||||
}
|
||||
|
||||
export function reduceLeft<T, U>(array: T[], f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U;
|
||||
export function reduceLeft<T>(array: T[], f: (memo: T, value: T, i: number) => T): T;
|
||||
export function reduceLeft<T, U>(array: ReadonlyArray<T>, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U;
|
||||
export function reduceLeft<T>(array: ReadonlyArray<T>, f: (memo: T, value: T, i: number) => T): T;
|
||||
export function reduceLeft<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T {
|
||||
if (array && array.length > 0) {
|
||||
const size = array.length;
|
||||
@@ -919,8 +922,8 @@ namespace ts {
|
||||
return initial;
|
||||
}
|
||||
|
||||
export function reduceRight<T, U>(array: T[], f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U;
|
||||
export function reduceRight<T>(array: T[], f: (memo: T, value: T, i: number) => T): T;
|
||||
export function reduceRight<T, U>(array: ReadonlyArray<T>, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U;
|
||||
export function reduceRight<T>(array: ReadonlyArray<T>, f: (memo: T, value: T, i: number) => T): T;
|
||||
export function reduceRight<T>(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T {
|
||||
if (array) {
|
||||
const size = array.length;
|
||||
@@ -953,7 +956,7 @@ namespace ts {
|
||||
* @param map A map-like.
|
||||
* @param key A property key.
|
||||
*/
|
||||
export function hasProperty<T>(map: MapLike<T>, key: string): boolean {
|
||||
export function hasProperty(map: MapLike<any>, key: string): boolean {
|
||||
return hasOwnProperty.call(map, key);
|
||||
}
|
||||
|
||||
@@ -977,9 +980,12 @@ namespace ts {
|
||||
*/
|
||||
export function getOwnKeys<T>(map: MapLike<T>): string[] {
|
||||
const keys: string[] = [];
|
||||
for (const key in map) if (hasOwnProperty.call(map, key)) {
|
||||
keys.push(key);
|
||||
for (const key in map) {
|
||||
if (hasOwnProperty.call(map, key)) {
|
||||
keys.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
@@ -994,23 +1000,17 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function convertToArray<T, U>(iterator: Iterator<T>, f: (value: T) => U) {
|
||||
const result: U[] = [];
|
||||
for (let { value, done } = iterator.next(); !done; { value, done } = iterator.next()) {
|
||||
result.push(f(value));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls `callback` for each entry in the map, returning the first truthy result.
|
||||
* Use `map.forEach` instead for normal iteration.
|
||||
*/
|
||||
export function forEachEntry<T, U>(map: Map<T>, callback: (value: T, key: string) => U | undefined): U | undefined {
|
||||
export function forEachEntry<T, U>(map: ReadonlyUnderscoreEscapedMap<T>, callback: (value: T, key: __String) => U | undefined): U | undefined;
|
||||
export function forEachEntry<T, U>(map: ReadonlyMap<T>, callback: (value: T, key: string) => U | undefined): U | undefined;
|
||||
export function forEachEntry<T, U>(map: ReadonlyUnderscoreEscapedMap<T> | ReadonlyMap<T>, callback: (value: T, key: (string & __String)) => U | undefined): U | undefined {
|
||||
const iterator = map.entries();
|
||||
for (let { value: pair, done } = iterator.next(); !done; { value: pair, done } = iterator.next()) {
|
||||
const [key, value] = pair;
|
||||
const result = callback(value, key);
|
||||
const result = callback(value, key as (string & __String));
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
@@ -1019,10 +1019,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** `forEachEntry` for just keys. */
|
||||
export function forEachKey<T>(map: Map<{}>, callback: (key: string) => T | undefined): T | undefined {
|
||||
export function forEachKey<T>(map: ReadonlyUnderscoreEscapedMap<{}>, callback: (key: __String) => T | undefined): T | undefined;
|
||||
export function forEachKey<T>(map: ReadonlyMap<{}>, callback: (key: string) => T | undefined): T | undefined;
|
||||
export function forEachKey<T>(map: ReadonlyUnderscoreEscapedMap<{}> | ReadonlyMap<{}>, callback: (key: string & __String) => T | undefined): T | undefined {
|
||||
const iterator = map.keys();
|
||||
for (let { value: key, done } = iterator.next(); !done; { value: key, done } = iterator.next()) {
|
||||
const result = callback(key);
|
||||
const result = callback(key as string & __String);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
@@ -1031,9 +1033,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Copy entries from `source` to `target`. */
|
||||
export function copyEntries<T>(source: Map<T>, target: Map<T>): void {
|
||||
source.forEach((value, key) => {
|
||||
target.set(key, value);
|
||||
export function copyEntries<T>(source: ReadonlyUnderscoreEscapedMap<T>, target: UnderscoreEscapedMap<T>): void;
|
||||
export function copyEntries<T>(source: ReadonlyMap<T>, target: Map<T>): void;
|
||||
export function copyEntries<T, U extends UnderscoreEscapedMap<T> | Map<T>>(source: U, target: U): void {
|
||||
(source as Map<T>).forEach((value, key) => {
|
||||
(target as Map<T>).set(key, value);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1042,8 +1046,10 @@ namespace ts {
|
||||
export function assign<T1 extends MapLike<{}>>(t: T1, ...args: any[]): any;
|
||||
export function assign<T1 extends MapLike<{}>>(t: T1, ...args: any[]) {
|
||||
for (const arg of args) {
|
||||
for (const p in arg) if (hasProperty(arg, p)) {
|
||||
t[p] = arg[p];
|
||||
for (const p in arg) {
|
||||
if (hasProperty(arg, p)) {
|
||||
t[p] = arg[p];
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
@@ -1058,13 +1064,19 @@ namespace ts {
|
||||
export function equalOwnProperties<T>(left: MapLike<T>, right: MapLike<T>, equalityComparer?: (left: T, right: T) => boolean) {
|
||||
if (left === right) return true;
|
||||
if (!left || !right) return false;
|
||||
for (const key in left) if (hasOwnProperty.call(left, key)) {
|
||||
if (!hasOwnProperty.call(right, key) === undefined) return false;
|
||||
if (equalityComparer ? !equalityComparer(left[key], right[key]) : left[key] !== right[key]) return false;
|
||||
for (const key in left) {
|
||||
if (hasOwnProperty.call(left, key)) {
|
||||
if (!hasOwnProperty.call(right, key) === undefined) return false;
|
||||
if (equalityComparer ? !equalityComparer(left[key], right[key]) : left[key] !== right[key]) return false;
|
||||
}
|
||||
}
|
||||
for (const key in right) if (hasOwnProperty.call(right, key)) {
|
||||
if (!hasOwnProperty.call(left, key)) return false;
|
||||
|
||||
for (const key in right) {
|
||||
if (hasOwnProperty.call(right, key)) {
|
||||
if (!hasOwnProperty.call(left, key)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1078,9 +1090,9 @@ namespace ts {
|
||||
* the same key with the given 'makeKey' function, then the element with the higher
|
||||
* index in the array will be the one associated with the produced key.
|
||||
*/
|
||||
export function arrayToMap<T>(array: T[], makeKey: (value: T) => string): Map<T>;
|
||||
export function arrayToMap<T, U>(array: T[], makeKey: (value: T) => string, makeValue: (value: T) => U): Map<U>;
|
||||
export function arrayToMap<T, U>(array: T[], makeKey: (value: T) => string, makeValue?: (value: T) => U): Map<T | U> {
|
||||
export function arrayToMap<T>(array: ReadonlyArray<T>, makeKey: (value: T) => string): Map<T>;
|
||||
export function arrayToMap<T, U>(array: ReadonlyArray<T>, makeKey: (value: T) => string, makeValue: (value: T) => U): Map<U>;
|
||||
export function arrayToMap<T, U>(array: ReadonlyArray<T>, makeKey: (value: T) => string, makeValue?: (value: T) => U): Map<T | U> {
|
||||
const result = createMap<T | U>();
|
||||
for (const value of array) {
|
||||
result.set(makeKey(value), makeValue ? makeValue(value) : value);
|
||||
@@ -1088,9 +1100,22 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function cloneMap<T>(map: Map<T>) {
|
||||
/**
|
||||
* Creates a set from the elements of an array.
|
||||
*
|
||||
* @param array the array of input elements.
|
||||
*/
|
||||
export function arrayToSet(array: ReadonlyArray<string>): Map<true>;
|
||||
export function arrayToSet<T>(array: ReadonlyArray<T>, makeKey: (value: T) => string): Map<true>;
|
||||
export function arrayToSet(array: ReadonlyArray<any>, makeKey?: (value: any) => string): Map<true> {
|
||||
return arrayToMap<any, true>(array, makeKey || (s => s), () => true);
|
||||
}
|
||||
|
||||
export function cloneMap(map: SymbolTable): SymbolTable;
|
||||
export function cloneMap<T>(map: ReadonlyMap<T>): Map<T>;
|
||||
export function cloneMap<T>(map: ReadonlyMap<T> | SymbolTable): Map<T> | SymbolTable {
|
||||
const clone = createMap<T>();
|
||||
copyEntries(map, clone);
|
||||
copyEntries(map as Map<T>, clone);
|
||||
return clone;
|
||||
}
|
||||
|
||||
@@ -1106,12 +1131,18 @@ namespace ts {
|
||||
|
||||
export function extend<T1, T2>(first: T1, second: T2): T1 & T2 {
|
||||
const result: T1 & T2 = <any>{};
|
||||
for (const id in second) if (hasOwnProperty.call(second, id)) {
|
||||
(result as any)[id] = (second as any)[id];
|
||||
for (const id in second) {
|
||||
if (hasOwnProperty.call(second, id)) {
|
||||
(result as any)[id] = (second as any)[id];
|
||||
}
|
||||
}
|
||||
for (const id in first) if (hasOwnProperty.call(first, id)) {
|
||||
(result as any)[id] = (first as any)[id];
|
||||
|
||||
for (const id in first) {
|
||||
if (hasOwnProperty.call(first, id)) {
|
||||
(result as any)[id] = (first as any)[id];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1159,7 +1190,7 @@ namespace ts {
|
||||
/**
|
||||
* Tests whether a value is an array.
|
||||
*/
|
||||
export function isArray(value: any): value is any[] {
|
||||
export function isArray(value: any): value is ReadonlyArray<any> {
|
||||
return Array.isArray ? Array.isArray(value) : value instanceof Array;
|
||||
}
|
||||
|
||||
@@ -1557,10 +1588,21 @@ 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 "..".
|
||||
return /^\.\.?($|[\\/])/.test(moduleName);
|
||||
// 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);
|
||||
}
|
||||
|
||||
export function getEmitScriptTarget(compilerOptions: CompilerOptions) {
|
||||
@@ -1629,7 +1671,7 @@ namespace ts {
|
||||
return getNormalizedPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory));
|
||||
}
|
||||
|
||||
export function getNormalizedPathFromPathComponents(pathComponents: string[]) {
|
||||
export function getNormalizedPathFromPathComponents(pathComponents: ReadonlyArray<string>) {
|
||||
if (pathComponents && pathComponents.length) {
|
||||
return pathComponents[0] + pathComponents.slice(1).join(directorySeparator);
|
||||
}
|
||||
@@ -1692,7 +1734,7 @@ namespace ts {
|
||||
if (directoryComponents.length > 1 && lastOrUndefined(directoryComponents) === "") {
|
||||
// If the directory path given was of type test/cases/ then we really need components of directory to be only till its name
|
||||
// that is ["test", "cases", ""] needs to be actually ["test", "cases"]
|
||||
directoryComponents.length--;
|
||||
directoryComponents.pop();
|
||||
}
|
||||
|
||||
// Find the component that differs
|
||||
@@ -1831,7 +1873,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function fileExtensionIsOneOf(path: string, extensions: string[]): boolean {
|
||||
export function fileExtensionIsOneOf(path: string, extensions: ReadonlyArray<string>): boolean {
|
||||
for (const extension of extensions) {
|
||||
if (fileExtensionIs(path, extension)) {
|
||||
return true;
|
||||
@@ -1856,7 +1898,7 @@ namespace ts {
|
||||
const singleAsteriskRegexFragmentFiles = "([^./]|(\\.(?!min\\.js$))?)*";
|
||||
const singleAsteriskRegexFragmentOther = "[^/]*";
|
||||
|
||||
export function getRegularExpressionForWildcard(specs: string[], basePath: string, usage: "files" | "directories" | "exclude"): string | undefined {
|
||||
export function getRegularExpressionForWildcard(specs: ReadonlyArray<string>, basePath: string, usage: "files" | "directories" | "exclude"): string | undefined {
|
||||
const patterns = getRegularExpressionsForWildcards(specs, basePath, usage);
|
||||
if (!patterns || !patterns.length) {
|
||||
return undefined;
|
||||
@@ -1868,7 +1910,7 @@ namespace ts {
|
||||
return `^(${pattern})${terminator}`;
|
||||
}
|
||||
|
||||
function getRegularExpressionsForWildcards(specs: string[], basePath: string, usage: "files" | "directories" | "exclude"): string[] | undefined {
|
||||
function getRegularExpressionsForWildcards(specs: ReadonlyArray<string>, basePath: string, usage: "files" | "directories" | "exclude"): string[] | undefined {
|
||||
if (specs === undefined || specs.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1973,21 +2015,21 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface FileSystemEntries {
|
||||
files: string[];
|
||||
directories: string[];
|
||||
files: ReadonlyArray<string>;
|
||||
directories: ReadonlyArray<string>;
|
||||
}
|
||||
|
||||
export interface FileMatcherPatterns {
|
||||
/** One pattern for each "include" spec. */
|
||||
includeFilePatterns: string[];
|
||||
includeFilePatterns: ReadonlyArray<string>;
|
||||
/** One pattern matching one of any of the "include" specs. */
|
||||
includeFilePattern: string;
|
||||
includeDirectoryPattern: string;
|
||||
excludePattern: string;
|
||||
basePaths: string[];
|
||||
basePaths: ReadonlyArray<string>;
|
||||
}
|
||||
|
||||
export function getFileMatcherPatterns(path: string, excludes: string[], includes: string[], useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns {
|
||||
export function getFileMatcherPatterns(path: string, excludes: ReadonlyArray<string>, includes: ReadonlyArray<string>, useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns {
|
||||
path = normalizePath(path);
|
||||
currentDirectory = normalizePath(currentDirectory);
|
||||
const absolutePath = combinePaths(currentDirectory, path);
|
||||
@@ -2001,7 +2043,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function matchFiles(path: string, extensions: string[], excludes: string[], includes: string[], useCaseSensitiveFileNames: boolean, currentDirectory: string, getFileSystemEntries: (path: string) => FileSystemEntries): string[] {
|
||||
export function matchFiles(path: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string>, includes: ReadonlyArray<string>, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries): string[] {
|
||||
path = normalizePath(path);
|
||||
currentDirectory = normalizePath(currentDirectory);
|
||||
|
||||
@@ -2018,15 +2060,14 @@ namespace ts {
|
||||
|
||||
const comparer = useCaseSensitiveFileNames ? compareStrings : compareStringsCaseInsensitive;
|
||||
for (const basePath of patterns.basePaths) {
|
||||
visitDirectory(basePath, combinePaths(currentDirectory, basePath));
|
||||
visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth);
|
||||
}
|
||||
|
||||
return flatten(results);
|
||||
return flatten<string>(results);
|
||||
|
||||
function visitDirectory(path: string, absolutePath: string) {
|
||||
function visitDirectory(path: string, absolutePath: string, depth: number | undefined) {
|
||||
let { files, directories } = getFileSystemEntries(path);
|
||||
files = files.slice().sort(comparer);
|
||||
directories = directories.slice().sort(comparer);
|
||||
|
||||
for (const current of files) {
|
||||
const name = combinePaths(path, current);
|
||||
@@ -2044,12 +2085,20 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (depth !== undefined) {
|
||||
depth--;
|
||||
if (depth === 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
directories = directories.slice().sort(comparer);
|
||||
for (const current of directories) {
|
||||
const name = combinePaths(path, current);
|
||||
const absoluteName = combinePaths(absolutePath, current);
|
||||
if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) &&
|
||||
(!excludeRegex || !excludeRegex.test(absoluteName))) {
|
||||
visitDirectory(name, absoluteName);
|
||||
visitDirectory(name, absoluteName, depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2058,7 +2107,7 @@ namespace ts {
|
||||
/**
|
||||
* Computes the unique non-wildcard base paths amongst the provided include patterns.
|
||||
*/
|
||||
function getBasePaths(path: string, includes: string[], useCaseSensitiveFileNames: boolean) {
|
||||
function getBasePaths(path: string, includes: ReadonlyArray<string>, useCaseSensitiveFileNames: boolean) {
|
||||
// Storage for our results in the form of literal paths (e.g. the paths as written by the user).
|
||||
const basePaths: string[] = [path];
|
||||
|
||||
@@ -2099,27 +2148,29 @@ namespace ts {
|
||||
return absolute.substring(0, absolute.lastIndexOf(directorySeparator, wildcardOffset));
|
||||
}
|
||||
|
||||
export function ensureScriptKind(fileName: string, scriptKind?: ScriptKind): ScriptKind {
|
||||
export function ensureScriptKind(fileName: string, scriptKind: ScriptKind | undefined): ScriptKind {
|
||||
// Using scriptKind as a condition handles both:
|
||||
// - 'scriptKind' is unspecified and thus it is `undefined`
|
||||
// - 'scriptKind' is set and it is `Unknown` (0)
|
||||
// If the 'scriptKind' is 'undefined' or 'Unknown' then we attempt
|
||||
// to get the ScriptKind from the file name. If it cannot be resolved
|
||||
// from the file name then the default 'TS' script kind is returned.
|
||||
return (scriptKind || getScriptKindFromFileName(fileName)) || ScriptKind.TS;
|
||||
return scriptKind || getScriptKindFromFileName(fileName) || ScriptKind.TS;
|
||||
}
|
||||
|
||||
export function getScriptKindFromFileName(fileName: string): ScriptKind {
|
||||
const ext = fileName.substr(fileName.lastIndexOf("."));
|
||||
switch (ext.toLowerCase()) {
|
||||
case ".js":
|
||||
case Extension.Js:
|
||||
return ScriptKind.JS;
|
||||
case ".jsx":
|
||||
case Extension.Jsx:
|
||||
return ScriptKind.JSX;
|
||||
case ".ts":
|
||||
case Extension.Ts:
|
||||
return ScriptKind.TS;
|
||||
case ".tsx":
|
||||
case Extension.Tsx:
|
||||
return ScriptKind.TSX;
|
||||
case ".json":
|
||||
return ScriptKind.JSON;
|
||||
default:
|
||||
return ScriptKind.Unknown;
|
||||
}
|
||||
@@ -2128,18 +2179,18 @@ namespace ts {
|
||||
/**
|
||||
* List of supported extensions in order of file resolution precedence.
|
||||
*/
|
||||
export const supportedTypeScriptExtensions = [".ts", ".tsx", ".d.ts"];
|
||||
export const supportedTypeScriptExtensions: ReadonlyArray<Extension> = [Extension.Ts, Extension.Tsx, Extension.Dts];
|
||||
/** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
|
||||
export const supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"];
|
||||
export const supportedJavascriptExtensions = [".js", ".jsx"];
|
||||
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
|
||||
export const supportedTypescriptExtensionsForExtractExtension: ReadonlyArray<Extension> = [Extension.Dts, Extension.Ts, Extension.Tsx];
|
||||
export const supportedJavascriptExtensions: ReadonlyArray<Extension> = [Extension.Js, Extension.Jsx];
|
||||
const allSupportedExtensions = [...supportedTypeScriptExtensions, ...supportedJavascriptExtensions];
|
||||
|
||||
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: JsFileExtensionInfo[]): string[] {
|
||||
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray<JsFileExtensionInfo>): ReadonlyArray<string> {
|
||||
const needAllExtensions = options && options.allowJs;
|
||||
if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) {
|
||||
return needAllExtensions ? allSupportedExtensions : supportedTypeScriptExtensions;
|
||||
}
|
||||
const extensions = allSupportedExtensions.slice(0);
|
||||
const extensions: string[] = allSupportedExtensions.slice(0);
|
||||
for (const extInfo of extraFileExtensions) {
|
||||
if (extensions.indexOf(extInfo.extension) === -1) {
|
||||
extensions.push(extInfo.extension);
|
||||
@@ -2156,7 +2207,7 @@ namespace ts {
|
||||
return forEach(supportedTypeScriptExtensions, extension => fileExtensionIs(fileName, extension));
|
||||
}
|
||||
|
||||
export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: JsFileExtensionInfo[]) {
|
||||
export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: ReadonlyArray<JsFileExtensionInfo>) {
|
||||
if (!fileName) { return false; }
|
||||
|
||||
for (const extension of getSupportedExtensions(compilerOptions, extraFileExtensions)) {
|
||||
@@ -2180,7 +2231,7 @@ namespace ts {
|
||||
Lowest = DeclarationAndJavaScriptFiles,
|
||||
}
|
||||
|
||||
export function getExtensionPriority(path: string, supportedExtensions: string[]): ExtensionPriority {
|
||||
export function getExtensionPriority(path: string, supportedExtensions: ReadonlyArray<string>): ExtensionPriority {
|
||||
for (let i = supportedExtensions.length - 1; i >= 0; i--) {
|
||||
if (fileExtensionIs(path, supportedExtensions[i])) {
|
||||
return adjustExtensionPriority(<ExtensionPriority>i, supportedExtensions);
|
||||
@@ -2195,7 +2246,7 @@ namespace ts {
|
||||
/**
|
||||
* Adjusts an extension priority to be the highest priority within the same range.
|
||||
*/
|
||||
export function adjustExtensionPriority(extensionPriority: ExtensionPriority, supportedExtensions: string[]): ExtensionPriority {
|
||||
export function adjustExtensionPriority(extensionPriority: ExtensionPriority, supportedExtensions: ReadonlyArray<string>): ExtensionPriority {
|
||||
if (extensionPriority < ExtensionPriority.DeclarationAndJavaScriptFiles) {
|
||||
return ExtensionPriority.TypeScriptFiles;
|
||||
}
|
||||
@@ -2204,12 +2255,13 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
return supportedExtensions.length;
|
||||
} }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next lowest extension priority for a given priority.
|
||||
*/
|
||||
export function getNextLowestExtensionPriority(extensionPriority: ExtensionPriority, supportedExtensions: string[]): ExtensionPriority {
|
||||
export function getNextLowestExtensionPriority(extensionPriority: ExtensionPriority, supportedExtensions: ReadonlyArray<string>): ExtensionPriority {
|
||||
if (extensionPriority < ExtensionPriority.DeclarationAndJavaScriptFiles) {
|
||||
return ExtensionPriority.DeclarationAndJavaScriptFiles;
|
||||
}
|
||||
@@ -2218,7 +2270,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const extensionsToRemove = [".d.ts", ".ts", ".js", ".tsx", ".jsx"];
|
||||
const extensionsToRemove = [Extension.Dts, Extension.Ts, Extension.Js, Extension.Tsx, Extension.Jsx];
|
||||
export function removeFileExtension(path: string): string {
|
||||
for (const ext of extensionsToRemove) {
|
||||
const extensionless = tryRemoveExtension(path, ext);
|
||||
@@ -2246,14 +2298,15 @@ namespace ts {
|
||||
getTokenConstructor(): new <TKind extends SyntaxKind>(kind: TKind, pos?: number, end?: number) => Token<TKind>;
|
||||
getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier;
|
||||
getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile;
|
||||
getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol;
|
||||
getSymbolConstructor(): new (flags: SymbolFlags, name: __String) => Symbol;
|
||||
getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type;
|
||||
getSignatureConstructor(): new (checker: TypeChecker) => Signature;
|
||||
getSourceMapSourceConstructor(): new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource;
|
||||
}
|
||||
|
||||
function Symbol(this: Symbol, flags: SymbolFlags, name: string) {
|
||||
function Symbol(this: Symbol, flags: SymbolFlags, name: __String) {
|
||||
this.flags = flags;
|
||||
this.name = name;
|
||||
this.escapedName = name;
|
||||
this.declarations = undefined;
|
||||
}
|
||||
|
||||
@@ -2279,6 +2332,12 @@ namespace ts {
|
||||
this.original = undefined;
|
||||
}
|
||||
|
||||
function SourceMapSource(this: SourceMapSource, fileName: string, text: string, skipTrivia?: (pos: number) => number) {
|
||||
this.fileName = fileName;
|
||||
this.text = text;
|
||||
this.skipTrivia = skipTrivia || (pos => pos);
|
||||
}
|
||||
|
||||
export let objectAllocator: ObjectAllocator = {
|
||||
getNodeConstructor: () => <any>Node,
|
||||
getTokenConstructor: () => <any>Node,
|
||||
@@ -2286,7 +2345,8 @@ namespace ts {
|
||||
getSourceFileConstructor: () => <any>Node,
|
||||
getSymbolConstructor: () => <any>Symbol,
|
||||
getTypeConstructor: () => <any>Type,
|
||||
getSignatureConstructor: () => <any>Signature
|
||||
getSignatureConstructor: () => <any>Signature,
|
||||
getSourceMapSourceConstructor: () => <any>SourceMapSource,
|
||||
};
|
||||
|
||||
export const enum AssertionLevel {
|
||||
@@ -2315,7 +2375,7 @@ namespace ts {
|
||||
|
||||
export function fail(message?: string, stackCrawlMark?: Function): void {
|
||||
debugger;
|
||||
const e = new Error(message ? `Debug Failure. ` : "Debug Failure.");
|
||||
const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure.");
|
||||
if ((<any>Error).captureStackTrace) {
|
||||
(<any>Error).captureStackTrace(e, stackCrawlMark || fail);
|
||||
}
|
||||
@@ -2390,7 +2450,7 @@ namespace ts {
|
||||
* (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.)
|
||||
*/
|
||||
/* @internal */
|
||||
export function matchPatternOrExact(patternStrings: string[], candidate: string): string | Pattern | undefined {
|
||||
export function matchPatternOrExact(patternStrings: ReadonlyArray<string>, candidate: string): string | Pattern | undefined {
|
||||
const patterns: Pattern[] = [];
|
||||
for (const patternString of patternStrings) {
|
||||
const pattern = tryParsePattern(patternString);
|
||||
@@ -2423,7 +2483,7 @@ namespace ts {
|
||||
|
||||
/** Return the object corresponding to the best pattern to match `candidate`. */
|
||||
/* @internal */
|
||||
export function findBestPatternMatch<T>(values: T[], getPattern: (value: T) => Pattern, candidate: string): T | undefined {
|
||||
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
|
||||
let longestMatchPrefixLength = -1;
|
||||
@@ -2464,7 +2524,7 @@ namespace ts {
|
||||
|
||||
/** True if an extension is one of the supported TypeScript extensions. */
|
||||
export function extensionIsTypeScript(ext: Extension): boolean {
|
||||
return ext <= Extension.LastTypeScriptExtension;
|
||||
return ext === Extension.Ts || ext === Extension.Tsx || ext === Extension.Dts;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2479,24 +2539,10 @@ namespace ts {
|
||||
Debug.fail(`File ${path} has unknown extension.`);
|
||||
}
|
||||
export function tryGetExtensionFromPath(path: string): Extension | undefined {
|
||||
if (fileExtensionIs(path, ".d.ts")) {
|
||||
return Extension.Dts;
|
||||
}
|
||||
if (fileExtensionIs(path, ".ts")) {
|
||||
return Extension.Ts;
|
||||
}
|
||||
if (fileExtensionIs(path, ".tsx")) {
|
||||
return Extension.Tsx;
|
||||
}
|
||||
if (fileExtensionIs(path, ".js")) {
|
||||
return Extension.Js;
|
||||
}
|
||||
if (fileExtensionIs(path, ".jsx")) {
|
||||
return Extension.Jsx;
|
||||
}
|
||||
return find<Extension>(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) || find(supportedJavascriptExtensions, e => fileExtensionIs(path, e));
|
||||
}
|
||||
|
||||
export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) {
|
||||
return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ namespace ts {
|
||||
decreaseIndent = newWriter.decreaseIndent;
|
||||
}
|
||||
|
||||
function writeAsynchronousModuleElements(nodes: Node[]) {
|
||||
function writeAsynchronousModuleElements(nodes: ReadonlyArray<Node>) {
|
||||
const oldWriter = writer;
|
||||
forEach(nodes, declaration => {
|
||||
let nodeToCheck: Node;
|
||||
@@ -335,9 +335,12 @@ namespace ts {
|
||||
write(": ");
|
||||
|
||||
// use the checker's type, not the declared type,
|
||||
// for non-optional initialized parameters that aren't a parameter property
|
||||
// for optional parameter properties
|
||||
// and also for non-optional initialized parameters that aren't a parameter property
|
||||
// these types may need to add `undefined`.
|
||||
const shouldUseResolverType = declaration.kind === SyntaxKind.Parameter &&
|
||||
resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration);
|
||||
(resolver.isRequiredInitializedParameter(declaration as ParameterDeclaration) ||
|
||||
resolver.isOptionalUninitializedParameterProperty(declaration as ParameterDeclaration));
|
||||
if (type && !shouldUseResolverType) {
|
||||
// Write the type
|
||||
emitType(type);
|
||||
@@ -371,13 +374,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitLines(nodes: Node[]) {
|
||||
function emitLines(nodes: ReadonlyArray<Node>) {
|
||||
for (const node of nodes) {
|
||||
emit(node);
|
||||
}
|
||||
}
|
||||
|
||||
function emitSeparatedList(nodes: Node[], separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
|
||||
function emitSeparatedList(nodes: ReadonlyArray<Node>, separator: string, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
|
||||
let currentWriterPos = writer.getTextPos();
|
||||
for (const node of nodes) {
|
||||
if (!canEmitFn || canEmitFn(node)) {
|
||||
@@ -390,7 +393,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitCommaList(nodes: Node[], eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
|
||||
function emitCommaList(nodes: ReadonlyArray<Node>, eachNodeEmitFn: (node: Node) => void, canEmitFn?: (node: Node) => boolean) {
|
||||
emitSeparatedList(nodes, ", ", eachNodeEmitFn, canEmitFn);
|
||||
}
|
||||
|
||||
@@ -596,7 +599,7 @@ namespace ts {
|
||||
currentIdentifiers = node.identifiers;
|
||||
isCurrentFileExternalModule = isExternalModule(node);
|
||||
enclosingDeclaration = node;
|
||||
emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, /*removeComents*/ true);
|
||||
emitDetachedComments(currentText, currentLineMap, writer, writeCommentRange, node, newLine, /*removeComments*/ true);
|
||||
emitLines(node.statements);
|
||||
}
|
||||
|
||||
@@ -1004,7 +1007,7 @@ namespace ts {
|
||||
return node.parent.kind === SyntaxKind.MethodDeclaration && hasModifier(node.parent, ModifierFlags.Private);
|
||||
}
|
||||
|
||||
function emitTypeParameters(typeParameters: TypeParameterDeclaration[]) {
|
||||
function emitTypeParameters(typeParameters: ReadonlyArray<TypeParameterDeclaration>) {
|
||||
function emitTypeParameter(node: TypeParameterDeclaration) {
|
||||
increaseIndent();
|
||||
emitJsDocComments(node);
|
||||
@@ -1106,7 +1109,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitHeritageClause(typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) {
|
||||
function emitHeritageClause(typeReferences: ReadonlyArray<ExpressionWithTypeArguments>, isImplementsList: boolean) {
|
||||
if (typeReferences) {
|
||||
write(isImplementsList ? " implements " : " extends ");
|
||||
emitCommaList(typeReferences, emitTypeOfTypeReference);
|
||||
@@ -1161,7 +1164,7 @@ namespace ts {
|
||||
if (baseTypeNode && !isEntityNameExpression(baseTypeNode.expression)) {
|
||||
tempVarName = baseTypeNode.expression.kind === SyntaxKind.NullKeyword ?
|
||||
"null" :
|
||||
emitTempVariableDeclaration(baseTypeNode.expression, `${node.name.text}_base`, {
|
||||
emitTempVariableDeclaration(baseTypeNode.expression, `${node.name.escapedText}_base`, {
|
||||
diagnosticMessage: Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1,
|
||||
errorNode: baseTypeNode,
|
||||
typeName: node.name
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
{
|
||||
"Unterminated string literal.": {
|
||||
"category": "Error",
|
||||
"code": 1002
|
||||
@@ -707,7 +707,7 @@
|
||||
"category": "Error",
|
||||
"code": 1223
|
||||
},
|
||||
"Signature '{0}' must have a type predicate.": {
|
||||
"Signature '{0}' must be a type predicate.": {
|
||||
"category": "Error",
|
||||
"code": 1224
|
||||
},
|
||||
@@ -899,6 +899,14 @@
|
||||
"category": "Error",
|
||||
"code": 1326
|
||||
},
|
||||
"String literal with double quotes expected.": {
|
||||
"category": "Error",
|
||||
"code": 1327
|
||||
},
|
||||
"Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal.": {
|
||||
"category": "Error",
|
||||
"code": 1328
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
@@ -2056,7 +2064,7 @@
|
||||
"category": "Error",
|
||||
"code": 2679
|
||||
},
|
||||
"A 'this' parameter must be the first parameter.": {
|
||||
"A '{0}' parameter must be the first parameter.": {
|
||||
"category": "Error",
|
||||
"code": 2680
|
||||
},
|
||||
@@ -2184,6 +2192,10 @@
|
||||
"category": "Error",
|
||||
"code": 2712
|
||||
},
|
||||
"Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?": {
|
||||
"category": "Error",
|
||||
"code": 2713
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@@ -2650,7 +2662,7 @@
|
||||
"category": "Message",
|
||||
"code": 6015
|
||||
},
|
||||
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.": {
|
||||
"Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'.": {
|
||||
"category": "Message",
|
||||
"code": 6016
|
||||
},
|
||||
@@ -3278,6 +3290,10 @@
|
||||
"category": "Message",
|
||||
"code": 6184
|
||||
},
|
||||
"Disable strict checking of generic signatures in function types.": {
|
||||
"category": "Message",
|
||||
"code": 6185
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
@@ -3443,6 +3459,10 @@
|
||||
"category": "Error",
|
||||
"code": 8012
|
||||
},
|
||||
"'non-null assertions' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8013
|
||||
},
|
||||
"'enum declarations' can only be used in a .ts file.": {
|
||||
"category": "Error",
|
||||
"code": 8015
|
||||
@@ -3451,6 +3471,22 @@
|
||||
"category": "Error",
|
||||
"code": 8016
|
||||
},
|
||||
"Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 8017
|
||||
},
|
||||
"Octal literals are not allowed in enums members initializer. Use the syntax '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 8018
|
||||
},
|
||||
"Report errors in .js files.": {
|
||||
"category": "Message",
|
||||
"code": 8019
|
||||
},
|
||||
"JSDoc types can only be used inside documentation comments.": {
|
||||
"category": "Error",
|
||||
"code": 8020
|
||||
},
|
||||
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": {
|
||||
"category": "Error",
|
||||
"code": 9002
|
||||
@@ -3621,7 +3657,15 @@
|
||||
"category": "Message",
|
||||
"code": 90024
|
||||
},
|
||||
|
||||
"Prefix '{0}' with an underscore.": {
|
||||
"category": "Message",
|
||||
"code": 90025
|
||||
},
|
||||
"Rewrite as the indexed access type '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 90026
|
||||
},
|
||||
|
||||
"Convert function to an ES2015 class": {
|
||||
"category": "Message",
|
||||
"code": 95001
|
||||
@@ -3629,18 +3673,5 @@
|
||||
"Convert function '{0}' to class": {
|
||||
"category": "Message",
|
||||
"code": 95002
|
||||
},
|
||||
|
||||
"Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 8017
|
||||
},
|
||||
"Octal literals are not allowed in enums members initializer. Use the syntax '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 8018
|
||||
},
|
||||
"Report errors in .js files.": {
|
||||
"category": "Message",
|
||||
"code": 8019
|
||||
}
|
||||
}
|
||||
|
||||
+97
-19
@@ -8,6 +8,70 @@ namespace ts {
|
||||
const delimiters = createDelimiterMap();
|
||||
const brackets = createBracketsMap();
|
||||
|
||||
/*@internal*/
|
||||
/**
|
||||
* Iterates over the source files that are expected to have an emit output.
|
||||
*
|
||||
* @param host An EmitHost.
|
||||
* @param action The action to execute.
|
||||
* @param sourceFilesOrTargetSourceFile
|
||||
* If an array, the full list of source files to emit.
|
||||
* Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit.
|
||||
*/
|
||||
export function forEachEmittedFile(
|
||||
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle, emitOnlyDtsFiles: boolean) => void,
|
||||
sourceFilesOrTargetSourceFile?: SourceFile[] | SourceFile,
|
||||
emitOnlyDtsFiles?: boolean) {
|
||||
|
||||
const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile);
|
||||
const options = host.getCompilerOptions();
|
||||
if (options.outFile || options.out) {
|
||||
if (sourceFiles.length) {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = options.declaration ? removeFileExtension(jsFilePath) + Extension.Dts : "";
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, createBundle(sourceFiles), emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const sourceFile of sourceFiles) {
|
||||
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = !isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
|
||||
action({ jsFilePath, sourceMapFilePath, declarationFilePath }, sourceFile, emitOnlyDtsFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) {
|
||||
return options.sourceMap ? jsFilePath + ".map" : undefined;
|
||||
}
|
||||
|
||||
// JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
|
||||
// So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
|
||||
// For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
|
||||
function getOutputExtension(sourceFile: SourceFile, options: CompilerOptions): Extension {
|
||||
if (options.jsx === JsxEmit.Preserve) {
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
if (fileExtensionIs(sourceFile.fileName, Extension.Jsx)) {
|
||||
return Extension.Jsx;
|
||||
}
|
||||
}
|
||||
else if (sourceFile.languageVariant === LanguageVariant.JSX) {
|
||||
// TypeScript source file preserving JSX syntax
|
||||
return Extension.Jsx;
|
||||
}
|
||||
}
|
||||
return Extension.Js;
|
||||
}
|
||||
|
||||
function getOriginalSourceFileOrBundle(sourceFileOrBundle: SourceFile | Bundle) {
|
||||
if (sourceFileOrBundle.kind === SyntaxKind.Bundle) {
|
||||
return updateBundle(sourceFileOrBundle, sameMap(sourceFileOrBundle.sourceFiles, getOriginalSourceFile));
|
||||
}
|
||||
return getOriginalSourceFile(sourceFileOrBundle);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<SourceFile>[]): EmitResult {
|
||||
@@ -217,7 +281,7 @@ namespace ts {
|
||||
let currentSourceFile: SourceFile | undefined;
|
||||
let nodeIdToGeneratedName: string[]; // Map of generated names for specific nodes.
|
||||
let autoGeneratedIdToGeneratedName: string[]; // Map of generated names for temp and loop variables.
|
||||
let generatedNames: Map<string>; // Set of names generated by the NameGenerator.
|
||||
let generatedNames: Map<true>; // Set of names generated by the NameGenerator.
|
||||
let tempFlagsStack: TempFlags[]; // Stack of enclosing name generation scopes.
|
||||
let tempFlags: TempFlags; // TempFlags for the current name generation scope.
|
||||
let writer: EmitTextWriter;
|
||||
@@ -335,7 +399,7 @@ namespace ts {
|
||||
function reset() {
|
||||
nodeIdToGeneratedName = [];
|
||||
autoGeneratedIdToGeneratedName = [];
|
||||
generatedNames = createMap<string>();
|
||||
generatedNames = createMap<true>();
|
||||
tempFlagsStack = [];
|
||||
tempFlags = TempFlags.Auto;
|
||||
comments.reset();
|
||||
@@ -959,7 +1023,7 @@ namespace ts {
|
||||
function emitConstructorType(node: ConstructorTypeNode) {
|
||||
write("new ");
|
||||
emitTypeParameters(node, node.typeParameters);
|
||||
emitParametersForArrow(node, node.parameters);
|
||||
emitParameters(node, node.parameters);
|
||||
write(" => ");
|
||||
emit(node.type);
|
||||
}
|
||||
@@ -2164,7 +2228,7 @@ namespace ts {
|
||||
* Emits any prologue directives at the start of a Statement list, returning the
|
||||
* number of prologue directives written to the output.
|
||||
*/
|
||||
function emitPrologueDirectives(statements: Node[], startWithNewLine?: boolean, seenPrologueDirectives?: Map<String>): number {
|
||||
function emitPrologueDirectives(statements: ReadonlyArray<Node>, startWithNewLine?: boolean, seenPrologueDirectives?: Map<true>): number {
|
||||
for (let i = 0; i < statements.length; i++) {
|
||||
const statement = statements[i];
|
||||
if (isPrologueDirective(statement)) {
|
||||
@@ -2175,7 +2239,7 @@ namespace ts {
|
||||
}
|
||||
emit(statement);
|
||||
if (seenPrologueDirectives) {
|
||||
seenPrologueDirectives.set(statement.expression.text, statement.expression.text);
|
||||
seenPrologueDirectives.set(statement.expression.text, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2194,7 +2258,7 @@ namespace ts {
|
||||
emitPrologueDirectives((sourceFileOrBundle as SourceFile).statements);
|
||||
}
|
||||
else {
|
||||
const seenPrologueDirectives = createMap<String>();
|
||||
const seenPrologueDirectives = createMap<true>();
|
||||
for (const sourceFile of (sourceFileOrBundle as Bundle).sourceFiles) {
|
||||
setSourceFile(sourceFile);
|
||||
emitPrologueDirectives(sourceFile.statements, /*startWithNewLine*/ true, seenPrologueDirectives);
|
||||
@@ -2283,11 +2347,25 @@ namespace ts {
|
||||
emitList(parentNode, parameters, ListFormat.Parameters);
|
||||
}
|
||||
|
||||
function emitParametersForArrow(parentNode: Node, parameters: NodeArray<ParameterDeclaration>) {
|
||||
if (parameters &&
|
||||
parameters.length === 1 &&
|
||||
parameters[0].type === undefined &&
|
||||
parameters[0].pos === parentNode.pos) {
|
||||
function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray<ParameterDeclaration>) {
|
||||
const parameter = singleOrUndefined(parameters);
|
||||
return parameter
|
||||
&& parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter
|
||||
&& !(isArrowFunction(parentNode) && parentNode.type) // arrow function may not have return type annotation
|
||||
&& !some(parentNode.decorators) // parent may not have decorators
|
||||
&& !some(parentNode.modifiers) // parent may not have modifiers
|
||||
&& !some(parentNode.typeParameters) // parent may not have type parameters
|
||||
&& !some(parameter.decorators) // parameter may not have decorators
|
||||
&& !some(parameter.modifiers) // parameter may not have modifiers
|
||||
&& !parameter.dotDotDotToken // parameter may not be rest
|
||||
&& !parameter.questionToken // parameter may not be optional
|
||||
&& !parameter.type // parameter may not have a type annotation
|
||||
&& !parameter.initializer // parameter may not have an initializer
|
||||
&& isIdentifier(parameter.name); // parameter name must be identifier
|
||||
}
|
||||
|
||||
function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray<ParameterDeclaration>) {
|
||||
if (canEmitSimpleArrowHead(parentNode, parameters)) {
|
||||
emit(parameters[0]);
|
||||
}
|
||||
else {
|
||||
@@ -2683,7 +2761,7 @@ namespace ts {
|
||||
return generateName(node);
|
||||
}
|
||||
else if (isIdentifier(node) && (nodeIsSynthesized(node) || !node.parent)) {
|
||||
return unescapeIdentifier(node.text);
|
||||
return unescapeLeadingUnderscores(node.escapedText);
|
||||
}
|
||||
else if (node.kind === SyntaxKind.StringLiteral && (<StringLiteral>node).textSourceNode) {
|
||||
return getTextOfNode((<StringLiteral>node).textSourceNode, includeTrivia);
|
||||
@@ -2740,13 +2818,13 @@ namespace ts {
|
||||
// Auto, Loop, and Unique names are cached based on their unique
|
||||
// autoGenerateId.
|
||||
const autoGenerateId = name.autoGenerateId;
|
||||
return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = unescapeIdentifier(makeName(name)));
|
||||
return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name));
|
||||
}
|
||||
}
|
||||
|
||||
function generateNameCached(node: Node) {
|
||||
const nodeId = getNodeId(node);
|
||||
return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = unescapeIdentifier(generateNameForNode(node)));
|
||||
return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = generateNameForNode(node));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2765,7 +2843,7 @@ namespace ts {
|
||||
function isUniqueLocalName(name: string, container: Node): boolean {
|
||||
for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer) {
|
||||
if (node.locals) {
|
||||
const local = node.locals.get(name);
|
||||
const local = node.locals.get(escapeLeadingUnderscores(name));
|
||||
// We conservatively include alias symbols to cover cases where they're emitted as locals
|
||||
if (local && local.flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) {
|
||||
return false;
|
||||
@@ -2818,7 +2896,7 @@ namespace ts {
|
||||
while (true) {
|
||||
const generatedName = baseName + i;
|
||||
if (isUniqueName(generatedName)) {
|
||||
generatedNames.set(generatedName, generatedName);
|
||||
generatedNames.set(generatedName, true);
|
||||
return generatedName;
|
||||
}
|
||||
i++;
|
||||
@@ -2839,8 +2917,8 @@ namespace ts {
|
||||
*/
|
||||
function generateNameForImportOrExportDeclaration(node: ImportDeclaration | ExportDeclaration) {
|
||||
const expr = getExternalModuleName(node);
|
||||
const baseName = expr.kind === SyntaxKind.StringLiteral ?
|
||||
escapeIdentifier(makeIdentifierFromModuleName((<LiteralExpression>expr).text)) : "module";
|
||||
const baseName = isStringLiteral(expr) ?
|
||||
makeIdentifierFromModuleName(expr.text) : "module";
|
||||
return makeUniqueName(baseName);
|
||||
}
|
||||
|
||||
@@ -2903,7 +2981,7 @@ namespace ts {
|
||||
case GeneratedIdentifierKind.Loop:
|
||||
return makeTempVariableName(TempFlags._i);
|
||||
case GeneratedIdentifierKind.Unique:
|
||||
return makeUniqueName(unescapeIdentifier(name.text));
|
||||
return makeUniqueName(unescapeLeadingUnderscores(name.escapedText));
|
||||
}
|
||||
|
||||
Debug.fail("Unsupported GeneratedIdentifierKind.");
|
||||
|
||||
+381
-323
File diff suppressed because it is too large
Load Diff
@@ -13,12 +13,6 @@ namespace ts {
|
||||
return compilerOptions.traceResolution && host.trace !== undefined;
|
||||
}
|
||||
|
||||
/** Array that is only intended to be pushed to, never read. */
|
||||
/* @internal */
|
||||
export interface Push<T> {
|
||||
push(value: T): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of trying to resolve a module.
|
||||
* At least one of `ts` and `js` should be defined, or the whole thing should be `undefined`.
|
||||
@@ -54,10 +48,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function moduleHasNonRelativeName(moduleName: string): boolean {
|
||||
return !(isRootedDiskPath(moduleName) || isExternalModuleNameRelative(moduleName));
|
||||
}
|
||||
|
||||
interface ModuleResolutionState {
|
||||
host: ModuleResolutionHost;
|
||||
compilerOptions: CompilerOptions;
|
||||
@@ -151,11 +141,7 @@ namespace ts {
|
||||
*/
|
||||
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(options, host);
|
||||
const moduleResolutionState: ModuleResolutionState = {
|
||||
compilerOptions: options,
|
||||
host: host,
|
||||
traceEnabled
|
||||
};
|
||||
const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled };
|
||||
|
||||
const typeRoots = getEffectiveTypeRoots(options, host);
|
||||
if (traceEnabled) {
|
||||
@@ -270,6 +256,8 @@ namespace ts {
|
||||
for (const typeDirectivePath of host.getDirectories(root)) {
|
||||
const normalized = normalizePath(typeDirectivePath);
|
||||
const packageJsonPath = pathToPackageJson(combinePaths(root, normalized));
|
||||
// `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
|
||||
// See `createNotNeededPackageJSON` in the types-publisher` repo.
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
const isNotNeededPackage = host.fileExists(packageJsonPath) && readJson(packageJsonPath, host).typings === null;
|
||||
if (!isNotNeededPackage) {
|
||||
@@ -306,7 +294,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache {
|
||||
const directoryToModuleNameMap = createFileMap<Map<ResolvedModuleWithFailedLookupLocations>>();
|
||||
const directoryToModuleNameMap = createMap<Map<ResolvedModuleWithFailedLookupLocations>>();
|
||||
const moduleNameToDirectoryMap = createMap<PerModuleNameCache>();
|
||||
|
||||
return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName };
|
||||
@@ -322,7 +310,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string) {
|
||||
if (!moduleHasNonRelativeName(nonRelativeModuleName)) {
|
||||
if (isExternalModuleNameRelative(nonRelativeModuleName)) {
|
||||
return undefined;
|
||||
}
|
||||
let perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName);
|
||||
@@ -334,7 +322,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createPerModuleNameCache(): PerModuleNameCache {
|
||||
const directoryPathMap = createFileMap<ResolvedModuleWithFailedLookupLocations>();
|
||||
const directoryPathMap = createMap<ResolvedModuleWithFailedLookupLocations>();
|
||||
|
||||
return { get, set };
|
||||
|
||||
@@ -356,7 +344,7 @@ namespace ts {
|
||||
function set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void {
|
||||
const path = toPath(directory, currentDirectory, getCanonicalFileName);
|
||||
// if entry is already in cache do nothing
|
||||
if (directoryPathMap.contains(path)) {
|
||||
if (directoryPathMap.has(path)) {
|
||||
return;
|
||||
}
|
||||
directoryPathMap.set(path, result);
|
||||
@@ -370,7 +358,7 @@ namespace ts {
|
||||
let current = path;
|
||||
while (true) {
|
||||
const parent = getDirectoryPath(current);
|
||||
if (parent === current || directoryPathMap.contains(parent)) {
|
||||
if (parent === current || directoryPathMap.has(parent)) {
|
||||
break;
|
||||
}
|
||||
directoryPathMap.set(parent, result);
|
||||
@@ -539,7 +527,7 @@ namespace ts {
|
||||
function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
|
||||
failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined {
|
||||
|
||||
if (moduleHasNonRelativeName(moduleName)) {
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state);
|
||||
}
|
||||
else {
|
||||
@@ -715,7 +703,7 @@ namespace ts {
|
||||
return toSearchResult({ resolved, isExternalLibraryImport: false });
|
||||
}
|
||||
|
||||
if (moduleHasNonRelativeName(moduleName)) {
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
|
||||
}
|
||||
@@ -815,15 +803,15 @@ namespace ts {
|
||||
|
||||
switch (extensions) {
|
||||
case Extensions.DtsOnly:
|
||||
return tryExtension(".d.ts", Extension.Dts);
|
||||
return tryExtension(Extension.Dts);
|
||||
case Extensions.TypeScript:
|
||||
return tryExtension(".ts", Extension.Ts) || tryExtension(".tsx", Extension.Tsx) || tryExtension(".d.ts", Extension.Dts);
|
||||
return tryExtension(Extension.Ts) || tryExtension(Extension.Tsx) || tryExtension(Extension.Dts);
|
||||
case Extensions.JavaScript:
|
||||
return tryExtension(".js", Extension.Js) || tryExtension(".jsx", Extension.Jsx);
|
||||
return tryExtension(Extension.Js) || tryExtension(Extension.Jsx);
|
||||
}
|
||||
|
||||
function tryExtension(ext: string, extension: Extension): Resolved | undefined {
|
||||
const path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state);
|
||||
function tryExtension(extension: Extension): Resolved | undefined {
|
||||
const path = tryFile(candidate + extension, failedLookupLocations, onlyRecordFailures, state);
|
||||
return path && { path, extension };
|
||||
}
|
||||
}
|
||||
@@ -995,7 +983,7 @@ namespace ts {
|
||||
export function getPackageNameFromAtTypesDirectory(mangledName: string): string {
|
||||
const withoutAtTypePrefix = removePrefix(mangledName, "@types/");
|
||||
if (withoutAtTypePrefix !== mangledName) {
|
||||
return withoutAtTypePrefix.indexOf("__") !== -1 ?
|
||||
return withoutAtTypePrefix.indexOf(mangledScopedPackageSeparator) !== -1 ?
|
||||
"@" + withoutAtTypePrefix.replace(mangledScopedPackageSeparator, ts.directorySeparator) :
|
||||
withoutAtTypePrefix;
|
||||
}
|
||||
@@ -1028,7 +1016,7 @@ namespace ts {
|
||||
}
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
|
||||
|
||||
if (moduleHasNonRelativeName(moduleName)) {
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
// Climb up parent directories looking for a module.
|
||||
const resolved = forEachAncestorDirectory(containingDirectory, directory => {
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host);
|
||||
|
||||
+583
-686
File diff suppressed because it is too large
Load Diff
+202
-74
@@ -3,7 +3,6 @@
|
||||
/// <reference path="core.ts" />
|
||||
|
||||
namespace ts {
|
||||
const emptyArray: any[] = [];
|
||||
const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
|
||||
|
||||
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string {
|
||||
@@ -332,6 +331,7 @@ namespace ts {
|
||||
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;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -382,7 +382,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
interface DiagnosticCache {
|
||||
perFile?: FileMap<Diagnostic[]>;
|
||||
perFile?: Map<Diagnostic[]>;
|
||||
allDiagnostics?: Diagnostic[];
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ namespace ts {
|
||||
let commonSourceDirectory: string;
|
||||
let diagnosticsProducingTypeChecker: TypeChecker;
|
||||
let noDiagnosticsTypeChecker: TypeChecker;
|
||||
let classifiableNames: Map<string>;
|
||||
let classifiableNames: UnderscoreEscapedMap<true>;
|
||||
let modifiedFilePaths: Path[] | undefined;
|
||||
|
||||
const cachedSemanticDiagnosticsForFile: DiagnosticCache = {};
|
||||
@@ -441,12 +441,13 @@ namespace ts {
|
||||
const supportedExtensions = getSupportedExtensions(options);
|
||||
|
||||
// Map storing if there is emit blocking diagnostics for given input
|
||||
const hasEmitBlockingDiagnostics = createFileMap<boolean>(getCanonicalFileName);
|
||||
const hasEmitBlockingDiagnostics = createMap<boolean>();
|
||||
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression;
|
||||
|
||||
let moduleResolutionCache: ModuleResolutionCache;
|
||||
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => ResolvedModuleFull[];
|
||||
if (host.resolveModuleNames) {
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile).map(resolved => {
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(checkAllDefined(moduleNames), containingFile).map(resolved => {
|
||||
// An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
|
||||
if (!resolved || (resolved as ResolvedModuleFull).extension !== undefined) {
|
||||
return resolved as ResolvedModuleFull;
|
||||
@@ -459,22 +460,22 @@ namespace ts {
|
||||
else {
|
||||
moduleResolutionCache = createModuleResolutionCache(currentDirectory, x => host.getCanonicalFileName(x));
|
||||
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule;
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => loadWithLocalCache(moduleNames, containingFile, loader);
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => loadWithLocalCache(checkAllDefined(moduleNames), containingFile, loader);
|
||||
}
|
||||
|
||||
let resolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[], containingFile: string) => ResolvedTypeReferenceDirective[];
|
||||
if (host.resolveTypeReferenceDirectives) {
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile);
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives(checkAllDefined(typeDirectiveNames), containingFile);
|
||||
}
|
||||
else {
|
||||
const loader = (typesRef: string, containingFile: string) => resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective;
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile) => loadWithLocalCache(typeReferenceDirectiveNames, containingFile, loader);
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile) => loadWithLocalCache(checkAllDefined(typeReferenceDirectiveNames), containingFile, loader);
|
||||
}
|
||||
|
||||
const filesByName = createFileMap<SourceFile>();
|
||||
const filesByName = createMap<SourceFile | undefined>();
|
||||
// stores 'filename -> file association' ignoring case
|
||||
// used to track cases when two file names differ only in casing
|
||||
const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createFileMap<SourceFile>(fileName => fileName.toLowerCase()) : undefined;
|
||||
const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createMap<SourceFile>() : undefined;
|
||||
|
||||
const structuralIsReused = tryReuseStructureFromOldProgram();
|
||||
if (structuralIsReused !== StructureIsReused.Completely) {
|
||||
@@ -512,6 +513,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const missingFilePaths = arrayFrom(filesByName.keys(), p => <Path>p).filter(p => !filesByName.get(p));
|
||||
|
||||
// unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks
|
||||
moduleResolutionCache = undefined;
|
||||
|
||||
@@ -523,6 +526,7 @@ namespace ts {
|
||||
getSourceFile,
|
||||
getSourceFileByPath,
|
||||
getSourceFiles: () => files,
|
||||
getMissingFilePaths: () => missingFilePaths,
|
||||
getCompilerOptions: () => options,
|
||||
getSyntacticDiagnostics,
|
||||
getOptionsDiagnostics,
|
||||
@@ -552,6 +556,10 @@ namespace ts {
|
||||
|
||||
return program;
|
||||
|
||||
function toPath(fileName: string): Path {
|
||||
return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
|
||||
}
|
||||
|
||||
function getCommonSourceDirectory() {
|
||||
if (commonSourceDirectory === undefined) {
|
||||
const emittedFiles = filter(files, file => sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary));
|
||||
@@ -576,7 +584,7 @@ namespace ts {
|
||||
if (!classifiableNames) {
|
||||
// Initialize a checker so that all our files are bound.
|
||||
getTypeChecker();
|
||||
classifiableNames = createMap<string>();
|
||||
classifiableNames = createUnderscoreEscapedMap<true>();
|
||||
|
||||
for (const sourceFile of files) {
|
||||
copyEntries(sourceFile.classifiableNames, classifiableNames);
|
||||
@@ -802,6 +810,10 @@ namespace ts {
|
||||
// moduleAugmentations has changed
|
||||
oldProgram.structureIsReused = StructureIsReused.SafeModules;
|
||||
}
|
||||
if ((oldSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport) !== (newSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport)) {
|
||||
// dynamicImport has changed
|
||||
oldProgram.structureIsReused = StructureIsReused.SafeModules;
|
||||
}
|
||||
|
||||
if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) {
|
||||
// 'types' references has changed
|
||||
@@ -857,6 +869,21 @@ namespace ts {
|
||||
return oldProgram.structureIsReused;
|
||||
}
|
||||
|
||||
// If a file has ceased to be missing, then we need to discard some of the old
|
||||
// structure in order to pick it up.
|
||||
// Caution: if the file has created and then deleted between since it was discovered to
|
||||
// be missing, then the corresponding file watcher will have been closed and no new one
|
||||
// will be created until we encounter a change that prevents complete structure reuse.
|
||||
// During this interval, creation of the file will go unnoticed. We expect this to be
|
||||
// both rare and low-impact.
|
||||
if (oldProgram.getMissingFilePaths().some(missingFilePath => host.fileExists(missingFilePath))) {
|
||||
return oldProgram.structureIsReused = StructureIsReused.SafeModules;
|
||||
}
|
||||
|
||||
for (const p of oldProgram.getMissingFilePaths()) {
|
||||
filesByName.set(p, undefined);
|
||||
}
|
||||
|
||||
// update fileName -> file mapping
|
||||
for (let i = 0; i < newSourceFiles.length; i++) {
|
||||
filesByName.set(filePaths[i], newSourceFiles[i]);
|
||||
@@ -911,7 +938,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isEmitBlocked(emitFileName: string): boolean {
|
||||
return hasEmitBlockingDiagnostics.contains(toPath(emitFileName, currentDirectory, getCanonicalFileName));
|
||||
return hasEmitBlockingDiagnostics.has(toPath(emitFileName));
|
||||
}
|
||||
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult {
|
||||
@@ -970,7 +997,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getSourceFile(fileName: string): SourceFile {
|
||||
return getSourceFileByPath(toPath(fileName, currentDirectory, getCanonicalFileName));
|
||||
return getSourceFileByPath(toPath(fileName));
|
||||
}
|
||||
|
||||
function getSourceFileByPath(path: Path): SourceFile {
|
||||
@@ -1132,7 +1159,6 @@ namespace ts {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
// type annotation
|
||||
if ((<FunctionLikeDeclaration | VariableDeclaration | ParameterDeclaration | PropertyDeclaration>parent).type === node) {
|
||||
@@ -1170,10 +1196,14 @@ namespace ts {
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
const typeAssertionExpression = <TypeAssertion>node;
|
||||
diagnostics.push(createDiagnosticForNode(typeAssertionExpression.type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
|
||||
case SyntaxKind.NonNullExpression:
|
||||
diagnostics.push(createDiagnosticForNode(node, Diagnostics.non_null_assertions_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
case SyntaxKind.AsExpression:
|
||||
diagnostics.push(createDiagnosticForNode((node as AsExpression).type, Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file));
|
||||
return;
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
Debug.fail(); // Won't parse these in a JS file anyway, as they are interpreted as JSX.
|
||||
}
|
||||
|
||||
const prevParent = parent;
|
||||
@@ -1197,7 +1227,6 @@ namespace ts {
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
// Check type parameters
|
||||
if (nodes === (<ClassDeclaration | FunctionLikeDeclaration>parent).typeParameters) {
|
||||
diagnostics.push(createDiagnosticForNodeArray(nodes, Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file));
|
||||
@@ -1311,7 +1340,7 @@ namespace ts {
|
||||
const result = getDiagnostics(sourceFile, cancellationToken) || emptyArray;
|
||||
if (sourceFile) {
|
||||
if (!cache.perFile) {
|
||||
cache.perFile = createFileMap<Diagnostic[]>();
|
||||
cache.perFile = createMap<Diagnostic[]>();
|
||||
}
|
||||
cache.perFile.set(sourceFile.path, result);
|
||||
}
|
||||
@@ -1328,7 +1357,11 @@ namespace ts {
|
||||
function getOptionsDiagnostics(): Diagnostic[] {
|
||||
return sortAndDeduplicateDiagnostics(concatenate(
|
||||
fileProcessingDiagnostics.getGlobalDiagnostics(),
|
||||
programDiagnostics.getGlobalDiagnostics()));
|
||||
concatenate(
|
||||
programDiagnostics.getGlobalDiagnostics(),
|
||||
options.configFile ? programDiagnostics.getDiagnostics(options.configFile.fileName) : []
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
function getGlobalDiagnostics(): Diagnostic[] {
|
||||
@@ -1360,8 +1393,8 @@ namespace ts {
|
||||
const isExternalModuleFile = isExternalModule(file);
|
||||
|
||||
// file.imports may not be undefined if there exists dynamic import
|
||||
let imports: LiteralExpression[];
|
||||
let moduleAugmentations: LiteralExpression[];
|
||||
let imports: StringLiteral[];
|
||||
let moduleAugmentations: StringLiteral[];
|
||||
let ambientModules: string[];
|
||||
|
||||
// If we are importing helpers, we need to add a synthetic reference to resolve the
|
||||
@@ -1379,7 +1412,7 @@ namespace ts {
|
||||
|
||||
for (const node of file.statements) {
|
||||
collectModuleReferences(node, /*inAmbientModule*/ false);
|
||||
if ((file.flags & NodeFlags.PossiblyContainDynamicImport) || isJavaScriptFile) {
|
||||
if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) {
|
||||
collectDynamicImportOrRequireCalls(node);
|
||||
}
|
||||
}
|
||||
@@ -1396,35 +1429,36 @@ namespace ts {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
const moduleNameExpr = getExternalModuleName(node);
|
||||
if (!moduleNameExpr || moduleNameExpr.kind !== SyntaxKind.StringLiteral) {
|
||||
if (!moduleNameExpr || !isStringLiteral(moduleNameExpr)) {
|
||||
break;
|
||||
}
|
||||
if (!(<LiteralExpression>moduleNameExpr).text) {
|
||||
if (!moduleNameExpr.text) {
|
||||
break;
|
||||
}
|
||||
|
||||
// TypeScript 1.0 spec (April 2014): 12.1.6
|
||||
// An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules
|
||||
// only through top - level external module names. Relative external module names are not permitted.
|
||||
if (!inAmbientModule || !isExternalModuleNameRelative((<LiteralExpression>moduleNameExpr).text)) {
|
||||
(imports || (imports = [])).push(<LiteralExpression>moduleNameExpr);
|
||||
if (!inAmbientModule || !isExternalModuleNameRelative(moduleNameExpr.text)) {
|
||||
(imports || (imports = [])).push(moduleNameExpr);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
if (isAmbientModule(<ModuleDeclaration>node) && (inAmbientModule || hasModifier(node, ModifierFlags.Ambient) || file.isDeclarationFile)) {
|
||||
const moduleName = <LiteralExpression>(<ModuleDeclaration>node).name;
|
||||
const moduleName = <StringLiteral>(<ModuleDeclaration>node).name; // TODO: GH#17347
|
||||
const nameText = ts.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
|
||||
// - if current file is not external module then module augmentation is an ambient module declaration with non-relative module name
|
||||
// immediately nested in top level ambient module declaration .
|
||||
if (isExternalModuleFile || (inAmbientModule && !isExternalModuleNameRelative(moduleName.text))) {
|
||||
if (isExternalModuleFile || (inAmbientModule && !isExternalModuleNameRelative(nameText))) {
|
||||
(moduleAugmentations || (moduleAugmentations = [])).push(moduleName);
|
||||
}
|
||||
else if (!inAmbientModule) {
|
||||
if (file.isDeclarationFile) {
|
||||
// for global .d.ts files record name of ambient module
|
||||
(ambientModules || (ambientModules = [])).push(moduleName.text);
|
||||
(ambientModules || (ambientModules = [])).push(nameText);
|
||||
}
|
||||
// An AmbientExternalModuleDeclaration declares an external module.
|
||||
// This type of declaration is permitted only in the global module.
|
||||
@@ -1459,7 +1493,7 @@ namespace ts {
|
||||
|
||||
/** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */
|
||||
function getSourceFileFromReference(referencingFile: SourceFile, ref: FileReference): SourceFile | undefined {
|
||||
return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), fileName => filesByName.get(toPath(fileName, currentDirectory, getCanonicalFileName)));
|
||||
return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), fileName => filesByName.get(toPath(fileName)));
|
||||
}
|
||||
|
||||
function getSourceFileFromReferenceWorker(
|
||||
@@ -1495,7 +1529,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const sourceFileWithAddedExtension = forEach(supportedExtensions, extension => getSourceFile(fileName + extension));
|
||||
if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.File_0_not_found, fileName + ".ts");
|
||||
if (fail && !sourceFileWithAddedExtension) fail(Diagnostics.File_0_not_found, fileName + Extension.Ts);
|
||||
return sourceFileWithAddedExtension;
|
||||
}
|
||||
}
|
||||
@@ -1503,7 +1537,7 @@ namespace ts {
|
||||
/** This has side effects through `findSourceFile`. */
|
||||
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): void {
|
||||
getSourceFileFromReferenceWorker(fileName,
|
||||
fileName => findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd),
|
||||
fileName => findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd),
|
||||
(diagnostic, ...args) => {
|
||||
fileProcessingDiagnostics.add(refFile !== undefined && refEnd !== undefined && refPos !== undefined
|
||||
? createFileDiagnostic(refFile, refPos, refEnd - refPos, diagnostic, ...args)
|
||||
@@ -1524,7 +1558,7 @@ namespace ts {
|
||||
|
||||
// Get source file from normalized fileName
|
||||
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
|
||||
if (filesByName.contains(path)) {
|
||||
if (filesByName.has(path)) {
|
||||
const file = filesByName.get(path);
|
||||
// try to check if we've already seen this file but with a different casing in path
|
||||
// NOTE: this only makes sense for case-insensitive file systems
|
||||
@@ -1572,13 +1606,14 @@ namespace ts {
|
||||
file.path = path;
|
||||
|
||||
if (host.useCaseSensitiveFileNames()) {
|
||||
const pathLowerCase = path.toLowerCase();
|
||||
// for case-sensitive file systems check if we've already seen some file with similar filename ignoring case
|
||||
const existingFile = filesByNameIgnoreCase.get(path);
|
||||
const existingFile = filesByNameIgnoreCase.get(pathLowerCase);
|
||||
if (existingFile) {
|
||||
reportFileNamesDifferOnlyInCasingError(fileName, existingFile.fileName, refFile, refPos, refEnd);
|
||||
}
|
||||
else {
|
||||
filesByNameIgnoreCase.set(path, file);
|
||||
filesByNameIgnoreCase.set(pathLowerCase, file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1725,7 +1760,7 @@ namespace ts {
|
||||
modulesWithElidedImports.set(file.path, true);
|
||||
}
|
||||
else if (shouldAddFile) {
|
||||
const path = toPath(resolvedFileName, currentDirectory, getCanonicalFileName);
|
||||
const path = toPath(resolvedFileName);
|
||||
const pos = skipTrivia(file.text, file.imports[i].pos);
|
||||
findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end);
|
||||
}
|
||||
@@ -1773,33 +1808,33 @@ namespace ts {
|
||||
function verifyCompilerOptions() {
|
||||
if (options.isolatedModules) {
|
||||
if (options.declaration) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules");
|
||||
}
|
||||
|
||||
if (options.noEmitOnError) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmitOnError", "isolatedModules"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmitOnError", "isolatedModules");
|
||||
}
|
||||
|
||||
if (options.out) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules");
|
||||
}
|
||||
|
||||
if (options.outFile) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.inlineSourceMap) {
|
||||
if (options.sourceMap) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap");
|
||||
}
|
||||
if (options.mapRoot) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.paths && options.baseUrl === undefined) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option, "paths");
|
||||
}
|
||||
|
||||
if (options.paths) {
|
||||
@@ -1808,63 +1843,65 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
if (!hasZeroOrOneAsteriskCharacter(key)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key));
|
||||
createDiagnosticForOptionPaths(/*onKey*/ true, key, Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key);
|
||||
}
|
||||
if (isArray(options.paths[key])) {
|
||||
if (options.paths[key].length === 0) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key));
|
||||
const len = options.paths[key].length;
|
||||
if (len === 0) {
|
||||
createDiagnosticForOptionPaths(/*onKey*/ false, key, Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key);
|
||||
}
|
||||
for (const subst of options.paths[key]) {
|
||||
for (let i = 0; i < len; i++) {
|
||||
const subst = options.paths[key][i];
|
||||
const typeOfSubst = typeof subst;
|
||||
if (typeOfSubst === "string") {
|
||||
if (!hasZeroOrOneAsteriskCharacter(subst)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key));
|
||||
createDiagnosticForOptionPathKeyValue(key, i, Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key);
|
||||
}
|
||||
}
|
||||
else {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst));
|
||||
createDiagnosticForOptionPathKeyValue(key, i, Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key));
|
||||
createDiagnosticForOptionPaths(/*onKey*/ false, key, Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.sourceMap && !options.inlineSourceMap) {
|
||||
if (options.inlineSources) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources");
|
||||
}
|
||||
if (options.sourceRoot) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.out && options.outFile) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile");
|
||||
}
|
||||
|
||||
if (options.mapRoot && !options.sourceMap) {
|
||||
// Error to specify --mapRoot without --sourcemap
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap");
|
||||
}
|
||||
|
||||
if (options.declarationDir) {
|
||||
if (!options.declaration) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationDir", "declaration"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationDir", "declaration");
|
||||
}
|
||||
if (options.out || options.outFile) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.lib && options.noLib) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib");
|
||||
}
|
||||
|
||||
if (options.noImplicitUseStrict && (options.alwaysStrict === undefined ? options.strict : options.alwaysStrict)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict");
|
||||
}
|
||||
|
||||
const languageVersion = options.target || ScriptTarget.ES3;
|
||||
@@ -1873,7 +1910,7 @@ namespace ts {
|
||||
const firstNonAmbientExternalModuleSourceFile = forEach(files, f => isExternalModule(f) && !f.isDeclarationFile ? f : undefined);
|
||||
if (options.isolatedModules) {
|
||||
if (options.module === ModuleKind.None && languageVersion < ScriptTarget.ES2015) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target");
|
||||
}
|
||||
|
||||
const firstNonExternalModuleSourceFile = forEach(files, f => !isExternalModule(f) && !f.isDeclarationFile ? f : undefined);
|
||||
@@ -1891,7 +1928,7 @@ namespace ts {
|
||||
// Cannot specify module gen that isn't amd or system with --out
|
||||
if (outFile) {
|
||||
if (options.module && !(options.module === ModuleKind.AMD || options.module === ModuleKind.System)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile"));
|
||||
createDiagnosticForOptionName(Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module");
|
||||
}
|
||||
else if (options.module === undefined && firstNonAmbientExternalModuleSourceFile) {
|
||||
const span = getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator);
|
||||
@@ -1910,12 +1947,12 @@ namespace ts {
|
||||
|
||||
// If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
|
||||
if (options.outDir && dir === "" && forEach(files, file => getRootLength(file.fileName) > 1)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
|
||||
createDiagnosticForOptionName(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir");
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.noEmit && options.allowJs && options.declaration) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration");
|
||||
}
|
||||
|
||||
if (options.checkJs && !options.allowJs) {
|
||||
@@ -1924,25 +1961,25 @@ namespace ts {
|
||||
|
||||
if (options.emitDecoratorMetadata &&
|
||||
!options.experimentalDecorators) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators");
|
||||
}
|
||||
|
||||
if (options.jsxFactory) {
|
||||
if (options.reactNamespace) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory");
|
||||
}
|
||||
if (!parseIsolatedEntityName(options.jsxFactory, languageVersion)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory));
|
||||
createOptionValueDiagnostic("jsxFactory", Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory);
|
||||
}
|
||||
}
|
||||
else if (options.reactNamespace && !isIdentifierText(options.reactNamespace, languageVersion)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace));
|
||||
createOptionValueDiagnostic("reactNamespace", Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace);
|
||||
}
|
||||
|
||||
// If the emit is enabled make sure that every output file is unique and not overwriting any of the input files
|
||||
if (!options.noEmit && !options.suppressOutputPathCheck) {
|
||||
const emitHost = getEmitHost();
|
||||
const emitFilesSeen = createFileMap<boolean>(!host.useCaseSensitiveFileNames() ? key => key.toLocaleLowerCase() : undefined);
|
||||
const emitFilesSeen = createMap<true>();
|
||||
forEachEmittedFile(emitHost, (emitFileNames) => {
|
||||
verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
|
||||
verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen);
|
||||
@@ -1950,11 +1987,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Verify that all the emit files are unique and don't overwrite input files
|
||||
function verifyEmitFilePath(emitFileName: string, emitFilesSeen: FileMap<boolean>) {
|
||||
function verifyEmitFilePath(emitFileName: string, emitFilesSeen: Map<true>) {
|
||||
if (emitFileName) {
|
||||
const emitFilePath = toPath(emitFileName, currentDirectory, getCanonicalFileName);
|
||||
const emitFilePath = toPath(emitFileName);
|
||||
// Report error if the output overwrites input file
|
||||
if (filesByName.contains(emitFilePath)) {
|
||||
if (filesByName.has(emitFilePath)) {
|
||||
let chain: DiagnosticMessageChain;
|
||||
if (!options.configFilePath) {
|
||||
// The program is from either an inferred project or an external project
|
||||
@@ -1964,20 +2001,106 @@ namespace ts {
|
||||
blockEmittingOfFile(emitFileName, createCompilerDiagnosticFromMessageChain(chain));
|
||||
}
|
||||
|
||||
const emitFileKey = !host.useCaseSensitiveFileNames() ? emitFilePath.toLocaleLowerCase() : emitFilePath;
|
||||
// Report error if multiple files write into same file
|
||||
if (emitFilesSeen.contains(emitFilePath)) {
|
||||
if (emitFilesSeen.has(emitFileKey)) {
|
||||
// Already seen the same emit file - report error
|
||||
blockEmittingOfFile(emitFileName, createCompilerDiagnostic(Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
|
||||
}
|
||||
else {
|
||||
emitFilesSeen.set(emitFilePath, true);
|
||||
emitFilesSeen.set(emitFileKey, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: DiagnosticMessage, arg0: string | number, arg1: string | number, arg2?: string | number) {
|
||||
let needCompilerDiagnostic = true;
|
||||
const pathsSyntax = getOptionPathsSyntax();
|
||||
for (const pathProp of pathsSyntax) {
|
||||
if (isObjectLiteralExpression(pathProp.initializer)) {
|
||||
for (const keyProps of getPropertyAssignment(pathProp.initializer, key)) {
|
||||
if (isArrayLiteralExpression(keyProps.initializer) &&
|
||||
keyProps.initializer.elements.length > valueIndex) {
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, keyProps.initializer.elements[valueIndex], message, arg0, arg1, arg2));
|
||||
needCompilerDiagnostic = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needCompilerDiagnostic) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1, arg2));
|
||||
}
|
||||
}
|
||||
|
||||
function createDiagnosticForOptionPaths(onKey: boolean, key: string, message: DiagnosticMessage, arg0: string | number) {
|
||||
let needCompilerDiagnostic = true;
|
||||
const pathsSyntax = getOptionPathsSyntax();
|
||||
for (const pathProp of pathsSyntax) {
|
||||
if (isObjectLiteralExpression(pathProp.initializer) &&
|
||||
createOptionDiagnosticInObjectLiteralSyntax(
|
||||
pathProp.initializer, onKey, key, /*key2*/ undefined,
|
||||
message, arg0)) {
|
||||
needCompilerDiagnostic = false;
|
||||
}
|
||||
}
|
||||
if (needCompilerDiagnostic) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, arg0));
|
||||
}
|
||||
}
|
||||
|
||||
function getOptionPathsSyntax() {
|
||||
const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
|
||||
if (compilerOptionsObjectLiteralSyntax) {
|
||||
return getPropertyAssignment(compilerOptionsObjectLiteralSyntax, "paths");
|
||||
}
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
function createDiagnosticForOptionName(message: DiagnosticMessage, option1: string, option2?: string) {
|
||||
createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2);
|
||||
}
|
||||
|
||||
function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0: string) {
|
||||
createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
|
||||
}
|
||||
|
||||
function createDiagnosticForOption(onKey: boolean, option1: string, option2: string, message: DiagnosticMessage, arg0: string | number, arg1?: string | number) {
|
||||
const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
|
||||
const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
|
||||
!createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1);
|
||||
|
||||
if (needCompilerDiagnostic) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1));
|
||||
}
|
||||
}
|
||||
|
||||
function getCompilerOptionsObjectLiteralSyntax() {
|
||||
if (_compilerOptionsObjectLiteralSyntax === undefined) {
|
||||
_compilerOptionsObjectLiteralSyntax = null; // tslint:disable-line:no-null-keyword
|
||||
if (options.configFile && options.configFile.jsonObject) {
|
||||
for (const prop of getPropertyAssignment(options.configFile.jsonObject, "compilerOptions")) {
|
||||
if (isObjectLiteralExpression(prop.initializer)) {
|
||||
_compilerOptionsObjectLiteralSyntax = prop.initializer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return _compilerOptionsObjectLiteralSyntax;
|
||||
}
|
||||
|
||||
function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string, message: DiagnosticMessage, arg0: string | number, arg1?: string | number): boolean {
|
||||
const props = getPropertyAssignment(objectLiteral, key1, key2);
|
||||
for (const prop of props) {
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, onKey ? prop.name : prop.initializer, message, arg0, arg1));
|
||||
}
|
||||
return !!props.length;
|
||||
}
|
||||
|
||||
function blockEmittingOfFile(emitFileName: string, diag: Diagnostic) {
|
||||
hasEmitBlockingDiagnostics.set(toPath(emitFileName, currentDirectory, getCanonicalFileName), true);
|
||||
hasEmitBlockingDiagnostics.set(toPath(emitFileName), true);
|
||||
programDiagnostics.add(diag);
|
||||
}
|
||||
}
|
||||
@@ -2009,4 +2132,9 @@ namespace ts {
|
||||
return options.allowJs ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_allowJs_is_not_set;
|
||||
}
|
||||
}
|
||||
|
||||
function checkAllDefined(names: string[]): string[] {
|
||||
Debug.assert(names.every(name => name !== undefined), "A name is undefined.", () => JSON.stringify(names));
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-6
File diff suppressed because one or more lines are too long
+36
-17
@@ -22,7 +22,7 @@ namespace ts {
|
||||
*
|
||||
* @param sourceFile The source file.
|
||||
*/
|
||||
setSourceFile(sourceFile: SourceFile): void;
|
||||
setSourceFile(sourceFile: SourceMapSource): void;
|
||||
|
||||
/**
|
||||
* Emits a mapping.
|
||||
@@ -81,7 +81,7 @@ namespace ts {
|
||||
export function createSourceMapWriter(host: EmitHost, writer: EmitTextWriter): SourceMapWriter {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const extendedDiagnostics = compilerOptions.extendedDiagnostics;
|
||||
let currentSourceFile: SourceFile;
|
||||
let currentSource: SourceMapSource;
|
||||
let currentSourceText: string;
|
||||
let sourceMapDir: string; // The directory in which sourcemap will be
|
||||
|
||||
@@ -109,6 +109,13 @@ namespace ts {
|
||||
getSourceMappingURL,
|
||||
};
|
||||
|
||||
/**
|
||||
* Skips trivia such as comments and white-space that can optionally overriden by the source map source
|
||||
*/
|
||||
function skipSourceTrivia(pos: number): number {
|
||||
return currentSource.skipTrivia ? currentSource.skipTrivia(pos) : skipTrivia(currentSourceText, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the SourceMapWriter for a new output file.
|
||||
*
|
||||
@@ -125,7 +132,7 @@ namespace ts {
|
||||
reset();
|
||||
}
|
||||
|
||||
currentSourceFile = undefined;
|
||||
currentSource = undefined;
|
||||
currentSourceText = undefined;
|
||||
|
||||
// Current source map file and its index in the sources list
|
||||
@@ -138,7 +145,7 @@ namespace ts {
|
||||
|
||||
// Initialize source map data
|
||||
sourceMapData = {
|
||||
sourceMapFilePath: sourceMapFilePath,
|
||||
sourceMapFilePath,
|
||||
jsSourceMappingURL: !compilerOptions.inlineSourceMap ? getBaseFileName(normalizeSlashes(sourceMapFilePath)) : undefined,
|
||||
sourceMapFile: getBaseFileName(normalizeSlashes(filePath)),
|
||||
sourceMapSourceRoot: compilerOptions.sourceRoot || "",
|
||||
@@ -192,7 +199,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
currentSourceFile = undefined;
|
||||
currentSource = undefined;
|
||||
sourceMapDir = undefined;
|
||||
sourceMapSourceIndex = undefined;
|
||||
lastRecordedSourceMapSpan = undefined;
|
||||
@@ -263,7 +270,7 @@ namespace ts {
|
||||
performance.mark("beforeSourcemap");
|
||||
}
|
||||
|
||||
const sourceLinePos = getLineAndCharacterOfPosition(currentSourceFile, pos);
|
||||
const sourceLinePos = getLineAndCharacterOfPosition(currentSource, pos);
|
||||
|
||||
// Convert the location to be one-based.
|
||||
sourceLinePos.line++;
|
||||
@@ -285,8 +292,8 @@ namespace ts {
|
||||
|
||||
// New span
|
||||
lastRecordedSourceMapSpan = {
|
||||
emittedLine: emittedLine,
|
||||
emittedColumn: emittedColumn,
|
||||
emittedLine,
|
||||
emittedColumn,
|
||||
sourceLine: sourceLinePos.line,
|
||||
sourceColumn: sourceLinePos.character,
|
||||
sourceIndex: sourceMapSourceIndex
|
||||
@@ -320,14 +327,22 @@ namespace ts {
|
||||
if (node) {
|
||||
const emitNode = node.emitNode;
|
||||
const emitFlags = emitNode && emitNode.flags;
|
||||
const { pos, end } = emitNode && emitNode.sourceMapRange || node;
|
||||
const range = emitNode && emitNode.sourceMapRange;
|
||||
const { pos, end } = range || node;
|
||||
let source = range && range.source;
|
||||
const oldSource = currentSource;
|
||||
if (source === oldSource) source = undefined;
|
||||
|
||||
if (source) setSourceFile(source);
|
||||
|
||||
if (node.kind !== SyntaxKind.NotEmittedStatement
|
||||
&& (emitFlags & EmitFlags.NoLeadingSourceMap) === 0
|
||||
&& pos >= 0) {
|
||||
emitPos(skipTrivia(currentSourceText, pos));
|
||||
emitPos(skipSourceTrivia(pos));
|
||||
}
|
||||
|
||||
if (source) setSourceFile(oldSource);
|
||||
|
||||
if (emitFlags & EmitFlags.NoNestedSourceMaps) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
@@ -337,11 +352,15 @@ namespace ts {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
|
||||
if (source) setSourceFile(source);
|
||||
|
||||
if (node.kind !== SyntaxKind.NotEmittedStatement
|
||||
&& (emitFlags & EmitFlags.NoTrailingSourceMap) === 0
|
||||
&& end >= 0) {
|
||||
emitPos(end);
|
||||
}
|
||||
|
||||
if (source) setSourceFile(oldSource);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +381,7 @@ namespace ts {
|
||||
const emitFlags = emitNode && emitNode.flags;
|
||||
const range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token];
|
||||
|
||||
tokenPos = skipTrivia(currentSourceText, range ? range.pos : tokenPos);
|
||||
tokenPos = skipSourceTrivia(range ? range.pos : tokenPos);
|
||||
if ((emitFlags & EmitFlags.NoTokenLeadingSourceMaps) === 0 && tokenPos >= 0) {
|
||||
emitPos(tokenPos);
|
||||
}
|
||||
@@ -382,13 +401,13 @@ namespace ts {
|
||||
*
|
||||
* @param sourceFile The source file.
|
||||
*/
|
||||
function setSourceFile(sourceFile: SourceFile) {
|
||||
function setSourceFile(sourceFile: SourceMapSource) {
|
||||
if (disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentSourceFile = sourceFile;
|
||||
currentSourceText = currentSourceFile.text;
|
||||
currentSource = sourceFile;
|
||||
currentSourceText = currentSource.text;
|
||||
|
||||
// Add the file to tsFilePaths
|
||||
// If sourceroot option: Use the relative path corresponding to the common directory path
|
||||
@@ -396,7 +415,7 @@ namespace ts {
|
||||
const sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
|
||||
|
||||
const source = getRelativePathToDirectoryOrUrl(sourcesDirectoryPath,
|
||||
currentSourceFile.fileName,
|
||||
currentSource.fileName,
|
||||
host.getCurrentDirectory(),
|
||||
host.getCanonicalFileName,
|
||||
/*isAbsolutePathAnUrl*/ true);
|
||||
@@ -407,10 +426,10 @@ namespace ts {
|
||||
sourceMapData.sourceMapSources.push(source);
|
||||
|
||||
// The one that can be used from program to get the actual source file
|
||||
sourceMapData.inputSourceFileNames.push(currentSourceFile.fileName);
|
||||
sourceMapData.inputSourceFileNames.push(currentSource.fileName);
|
||||
|
||||
if (compilerOptions.inlineSources) {
|
||||
sourceMapData.sourceMapSourcesContent.push(currentSourceFile.text);
|
||||
sourceMapData.sourceMapSourcesContent.push(currentSource.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+57
-19
@@ -4,7 +4,25 @@ declare function setTimeout(handler: (...args: any[]) => void, timeout: number):
|
||||
declare function clearTimeout(handle: any): void;
|
||||
|
||||
namespace ts {
|
||||
export type FileWatcherCallback = (fileName: string, removed?: boolean) => void;
|
||||
/**
|
||||
* Set a high stack trace limit to provide more information in case of an error.
|
||||
* Called for command-line and server use cases.
|
||||
* Not called if TypeScript is used as a library.
|
||||
*/
|
||||
/* @internal */
|
||||
export function setStackTraceLimit() {
|
||||
if ((Error as any).stackTraceLimit < 100) { // Also tests that we won't set the property if it doesn't exist.
|
||||
(Error as any).stackTraceLimit = 100;
|
||||
}
|
||||
}
|
||||
|
||||
export enum FileWatcherEventKind {
|
||||
Created,
|
||||
Changed,
|
||||
Deleted
|
||||
}
|
||||
|
||||
export type FileWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind) => void;
|
||||
export type DirectoryWatcherCallback = (fileName: string) => void;
|
||||
export interface WatchedFile {
|
||||
fileName: string;
|
||||
@@ -17,7 +35,7 @@ namespace ts {
|
||||
newLine: string;
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
write(s: string): void;
|
||||
readFile(path: string, encoding?: string): string;
|
||||
readFile(path: string, encoding?: string): string | undefined;
|
||||
getFileSize?(path: string): number;
|
||||
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
/**
|
||||
@@ -33,8 +51,12 @@ namespace ts {
|
||||
getExecutingFilePath(): string;
|
||||
getCurrentDirectory(): string;
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
getModifiedTime?(path: string): Date;
|
||||
/**
|
||||
* This should be cryptographically secure.
|
||||
* A good implementation is node.js' `crypto.createHash`. (https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm)
|
||||
*/
|
||||
createHash?(data: string): string;
|
||||
getMemoryUsage?(): number;
|
||||
exit(exitCode?: number): void;
|
||||
@@ -87,10 +109,10 @@ namespace ts {
|
||||
directoryExists(path: string): boolean;
|
||||
createDirectory(path: string): void;
|
||||
resolvePath(path: string): string;
|
||||
readFile(path: string): string;
|
||||
readFile(path: string): string | undefined;
|
||||
writeFile(path: string, contents: string): void;
|
||||
getDirectories(path: string): string[];
|
||||
readDirectory(path: string, extensions?: string[], basePaths?: string[], excludeEx?: string, includeFileEx?: string, includeDirEx?: string): string[];
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, basePaths?: ReadonlyArray<string>, excludeEx?: string, includeFileEx?: string, includeDirEx?: string): string[];
|
||||
watchFile?(path: string, callback: FileWatcherCallback): FileWatcher;
|
||||
watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
|
||||
realpath(path: string): string;
|
||||
@@ -170,7 +192,7 @@ namespace ts {
|
||||
const callbacks = fileWatcherCallbacks.get(fileName);
|
||||
if (callbacks) {
|
||||
for (const fileCallback of callbacks) {
|
||||
fileCallback(fileName);
|
||||
fileCallback(fileName, FileWatcherEventKind.Changed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,15 +208,22 @@ namespace ts {
|
||||
if (platform === "win32" || platform === "win64") {
|
||||
return false;
|
||||
}
|
||||
// convert current file name to upper case / lower case and check if file exists
|
||||
// (guards against cases when name is already all uppercase or lowercase)
|
||||
return !fileExists(__filename.toUpperCase()) || !fileExists(__filename.toLowerCase());
|
||||
// If this file exists under a different case, we must be case-insensitve.
|
||||
return !fileExists(swapCase(__filename));
|
||||
}
|
||||
|
||||
/** Convert all lowercase chars to uppercase, and vice-versa */
|
||||
function swapCase(s: string): string {
|
||||
return s.replace(/\w/g, (ch) => {
|
||||
const up = ch.toUpperCase();
|
||||
return ch === up ? ch.toLowerCase() : up;
|
||||
});
|
||||
}
|
||||
|
||||
const platform: string = _os.platform();
|
||||
const useCaseSensitiveFileNames = isFileSystemCaseSensitive();
|
||||
|
||||
function readFile(fileName: string, _encoding?: string): string {
|
||||
function readFile(fileName: string, _encoding?: string): string | undefined {
|
||||
if (!fileExists(fileName)) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -277,8 +306,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function readDirectory(path: string, extensions?: string[], excludes?: string[], includes?: string[]): string[] {
|
||||
return matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), getAccessibleFileSystemEntries);
|
||||
function readDirectory(path: string, extensions?: ReadonlyArray<string>, excludes?: ReadonlyArray<string>, includes?: ReadonlyArray<string>, depth?: number): string[] {
|
||||
return matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries);
|
||||
}
|
||||
|
||||
const enum FileSystemEntryKind {
|
||||
@@ -315,7 +344,7 @@ namespace ts {
|
||||
const nodeSystem: System = {
|
||||
args: process.argv.slice(2),
|
||||
newLine: _os.EOL,
|
||||
useCaseSensitiveFileNames: useCaseSensitiveFileNames,
|
||||
useCaseSensitiveFileNames,
|
||||
write(s: string): void {
|
||||
process.stdout.write(s);
|
||||
},
|
||||
@@ -336,11 +365,22 @@ namespace ts {
|
||||
}
|
||||
|
||||
function fileChanged(curr: any, prev: any) {
|
||||
if (+curr.mtime <= +prev.mtime) {
|
||||
const isCurrZero = +curr.mtime === 0;
|
||||
const isPrevZero = +prev.mtime === 0;
|
||||
const created = !isCurrZero && isPrevZero;
|
||||
const deleted = isCurrZero && !isPrevZero;
|
||||
|
||||
const eventKind = created
|
||||
? FileWatcherEventKind.Created
|
||||
: deleted
|
||||
? FileWatcherEventKind.Deleted
|
||||
: FileWatcherEventKind.Changed;
|
||||
|
||||
if (eventKind === FileWatcherEventKind.Changed && +curr.mtime <= +prev.mtime) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(fileName);
|
||||
callback(fileName, eventKind);
|
||||
}
|
||||
},
|
||||
watchDirectory: (directoryName, callback, recursive) => {
|
||||
@@ -373,9 +413,7 @@ namespace ts {
|
||||
}
|
||||
);
|
||||
},
|
||||
resolvePath: function(path: string): string {
|
||||
return _path.resolve(path);
|
||||
},
|
||||
resolvePath: path => _path.resolve(path),
|
||||
fileExists,
|
||||
directoryExists,
|
||||
createDirectory(directoryName: string) {
|
||||
@@ -471,7 +509,7 @@ namespace ts {
|
||||
getCurrentDirectory: () => ChakraHost.currentDirectory,
|
||||
getDirectories: ChakraHost.getDirectories,
|
||||
getEnvironmentVariable: ChakraHost.getEnvironmentVariable || (() => ""),
|
||||
readDirectory: (path: string, extensions?: string[], excludes?: string[], includes?: string[]) => {
|
||||
readDirectory(path, extensions, excludes, includes, _depth) {
|
||||
const pattern = getFileMatcherPatterns(path, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
|
||||
return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern);
|
||||
},
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/// <reference path="visitor.ts" />
|
||||
/// <reference path="transformers/utilities.ts" />
|
||||
/// <reference path="transformers/ts.ts" />
|
||||
/// <reference path="transformers/jsx.ts" />
|
||||
/// <reference path="transformers/esnext.ts" />
|
||||
@@ -239,7 +240,7 @@ namespace ts {
|
||||
function hoistVariableDeclaration(name: Identifier): void {
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the lexical environment during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the lexical environment after transformation has completed.");
|
||||
const decl = createVariableDeclaration(name);
|
||||
const decl = setEmitFlags(createVariableDeclaration(name), EmitFlags.NoNestedSourceMaps);
|
||||
if (!lexicalEnvironmentVariableDeclarations) {
|
||||
lexicalEnvironmentVariableDeclarations = [decl];
|
||||
}
|
||||
|
||||
@@ -411,11 +411,11 @@ namespace ts {
|
||||
}
|
||||
else if (isStringOrNumericLiteral(propertyName)) {
|
||||
const argumentExpression = getSynthesizedClone(propertyName);
|
||||
argumentExpression.text = unescapeIdentifier(argumentExpression.text);
|
||||
argumentExpression.text = argumentExpression.text;
|
||||
return createElementAccess(value, argumentExpression);
|
||||
}
|
||||
else {
|
||||
const name = createIdentifier(unescapeIdentifier(propertyName.text));
|
||||
const name = createIdentifier(unescapeLeadingUnderscores(propertyName.escapedText));
|
||||
return createPropertyAccess(value, name);
|
||||
}
|
||||
}
|
||||
@@ -492,7 +492,7 @@ namespace ts {
|
||||
/** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement
|
||||
* `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);`
|
||||
*/
|
||||
function createRestCall(context: TransformationContext, value: Expression, elements: BindingOrAssignmentElement[], computedTempVariables: Expression[], location: TextRange): Expression {
|
||||
function createRestCall(context: TransformationContext, value: Expression, elements: ReadonlyArray<BindingOrAssignmentElement>, computedTempVariables: ReadonlyArray<Expression>, location: TextRange): Expression {
|
||||
context.requestEmitHelper(restHelper);
|
||||
const propertyNames: Expression[] = [];
|
||||
let computedTempVariableOffset = 0;
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace ts {
|
||||
* set of labels that occurred inside the converted loop
|
||||
* used to determine if labeled jump can be emitted as is or it should be dispatched to calling code
|
||||
*/
|
||||
labels?: Map<string>;
|
||||
labels?: Map<boolean>;
|
||||
/*
|
||||
* collection of labeled jumps that transfer control outside the converted loop.
|
||||
* maps store association 'label -> labelMarker' where
|
||||
@@ -647,7 +647,7 @@ namespace ts {
|
||||
if (isGeneratedIdentifier(node)) {
|
||||
return node;
|
||||
}
|
||||
if (node.text !== "arguments" || !resolver.isArgumentsLocalBinding(node)) {
|
||||
if (node.escapedText !== "arguments" || !resolver.isArgumentsLocalBinding(node)) {
|
||||
return node;
|
||||
}
|
||||
return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = createUniqueName("arguments"));
|
||||
@@ -661,7 +661,7 @@ namespace ts {
|
||||
// - break/continue is non-labeled and located in non-converted loop/switch statement
|
||||
const jump = node.kind === SyntaxKind.BreakStatement ? Jump.Break : Jump.Continue;
|
||||
const canUseBreakOrContinue =
|
||||
(node.label && convertedLoopState.labels && convertedLoopState.labels.get(node.label.text)) ||
|
||||
(node.label && convertedLoopState.labels && convertedLoopState.labels.get(unescapeLeadingUnderscores(node.label.escapedText))) ||
|
||||
(!node.label && (convertedLoopState.allowedNonLabeledJumps & jump));
|
||||
|
||||
if (!canUseBreakOrContinue) {
|
||||
@@ -679,12 +679,12 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
if (node.kind === SyntaxKind.BreakStatement) {
|
||||
labelMarker = `break-${node.label.text}`;
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ true, node.label.text, labelMarker);
|
||||
labelMarker = `break-${node.label.escapedText}`;
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ true, unescapeLeadingUnderscores(node.label.escapedText), labelMarker);
|
||||
}
|
||||
else {
|
||||
labelMarker = `continue-${node.label.text}`;
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ false, node.label.text, labelMarker);
|
||||
labelMarker = `continue-${node.label.escapedText}`;
|
||||
setLabeledJump(convertedLoopState, /*isBreak*/ false, unescapeLeadingUnderscores(node.label.escapedText), labelMarker);
|
||||
}
|
||||
}
|
||||
let returnExpression: Expression = createLiteral(labelMarker);
|
||||
@@ -1963,7 +1963,7 @@ namespace ts {
|
||||
updated,
|
||||
setTextRange(
|
||||
createNodeArray(
|
||||
prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true)
|
||||
prependCaptureNewTargetIfNeeded(updated.statements as MutableNodeArray<Statement>, node, /*copyOnWrite*/ true)
|
||||
),
|
||||
/*location*/ updated.statements
|
||||
)
|
||||
@@ -2236,16 +2236,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
function recordLabel(node: LabeledStatement) {
|
||||
convertedLoopState.labels.set(node.label.text, node.label.text);
|
||||
convertedLoopState.labels.set(unescapeLeadingUnderscores(node.label.escapedText), true);
|
||||
}
|
||||
|
||||
function resetLabel(node: LabeledStatement) {
|
||||
convertedLoopState.labels.set(node.label.text, undefined);
|
||||
convertedLoopState.labels.set(unescapeLeadingUnderscores(node.label.escapedText), false);
|
||||
}
|
||||
|
||||
function visitLabeledStatement(node: LabeledStatement): VisitResult<Statement> {
|
||||
if (convertedLoopState && !convertedLoopState.labels) {
|
||||
convertedLoopState.labels = createMap<string>();
|
||||
convertedLoopState.labels = createMap<boolean>();
|
||||
}
|
||||
const statement = unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel);
|
||||
return isIterationStatement(statement, /*lookInLabeledStatements*/ false)
|
||||
@@ -3053,7 +3053,7 @@ namespace ts {
|
||||
else {
|
||||
loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
|
||||
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
|
||||
const outParamName = createUniqueName("out_" + unescapeIdentifier(name.text));
|
||||
const outParamName = createUniqueName("out_" + unescapeLeadingUnderscores(name.escapedText));
|
||||
loopOutParameters.push({ originalName: name, outParamName });
|
||||
}
|
||||
}
|
||||
@@ -3199,7 +3199,7 @@ namespace ts {
|
||||
|
||||
function addStatementToStartOfBlock(block: Block, statement: Statement): Block {
|
||||
const transformedStatements = visitNodes(block.statements, visitor, isStatement);
|
||||
return updateBlock(block, [statement].concat(transformedStatements));
|
||||
return updateBlock(block, [statement, ...transformedStatements]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3401,28 +3401,19 @@ namespace ts {
|
||||
classBodyStart++;
|
||||
}
|
||||
|
||||
// We reuse the comment and source-map positions from the original variable statement
|
||||
// and class alias, while converting the function declaration for the class constructor
|
||||
// into an expression.
|
||||
// The next statement is the function declaration.
|
||||
statements.push(funcStatements[classBodyStart]);
|
||||
classBodyStart++;
|
||||
|
||||
// Add the class alias following the declaration.
|
||||
statements.push(
|
||||
updateVariableStatement(
|
||||
varStatement,
|
||||
/*modifiers*/ undefined,
|
||||
updateVariableDeclarationList(varStatement.declarationList, [
|
||||
updateVariableDeclaration(variable,
|
||||
variable.name,
|
||||
/*type*/ undefined,
|
||||
updateBinary(aliasAssignment,
|
||||
aliasAssignment.left,
|
||||
convertFunctionDeclarationToExpression(
|
||||
cast(funcStatements[classBodyStart], isFunctionDeclaration)
|
||||
)
|
||||
)
|
||||
)
|
||||
])
|
||||
createStatement(
|
||||
createAssignment(
|
||||
aliasAssignment.left,
|
||||
cast(variable.name, isIdentifier)
|
||||
)
|
||||
)
|
||||
);
|
||||
classBodyStart++;
|
||||
}
|
||||
|
||||
// Find the trailing 'return' statement (4)
|
||||
@@ -3588,7 +3579,7 @@ namespace ts {
|
||||
// Map spans of spread expressions into their expressions and spans of other
|
||||
// expressions into an array literal.
|
||||
const numElements = elements.length;
|
||||
const segments = flatten(
|
||||
const segments = flatten<Expression>(
|
||||
spanMap(elements, partitionSpread, (partition, visitPartition, _start, end) =>
|
||||
visitPartition(partition, multiLine, hasTrailingComma && end === numElements)
|
||||
)
|
||||
@@ -3600,7 +3591,7 @@ namespace ts {
|
||||
if (isCallExpression(firstSegment)
|
||||
&& isIdentifier(firstSegment.expression)
|
||||
&& (getEmitFlags(firstSegment.expression) & EmitFlags.HelperName)
|
||||
&& firstSegment.expression.text === "___spread") {
|
||||
&& firstSegment.expression.escapedText === "___spread") {
|
||||
return segments[0];
|
||||
}
|
||||
}
|
||||
@@ -3851,7 +3842,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitMetaProperty(node: MetaProperty) {
|
||||
if (node.keywordToken === SyntaxKind.NewKeyword && node.name.text === "target") {
|
||||
if (node.keywordToken === SyntaxKind.NewKeyword && node.name.escapedText === "target") {
|
||||
if (hierarchyFacts & HierarchyFacts.ComputedPropertyName) {
|
||||
hierarchyFacts |= HierarchyFacts.NewTargetInComputedPropertyName;
|
||||
}
|
||||
@@ -4076,7 +4067,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const expression = (<SpreadElement>callArgument).expression;
|
||||
return isIdentifier(expression) && expression.text === "arguments";
|
||||
return isIdentifier(expression) && expression.escapedText === "arguments";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,7 +369,7 @@ namespace ts {
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
createLiteral(unescapeLeadingUnderscores(node.name.escapedText)),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace ts {
|
||||
* @param name An Identifier
|
||||
*/
|
||||
function trySubstituteReservedName(name: Identifier) {
|
||||
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(name.text) : undefined);
|
||||
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(unescapeLeadingUnderscores(name.escapedText)) : undefined);
|
||||
if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) {
|
||||
return setTextRange(createLiteral(name), name);
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function chunkObjectLiteralElements(elements: ObjectLiteralElement[]): Expression[] {
|
||||
function chunkObjectLiteralElements(elements: ReadonlyArray<ObjectLiteralElement>): Expression[] {
|
||||
let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[];
|
||||
const objects: Expression[] = [];
|
||||
for (const e of elements) {
|
||||
@@ -776,7 +776,7 @@ namespace ts {
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
createLiteral(unescapeLeadingUnderscores(node.name.escapedText)),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
@@ -640,10 +640,13 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return createStatement(
|
||||
inlineExpressions(
|
||||
map(variables, transformInitializedVariable)
|
||||
)
|
||||
return setSourceMapRange(
|
||||
createStatement(
|
||||
inlineExpressions(
|
||||
map(variables, transformInitializedVariable)
|
||||
)
|
||||
),
|
||||
node
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1173,7 +1176,7 @@ namespace ts {
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function transformAndEmitStatements(statements: Statement[], start = 0) {
|
||||
function transformAndEmitStatements(statements: ReadonlyArray<Statement>, start = 0) {
|
||||
const numStatements = statements.length;
|
||||
for (let i = start; i < numStatements; i++) {
|
||||
transformAndEmitStatement(statements[i]);
|
||||
@@ -1281,9 +1284,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function transformInitializedVariable(node: VariableDeclaration) {
|
||||
return createAssignment(
|
||||
<Identifier>getSynthesizedClone(node.name),
|
||||
visitNode(node.initializer, visitor, isExpression)
|
||||
return setSourceMapRange(
|
||||
createAssignment(
|
||||
setSourceMapRange(<Identifier>getSynthesizedClone(node.name), node.name),
|
||||
visitNode(node.initializer, visitor, isExpression)
|
||||
),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1629,14 +1635,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function transformAndEmitContinueStatement(node: ContinueStatement): void {
|
||||
const label = findContinueTarget(node.label ? node.label.text : undefined);
|
||||
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);
|
||||
}
|
||||
|
||||
function visitContinueStatement(node: ContinueStatement): Statement {
|
||||
if (inStatementContainingYield) {
|
||||
const label = findContinueTarget(node.label && node.label.text);
|
||||
const label = findContinueTarget(node.label && unescapeLeadingUnderscores(node.label.escapedText));
|
||||
if (label > 0) {
|
||||
return createInlineBreak(label, /*location*/ node);
|
||||
}
|
||||
@@ -1646,14 +1652,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function transformAndEmitBreakStatement(node: BreakStatement): void {
|
||||
const label = findBreakTarget(node.label ? node.label.text : undefined);
|
||||
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);
|
||||
}
|
||||
|
||||
function visitBreakStatement(node: BreakStatement): Statement {
|
||||
if (inStatementContainingYield) {
|
||||
const label = findBreakTarget(node.label && node.label.text);
|
||||
const label = findBreakTarget(node.label && unescapeLeadingUnderscores(node.label.escapedText));
|
||||
if (label > 0) {
|
||||
return createInlineBreak(label, /*location*/ node);
|
||||
}
|
||||
@@ -1832,7 +1838,7 @@ namespace ts {
|
||||
// /*body*/
|
||||
// .endlabeled
|
||||
// .mark endLabel
|
||||
beginLabeledBlock(node.label.text);
|
||||
beginLabeledBlock(unescapeLeadingUnderscores(node.label.escapedText));
|
||||
transformAndEmitEmbeddedStatement(node.statement);
|
||||
endLabeledBlock();
|
||||
}
|
||||
@@ -1843,7 +1849,7 @@ namespace ts {
|
||||
|
||||
function visitLabeledStatement(node: LabeledStatement) {
|
||||
if (inStatementContainingYield) {
|
||||
beginScriptLabeledBlock(node.label.text);
|
||||
beginScriptLabeledBlock(unescapeLeadingUnderscores(node.label.escapedText));
|
||||
}
|
||||
|
||||
node = visitEachChild(node, visitor, context);
|
||||
@@ -1944,7 +1950,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function substituteExpressionIdentifier(node: Identifier) {
|
||||
if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(node.text)) {
|
||||
if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(unescapeLeadingUnderscores(node.escapedText))) {
|
||||
const original = getOriginalNode(node);
|
||||
if (isIdentifier(original) && original.parent) {
|
||||
const declaration = resolver.getReferencedValueDeclaration(original);
|
||||
@@ -2117,7 +2123,7 @@ namespace ts {
|
||||
hoistVariableDeclaration(variable.name);
|
||||
}
|
||||
else {
|
||||
const text = (<Identifier>variable.name).text;
|
||||
const text = unescapeLeadingUnderscores((<Identifier>variable.name).escapedText);
|
||||
name = declareLocal(text);
|
||||
if (!renamedCatchVariables) {
|
||||
renamedCatchVariables = createMap<boolean>();
|
||||
@@ -2214,8 +2220,8 @@ namespace ts {
|
||||
beginBlock(<LoopBlock>{
|
||||
kind: CodeBlockKind.Loop,
|
||||
isScript: false,
|
||||
breakLabel: breakLabel,
|
||||
continueLabel: continueLabel
|
||||
breakLabel,
|
||||
continueLabel,
|
||||
});
|
||||
return breakLabel;
|
||||
}
|
||||
@@ -2256,7 +2262,7 @@ namespace ts {
|
||||
beginBlock(<SwitchBlock>{
|
||||
kind: CodeBlockKind.Switch,
|
||||
isScript: false,
|
||||
breakLabel: breakLabel
|
||||
breakLabel,
|
||||
});
|
||||
return breakLabel;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace ts {
|
||||
return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node);
|
||||
}
|
||||
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[], isChild: boolean, location: TextRange) {
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: ReadonlyArray<JsxChild>, isChild: boolean, location: TextRange) {
|
||||
const tagName = getTagName(node);
|
||||
let objectProperties: Expression;
|
||||
const attrs = node.attributes.properties;
|
||||
@@ -88,7 +88,7 @@ namespace ts {
|
||||
else {
|
||||
// Map spans of JsxAttribute nodes into object literals and spans
|
||||
// of JsxSpreadAttribute nodes into expressions.
|
||||
const segments = flatten(
|
||||
const segments = flatten<Expression | ObjectLiteralExpression>(
|
||||
spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread
|
||||
? map(attrs, transformJsxSpreadAttributeToExpression)
|
||||
: createObjectLiteral(map(attrs, transformJsxAttributeToObjectLiteralElement))
|
||||
@@ -252,8 +252,8 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const name = (<JsxOpeningLikeElement>node).tagName;
|
||||
if (isIdentifier(name) && isIntrinsicJsxName(name.text)) {
|
||||
return createLiteral(name.text);
|
||||
if (isIdentifier(name) && isIntrinsicJsxName(name.escapedText)) {
|
||||
return createLiteral(unescapeLeadingUnderscores(name.escapedText));
|
||||
}
|
||||
else {
|
||||
return createExpressionFromEntityName(name);
|
||||
@@ -268,11 +268,11 @@ namespace ts {
|
||||
*/
|
||||
function getAttributeName(node: JsxAttribute): StringLiteral | Identifier {
|
||||
const name = node.name;
|
||||
if (/^[A-Za-z_]\w*$/.test(name.text)) {
|
||||
if (/^[A-Za-z_]\w*$/.test(unescapeLeadingUnderscores(name.escapedText))) {
|
||||
return name;
|
||||
}
|
||||
else {
|
||||
return createLiteral(name.text);
|
||||
return createLiteral(unescapeLeadingUnderscores(name.escapedText));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace ts {
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
||||
const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements));
|
||||
if (currentModuleInfo.hasExportStarsToExportValues) {
|
||||
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
|
||||
// If we have any `export * from ...` declarations
|
||||
// we need to inform the emitter to add the __export helper.
|
||||
addEmitHelper(updated, exportStarHelper);
|
||||
@@ -408,7 +408,7 @@ namespace ts {
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
||||
const body = createBlock(statements, /*multiLine*/ true);
|
||||
if (currentModuleInfo.hasExportStarsToExportValues) {
|
||||
if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) {
|
||||
// If we have any `export * from ...` declarations
|
||||
// we need to inform the emitter to add the __export helper.
|
||||
addEmitHelper(body, exportStarHelper);
|
||||
@@ -514,14 +514,14 @@ namespace ts {
|
||||
|
||||
function visitImportCallExpression(node: ImportCall): Expression {
|
||||
switch (compilerOptions.module) {
|
||||
case ModuleKind.CommonJS:
|
||||
return transformImportCallExpressionCommonJS(node);
|
||||
case ModuleKind.AMD:
|
||||
return transformImportCallExpressionAMD(node);
|
||||
case ModuleKind.UMD:
|
||||
return transformImportCallExpressionUMD(node);
|
||||
case ModuleKind.CommonJS:
|
||||
default:
|
||||
return transformImportCallExpressionCommonJS(node);
|
||||
}
|
||||
Debug.fail("All supported module kind in this transformation step should have been handled");
|
||||
}
|
||||
|
||||
function transformImportCallExpressionUMD(node: ImportCall): Expression {
|
||||
@@ -833,15 +833,7 @@ namespace ts {
|
||||
// export * from "mod";
|
||||
return setTextRange(
|
||||
createStatement(
|
||||
createCall(
|
||||
createIdentifier("__export"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
moduleKind !== ModuleKind.AMD
|
||||
? createRequireCall(node)
|
||||
: generatedName
|
||||
]
|
||||
)
|
||||
createExportStarHelper(context, moduleKind !== ModuleKind.AMD ? createRequireCall(node) : generatedName)
|
||||
),
|
||||
node
|
||||
);
|
||||
@@ -932,7 +924,7 @@ namespace ts {
|
||||
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.heritageClauses, importCallExpressionVisitor),
|
||||
node.members
|
||||
visitNodes(node.members, importCallExpressionVisitor)
|
||||
),
|
||||
node
|
||||
),
|
||||
@@ -1233,7 +1225,7 @@ namespace ts {
|
||||
*/
|
||||
function appendExportsOfDeclaration(statements: Statement[] | undefined, decl: Declaration): Statement[] | undefined {
|
||||
const name = getDeclarationName(decl);
|
||||
const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(name.text);
|
||||
const exportSpecifiers = currentModuleInfo.exportSpecifiers.get(unescapeLeadingUnderscores(name.escapedText));
|
||||
if (exportSpecifiers) {
|
||||
for (const exportSpecifier of exportSpecifiers) {
|
||||
statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name);
|
||||
@@ -1598,9 +1590,17 @@ namespace ts {
|
||||
text: `
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}`
|
||||
}
|
||||
`
|
||||
};
|
||||
|
||||
function createExportStarHelper(context: TransformationContext, module: Expression) {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
return compilerOptions.importHelpers
|
||||
? createCall(getHelperName("__exportStar"), /*typeArguments*/ undefined, [module, createIdentifier("exports")])
|
||||
: createCall(createIdentifier("__export"), /*typeArguments*/ undefined, [module]);
|
||||
}
|
||||
|
||||
// emit helper for dynamic import
|
||||
const dynamicImportUMDHelper: EmitHelper = {
|
||||
name: "typescript:dynamicimport-sync-require",
|
||||
|
||||
@@ -324,7 +324,7 @@ namespace ts {
|
||||
const exportedNames: ObjectLiteralElementLike[] = [];
|
||||
if (moduleInfo.exportedNames) {
|
||||
for (const exportedLocalName of moduleInfo.exportedNames) {
|
||||
if (exportedLocalName.text === "default") {
|
||||
if (exportedLocalName.escapedText === "default") {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -353,7 +353,7 @@ namespace ts {
|
||||
// write name of indirectly exported entry, i.e. 'export {x} from ...'
|
||||
exportedNames.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral((element.name || element.propertyName).text),
|
||||
createLiteral(unescapeLeadingUnderscores((element.name || element.propertyName).escapedText)),
|
||||
createTrue()
|
||||
)
|
||||
);
|
||||
@@ -504,10 +504,10 @@ namespace ts {
|
||||
for (const e of (<ExportDeclaration>entry).exportClause.elements) {
|
||||
properties.push(
|
||||
createPropertyAssignment(
|
||||
createLiteral(e.name.text),
|
||||
createLiteral(unescapeLeadingUnderscores(e.name.escapedText)),
|
||||
createElementAccess(
|
||||
parameterName,
|
||||
createLiteral((e.propertyName || e.name).text)
|
||||
createLiteral(unescapeLeadingUnderscores((e.propertyName || e.name).escapedText))
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -1028,7 +1028,7 @@ namespace ts {
|
||||
let excludeName: string;
|
||||
if (exportSelf) {
|
||||
statements = appendExportStatement(statements, decl.name, getLocalName(decl));
|
||||
excludeName = decl.name.text;
|
||||
excludeName = unescapeLeadingUnderscores(decl.name.escapedText);
|
||||
}
|
||||
|
||||
statements = appendExportsOfDeclaration(statements, decl, excludeName);
|
||||
@@ -1055,7 +1055,7 @@ namespace ts {
|
||||
if (hasModifier(decl, ModifierFlags.Export)) {
|
||||
const exportName = hasModifier(decl, ModifierFlags.Default) ? createLiteral("default") : decl.name;
|
||||
statements = appendExportStatement(statements, exportName, getLocalName(decl));
|
||||
excludeName = exportName.text;
|
||||
excludeName = getTextOfIdentifierOrLiteral(exportName);
|
||||
}
|
||||
|
||||
if (decl.name) {
|
||||
@@ -1080,10 +1080,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
const name = getDeclarationName(decl);
|
||||
const exportSpecifiers = moduleInfo.exportSpecifiers.get(name.text);
|
||||
const exportSpecifiers = moduleInfo.exportSpecifiers.get(unescapeLeadingUnderscores(name.escapedText));
|
||||
if (exportSpecifiers) {
|
||||
for (const exportSpecifier of exportSpecifiers) {
|
||||
if (exportSpecifier.name.text !== excludeName) {
|
||||
if (exportSpecifier.name.escapedText !== excludeName) {
|
||||
statements = appendExportStatement(statements, exportSpecifier.name, name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace ts {
|
||||
let currentNamespace: ModuleDeclaration;
|
||||
let currentNamespaceContainerName: Identifier;
|
||||
let currentScope: SourceFile | Block | ModuleBlock | CaseBlock;
|
||||
let currentScopeFirstDeclarationsOfName: Map<Node>;
|
||||
let currentScopeFirstDeclarationsOfName: UnderscoreEscapedMap<Node>;
|
||||
|
||||
/**
|
||||
* Keeps track of whether expression substitution has been enabled for specific edge cases.
|
||||
@@ -522,7 +522,7 @@ namespace ts {
|
||||
return parameter.decorators !== undefined && parameter.decorators.length > 0;
|
||||
}
|
||||
|
||||
function getClassFacts(node: ClassDeclaration, staticProperties: PropertyDeclaration[]) {
|
||||
function getClassFacts(node: ClassDeclaration, staticProperties: ReadonlyArray<PropertyDeclaration>) {
|
||||
let facts = ClassFacts.None;
|
||||
if (some(staticProperties)) facts |= ClassFacts.HasStaticInitializedProperties;
|
||||
if (getClassExtendsHeritageClauseElement(node)) facts |= ClassFacts.HasExtendsClause;
|
||||
@@ -1051,7 +1051,7 @@ namespace ts {
|
||||
*
|
||||
* @param node The constructor node.
|
||||
*/
|
||||
function getParametersWithPropertyAssignments(node: ConstructorDeclaration): ParameterDeclaration[] {
|
||||
function getParametersWithPropertyAssignments(node: ConstructorDeclaration): ReadonlyArray<ParameterDeclaration> {
|
||||
return filter(node.parameters, isParameterWithPropertyAssignment);
|
||||
}
|
||||
|
||||
@@ -1104,7 +1104,7 @@ namespace ts {
|
||||
* @param node The class node.
|
||||
* @param isStatic A value indicating whether to get properties from the static or instance side of the class.
|
||||
*/
|
||||
function getInitializedProperties(node: ClassExpression | ClassDeclaration, isStatic: boolean): PropertyDeclaration[] {
|
||||
function getInitializedProperties(node: ClassExpression | ClassDeclaration, isStatic: boolean): ReadonlyArray<PropertyDeclaration> {
|
||||
return filter(node.members, isStatic ? isStaticInitializedProperty : isInstanceInitializedProperty);
|
||||
}
|
||||
|
||||
@@ -1144,7 +1144,7 @@ namespace ts {
|
||||
* @param properties An array of property declarations to transform.
|
||||
* @param receiver The receiver on which each property should be assigned.
|
||||
*/
|
||||
function addInitializedPropertyStatements(statements: Statement[], properties: PropertyDeclaration[], receiver: LeftHandSideExpression) {
|
||||
function addInitializedPropertyStatements(statements: Statement[], properties: ReadonlyArray<PropertyDeclaration>, receiver: LeftHandSideExpression) {
|
||||
for (const property of properties) {
|
||||
const statement = createStatement(transformInitializedProperty(property, receiver));
|
||||
setSourceMapRange(statement, moveRangePastModifiers(property));
|
||||
@@ -1159,7 +1159,7 @@ namespace ts {
|
||||
* @param properties An array of property declarations to transform.
|
||||
* @param receiver The receiver on which each property should be assigned.
|
||||
*/
|
||||
function generateInitializedPropertyExpressions(properties: PropertyDeclaration[], receiver: LeftHandSideExpression) {
|
||||
function generateInitializedPropertyExpressions(properties: ReadonlyArray<PropertyDeclaration>, receiver: LeftHandSideExpression) {
|
||||
const expressions: Expression[] = [];
|
||||
for (const property of properties) {
|
||||
const expression = transformInitializedProperty(property, receiver);
|
||||
@@ -1194,7 +1194,7 @@ namespace ts {
|
||||
* @param isStatic A value indicating whether to retrieve static or instance members of
|
||||
* the class.
|
||||
*/
|
||||
function getDecoratedClassElements(node: ClassExpression | ClassDeclaration, isStatic: boolean): ClassElement[] {
|
||||
function getDecoratedClassElements(node: ClassExpression | ClassDeclaration, isStatic: boolean): ReadonlyArray<ClassElement> {
|
||||
return filter(node.members, isStatic ? isStaticDecoratedClassElement : isInstanceDecoratedClassElement);
|
||||
}
|
||||
|
||||
@@ -1233,8 +1233,8 @@ namespace ts {
|
||||
* A structure describing the decorators for a class element.
|
||||
*/
|
||||
interface AllDecorators {
|
||||
decorators: Decorator[];
|
||||
parameters?: Decorator[][];
|
||||
decorators: ReadonlyArray<Decorator>;
|
||||
parameters?: ReadonlyArray<ReadonlyArray<Decorator>>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1244,7 +1244,7 @@ namespace ts {
|
||||
* @param node The function-like node.
|
||||
*/
|
||||
function getDecoratorsOfParameters(node: FunctionLikeDeclaration) {
|
||||
let decorators: Decorator[][];
|
||||
let decorators: ReadonlyArray<Decorator>[];
|
||||
if (node) {
|
||||
const parameters = node.parameters;
|
||||
for (let i = 0; i < parameters.length; i++) {
|
||||
@@ -1682,7 +1682,7 @@ namespace ts {
|
||||
const valueDeclaration =
|
||||
isClassLike(node)
|
||||
? getFirstConstructorWithBody(node)
|
||||
: isFunctionLike(node) && nodeIsPresent(node.body)
|
||||
: isFunctionLike(node) && nodeIsPresent((node as FunctionLikeDeclaration).body)
|
||||
? node
|
||||
: undefined;
|
||||
|
||||
@@ -1692,7 +1692,7 @@ namespace ts {
|
||||
const numParameters = parameters.length;
|
||||
for (let i = 0; i < numParameters; i++) {
|
||||
const parameter = parameters[i];
|
||||
if (i === 0 && isIdentifier(parameter.name) && parameter.name.text === "this") {
|
||||
if (i === 0 && isIdentifier(parameter.name) && parameter.name.escapedText === "this") {
|
||||
continue;
|
||||
}
|
||||
if (parameter.dotDotDotToken) {
|
||||
@@ -1707,7 +1707,7 @@ namespace ts {
|
||||
return createArrayLiteral(expressions);
|
||||
}
|
||||
|
||||
function getParametersOfDecoratedDeclaration(node: FunctionLikeDeclaration, container: ClassLikeDeclaration) {
|
||||
function getParametersOfDecoratedDeclaration(node: FunctionLike, container: ClassLikeDeclaration) {
|
||||
if (container && node.kind === SyntaxKind.GetAccessor) {
|
||||
const { setAccessor } = getAllAccessorDeclarations(container.members, <AccessorDeclaration>node);
|
||||
if (setAccessor) {
|
||||
@@ -1841,7 +1841,7 @@ namespace ts {
|
||||
for (const typeNode of node.types) {
|
||||
const serializedIndividual = serializeTypeNode(typeNode);
|
||||
|
||||
if (isIdentifier(serializedIndividual) && serializedIndividual.text === "Object") {
|
||||
if (isIdentifier(serializedIndividual) && serializedIndividual.escapedText === "Object") {
|
||||
// One of the individual is global object, return immediately
|
||||
return serializedIndividual;
|
||||
}
|
||||
@@ -1851,7 +1851,7 @@ namespace ts {
|
||||
// Different types
|
||||
if (!isIdentifier(serializedUnion) ||
|
||||
!isIdentifier(serializedIndividual) ||
|
||||
serializedUnion.text !== serializedIndividual.text) {
|
||||
serializedUnion.escapedText !== serializedIndividual.escapedText) {
|
||||
return createIdentifier("Object");
|
||||
}
|
||||
}
|
||||
@@ -2007,7 +2007,7 @@ namespace ts {
|
||||
: (<ComputedPropertyName>name).expression;
|
||||
}
|
||||
else if (isIdentifier(name)) {
|
||||
return createLiteral(unescapeIdentifier(name.text));
|
||||
return createLiteral(unescapeLeadingUnderscores(name.escapedText));
|
||||
}
|
||||
else {
|
||||
return getSynthesizedClone(name);
|
||||
@@ -2644,10 +2644,10 @@ namespace ts {
|
||||
* on symbol names.
|
||||
*/
|
||||
function recordEmittedDeclarationInScope(node: Node) {
|
||||
const name = node.symbol && node.symbol.name;
|
||||
const name = node.symbol && node.symbol.escapedName;
|
||||
if (name) {
|
||||
if (!currentScopeFirstDeclarationsOfName) {
|
||||
currentScopeFirstDeclarationsOfName = createMap<Node>();
|
||||
currentScopeFirstDeclarationsOfName = createUnderscoreEscapedMap<Node>();
|
||||
}
|
||||
|
||||
if (!currentScopeFirstDeclarationsOfName.has(name)) {
|
||||
@@ -2662,7 +2662,7 @@ namespace ts {
|
||||
*/
|
||||
function isFirstEmittedDeclarationInScope(node: Node) {
|
||||
if (currentScopeFirstDeclarationsOfName) {
|
||||
const name = node.symbol && node.symbol.name;
|
||||
const name = node.symbol && node.symbol.escapedName;
|
||||
if (name) {
|
||||
return currentScopeFirstDeclarationsOfName.get(name) === node;
|
||||
}
|
||||
@@ -3158,7 +3158,7 @@ namespace ts {
|
||||
getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true),
|
||||
getLocalName(node)
|
||||
);
|
||||
setSourceMapRange(expression, createRange(node.name.pos, node.end));
|
||||
setSourceMapRange(expression, createRange(node.name ? node.name.pos : node.pos, node.end));
|
||||
|
||||
const statement = createStatement(expression);
|
||||
setSourceMapRange(statement, createRange(-1, node.end));
|
||||
@@ -3210,7 +3210,7 @@ namespace ts {
|
||||
function getClassAliasIfNeeded(node: ClassDeclaration) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) {
|
||||
enableSubstitutionForClassAliases();
|
||||
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? unescapeIdentifier(node.name.text) : "default");
|
||||
const classAlias = createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? unescapeLeadingUnderscores(node.name.escapedText) : "default");
|
||||
classAliases[getOriginalNodeId(node)] = classAlias;
|
||||
hoistVariableDeclaration(classAlias);
|
||||
return classAlias;
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export function getOriginalNodeId(node: Node) {
|
||||
node = getOriginalNode(node);
|
||||
return node ? getNodeId(node) : 0;
|
||||
}
|
||||
|
||||
export interface ExternalModuleInfo {
|
||||
externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules
|
||||
externalHelpersImportDeclaration: ImportDeclaration | undefined; // import of external helpers
|
||||
exportSpecifiers: Map<ExportSpecifier[]>; // export specifiers by name
|
||||
exportedBindings: Identifier[][]; // exported names of local declarations
|
||||
exportedNames: Identifier[]; // all exported names local to module
|
||||
exportEquals: ExportAssignment | undefined; // an export= declaration if one was present
|
||||
hasExportStarsToExportValues: boolean; // whether this module contains export*
|
||||
}
|
||||
|
||||
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver, compilerOptions: CompilerOptions): ExternalModuleInfo {
|
||||
const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
|
||||
const exportSpecifiers = createMultiMap<ExportSpecifier>();
|
||||
const exportedBindings: Identifier[][] = [];
|
||||
const uniqueExports = createMap<boolean>();
|
||||
let exportedNames: Identifier[];
|
||||
let hasExportDefault = false;
|
||||
let exportEquals: ExportAssignment = undefined;
|
||||
let hasExportStarsToExportValues = false;
|
||||
|
||||
for (const node of sourceFile.statements) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
// import "mod"
|
||||
// import x from "mod"
|
||||
// import * as x from "mod"
|
||||
// import { x, y } from "mod"
|
||||
externalImports.push(<ImportDeclaration>node);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
if ((<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference) {
|
||||
// import x = require("mod")
|
||||
externalImports.push(<ImportEqualsDeclaration>node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
if ((<ExportDeclaration>node).moduleSpecifier) {
|
||||
if (!(<ExportDeclaration>node).exportClause) {
|
||||
// export * from "mod"
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
hasExportStarsToExportValues = true;
|
||||
}
|
||||
else {
|
||||
// export { x, y } from "mod"
|
||||
externalImports.push(<ExportDeclaration>node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export { x, y }
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
|
||||
if (!uniqueExports.get(unescapeLeadingUnderscores(specifier.name.escapedText))) {
|
||||
const name = specifier.propertyName || specifier.name;
|
||||
exportSpecifiers.add(unescapeLeadingUnderscores(name.escapedText), specifier);
|
||||
|
||||
const decl = resolver.getReferencedImportDeclaration(name)
|
||||
|| resolver.getReferencedValueDeclaration(name);
|
||||
|
||||
if (decl) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
|
||||
}
|
||||
|
||||
uniqueExports.set(unescapeLeadingUnderscores(specifier.name.escapedText), true);
|
||||
exportedNames = append(exportedNames, specifier.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportAssignment:
|
||||
if ((<ExportAssignment>node).isExportEquals && !exportEquals) {
|
||||
// export = x
|
||||
exportEquals = <ExportAssignment>node;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.VariableStatement:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
for (const decl of (<VariableStatement>node).declarationList.declarations) {
|
||||
exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default function() { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<FunctionDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export function x() { }
|
||||
const name = (<FunctionDeclaration>node).name;
|
||||
if (!uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(unescapeLeadingUnderscores(name.escapedText), true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default class { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<ClassDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export class x { }
|
||||
const name = (<ClassDeclaration>node).name;
|
||||
if (!uniqueExports.get(unescapeLeadingUnderscores(name.escapedText))) {
|
||||
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports.set(unescapeLeadingUnderscores(name.escapedText), true);
|
||||
exportedNames = append(exportedNames, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const externalHelpersModuleName = getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues);
|
||||
const externalHelpersImportDeclaration = externalHelpersModuleName && createImportDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
|
||||
createLiteral(externalHelpersModuleNameText));
|
||||
|
||||
if (externalHelpersImportDeclaration) {
|
||||
externalImports.unshift(externalHelpersImportDeclaration);
|
||||
}
|
||||
|
||||
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames, externalHelpersImportDeclaration };
|
||||
}
|
||||
|
||||
function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map<boolean>, exportedNames: Identifier[]) {
|
||||
if (isBindingPattern(decl.name)) {
|
||||
for (const element of decl.name.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!isGeneratedIdentifier(decl.name)) {
|
||||
if (!uniqueExports.get(unescapeLeadingUnderscores(decl.name.escapedText))) {
|
||||
uniqueExports.set(unescapeLeadingUnderscores(decl.name.escapedText), true);
|
||||
exportedNames = append(exportedNames, decl.name);
|
||||
}
|
||||
}
|
||||
return exportedNames;
|
||||
}
|
||||
|
||||
/** Use a sparse array as a multi-map. */
|
||||
function multiMapSparseArrayAdd<V>(map: V[][], key: number, value: V): V[] {
|
||||
let values = map[key];
|
||||
if (values) {
|
||||
values.push(value);
|
||||
}
|
||||
else {
|
||||
map[key] = values = [value];
|
||||
}
|
||||
return values;
|
||||
}
|
||||
}
|
||||
+26
-17
@@ -61,7 +61,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function reportDiagnosticWithColorAndContext(diagnostic: Diagnostic, host: FormatDiagnosticsHost): void {
|
||||
sys.write(ts.formatDiagnosticsWithColorAndContext([diagnostic], host) + sys.newLine + sys.newLine);
|
||||
sys.write(ts.formatDiagnosticsWithColorAndContext([diagnostic], host) + sys.newLine);
|
||||
}
|
||||
|
||||
function reportWatchDiagnostic(diagnostic: Diagnostic) {
|
||||
@@ -223,20 +223,13 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = parseConfigFileTextToJson(configFileName, cachedConfigFileText);
|
||||
const configObject = result.config;
|
||||
if (!configObject) {
|
||||
reportDiagnostics([result.error], /* compilerHost */ undefined);
|
||||
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
return;
|
||||
}
|
||||
const result = parseJsonText(configFileName, cachedConfigFileText);
|
||||
reportDiagnostics(result.parseDiagnostics, /* compilerHost */ undefined);
|
||||
|
||||
const cwd = sys.getCurrentDirectory();
|
||||
const configParseResult = parseJsonConfigFileContent(configObject, sys, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), commandLine.options, getNormalizedAbsolutePath(configFileName, cwd));
|
||||
if (configParseResult.errors.length > 0) {
|
||||
reportDiagnostics(configParseResult.errors, /* compilerHost */ undefined);
|
||||
sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
return;
|
||||
}
|
||||
const configParseResult = parseJsonSourceFileConfigFileContent(result, sys, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), commandLine.options, getNormalizedAbsolutePath(configFileName, cwd));
|
||||
reportDiagnostics(configParseResult.errors, /* compilerHost */ undefined);
|
||||
|
||||
if (isWatchSet(configParseResult.options)) {
|
||||
if (!sys.watchFile) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--watch"), /* host */ undefined);
|
||||
@@ -292,6 +285,16 @@ namespace ts {
|
||||
|
||||
setCachedProgram(compileResult.program);
|
||||
reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes));
|
||||
|
||||
const missingPaths = compileResult.program.getMissingFilePaths();
|
||||
missingPaths.forEach(path => {
|
||||
const fileWatcher = sys.watchFile(path, (_fileName, eventKind) => {
|
||||
if (eventKind === FileWatcherEventKind.Created) {
|
||||
fileWatcher.close();
|
||||
startTimerForRecompilation();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function cachedFileExists(fileName: string): boolean {
|
||||
@@ -315,7 +318,7 @@ namespace ts {
|
||||
const sourceFile = hostGetSourceFile(fileName, languageVersion, onError);
|
||||
if (sourceFile && isWatchSet(compilerOptions) && sys.watchFile) {
|
||||
// Attach a file watcher
|
||||
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (_fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
|
||||
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (_fileName, eventKind) => sourceFileChanged(sourceFile, eventKind));
|
||||
}
|
||||
return sourceFile;
|
||||
}
|
||||
@@ -337,10 +340,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
// If a source file changes, mark it as unwatched and start the recompilation timer
|
||||
function sourceFileChanged(sourceFile: SourceFile, removed?: boolean) {
|
||||
function sourceFileChanged(sourceFile: SourceFile, eventKind: FileWatcherEventKind) {
|
||||
sourceFile.fileWatcher.close();
|
||||
sourceFile.fileWatcher = undefined;
|
||||
if (removed) {
|
||||
if (eventKind === FileWatcherEventKind.Deleted) {
|
||||
unorderedRemoveItem(rootFileNames, sourceFile.fileName);
|
||||
}
|
||||
startTimerForRecompilation();
|
||||
@@ -662,6 +665,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
ts.setStackTraceLimit();
|
||||
|
||||
if (ts.Debug.isDebugging) {
|
||||
ts.Debug.enableDebugInfo();
|
||||
}
|
||||
|
||||
if (ts.sys.tryEnableSourceMapsForHost && /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV"))) {
|
||||
ts.sys.tryEnableSourceMapsForHost();
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"checker.ts",
|
||||
"factory.ts",
|
||||
"visitor.ts",
|
||||
"transformers/utilities.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/esnext.ts",
|
||||
@@ -25,7 +26,6 @@
|
||||
"transformers/es2015.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformers/generators.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformers/module/system.ts",
|
||||
|
||||
+243
-195
@@ -8,13 +8,10 @@ namespace ts {
|
||||
[index: string]: T;
|
||||
}
|
||||
|
||||
/** ES6 Map interface. */
|
||||
export interface Map<T> {
|
||||
/** ES6 Map interface, only read methods included. */
|
||||
export interface ReadonlyMap<T> {
|
||||
get(key: string): T | undefined;
|
||||
has(key: string): boolean;
|
||||
set(key: string, value: T): this;
|
||||
delete(key: string): boolean;
|
||||
clear(): void;
|
||||
forEach(action: (value: T, key: string) => void): void;
|
||||
readonly size: number;
|
||||
keys(): Iterator<string>;
|
||||
@@ -22,26 +19,27 @@ namespace ts {
|
||||
entries(): Iterator<[string, T]>;
|
||||
}
|
||||
|
||||
/** ES6 Map interface. */
|
||||
export interface Map<T> extends ReadonlyMap<T> {
|
||||
set(key: string, value: T): this;
|
||||
delete(key: string): boolean;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
/** ES6 Iterator type. */
|
||||
export interface Iterator<T> {
|
||||
next(): { value: T, done: false } | { value: never, done: true };
|
||||
}
|
||||
|
||||
/** Array that is only intended to be pushed to, never read. */
|
||||
export interface Push<T> {
|
||||
push(...values: T[]): void;
|
||||
}
|
||||
|
||||
// branded string type used to store absolute, normalized and canonicalized paths
|
||||
// arbitrary file name can be converted to Path via toPath function
|
||||
export type Path = string & { __pathBrand: any };
|
||||
|
||||
export interface FileMap<T> {
|
||||
get(fileName: Path): T;
|
||||
set(fileName: Path, value: T): void;
|
||||
contains(fileName: Path): boolean;
|
||||
remove(fileName: Path): void;
|
||||
|
||||
forEachValue(f: (key: Path, v: T) => void): void;
|
||||
getKeys(): Path[];
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
export interface TextRange {
|
||||
pos: number;
|
||||
end: number;
|
||||
@@ -358,22 +356,15 @@ namespace ts {
|
||||
JSDocAllType,
|
||||
// The ? type
|
||||
JSDocUnknownType,
|
||||
JSDocArrayType,
|
||||
JSDocUnionType,
|
||||
JSDocTupleType,
|
||||
JSDocNullableType,
|
||||
JSDocNonNullableType,
|
||||
JSDocRecordType,
|
||||
JSDocRecordMember,
|
||||
JSDocTypeReference,
|
||||
JSDocOptionalType,
|
||||
JSDocFunctionType,
|
||||
JSDocVariadicType,
|
||||
JSDocConstructorType,
|
||||
JSDocThisType,
|
||||
JSDocComment,
|
||||
JSDocTag,
|
||||
JSDocAugmentsTag,
|
||||
JSDocClassTag,
|
||||
JSDocParameterTag,
|
||||
JSDocReturnTag,
|
||||
JSDocTypeTag,
|
||||
@@ -381,7 +372,6 @@ namespace ts {
|
||||
JSDocTypedefTag,
|
||||
JSDocPropertyTag,
|
||||
JSDocTypeLiteral,
|
||||
JSDocLiteralType,
|
||||
|
||||
// Synthesized list
|
||||
SyntaxList,
|
||||
@@ -423,9 +413,9 @@ namespace ts {
|
||||
LastBinaryOperator = CaretEqualsToken,
|
||||
FirstNode = QualifiedName,
|
||||
FirstJSDocNode = JSDocTypeExpression,
|
||||
LastJSDocNode = JSDocLiteralType,
|
||||
FirstJSDocTagNode = JSDocComment,
|
||||
LastJSDocTagNode = JSDocLiteralType
|
||||
LastJSDocNode = JSDocTypeLiteral,
|
||||
FirstJSDocTagNode = JSDocTag,
|
||||
LastJSDocTagNode = JSDocTypeLiteral
|
||||
}
|
||||
|
||||
export const enum NodeFlags {
|
||||
@@ -450,13 +440,17 @@ namespace ts {
|
||||
ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error
|
||||
HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node
|
||||
|
||||
// This flag will be set to true when the parse encounter dynamic import so that post-parsing process of module resolution
|
||||
// will not walk the tree if the flag is not set. However, this flag is just a approximation because once it is set, the flag never get reset.
|
||||
// (hence it is named "possiblyContainDynamicImport").
|
||||
// During editing, if dynamic import is remove, incremental parsing will *NOT* update this flag. This will then causes walking of the tree during module resolution.
|
||||
// However, the removal operation should not occur often and in the case of the removal, it is likely that users will add back the import anyway.
|
||||
// The advantage of this approach is its simplicity. For the case of batch compilation, we garuntee that users won't have to pay the price of walking the tree if dynamic import isn't used.
|
||||
PossiblyContainDynamicImport = 1 << 19,
|
||||
// This flag will be set when the parser encounters a dynamic import expression so that module resolution
|
||||
// will not have to walk the tree if the flag is not set. However, this flag is just a approximation because
|
||||
// once it is set, the flag never gets cleared (hence why it's named "PossiblyContainsDynamicImport").
|
||||
// During editing, if dynamic import is removed, incremental parsing will *NOT* update this flag. This means that the tree will always be traversed
|
||||
// during module resolution. However, the removal operation should not occur often and in the case of the
|
||||
// removal, it is likely that users will add the import anyway.
|
||||
// The advantage of this approach is its simplicity. For the case of batch compilation,
|
||||
// we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
|
||||
/* @internal */
|
||||
PossiblyContainsDynamicImport = 1 << 19,
|
||||
JSDoc = 1 << 20, // If node was parsed inside jsdoc
|
||||
|
||||
BlockScoped = Let | Const,
|
||||
|
||||
@@ -516,25 +510,28 @@ namespace ts {
|
||||
flags: NodeFlags;
|
||||
/* @internal */ modifierFlagsCache?: ModifierFlags;
|
||||
/* @internal */ transformFlags?: TransformFlags;
|
||||
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
|
||||
modifiers?: ModifiersArray; // Array of modifiers
|
||||
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
|
||||
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?: (JSDoc | JSDocTag)[]; // All JSDoc that applies to the node, including parent docs and @param tags
|
||||
/* @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)
|
||||
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
|
||||
/* @internal */ flowNode?: FlowNode; // Associated FlowNode (initialized by binding)
|
||||
/* @internal */ emitNode?: EmitNode; // Associated EmitNode (initialized by transforms)
|
||||
/* @internal */ contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
|
||||
/* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type
|
||||
decorators?: NodeArray<Decorator>; // Array of decorators (in document order)
|
||||
modifiers?: ModifiersArray; // Array of modifiers
|
||||
/* @internal */ id?: number; // Unique id (used to look up NodeLinks)
|
||||
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)
|
||||
/* @internal */ localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
|
||||
/* @internal */ flowNode?: FlowNode; // Associated FlowNode (initialized by binding)
|
||||
/* @internal */ emitNode?: EmitNode; // Associated EmitNode (initialized by transforms)
|
||||
/* @internal */ contextualType?: Type; // Used to temporarily assign a contextual type during overload resolution
|
||||
/* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type
|
||||
}
|
||||
|
||||
export interface NodeArray<T extends Node> extends Array<T>, TextRange {
|
||||
/* @internal */
|
||||
export type MutableNodeArray<T extends Node> = NodeArray<T> & T[];
|
||||
|
||||
export interface NodeArray<T extends Node> extends ReadonlyArray<T>, TextRange {
|
||||
hasTrailingComma?: boolean;
|
||||
/* @internal */ transformFlags?: TransformFlags;
|
||||
}
|
||||
@@ -582,15 +579,16 @@ namespace ts {
|
||||
export interface Identifier extends PrimaryExpression {
|
||||
kind: SyntaxKind.Identifier;
|
||||
/**
|
||||
* Text of identifier (with escapes converted to characters).
|
||||
* If the identifier begins with two underscores, this will begin with three.
|
||||
* Prefer to use `id.unescapedText`. (Note: This is available only in services, not internally to the TypeScript compiler.)
|
||||
* Text of identifier, but if the identifier begins with two underscores, this will begin with three.
|
||||
*/
|
||||
text: string;
|
||||
escapedText: __String;
|
||||
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
|
||||
/*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
|
||||
/*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name.
|
||||
isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace
|
||||
/*@internal*/ typeArguments?: NodeArray<TypeNode>; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics.
|
||||
/*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id.<T>
|
||||
}
|
||||
|
||||
// Transient identifier node (marked by id === -1)
|
||||
@@ -610,6 +608,7 @@ namespace ts {
|
||||
kind: SyntaxKind.QualifiedName;
|
||||
left: EntityName;
|
||||
right: Identifier;
|
||||
/*@internal*/ jsdocDotPos?: number; // QualifiedName occurs in JSDoc-style generic: Id1.Id2.<T>
|
||||
}
|
||||
|
||||
export type EntityName = Identifier | QualifiedName;
|
||||
@@ -686,7 +685,7 @@ namespace ts {
|
||||
kind: SyntaxKind.Parameter;
|
||||
parent?: SignatureDeclaration;
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
|
||||
name: BindingName; // Declared parameter name
|
||||
name: BindingName; // Declared parameter name.
|
||||
questionToken?: QuestionToken; // Present on optional parameter
|
||||
type?: TypeNode; // Optional type annotation
|
||||
initializer?: Expression; // Optional initializer
|
||||
@@ -702,7 +701,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface PropertySignature extends TypeElement {
|
||||
kind: SyntaxKind.PropertySignature | SyntaxKind.JSDocRecordMember;
|
||||
kind: SyntaxKind.PropertySignature;
|
||||
name: PropertyName; // Declared property name
|
||||
questionToken?: QuestionToken; // Present on optional property
|
||||
type?: TypeNode; // Optional type annotation
|
||||
@@ -761,10 +760,11 @@ namespace ts {
|
||||
// SyntaxKind.ShorthandPropertyAssignment
|
||||
// SyntaxKind.EnumMember
|
||||
// SyntaxKind.JSDocPropertyTag
|
||||
// SyntaxKind.JSDocParameterTag
|
||||
export interface VariableLikeDeclaration extends NamedDeclaration {
|
||||
propertyName?: PropertyName;
|
||||
dotDotDotToken?: DotDotDotToken;
|
||||
name: DeclarationName;
|
||||
name?: DeclarationName; // May be missing for ParameterDeclaration, see comment there
|
||||
questionToken?: QuestionToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
@@ -792,13 +792,13 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Several node kinds share function-like features such as a signature,
|
||||
* a name, and a body. These nodes should extend FunctionLikeDeclaration.
|
||||
* a name, and a body. These nodes should extend FunctionLikeDeclarationBase.
|
||||
* Examples:
|
||||
* - FunctionDeclaration
|
||||
* - MethodDeclaration
|
||||
* - AccessorDeclaration
|
||||
*/
|
||||
export interface FunctionLikeDeclaration extends SignatureDeclaration {
|
||||
export interface FunctionLikeDeclarationBase extends SignatureDeclaration {
|
||||
_functionLikeDeclarationBrand: any;
|
||||
|
||||
asteriskToken?: AsteriskToken;
|
||||
@@ -806,7 +806,24 @@ namespace ts {
|
||||
body?: Block | Expression;
|
||||
}
|
||||
|
||||
export interface FunctionDeclaration extends FunctionLikeDeclaration, DeclarationStatement {
|
||||
export type FunctionLikeDeclaration =
|
||||
| FunctionDeclaration
|
||||
| MethodDeclaration
|
||||
| ConstructorDeclaration
|
||||
| GetAccessorDeclaration
|
||||
| SetAccessorDeclaration
|
||||
| FunctionExpression
|
||||
| ArrowFunction;
|
||||
export type FunctionLike =
|
||||
| FunctionLikeDeclaration
|
||||
| FunctionTypeNode
|
||||
| ConstructorTypeNode
|
||||
| IndexSignatureDeclaration
|
||||
| MethodSignature
|
||||
| ConstructSignatureDeclaration
|
||||
| CallSignatureDeclaration;
|
||||
|
||||
export interface FunctionDeclaration extends FunctionLikeDeclarationBase, DeclarationStatement {
|
||||
kind: SyntaxKind.FunctionDeclaration;
|
||||
name?: Identifier;
|
||||
body?: FunctionBody;
|
||||
@@ -826,13 +843,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 FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
|
||||
export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
kind: SyntaxKind.MethodDeclaration;
|
||||
name: PropertyName;
|
||||
body?: FunctionBody;
|
||||
}
|
||||
|
||||
export interface ConstructorDeclaration extends FunctionLikeDeclaration, ClassElement {
|
||||
export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement {
|
||||
kind: SyntaxKind.Constructor;
|
||||
parent?: ClassDeclaration | ClassExpression;
|
||||
body?: FunctionBody;
|
||||
@@ -846,7 +863,7 @@ namespace ts {
|
||||
|
||||
// See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface GetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
|
||||
export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
kind: SyntaxKind.GetAccessor;
|
||||
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
@@ -855,7 +872,7 @@ namespace ts {
|
||||
|
||||
// See the comment on MethodDeclaration for the intuition behind SetAccessorDeclaration being a
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface SetAccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement {
|
||||
export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
kind: SyntaxKind.SetAccessor;
|
||||
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
@@ -901,7 +918,7 @@ namespace ts {
|
||||
kind: SyntaxKind.ConstructorType;
|
||||
}
|
||||
|
||||
export type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference;
|
||||
export type TypeReferenceType = TypeReferenceNode | ExpressionWithTypeArguments;
|
||||
|
||||
export interface TypeReferenceNode extends TypeNode {
|
||||
kind: SyntaxKind.TypeReference;
|
||||
@@ -1319,13 +1336,13 @@ namespace ts {
|
||||
export type FunctionBody = Block;
|
||||
export type ConciseBody = FunctionBody | Expression;
|
||||
|
||||
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclaration {
|
||||
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclarationBase {
|
||||
kind: SyntaxKind.FunctionExpression;
|
||||
name?: Identifier;
|
||||
body: FunctionBody; // Required, whereas the member inherited from FunctionDeclaration is optional
|
||||
}
|
||||
|
||||
export interface ArrowFunction extends Expression, FunctionLikeDeclaration {
|
||||
export interface ArrowFunction extends Expression, FunctionLikeDeclarationBase {
|
||||
kind: SyntaxKind.ArrowFunction;
|
||||
equalsGreaterThanToken: EqualsGreaterThanToken;
|
||||
body: ConciseBody;
|
||||
@@ -1704,6 +1721,8 @@ namespace ts {
|
||||
incrementor?: Expression;
|
||||
}
|
||||
|
||||
export type ForInOrOfStatement = ForInStatement | ForOfStatement;
|
||||
|
||||
export interface ForInStatement extends IterationStatement {
|
||||
kind: SyntaxKind.ForInStatement;
|
||||
initializer: ForInitializer;
|
||||
@@ -1793,7 +1812,7 @@ namespace ts {
|
||||
block: Block;
|
||||
}
|
||||
|
||||
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration;
|
||||
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
|
||||
export interface ClassLikeDeclaration extends NamedDeclaration {
|
||||
name?: Identifier;
|
||||
@@ -2018,9 +2037,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
// represents a top level: { type } expression in a JSDoc comment.
|
||||
export interface JSDocTypeExpression extends Node {
|
||||
export interface JSDocTypeExpression extends TypeNode {
|
||||
kind: SyntaxKind.JSDocTypeExpression;
|
||||
type: JSDocType;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface JSDocType extends TypeNode {
|
||||
@@ -2035,80 +2054,31 @@ namespace ts {
|
||||
kind: SyntaxKind.JSDocUnknownType;
|
||||
}
|
||||
|
||||
export interface JSDocArrayType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocArrayType;
|
||||
elementType: JSDocType;
|
||||
}
|
||||
|
||||
export interface JSDocUnionType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocUnionType;
|
||||
types: NodeArray<JSDocType>;
|
||||
}
|
||||
|
||||
export interface JSDocTupleType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocTupleType;
|
||||
types: NodeArray<JSDocType>;
|
||||
}
|
||||
|
||||
export interface JSDocNonNullableType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocNonNullableType;
|
||||
type: JSDocType;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface JSDocNullableType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocNullableType;
|
||||
type: JSDocType;
|
||||
}
|
||||
|
||||
export interface JSDocRecordType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocRecordType;
|
||||
literal: TypeLiteralNode;
|
||||
}
|
||||
|
||||
export interface JSDocTypeReference extends JSDocType {
|
||||
kind: SyntaxKind.JSDocTypeReference;
|
||||
name: EntityName;
|
||||
typeArguments: NodeArray<JSDocType>;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface JSDocOptionalType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocOptionalType;
|
||||
type: JSDocType;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface JSDocFunctionType extends JSDocType, SignatureDeclaration {
|
||||
kind: SyntaxKind.JSDocFunctionType;
|
||||
parameters: NodeArray<ParameterDeclaration>;
|
||||
type: JSDocType;
|
||||
}
|
||||
|
||||
export interface JSDocVariadicType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocVariadicType;
|
||||
type: JSDocType;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface JSDocConstructorType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocConstructorType;
|
||||
type: JSDocType;
|
||||
}
|
||||
|
||||
export interface JSDocThisType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocThisType;
|
||||
type: JSDocType;
|
||||
}
|
||||
|
||||
export interface JSDocLiteralType extends JSDocType {
|
||||
kind: SyntaxKind.JSDocLiteralType;
|
||||
literal: LiteralTypeNode;
|
||||
}
|
||||
|
||||
export type JSDocTypeReferencingNode = JSDocThisType | JSDocConstructorType | JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType;
|
||||
|
||||
export interface JSDocRecordMember extends PropertySignature {
|
||||
kind: SyntaxKind.JSDocRecordMember;
|
||||
name: Identifier | StringLiteral | NumericLiteral;
|
||||
type?: JSDocType;
|
||||
}
|
||||
export type JSDocTypeReferencingNode = JSDocVariadicType | JSDocOptionalType | JSDocNullableType | JSDocNonNullableType;
|
||||
|
||||
export interface JSDoc extends Node {
|
||||
kind: SyntaxKind.JSDocComment;
|
||||
@@ -2132,6 +2102,10 @@ namespace ts {
|
||||
typeExpression: JSDocTypeExpression;
|
||||
}
|
||||
|
||||
export interface JSDocClassTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocClassTag;
|
||||
}
|
||||
|
||||
export interface JSDocTemplateTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocTemplateTag;
|
||||
typeParameters: NodeArray<TypeParameterDeclaration>;
|
||||
@@ -2152,38 +2126,32 @@ namespace ts {
|
||||
kind: SyntaxKind.JSDocTypedefTag;
|
||||
fullName?: JSDocNamespaceDeclaration | Identifier;
|
||||
name?: Identifier;
|
||||
typeExpression?: JSDocTypeExpression;
|
||||
jsDocTypeLiteral?: JSDocTypeLiteral;
|
||||
typeExpression?: JSDocTypeExpression | JSDocTypeLiteral;
|
||||
}
|
||||
|
||||
export interface JSDocPropertyTag extends JSDocTag, TypeElement {
|
||||
export interface JSDocPropertyLikeTag extends JSDocTag, Declaration {
|
||||
parent: JSDoc;
|
||||
kind: SyntaxKind.JSDocPropertyTag;
|
||||
name: Identifier;
|
||||
/** the parameter name, if provided *before* the type (TypeScript-style) */
|
||||
preParameterName?: Identifier;
|
||||
/** the parameter name, if provided *after* the type (JSDoc-standard) */
|
||||
postParameterName?: Identifier;
|
||||
name: EntityName;
|
||||
typeExpression: JSDocTypeExpression;
|
||||
/** Whether the property name came before the type -- non-standard for JSDoc, but Typescript-like */
|
||||
isNameFirst: boolean;
|
||||
isBracketed: boolean;
|
||||
}
|
||||
|
||||
export interface JSDocPropertyTag extends JSDocPropertyLikeTag {
|
||||
kind: SyntaxKind.JSDocPropertyTag;
|
||||
}
|
||||
|
||||
export interface JSDocParameterTag extends JSDocPropertyLikeTag {
|
||||
kind: SyntaxKind.JSDocParameterTag;
|
||||
}
|
||||
|
||||
export interface JSDocTypeLiteral extends JSDocType {
|
||||
kind: SyntaxKind.JSDocTypeLiteral;
|
||||
jsDocPropertyTags?: NodeArray<JSDocPropertyTag>;
|
||||
jsDocPropertyTags?: ReadonlyArray<JSDocPropertyLikeTag>;
|
||||
jsDocTypeTag?: JSDocTypeTag;
|
||||
}
|
||||
|
||||
export interface JSDocParameterTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocParameterTag;
|
||||
/** the parameter name, if provided *before* the type (TypeScript-style) */
|
||||
preParameterName?: Identifier;
|
||||
typeExpression?: JSDocTypeExpression;
|
||||
/** the parameter name, if provided *after* the type (JSDoc-standard) */
|
||||
postParameterName?: Identifier;
|
||||
/** the parameter name, regardless of the location it was provided */
|
||||
name: Identifier;
|
||||
isBracketed: boolean;
|
||||
/** If true, then this type literal represents an *array* of its type. */
|
||||
isArrayType?: boolean;
|
||||
}
|
||||
|
||||
export const enum FlowFlags {
|
||||
@@ -2326,7 +2294,7 @@ namespace ts {
|
||||
// The first node that causes this file to be a CommonJS module
|
||||
/* @internal */ commonJsModuleIndicator: Node;
|
||||
|
||||
/* @internal */ identifiers: Map<string>;
|
||||
/* @internal */ identifiers: Map<string>; // Map from a string to an interned string
|
||||
/* @internal */ nodeCount: number;
|
||||
/* @internal */ identifierCount: number;
|
||||
/* @internal */ symbolCount: number;
|
||||
@@ -2347,16 +2315,16 @@ namespace ts {
|
||||
// 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?: Map<string>;
|
||||
/* @internal */ classifiableNames?: UnderscoreEscapedMap<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: StringLiteral[];
|
||||
/* @internal */ moduleAugmentations: StringLiteral[];
|
||||
/* @internal */ imports: ReadonlyArray<StringLiteral>;
|
||||
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral>;
|
||||
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
|
||||
/* @internal */ ambientModuleNames: string[];
|
||||
/* @internal */ ambientModuleNames: ReadonlyArray<string>;
|
||||
/* @internal */ checkJsDirective: CheckJsDirective | undefined;
|
||||
}
|
||||
|
||||
@@ -2365,6 +2333,11 @@ namespace ts {
|
||||
sourceFiles: SourceFile[];
|
||||
}
|
||||
|
||||
export interface JsonSourceFile extends SourceFile {
|
||||
jsonObject?: ObjectLiteralExpression;
|
||||
extendedSourceFiles?: string[];
|
||||
}
|
||||
|
||||
export interface ScriptReferenceHost {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getSourceFile(fileName: string): SourceFile;
|
||||
@@ -2375,7 +2348,7 @@ namespace ts {
|
||||
export interface ParseConfigHost {
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
|
||||
readDirectory(rootDir: string, extensions: string[], excludes: string[], includes: string[]): string[];
|
||||
readDirectory(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string>, includes: ReadonlyArray<string>, depth: number): string[];
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether the specified path exists and is a file.
|
||||
@@ -2383,11 +2356,11 @@ namespace ts {
|
||||
*/
|
||||
fileExists(path: string): boolean;
|
||||
|
||||
readFile(path: string): string;
|
||||
readFile(path: string): string | undefined;
|
||||
}
|
||||
|
||||
export interface WriteFileCallback {
|
||||
(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: SourceFile[]): void;
|
||||
(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: ReadonlyArray<SourceFile>): void;
|
||||
}
|
||||
|
||||
export class OperationCanceledException { }
|
||||
@@ -2411,6 +2384,13 @@ namespace ts {
|
||||
*/
|
||||
getSourceFiles(): 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[];
|
||||
|
||||
/**
|
||||
* Emits the JavaScript and declaration files. If targetSourceFile is not specified, then
|
||||
* the JavaScript and declaration files will be produced for all the files in this program.
|
||||
@@ -2441,7 +2421,7 @@ namespace ts {
|
||||
/* @internal */ getDiagnosticsProducingTypeChecker(): TypeChecker;
|
||||
/* @internal */ dropDiagnosticsProducingTypeChecker(): void;
|
||||
|
||||
/* @internal */ getClassifiableNames(): Map<string>;
|
||||
/* @internal */ getClassifiableNames(): UnderscoreEscapedMap<true>;
|
||||
|
||||
/* @internal */ getNodeCount(): number;
|
||||
/* @internal */ getIdentifierCount(): number;
|
||||
@@ -2547,6 +2527,7 @@ namespace ts {
|
||||
* Returns `any` if the index is not valid.
|
||||
*/
|
||||
/* @internal */ getParameterType(signature: Signature, parameterIndex: number): Type;
|
||||
getNullableType(type: Type, flags: TypeFlags): Type;
|
||||
getNonNullableType(type: Type): Type;
|
||||
|
||||
/** Note that the resulting nodes cannot be checked. */
|
||||
@@ -2572,9 +2553,13 @@ namespace ts {
|
||||
getAugmentedPropertiesOfType(type: Type): Symbol[];
|
||||
getRootSymbols(symbol: Symbol): Symbol[];
|
||||
getContextualType(node: Expression): Type | undefined;
|
||||
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature | undefined;
|
||||
/**
|
||||
* returns unknownSignature in the case of an error. Don't know when it returns undefined.
|
||||
* @param argumentCount Apparent number of arguments, passed in case of a possibly incomplete call. This should come from an ArgumentListInfo. See `signatureHelp.ts`.
|
||||
*/
|
||||
getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[], argumentCount?: number): Signature | undefined;
|
||||
getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature | undefined;
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined;
|
||||
isImplementationOfOverload(node: FunctionLike): boolean | undefined;
|
||||
isUndefinedSymbol(symbol: Symbol): boolean;
|
||||
isArgumentsSymbol(symbol: Symbol): boolean;
|
||||
isUnknownSymbol(symbol: Symbol): boolean;
|
||||
@@ -2596,6 +2581,8 @@ namespace ts {
|
||||
getAmbientModules(): Symbol[];
|
||||
|
||||
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
/** Unlike `tryGetMemberInModuleExports`, this includes properties of an `export =` value. */
|
||||
/* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
getApparentType(type: Type): Type;
|
||||
getSuggestionForNonexistentProperty(node: Identifier, containingType: Type): string | undefined;
|
||||
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
@@ -2700,6 +2687,7 @@ namespace ts {
|
||||
SuppressAnyReturnType = 1 << 12, // If the return type is any-like, don't offer a return type.
|
||||
AddUndefined = 1 << 13, // Add undefined to types of initialized, non-optional parameters
|
||||
WriteClassExpressionAsTypeLiteral = 1 << 14, // Write a type literal instead of (Anonymous class)
|
||||
InArrayType = 1 << 15, // Writing an array element type
|
||||
}
|
||||
|
||||
export const enum SymbolFormatFlags {
|
||||
@@ -2804,6 +2792,7 @@ namespace ts {
|
||||
collectLinkedAliases(node: Identifier): Node[];
|
||||
isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined;
|
||||
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
|
||||
isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean;
|
||||
writeTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
writeReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter): void;
|
||||
@@ -2847,13 +2836,11 @@ namespace ts {
|
||||
TypeParameter = 1 << 18, // Type parameter
|
||||
TypeAlias = 1 << 19, // Type alias
|
||||
ExportValue = 1 << 20, // Exported value marker (see comment in declareModuleMember in binder)
|
||||
ExportType = 1 << 21, // Exported type marker (see comment in declareModuleMember in binder)
|
||||
ExportNamespace = 1 << 22, // Exported namespace marker (see comment in declareModuleMember in binder)
|
||||
Alias = 1 << 23, // An alias for another symbol (see comment in isAliasSymbolDeclaration in checker)
|
||||
Prototype = 1 << 24, // Prototype property (no source representation)
|
||||
ExportStar = 1 << 25, // Export * declaration
|
||||
Optional = 1 << 26, // Optional property
|
||||
Transient = 1 << 27, // Transient symbol (created during type check)
|
||||
Alias = 1 << 21, // An alias for another symbol (see comment in isAliasSymbolDeclaration in checker)
|
||||
Prototype = 1 << 22, // Prototype property (no source representation)
|
||||
ExportStar = 1 << 23, // Export * declaration
|
||||
Optional = 1 << 24, // Optional property
|
||||
Transient = 1 << 25, // Transient symbol (created during type check)
|
||||
|
||||
Enum = RegularEnum | ConstEnum,
|
||||
Variable = FunctionScopedVariable | BlockScopedVariable,
|
||||
@@ -2898,7 +2885,6 @@ namespace ts {
|
||||
BlockScoped = BlockScopedVariable | Class | Enum,
|
||||
|
||||
PropertyOrAccessor = Property | Accessor,
|
||||
Export = ExportNamespace | ExportType | ExportValue,
|
||||
|
||||
ClassMember = Method | Accessor | Property,
|
||||
|
||||
@@ -2910,7 +2896,7 @@ namespace ts {
|
||||
|
||||
export interface Symbol {
|
||||
flags: SymbolFlags; // Symbol flags
|
||||
name: 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
|
||||
@@ -2978,7 +2964,55 @@ namespace ts {
|
||||
isRestParameter?: boolean;
|
||||
}
|
||||
|
||||
export type SymbolTable = Map<Symbol>;
|
||||
export const enum InternalSymbolName {
|
||||
Call = "__call", // Call signatures
|
||||
Constructor = "__constructor", // Constructor implementations
|
||||
New = "__new", // Constructor signatures
|
||||
Index = "__index", // Index signatures
|
||||
ExportStar = "__export", // Module export * declarations
|
||||
Global = "__global", // Global self-reference
|
||||
Missing = "__missing", // Indicates missing symbol
|
||||
Type = "__type", // Anonymous type literal symbol
|
||||
Object = "__object", // Anonymous object literal declaration
|
||||
JSXAttributes = "__jsxAttributes", // Anonymous JSX attributes object literal declaration
|
||||
Class = "__class", // Unnamed class expression
|
||||
Function = "__function", // Unnamed function expression
|
||||
Computed = "__computed", // Computed property name declaration with dynamic name
|
||||
Resolving = "__resolving__", // Indicator symbol used to mark partially resolved type aliases
|
||||
ExportEquals = "export=", // Export assignment symbol
|
||||
Default = "default", // Default export symbol (technically not wholly internal, but included here for usability)
|
||||
}
|
||||
|
||||
/**
|
||||
* This represents a string whose leading underscore have been escaped by adding extra leading underscores.
|
||||
* The shape of this brand is rather unique compared to others we've used.
|
||||
* Instead of just an intersection of a string and an object, it is that union-ed
|
||||
* with an intersection of void and an object. This makes it wholly incompatible
|
||||
* with a normal string (which is good, it cannot be misused on assignment or on usage),
|
||||
* while still being comparable with a normal string via === (also good) and castable from a string.
|
||||
*/
|
||||
export type __String = (string & { __escapedIdentifier: void }) | (void & { __escapedIdentifier: void }) | InternalSymbolName;
|
||||
|
||||
/** ReadonlyMap where keys are `__String`s. */
|
||||
export interface ReadonlyUnderscoreEscapedMap<T> {
|
||||
get(key: __String): T | undefined;
|
||||
has(key: __String): boolean;
|
||||
forEach(action: (value: T, key: __String) => void): void;
|
||||
readonly size: number;
|
||||
keys(): Iterator<__String>;
|
||||
values(): Iterator<T>;
|
||||
entries(): Iterator<[__String, T]>;
|
||||
}
|
||||
|
||||
/** Map where keys are `__String`s. */
|
||||
export interface UnderscoreEscapedMap<T> extends ReadonlyUnderscoreEscapedMap<T> {
|
||||
set(key: __String, value: T): this;
|
||||
delete(key: __String): boolean;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
/** SymbolTable based on ES6 Map interface. */
|
||||
export type SymbolTable = UnderscoreEscapedMap<Symbol>;
|
||||
|
||||
/** Represents a "prefix*suffix" pattern. */
|
||||
/* @internal */
|
||||
@@ -3159,7 +3193,7 @@ namespace ts {
|
||||
objectFlags: ObjectFlags;
|
||||
}
|
||||
|
||||
/** Class and interface types (TypeFlags.Class and TypeFlags.Interface). */
|
||||
/** Class and interface types (ObjectFlags.Class and ObjectFlags.Interface). */
|
||||
export interface InterfaceType extends ObjectType {
|
||||
typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic)
|
||||
outerTypeParameters: TypeParameter[]; // Outer type parameters (undefined if none)
|
||||
@@ -3183,7 +3217,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Type references (TypeFlags.Reference). When a class or interface has type parameters or
|
||||
* Type references (ObjectFlags.Reference). When a class or interface has type parameters or
|
||||
* a "this" type, references to the class or interface are made using type references. The
|
||||
* typeArguments property specifies the types to substitute for the type parameters of the
|
||||
* class or interface and optionally includes an extra element that specifies the type to
|
||||
@@ -3366,8 +3400,8 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface TypeMapper {
|
||||
(t: TypeParameter): Type;
|
||||
mappedTypes?: Type[]; // Types mapped by this mapper
|
||||
instantiations?: Type[]; // Cache of instantiations created using this type mapper.
|
||||
mappedTypes?: TypeParameter[]; // Types mapped by this mapper
|
||||
instantiations?: Type[]; // Cache of instantiations created using this type mapper.
|
||||
}
|
||||
|
||||
export const enum InferencePriority {
|
||||
@@ -3396,8 +3430,6 @@ namespace ts {
|
||||
signature: Signature; // Generic signature for which inferences are made
|
||||
inferences: InferenceInfo[]; // Inferences made for each type parameter
|
||||
flags: InferenceFlags; // Inference flags
|
||||
failedTypeParameterIndex?: number; // Index of type parameter for which inference failed
|
||||
// It is optional because in contextual signature instantiation, nothing fails
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3479,6 +3511,7 @@ namespace ts {
|
||||
charset?: string;
|
||||
checkJs?: boolean;
|
||||
/* @internal */ configFilePath?: string;
|
||||
/* @internal */ readonly configFile?: JsonSourceFile;
|
||||
declaration?: boolean;
|
||||
declarationDir?: string;
|
||||
/* @internal */ diagnostics?: boolean;
|
||||
@@ -3514,6 +3547,7 @@ namespace ts {
|
||||
noImplicitAny?: boolean; // Always combine with strict property
|
||||
noImplicitReturns?: boolean;
|
||||
noImplicitThis?: boolean; // Always combine with strict property
|
||||
noStrictGenericChecks?: boolean;
|
||||
noUnusedLocals?: boolean;
|
||||
noUnusedParameters?: boolean;
|
||||
noImplicitUseStrict?: boolean;
|
||||
@@ -3550,7 +3584,7 @@ namespace ts {
|
||||
/*@internal*/ version?: boolean;
|
||||
/*@internal*/ watch?: boolean;
|
||||
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
[option: string]: CompilerOptionsValue | JsonSourceFile | undefined;
|
||||
}
|
||||
|
||||
export interface TypeAcquisition {
|
||||
@@ -3610,7 +3644,8 @@ namespace ts {
|
||||
JSX = 2,
|
||||
TS = 3,
|
||||
TSX = 4,
|
||||
External = 5
|
||||
External = 5,
|
||||
JSON = 6
|
||||
}
|
||||
|
||||
export const enum ScriptTarget {
|
||||
@@ -3682,6 +3717,8 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface TsConfigOnlyOption extends CommandLineOptionBase {
|
||||
type: "object";
|
||||
elementOptions?: Map<CommandLineOption>;
|
||||
extraKeyDiagnosticMessage?: DiagnosticMessage;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3834,7 +3871,7 @@ namespace ts {
|
||||
fileExists(fileName: string): boolean;
|
||||
// readFile function is used to read arbitrary text files on disk, i.e. when resolution procedure needs the content of 'package.json'
|
||||
// to determine location of bundled typings for node module
|
||||
readFile(fileName: string): string;
|
||||
readFile(fileName: string): string | undefined;
|
||||
trace?(s: string): void;
|
||||
directoryExists?(directoryName: string): boolean;
|
||||
realpath?(path: string): string;
|
||||
@@ -3873,13 +3910,12 @@ namespace ts {
|
||||
extension: Extension;
|
||||
}
|
||||
|
||||
export enum Extension {
|
||||
Ts,
|
||||
Tsx,
|
||||
Dts,
|
||||
Js,
|
||||
Jsx,
|
||||
LastTypeScriptExtension = Dts
|
||||
export const enum Extension {
|
||||
Ts = ".ts",
|
||||
Tsx = ".tsx",
|
||||
Dts = ".d.ts",
|
||||
Js = ".js",
|
||||
Jsx = ".jsx"
|
||||
}
|
||||
|
||||
export interface ResolvedModuleWithFailedLookupLocations {
|
||||
@@ -4008,18 +4044,29 @@ namespace ts {
|
||||
ES2015FunctionSyntaxMask = ContainsCapturedLexicalThis | ContainsDefaultValueAssignments,
|
||||
}
|
||||
|
||||
export interface SourceMapRange extends TextRange {
|
||||
source?: SourceMapSource;
|
||||
}
|
||||
|
||||
export interface SourceMapSource {
|
||||
fileName: string;
|
||||
text: string;
|
||||
/* @internal */ lineMap: number[];
|
||||
skipTrivia?: (pos: number) => number;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface EmitNode {
|
||||
annotatedNodes?: Node[]; // Tracks Parse-tree nodes with EmitNodes for eventual cleanup.
|
||||
flags?: EmitFlags; // Flags that customize emit
|
||||
leadingComments?: SynthesizedComment[]; // Synthesized leading comments
|
||||
annotatedNodes?: Node[]; // Tracks Parse-tree nodes with EmitNodes for eventual cleanup.
|
||||
flags?: EmitFlags; // Flags that customize emit
|
||||
leadingComments?: SynthesizedComment[]; // Synthesized leading comments
|
||||
trailingComments?: SynthesizedComment[]; // Synthesized trailing comments
|
||||
commentRange?: TextRange; // The text range to use when emitting leading or trailing comments
|
||||
sourceMapRange?: TextRange; // The text range to use when emitting leading or trailing source mappings
|
||||
tokenSourceMapRanges?: TextRange[]; // The text range to use when emitting source mappings for tokens
|
||||
constantValue?: string | number; // The constant value of an expression
|
||||
externalHelpersModuleName?: Identifier; // The local name for an imported helpers module
|
||||
helpers?: EmitHelper[]; // Emit helpers for the node
|
||||
commentRange?: TextRange; // The text range to use when emitting leading or trailing comments
|
||||
sourceMapRange?: SourceMapRange; // The text range to use when emitting leading or trailing source mappings
|
||||
tokenSourceMapRanges?: SourceMapRange[]; // The text range to use when emitting source mappings for tokens
|
||||
constantValue?: string | number; // The constant value of an expression
|
||||
externalHelpersModuleName?: Identifier; // The local name for an imported helpers module
|
||||
helpers?: EmitHelper[]; // Emit helpers for the node
|
||||
}
|
||||
|
||||
export const enum EmitFlags {
|
||||
@@ -4081,6 +4128,7 @@ namespace ts {
|
||||
AsyncGenerator = 1 << 12, // __asyncGenerator (used by ES2017 async generator transformation)
|
||||
AsyncDelegator = 1 << 13, // __asyncDelegator (used by ES2017 async generator yield* transformation)
|
||||
AsyncValues = 1 << 14, // __asyncValues (used by ES2017 for..await..of transformation)
|
||||
ExportStar = 1 << 15, // __exportStar (used by CommonJS/AMD/UMD module transformation)
|
||||
|
||||
// Helpers included by ES2015 for..of
|
||||
ForOfIncludes = Values,
|
||||
@@ -4098,7 +4146,7 @@ namespace ts {
|
||||
SpreadIncludes = Read | Spread,
|
||||
|
||||
FirstEmitHelper = Extends,
|
||||
LastEmitHelper = AsyncValues
|
||||
LastEmitHelper = ExportStar
|
||||
}
|
||||
|
||||
export const enum EmitHint {
|
||||
@@ -4238,7 +4286,7 @@ namespace ts {
|
||||
*/
|
||||
export type Visitor = (node: Node) => VisitResult<Node>;
|
||||
|
||||
export type VisitResult<T extends Node> = T | T[];
|
||||
export type VisitResult<T extends Node> = T | T[] | undefined;
|
||||
|
||||
export interface Printer {
|
||||
/**
|
||||
|
||||
+387
-281
File diff suppressed because it is too large
Load Diff
+71
-56
@@ -86,7 +86,7 @@ namespace ts {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
let updated: NodeArray<T>;
|
||||
let updated: MutableNodeArray<T>;
|
||||
|
||||
// Ensure start and count have valid values
|
||||
const length = nodes.length;
|
||||
@@ -270,12 +270,13 @@ namespace ts {
|
||||
nodesVisitor((<PropertyDeclaration>node).decorators, visitor, isDecorator),
|
||||
nodesVisitor((<PropertyDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<PropertyDeclaration>node).name, visitor, isPropertyName),
|
||||
visitNode((<PropertyDeclaration>node).questionToken, tokenVisitor, isToken),
|
||||
visitNode((<PropertyDeclaration>node).type, visitor, isTypeNode),
|
||||
visitNode((<PropertyDeclaration>node).initializer, visitor, isExpression));
|
||||
|
||||
case SyntaxKind.MethodSignature:
|
||||
return updateMethodSignature(<MethodSignature>node,
|
||||
nodesVisitor((<MethodSignature>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<MethodSignature>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
nodesVisitor((<MethodSignature>node).parameters, visitor, isParameterDeclaration),
|
||||
visitNode((<MethodSignature>node).type, visitor, isTypeNode),
|
||||
visitNode((<MethodSignature>node).name, visitor, isPropertyName),
|
||||
@@ -288,7 +289,7 @@ namespace ts {
|
||||
visitNode((<MethodDeclaration>node).asteriskToken, tokenVisitor, isToken),
|
||||
visitNode((<MethodDeclaration>node).name, visitor, isPropertyName),
|
||||
visitNode((<MethodDeclaration>node).questionToken, tokenVisitor, isToken),
|
||||
nodesVisitor((<MethodDeclaration>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<MethodDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
visitParameterList((<MethodDeclaration>node).parameters, visitor, context, nodesVisitor),
|
||||
visitNode((<MethodDeclaration>node).type, visitor, isTypeNode),
|
||||
visitFunctionBody((<MethodDeclaration>node).body, visitor, context));
|
||||
@@ -319,13 +320,13 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.CallSignature:
|
||||
return updateCallSignature(<CallSignatureDeclaration>node,
|
||||
nodesVisitor((<CallSignatureDeclaration>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<CallSignatureDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
nodesVisitor((<CallSignatureDeclaration>node).parameters, visitor, isParameterDeclaration),
|
||||
visitNode((<CallSignatureDeclaration>node).type, visitor, isTypeNode));
|
||||
|
||||
case SyntaxKind.ConstructSignature:
|
||||
return updateConstructSignature(<ConstructSignatureDeclaration>node,
|
||||
nodesVisitor((<ConstructSignatureDeclaration>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<ConstructSignatureDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
nodesVisitor((<ConstructSignatureDeclaration>node).parameters, visitor, isParameterDeclaration),
|
||||
visitNode((<ConstructSignatureDeclaration>node).type, visitor, isTypeNode));
|
||||
|
||||
@@ -350,13 +351,13 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.FunctionType:
|
||||
return updateFunctionTypeNode(<FunctionTypeNode>node,
|
||||
nodesVisitor((<FunctionTypeNode>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<FunctionTypeNode>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
nodesVisitor((<FunctionTypeNode>node).parameters, visitor, isParameterDeclaration),
|
||||
visitNode((<FunctionTypeNode>node).type, visitor, isTypeNode));
|
||||
|
||||
case SyntaxKind.ConstructorType:
|
||||
return updateConstructorTypeNode(<ConstructorTypeNode>node,
|
||||
nodesVisitor((<ConstructorTypeNode>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<ConstructorTypeNode>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
nodesVisitor((<ConstructorTypeNode>node).parameters, visitor, isParameterDeclaration),
|
||||
visitNode((<ConstructorTypeNode>node).type, visitor, isTypeNode));
|
||||
|
||||
@@ -400,7 +401,7 @@ namespace ts {
|
||||
case SyntaxKind.MappedType:
|
||||
return updateMappedTypeNode((<MappedTypeNode>node),
|
||||
visitNode((<MappedTypeNode>node).readonlyToken, tokenVisitor, isToken),
|
||||
visitNode((<MappedTypeNode>node).typeParameter, visitor, isTypeParameter),
|
||||
visitNode((<MappedTypeNode>node).typeParameter, visitor, isTypeParameterDeclaration),
|
||||
visitNode((<MappedTypeNode>node).questionToken, tokenVisitor, isToken),
|
||||
visitNode((<MappedTypeNode>node).type, visitor, isTypeNode));
|
||||
|
||||
@@ -476,7 +477,7 @@ namespace ts {
|
||||
nodesVisitor((<FunctionExpression>node).modifiers, visitor, isModifier),
|
||||
visitNode((<FunctionExpression>node).asteriskToken, tokenVisitor, isToken),
|
||||
visitNode((<FunctionExpression>node).name, visitor, isIdentifier),
|
||||
nodesVisitor((<FunctionExpression>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<FunctionExpression>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
visitParameterList((<FunctionExpression>node).parameters, visitor, context, nodesVisitor),
|
||||
visitNode((<FunctionExpression>node).type, visitor, isTypeNode),
|
||||
visitFunctionBody((<FunctionExpression>node).body, visitor, context));
|
||||
@@ -484,7 +485,7 @@ namespace ts {
|
||||
case SyntaxKind.ArrowFunction:
|
||||
return updateArrowFunction(<ArrowFunction>node,
|
||||
nodesVisitor((<ArrowFunction>node).modifiers, visitor, isModifier),
|
||||
nodesVisitor((<ArrowFunction>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<ArrowFunction>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
visitParameterList((<ArrowFunction>node).parameters, visitor, context, nodesVisitor),
|
||||
visitNode((<ArrowFunction>node).type, visitor, isTypeNode),
|
||||
visitFunctionBody((<ArrowFunction>node).body, visitor, context));
|
||||
@@ -543,7 +544,7 @@ namespace ts {
|
||||
return updateClassExpression(<ClassExpression>node,
|
||||
nodesVisitor((<ClassExpression>node).modifiers, visitor, isModifier),
|
||||
visitNode((<ClassExpression>node).name, visitor, isIdentifier),
|
||||
nodesVisitor((<ClassExpression>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<ClassExpression>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
nodesVisitor((<ClassExpression>node).heritageClauses, visitor, isHeritageClause),
|
||||
nodesVisitor((<ClassExpression>node).members, visitor, isClassElement));
|
||||
|
||||
@@ -676,7 +677,7 @@ namespace ts {
|
||||
nodesVisitor((<FunctionDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<FunctionDeclaration>node).asteriskToken, tokenVisitor, isToken),
|
||||
visitNode((<FunctionDeclaration>node).name, visitor, isIdentifier),
|
||||
nodesVisitor((<FunctionDeclaration>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<FunctionDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
visitParameterList((<FunctionDeclaration>node).parameters, visitor, context, nodesVisitor),
|
||||
visitNode((<FunctionDeclaration>node).type, visitor, isTypeNode),
|
||||
visitFunctionBody((<FunctionExpression>node).body, visitor, context));
|
||||
@@ -686,7 +687,7 @@ namespace ts {
|
||||
nodesVisitor((<ClassDeclaration>node).decorators, visitor, isDecorator),
|
||||
nodesVisitor((<ClassDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<ClassDeclaration>node).name, visitor, isIdentifier),
|
||||
nodesVisitor((<ClassDeclaration>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<ClassDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
nodesVisitor((<ClassDeclaration>node).heritageClauses, visitor, isHeritageClause),
|
||||
nodesVisitor((<ClassDeclaration>node).members, visitor, isClassElement));
|
||||
|
||||
@@ -695,7 +696,7 @@ namespace ts {
|
||||
nodesVisitor((<InterfaceDeclaration>node).decorators, visitor, isDecorator),
|
||||
nodesVisitor((<InterfaceDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<InterfaceDeclaration>node).name, visitor, isIdentifier),
|
||||
nodesVisitor((<InterfaceDeclaration>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<InterfaceDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
nodesVisitor((<InterfaceDeclaration>node).heritageClauses, visitor, isHeritageClause),
|
||||
nodesVisitor((<InterfaceDeclaration>node).members, visitor, isTypeElement));
|
||||
|
||||
@@ -704,7 +705,7 @@ namespace ts {
|
||||
nodesVisitor((<TypeAliasDeclaration>node).decorators, visitor, isDecorator),
|
||||
nodesVisitor((<TypeAliasDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<TypeAliasDeclaration>node).name, visitor, isIdentifier),
|
||||
nodesVisitor((<TypeAliasDeclaration>node).typeParameters, visitor, isTypeParameter),
|
||||
nodesVisitor((<TypeAliasDeclaration>node).typeParameters, visitor, isTypeParameterDeclaration),
|
||||
visitNode((<TypeAliasDeclaration>node).type, visitor, isTypeNode));
|
||||
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
@@ -900,7 +901,7 @@ namespace ts {
|
||||
*
|
||||
* @param nodes The NodeArray.
|
||||
*/
|
||||
function extractSingleNode(nodes: Node[]): Node {
|
||||
function extractSingleNode(nodes: ReadonlyArray<Node>): Node {
|
||||
Debug.assert(nodes.length <= 1, "Too many nodes written to output.");
|
||||
return singleOrUndefined(nodes);
|
||||
}
|
||||
@@ -1148,10 +1149,6 @@ namespace ts {
|
||||
result = reduceNode((<AsExpression>node).type, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.NonNullExpression:
|
||||
result = reduceNode((<NonNullExpression>node).expression, cbNode, result);
|
||||
break;
|
||||
|
||||
// Misc
|
||||
case SyntaxKind.TemplateSpan:
|
||||
result = reduceNode((<TemplateSpan>node).expression, cbNode, result);
|
||||
@@ -1198,9 +1195,9 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
result = reduceNode((<ForInStatement | ForOfStatement>node).initializer, cbNode, result);
|
||||
result = reduceNode((<ForInStatement | ForOfStatement>node).expression, cbNode, result);
|
||||
result = reduceNode((<ForInStatement | ForOfStatement>node).statement, cbNode, result);
|
||||
result = reduceNode((<ForInOrOfStatement>node).initializer, cbNode, result);
|
||||
result = reduceNode((<ForInOrOfStatement>node).expression, cbNode, result);
|
||||
result = reduceNode((<ForInOrOfStatement>node).statement, cbNode, result);
|
||||
break;
|
||||
|
||||
case SyntaxKind.ReturnStatement:
|
||||
@@ -1424,13 +1421,13 @@ namespace ts {
|
||||
/**
|
||||
* Merges generated lexical declarations into a new statement list.
|
||||
*/
|
||||
export function mergeLexicalEnvironment(statements: NodeArray<Statement>, declarations: Statement[]): NodeArray<Statement>;
|
||||
export function mergeLexicalEnvironment(statements: NodeArray<Statement>, declarations: ReadonlyArray<Statement>): NodeArray<Statement>;
|
||||
|
||||
/**
|
||||
* Appends generated lexical declarations to an array of statements.
|
||||
*/
|
||||
export function mergeLexicalEnvironment(statements: Statement[], declarations: Statement[]): Statement[];
|
||||
export function mergeLexicalEnvironment(statements: Statement[], declarations: Statement[]) {
|
||||
export function mergeLexicalEnvironment(statements: Statement[], declarations: ReadonlyArray<Statement>): Statement[];
|
||||
export function mergeLexicalEnvironment(statements: Statement[] | NodeArray<Statement>, declarations: ReadonlyArray<Statement>) {
|
||||
if (!some(declarations)) {
|
||||
return statements;
|
||||
}
|
||||
@@ -1445,7 +1442,7 @@ namespace ts {
|
||||
*
|
||||
* @param nodes The NodeArray.
|
||||
*/
|
||||
export function liftToBlock(nodes: Node[]): Statement {
|
||||
export function liftToBlock(nodes: ReadonlyArray<Node>): Statement {
|
||||
Debug.assert(every(nodes, isStatement), "Cannot lift nodes to a Block.");
|
||||
return <Statement>singleOrUndefined(nodes) || createBlock(<NodeArray<Statement>>nodes);
|
||||
}
|
||||
@@ -1517,35 +1514,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export namespace Debug {
|
||||
if (isDebugging) {
|
||||
// Add additional properties in debug mode to assist with debugging.
|
||||
Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, {
|
||||
"__debugFlags": { get(this: Symbol) { return formatSymbolFlags(this.flags); } }
|
||||
});
|
||||
|
||||
Object.defineProperties(objectAllocator.getTypeConstructor().prototype, {
|
||||
"__debugFlags": { get(this: Type) { return formatTypeFlags(this.flags); } },
|
||||
"__debugObjectFlags": { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((<ObjectType>this).objectFlags) : ""; } },
|
||||
"__debugTypeToString": { value(this: Type) { return this.checker.typeToString(this); } },
|
||||
});
|
||||
|
||||
for (const ctor of [objectAllocator.getNodeConstructor(), objectAllocator.getIdentifierConstructor(), objectAllocator.getTokenConstructor(), objectAllocator.getSourceFileConstructor()]) {
|
||||
if (!ctor.prototype.hasOwnProperty("__debugKind")) {
|
||||
Object.defineProperties(ctor.prototype, {
|
||||
"__debugKind": { get(this: Node) { return formatSyntaxKind(this.kind); } },
|
||||
"__debugModifierFlags": { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } },
|
||||
"__debugTransformFlags": { get(this: Node) { return formatTransformFlags(this.transformFlags); } },
|
||||
"__debugEmitFlags": { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } },
|
||||
"__debugGetText": { value(this: Node, includeTrivia?: boolean) {
|
||||
if (nodeIsSynthesized(this)) return "";
|
||||
const parseNode = getParseTreeNode(this);
|
||||
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
|
||||
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
|
||||
} }
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
let isDebugInfoEnabled = false;
|
||||
|
||||
export const failBadSyntaxKind = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, message?: string): void => fail(
|
||||
@@ -1592,5 +1561,51 @@ namespace ts {
|
||||
() => `Node ${formatSyntaxKind(node.kind)} was unexpected'.`,
|
||||
assertMissingNode)
|
||||
: noop;
|
||||
|
||||
/**
|
||||
* Injects debug information into frequently used types.
|
||||
*/
|
||||
export function enableDebugInfo() {
|
||||
if (isDebugInfoEnabled) return;
|
||||
|
||||
// Add additional properties in debug mode to assist with debugging.
|
||||
Object.defineProperties(objectAllocator.getSymbolConstructor().prototype, {
|
||||
"__debugFlags": { get(this: Symbol) { return formatSymbolFlags(this.flags); } }
|
||||
});
|
||||
|
||||
Object.defineProperties(objectAllocator.getTypeConstructor().prototype, {
|
||||
"__debugFlags": { get(this: Type) { return formatTypeFlags(this.flags); } },
|
||||
"__debugObjectFlags": { get(this: Type) { return this.flags & TypeFlags.Object ? formatObjectFlags((<ObjectType>this).objectFlags) : ""; } },
|
||||
"__debugTypeToString": { value(this: Type) { return this.checker.typeToString(this); } },
|
||||
});
|
||||
|
||||
const nodeConstructors = [
|
||||
objectAllocator.getNodeConstructor(),
|
||||
objectAllocator.getIdentifierConstructor(),
|
||||
objectAllocator.getTokenConstructor(),
|
||||
objectAllocator.getSourceFileConstructor()
|
||||
];
|
||||
|
||||
for (const ctor of nodeConstructors) {
|
||||
if (!ctor.prototype.hasOwnProperty("__debugKind")) {
|
||||
Object.defineProperties(ctor.prototype, {
|
||||
"__debugKind": { get(this: Node) { return formatSyntaxKind(this.kind); } },
|
||||
"__debugModifierFlags": { get(this: Node) { return formatModifierFlags(getModifierFlagsNoCache(this)); } },
|
||||
"__debugTransformFlags": { get(this: Node) { return formatTransformFlags(this.transformFlags); } },
|
||||
"__debugEmitFlags": { get(this: Node) { return formatEmitFlags(getEmitFlags(this)); } },
|
||||
"__debugGetText": {
|
||||
value(this: Node, includeTrivia?: boolean) {
|
||||
if (nodeIsSynthesized(this)) return "";
|
||||
const parseNode = getParseTreeNode(this);
|
||||
const sourceFile = parseNode && getSourceFileOfNode(parseNode);
|
||||
return sourceFile ? getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : "";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
isDebugInfoEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
let result: Harness.Compiler.CompilerResult;
|
||||
let options: ts.CompilerOptions;
|
||||
let tsConfigFiles: Harness.Compiler.TestFile[];
|
||||
// equivalent to the files that will be passed on the command line
|
||||
let toBeCompiled: Harness.Compiler.TestFile[];
|
||||
// equivalent to other files on the file system not directly passed to the compiler (ie things that are referenced by other files)
|
||||
@@ -77,10 +78,12 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
const units = testCaseContent.testUnitData;
|
||||
harnessSettings = testCaseContent.settings;
|
||||
let tsConfigOptions: ts.CompilerOptions;
|
||||
tsConfigFiles = [];
|
||||
if (testCaseContent.tsConfig) {
|
||||
assert.equal(testCaseContent.tsConfig.fileNames.length, 0, `list of files in tsconfig is not currently supported`);
|
||||
|
||||
tsConfigOptions = ts.clone(testCaseContent.tsConfig.options);
|
||||
tsConfigOptions = ts.cloneCompilerOptions(testCaseContent.tsConfig.options);
|
||||
tsConfigFiles.push(this.createHarnessTestFile(testCaseContent.tsConfigFileUnitData, rootDir, ts.combinePaths(rootDir, tsConfigOptions.configFilePath)));
|
||||
}
|
||||
else {
|
||||
const baseUrl = harnessSettings["baseUrl"];
|
||||
@@ -90,7 +93,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
lastUnit = units[units.length - 1];
|
||||
hasNonDtsFiles = ts.forEach(units, unit => !ts.fileExtensionIs(unit.name, ".d.ts"));
|
||||
hasNonDtsFiles = ts.forEach(units, unit => !ts.fileExtensionIs(unit.name, ts.Extension.Dts));
|
||||
// We need to assemble the list of input files for the compiler and other related files on the 'filesystem' (ie in a multi-file test)
|
||||
// If the last file in a test uses require or a triple slash reference we'll assume all other files will be brought in via references,
|
||||
// otherwise, assume all files are just meant to be in the same compilation session without explicit references to one another.
|
||||
@@ -98,21 +101,22 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
otherFiles = [];
|
||||
|
||||
if (testCaseContent.settings["noImplicitReferences"] || /require\(/.test(lastUnit.content) || /reference\spath/.test(lastUnit.content)) {
|
||||
toBeCompiled.push({ unitName: this.makeUnitName(lastUnit.name, rootDir), content: lastUnit.content, fileOptions: lastUnit.fileOptions });
|
||||
toBeCompiled.push(this.createHarnessTestFile(lastUnit, rootDir));
|
||||
units.forEach(unit => {
|
||||
if (unit.name !== lastUnit.name) {
|
||||
otherFiles.push({ unitName: this.makeUnitName(unit.name, rootDir), content: unit.content, fileOptions: unit.fileOptions });
|
||||
otherFiles.push(this.createHarnessTestFile(unit, rootDir));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
toBeCompiled = units.map(unit => {
|
||||
return { unitName: this.makeUnitName(unit.name, rootDir), content: unit.content, fileOptions: unit.fileOptions };
|
||||
return this.createHarnessTestFile(unit, rootDir);
|
||||
});
|
||||
}
|
||||
|
||||
if (tsConfigOptions && tsConfigOptions.configFilePath !== undefined) {
|
||||
tsConfigOptions.configFilePath = ts.combinePaths(rootDir, tsConfigOptions.configFilePath);
|
||||
tsConfigOptions.configFile.fileName = tsConfigOptions.configFilePath;
|
||||
}
|
||||
|
||||
const output = Harness.Compiler.compileFiles(
|
||||
@@ -132,11 +136,12 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
options = undefined;
|
||||
toBeCompiled = undefined;
|
||||
otherFiles = undefined;
|
||||
tsConfigFiles = undefined;
|
||||
});
|
||||
|
||||
// check errors
|
||||
it("Correct errors for " + fileName, () => {
|
||||
Harness.Compiler.doErrorBaseline(justName, toBeCompiled.concat(otherFiles), result.errors);
|
||||
Harness.Compiler.doErrorBaseline(justName, tsConfigFiles.concat(toBeCompiled, otherFiles), result.errors);
|
||||
});
|
||||
|
||||
it (`Correct module resolution tracing for ${fileName}`, () => {
|
||||
@@ -165,7 +170,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
|
||||
it("Correct JS output for " + fileName, () => {
|
||||
if (hasNonDtsFiles && this.emit) {
|
||||
Harness.Compiler.doJsEmitBaseline(justName, fileName, options, result, toBeCompiled, otherFiles, harnessSettings);
|
||||
Harness.Compiler.doJsEmitBaseline(justName, fileName, options, result, tsConfigFiles, toBeCompiled, otherFiles, harnessSettings);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -183,6 +188,10 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
});
|
||||
}
|
||||
|
||||
private createHarnessTestFile(lastUnit: Harness.TestCaseParser.TestUnitData, rootDir: string, unitName?: string): Harness.Compiler.TestFile {
|
||||
return { unitName: unitName || this.makeUnitName(lastUnit.name, rootDir), content: lastUnit.content, fileOptions: lastUnit.fileOptions };
|
||||
}
|
||||
|
||||
public initializeTests() {
|
||||
describe(this.testSuiteName + " tests", () => {
|
||||
describe("Setup compiler for compiler baselines", () => {
|
||||
|
||||
+186
-148
@@ -130,7 +130,7 @@ namespace FourSlash {
|
||||
// 0 - cancelled
|
||||
// >0 - not cancelled
|
||||
// <0 - not cancelled and value denotes number of isCancellationRequested after which token become cancelled
|
||||
private static NotCanceled: number = -1;
|
||||
private static readonly NotCanceled: number = -1;
|
||||
private numberOfCallsBeforeCancellation: number = TestCancellationToken.NotCanceled;
|
||||
|
||||
public isCancellationRequested(): boolean {
|
||||
@@ -219,7 +219,7 @@ namespace FourSlash {
|
||||
|
||||
// Add input file which has matched file name with the given reference-file path.
|
||||
// This is necessary when resolveReference flag is specified
|
||||
private addMatchedInputFile(referenceFilePath: string, extensions: string[]) {
|
||||
private addMatchedInputFile(referenceFilePath: string, extensions: ReadonlyArray<string>) {
|
||||
const inputFiles = this.inputFiles;
|
||||
const languageServiceAdapterHost = this.languageServiceAdapterHost;
|
||||
if (!extensions) {
|
||||
@@ -536,11 +536,16 @@ namespace FourSlash {
|
||||
Harness.IO.log("Unexpected error(s) found. Error list is:");
|
||||
}
|
||||
|
||||
for (const { start, length, messageText } of errors) {
|
||||
Harness.IO.log(" minChar: " + start +
|
||||
", limChar: " + (start + length) +
|
||||
for (const { start, length, messageText, file } of errors) {
|
||||
Harness.IO.log(" from: " + showPosition(file, start) +
|
||||
", to: " + showPosition(file, start + length) +
|
||||
", message: " + ts.flattenDiagnosticMessageText(messageText, Harness.IO.newLine()) + "\n");
|
||||
}
|
||||
|
||||
function showPosition(file: ts.SourceFile, pos: number) {
|
||||
const { line, character } = ts.getLineAndCharacterOfPosition(file, pos);
|
||||
return `${line}:${character}`;
|
||||
}
|
||||
}
|
||||
|
||||
public verifyNoErrors() {
|
||||
@@ -600,7 +605,7 @@ namespace FourSlash {
|
||||
this.verifyGoToXPlain(arg0, endMarkerNames, getDefs);
|
||||
}
|
||||
else if (ts.isArray(arg0)) {
|
||||
const pairs: [string | string[], string | string[]][] = arg0;
|
||||
const pairs: ReadonlyArray<[string | string[], string | string[]]> = arg0;
|
||||
for (const [start, end] of pairs) {
|
||||
this.verifyGoToXPlain(start, end, getDefs);
|
||||
}
|
||||
@@ -689,7 +694,7 @@ namespace FourSlash {
|
||||
|
||||
public verifyCompletionListItemsCountIsGreaterThan(count: number, negative: boolean) {
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
const itemsCount = completions.entries.length;
|
||||
const itemsCount = completions ? completions.entries.length : 0;
|
||||
|
||||
if (negative) {
|
||||
if (itemsCount > count) {
|
||||
@@ -809,8 +814,8 @@ namespace FourSlash {
|
||||
|
||||
function filterByTextOrDocumentation(entry: ts.CompletionEntry) {
|
||||
const details = that.getCompletionEntryDetails(entry.name);
|
||||
const documentation = ts.displayPartsToString(details.documentation);
|
||||
const text = ts.displayPartsToString(details.displayParts);
|
||||
const documentation = details && ts.displayPartsToString(details.documentation);
|
||||
const text = details && ts.displayPartsToString(details.displayParts);
|
||||
|
||||
// If any of the expected values are undefined, assume that users don't
|
||||
// care about them.
|
||||
@@ -847,6 +852,9 @@ namespace FourSlash {
|
||||
if (expectedKind) {
|
||||
error += "Expected kind: " + expectedKind + " to equal: " + filterCompletions[0].kind + ".";
|
||||
}
|
||||
else {
|
||||
error += "kind: " + filterCompletions[0].kind + ".";
|
||||
}
|
||||
if (replacementSpan) {
|
||||
const spanText = filterCompletions[0].replacementSpan ? stringify(filterCompletions[0].replacementSpan) : undefined;
|
||||
error += "Expected replacement span: " + stringify(replacementSpan) + " to equal: " + spanText + ".";
|
||||
@@ -941,6 +949,22 @@ namespace FourSlash {
|
||||
this.verifySymbol(symbol, declarationRanges);
|
||||
}
|
||||
|
||||
public symbolsInScope(range: Range): ts.Symbol[] {
|
||||
const node = this.goToAndGetNode(range);
|
||||
return this.getChecker().getSymbolsInScope(node, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace);
|
||||
}
|
||||
|
||||
public verifyTypeOfSymbolAtLocation(range: Range, symbol: ts.Symbol, expected: string): void {
|
||||
const node = this.goToAndGetNode(range);
|
||||
const checker = this.getChecker();
|
||||
const type = checker.getTypeOfSymbolAtLocation(symbol, node);
|
||||
|
||||
const actual = checker.typeToString(type);
|
||||
if (actual !== expected) {
|
||||
this.raiseError(`Expected: '${expected}', actual: '${actual}'`);
|
||||
}
|
||||
}
|
||||
|
||||
private verifyReferencesAre(expectedReferences: Range[]) {
|
||||
const actualReferences = this.getReferencesAtCaret() || [];
|
||||
|
||||
@@ -1036,21 +1060,27 @@ namespace FourSlash {
|
||||
fail(`Expected ${expected}, got ${actual}`);
|
||||
}
|
||||
|
||||
for (const key in actual) if (ts.hasProperty(actual as any, key)) {
|
||||
const ak = actual[key], ek = expected[key];
|
||||
if (typeof ak === "object" && typeof ek === "object") {
|
||||
recur(ak, ek, path ? path + "." + key : key);
|
||||
}
|
||||
else if (ak !== ek) {
|
||||
fail(`Expected '${key}' to be '${ek}', got '${ak}'`);
|
||||
for (const key in actual) {
|
||||
if (ts.hasProperty(actual as any, key)) {
|
||||
const ak = actual[key], ek = expected[key];
|
||||
if (typeof ak === "object" && typeof ek === "object") {
|
||||
recur(ak, ek, path ? path + "." + key : key);
|
||||
}
|
||||
else if (ak !== ek) {
|
||||
fail(`Expected '${key}' to be '${ek}', got '${ak}'`);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const key in expected) if (ts.hasProperty(expected as any, key)) {
|
||||
if (!ts.hasProperty(actual as any, key)) {
|
||||
fail(`${msgPrefix}Missing property '${key}'`);
|
||||
|
||||
for (const key in expected) {
|
||||
if (ts.hasProperty(expected as any, key)) {
|
||||
if (!ts.hasProperty(actual as any, key)) {
|
||||
fail(`${msgPrefix}Missing property '${key}'`);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (fullActual === undefined || fullExpected === undefined) {
|
||||
if (fullActual === fullExpected) {
|
||||
return;
|
||||
@@ -1132,15 +1162,17 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public verifyQuickInfos(namesAndTexts: { [name: string]: string | [string, string] }) {
|
||||
for (const name in namesAndTexts) if (ts.hasProperty(namesAndTexts, name)) {
|
||||
const text = namesAndTexts[name];
|
||||
if (ts.isArray(text)) {
|
||||
assert(text.length === 2);
|
||||
const [expectedText, expectedDocumentation] = text;
|
||||
this.verifyQuickInfoAt(name, expectedText, expectedDocumentation);
|
||||
}
|
||||
else {
|
||||
this.verifyQuickInfoAt(name, text);
|
||||
for (const name in namesAndTexts) {
|
||||
if (ts.hasProperty(namesAndTexts, name)) {
|
||||
const text = namesAndTexts[name];
|
||||
if (ts.isArray(text)) {
|
||||
assert(text.length === 2);
|
||||
const [expectedText, expectedDocumentation] = text;
|
||||
this.verifyQuickInfoAt(name, expectedText, expectedDocumentation);
|
||||
}
|
||||
else {
|
||||
this.verifyQuickInfoAt(name, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1149,7 +1181,6 @@ namespace FourSlash {
|
||||
if (expectedDocumentation === "") {
|
||||
throw new Error("Use 'undefined' instead");
|
||||
}
|
||||
|
||||
const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
const actualQuickInfoText = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.displayParts) : "";
|
||||
const actualQuickInfoDocumentation = actualQuickInfo ? ts.displayPartsToString(actualQuickInfo.documentation) : "";
|
||||
@@ -1452,7 +1483,7 @@ namespace FourSlash {
|
||||
let baselineFile = this.testData.globalOptions[metadataOptionNames.baselineFile];
|
||||
if (!baselineFile) {
|
||||
baselineFile = this.activeFile.fileName.replace(this.basePath + "/breakpointValidation", "bpSpan");
|
||||
baselineFile = baselineFile.replace(".ts", ".baseline");
|
||||
baselineFile = baselineFile.replace(ts.Extension.Ts, ".baseline");
|
||||
|
||||
}
|
||||
Harness.Baseline.runBaseline(
|
||||
@@ -1522,7 +1553,7 @@ namespace FourSlash {
|
||||
public baselineQuickInfo() {
|
||||
let baselineFile = this.testData.globalOptions[metadataOptionNames.baselineFile];
|
||||
if (!baselineFile) {
|
||||
baselineFile = ts.getBaseFileName(this.activeFile.fileName).replace(".ts", ".baseline");
|
||||
baselineFile = ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline");
|
||||
}
|
||||
|
||||
Harness.Baseline.runBaseline(
|
||||
@@ -1569,7 +1600,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
public printCurrentFileState(makeWhitespaceVisible = false, makeCaretVisible = true) {
|
||||
public printCurrentFileState(makeWhitespaceVisible: 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 |)" : "")} ===`);
|
||||
@@ -1595,16 +1626,19 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private printMembersOrCompletions(info: ts.CompletionInfo) {
|
||||
if (info === undefined) { return "No completion info."; }
|
||||
const { entries } = info;
|
||||
|
||||
function pad(s: string, length: number) {
|
||||
return s + new Array(length - s.length + 1).join(" ");
|
||||
}
|
||||
function max<T>(arr: T[], selector: (x: T) => number): number {
|
||||
return arr.reduce((prev, x) => Math.max(prev, selector(x)), 0);
|
||||
}
|
||||
const longestNameLength = max(info.entries, m => m.name.length);
|
||||
const longestKindLength = max(info.entries, m => m.kind.length);
|
||||
info.entries.sort((m, n) => m.sortText > n.sortText ? 1 : m.sortText < n.sortText ? -1 : m.name > n.name ? 1 : m.name < n.name ? -1 : 0);
|
||||
const membersString = info.entries.map(m => `${pad(m.name, longestNameLength)} ${pad(m.kind, longestKindLength)} ${m.kindModifiers}`).join("\n");
|
||||
const longestNameLength = max(entries, m => m.name.length);
|
||||
const longestKindLength = max(entries, m => m.kind.length);
|
||||
entries.sort((m, n) => m.sortText > n.sortText ? 1 : m.sortText < n.sortText ? -1 : m.name > n.name ? 1 : m.name < n.name ? -1 : 0);
|
||||
const membersString = entries.map(m => `${pad(m.name, longestNameLength)} ${pad(m.kind, longestKindLength)} ${m.kindModifiers}`).join("\n");
|
||||
Harness.IO.log(membersString);
|
||||
}
|
||||
|
||||
@@ -1619,9 +1653,7 @@ namespace FourSlash {
|
||||
const checkCadence = (count >> 2) + 1;
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
// Make the edit
|
||||
this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset + 1, ch);
|
||||
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch);
|
||||
this.editScriptAndUpdateMarkers(this.activeFile.fileName, offset, offset + 1, ch);
|
||||
|
||||
if (i % checkCadence === 0) {
|
||||
this.checkPostEditInvariants();
|
||||
@@ -1632,21 +1664,15 @@ namespace FourSlash {
|
||||
const edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeSettings);
|
||||
if (edits.length) {
|
||||
offset += this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
|
||||
// this.checkPostEditInvariants();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move the caret to wherever we ended up
|
||||
this.currentCaretPosition = offset;
|
||||
|
||||
this.fixCaretPosition();
|
||||
this.checkPostEditInvariants();
|
||||
}
|
||||
|
||||
public replace(start: number, length: number, text: string) {
|
||||
this.languageServiceAdapterHost.editScript(this.activeFile.fileName, start, start + length, text);
|
||||
this.updateMarkersForEdit(this.activeFile.fileName, start, start + length, text);
|
||||
this.editScriptAndUpdateMarkers(this.activeFile.fileName, start, start + length, text);
|
||||
this.checkPostEditInvariants();
|
||||
}
|
||||
|
||||
@@ -1656,28 +1682,17 @@ namespace FourSlash {
|
||||
const checkCadence = (count >> 2) + 1;
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
this.currentCaretPosition--;
|
||||
offset--;
|
||||
// Make the edit
|
||||
this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset + 1, ch);
|
||||
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset + 1, ch);
|
||||
this.editScriptAndUpdateMarkers(this.activeFile.fileName, offset, offset + 1, ch);
|
||||
|
||||
if (i % checkCadence === 0) {
|
||||
this.checkPostEditInvariants();
|
||||
}
|
||||
|
||||
// Handle post-keystroke formatting
|
||||
if (this.enableFormatting) {
|
||||
const edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, offset, ch, this.formatCodeSettings);
|
||||
if (edits.length) {
|
||||
offset += this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
|
||||
}
|
||||
}
|
||||
// Don't need to examine formatting because there are no formatting changes on backspace.
|
||||
}
|
||||
|
||||
// Move the caret to wherever we ended up
|
||||
this.currentCaretPosition = offset;
|
||||
|
||||
this.fixCaretPosition();
|
||||
this.checkPostEditInvariants();
|
||||
}
|
||||
|
||||
@@ -1688,14 +1703,13 @@ namespace FourSlash {
|
||||
const checkCadence = (text.length >> 2) + 1;
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
// Make the edit
|
||||
const ch = text.charAt(i);
|
||||
this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset, ch);
|
||||
this.editScriptAndUpdateMarkers(this.activeFile.fileName, offset, offset, ch);
|
||||
if (highFidelity) {
|
||||
this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, offset);
|
||||
}
|
||||
|
||||
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, ch);
|
||||
this.currentCaretPosition++;
|
||||
offset++;
|
||||
|
||||
if (highFidelity) {
|
||||
@@ -1722,32 +1736,24 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
// Move the caret to wherever we ended up
|
||||
this.currentCaretPosition = offset;
|
||||
this.fixCaretPosition();
|
||||
this.checkPostEditInvariants();
|
||||
}
|
||||
|
||||
// Enters text as if the user had pasted it
|
||||
public paste(text: string) {
|
||||
const start = this.currentCaretPosition;
|
||||
let offset = this.currentCaretPosition;
|
||||
this.languageServiceAdapterHost.editScript(this.activeFile.fileName, offset, offset, text);
|
||||
this.updateMarkersForEdit(this.activeFile.fileName, offset, offset, text);
|
||||
this.editScriptAndUpdateMarkers(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition, text);
|
||||
this.checkPostEditInvariants();
|
||||
offset += text.length;
|
||||
const offset = this.currentCaretPosition += text.length;
|
||||
|
||||
// Handle formatting
|
||||
if (this.enableFormatting) {
|
||||
const edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, offset, this.formatCodeSettings);
|
||||
if (edits.length) {
|
||||
offset += this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
|
||||
this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
// Move the caret to wherever we ended up
|
||||
this.currentCaretPosition = offset;
|
||||
this.fixCaretPosition();
|
||||
|
||||
this.checkPostEditInvariants();
|
||||
}
|
||||
@@ -1775,30 +1781,41 @@ namespace FourSlash {
|
||||
Utils.assertStructuralEquals(incrementalSourceFile, referenceSourceFile);
|
||||
}
|
||||
|
||||
private fixCaretPosition() {
|
||||
// The caret can potentially end up between the \r and \n, which is confusing. If
|
||||
// that happens, move it back one character
|
||||
if (this.currentCaretPosition > 0) {
|
||||
const ch = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition - 1, this.currentCaretPosition);
|
||||
if (ch === "\r") {
|
||||
this.currentCaretPosition--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private applyEdits(fileName: string, edits: ts.TextChange[], isFormattingEdit = false): number {
|
||||
/**
|
||||
* @returns The number of characters added to the file as a result of the edits.
|
||||
* May be negative.
|
||||
*/
|
||||
private applyEdits(fileName: string, edits: ts.TextChange[], isFormattingEdit: boolean): number {
|
||||
// We get back a set of edits, but langSvc.editScript only accepts one at a time. Use this to keep track
|
||||
// of the incremental offset from each edit to the next. Assumption is that these edit ranges don't overlap
|
||||
let runningOffset = 0;
|
||||
// of the incremental offset from each edit to the next. We assume these edit ranges don't overlap
|
||||
|
||||
edits = edits.sort((a, b) => a.span.start - b.span.start);
|
||||
for (let i = 0; i < edits.length - 1; i++) {
|
||||
const firstEditSpan = edits[i].span;
|
||||
const firstEditEnd = firstEditSpan.start + firstEditSpan.length;
|
||||
assert.isTrue(firstEditEnd <= edits[i + 1].span.start);
|
||||
}
|
||||
|
||||
// Get a snapshot of the content of the file so we can make sure any formatting edits didn't destroy non-whitespace characters
|
||||
const oldContent = this.getFileContent(fileName);
|
||||
let runningOffset = 0;
|
||||
|
||||
for (const edit of edits) {
|
||||
this.languageServiceAdapterHost.editScript(fileName, edit.span.start + runningOffset, ts.textSpanEnd(edit.span) + runningOffset, edit.newText);
|
||||
this.updateMarkersForEdit(fileName, edit.span.start + runningOffset, ts.textSpanEnd(edit.span) + runningOffset, edit.newText);
|
||||
const change = (edit.span.start - ts.textSpanEnd(edit.span)) + edit.newText.length;
|
||||
runningOffset += change;
|
||||
const offsetStart = edit.span.start + runningOffset;
|
||||
const offsetEnd = offsetStart + edit.span.length;
|
||||
this.editScriptAndUpdateMarkers(fileName, offsetStart, offsetEnd, edit.newText);
|
||||
const editDelta = edit.newText.length - edit.span.length;
|
||||
if (offsetStart <= this.currentCaretPosition) {
|
||||
if (offsetEnd <= this.currentCaretPosition) {
|
||||
// The entirety of the edit span falls before the caret position, shift the caret accordingly
|
||||
this.currentCaretPosition += editDelta;
|
||||
}
|
||||
else {
|
||||
// The span being replaced includes the caret position, place the caret at the beginning of the span
|
||||
this.currentCaretPosition = offsetStart;
|
||||
}
|
||||
}
|
||||
runningOffset += editDelta;
|
||||
// TODO: Consider doing this at least some of the time for higher fidelity. Currently causes a failure (bug 707150)
|
||||
// this.languageService.getScriptLexicalStructure(fileName);
|
||||
}
|
||||
@@ -1810,6 +1827,7 @@ namespace FourSlash {
|
||||
this.raiseError("Formatting operation destroyed non-whitespace content");
|
||||
}
|
||||
}
|
||||
|
||||
return runningOffset;
|
||||
}
|
||||
|
||||
@@ -1825,23 +1843,21 @@ namespace FourSlash {
|
||||
|
||||
public formatDocument() {
|
||||
const edits = this.languageService.getFormattingEditsForDocument(this.activeFile.fileName, this.formatCodeSettings);
|
||||
this.currentCaretPosition += this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
|
||||
this.fixCaretPosition();
|
||||
this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
|
||||
}
|
||||
|
||||
public formatSelection(start: number, end: number) {
|
||||
const edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, end, this.formatCodeSettings);
|
||||
this.currentCaretPosition += this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
|
||||
this.fixCaretPosition();
|
||||
this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
|
||||
}
|
||||
|
||||
public formatOnType(pos: number, key: string) {
|
||||
const edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, pos, key, this.formatCodeSettings);
|
||||
this.currentCaretPosition += this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
|
||||
this.fixCaretPosition();
|
||||
this.applyEdits(this.activeFile.fileName, edits, /*isFormattingEdit*/ true);
|
||||
}
|
||||
|
||||
private updateMarkersForEdit(fileName: string, minChar: number, limChar: number, text: string) {
|
||||
private editScriptAndUpdateMarkers(fileName: string, editStart: number, editEnd: number, newText: string) {
|
||||
this.languageServiceAdapterHost.editScript(fileName, editStart, editEnd, newText);
|
||||
for (const marker of this.testData.markers) {
|
||||
if (marker.fileName === fileName) {
|
||||
marker.position = updatePosition(marker.position);
|
||||
@@ -1856,14 +1872,14 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
function updatePosition(position: number) {
|
||||
if (position > minChar) {
|
||||
if (position < limChar) {
|
||||
if (position > editStart) {
|
||||
if (position < editEnd) {
|
||||
// Inside the edit - mark it as invalidated (?)
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
// Move marker back/forward by the appropriate amount
|
||||
return position + (minChar - limChar) + text.length;
|
||||
return position + (editStart - editEnd) + newText.length;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2109,8 +2125,8 @@ namespace FourSlash {
|
||||
const actual = this.getFileContent(this.activeFile.fileName);
|
||||
if (normalizeNewLines(actual) !== normalizeNewLines(text)) {
|
||||
throw new Error("verifyCurrentFileContent\n" +
|
||||
"\tExpected: \"" + text + "\"\n" +
|
||||
"\t Actual: \"" + actual + "\"");
|
||||
"\tExpected: \"" + TestState.makeWhitespaceVisible(text) + "\"\n" +
|
||||
"\t Actual: \"" + TestState.makeWhitespaceVisible(actual) + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2156,7 +2172,7 @@ namespace FourSlash {
|
||||
Harness.IO.log(this.spanInfoToString(this.getNameOrDottedNameSpan(pos), "**"));
|
||||
}
|
||||
|
||||
private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[]) {
|
||||
private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[], sourceFileText: string) {
|
||||
if (actual.length !== expected.length) {
|
||||
this.raiseError("verifyClassifications failed - expected total classifications to be " + expected.length +
|
||||
", but was " + actual.length +
|
||||
@@ -2196,9 +2212,11 @@ namespace FourSlash {
|
||||
});
|
||||
|
||||
function jsonMismatchString() {
|
||||
const showActual = actual.map(({ classificationType, textSpan }) =>
|
||||
({ classificationType, text: sourceFileText.slice(textSpan.start, textSpan.start + textSpan.length) }));
|
||||
return Harness.IO.newLine() +
|
||||
"expected: '" + Harness.IO.newLine() + stringify(expected) + "'" + Harness.IO.newLine() +
|
||||
"actual: '" + Harness.IO.newLine() + stringify(actual) + "'";
|
||||
"actual: '" + Harness.IO.newLine() + stringify(showActual) + "'";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2221,14 +2239,14 @@ namespace FourSlash {
|
||||
const actual = this.languageService.getSemanticClassifications(this.activeFile.fileName,
|
||||
ts.createTextSpan(0, this.activeFile.content.length));
|
||||
|
||||
this.verifyClassifications(expected, actual);
|
||||
this.verifyClassifications(expected, actual, this.activeFile.content);
|
||||
}
|
||||
|
||||
public verifySyntacticClassifications(expected: { classificationType: string; text: string }[]) {
|
||||
const actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName,
|
||||
ts.createTextSpan(0, this.activeFile.content.length));
|
||||
|
||||
this.verifyClassifications(expected, actual);
|
||||
this.verifyClassifications(expected, actual, this.activeFile.content);
|
||||
}
|
||||
|
||||
public verifyOutliningSpans(spans: TextSpan[]) {
|
||||
@@ -2325,35 +2343,25 @@ namespace FourSlash {
|
||||
* @param fileName Path to file where error should be retrieved from.
|
||||
*/
|
||||
private getCodeFixActions(fileName: string, errorCode?: number): ts.CodeAction[] {
|
||||
const diagnosticsForCodeFix = this.getDiagnostics(fileName).map(diagnostic => {
|
||||
return {
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
code: diagnostic.code
|
||||
};
|
||||
});
|
||||
const dedupedDiagnositcs = ts.deduplicate(diagnosticsForCodeFix, ts.equalOwnProperties);
|
||||
|
||||
let actions: ts.CodeAction[] = undefined;
|
||||
|
||||
for (const diagnostic of dedupedDiagnositcs) {
|
||||
const diagnosticsForCodeFix = this.getDiagnostics(fileName).map(diagnostic => ({
|
||||
start: diagnostic.start,
|
||||
length: diagnostic.length,
|
||||
code: diagnostic.code
|
||||
}));
|
||||
|
||||
return ts.flatMap(ts.deduplicate(diagnosticsForCodeFix, ts.equalOwnProperties), diagnostic => {
|
||||
if (errorCode && errorCode !== diagnostic.code) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
const newActions = this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.length, [diagnostic.code], this.formatCodeSettings);
|
||||
if (newActions && newActions.length) {
|
||||
actions = actions ? actions.concat(newActions) : newActions;
|
||||
}
|
||||
}
|
||||
return actions;
|
||||
return this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.start + diagnostic.length, [diagnostic.code], this.formatCodeSettings);
|
||||
});
|
||||
}
|
||||
|
||||
private applyCodeActions(actions: ts.CodeAction[], index?: number): void {
|
||||
if (index === undefined) {
|
||||
if (!(actions && actions.length === 1)) {
|
||||
this.raiseError(`Should find exactly one codefix, but ${actions ? actions.length : "none"} found.`);
|
||||
this.raiseError(`Should find exactly one codefix, but ${actions ? actions.length : "none"} found. ${actions ? actions.map(a => `${Harness.IO.newLine()} "${a.description}"`) : "" }`);
|
||||
}
|
||||
index = 0;
|
||||
}
|
||||
@@ -2378,7 +2386,7 @@ namespace FourSlash {
|
||||
|
||||
const codeFixes = this.getCodeFixActions(this.activeFile.fileName, errorCode);
|
||||
|
||||
if (!codeFixes || codeFixes.length === 0) {
|
||||
if (codeFixes.length === 0) {
|
||||
if (expectedTextArray.length !== 0) {
|
||||
this.raiseError("No codefixes returned.");
|
||||
}
|
||||
@@ -2397,7 +2405,7 @@ namespace FourSlash {
|
||||
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")}'`);
|
||||
`Actual text array doesn't match expected text array. \nActual: \n'${sortedActualArray.join("\n\n")}'\n---\nExpected: \n'${sortedExpectedArray.join("\n\n")}'`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2563,7 +2571,7 @@ namespace FourSlash {
|
||||
|
||||
// if there was an explicit match kind specified, then it should be validated.
|
||||
if (matchKind !== undefined) {
|
||||
const missingItem = { name: name, kind: kind, searchValue: searchValue, matchKind: matchKind, fileName: fileName, parentName: parentName };
|
||||
const missingItem = { name, kind, searchValue, matchKind, fileName, parentName };
|
||||
this.raiseError(`verifyNavigationItemsListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(items)})`);
|
||||
}
|
||||
}
|
||||
@@ -2637,7 +2645,7 @@ namespace FourSlash {
|
||||
}
|
||||
}
|
||||
|
||||
const missingItem = { fileName: fileName, start: start, end: end, isWriteAccess: isWriteAccess };
|
||||
const missingItem = { fileName, start, end, isWriteAccess };
|
||||
this.raiseError(`verifyOccurrencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(occurrences)})`);
|
||||
}
|
||||
|
||||
@@ -2673,6 +2681,13 @@ namespace FourSlash {
|
||||
this.rangesByText().forEach(ranges => this.verifyRangesAreDocumentHighlights(ranges));
|
||||
}
|
||||
|
||||
public verifyDocumentHighlightsOf(startRange: Range, ranges: Range[]) {
|
||||
ts.Debug.assert(ts.contains(ranges, startRange));
|
||||
const fileNames = unique(ranges, range => range.fileName);
|
||||
this.goToRangeStart(startRange);
|
||||
this.verifyDocumentHighlights(ranges, fileNames);
|
||||
}
|
||||
|
||||
public verifyRangesAreDocumentHighlights(ranges?: Range[]) {
|
||||
ranges = ranges || this.getRanges();
|
||||
const fileNames = unique(ranges, range => range.fileName);
|
||||
@@ -2714,11 +2729,11 @@ namespace FourSlash {
|
||||
public verifyCodeFixAvailable(negative: boolean) {
|
||||
const codeFix = this.getCodeFixActions(this.activeFile.fileName);
|
||||
|
||||
if (negative && codeFix) {
|
||||
if (negative && codeFix.length) {
|
||||
this.raiseError(`verifyCodeFixAvailable failed - expected no fixes but found one.`);
|
||||
}
|
||||
|
||||
if (!(negative || codeFix)) {
|
||||
if (!(negative || codeFix.length)) {
|
||||
this.raiseError(`verifyCodeFixAvailable failed - expected code fixes but none found.`);
|
||||
}
|
||||
}
|
||||
@@ -2755,6 +2770,7 @@ namespace FourSlash {
|
||||
markerName: string,
|
||||
expectedContent: string,
|
||||
refactorNameToApply: string,
|
||||
actionName: string,
|
||||
formattingOptions?: ts.FormatCodeSettings) {
|
||||
|
||||
formattingOptions = formattingOptions || this.formatCodeSettings;
|
||||
@@ -2767,9 +2783,11 @@ namespace FourSlash {
|
||||
this.raiseError(`The expected refactor: ${refactorNameToApply} is not available at the marker location.`);
|
||||
}
|
||||
|
||||
const codeActions = this.languageService.getRefactorCodeActions(this.activeFile.fileName, formattingOptions, markerPos, refactorNameToApply);
|
||||
const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, formattingOptions, markerPos, refactorNameToApply, actionName);
|
||||
|
||||
this.applyCodeActions(codeActions);
|
||||
for (const edit of editInfo.edits) {
|
||||
this.applyEdits(edit.fileName, edit.textChanges, /*isFormattingEdit*/ false);
|
||||
}
|
||||
const actualContent = this.getFileContent(this.activeFile.fileName);
|
||||
|
||||
if (this.normalizeNewlines(actualContent) !== this.normalizeNewlines(expectedContent)) {
|
||||
@@ -2963,7 +2981,6 @@ ${code}
|
||||
f(test, goTo, verify, edit, debug, format, cancellation, FourSlashInterface.Classification, FourSlash.verifyOperationIsCancelled);
|
||||
}
|
||||
catch (err) {
|
||||
// Debugging: FourSlash.currentTestState.printCurrentFileState();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -3249,7 +3266,7 @@ ${code}
|
||||
}
|
||||
|
||||
const range: Range = {
|
||||
fileName: fileName,
|
||||
fileName,
|
||||
start: rangeStart.position,
|
||||
end: (i - 1) - difference,
|
||||
marker: rangeStart.marker
|
||||
@@ -3377,7 +3394,7 @@ ${code}
|
||||
content: output,
|
||||
fileOptions: {},
|
||||
version: 0,
|
||||
fileName: fileName
|
||||
fileName,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3436,6 +3453,10 @@ namespace FourSlashInterface {
|
||||
public markerByName(s: string): FourSlash.Marker {
|
||||
return this.state.getMarkerByName(s);
|
||||
}
|
||||
|
||||
public symbolsInScope(range: FourSlash.Range): ts.Symbol[] {
|
||||
return this.state.symbolsInScope(range);
|
||||
}
|
||||
}
|
||||
|
||||
export class GoTo {
|
||||
@@ -3505,6 +3526,12 @@ namespace FourSlashInterface {
|
||||
"constructor",
|
||||
"async"
|
||||
];
|
||||
public allowedConstructorParameterKeywords = [
|
||||
"public",
|
||||
"private",
|
||||
"protected",
|
||||
"readonly",
|
||||
];
|
||||
|
||||
constructor(protected state: FourSlash.TestState, private negative = false) {
|
||||
if (!negative) {
|
||||
@@ -3547,6 +3574,12 @@ namespace FourSlashInterface {
|
||||
}
|
||||
}
|
||||
|
||||
public completionListContainsConstructorParameterKeywords() {
|
||||
for (const keyword of this.allowedConstructorParameterKeywords) {
|
||||
this.completionListContains(keyword, keyword, /*documentation*/ undefined, "keyword");
|
||||
}
|
||||
}
|
||||
|
||||
public completionListIsGlobal(expected: boolean) {
|
||||
this.state.verifyCompletionListIsGlobal(expected);
|
||||
}
|
||||
@@ -3696,6 +3729,10 @@ namespace FourSlashInterface {
|
||||
this.state.verifySymbolAtLocation(startRange, declarationRanges);
|
||||
}
|
||||
|
||||
public typeOfSymbolAtLocation(range: FourSlash.Range, symbol: ts.Symbol, expected: string) {
|
||||
this.state.verifyTypeOfSymbolAtLocation(range, symbol, expected);
|
||||
}
|
||||
|
||||
public referencesOf(start: FourSlash.Range, references: FourSlash.Range[]) {
|
||||
this.state.verifyReferencesOf(start, references);
|
||||
}
|
||||
@@ -3816,8 +3853,8 @@ namespace FourSlashInterface {
|
||||
this.state.verifyRangeAfterCodeFix(expectedText, includeWhiteSpace, errorCode, index);
|
||||
}
|
||||
|
||||
public fileAfterApplyingRefactorAtMarker(markerName: string, expectedContent: string, refactorNameToApply: string, formattingOptions?: ts.FormatCodeSettings): void {
|
||||
this.state.verifyFileAfterApplyingRefactorAtMarker(markerName, expectedContent, refactorNameToApply, formattingOptions);
|
||||
public fileAfterApplyingRefactorAtMarker(markerName: string, expectedContent: string, refactorNameToApply: string, actionName: string, formattingOptions?: ts.FormatCodeSettings): void {
|
||||
this.state.verifyFileAfterApplyingRefactorAtMarker(markerName, expectedContent, refactorNameToApply, actionName, formattingOptions);
|
||||
}
|
||||
|
||||
public rangeIs(expectedText: string, includeWhiteSpace?: boolean): void {
|
||||
@@ -3888,6 +3925,10 @@ namespace FourSlashInterface {
|
||||
this.state.verifyRangesWithSameTextAreDocumentHighlights();
|
||||
}
|
||||
|
||||
public documentHighlightsOf(startRange: FourSlash.Range, ranges: FourSlash.Range[]) {
|
||||
this.state.verifyDocumentHighlightsOf(startRange, ranges);
|
||||
}
|
||||
|
||||
public completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string, tags?: ts.JSDocTagInfo[]) {
|
||||
this.state.verifyCompletionEntryDetails(entryName, text, documentation, kind, tags);
|
||||
}
|
||||
@@ -4000,11 +4041,11 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
public printCurrentFileState() {
|
||||
this.state.printCurrentFileState();
|
||||
this.state.printCurrentFileState(/*makeWhitespaceVisible*/ false, /*makeCaretVisible*/ true);
|
||||
}
|
||||
|
||||
public printCurrentFileStateWithWhitespace() {
|
||||
this.state.printCurrentFileState(/*makeWhitespaceVisible*/ true);
|
||||
this.state.printCurrentFileState(/*makeWhitespaceVisible*/ true, /*makeCaretVisible*/ true);
|
||||
}
|
||||
|
||||
public printCurrentFileStateWithoutCaret() {
|
||||
@@ -4196,11 +4237,8 @@ namespace FourSlashInterface {
|
||||
}
|
||||
|
||||
function getClassification(classificationType: ts.ClassificationTypeNames, text: string, position?: number): Classification {
|
||||
return {
|
||||
classificationType,
|
||||
text: text,
|
||||
textSpan: position === undefined ? undefined : { start: position, end: position + text.length }
|
||||
};
|
||||
const textSpan = position === undefined ? undefined : { start: position, end: position + text.length };
|
||||
return { classificationType, text, textSpan };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+40
-32
@@ -259,8 +259,9 @@ namespace Utils {
|
||||
return true;
|
||||
}
|
||||
else if ((f & v) > 0) {
|
||||
if (result.length)
|
||||
if (result.length) {
|
||||
result += " | ";
|
||||
}
|
||||
result += flags[v];
|
||||
return false;
|
||||
}
|
||||
@@ -478,7 +479,7 @@ namespace Harness {
|
||||
getCurrentDirectory(): string;
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
resolvePath(path: string): string;
|
||||
readFile(path: string): string;
|
||||
readFile(path: string): string | undefined;
|
||||
writeFile(path: string, contents: string): void;
|
||||
directoryName(path: string): string;
|
||||
getDirectories(path: string): string[];
|
||||
@@ -492,7 +493,7 @@ namespace Harness {
|
||||
args(): string[];
|
||||
getExecutingFilePath(): string;
|
||||
exit(exitCode?: number): void;
|
||||
readDirectory(path: string, extension?: string[], exclude?: string[], include?: string[]): string[];
|
||||
readDirectory(path: string, extension?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[];
|
||||
tryEnableSourceMapsForHost?(): void;
|
||||
getEnvironmentVariable?(name: string): string;
|
||||
}
|
||||
@@ -536,7 +537,7 @@ namespace Harness {
|
||||
ts.sys.tryEnableSourceMapsForHost();
|
||||
}
|
||||
}
|
||||
export const readDirectory: typeof IO.readDirectory = (path, extension, exclude, include) => ts.sys.readDirectory(path, extension, exclude, include);
|
||||
export const readDirectory: typeof IO.readDirectory = (path, extension, exclude, include, depth) => ts.sys.readDirectory(path, extension, exclude, include, depth);
|
||||
|
||||
export function createDirectory(path: string) {
|
||||
if (!directoryExists(path)) {
|
||||
@@ -718,7 +719,7 @@ namespace Harness {
|
||||
}
|
||||
});
|
||||
|
||||
export function readFile(file: string) {
|
||||
export function readFile(file: string): string | undefined {
|
||||
const response = Http.getFileFromServerSync(serverRoot + file);
|
||||
if (response.status === 200) {
|
||||
return response.responseText;
|
||||
@@ -732,12 +733,12 @@ namespace Harness {
|
||||
Http.writeToServerSync(serverRoot + path, "WRITE", contents);
|
||||
}
|
||||
|
||||
export function readDirectory(path: string, extension?: string[], exclude?: string[], include?: string[]) {
|
||||
export function readDirectory(path: string, extension?: string[], exclude?: string[], include?: string[], depth?: number) {
|
||||
const fs = new Utils.VirtualFileSystem(path, useCaseSensitiveFileNames());
|
||||
for (const file of listFiles(path)) {
|
||||
fs.addFile(file);
|
||||
}
|
||||
return ts.matchFiles(path, extension, exclude, include, useCaseSensitiveFileNames(), getCurrentDirectory(), path => {
|
||||
return ts.matchFiles(path, extension, exclude, include, useCaseSensitiveFileNames(), getCurrentDirectory(), depth, path => {
|
||||
const entry = fs.traversePath(path);
|
||||
if (entry && entry.isDirectory()) {
|
||||
const directory = <Utils.VirtualDirectory>entry;
|
||||
@@ -892,13 +893,13 @@ namespace Harness {
|
||||
const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
|
||||
/** Maps a symlink name to a realpath. Used only for exposing `realpath`. */
|
||||
const realPathMap = ts.createFileMap<string>();
|
||||
const realPathMap = ts.createMap<string>();
|
||||
/**
|
||||
* Maps a file name to a source file.
|
||||
* This will have a different SourceFile for every symlink pointing to that file;
|
||||
* if the program resolves realpaths then symlink entries will be ignored.
|
||||
*/
|
||||
const fileMap = ts.createFileMap<ts.SourceFile>();
|
||||
const fileMap = ts.createMap<ts.SourceFile>();
|
||||
for (const file of inputFiles) {
|
||||
if (file.content !== undefined) {
|
||||
const fileName = ts.normalizePath(file.unitName);
|
||||
@@ -974,8 +975,8 @@ namespace Harness {
|
||||
getCanonicalFileName,
|
||||
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
|
||||
getNewLine: () => newLine,
|
||||
fileExists: fileName => fileMap.contains(toPath(fileName)),
|
||||
readFile: (fileName: string): string => {
|
||||
fileExists: fileName => fileMap.has(toPath(fileName)),
|
||||
readFile(fileName: string): string | undefined {
|
||||
const file = fileMap.get(toPath(fileName));
|
||||
if (ts.endsWith(fileName, "json")) {
|
||||
// strip comments
|
||||
@@ -998,7 +999,7 @@ namespace Harness {
|
||||
getDirectories: d => {
|
||||
const path = ts.toPath(d, currentDirectory, getCanonicalFileName);
|
||||
const result: string[] = [];
|
||||
fileMap.forEachValue(key => {
|
||||
ts.forEachKey(fileMap, key => {
|
||||
if (key.indexOf(path) === 0 && key.lastIndexOf("/") > path.length) {
|
||||
let dirName = key.substr(path.length, key.indexOf("/", path.length + 1) - path.length);
|
||||
if (dirName[0] === "/") {
|
||||
@@ -1014,12 +1015,12 @@ namespace Harness {
|
||||
};
|
||||
}
|
||||
|
||||
function mapHasFileInDirectory(directoryPath: ts.Path, map: ts.FileMap<any>): boolean {
|
||||
function mapHasFileInDirectory(directoryPath: ts.Path, map: ts.Map<{}>): boolean {
|
||||
if (!map) {
|
||||
return false;
|
||||
}
|
||||
let exists = false;
|
||||
map.forEachValue(fileName => {
|
||||
ts.forEachKey(map, fileName => {
|
||||
if (!exists && ts.startsWith(fileName, directoryPath) && fileName[directoryPath.length] === "/") {
|
||||
exists = true;
|
||||
}
|
||||
@@ -1052,7 +1053,7 @@ namespace Harness {
|
||||
];
|
||||
|
||||
let optionsIndex: ts.Map<ts.CommandLineOption>;
|
||||
function getCommandLineOption(name: string): ts.CommandLineOption {
|
||||
function getCommandLineOption(name: string): ts.CommandLineOption | undefined {
|
||||
if (!optionsIndex) {
|
||||
optionsIndex = ts.createMap<ts.CommandLineOption>();
|
||||
const optionDeclarations = harnessOptionDeclarations.concat(ts.optionDeclarations);
|
||||
@@ -1124,7 +1125,7 @@ namespace Harness {
|
||||
compilerOptions: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory: string): CompilationOutput {
|
||||
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.clone(compilerOptions) : { noResolve: false };
|
||||
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.cloneCompilerOptions(compilerOptions) : { noResolve: false };
|
||||
options.target = options.target || ts.ScriptTarget.ES3;
|
||||
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
|
||||
options.noErrorTruncation = true;
|
||||
@@ -1248,7 +1249,7 @@ namespace Harness {
|
||||
sourceFileName = outFile;
|
||||
}
|
||||
|
||||
const dTsFileName = ts.removeFileExtension(sourceFileName) + ".d.ts";
|
||||
const dTsFileName = ts.removeFileExtension(sourceFileName) + ts.Extension.Dts;
|
||||
|
||||
return ts.forEach(result.declFilesCode, declFile => declFile.fileName === dTsFileName ? declFile : undefined);
|
||||
}
|
||||
@@ -1464,7 +1465,7 @@ namespace Harness {
|
||||
// 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") || ts.endsWith(baselinePath, ".tsx") ?
|
||||
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);
|
||||
}
|
||||
@@ -1556,13 +1557,13 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export function doJsEmitBaseline(baselinePath: string, header: string, options: ts.CompilerOptions, result: CompilerResult, toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], harnessSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
export function doJsEmitBaseline(baselinePath: string, header: string, options: ts.CompilerOptions, result: CompilerResult, tsConfigFiles: Harness.Compiler.TestFile[], toBeCompiled: Harness.Compiler.TestFile[], otherFiles: Harness.Compiler.TestFile[], harnessSettings: Harness.TestCaseParser.CompilerSettings) {
|
||||
if (!options.noEmit && result.files.length === 0 && result.errors.length === 0) {
|
||||
throw new Error("Expected at least one js file to be emitted or at least one error to be created.");
|
||||
}
|
||||
|
||||
// check js output
|
||||
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ".js"), () => {
|
||||
Harness.Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ts.Extension.Js), () => {
|
||||
let tsCode = "";
|
||||
const tsSources = otherFiles.concat(toBeCompiled);
|
||||
if (tsSources.length > 1) {
|
||||
@@ -1592,7 +1593,7 @@ namespace Harness {
|
||||
if (declFileCompilationResult && declFileCompilationResult.declResult.errors.length) {
|
||||
jsCode += "\r\n\r\n//// [DtsFileErrors]\r\n";
|
||||
jsCode += "\r\n\r\n";
|
||||
jsCode += Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
jsCode += Harness.Compiler.getErrorBaseline(tsConfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
}
|
||||
|
||||
if (jsCode.length > 0) {
|
||||
@@ -1650,22 +1651,22 @@ namespace Harness {
|
||||
}
|
||||
|
||||
export function isTS(fileName: string) {
|
||||
return ts.endsWith(fileName, ".ts");
|
||||
return ts.endsWith(fileName, ts.Extension.Ts);
|
||||
}
|
||||
|
||||
export function isTSX(fileName: string) {
|
||||
return ts.endsWith(fileName, ".tsx");
|
||||
return ts.endsWith(fileName, ts.Extension.Tsx);
|
||||
}
|
||||
|
||||
export function isDTS(fileName: string) {
|
||||
return ts.endsWith(fileName, ".d.ts");
|
||||
return ts.endsWith(fileName, ts.Extension.Dts);
|
||||
}
|
||||
|
||||
export function isJS(fileName: string) {
|
||||
return ts.endsWith(fileName, ".js");
|
||||
return ts.endsWith(fileName, ts.Extension.Js);
|
||||
}
|
||||
export function isJSX(fileName: string) {
|
||||
return ts.endsWith(fileName, ".jsx");
|
||||
return ts.endsWith(fileName, ts.Extension.Jsx);
|
||||
}
|
||||
|
||||
export function isJSMap(fileName: string) {
|
||||
@@ -1743,7 +1744,12 @@ namespace Harness {
|
||||
}
|
||||
|
||||
/** Given a test file containing // @FileName directives, return an array of named units of code to be added to an existing compiler instance */
|
||||
export function makeUnitsFromTest(code: string, fileName: string, rootDir?: string): { settings: CompilerSettings; testUnitData: TestUnitData[]; tsConfig: ts.ParsedCommandLine } {
|
||||
export function makeUnitsFromTest(code: string, fileName: string, rootDir?: string): {
|
||||
settings: CompilerSettings;
|
||||
testUnitData: TestUnitData[];
|
||||
tsConfig: ts.ParsedCommandLine;
|
||||
tsConfigFileUnitData: TestUnitData;
|
||||
} {
|
||||
const settings = extractCompilerSettings(code);
|
||||
|
||||
// List of all the subfiles we've parsed out
|
||||
@@ -1829,17 +1835,19 @@ namespace Harness {
|
||||
|
||||
// check if project has tsconfig.json in the list of files
|
||||
let tsConfig: ts.ParsedCommandLine;
|
||||
let tsConfigFileUnitData: TestUnitData;
|
||||
for (let i = 0; i < testUnitData.length; i++) {
|
||||
const data = testUnitData[i];
|
||||
if (ts.getBaseFileName(data.name).toLowerCase() === "tsconfig.json") {
|
||||
const configJson = ts.parseConfigFileTextToJson(data.name, data.content);
|
||||
assert.isTrue(configJson.config !== undefined);
|
||||
const configJson = ts.parseJsonText(data.name, data.content);
|
||||
assert.isTrue(configJson.endOfFileToken !== undefined);
|
||||
let baseDir = ts.normalizePath(ts.getDirectoryPath(data.name));
|
||||
if (rootDir) {
|
||||
baseDir = ts.getNormalizedAbsolutePath(baseDir, rootDir);
|
||||
}
|
||||
tsConfig = ts.parseJsonConfigFileContent(configJson.config, parseConfigHost, baseDir);
|
||||
tsConfig = ts.parseJsonSourceFileConfigFileContent(configJson, parseConfigHost, baseDir);
|
||||
tsConfig.options.configFilePath = data.name;
|
||||
tsConfigFileUnitData = data;
|
||||
|
||||
// delete entry from the list
|
||||
ts.orderedRemoveItemAt(testUnitData, i);
|
||||
@@ -1847,7 +1855,7 @@ namespace Harness {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { settings, testUnitData, tsConfig };
|
||||
return { settings, testUnitData, tsConfig, tsConfigFileUnitData };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1972,7 +1980,7 @@ namespace Harness {
|
||||
export function isDefaultLibraryFile(filePath: string): boolean {
|
||||
// We need to make sure that the filePath is prefixed with "lib." not just containing "lib." and end with ".d.ts"
|
||||
const fileName = ts.getBaseFileName(ts.normalizeSlashes(filePath));
|
||||
return ts.startsWith(fileName, "lib.") && ts.endsWith(fileName, ".d.ts");
|
||||
return ts.startsWith(fileName, "lib.") && ts.endsWith(fileName, ts.Extension.Dts);
|
||||
}
|
||||
|
||||
export function isBuiltFile(filePath: string): boolean {
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
class DefaultHostCancellationToken implements ts.HostCancellationToken {
|
||||
public static Instance = new DefaultHostCancellationToken();
|
||||
public static readonly Instance = new DefaultHostCancellationToken();
|
||||
|
||||
public isCancellationRequested() {
|
||||
return false;
|
||||
@@ -208,13 +208,14 @@ namespace Harness.LanguageService {
|
||||
const script = this.getScriptSnapshot(fileName);
|
||||
return script !== undefined;
|
||||
}
|
||||
readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
|
||||
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[] {
|
||||
return ts.matchFiles(path, extensions, exclude, include,
|
||||
/*useCaseSensitiveFileNames*/ false,
|
||||
this.getCurrentDirectory(),
|
||||
depth,
|
||||
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
|
||||
}
|
||||
readFile(path: string): string {
|
||||
readFile(path: string): string | undefined {
|
||||
const snapshot = this.getScriptSnapshot(path);
|
||||
return snapshot.getText(0, snapshot.getLength());
|
||||
}
|
||||
@@ -312,9 +313,7 @@ namespace Harness.LanguageService {
|
||||
getScriptVersion(fileName: string): string { return this.nativeHost.getScriptVersion(fileName); }
|
||||
getLocalizedDiagnosticMessages(): string { return JSON.stringify({}); }
|
||||
|
||||
readDirectory(_rootDir: string, _extension: string): string {
|
||||
return ts.notImplemented();
|
||||
}
|
||||
readDirectory = ts.notImplemented;
|
||||
readDirectoryNames = ts.notImplemented;
|
||||
readFileNames = ts.notImplemented;
|
||||
fileExists(fileName: string) { return this.getScriptInfo(fileName) !== undefined; }
|
||||
@@ -495,7 +494,7 @@ namespace Harness.LanguageService {
|
||||
getCodeFixDiagnostics(): ts.Diagnostic[] {
|
||||
throw new Error("Not supported on the shim.");
|
||||
}
|
||||
getRefactorCodeActions(): ts.CodeAction[] {
|
||||
getEditsForRefactor(): ts.RefactorEditInfo {
|
||||
throw new Error("Not supported on the shim.");
|
||||
}
|
||||
getApplicableRefactors(): ts.ApplicableRefactorInfo[] {
|
||||
@@ -623,7 +622,7 @@ namespace Harness.LanguageService {
|
||||
this.writeMessage(message);
|
||||
}
|
||||
|
||||
readFile(fileName: string): string {
|
||||
readFile(fileName: string): string | undefined {
|
||||
if (fileName.indexOf(Harness.Compiler.defaultLibFileName) >= 0) {
|
||||
fileName = Harness.Compiler.defaultLibFileName;
|
||||
}
|
||||
@@ -671,9 +670,7 @@ namespace Harness.LanguageService {
|
||||
return ts.sys.getEnvironmentVariable(name);
|
||||
}
|
||||
|
||||
readDirectory(_path: string, _extension?: string[], _exclude?: string[], _include?: string[]): string[] {
|
||||
return ts.notImplemented();
|
||||
}
|
||||
readDirectory() { return ts.notImplemented(); }
|
||||
|
||||
watchFile(): ts.FileWatcher {
|
||||
return { close: ts.noop };
|
||||
@@ -734,7 +731,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
createHash(s: string) {
|
||||
return s;
|
||||
return mockHash(s);
|
||||
}
|
||||
|
||||
require(_initialDir: string, _moduleName: string): ts.server.RequireResult {
|
||||
@@ -859,4 +856,8 @@ namespace Harness.LanguageService {
|
||||
getClassifier(): ts.Classifier { throw new Error("getClassifier is not available using the server interface."); }
|
||||
getPreProcessedFileInfo(): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); }
|
||||
}
|
||||
|
||||
export function mockHash(s: string): string {
|
||||
return `hash-${s}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,10 +64,11 @@ interface IOLog {
|
||||
}[];
|
||||
directoriesRead: {
|
||||
path: string,
|
||||
extensions: string[],
|
||||
exclude: string[],
|
||||
include: string[],
|
||||
result: string[]
|
||||
extensions: ReadonlyArray<string>,
|
||||
exclude: ReadonlyArray<string>,
|
||||
include: ReadonlyArray<string>,
|
||||
depth: number,
|
||||
result: ReadonlyArray<string>,
|
||||
}[];
|
||||
}
|
||||
|
||||
@@ -220,10 +221,9 @@ namespace Playback {
|
||||
memoize(path => findFileByPath(replayLog.filesRead, path, /*throwFileNotFoundError*/ true).contents));
|
||||
|
||||
wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)(
|
||||
(path, extensions, exclude, include) => {
|
||||
const result = (<ts.System>underlying).readDirectory(path, extensions, exclude, include);
|
||||
const logEntry = { path, extensions, exclude, include, result };
|
||||
recordLog.directoriesRead.push(logEntry);
|
||||
(path, extensions, exclude, include, depth) => {
|
||||
const result = (<ts.System>underlying).readDirectory(path, extensions, exclude, include, depth);
|
||||
recordLog.directoriesRead.push({ path, extensions, exclude, include, depth, result });
|
||||
return result;
|
||||
},
|
||||
path => {
|
||||
|
||||
@@ -24,6 +24,7 @@ interface BatchCompileProjectTestCaseEmittedFile extends Harness.Compiler.Genera
|
||||
}
|
||||
|
||||
interface CompileProjectFilesResult {
|
||||
configFileSourceFiles: ts.SourceFile[];
|
||||
moduleKind: ts.ModuleKind;
|
||||
program?: ts.Program;
|
||||
compilerOptions?: ts.CompilerOptions;
|
||||
@@ -124,7 +125,8 @@ class ProjectRunner extends RunnerBase {
|
||||
return Harness.IO.resolvePath(testCase.projectRoot);
|
||||
}
|
||||
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: () => string[],
|
||||
function compileProjectFiles(moduleKind: ts.ModuleKind, configFileSourceFiles: ts.SourceFile[],
|
||||
getInputFiles: () => string[],
|
||||
getSourceFileTextImpl: (fileName: string) => string,
|
||||
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void,
|
||||
compilerOptions: ts.CompilerOptions): CompileProjectFilesResult {
|
||||
@@ -148,6 +150,7 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
return {
|
||||
configFileSourceFiles,
|
||||
moduleKind,
|
||||
program,
|
||||
errors,
|
||||
@@ -196,6 +199,7 @@ class ProjectRunner extends RunnerBase {
|
||||
const outputFiles: BatchCompileProjectTestCaseEmittedFile[] = [];
|
||||
let inputFiles = testCase.inputFiles;
|
||||
let compilerOptions = createCompilerOptions();
|
||||
const configFileSourceFiles: ts.SourceFile[] = [];
|
||||
|
||||
let configFileName: string;
|
||||
if (compilerOptions.project) {
|
||||
@@ -207,41 +211,31 @@ class ProjectRunner extends RunnerBase {
|
||||
configFileName = ts.findConfigFile("", fileExists);
|
||||
}
|
||||
|
||||
let errors: ts.Diagnostic[];
|
||||
if (configFileName) {
|
||||
const result = ts.readConfigFile(configFileName, getSourceFileText);
|
||||
if (result.error) {
|
||||
return {
|
||||
moduleKind,
|
||||
errors: [result.error]
|
||||
};
|
||||
}
|
||||
|
||||
const configObject = result.config;
|
||||
const result = ts.readJsonConfigFile(configFileName, getSourceFileText);
|
||||
configFileSourceFiles.push(result);
|
||||
const configParseHost: ts.ParseConfigHost = {
|
||||
useCaseSensitiveFileNames: Harness.IO.useCaseSensitiveFileNames(),
|
||||
fileExists,
|
||||
readDirectory,
|
||||
readFile
|
||||
};
|
||||
const configParseResult = ts.parseJsonConfigFileContent(configObject, configParseHost, ts.getDirectoryPath(configFileName), compilerOptions);
|
||||
if (configParseResult.errors.length > 0) {
|
||||
return {
|
||||
moduleKind,
|
||||
errors: configParseResult.errors
|
||||
};
|
||||
}
|
||||
const configParseResult = ts.parseJsonSourceFileConfigFileContent(result, configParseHost, ts.getDirectoryPath(configFileName), compilerOptions);
|
||||
inputFiles = configParseResult.fileNames;
|
||||
compilerOptions = configParseResult.options;
|
||||
errors = result.parseDiagnostics.concat(configParseResult.errors);
|
||||
}
|
||||
|
||||
const projectCompilerResult = compileProjectFiles(moduleKind, () => inputFiles, getSourceFileText, writeFile, compilerOptions);
|
||||
const projectCompilerResult = compileProjectFiles(moduleKind, configFileSourceFiles, () => inputFiles, getSourceFileText, writeFile, compilerOptions);
|
||||
return {
|
||||
configFileSourceFiles,
|
||||
moduleKind,
|
||||
program: projectCompilerResult.program,
|
||||
compilerOptions,
|
||||
sourceMapData: projectCompilerResult.sourceMapData,
|
||||
outputFiles,
|
||||
errors: projectCompilerResult.errors,
|
||||
errors: errors ? errors.concat(projectCompilerResult.errors) : projectCompilerResult.errors,
|
||||
};
|
||||
|
||||
function createCompilerOptions() {
|
||||
@@ -281,8 +275,8 @@ class ProjectRunner extends RunnerBase {
|
||||
: ts.normalizeSlashes(testCase.projectRoot) + "/" + ts.normalizeSlashes(fileName);
|
||||
}
|
||||
|
||||
function readDirectory(rootDir: string, extension: string[], exclude: string[], include: string[]): string[] {
|
||||
const harnessReadDirectoryResult = Harness.IO.readDirectory(getFileNameInTheProjectTest(rootDir), extension, exclude, include);
|
||||
function readDirectory(rootDir: string, extension: string[], exclude: string[], include: string[], depth: number): string[] {
|
||||
const harnessReadDirectoryResult = Harness.IO.readDirectory(getFileNameInTheProjectTest(rootDir), extension, exclude, include, depth);
|
||||
const result: string[] = [];
|
||||
for (let i = 0; i < harnessReadDirectoryResult.length; i++) {
|
||||
result[i] = ts.getRelativePathToDirectoryOrUrl(testCase.projectRoot, harnessReadDirectoryResult[i],
|
||||
@@ -295,7 +289,7 @@ class ProjectRunner extends RunnerBase {
|
||||
return Harness.IO.fileExists(getFileNameInTheProjectTest(fileName));
|
||||
}
|
||||
|
||||
function readFile(fileName: string): string {
|
||||
function readFile(fileName: string): string | undefined {
|
||||
return Harness.IO.readFile(getFileNameInTheProjectTest(fileName));
|
||||
}
|
||||
|
||||
@@ -325,8 +319,8 @@ class ProjectRunner extends RunnerBase {
|
||||
// we need to instead create files that can live in the project reference folder
|
||||
// but make sure extension of these files matches with the fileName the compiler asked to write
|
||||
diskRelativeName = "diskFile" + nonSubfolderDiskFiles +
|
||||
(Harness.Compiler.isDTS(fileName) ? ".d.ts" :
|
||||
Harness.Compiler.isJS(fileName) ? ".js" : ".js.map");
|
||||
(Harness.Compiler.isDTS(fileName) ? ts.Extension.Dts :
|
||||
Harness.Compiler.isJS(fileName) ? ts.Extension.Js : ".js.map");
|
||||
nonSubfolderDiskFiles++;
|
||||
}
|
||||
|
||||
@@ -360,7 +354,7 @@ class ProjectRunner extends RunnerBase {
|
||||
ensureDirectoryStructure(ts.getDirectoryPath(ts.normalizePath(outputFilePath)));
|
||||
Harness.IO.writeFile(outputFilePath, data);
|
||||
|
||||
outputFiles.push({ emittedFileName: fileName, code: data, fileName: diskRelativeName, writeByteOrderMark: writeByteOrderMark });
|
||||
outputFiles.push({ emittedFileName: fileName, code: data, fileName: diskRelativeName, writeByteOrderMark });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,14 +380,14 @@ class ProjectRunner extends RunnerBase {
|
||||
emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName);
|
||||
}
|
||||
|
||||
const outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts";
|
||||
const outputDtsFileName = emitOutputFilePathWithoutExtension + ts.Extension.Dts;
|
||||
const file = findOutputDtsFile(outputDtsFileName);
|
||||
if (file) {
|
||||
allInputFiles.unshift(file);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ".d.ts";
|
||||
const outputDtsFileName = ts.removeFileExtension(compilerOptions.outFile || compilerOptions.out) + ts.Extension.Dts;
|
||||
const outputDtsFile = findOutputDtsFile(outputDtsFileName);
|
||||
if (!ts.contains(allInputFiles, outputDtsFile)) {
|
||||
allInputFiles.unshift(outputDtsFile);
|
||||
@@ -402,7 +396,7 @@ class ProjectRunner extends RunnerBase {
|
||||
});
|
||||
|
||||
// Dont allow config files since we are compiling existing source options
|
||||
return compileProjectFiles(compilerResult.moduleKind, getInputFiles, getSourceFileText, writeFile, compilerResult.compilerOptions);
|
||||
return compileProjectFiles(compilerResult.moduleKind, compilerResult.configFileSourceFiles, getInputFiles, getSourceFileText, writeFile, compilerResult.compilerOptions);
|
||||
|
||||
function findOutputDtsFile(fileName: string) {
|
||||
return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined);
|
||||
@@ -428,16 +422,16 @@ class ProjectRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
function getErrorsBaseline(compilerResult: CompileProjectFilesResult) {
|
||||
const inputFiles = compilerResult.program ? ts.map(ts.filter(compilerResult.program.getSourceFiles(),
|
||||
sourceFile => !Harness.isDefaultLibraryFile(sourceFile.fileName)),
|
||||
sourceFile => {
|
||||
return {
|
||||
unitName: ts.isRootedDiskPath(sourceFile.fileName) ?
|
||||
RunnerBase.removeFullPaths(sourceFile.fileName) :
|
||||
sourceFile.fileName,
|
||||
content: sourceFile.text
|
||||
};
|
||||
}) : [];
|
||||
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
|
||||
});
|
||||
|
||||
return Harness.Compiler.getErrorBaseline(inputFiles, compilerResult.errors);
|
||||
}
|
||||
|
||||
@@ -222,6 +222,10 @@ if (taskConfigsFolder) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ts.Debug.isDebugging) {
|
||||
ts.Debug.enableDebugInfo();
|
||||
}
|
||||
|
||||
runTests(runners);
|
||||
}
|
||||
if (!runUnitTests) {
|
||||
|
||||
+18
-16
@@ -22,14 +22,14 @@ namespace RWC {
|
||||
}
|
||||
|
||||
function isTsConfigFile(file: { path: string }): boolean {
|
||||
const tsConfigFileName = "tsconfig.json";
|
||||
return file.path.substr(file.path.length - tsConfigFileName.length).toLowerCase() === tsConfigFileName;
|
||||
return file.path.indexOf("tsconfig") !== -1 && file.path.indexOf("json") !== -1;
|
||||
}
|
||||
|
||||
export function runRWCTest(jsonPath: string) {
|
||||
describe("Testing a RWC project: " + jsonPath, () => {
|
||||
let inputFiles: Harness.Compiler.TestFile[] = [];
|
||||
let otherFiles: Harness.Compiler.TestFile[] = [];
|
||||
let tsconfigFiles: Harness.Compiler.TestFile[] = [];
|
||||
let compilerResult: Harness.Compiler.CompilerResult;
|
||||
let compilerOptions: ts.CompilerOptions;
|
||||
const baselineOpts: Harness.Baseline.BaselineOptions = {
|
||||
@@ -44,6 +44,7 @@ namespace RWC {
|
||||
// Therefore we have to clean out large objects after the test is done.
|
||||
inputFiles = [];
|
||||
otherFiles = [];
|
||||
tsconfigFiles = [];
|
||||
compilerResult = undefined;
|
||||
compilerOptions = undefined;
|
||||
currentDirectory = undefined;
|
||||
@@ -53,7 +54,8 @@ namespace RWC {
|
||||
useCustomLibraryFile = undefined;
|
||||
});
|
||||
|
||||
it("can compile", () => {
|
||||
it("can compile", function(this: Mocha.ITestCallbackContext) {
|
||||
this.timeout(800000); // Allow long timeouts for RWC compilations
|
||||
let opts: ts.ParsedCommandLine;
|
||||
|
||||
const ioLog: IOLog = JSON.parse(Harness.IO.readFile(jsonPath));
|
||||
@@ -74,16 +76,18 @@ namespace RWC {
|
||||
const tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined);
|
||||
if (tsconfigFile) {
|
||||
const tsconfigFileContents = getHarnessCompilerInputUnit(tsconfigFile.path);
|
||||
const parsedTsconfigFileContents = ts.parseConfigFileTextToJson(tsconfigFile.path, tsconfigFileContents.content);
|
||||
tsconfigFiles.push({ unitName: tsconfigFile.path, content: tsconfigFileContents.content });
|
||||
const parsedTsconfigFileContents = ts.parseJsonText(tsconfigFile.path, tsconfigFileContents.content);
|
||||
const configParseHost: ts.ParseConfigHost = {
|
||||
useCaseSensitiveFileNames: Harness.IO.useCaseSensitiveFileNames(),
|
||||
fileExists: Harness.IO.fileExists,
|
||||
readDirectory: Harness.IO.readDirectory,
|
||||
readFile: Harness.IO.readFile
|
||||
};
|
||||
const configParseResult = ts.parseJsonConfigFileContent(parsedTsconfigFileContents.config, configParseHost, ts.getDirectoryPath(tsconfigFile.path));
|
||||
const configParseResult = ts.parseJsonSourceFileConfigFileContent(parsedTsconfigFileContents, configParseHost, ts.getDirectoryPath(tsconfigFile.path));
|
||||
fileNames = configParseResult.fileNames;
|
||||
opts.options = ts.extend(opts.options, configParseResult.options);
|
||||
ts.setConfigFileInOptions(opts.options, configParseResult.options.configFile);
|
||||
}
|
||||
|
||||
// Load the files
|
||||
@@ -198,8 +202,8 @@ namespace RWC {
|
||||
return null;
|
||||
}
|
||||
// Do not include the library in the baselines to avoid noise
|
||||
const baselineFiles = inputFiles.concat(otherFiles).filter(f => !Harness.isDefaultLibraryFile(f.unitName));
|
||||
const errors = compilerResult.errors.filter(e => e.file && !Harness.isDefaultLibraryFile(e.file.fileName));
|
||||
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);
|
||||
}, baselineOpts);
|
||||
});
|
||||
@@ -209,16 +213,16 @@ namespace RWC {
|
||||
it("has the expected errors in generated declaration files", () => {
|
||||
if (compilerOptions.declaration && !compilerResult.errors.length) {
|
||||
Harness.Baseline.runBaseline(`${baseName}.dts.errors.txt`, () => {
|
||||
const declFileCompilationResult = Harness.Compiler.compileDeclarationFiles(
|
||||
inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined, compilerOptions, currentDirectory);
|
||||
|
||||
if (declFileCompilationResult.declResult.errors.length === 0) {
|
||||
if (compilerResult.errors.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const declFileCompilationResult = Harness.Compiler.compileDeclarationFiles(
|
||||
inputFiles, otherFiles, compilerResult, /*harnessSettings*/ undefined, compilerOptions, currentDirectory);
|
||||
|
||||
return Harness.Compiler.minimalDiagnosticsToString(declFileCompilationResult.declResult.errors) +
|
||||
Harness.IO.newLine() + Harness.IO.newLine() +
|
||||
Harness.Compiler.getErrorBaseline(declFileCompilationResult.declInputFiles.concat(declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
Harness.Compiler.getErrorBaseline(tsconfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.errors);
|
||||
}, baselineOpts);
|
||||
}
|
||||
});
|
||||
@@ -235,10 +239,8 @@ namespace RWC {
|
||||
}
|
||||
|
||||
class RWCRunner extends RunnerBase {
|
||||
private static sourcePath = "internal/cases/rwc/";
|
||||
|
||||
public enumerateTestFiles() {
|
||||
return Harness.IO.listFiles(RWCRunner.sourcePath, /.+\.json$/);
|
||||
return Harness.IO.listFiles("internal/cases/rwc/", /.+\.json$/);
|
||||
}
|
||||
|
||||
public kind(): TestRunnerKind {
|
||||
@@ -259,4 +261,4 @@ class RWCRunner extends RunnerBase {
|
||||
private runTest(jsonFileName: string) {
|
||||
RWC.runRWCTest(jsonFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace Harness.SourceMapRecorder {
|
||||
export function recordSourceMapSpan(sourceMapSpan: ts.SourceMapSpan) {
|
||||
// verify the decoded span is same as the new span
|
||||
const decodeResult = SourceMapDecoder.decodeNextEncodedSourceMapSpan();
|
||||
let decodedErrors: string[];
|
||||
let decodeErrors: string[];
|
||||
if (decodeResult.error
|
||||
|| decodeResult.sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine
|
||||
|| decodeResult.sourceMapSpan.emittedColumn !== sourceMapSpan.emittedColumn
|
||||
@@ -268,22 +268,20 @@ namespace Harness.SourceMapRecorder {
|
||||
|| decodeResult.sourceMapSpan.sourceIndex !== sourceMapSpan.sourceIndex
|
||||
|| decodeResult.sourceMapSpan.nameIndex !== sourceMapSpan.nameIndex) {
|
||||
if (decodeResult.error) {
|
||||
decodedErrors = ["!!^^ !!^^ There was decoding error in the sourcemap at this location: " + decodeResult.error];
|
||||
decodeErrors = ["!!^^ !!^^ There was decoding error in the sourcemap at this location: " + decodeResult.error];
|
||||
}
|
||||
else {
|
||||
decodedErrors = ["!!^^ !!^^ The decoded span from sourcemap's mapping entry does not match what was encoded for this span:"];
|
||||
decodeErrors = ["!!^^ !!^^ The decoded span from sourcemap's mapping entry does not match what was encoded for this span:"];
|
||||
}
|
||||
decodedErrors.push("!!^^ !!^^ Decoded span from sourcemap's mappings entry: " + getSourceMapSpanString(decodeResult.sourceMapSpan, /*getAbsentNameIndex*/ true) + " Span encoded by the emitter:" + getSourceMapSpanString(sourceMapSpan, /*getAbsentNameIndex*/ true));
|
||||
decodeErrors.push("!!^^ !!^^ Decoded span from sourcemap's mappings entry: " + getSourceMapSpanString(decodeResult.sourceMapSpan, /*getAbsentNameIndex*/ true) + " Span encoded by the emitter:" + getSourceMapSpanString(sourceMapSpan, /*getAbsentNameIndex*/ true));
|
||||
}
|
||||
|
||||
if (spansOnSingleLine.length && spansOnSingleLine[0].sourceMapSpan.emittedLine !== sourceMapSpan.emittedLine) {
|
||||
// On different line from the one that we have been recording till now,
|
||||
writeRecordedSpans();
|
||||
spansOnSingleLine = [{ sourceMapSpan: sourceMapSpan, decodeErrors: decodedErrors }];
|
||||
}
|
||||
else {
|
||||
spansOnSingleLine.push({ sourceMapSpan: sourceMapSpan, decodeErrors: decodedErrors });
|
||||
spansOnSingleLine = [];
|
||||
}
|
||||
spansOnSingleLine.push({ sourceMapSpan, decodeErrors });
|
||||
}
|
||||
|
||||
export function recordNewSourceFileSpan(sourceMapSpan: ts.SourceMapSpan, newSourceFileCode: string) {
|
||||
|
||||
@@ -4,19 +4,19 @@
|
||||
/* tslint:disable:no-null-keyword */
|
||||
|
||||
class Test262BaselineRunner extends RunnerBase {
|
||||
private static basePath = "internal/cases/test262";
|
||||
private static helpersFilePath = "tests/cases/test262-harness/helpers.d.ts";
|
||||
private static helperFile: Harness.Compiler.TestFile = {
|
||||
private static readonly basePath = "internal/cases/test262";
|
||||
private static readonly helpersFilePath = "tests/cases/test262-harness/helpers.d.ts";
|
||||
private static readonly helperFile: Harness.Compiler.TestFile = {
|
||||
unitName: Test262BaselineRunner.helpersFilePath,
|
||||
content: Harness.IO.readFile(Test262BaselineRunner.helpersFilePath),
|
||||
};
|
||||
private static testFileExtensionRegex = /\.js$/;
|
||||
private static options: ts.CompilerOptions = {
|
||||
private static readonly testFileExtensionRegex = /\.js$/;
|
||||
private static readonly options: ts.CompilerOptions = {
|
||||
allowNonTsExtensions: true,
|
||||
target: ts.ScriptTarget.Latest,
|
||||
module: ts.ModuleKind.CommonJS
|
||||
};
|
||||
private static baselineOptions: Harness.Baseline.BaselineOptions = {
|
||||
private static readonly baselineOptions: Harness.Baseline.BaselineOptions = {
|
||||
Subfolder: "test262",
|
||||
Baselinefolder: "internal/baselines"
|
||||
};
|
||||
@@ -48,7 +48,7 @@ class Test262BaselineRunner extends RunnerBase {
|
||||
// Emit the results
|
||||
testState = {
|
||||
filename: testFilename,
|
||||
inputFiles: inputFiles,
|
||||
inputFiles,
|
||||
compilerResult: undefined,
|
||||
};
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"../compiler/checker.ts",
|
||||
"../compiler/factory.ts",
|
||||
"../compiler/visitor.ts",
|
||||
"../compiler/transformers/utilities.ts",
|
||||
"../compiler/transformers/ts.ts",
|
||||
"../compiler/transformers/jsx.ts",
|
||||
"../compiler/transformers/esnext.ts",
|
||||
@@ -73,14 +74,9 @@
|
||||
"../services/formatting/tokenRange.ts",
|
||||
"../services/codeFixProvider.ts",
|
||||
"../services/codefixes/fixes.ts",
|
||||
"../services/codefixes/fixExtendsInterfaceBecomesImplements.ts",
|
||||
"../services/codefixes/fixClassIncorrectlyImplementsInterface.ts",
|
||||
"../services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts",
|
||||
"../services/codefixes/fixClassSuperMustPrecedeThisAccess.ts",
|
||||
"../services/codefixes/fixConstructorForDerivedNeedSuperCall.ts",
|
||||
"../services/codefixes/helpers.ts",
|
||||
"../services/codefixes/importFixes.ts",
|
||||
"../services/codefixes/unusedIdentifierFixes.ts",
|
||||
"../services/codefixes/fixUnusedIdentifier.ts",
|
||||
"../services/codefixes/disableJsDiagnostics.ts",
|
||||
|
||||
"harness.ts",
|
||||
@@ -128,6 +124,7 @@
|
||||
"./unittests/transform.ts",
|
||||
"./unittests/customTransforms.ts",
|
||||
"./unittests/textChanges.ts",
|
||||
"./unittests/telemetry.ts"
|
||||
"./unittests/telemetry.ts",
|
||||
"./unittests/programMissingFiles.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ class TypeWriterWalker {
|
||||
this.results.push({
|
||||
line: lineAndCharacter.line,
|
||||
syntaxKind: node.kind,
|
||||
sourceText: sourceText,
|
||||
sourceText,
|
||||
type: typeString,
|
||||
symbol: symbolString
|
||||
});
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace ts {
|
||||
clearTimeout,
|
||||
setImmediate: typeof setImmediate !== "undefined" ? setImmediate : action => setTimeout(action, 0),
|
||||
clearImmediate: typeof clearImmediate !== "undefined" ? clearImmediate : clearTimeout,
|
||||
createHash: s => s
|
||||
createHash: Harness.LanguageService.mockHash,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace ts {
|
||||
const rootScriptInfo = projectService.getOrCreateScriptInfo(rootFile, /* openedByClient */ true, /*containingProject*/ undefined);
|
||||
|
||||
const project = projectService.createInferredProjectWithRootFileIfNecessary(rootScriptInfo);
|
||||
project.setCompilerOptions({ module: ts.ModuleKind.AMD } );
|
||||
project.setCompilerOptions({ module: ts.ModuleKind.AMD, noLib: true } );
|
||||
return {
|
||||
project,
|
||||
rootScriptInfo
|
||||
@@ -158,7 +158,7 @@ namespace ts {
|
||||
// setting compiler options discards module resolution cache
|
||||
fileExistsCalled = false;
|
||||
|
||||
const compilerOptions = ts.clone(project.getCompilerOptions());
|
||||
const compilerOptions = ts.cloneCompilerOptions(project.getCompilerOptions());
|
||||
compilerOptions.target = ts.ScriptTarget.ES5;
|
||||
project.setCompilerOptions(compilerOptions);
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace ts.projectSystem {
|
||||
|
||||
file1Consumer1.content = `let y = 10;`;
|
||||
host.reloadFS([moduleFile1, file1Consumer1, file1Consumer2, configFile, libFile]);
|
||||
host.triggerFileWatcherCallback(file1Consumer1.path, /*removed*/ false);
|
||||
host.triggerFileWatcherCallback(file1Consumer1.path, FileWatcherEventKind.Changed);
|
||||
|
||||
session.executeCommand(changeModuleFile1ShapeRequest1);
|
||||
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer2] }]);
|
||||
@@ -225,7 +225,7 @@ namespace ts.projectSystem {
|
||||
session.executeCommand(changeModuleFile1ShapeRequest1);
|
||||
// Delete file1Consumer2
|
||||
host.reloadFS([moduleFile1, file1Consumer1, configFile, libFile]);
|
||||
host.triggerFileWatcherCallback(file1Consumer2.path, /*removed*/ true);
|
||||
host.triggerFileWatcherCallback(file1Consumer2.path, FileWatcherEventKind.Deleted);
|
||||
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1] }]);
|
||||
});
|
||||
|
||||
@@ -475,7 +475,7 @@ namespace ts.projectSystem {
|
||||
|
||||
openFilesForSession([referenceFile1], session);
|
||||
host.reloadFS([referenceFile1, configFile]);
|
||||
host.triggerFileWatcherCallback(moduleFile1.path, /*removed*/ true);
|
||||
host.triggerFileWatcherCallback(moduleFile1.path, FileWatcherEventKind.Deleted);
|
||||
|
||||
const request = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: referenceFile1.path });
|
||||
sendAffectedFileRequestAndCheckResult(session, request, [
|
||||
@@ -513,7 +513,7 @@ namespace ts.projectSystem {
|
||||
const lines = ["var x = 1;", "var y = 2;"];
|
||||
const path = "/a/app";
|
||||
const f = {
|
||||
path: path + ".ts",
|
||||
path: path + ts.Extension.Ts,
|
||||
content: lines.join(newLine)
|
||||
};
|
||||
const host = createServerHost([f], { newLine });
|
||||
@@ -530,7 +530,7 @@ namespace ts.projectSystem {
|
||||
command: "compileOnSaveEmitFile",
|
||||
arguments: { file: f.path }
|
||||
});
|
||||
const emitOutput = host.readFile(path + ".js");
|
||||
const emitOutput = host.readFile(path + ts.Extension.Js);
|
||||
assert.equal(emitOutput, f.content + newLine, "content of emit output should be identical with the input + newline");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -111,23 +111,47 @@ namespace ts {
|
||||
["under a case insensitive host", caseInsensitiveBasePath, caseInsensitiveHost],
|
||||
["under a case sensitive host", caseSensitiveBasePath, caseSensitiveHost]
|
||||
], ([testName, basePath, host]) => {
|
||||
function getParseCommandLine(entry: string) {
|
||||
const {config, error} = ts.readConfigFile(entry, name => host.readFile(name));
|
||||
assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n"));
|
||||
return ts.parseJsonConfigFileContent(config, host, basePath, {}, entry);
|
||||
}
|
||||
|
||||
function getParseCommandLineJsonSourceFile(entry: string) {
|
||||
const jsonSourceFile = ts.readJsonConfigFile(entry, name => host.readFile(name));
|
||||
assert(jsonSourceFile.endOfFileToken && !jsonSourceFile.parseDiagnostics.length, flattenDiagnosticMessageText(jsonSourceFile.parseDiagnostics[0] && jsonSourceFile.parseDiagnostics[0].messageText, "\n"));
|
||||
return {
|
||||
jsonSourceFile,
|
||||
parsed: ts.parseJsonSourceFileConfigFileContent(jsonSourceFile, host, basePath, {}, entry)
|
||||
};
|
||||
}
|
||||
|
||||
function testSuccess(name: string, entry: string, expected: CompilerOptions, expectedFiles: string[]) {
|
||||
expected.configFilePath = entry;
|
||||
it(name, () => {
|
||||
const {config, error} = ts.readConfigFile(entry, name => host.readFile(name));
|
||||
assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n"));
|
||||
const parsed = ts.parseJsonConfigFileContent(config, host, basePath, {}, entry);
|
||||
const parsed = getParseCommandLine(entry);
|
||||
assert(!parsed.errors.length, flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n"));
|
||||
expected.configFilePath = entry;
|
||||
assert.deepEqual(parsed.options, expected);
|
||||
assert.deepEqual(parsed.fileNames, expectedFiles);
|
||||
});
|
||||
|
||||
it(name + " with jsonSourceFile", () => {
|
||||
const { parsed, jsonSourceFile } = getParseCommandLineJsonSourceFile(entry);
|
||||
assert(!parsed.errors.length, flattenDiagnosticMessageText(parsed.errors[0] && parsed.errors[0].messageText, "\n"));
|
||||
assert.deepEqual(parsed.options, expected);
|
||||
assert.equal(parsed.options.configFile, jsonSourceFile);
|
||||
assert.deepEqual(parsed.fileNames, expectedFiles);
|
||||
});
|
||||
}
|
||||
|
||||
function testFailure(name: string, entry: string, expectedDiagnostics: {code: number, category: DiagnosticCategory, messageText: string}[]) {
|
||||
function testFailure(name: string, entry: string, expectedDiagnostics: { code: number, category: DiagnosticCategory, messageText: string }[]) {
|
||||
it(name, () => {
|
||||
const {config, error} = ts.readConfigFile(entry, name => host.readFile(name));
|
||||
assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n"));
|
||||
const parsed = ts.parseJsonConfigFileContent(config, host, basePath, {}, entry);
|
||||
const parsed = getParseCommandLine(entry);
|
||||
verifyDiagnostics(parsed.errors, expectedDiagnostics);
|
||||
});
|
||||
|
||||
it(name + " with jsonSourceFile", () => {
|
||||
const { parsed } = getParseCommandLineJsonSourceFile(entry);
|
||||
verifyDiagnostics(parsed.errors, expectedDiagnostics);
|
||||
});
|
||||
}
|
||||
@@ -185,4 +209,4 @@ namespace ts {
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
namespace ts {
|
||||
describe("convertCompilerOptionsFromJson", () => {
|
||||
function assertCompilerOptions(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
assertCompilerOptionsWithJson(json, configFileName, expectedResult);
|
||||
assertCompilerOptionsWithJsonNode(json, configFileName, expectedResult);
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const { options: actualCompilerOptions, errors: actualErrors} = convertCompilerOptionsFromJson(json["compilerOptions"], "/apath/", configFileName);
|
||||
|
||||
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
|
||||
@@ -21,6 +26,34 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJsonNode(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const fileText = JSON.stringify(json);
|
||||
const result = parseJsonText(configFileName, fileText);
|
||||
assert(!result.parseDiagnostics.length);
|
||||
assert(!!result.endOfFileToken);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost("/apath/", true, []);
|
||||
const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
expectedResult.compilerOptions["configFilePath"] = configFileName;
|
||||
|
||||
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
|
||||
const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions);
|
||||
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
|
||||
assert.equal(actualCompilerOptions.configFile, result);
|
||||
|
||||
const actualErrors = filter(actualParseErrors, error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
const expectedErrors = expectedResult.errors;
|
||||
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
|
||||
for (let i = 0; i < actualErrors.length; i++) {
|
||||
const actualError = actualErrors[i];
|
||||
const expectedError = expectedErrors[i];
|
||||
assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
|
||||
assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
|
||||
assert(actualError.file);
|
||||
assert(actualError.start);
|
||||
assert(actualError.length);
|
||||
}
|
||||
}
|
||||
|
||||
// tsconfig.json tests
|
||||
it("Convert correctly format tsconfig.json to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
|
||||
@@ -2,14 +2,20 @@
|
||||
/// <reference path="..\..\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
type ExpectedResult = { typeAcquisition: TypeAcquisition, errors: Diagnostic[] };
|
||||
describe("convertTypeAcquisitionFromJson", () => {
|
||||
function assertTypeAcquisition(json: any, configFileName: string, expectedResult: { typeAcquisition: TypeAcquisition, errors: Diagnostic[] }) {
|
||||
const jsonOptions = json["typeAcquisition"] || json["typingOptions"];
|
||||
const { options: actualTypeAcquisition, errors: actualErrors } = convertTypeAcquisitionFromJson(jsonOptions, "/apath/", configFileName);
|
||||
function assertTypeAcquisition(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
assertTypeAcquisitionWithJson(json, configFileName, expectedResult);
|
||||
assertTypeAcquisitionWithJsonNode(json, configFileName, expectedResult);
|
||||
}
|
||||
|
||||
function verifyAcquisition(actualTypeAcquisition: TypeAcquisition, expectedResult: ExpectedResult) {
|
||||
const parsedTypeAcquisition = JSON.stringify(actualTypeAcquisition);
|
||||
const expectedTypeAcquisition = JSON.stringify(expectedResult.typeAcquisition);
|
||||
assert.equal(parsedTypeAcquisition, expectedTypeAcquisition);
|
||||
}
|
||||
|
||||
function verifyErrors(actualErrors: Diagnostic[], expectedResult: ExpectedResult, hasLocation?: boolean) {
|
||||
const expectedErrors = expectedResult.errors;
|
||||
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
|
||||
for (let i = 0; i < actualErrors.length; i++) {
|
||||
@@ -17,9 +23,34 @@ namespace ts {
|
||||
const expectedError = expectedErrors[i];
|
||||
assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
|
||||
assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
|
||||
if (hasLocation) {
|
||||
assert(actualError.file);
|
||||
assert(actualError.start);
|
||||
assert(actualError.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function assertTypeAcquisitionWithJson(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
const jsonOptions = json["typeAcquisition"] || json["typingOptions"];
|
||||
const { options: actualTypeAcquisition, errors: actualErrors } = convertTypeAcquisitionFromJson(jsonOptions, "/apath/", configFileName);
|
||||
verifyAcquisition(actualTypeAcquisition, expectedResult);
|
||||
verifyErrors(actualErrors, expectedResult);
|
||||
}
|
||||
|
||||
function assertTypeAcquisitionWithJsonNode(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
const fileText = JSON.stringify(json);
|
||||
const result = parseJsonText(configFileName, fileText);
|
||||
assert(!result.parseDiagnostics.length);
|
||||
assert(!!result.endOfFileToken);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost("/apath/", true, []);
|
||||
const { typeAcquisition: actualTypeAcquisition, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
verifyAcquisition(actualTypeAcquisition, expectedResult);
|
||||
|
||||
const actualErrors = filter(actualParseErrors, error => error.code !== Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
verifyErrors(actualErrors, expectedResult, /*hasLocation*/ true);
|
||||
}
|
||||
|
||||
// tsconfig.json
|
||||
it("Convert deprecated typingOptions.enableAutoDiscovery format tsconfig.json to typeAcquisition ", () => {
|
||||
assertTypeAcquisition(
|
||||
@@ -177,7 +208,7 @@ namespace ts {
|
||||
},
|
||||
errors: [
|
||||
{
|
||||
category: Diagnostics.Unknown_compiler_option_0.category,
|
||||
category: Diagnostics.Unknown_type_acquisition_option_0.category,
|
||||
code: Diagnostics.Unknown_type_acquisition_option_0.code,
|
||||
file: undefined,
|
||||
start: 0,
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace ts {
|
||||
parsesCorrectly("functionType1", "{function()}");
|
||||
parsesCorrectly("functionType2", "{function(string, boolean)}");
|
||||
parsesCorrectly("functionReturnType1", "{function(string, boolean)}");
|
||||
parsesCorrectly("thisType1", "{this:a.b}");
|
||||
parsesCorrectly("newType1", "{new:a.b}");
|
||||
parsesCorrectly("thisType1", "{function(this:a.b)}");
|
||||
parsesCorrectly("newType1", "{function(new:a.b)}");
|
||||
parsesCorrectly("variadicType", "{...number}");
|
||||
parsesCorrectly("optionalType", "{number=}");
|
||||
parsesCorrectly("optionalNullable", "{?=}");
|
||||
@@ -54,7 +54,7 @@ namespace ts {
|
||||
parsesCorrectly("typeReference3", "{a.function}");
|
||||
parsesCorrectly("arrayType1", "{a[]}");
|
||||
parsesCorrectly("arrayType2", "{a[][]}");
|
||||
parsesCorrectly("arrayType3", "{a[][]=}");
|
||||
parsesCorrectly("arrayType3", "{(a[][])=}");
|
||||
parsesCorrectly("keyword1", "{var}");
|
||||
parsesCorrectly("keyword2", "{null}");
|
||||
parsesCorrectly("keyword3", "{undefined}");
|
||||
@@ -62,6 +62,12 @@ namespace ts {
|
||||
parsesCorrectly("tupleType1", "{[number]}");
|
||||
parsesCorrectly("tupleType2", "{[number,string]}");
|
||||
parsesCorrectly("tupleType3", "{[number,string,boolean]}");
|
||||
parsesCorrectly("tupleTypeWithTrailingComma", "{[number,]}");
|
||||
parsesCorrectly("typeOfType", "{typeof M}");
|
||||
parsesCorrectly("tsConstructorType", "{new () => string}");
|
||||
parsesCorrectly("tsFunctionType", "{() => string}");
|
||||
parsesCorrectly("typeArgumentsNotFollowingDot", "{a<>}");
|
||||
parsesCorrectly("functionTypeWithTrailingComma", "{function(a,)}");
|
||||
});
|
||||
|
||||
describe("parsesIncorrectly", () => {
|
||||
@@ -69,21 +75,13 @@ namespace ts {
|
||||
parsesIncorrectly("unionTypeWithTrailingBar", "{(a|)}");
|
||||
parsesIncorrectly("unionTypeWithoutTypes", "{()}");
|
||||
parsesIncorrectly("nullableTypeWithoutType", "{!}");
|
||||
parsesIncorrectly("functionTypeWithTrailingComma", "{function(a,)}");
|
||||
parsesIncorrectly("thisWithoutType", "{this:}");
|
||||
parsesIncorrectly("newWithoutType", "{new:}");
|
||||
parsesIncorrectly("variadicWithoutType", "{...}");
|
||||
parsesIncorrectly("optionalWithoutType", "{=}");
|
||||
parsesIncorrectly("allWithType", "{*foo}");
|
||||
parsesIncorrectly("typeArgumentsNotFollowingDot", "{a<>}");
|
||||
parsesIncorrectly("emptyTypeArguments", "{a.<>}");
|
||||
parsesIncorrectly("typeArgumentsWithTrailingComma", "{a.<a,>}");
|
||||
parsesIncorrectly("tsFunctionType", "{() => string}");
|
||||
parsesIncorrectly("tsConstructoType", "{new () => string}");
|
||||
parsesIncorrectly("typeOfType", "{typeof M}");
|
||||
parsesIncorrectly("namedParameter", "{function(a: number)}");
|
||||
parsesIncorrectly("tupleTypeWithComma", "{[,]}");
|
||||
parsesIncorrectly("tupleTypeWithTrailingComma", "{[number,]}");
|
||||
parsesIncorrectly("tupleTypeWithLeadingComma", "{[,number]}");
|
||||
});
|
||||
});
|
||||
|
||||
+101
-119
@@ -95,6 +95,44 @@ namespace ts {
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
}
|
||||
|
||||
function validateMatches(expected: ts.ParsedCommandLine, json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[]) {
|
||||
{
|
||||
const jsonText = JSON.stringify(json);
|
||||
const result = parseJsonText(caseInsensitiveTsconfigPath, jsonText);
|
||||
const actual = ts.parseJsonSourceFileConfigFileContent(result, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
for (const error of expected.errors) {
|
||||
if (error.file) {
|
||||
error.file = result;
|
||||
}
|
||||
}
|
||||
assertParsed(actual, expected);
|
||||
}
|
||||
{
|
||||
const actual = ts.parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack);
|
||||
expected.errors = map(expected.errors, error => {
|
||||
return <Diagnostic>{
|
||||
category: error.category,
|
||||
code: error.code,
|
||||
file: undefined,
|
||||
length: undefined,
|
||||
messageText: error.messageText,
|
||||
start: undefined,
|
||||
};
|
||||
});
|
||||
assertParsed(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
function createDiagnosticForConfigFile(json: any, start: number, length: number, diagnosticMessage: DiagnosticMessage, arg0: string) {
|
||||
const text = JSON.stringify(json);
|
||||
const file = <SourceFile>{
|
||||
fileName: caseInsensitiveTsconfigPath,
|
||||
kind: SyntaxKind.SourceFile,
|
||||
text
|
||||
};
|
||||
return ts.createFileDiagnostic(file, start, length, diagnosticMessage, arg0);
|
||||
}
|
||||
|
||||
describe("matchFiles", () => {
|
||||
it("with defaults", () => {
|
||||
const json = {};
|
||||
@@ -109,8 +147,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
describe("with literal file list", () => {
|
||||
@@ -130,8 +167,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("missing files are still present", () => {
|
||||
const json = {
|
||||
@@ -149,8 +185,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("are not removed due to excludes", () => {
|
||||
const json = {
|
||||
@@ -171,8 +206,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -193,8 +227,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with non .ts file extensions are excluded", () => {
|
||||
const json = {
|
||||
@@ -212,8 +245,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("with missing files are excluded", () => {
|
||||
const json = {
|
||||
@@ -231,8 +263,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("with literal excludes", () => {
|
||||
const json = {
|
||||
@@ -252,8 +283,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with wildcard excludes", () => {
|
||||
const json = {
|
||||
@@ -280,8 +310,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with recursive excludes", () => {
|
||||
const json = {
|
||||
@@ -307,8 +336,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with case sensitive exclude", () => {
|
||||
const json = {
|
||||
@@ -327,8 +355,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and no exclusions", () => {
|
||||
const json = {
|
||||
@@ -352,8 +379,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and exclusions", () => {
|
||||
const json = {
|
||||
@@ -379,8 +405,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and empty exclude", () => {
|
||||
const json = {
|
||||
@@ -404,8 +429,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -436,8 +460,7 @@ namespace ts {
|
||||
"c:/dev/x": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
it("same named declarations are excluded", () => {
|
||||
@@ -458,8 +481,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("`*` matches only ts files", () => {
|
||||
const json = {
|
||||
@@ -479,8 +501,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("`?` matches only a single character", () => {
|
||||
const json = {
|
||||
@@ -499,8 +520,7 @@ namespace ts {
|
||||
"c:/dev/x": ts.WatchDirectoryFlags.None
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with recursive directory", () => {
|
||||
const json = {
|
||||
@@ -521,8 +541,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with multiple recursive directories", () => {
|
||||
const json = {
|
||||
@@ -545,8 +564,7 @@ namespace ts {
|
||||
"c:/dev/z": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("case sensitive", () => {
|
||||
const json = {
|
||||
@@ -564,8 +582,7 @@ namespace ts {
|
||||
"/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
});
|
||||
it("with missing files are excluded", () => {
|
||||
const json = {
|
||||
@@ -584,8 +601,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("always include literal files", () => {
|
||||
const json = {
|
||||
@@ -609,8 +625,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude folders", () => {
|
||||
const json = {
|
||||
@@ -634,8 +649,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and no exclusions", () => {
|
||||
const json = {
|
||||
@@ -656,8 +670,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and exclusions", () => {
|
||||
const json = {
|
||||
@@ -680,8 +693,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with common package folders and empty exclude", () => {
|
||||
const json = {
|
||||
@@ -703,8 +715,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude .js files when allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -728,8 +739,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("include .js files when allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -753,8 +763,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("include explicitly listed .min.js files when allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -778,8 +787,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("include paths outside of the project", () => {
|
||||
const json = {
|
||||
@@ -802,8 +810,7 @@ namespace ts {
|
||||
"c:/ext": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("include paths outside of the project using relative paths", () => {
|
||||
const json = {
|
||||
@@ -825,8 +832,7 @@ namespace ts {
|
||||
"c:/ext": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude paths outside of the project using relative paths", () => {
|
||||
const json = {
|
||||
@@ -846,8 +852,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("include files with .. in their name", () => {
|
||||
const json = {
|
||||
@@ -866,8 +871,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude files with .. in their name", () => {
|
||||
const json = {
|
||||
@@ -888,8 +892,7 @@ namespace ts {
|
||||
"c:/ext": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=none, allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -911,8 +914,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=preserve, allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -936,8 +938,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=react-native, allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -961,8 +962,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=none, allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -986,8 +986,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=preserve, allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -1013,8 +1012,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with jsx=react-native, allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -1040,8 +1038,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("exclude .min.js files using wildcards", () => {
|
||||
const json = {
|
||||
@@ -1067,8 +1064,7 @@ namespace ts {
|
||||
"c:/dev/js": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
describe("with trailing recursive directory", () => {
|
||||
it("in includes", () => {
|
||||
@@ -1080,15 +1076,14 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**"),
|
||||
createDiagnosticForConfigFile(json, 12, 4, ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("in excludes", () => {
|
||||
const json = {
|
||||
@@ -1108,8 +1103,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
});
|
||||
describe("with multiple recursive directory patterns", () => {
|
||||
@@ -1122,15 +1116,14 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**/*"),
|
||||
createDiagnosticForConfigFile(json, 12, 11, ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**/*"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
it("in excludes", () => {
|
||||
const json = {
|
||||
@@ -1144,7 +1137,7 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**")
|
||||
createDiagnosticForConfigFile(json, 34, 9, ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**")
|
||||
],
|
||||
fileNames: [
|
||||
"c:/dev/a.ts",
|
||||
@@ -1156,8 +1149,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1171,15 +1163,14 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*"),
|
||||
createDiagnosticForConfigFile(json, 12, 9, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
|
||||
it("in includes after a subdirectory", () => {
|
||||
@@ -1191,15 +1182,14 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*"),
|
||||
createDiagnosticForConfigFile(json, 12, 11, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), "[]")
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
|
||||
it("in excludes immediately after", () => {
|
||||
@@ -1214,7 +1204,7 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/..")
|
||||
createDiagnosticForConfigFile(json, 34, 7, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/..")
|
||||
],
|
||||
fileNames: [
|
||||
"c:/dev/a.ts",
|
||||
@@ -1226,8 +1216,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
|
||||
it("in excludes after a subdirectory", () => {
|
||||
@@ -1242,7 +1231,7 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/..")
|
||||
createDiagnosticForConfigFile(json, 34, 9, ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/..")
|
||||
],
|
||||
fileNames: [
|
||||
"c:/dev/a.ts",
|
||||
@@ -1254,8 +1243,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1272,8 +1260,7 @@ namespace ts {
|
||||
"c:/dev/z": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1297,8 +1284,7 @@ namespace ts {
|
||||
"c:/dev/w": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
describe("that are explicitly included", () => {
|
||||
it("without wildcards", () => {
|
||||
@@ -1317,8 +1303,7 @@ namespace ts {
|
||||
],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with recursive wildcards that match directories", () => {
|
||||
const json = {
|
||||
@@ -1339,8 +1324,7 @@ namespace ts {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with recursive wildcards that match nothing", () => {
|
||||
const json = {
|
||||
@@ -1361,8 +1345,7 @@ namespace ts {
|
||||
"c:/dev/x": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
});
|
||||
it("with wildcard excludes that implicitly exclude dotted files", () => {
|
||||
const json = {
|
||||
@@ -1382,8 +1365,7 @@ namespace ts {
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
validateMatches(expected, json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, /*existingOptions*/ undefined, caseInsensitiveTsconfigPath);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace ts {
|
||||
if (!expected === !actual) {
|
||||
if (expected) {
|
||||
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
|
||||
assert.isTrue(expected.extension === actual.extension, `'ext': expected '${Extension[expected.extension]}' to be equal to '${Extension[actual.extension]}'`);
|
||||
assert.isTrue(expected.extension === actual.extension, `'ext': expected '${expected.extension}' to be equal to '${actual.extension}'`);
|
||||
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
|
||||
}
|
||||
return true;
|
||||
@@ -56,7 +56,7 @@ namespace ts {
|
||||
else {
|
||||
return { readFile, fileExists: path => map.has(path) };
|
||||
}
|
||||
function readFile(path: string): string {
|
||||
function readFile(path: string): string | undefined {
|
||||
const file = map.get(path);
|
||||
return file && file.content;
|
||||
}
|
||||
@@ -950,8 +950,8 @@ import b = require("./moduleB");
|
||||
{
|
||||
const f1 = { name: "/root/src/app.ts" };
|
||||
const f2 = { name: "/root/src/types/lib/typings/lib.d.ts" };
|
||||
const package = { name: "/root/src/types/lib/package.json", content: JSON.stringify({ types: "typings/lib.d.ts" }) };
|
||||
test(/*typesRoot*/"/root/src/types", /* typeDirective */"lib", /*primary*/ true, f1, f2, package);
|
||||
const packageFile = { name: "/root/src/types/lib/package.json", content: JSON.stringify({ types: "typings/lib.d.ts" }) };
|
||||
test(/*typesRoot*/"/root/src/types", /* typeDirective */"lib", /*primary*/ true, f1, f2, packageFile);
|
||||
}
|
||||
{
|
||||
const f1 = { name: "/root/src/app.ts" };
|
||||
@@ -961,8 +961,8 @@ import b = require("./moduleB");
|
||||
{
|
||||
const f1 = { name: "/root/src/app.ts" };
|
||||
const f2 = { name: "/root/src/node_modules/lib/typings/lib.d.ts" };
|
||||
const package = { name: "/root/src/node_modules/lib/package.json", content: JSON.stringify({ types: "typings/lib.d.ts" }) };
|
||||
test(/*typesRoot*/"/root/src/types", /* typeDirective */"lib", /*primary*/ false, f1, f2, package);
|
||||
const packageFile = { name: "/root/src/node_modules/lib/package.json", content: JSON.stringify({ types: "typings/lib.d.ts" }) };
|
||||
test(/*typesRoot*/"/root/src/types", /* typeDirective */"lib", /*primary*/ false, f1, f2, packageFile);
|
||||
}
|
||||
{
|
||||
const f1 = { name: "/root/src/app.ts" };
|
||||
@@ -972,8 +972,8 @@ import b = require("./moduleB");
|
||||
{
|
||||
const f1 = { name: "/root/src/app.ts" };
|
||||
const f2 = { name: "/root/src/node_modules/@types/lib/typings/lib.d.ts" };
|
||||
const package = { name: "/root/src/node_modules/@types/lib/package.json", content: JSON.stringify({ types: "typings/lib.d.ts" }) };
|
||||
test(/*typesRoot*/"/root/src/types", /* typeDirective */"lib", /*primary*/ false, f1, f2, package);
|
||||
const packageFile = { name: "/root/src/node_modules/@types/lib/package.json", content: JSON.stringify({ types: "typings/lib.d.ts" }) };
|
||||
test(/*typesRoot*/"/root/src/types", /* typeDirective */"lib", /*primary*/ false, f1, f2, packageFile);
|
||||
}
|
||||
});
|
||||
it("Can be resolved from secondary location", () => {
|
||||
@@ -990,8 +990,8 @@ import b = require("./moduleB");
|
||||
{
|
||||
const f1 = { name: "/root/src/app.ts" };
|
||||
const f2 = { name: "/root/node_modules/lib/typings/lib.d.ts" };
|
||||
const package = { name: "/root/node_modules/lib/package.json", content: JSON.stringify({ typings: "typings/lib.d.ts" }) };
|
||||
test(/*typesRoot*/"/root/src/types", /* typeDirective */"lib", /*primary*/ false, f1, f2, package);
|
||||
const packageFile = { name: "/root/node_modules/lib/package.json", content: JSON.stringify({ typings: "typings/lib.d.ts" }) };
|
||||
test(/*typesRoot*/"/root/src/types", /* typeDirective */"lib", /*primary*/ false, f1, f2, packageFile);
|
||||
}
|
||||
{
|
||||
const f1 = { name: "/root/src/app.ts" };
|
||||
@@ -1001,8 +1001,8 @@ import b = require("./moduleB");
|
||||
{
|
||||
const f1 = { name: "/root/src/app.ts" };
|
||||
const f2 = { name: "/root/node_modules/@types/lib/typings/lib.d.ts" };
|
||||
const package = { name: "/root/node_modules/@types/lib/package.json", content: JSON.stringify({ typings: "typings/lib.d.ts" }) };
|
||||
test(/*typesRoot*/"/root/src/types", /* typeDirective */"lib", /*primary*/ false, f1, f2, package);
|
||||
const packageFile = { name: "/root/node_modules/@types/lib/package.json", content: JSON.stringify({ typings: "typings/lib.d.ts" }) };
|
||||
test(/*typesRoot*/"/root/src/types", /* typeDirective */"lib", /*primary*/ false, f1, f2, packageFile);
|
||||
}
|
||||
});
|
||||
it("Primary resolution overrides secondary resolutions", () => {
|
||||
|
||||
@@ -81,63 +81,136 @@ namespace ts {
|
||||
|
||||
describe("printNode", () => {
|
||||
const printsCorrectly = makePrintsCorrectly("printsNodeCorrectly");
|
||||
let sourceFile: SourceFile;
|
||||
before(() => sourceFile = createSourceFile("source.ts", "", ScriptTarget.ES2015));
|
||||
// tslint:disable boolean-trivia
|
||||
const syntheticNode = createClassDeclaration(
|
||||
undefined,
|
||||
undefined,
|
||||
/*name*/ createIdentifier("C"),
|
||||
undefined,
|
||||
undefined,
|
||||
createNodeArray([
|
||||
createProperty(
|
||||
undefined,
|
||||
printsCorrectly("class", {}, printer => printer.printNode(
|
||||
EmitHint.Unspecified,
|
||||
createClassDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*name*/ createIdentifier("C"),
|
||||
/*typeParameters*/ undefined,
|
||||
/*heritageClauses*/ undefined,
|
||||
[createProperty(
|
||||
/*decorators*/ undefined,
|
||||
createNodeArray([createToken(SyntaxKind.PublicKeyword)]),
|
||||
createIdentifier("prop"),
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
)
|
||||
])
|
||||
);
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
/*initializer*/ undefined
|
||||
)]
|
||||
),
|
||||
createSourceFile("source.ts", "", ScriptTarget.ES2015)
|
||||
));
|
||||
|
||||
printsCorrectly("namespaceExportDeclaration", {}, printer => printer.printNode(
|
||||
EmitHint.Unspecified,
|
||||
createNamespaceExportDeclaration("B"),
|
||||
createSourceFile("source.ts", "", ScriptTarget.ES2015)
|
||||
));
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/15971
|
||||
const classWithOptionalMethodAndProperty = createClassDeclaration(
|
||||
undefined,
|
||||
/* modifiers */ createNodeArray([createToken(SyntaxKind.DeclareKeyword)]),
|
||||
/* name */ createIdentifier("X"),
|
||||
undefined,
|
||||
undefined,
|
||||
createNodeArray([
|
||||
createMethod(
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
/* name */ createIdentifier("method"),
|
||||
/* questionToken */ createToken(SyntaxKind.QuestionToken),
|
||||
undefined,
|
||||
undefined,
|
||||
/* type */ createKeywordTypeNode(SyntaxKind.VoidKeyword),
|
||||
undefined
|
||||
printsCorrectly("classWithOptionalMethodAndProperty", {}, printer => printer.printNode(
|
||||
EmitHint.Unspecified,
|
||||
createClassDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ [createToken(SyntaxKind.DeclareKeyword)],
|
||||
/*name*/ createIdentifier("X"),
|
||||
/*typeParameters*/ undefined,
|
||||
/*heritageClauses*/ undefined,
|
||||
[
|
||||
createMethod(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ createIdentifier("method"),
|
||||
/*questionToken*/ createToken(SyntaxKind.QuestionToken),
|
||||
/*typeParameters*/ undefined,
|
||||
[],
|
||||
/*type*/ createKeywordTypeNode(SyntaxKind.VoidKeyword),
|
||||
/*body*/ undefined
|
||||
),
|
||||
createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*name*/ createIdentifier("property"),
|
||||
/*questionToken*/ createToken(SyntaxKind.QuestionToken),
|
||||
/*type*/ createKeywordTypeNode(SyntaxKind.StringKeyword),
|
||||
/*initializer*/ undefined
|
||||
),
|
||||
]
|
||||
),
|
||||
createSourceFile("source.ts", "", ScriptTarget.ES2015)
|
||||
));
|
||||
|
||||
// https://github.com/Microsoft/TypeScript/issues/15651
|
||||
printsCorrectly("functionTypes", {}, printer => printer.printNode(
|
||||
EmitHint.Unspecified,
|
||||
createTupleTypeNode([
|
||||
createFunctionTypeNode(
|
||||
/*typeArguments*/ undefined,
|
||||
[createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
createIdentifier("args")
|
||||
)],
|
||||
createKeywordTypeNode(SyntaxKind.AnyKeyword)
|
||||
),
|
||||
createProperty(
|
||||
undefined,
|
||||
undefined,
|
||||
/* name */ createIdentifier("property"),
|
||||
/* questionToken */ createToken(SyntaxKind.QuestionToken),
|
||||
/* type */ createKeywordTypeNode(SyntaxKind.StringKeyword),
|
||||
undefined
|
||||
createFunctionTypeNode(
|
||||
[createTypeParameterDeclaration("T")],
|
||||
[createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
createIdentifier("args")
|
||||
)],
|
||||
createKeywordTypeNode(SyntaxKind.AnyKeyword)
|
||||
),
|
||||
])
|
||||
);
|
||||
|
||||
// tslint:enable boolean-trivia
|
||||
printsCorrectly("class", {}, printer => printer.printNode(EmitHint.Unspecified, syntheticNode, sourceFile));
|
||||
|
||||
printsCorrectly("namespaceExportDeclaration", {}, printer => printer.printNode(EmitHint.Unspecified, createNamespaceExportDeclaration("B"), sourceFile));
|
||||
|
||||
printsCorrectly("classWithOptionalMethodAndProperty", {}, printer => printer.printNode(EmitHint.Unspecified, classWithOptionalMethodAndProperty, sourceFile));
|
||||
createFunctionTypeNode(
|
||||
/*typeArguments*/ undefined,
|
||||
[createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createToken(SyntaxKind.DotDotDotToken),
|
||||
createIdentifier("args")
|
||||
)],
|
||||
createKeywordTypeNode(SyntaxKind.AnyKeyword)
|
||||
),
|
||||
createFunctionTypeNode(
|
||||
/*typeArguments*/ undefined,
|
||||
[createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
createIdentifier("args"),
|
||||
createToken(SyntaxKind.QuestionToken)
|
||||
)],
|
||||
createKeywordTypeNode(SyntaxKind.AnyKeyword)
|
||||
),
|
||||
createFunctionTypeNode(
|
||||
/*typeArguments*/ undefined,
|
||||
[createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
createIdentifier("args"),
|
||||
/*questionToken*/ undefined,
|
||||
createKeywordTypeNode(SyntaxKind.AnyKeyword)
|
||||
)],
|
||||
createKeywordTypeNode(SyntaxKind.AnyKeyword)
|
||||
),
|
||||
createFunctionTypeNode(
|
||||
/*typeArguments*/ undefined,
|
||||
[createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
createObjectBindingPattern([])
|
||||
)],
|
||||
createKeywordTypeNode(SyntaxKind.AnyKeyword)
|
||||
),
|
||||
]),
|
||||
createSourceFile("source.ts", "", ScriptTarget.ES2015)
|
||||
));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("Program.getMissingFilePaths", () => {
|
||||
|
||||
const options: CompilerOptions = {
|
||||
noLib: true,
|
||||
};
|
||||
|
||||
const emptyFileName = "empty.ts";
|
||||
const emptyFileRelativePath = "./" + emptyFileName;
|
||||
|
||||
const emptyFile: Harness.Compiler.TestFile = {
|
||||
unitName: emptyFileName,
|
||||
content: ""
|
||||
};
|
||||
|
||||
const referenceFileName = "reference.ts";
|
||||
const referenceFileRelativePath = "./" + referenceFileName;
|
||||
|
||||
const referenceFile: Harness.Compiler.TestFile = {
|
||||
unitName: referenceFileName,
|
||||
content:
|
||||
"/// <reference path=\"d:/imaginary/nonexistent1.ts\"/>\n" + // Absolute
|
||||
"/// <reference path=\"./nonexistent2.ts\"/>\n" + // Relative
|
||||
"/// <reference path=\"nonexistent3.ts\"/>\n" + // Unqualified
|
||||
"/// <reference path=\"nonexistent4\"/>\n" // No extension
|
||||
};
|
||||
|
||||
const testCompilerHost = Harness.Compiler.createCompilerHost(
|
||||
/*inputFiles*/ [emptyFile, referenceFile],
|
||||
/*writeFile*/ undefined,
|
||||
/*scriptTarget*/ undefined,
|
||||
/*useCaseSensitiveFileNames*/ false,
|
||||
/*currentDirectory*/ "d:\\pretend\\",
|
||||
/*newLineKind*/ NewLineKind.LineFeed,
|
||||
/*libFiles*/ undefined
|
||||
);
|
||||
|
||||
it("handles no missing root files", () => {
|
||||
const program = createProgram([emptyFileRelativePath], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths();
|
||||
assert.isDefined(missing);
|
||||
assert.deepEqual(missing, []);
|
||||
});
|
||||
|
||||
it("handles missing root file", () => {
|
||||
const program = createProgram(["./nonexistent.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths();
|
||||
assert.isDefined(missing);
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent.ts"]); // Absolute path
|
||||
});
|
||||
|
||||
it("handles multiple missing root files", () => {
|
||||
const program = createProgram(["./nonexistent0.ts", "./nonexistent1.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths().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();
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent0.ts", "d:/pretend/nonexistent1.ts"]);
|
||||
});
|
||||
|
||||
it("handles repeatedly specified root files", () => {
|
||||
const program = createProgram(["./nonexistent.ts", "./nonexistent.ts"], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths();
|
||||
assert.isDefined(missing);
|
||||
assert.deepEqual(missing, ["d:/pretend/nonexistent.ts"]);
|
||||
});
|
||||
|
||||
it("normalizes file paths", () => {
|
||||
const program0 = createProgram(["./nonexistent.ts", "./NONEXISTENT.ts"], options, testCompilerHost);
|
||||
const program1 = createProgram(["./NONEXISTENT.ts", "./nonexistent.ts"], options, testCompilerHost);
|
||||
const missing0 = program0.getMissingFilePaths();
|
||||
const missing1 = program1.getMissingFilePaths();
|
||||
assert.equal(missing0.length, 1);
|
||||
assert.deepEqual(missing0, missing1);
|
||||
});
|
||||
|
||||
it("handles missing triple slash references", () => {
|
||||
const program = createProgram([referenceFileRelativePath], options, testCompilerHost);
|
||||
const missing = program.getMissingFilePaths().sort();
|
||||
assert.isDefined(missing);
|
||||
assert.deepEqual(missing, [
|
||||
// From absolute reference
|
||||
"d:/imaginary/nonexistent1.ts",
|
||||
|
||||
// From relative reference
|
||||
"d:/pretend/nonexistent2.ts",
|
||||
|
||||
// From unqualified reference
|
||||
"d:/pretend/nonexistent3.ts",
|
||||
|
||||
// From no-extension reference
|
||||
"d:/pretend/nonexistent4.d.ts",
|
||||
"d:/pretend/nonexistent4.ts",
|
||||
"d:/pretend/nonexistent4.tsx"
|
||||
]);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -6,7 +6,10 @@ namespace ts.projectSystem {
|
||||
describe("Project errors", () => {
|
||||
function checkProjectErrors(projectFiles: server.ProjectFilesWithTSDiagnostics, expectedErrors: string[]) {
|
||||
assert.isTrue(projectFiles !== undefined, "missing project files");
|
||||
const errors = projectFiles.projectErrors;
|
||||
checkProjectErrorsWorker(projectFiles.projectErrors, expectedErrors);
|
||||
}
|
||||
|
||||
function checkProjectErrorsWorker(errors: Diagnostic[], expectedErrors: string[]) {
|
||||
assert.equal(errors ? errors.length : 0, expectedErrors.length, `expected ${expectedErrors.length} error in the list`);
|
||||
if (expectedErrors.length) {
|
||||
for (let i = 0; i < errors.length; i++) {
|
||||
@@ -122,21 +125,24 @@ namespace ts.projectSystem {
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, [
|
||||
"')' expected.",
|
||||
"Declaration or statement expected.",
|
||||
"Declaration or statement expected.",
|
||||
"Failed to parse file '/a/b/tsconfig.json'"
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = projectService.configuredProjects[0].getAllProjectErrors();
|
||||
checkProjectErrorsWorker(projectErrors, [
|
||||
"'{' expected."
|
||||
]);
|
||||
assert.isNotNull(projectErrors[0].file);
|
||||
assert.equal(projectErrors[0].file.fileName, corruptedConfig.path);
|
||||
}
|
||||
// fix config and trigger watcher
|
||||
host.reloadFS([file1, file2, correctConfig]);
|
||||
host.triggerFileWatcherCallback(correctConfig.path, /*false*/);
|
||||
host.triggerFileWatcherCallback(correctConfig.path, FileWatcherEventKind.Changed);
|
||||
{
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = projectService.configuredProjects[0].getAllProjectErrors();
|
||||
checkProjectErrorsWorker(projectErrors, []);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -166,21 +172,24 @@ namespace ts.projectSystem {
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = projectService.configuredProjects[0].getAllProjectErrors();
|
||||
checkProjectErrorsWorker(projectErrors, []);
|
||||
}
|
||||
// break config and trigger watcher
|
||||
host.reloadFS([file1, file2, corruptedConfig]);
|
||||
host.triggerFileWatcherCallback(corruptedConfig.path, /*false*/);
|
||||
host.triggerFileWatcherCallback(corruptedConfig.path, FileWatcherEventKind.Changed);
|
||||
{
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1 });
|
||||
const configuredProject = forEach(projectService.synchronizeProjectList([]), f => f.info.projectName === corruptedConfig.path && f);
|
||||
assert.isTrue(configuredProject !== undefined, "should find configured project");
|
||||
checkProjectErrors(configuredProject, [
|
||||
"')' expected.",
|
||||
"Declaration or statement expected.",
|
||||
"Declaration or statement expected.",
|
||||
"Failed to parse file '/a/b/tsconfig.json'"
|
||||
checkProjectErrors(configuredProject, []);
|
||||
const projectErrors = projectService.configuredProjects[0].getAllProjectErrors();
|
||||
checkProjectErrorsWorker(projectErrors, [
|
||||
"'{' expected."
|
||||
]);
|
||||
assert.isNotNull(projectErrors[0].file);
|
||||
assert.equal(projectErrors[0].file.fileName, corruptedConfig.path);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,6 +316,31 @@ namespace ts {
|
||||
assert.isTrue(program_1.structureIsReused === StructureIsReused.Not);
|
||||
});
|
||||
|
||||
it("succeeds if missing files remain missing", () => {
|
||||
const options: CompilerOptions = { target, noLib: true };
|
||||
|
||||
const program_1 = newProgram(files, ["a.ts"], options);
|
||||
assert.notDeepEqual(emptyArray, program_1.getMissingFilePaths());
|
||||
|
||||
const program_2 = updateProgram(program_1, ["a.ts"], options, noop);
|
||||
assert.deepEqual(program_1.getMissingFilePaths(), program_2.getMissingFilePaths());
|
||||
|
||||
assert.equal(StructureIsReused.Completely, program_1.structureIsReused);
|
||||
});
|
||||
|
||||
it("fails if missing file is created", () => {
|
||||
const options: CompilerOptions = { target, noLib: true };
|
||||
|
||||
const program_1 = newProgram(files, ["a.ts"], options);
|
||||
assert.notDeepEqual(emptyArray, program_1.getMissingFilePaths());
|
||||
|
||||
const newTexts: NamedSourceText[] = files.concat([{ name: "non-existing-file.ts", text: SourceText.New("", "", `var x = 1`) }]);
|
||||
const program_2 = updateProgram(program_1, ["a.ts"], options, noop, newTexts);
|
||||
assert.deepEqual(emptyArray, program_2.getMissingFilePaths());
|
||||
|
||||
assert.equal(StructureIsReused.SafeModules, program_1.structureIsReused);
|
||||
});
|
||||
|
||||
it("resolution cache follows imports", () => {
|
||||
(<any>Error).stackTraceLimit = Infinity;
|
||||
|
||||
|
||||
@@ -30,13 +30,9 @@ describe("Colorization", function () {
|
||||
function identifier(text: string, position?: number) { return createClassification(text, ts.TokenClass.Identifier, position); }
|
||||
function numberLiteral(text: string, position?: number) { return createClassification(text, ts.TokenClass.NumberLiteral, position); }
|
||||
function stringLiteral(text: string, position?: number) { return createClassification(text, ts.TokenClass.StringLiteral, position); }
|
||||
function finalEndOfLineState(value: number): ClassificationEntry { return { value: value, classification: undefined, position: 0 }; }
|
||||
function createClassification(text: string, tokenClass: ts.TokenClass, position?: number): ClassificationEntry {
|
||||
return {
|
||||
value: text,
|
||||
classification: tokenClass,
|
||||
position: position,
|
||||
};
|
||||
function finalEndOfLineState(value: number): ClassificationEntry { return { value, classification: undefined, position: 0 }; }
|
||||
function createClassification(value: string, classification: ts.TokenClass, position?: number): ClassificationEntry {
|
||||
return { value, classification, position };
|
||||
}
|
||||
|
||||
function testLexicalClassification(text: string, initialEndOfLineState: ts.EndOfLineState, ...expectedEntries: ClassificationEntry[]): void {
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace ts.server {
|
||||
newLine: "\n",
|
||||
useCaseSensitiveFileNames: true,
|
||||
write(s): void { lastWrittenToHost = s; },
|
||||
readFile(): string { return void 0; },
|
||||
readFile: () => undefined,
|
||||
writeFile: noop,
|
||||
resolvePath(): string { return void 0; },
|
||||
fileExists: () => false,
|
||||
@@ -19,13 +19,13 @@ namespace ts.server {
|
||||
getExecutingFilePath(): string { return void 0; },
|
||||
getCurrentDirectory(): string { return void 0; },
|
||||
getEnvironmentVariable(): string { return ""; },
|
||||
readDirectory(): string[] { return []; },
|
||||
readDirectory() { return []; },
|
||||
exit: noop,
|
||||
setTimeout() { return 0; },
|
||||
clearTimeout: noop,
|
||||
setImmediate: () => 0,
|
||||
clearImmediate: noop,
|
||||
createHash: s => s
|
||||
createHash: Harness.LanguageService.mockHash,
|
||||
};
|
||||
|
||||
const mockLogger: Logger = {
|
||||
@@ -240,8 +240,8 @@ namespace ts.server {
|
||||
CommandNames.GetCodeFixesFull,
|
||||
CommandNames.GetSupportedCodeFixes,
|
||||
CommandNames.GetApplicableRefactors,
|
||||
CommandNames.GetRefactorCodeActions,
|
||||
CommandNames.GetRefactorCodeActionsFull,
|
||||
CommandNames.GetEditsForRefactor,
|
||||
CommandNames.GetEditsForRefactorFull,
|
||||
];
|
||||
|
||||
it("should not throw when commands are executed with invalid arguments", () => {
|
||||
@@ -389,7 +389,7 @@ namespace ts.server {
|
||||
request_seq: 0,
|
||||
type: "response",
|
||||
command,
|
||||
body: body,
|
||||
body,
|
||||
success: true
|
||||
});
|
||||
});
|
||||
@@ -436,7 +436,7 @@ namespace ts.server {
|
||||
request_seq: 0,
|
||||
type: "response",
|
||||
command,
|
||||
body: body,
|
||||
body,
|
||||
success: true
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace ts.projectSystem {
|
||||
et.service.openClientFile(file.path);
|
||||
assert.equal(et.getEvents().length, 0);
|
||||
});
|
||||
|
||||
it("only sends an event once", () => {
|
||||
const file = makeFile("/a.ts");
|
||||
const tsconfig = makeFile("/tsconfig.json", {});
|
||||
@@ -44,14 +45,15 @@ namespace ts.projectSystem {
|
||||
it("works with external project", () => {
|
||||
const file1 = makeFile("/a.ts");
|
||||
const et = new EventTracker([file1]);
|
||||
const compilerOptions: ts.CompilerOptions = { strict: true };
|
||||
const compilerOptions: ts.server.protocol.CompilerOptions = { strict: true };
|
||||
|
||||
const projectFileName = "foo.csproj";
|
||||
const projectFileName = "/hunter2/foo.csproj";
|
||||
|
||||
open();
|
||||
|
||||
// TODO: Apparently compilerOptions is mutated, so have to repeat it here!
|
||||
et.assertProjectInfoTelemetryEvent({
|
||||
projectId: Harness.LanguageService.mockHash("/hunter2/foo.csproj"),
|
||||
compilerOptions: { strict: true },
|
||||
compileOnSave: true,
|
||||
// These properties can't be present for an external project, so they are undefined instead of false.
|
||||
@@ -75,7 +77,7 @@ namespace ts.projectSystem {
|
||||
et.service.openExternalProject({
|
||||
rootFiles: toExternalFiles([file1.path]),
|
||||
options: compilerOptions,
|
||||
projectFileName: projectFileName,
|
||||
projectFileName,
|
||||
});
|
||||
checkNumberOfProjects(et.service, { externalProjects: 1 });
|
||||
}
|
||||
@@ -136,8 +138,6 @@ namespace ts.projectSystem {
|
||||
declaration: true,
|
||||
|
||||
lib: ["es6", "dom"],
|
||||
|
||||
checkJs: "" as any as boolean,
|
||||
};
|
||||
(compilerOptions as any).unknownCompilerOption = "hunter2"; // These are always ignored.
|
||||
const tsconfig = makeFile("/tsconfig.json", { compilerOptions, files: ["/a.ts"] });
|
||||
@@ -195,6 +195,7 @@ namespace ts.projectSystem {
|
||||
const et = new EventTracker([jsconfig, file]);
|
||||
et.service.openClientFile(file.path);
|
||||
et.assertProjectInfoTelemetryEvent({
|
||||
projectId: Harness.LanguageService.mockHash("/jsconfig.json"),
|
||||
fileStats: fileStats({ js: 1 }),
|
||||
compilerOptions: autoJsCompilerOptions,
|
||||
typeAcquisition: {
|
||||
@@ -214,6 +215,7 @@ namespace ts.projectSystem {
|
||||
et.service.openClientFile(file.path);
|
||||
et.getEvent<server.ProjectLanguageServiceStateEvent>(server.ProjectLanguageServiceStateEvent, /*mayBeMore*/ true);
|
||||
et.assertProjectInfoTelemetryEvent({
|
||||
projectId: Harness.LanguageService.mockHash("/jsconfig.json"),
|
||||
fileStats: fileStats({ js: 1 }),
|
||||
compilerOptions: autoJsCompilerOptions,
|
||||
configFileName: "jsconfig.json",
|
||||
@@ -248,7 +250,26 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
assertProjectInfoTelemetryEvent(partial: Partial<server.ProjectInfoTelemetryEventData>): void {
|
||||
assert.deepEqual(this.getEvent<server.ProjectInfoTelemetryEvent>(ts.server.ProjectInfoTelemetryEvent), makePayload(partial));
|
||||
assert.deepEqual(this.getEvent<server.ProjectInfoTelemetryEvent>(ts.server.ProjectInfoTelemetryEvent), {
|
||||
projectId: Harness.LanguageService.mockHash("/tsconfig.json"),
|
||||
fileStats: fileStats({ ts: 1 }),
|
||||
compilerOptions: {},
|
||||
extends: false,
|
||||
files: false,
|
||||
include: false,
|
||||
exclude: false,
|
||||
compileOnSave: false,
|
||||
typeAcquisition: {
|
||||
enable: false,
|
||||
exclude: false,
|
||||
include: false,
|
||||
},
|
||||
configFileName: "tsconfig.json",
|
||||
projectType: "configured",
|
||||
languageServiceEnabled: true,
|
||||
version: ts.version,
|
||||
...partial,
|
||||
});
|
||||
}
|
||||
|
||||
getEvent<T extends server.ProjectServiceEvent>(eventName: T["eventName"], mayBeMore = false): T["data"] {
|
||||
@@ -260,28 +281,6 @@ namespace ts.projectSystem {
|
||||
}
|
||||
}
|
||||
|
||||
function makePayload(partial: Partial<server.ProjectInfoTelemetryEventData>): server.ProjectInfoTelemetryEventData {
|
||||
return {
|
||||
fileStats: fileStats({ ts: 1 }),
|
||||
compilerOptions: {},
|
||||
extends: false,
|
||||
files: false,
|
||||
include: false,
|
||||
exclude: false,
|
||||
compileOnSave: false,
|
||||
typeAcquisition: {
|
||||
enable: false,
|
||||
exclude: false,
|
||||
include: false,
|
||||
},
|
||||
configFileName: "tsconfig.json",
|
||||
projectType: "configured",
|
||||
languageServiceEnabled: true,
|
||||
version: ts.version,
|
||||
...partial
|
||||
};
|
||||
}
|
||||
|
||||
function makeFile(path: string, content: {} = ""): projectSystem.FileOrFolder {
|
||||
return { path, content: typeof content === "string" ? "" : JSON.stringify(content) };
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace ts {
|
||||
return find(n);
|
||||
|
||||
function find(node: Node): Node {
|
||||
if (isDeclaration(node) && node.name && isIdentifier(node.name) && node.name.text === name) {
|
||||
if (isDeclaration(node) && node.name && isIdentifier(node.name) && node.name.escapedText === name) {
|
||||
return node;
|
||||
}
|
||||
else {
|
||||
@@ -67,12 +67,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
function flattenNodes(n: Node) {
|
||||
const data: (Node | NodeArray<any>)[] = [];
|
||||
const data: (Node | NodeArray<Node>)[] = [];
|
||||
walk(n);
|
||||
return data;
|
||||
|
||||
function walk(n: Node | Node[]): void {
|
||||
data.push(<any>n);
|
||||
function walk(n: Node | NodeArray<Node>): void {
|
||||
data.push(n);
|
||||
return isArray(n) ? forEach(n, walk) : forEachChild(n, walk, walk);
|
||||
}
|
||||
}
|
||||
@@ -367,20 +367,22 @@ namespace M {
|
||||
changeTracker.insertNodeAfter(sourceFile, findChild("M", sourceFile), createTestClass(), { prefix: newLineCharacter });
|
||||
});
|
||||
}
|
||||
{
|
||||
function findOpenBraceForConstructor(sourceFile: SourceFile) {
|
||||
const classDecl = <ClassDeclaration>sourceFile.statements[0];
|
||||
const constructorDecl = forEach(classDecl.members, m => m.kind === SyntaxKind.Constructor && (<ConstructorDeclaration>m).body && <ConstructorDeclaration>m);
|
||||
return constructorDecl.body.getFirstToken();
|
||||
}
|
||||
function createTestSuperCall() {
|
||||
const superCall = createCall(
|
||||
createSuper(),
|
||||
|
||||
function findOpenBraceForConstructor(sourceFile: SourceFile) {
|
||||
const classDecl = <ClassDeclaration>sourceFile.statements[0];
|
||||
const constructorDecl = forEach(classDecl.members, m => m.kind === SyntaxKind.Constructor && (<ConstructorDeclaration>m).body && <ConstructorDeclaration>m);
|
||||
return constructorDecl.body.getFirstToken();
|
||||
}
|
||||
function createTestSuperCall() {
|
||||
const superCall = createCall(
|
||||
createSuper(),
|
||||
/*typeArguments*/ undefined,
|
||||
/*argumentsArray*/ emptyArray
|
||||
);
|
||||
return createStatement(superCall);
|
||||
}
|
||||
);
|
||||
return createStatement(superCall);
|
||||
}
|
||||
|
||||
{
|
||||
const text1 = `
|
||||
class A {
|
||||
constructor() {
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace ts {
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
context.onSubstituteNode = (hint, node) => {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression && node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "undefined") {
|
||||
if (hint === EmitHint.Expression && isIdentifier(node) && node.escapedText === "undefined") {
|
||||
node = createPartiallyEmittedExpression(
|
||||
addSyntheticTrailingComment(
|
||||
setTextRange(
|
||||
@@ -26,7 +26,7 @@ namespace ts {
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
context.onSubstituteNode = (hint, node) => {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "oldName") {
|
||||
if (isIdentifier(node) && node.escapedText === "oldName") {
|
||||
node = setTextRange(createIdentifier("newName"), node);
|
||||
}
|
||||
return node;
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace ts {
|
||||
|
||||
transpileOptions.reportDiagnostics = true;
|
||||
|
||||
justName = "transpile/" + name.replace(/[^a-z0-9\-. ]/ig, "") + (transpileOptions.compilerOptions.jsx ? ".tsx" : ".ts");
|
||||
justName = "transpile/" + name.replace(/[^a-z0-9\-. ]/ig, "") + (transpileOptions.compilerOptions.jsx ? Extension.Tsx : Extension.Ts);
|
||||
toBeCompiled = [{
|
||||
unitName: transpileOptions.fileName,
|
||||
content: input
|
||||
@@ -88,7 +88,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
it("Correct output for " + justName, () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ".js"), () => {
|
||||
Harness.Baseline.runBaseline(justName.replace(/\.tsx?$/, ts.Extension.Js), () => {
|
||||
if (transpileResult.outputText) {
|
||||
return transpileResult.outputText;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user