mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into enum_member
This commit is contained in:
@@ -57,3 +57,4 @@ internal/
|
||||
!tests/cases/projects/NodeModulesSearch/**/*
|
||||
!tests/baselines/reference/project/nodeModules*/**/*
|
||||
.idea
|
||||
yarn.lock
|
||||
@@ -17,6 +17,7 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.1
|
||||
- release-2.2
|
||||
|
||||
install:
|
||||
- npm uninstall typescript
|
||||
|
||||
+23
-13
@@ -21,10 +21,6 @@ declare module "gulp-typescript" {
|
||||
import * as insert from "gulp-insert";
|
||||
import * as sourcemaps from "gulp-sourcemaps";
|
||||
import Q = require("q");
|
||||
declare global {
|
||||
// `del` further depends on `Promise` (and is also not included), so we just, patch the global scope's Promise to Q's (which we already include in our deps because gulp depends on it)
|
||||
type Promise<T> = Q.Promise<T>;
|
||||
}
|
||||
import del = require("del");
|
||||
import mkdirP = require("mkdirp");
|
||||
import minimist = require("minimist");
|
||||
@@ -41,7 +37,7 @@ const {runTestsInParallel} = mochaParallel;
|
||||
Error.stackTraceLimit = 1000;
|
||||
|
||||
const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
boolean: ["debug", "light", "colors", "lint", "soft"],
|
||||
boolean: ["debug", "inspect", "light", "colors", "lint", "soft"],
|
||||
string: ["browser", "tests", "host", "reporter", "stackTraceLimit"],
|
||||
alias: {
|
||||
d: "debug",
|
||||
@@ -57,6 +53,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
soft: false,
|
||||
colors: process.env.colors || process.env.color || true,
|
||||
debug: process.env.debug || process.env.d,
|
||||
inspect: process.env.inspect,
|
||||
host: process.env.TYPESCRIPT_HOST || process.env.host || "node",
|
||||
browser: process.env.browser || process.env.b || "IE",
|
||||
tests: process.env.test || process.env.tests || process.env.t,
|
||||
@@ -138,6 +135,14 @@ const es2017LibrarySourceMap = es2017LibrarySource.map(function(source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
const esnextLibrarySource = [
|
||||
"esnext.asynciterable.d.ts"
|
||||
];
|
||||
|
||||
const esnextLibrarySourceMap = esnextLibrarySource.map(function (source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
const hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"];
|
||||
|
||||
const librarySourceMap = [
|
||||
@@ -152,11 +157,12 @@ const librarySourceMap = [
|
||||
{ target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] },
|
||||
{ target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] },
|
||||
{ target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] },
|
||||
{ target: "lib.esnext.d.ts", sources: ["header.d.ts", "esnext.d.ts"] },
|
||||
|
||||
// JavaScript + all host library
|
||||
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
|
||||
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") }
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap);
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap, esnextLibrarySourceMap);
|
||||
|
||||
const libraryTargets = librarySourceMap.map(function(f) {
|
||||
return path.join(builtLocalDirectory, f.target);
|
||||
@@ -384,7 +390,7 @@ gulp.task(builtLocalCompiler, false, [servicesFile], () => {
|
||||
.pipe(localCompilerProject())
|
||||
.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(gulp.dest("src/compiler"));
|
||||
});
|
||||
|
||||
gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => {
|
||||
@@ -416,7 +422,7 @@ gulp.task(servicesFile, false, ["lib", "generate-diagnostics"], () => {
|
||||
file.path = nodeStandaloneDefinitionsFile;
|
||||
return content.replace(/declare (namespace|module) ts/g, 'declare module "typescript"');
|
||||
}))
|
||||
]).pipe(gulp.dest("."));
|
||||
]).pipe(gulp.dest("src/services"));
|
||||
});
|
||||
|
||||
// cancellationToken.js
|
||||
@@ -442,7 +448,7 @@ gulp.task(typingsInstallerJs, false, [servicesFile], () => {
|
||||
.pipe(cancellationTokenProject())
|
||||
.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(gulp.dest("src/server/typingsInstaller"));
|
||||
});
|
||||
|
||||
const serverFile = path.join(builtLocalDirectory, "tsserver.js");
|
||||
@@ -455,7 +461,7 @@ gulp.task(serverFile, false, [servicesFile, typingsInstallerJs, cancellationToke
|
||||
.pipe(serverProject())
|
||||
.pipe(prependCopyright())
|
||||
.pipe(sourcemaps.write("."))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(gulp.dest("src/server"));
|
||||
});
|
||||
|
||||
const tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
|
||||
@@ -550,7 +556,7 @@ gulp.task(run, false, [servicesFile], () => {
|
||||
.pipe(sourcemaps.init())
|
||||
.pipe(testProject())
|
||||
.pipe(sourcemaps.write(".", { includeContent: false, sourceRoot: "../../" }))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(gulp.dest("src/harness"));
|
||||
});
|
||||
|
||||
const internalTests = "internal/";
|
||||
@@ -588,6 +594,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
cleanTestDirs((err) => {
|
||||
if (err) { console.error(err); failWithStatus(err, 1); }
|
||||
const debug = cmdLineOptions["debug"];
|
||||
const inspect = cmdLineOptions["inspect"];
|
||||
const tests = cmdLineOptions["tests"];
|
||||
const light = cmdLineOptions["light"];
|
||||
const stackTraceLimit = cmdLineOptions["stackTraceLimit"];
|
||||
@@ -624,7 +631,10 @@ 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 (debug) {
|
||||
if (inspect) {
|
||||
args.push("--inspect");
|
||||
}
|
||||
if (inspect || debug) {
|
||||
args.push("--debug-brk");
|
||||
}
|
||||
args.push("-R", reporter);
|
||||
@@ -768,7 +778,7 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo
|
||||
});
|
||||
}))
|
||||
.pipe(sourcemaps.write(".", { includeContent: false }))
|
||||
.pipe(gulp.dest("."));
|
||||
.pipe(gulp.dest("src/harness"));
|
||||
});
|
||||
|
||||
|
||||
|
||||
+50
-12
@@ -15,6 +15,7 @@ var servicesDirectory = "src/services/";
|
||||
var serverDirectory = "src/server/";
|
||||
var typingsInstallerDirectory = "src/server/typingsInstaller";
|
||||
var cancellationTokenDirectory = "src/server/cancellationToken";
|
||||
var watchGuardDirectory = "src/server/watchGuard";
|
||||
var harnessDirectory = "src/harness/";
|
||||
var libraryDirectory = "src/lib/";
|
||||
var scriptsDirectory = "scripts/";
|
||||
@@ -80,6 +81,7 @@ var compilerSources = filesFromConfig("./src/compiler/tsconfig.json");
|
||||
var servicesSources = filesFromConfig("./src/services/tsconfig.json");
|
||||
var cancellationTokenSources = filesFromConfig(path.join(serverDirectory, "cancellationToken/tsconfig.json"));
|
||||
var typingsInstallerSources = filesFromConfig(path.join(serverDirectory, "typingsInstaller/tsconfig.json"));
|
||||
var watchGuardSources = filesFromConfig(path.join(serverDirectory, "watchGuard/tsconfig.json"));
|
||||
var serverSources = filesFromConfig(path.join(serverDirectory, "tsconfig.json"))
|
||||
var languageServiceLibrarySources = filesFromConfig(path.join(serverDirectory, "tsconfig.library.json"));
|
||||
|
||||
@@ -129,6 +131,8 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"matchFiles.ts",
|
||||
"initializeTSConfig.ts",
|
||||
"printer.ts",
|
||||
"transform.ts",
|
||||
"customTransforms.ts",
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
@@ -170,13 +174,21 @@ var es2016LibrarySourceMap = es2016LibrarySource.map(function (source) {
|
||||
var es2017LibrarySource = [
|
||||
"es2017.object.d.ts",
|
||||
"es2017.sharedmemory.d.ts",
|
||||
"es2017.string.d.ts",
|
||||
"es2017.string.d.ts"
|
||||
];
|
||||
|
||||
var es2017LibrarySourceMap = es2017LibrarySource.map(function (source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
var esnextLibrarySource = [
|
||||
"esnext.asynciterable.d.ts"
|
||||
];
|
||||
|
||||
var esnextLibrarySourceMap = esnextLibrarySource.map(function (source) {
|
||||
return { target: "lib." + source, sources: ["header.d.ts", source] };
|
||||
});
|
||||
|
||||
var hostsLibrarySources = ["dom.generated.d.ts", "webworker.importscripts.d.ts", "scripthost.d.ts"];
|
||||
|
||||
var librarySourceMap = [
|
||||
@@ -191,11 +203,12 @@ var librarySourceMap = [
|
||||
{ target: "lib.es2015.d.ts", sources: ["header.d.ts", "es2015.d.ts"] },
|
||||
{ target: "lib.es2016.d.ts", sources: ["header.d.ts", "es2016.d.ts"] },
|
||||
{ target: "lib.es2017.d.ts", sources: ["header.d.ts", "es2017.d.ts"] },
|
||||
{ target: "lib.esnext.d.ts", sources: ["header.d.ts", "esnext.d.ts"] },
|
||||
|
||||
// JavaScript + all host library
|
||||
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
|
||||
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") }
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap);
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap, esnextLibrarySourceMap);
|
||||
|
||||
var libraryTargets = librarySourceMap.map(function (f) {
|
||||
return path.join(builtLocalDirectory, f.target);
|
||||
@@ -570,8 +583,11 @@ compileFile(cancellationTokenFile, cancellationTokenSources, [builtLocalDirector
|
||||
var typingsInstallerFile = path.join(builtLocalDirectory, "typingsInstaller.js");
|
||||
compileFile(typingsInstallerFile, typingsInstallerSources, [builtLocalDirectory].concat(typingsInstallerSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: false });
|
||||
|
||||
var watchGuardFile = path.join(builtLocalDirectory, "watchGuard.js");
|
||||
compileFile(watchGuardFile, watchGuardSources, [builtLocalDirectory].concat(watchGuardSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { outDir: builtLocalDirectory, noOutFile: false });
|
||||
|
||||
var serverFile = path.join(builtLocalDirectory, "tsserver.js");
|
||||
compileFile(serverFile, serverSources, [builtLocalDirectory, copyright, cancellationTokenFile, typingsInstallerFile].concat(serverSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"] });
|
||||
compileFile(serverFile, serverSources, [builtLocalDirectory, copyright, cancellationTokenFile, typingsInstallerFile, watchGuardFile].concat(serverSources).concat(servicesSources), /*prefixes*/ [copyright], /*useBuiltCompiler*/ true, { types: ["node"], preserveConstEnums: true });
|
||||
var tsserverLibraryFile = path.join(builtLocalDirectory, "tsserverlibrary.js");
|
||||
var tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverlibrary.d.ts");
|
||||
compileFile(
|
||||
@@ -580,7 +596,7 @@ compileFile(
|
||||
[builtLocalDirectory, copyright, builtLocalCompiler].concat(languageServiceLibrarySources).concat(libraryTargets),
|
||||
/*prefixes*/[copyright],
|
||||
/*useBuiltCompiler*/ true,
|
||||
{ noOutFile: false, generateDeclarations: true, stripInternal: true },
|
||||
{ noOutFile: false, generateDeclarations: true, stripInternal: true, preserveConstEnums: true },
|
||||
/*callback*/ function () {
|
||||
prependFile(copyright, tsserverLibraryDefinitionFile);
|
||||
|
||||
@@ -665,7 +681,7 @@ task("generate-spec", [specMd]);
|
||||
// Makes a new LKG. This target does not build anything, but errors if not all the outputs are present in the built/local directory
|
||||
desc("Makes a new LKG out of the built js files");
|
||||
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () {
|
||||
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts].concat(libraryTargets);
|
||||
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts, watchGuardFile].concat(libraryTargets);
|
||||
var missingFiles = expectedFiles.filter(function (f) {
|
||||
return !fs.existsSync(f);
|
||||
});
|
||||
@@ -778,6 +794,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
}
|
||||
|
||||
var debug = process.env.debug || process.env.d;
|
||||
var inspect = process.env.inspect;
|
||||
tests = process.env.test || process.env.tests || process.env.t;
|
||||
var light = process.env.light || false;
|
||||
var stackTraceLimit = process.env.stackTraceLimit;
|
||||
@@ -807,18 +824,39 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
testTimeout = 800000;
|
||||
}
|
||||
|
||||
colors = process.env.colors || process.env.color;
|
||||
colors = colors ? ' --no-colors ' : ' --colors ';
|
||||
reporter = process.env.reporter || process.env.r || defaultReporter;
|
||||
var bail = (process.env.bail || process.env.b) ? "--bail" : "";
|
||||
var colors = process.env.colors || process.env.color || true;
|
||||
var reporter = process.env.reporter || process.env.r || defaultReporter;
|
||||
var bail = process.env.bail || process.env.b;
|
||||
var lintFlag = process.env.lint !== 'false';
|
||||
|
||||
// timeout normally isn't necessary but Travis-CI has been timing out on compiler baselines occasionally
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
var startTime = mark();
|
||||
tests = tests ? ' -g "' + tests + '"' : '';
|
||||
var cmd = "mocha" + (debug ? " --debug-brk" : "") + " -R " + reporter + tests + colors + bail + ' -t ' + testTimeout + ' ' + run;
|
||||
var args = [];
|
||||
if (inspect) {
|
||||
args.push("--inspect");
|
||||
}
|
||||
if (inspect || debug) {
|
||||
args.push("--debug-brk");
|
||||
}
|
||||
args.push("-R", reporter);
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
}
|
||||
if (colors) {
|
||||
args.push("--colors");
|
||||
}
|
||||
else {
|
||||
args.push("--no-colors");
|
||||
}
|
||||
if (bail) {
|
||||
args.push("--bail");
|
||||
}
|
||||
args.push("-t", testTimeout);
|
||||
args.push(run);
|
||||
|
||||
var cmd = "mocha " + args.join(" ");
|
||||
console.log(cmd);
|
||||
|
||||
var savedNodeEnv = process.env.NODE_ENV;
|
||||
@@ -839,7 +877,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
var savedNodeEnv = process.env.NODE_ENV;
|
||||
process.env.NODE_ENV = "development";
|
||||
var startTime = mark();
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: colors === " --no-colors " }, function (err) {
|
||||
runTestsInParallel(taskConfigsFolder, run, { testTimeout: testTimeout, noColors: !colors }, function (err) {
|
||||
process.env.NODE_ENV = savedNodeEnv;
|
||||
measure(startTime);
|
||||
// last worker clean everything and runs linter in case if there were no errors
|
||||
|
||||
+41
-11
@@ -15,6 +15,15 @@ and limitations under the License.
|
||||
|
||||
"use strict";
|
||||
var fs = require("fs");
|
||||
function pipeExists(name) {
|
||||
try {
|
||||
fs.statSync(name);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function createCancellationToken(args) {
|
||||
var cancellationPipeName;
|
||||
for (var i = 0; i < args.length - 1; i++) {
|
||||
@@ -24,18 +33,39 @@ function createCancellationToken(args) {
|
||||
}
|
||||
}
|
||||
if (!cancellationPipeName) {
|
||||
return { isCancellationRequested: function () { return false; } };
|
||||
return {
|
||||
isCancellationRequested: function () { return false; },
|
||||
setRequest: function (_requestId) { return void 0; },
|
||||
resetRequest: function (_requestId) { return void 0; }
|
||||
};
|
||||
}
|
||||
return {
|
||||
isCancellationRequested: function () {
|
||||
try {
|
||||
fs.statSync(cancellationPipeName);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
if (cancellationPipeName.charAt(cancellationPipeName.length - 1) === "*") {
|
||||
var namePrefix_1 = cancellationPipeName.slice(0, -1);
|
||||
if (namePrefix_1.length === 0 || namePrefix_1.indexOf("*") >= 0) {
|
||||
throw new Error("Invalid name for template cancellation pipe: it should have length greater than 2 characters and contain only one '*'.");
|
||||
}
|
||||
};
|
||||
var perRequestPipeName_1;
|
||||
var currentRequestId_1;
|
||||
return {
|
||||
isCancellationRequested: function () { return perRequestPipeName_1 !== undefined && pipeExists(perRequestPipeName_1); },
|
||||
setRequest: function (requestId) {
|
||||
currentRequestId_1 = currentRequestId_1;
|
||||
perRequestPipeName_1 = namePrefix_1 + requestId;
|
||||
},
|
||||
resetRequest: function (requestId) {
|
||||
if (currentRequestId_1 !== requestId) {
|
||||
throw new Error("Mismatched request id, expected " + currentRequestId_1 + ", actual " + requestId);
|
||||
}
|
||||
perRequestPipeName_1 = undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
isCancellationRequested: function () { return pipeExists(cancellationPipeName); },
|
||||
setRequest: function (_requestId) { return void 0; },
|
||||
resetRequest: function (_requestId) { return void 0; }
|
||||
};
|
||||
}
|
||||
}
|
||||
module.exports = createCancellationToken;
|
||||
|
||||
Vendored
+1599
-418
File diff suppressed because it is too large
Load Diff
Vendored
+1583
-384
File diff suppressed because it is too large
Load Diff
Vendored
+4
-4
@@ -24,7 +24,7 @@ interface Map<K, V> {
|
||||
forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void;
|
||||
get(key: K): V | undefined;
|
||||
has(key: K): boolean;
|
||||
set(key: K, value?: V): this;
|
||||
set(key: K, value: V): this;
|
||||
readonly size: number;
|
||||
}
|
||||
|
||||
@@ -42,16 +42,16 @@ interface ReadonlyMap<K, V> {
|
||||
readonly size: number;
|
||||
}
|
||||
|
||||
interface WeakMap<K, V> {
|
||||
interface WeakMap<K extends object, V> {
|
||||
delete(key: K): boolean;
|
||||
get(key: K): V | undefined;
|
||||
has(key: K): boolean;
|
||||
set(key: K, value?: V): this;
|
||||
set(key: K, value: V): this;
|
||||
}
|
||||
|
||||
interface WeakMapConstructor {
|
||||
new (): WeakMap<any, any>;
|
||||
new <K, V>(entries?: [K, V][]): WeakMap<K, V>;
|
||||
new <K extends object, V>(entries?: [K, V][]): WeakMap<K, V>;
|
||||
readonly prototype: WeakMap<any, any>;
|
||||
}
|
||||
declare var WeakMap: WeakMapConstructor;
|
||||
|
||||
Vendored
+1
-1
@@ -345,7 +345,7 @@ interface ObjectConstructor {
|
||||
* @param o The object to change its prototype.
|
||||
* @param proto The value of the new prototype or null.
|
||||
*/
|
||||
setPrototypeOf(o: any, proto: any): any;
|
||||
setPrototypeOf(o: any, proto: object | null): any;
|
||||
|
||||
/**
|
||||
* Gets the own property descriptor of the specified object.
|
||||
|
||||
Vendored
+3
-3
@@ -119,10 +119,10 @@ interface MapConstructor {
|
||||
new <K, V>(iterable: Iterable<[K, V]>): Map<K, V>;
|
||||
}
|
||||
|
||||
interface WeakMap<K, V> { }
|
||||
interface WeakMap<K extends object, V> { }
|
||||
|
||||
interface WeakMapConstructor {
|
||||
new <K, V>(iterable: Iterable<[K, V]>): WeakMap<K, V>;
|
||||
new <K extends object, V>(iterable: Iterable<[K, V]>): WeakMap<K, V>;
|
||||
}
|
||||
|
||||
interface Set<T> {
|
||||
@@ -462,4 +462,4 @@ interface Float64ArrayConstructor {
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Float64Array;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
-51
@@ -18,57 +18,6 @@ and limitations under the License.
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
interface Promise<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then(onfulfilled?: ((value: T) => T | PromiseLike<T>) | undefined | null, onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: ((value: T) => T | PromiseLike<T>) | undefined | null, onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: (value: T) => TResult | PromiseLike<TResult>, onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult1, TResult2>(onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): Promise<TResult1 | TResult2>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch(onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch<TResult>(onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
|
||||
}
|
||||
|
||||
interface PromiseConstructor {
|
||||
/**
|
||||
* A reference to the prototype.
|
||||
|
||||
Vendored
+2
-2
@@ -19,7 +19,7 @@ and limitations under the License.
|
||||
|
||||
|
||||
interface ProxyHandler<T> {
|
||||
getPrototypeOf? (target: T): {} | null;
|
||||
getPrototypeOf? (target: T): object | null;
|
||||
setPrototypeOf? (target: T, v: any): boolean;
|
||||
isExtensible? (target: T): boolean;
|
||||
preventExtensions? (target: T): boolean;
|
||||
@@ -32,7 +32,7 @@ interface ProxyHandler<T> {
|
||||
enumerate? (target: T): PropertyKey[];
|
||||
ownKeys? (target: T): PropertyKey[];
|
||||
apply? (target: T, thisArg: any, argArray?: any): any;
|
||||
construct? (target: T, argArray: any, newTarget?: any): {};
|
||||
construct? (target: T, argArray: any, newTarget?: any): object
|
||||
}
|
||||
|
||||
interface ProxyConstructor {
|
||||
|
||||
Vendored
+1
-1
@@ -23,7 +23,7 @@ interface Symbol {
|
||||
toString(): string;
|
||||
|
||||
/** Returns the primitive value of the specified object. */
|
||||
valueOf(): Object;
|
||||
valueOf(): symbol;
|
||||
}
|
||||
|
||||
interface SymbolConstructor {
|
||||
|
||||
Vendored
+2
-2
@@ -130,7 +130,7 @@ interface Map<K, V> {
|
||||
readonly [Symbol.toStringTag]: "Map";
|
||||
}
|
||||
|
||||
interface WeakMap<K, V>{
|
||||
interface WeakMap<K extends object, V>{
|
||||
readonly [Symbol.toStringTag]: "WeakMap";
|
||||
}
|
||||
|
||||
@@ -344,4 +344,4 @@ interface Float32Array {
|
||||
*/
|
||||
interface Float64Array {
|
||||
readonly [Symbol.toStringTag]: "Float64Array";
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+16
-34
@@ -157,23 +157,17 @@ interface ObjectConstructor {
|
||||
getOwnPropertyNames(o: any): string[];
|
||||
|
||||
/**
|
||||
* Creates an object that has null prototype.
|
||||
* @param o Object to use as a prototype. May be null
|
||||
* Creates an object that has the specified prototype or that has null prototype.
|
||||
* @param o Object to use as a prototype. May be null.
|
||||
*/
|
||||
create(o: null): any;
|
||||
|
||||
/**
|
||||
* Creates an object that has the specified prototype, and that optionally contains specified properties.
|
||||
* @param o Object to use as a prototype. May be null
|
||||
*/
|
||||
create<T>(o: T): T;
|
||||
create<T extends object>(o: T | null): T | object;
|
||||
|
||||
/**
|
||||
* Creates an object that has the specified prototype, and that optionally contains specified properties.
|
||||
* @param o Object to use as a prototype. May be null
|
||||
* @param properties JavaScript object that contains one or more property descriptors.
|
||||
*/
|
||||
create(o: any, properties: PropertyDescriptorMap): any;
|
||||
create(o: object | null, properties: PropertyDescriptorMap): any;
|
||||
|
||||
/**
|
||||
* Adds a property to an object, or modifies attributes of an existing property.
|
||||
@@ -361,14 +355,14 @@ interface String {
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using a regular expression or search string.
|
||||
* @param searchValue A string that represents the regular expression.
|
||||
* @param searchValue A string to search for.
|
||||
* @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.
|
||||
*/
|
||||
replace(searchValue: string, replaceValue: string): string;
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using a regular expression or search string.
|
||||
* @param searchValue A string that represents the regular expression.
|
||||
* @param searchValue A string to search for.
|
||||
* @param replacer A function that returns the replacement text.
|
||||
*/
|
||||
replace(searchValue: string, replacer: (substring: string, ...args: any[]) => string): string;
|
||||
@@ -1336,39 +1330,27 @@ interface PromiseLike<T> {
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then(
|
||||
onfulfilled?: ((value: T) => T | PromiseLike<T>) | undefined | null,
|
||||
onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): PromiseLike<T>;
|
||||
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
interface Promise<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(
|
||||
onfulfilled: ((value: T) => T | PromiseLike<T>) | undefined | null,
|
||||
onrejected: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<T | TResult>;
|
||||
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
then<TResult>(
|
||||
onfulfilled: (value: T) => TResult | PromiseLike<TResult>,
|
||||
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): PromiseLike<TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult1, TResult2>(
|
||||
onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>,
|
||||
onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
|
||||
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
|
||||
}
|
||||
|
||||
interface ArrayLike<T> {
|
||||
|
||||
Vendored
+1611
-479
File diff suppressed because it is too large
Load Diff
Vendored
+636
-161
File diff suppressed because it is too large
Load Diff
Vendored
+32
-6
@@ -734,9 +734,9 @@ declare namespace ts.server.protocol {
|
||||
*/
|
||||
formatOptions?: FormatCodeSettings;
|
||||
/**
|
||||
* The host's additional supported file extensions
|
||||
* The host's additional supported .js file extensions
|
||||
*/
|
||||
extraFileExtensions?: FileExtensionInfo[];
|
||||
extraFileExtensions?: JsFileExtensionInfo[];
|
||||
}
|
||||
/**
|
||||
* Configure request; value of command field is "configure". Specifies
|
||||
@@ -905,6 +905,10 @@ declare namespace ts.server.protocol {
|
||||
* List of files names that should be recompiled
|
||||
*/
|
||||
fileNames: string[];
|
||||
/**
|
||||
* true if project uses outFile or out compiler option
|
||||
*/
|
||||
projectUsesOutFile: boolean;
|
||||
}
|
||||
/**
|
||||
* Response for CompileOnSaveAffectedFileListRequest request;
|
||||
@@ -1352,6 +1356,17 @@ declare namespace ts.server.protocol {
|
||||
command: CommandTypes.Geterr;
|
||||
arguments: GeterrRequestArgs;
|
||||
}
|
||||
type RequestCompletedEventName = "requestCompleted";
|
||||
/**
|
||||
* Event that is sent when server have finished processing request with specified id.
|
||||
*/
|
||||
interface RequestCompletedEvent extends Event {
|
||||
event: RequestCompletedEventName;
|
||||
body: RequestCompletedEventBody;
|
||||
}
|
||||
interface RequestCompletedEventBody {
|
||||
request_seq: number;
|
||||
}
|
||||
/**
|
||||
* Item of diagnostic information found in a DiagnosticEvent message.
|
||||
*/
|
||||
@@ -1727,6 +1742,7 @@ declare namespace ts.server.protocol {
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
insertSpaceBeforeFunctionParenthesis?: boolean;
|
||||
@@ -1775,6 +1791,7 @@ declare namespace ts.server.protocol {
|
||||
outDir?: string;
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
plugins?: PluginImport[];
|
||||
preserveConstEnums?: boolean;
|
||||
project?: string;
|
||||
reactNamespace?: string;
|
||||
@@ -1798,9 +1815,10 @@ declare namespace ts.server.protocol {
|
||||
namespace JsxEmit {
|
||||
type None = "None";
|
||||
type Preserve = "Preserve";
|
||||
type ReactNative = "ReactNative";
|
||||
type React = "React";
|
||||
}
|
||||
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
|
||||
type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React | JsxEmit.ReactNative;
|
||||
namespace ModuleKind {
|
||||
type None = "None";
|
||||
type CommonJS = "CommonJS";
|
||||
@@ -1856,17 +1874,25 @@ declare namespace ts.server.protocol {
|
||||
[option: string]: string[] | boolean | undefined;
|
||||
}
|
||||
|
||||
interface FileExtensionInfo {
|
||||
interface JsFileExtensionInfo {
|
||||
extension: string;
|
||||
scriptKind: ScriptKind;
|
||||
isMixedContent: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of objects whose values are all of the same type.
|
||||
* The `in` and `for-in` operators can *not* be safely used,
|
||||
* since `Object.prototype` may be modified by outside code.
|
||||
*/
|
||||
interface MapLike<T> {
|
||||
[index: string]: T;
|
||||
}
|
||||
|
||||
type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]>;
|
||||
interface PluginImport {
|
||||
name: string;
|
||||
}
|
||||
|
||||
type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[];
|
||||
}
|
||||
declare namespace ts {
|
||||
// these types are empty stubs for types from services and should not be used directly
|
||||
|
||||
+8912
-7676
File diff suppressed because it is too large
Load Diff
+22809
-19692
File diff suppressed because it is too large
Load Diff
Vendored
+975
-546
File diff suppressed because it is too large
Load Diff
+14880
-11770
File diff suppressed because it is too large
Load Diff
Vendored
+750
-210
File diff suppressed because it is too large
Load Diff
+13683
-12035
File diff suppressed because it is too large
Load Diff
Vendored
+750
-210
File diff suppressed because it is too large
Load Diff
+13683
-12035
File diff suppressed because it is too large
Load Diff
+472
-348
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -2,7 +2,7 @@
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "http://typescriptlang.org/",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
@@ -60,7 +60,7 @@
|
||||
"gulp-insert": "latest",
|
||||
"gulp-newer": "latest",
|
||||
"gulp-sourcemaps": "latest",
|
||||
"gulp-typescript": "3.1.3",
|
||||
"gulp-typescript": "3.1.5",
|
||||
"into-stream": "latest",
|
||||
"istanbul": "latest",
|
||||
"jake": "latest",
|
||||
|
||||
@@ -167,7 +167,7 @@ function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string)
|
||||
const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
|
||||
const diagnostics = [...sanityCheckProgram.getSyntacticDiagnostics(), ...sanityCheckProgram.getSemanticDiagnostics(), ...sanityCheckProgram.getGlobalDiagnostics()];
|
||||
if (diagnostics.length) {
|
||||
const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n");
|
||||
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;
|
||||
|
||||
+138
-30
@@ -265,6 +265,7 @@ namespace ts {
|
||||
return "export=";
|
||||
case SpecialPropertyAssignmentKind.ExportsProperty:
|
||||
case SpecialPropertyAssignmentKind.ThisProperty:
|
||||
case SpecialPropertyAssignmentKind.Property:
|
||||
// exports.x = ... or this.y = ...
|
||||
return ((node as BinaryExpression).left as PropertyAccessExpression).name.text;
|
||||
case SpecialPropertyAssignmentKind.PrototypeProperty:
|
||||
@@ -669,6 +670,12 @@ namespace ts {
|
||||
case SyntaxKind.CallExpression:
|
||||
bindCallExpressionFlow(<CallExpression>node);
|
||||
break;
|
||||
case SyntaxKind.JSDocComment:
|
||||
bindJSDocComment(<JSDoc>node);
|
||||
break;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
bindJSDocTypedefTag(<JSDocTypedefTag>node);
|
||||
break;
|
||||
default:
|
||||
bindEachChild(node);
|
||||
break;
|
||||
@@ -956,6 +963,9 @@ namespace ts {
|
||||
const postLoopLabel = createBranchLabel();
|
||||
addAntecedent(preLoopLabel, currentFlow);
|
||||
currentFlow = preLoopLabel;
|
||||
if (node.kind === SyntaxKind.ForOfStatement) {
|
||||
bind(node.awaitModifier);
|
||||
}
|
||||
bind(node.expression);
|
||||
addAntecedent(postLoopLabel, currentFlow);
|
||||
bind(node.initializer);
|
||||
@@ -1051,8 +1061,8 @@ namespace ts {
|
||||
// second -> edge that represents post-finally flow.
|
||||
// these edges are used in following scenario:
|
||||
// let a; (1)
|
||||
// try { a = someOperation(); (2)}
|
||||
// finally { (3) console.log(a) } (4)
|
||||
// try { a = someOperation(); (2)}
|
||||
// finally { (3) console.log(a) } (4)
|
||||
// (5) a
|
||||
|
||||
// flow graph for this case looks roughly like this (arrows show ):
|
||||
@@ -1064,11 +1074,11 @@ namespace ts {
|
||||
// In case when we walk the flow starting from inside the finally block we want to take edge '*****' into account
|
||||
// since it ensures that finally is always reachable. However when we start outside the finally block and go through label (5)
|
||||
// then edge '*****' should be discarded because label 4 is only reachable if post-finally label-4 is reachable
|
||||
// Simply speaking code inside finally block is treated as reachable as pre-try-flow
|
||||
// Simply speaking code inside finally block is treated as reachable as pre-try-flow
|
||||
// since we conservatively assume that any line in try block can throw or return in which case we'll enter finally.
|
||||
// However code after finally is reachable only if control flow was not abrupted in try/catch or finally blocks - it should be composed from
|
||||
// final flows of these blocks without taking pre-try flow into account.
|
||||
//
|
||||
//
|
||||
// extra edges that we inject allows to control this behavior
|
||||
// if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped.
|
||||
const preFinallyFlow: PreFinallyFlow = { flags: FlowFlags.PreFinally, antecedent: preTryFlow, lock: {} };
|
||||
@@ -1331,6 +1341,26 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function bindJSDocComment(node: JSDoc) {
|
||||
forEachChild(node, n => {
|
||||
if (n.kind !== SyntaxKind.JSDocTypedefTag) {
|
||||
bind(n);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function bindJSDocTypedefTag(node: JSDocTypedefTag) {
|
||||
forEachChild(node, n => {
|
||||
// if the node has a fullName "A.B.C", that means symbol "C" was already bound
|
||||
// when we visit "fullName"; so when we visit the name "C" as the next child of
|
||||
// the jsDocTypedefTag, we should skip binding it.
|
||||
if (node.fullName && n === node.name && node.fullName.kind !== SyntaxKind.Identifier) {
|
||||
return;
|
||||
}
|
||||
bind(n);
|
||||
});
|
||||
}
|
||||
|
||||
function bindCallExpressionFlow(node: CallExpression) {
|
||||
// If the target of the call expression is a function expression or arrow function we have
|
||||
// an immediately invoked function expression (IIFE). Initialize the flowNode property to
|
||||
@@ -1364,6 +1394,7 @@ namespace ts {
|
||||
case SyntaxKind.TypeLiteral:
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
case SyntaxKind.JSDocRecordType:
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return ContainerFlags.IsContainer;
|
||||
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
@@ -1470,6 +1501,7 @@ namespace ts {
|
||||
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
|
||||
// container, and are never in scope otherwise (even inside the body of the
|
||||
@@ -1659,6 +1691,14 @@ namespace ts {
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__object");
|
||||
}
|
||||
|
||||
function bindJsxAttributes(node: JsxAttributes) {
|
||||
return bindAnonymousDeclaration(node, SymbolFlags.ObjectLiteral, "__jsxAttributes");
|
||||
}
|
||||
|
||||
function bindJsxAttribute(node: JsxAttribute, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
|
||||
}
|
||||
|
||||
function bindAnonymousDeclaration(node: Declaration, symbolFlags: SymbolFlags, name: string) {
|
||||
const symbol = createSymbol(symbolFlags, name);
|
||||
addDeclarationToSymbol(symbol, node, symbolFlags);
|
||||
@@ -1860,6 +1900,18 @@ namespace ts {
|
||||
}
|
||||
node.parent = parent;
|
||||
const saveInStrictMode = inStrictMode;
|
||||
|
||||
// Even though in the AST the jsdoc @typedef node belongs to the current node,
|
||||
// its symbol might be in the same scope with the current node's symbol. Consider:
|
||||
//
|
||||
// /** @typedef {string | number} MyType */
|
||||
// function foo();
|
||||
//
|
||||
// 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);
|
||||
|
||||
// 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
|
||||
// destination symbol tables are:
|
||||
@@ -1894,6 +1946,27 @@ namespace ts {
|
||||
inStrictMode = saveInStrictMode;
|
||||
}
|
||||
|
||||
function bindJSDocTypedefTagIfAny(node: Node) {
|
||||
if (!node.jsDoc) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const jsDoc of node.jsDoc) {
|
||||
if (!jsDoc.tags) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const tag of jsDoc.tags) {
|
||||
if (tag.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
const savedParent = parent;
|
||||
parent = jsDoc;
|
||||
bind(tag);
|
||||
parent = savedParent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateStrictModeStatementList(statements: NodeArray<Statement>) {
|
||||
if (!inStrictMode) {
|
||||
for (const statement of statements) {
|
||||
@@ -1959,6 +2032,9 @@ namespace ts {
|
||||
case SpecialPropertyAssignmentKind.ThisProperty:
|
||||
bindThisPropertyAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.Property:
|
||||
bindStaticPropertyAssignment(<BinaryExpression>node);
|
||||
break;
|
||||
case SpecialPropertyAssignmentKind.None:
|
||||
// Nothing to do
|
||||
break;
|
||||
@@ -2080,6 +2156,12 @@ namespace ts {
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return bindModuleDeclaration(<ModuleDeclaration>node);
|
||||
|
||||
// Jsx-attributes
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return bindJsxAttributes(<JsxAttributes>node);
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return bindJsxAttribute(<JsxAttribute>node, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
|
||||
// Imports and exports
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
case SyntaxKind.NamespaceImport:
|
||||
@@ -2249,18 +2331,41 @@ namespace ts {
|
||||
constructorFunction.parent = classPrototype;
|
||||
classPrototype.parent = leftSideOfAssignment;
|
||||
|
||||
const funcSymbol = container.locals.get(constructorFunction.text);
|
||||
if (!funcSymbol || !(funcSymbol.flags & SymbolFlags.Function || isDeclarationOfFunctionExpression(funcSymbol))) {
|
||||
bindPropertyAssignment(constructorFunction.text, leftSideOfAssignment, /*isPrototypeProperty*/ true);
|
||||
}
|
||||
|
||||
function bindStaticPropertyAssignment(node: BinaryExpression) {
|
||||
// We saw a node of the form 'x.y = z'. Declare a 'member' y on x if x was a function.
|
||||
|
||||
// Look up the function in the local scope, since prototype assignments should
|
||||
// follow the function declaration
|
||||
const leftSideOfAssignment = node.left as PropertyAccessExpression;
|
||||
const target = leftSideOfAssignment.expression as Identifier;
|
||||
|
||||
// Fix up parent pointers since we're going to use these nodes before we bind into them
|
||||
leftSideOfAssignment.parent = node;
|
||||
target.parent = leftSideOfAssignment;
|
||||
|
||||
bindPropertyAssignment(target.text, leftSideOfAssignment, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
|
||||
function bindPropertyAssignment(functionName: string, propertyAccessExpression: PropertyAccessExpression, isPrototypeProperty: boolean) {
|
||||
let targetSymbol = container.locals.get(functionName);
|
||||
if (targetSymbol && isDeclarationOfFunctionOrClassExpression(targetSymbol)) {
|
||||
targetSymbol = (targetSymbol.valueDeclaration as VariableDeclaration).initializer.symbol;
|
||||
}
|
||||
|
||||
if (!targetSymbol || !(targetSymbol.flags & (SymbolFlags.Function | SymbolFlags.Class))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up the members collection if it doesn't exist already
|
||||
if (!funcSymbol.members) {
|
||||
funcSymbol.members = createMap<Symbol>();
|
||||
}
|
||||
const symbolTable = isPrototypeProperty ?
|
||||
(targetSymbol.members || (targetSymbol.members = createMap<Symbol>())) :
|
||||
(targetSymbol.exports || (targetSymbol.exports = createMap<Symbol>()));
|
||||
|
||||
// Declare the method/property
|
||||
declareSymbol(funcSymbol.members, funcSymbol, leftSideOfAssignment, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
declareSymbol(symbolTable, targetSymbol, propertyAccessExpression, SymbolFlags.Property, SymbolFlags.PropertyExcludes);
|
||||
}
|
||||
|
||||
function bindCallExpression(node: CallExpression) {
|
||||
@@ -2364,7 +2469,7 @@ namespace ts {
|
||||
|
||||
function bindFunctionDeclaration(node: FunctionDeclaration) {
|
||||
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
if (isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
}
|
||||
@@ -2381,7 +2486,7 @@ namespace ts {
|
||||
|
||||
function bindFunctionExpression(node: FunctionExpression) {
|
||||
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
if (isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
}
|
||||
@@ -2395,7 +2500,7 @@ namespace ts {
|
||||
|
||||
function bindPropertyOrMethodOrAccessor(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) {
|
||||
if (!isDeclarationFile(file) && !isInAmbientContext(node)) {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
if (isAsyncFunction(node)) {
|
||||
emitFlags |= NodeFlags.HasAsyncFunctions;
|
||||
}
|
||||
}
|
||||
@@ -2829,11 +2934,10 @@ namespace ts {
|
||||
|
||||
// An async method declaration is ES2017 syntax.
|
||||
if (hasModifier(node, ModifierFlags.Async)) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
transformFlags |= node.asteriskToken ? TransformFlags.AssertESNext : TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// Currently, we only support generators that were originally async function bodies.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken) {
|
||||
transformFlags |= TransformFlags.AssertGenerator;
|
||||
}
|
||||
|
||||
@@ -2899,7 +3003,7 @@ namespace ts {
|
||||
|
||||
// An async function declaration is ES2017 syntax.
|
||||
if (modifierFlags & ModifierFlags.Async) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
transformFlags |= node.asteriskToken ? TransformFlags.AssertESNext : TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// function declarations with object rest destructuring are ES Next syntax
|
||||
@@ -2919,7 +3023,7 @@ namespace ts {
|
||||
// down-level generator.
|
||||
// Currently we do not support transforming any other generator fucntions
|
||||
// down level.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken) {
|
||||
transformFlags |= TransformFlags.AssertGenerator;
|
||||
}
|
||||
}
|
||||
@@ -2941,7 +3045,7 @@ namespace ts {
|
||||
|
||||
// An async function expression is ES2017 syntax.
|
||||
if (hasModifier(node, ModifierFlags.Async)) {
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
transformFlags |= node.asteriskToken ? TransformFlags.AssertESNext : TransformFlags.AssertES2017;
|
||||
}
|
||||
|
||||
// function expressions with object rest destructuring are ES Next syntax
|
||||
@@ -2960,9 +3064,7 @@ namespace ts {
|
||||
// If a FunctionExpression is generator function and is the body of a
|
||||
// transformed async function, then this node can be transformed to a
|
||||
// down-level generator.
|
||||
// Currently we do not support transforming any other generator fucntions
|
||||
// down level.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken) {
|
||||
transformFlags |= TransformFlags.AssertGenerator;
|
||||
}
|
||||
|
||||
@@ -3130,8 +3232,8 @@ namespace ts {
|
||||
switch (kind) {
|
||||
case SyntaxKind.AsyncKeyword:
|
||||
case SyntaxKind.AwaitExpression:
|
||||
// async/await is ES2017 syntax
|
||||
transformFlags |= TransformFlags.AssertES2017;
|
||||
// async/await is ES2017 syntax, but may be ESNext syntax (for async generators)
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2017;
|
||||
break;
|
||||
|
||||
case SyntaxKind.PublicKeyword:
|
||||
@@ -3156,16 +3258,13 @@ namespace ts {
|
||||
case SyntaxKind.JsxText:
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
case SyntaxKind.JsxAttribute:
|
||||
case SyntaxKind.JsxAttributes:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
case SyntaxKind.JsxExpression:
|
||||
// These nodes are Jsx syntax.
|
||||
transformFlags |= TransformFlags.AssertJsx;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ForOfStatement:
|
||||
// for-of might be ESNext if it has a rest destructuring
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
// FALLTHROUGH
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateHead:
|
||||
case SyntaxKind.TemplateMiddle:
|
||||
@@ -3179,9 +3278,18 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ForOfStatement:
|
||||
// This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
|
||||
if ((<ForOfStatement>node).awaitModifier) {
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
}
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
break;
|
||||
|
||||
case SyntaxKind.YieldExpression:
|
||||
// This node is ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.ContainsYield;
|
||||
// This node is either ES2015 syntax (in a generator) or ES2017 syntax (in an async
|
||||
// generator).
|
||||
transformFlags |= TransformFlags.AssertESNext | TransformFlags.AssertES2015 | TransformFlags.ContainsYield;
|
||||
break;
|
||||
|
||||
case SyntaxKind.AnyKeyword:
|
||||
|
||||
+1624
-831
File diff suppressed because it is too large
Load Diff
@@ -333,6 +333,11 @@ namespace ts {
|
||||
type: "boolean",
|
||||
description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
|
||||
},
|
||||
{
|
||||
name: "downlevelIteration",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Use_full_down_level_iteration_for_iterables_and_arrays_for_for_of_spread_and_destructuring_in_ES5_Slash3
|
||||
},
|
||||
{
|
||||
name: "baseUrl",
|
||||
type: "string",
|
||||
@@ -418,6 +423,7 @@ namespace ts {
|
||||
"es7": "lib.es2016.d.ts",
|
||||
"es2016": "lib.es2016.d.ts",
|
||||
"es2017": "lib.es2017.d.ts",
|
||||
"esnext": "lib.esnext.d.ts",
|
||||
// Host only
|
||||
"dom": "lib.dom.d.ts",
|
||||
"dom.iterable": "lib.dom.iterable.d.ts",
|
||||
@@ -437,6 +443,7 @@ namespace ts {
|
||||
"es2017.object": "lib.es2017.object.d.ts",
|
||||
"es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts",
|
||||
"es2017.string": "lib.es2017.string.d.ts",
|
||||
"esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
|
||||
}),
|
||||
},
|
||||
description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon
|
||||
@@ -459,6 +466,16 @@ namespace ts {
|
||||
name: "alwaysStrict",
|
||||
type: "boolean",
|
||||
description: Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file
|
||||
},
|
||||
{
|
||||
// A list of plugins to load in the language service
|
||||
name: "plugins",
|
||||
type: "list",
|
||||
isTSConfigOnly: true,
|
||||
element: {
|
||||
name: "plugin",
|
||||
type: "object"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
+85
-20
@@ -43,18 +43,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (node) {
|
||||
const { pos, end } = getCommentRange(node);
|
||||
const emitFlags = getEmitFlags(node);
|
||||
hasWrittenComment = false;
|
||||
|
||||
const emitNode = node.emitNode;
|
||||
const emitFlags = emitNode && emitNode.flags;
|
||||
const { pos, end } = emitNode && emitNode.commentRange || node;
|
||||
if ((pos < 0 && end < 0) || (pos === end)) {
|
||||
// Both pos and end are synthesized, so just emit the node without comments.
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
|
||||
}
|
||||
else {
|
||||
if (extendedDiagnostics) {
|
||||
@@ -94,17 +90,10 @@ namespace ts {
|
||||
performance.measure("commentTime", "preEmitNodeWithComment");
|
||||
}
|
||||
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("beginEmitNodeWithComment");
|
||||
performance.mark("postEmitNodeWithComment");
|
||||
}
|
||||
|
||||
// Restore previous container state.
|
||||
@@ -119,12 +108,88 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "beginEmitNodeWithComment");
|
||||
performance.measure("commentTime", "postEmitNodeWithComment");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitNodeWithSynthesizedComments(hint: EmitHint, node: Node, emitNode: EmitNode, emitFlags: EmitFlags, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
const leadingComments = emitNode && emitNode.leadingComments;
|
||||
if (some(leadingComments)) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("preEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
|
||||
forEach(leadingComments, emitLeadingSynthesizedComment);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "preEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
}
|
||||
|
||||
emitNodeWithNestedComments(hint, node, emitFlags, emitCallback);
|
||||
|
||||
const trailingComments = emitNode && emitNode.trailingComments;
|
||||
if (some(trailingComments)) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("postEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
|
||||
forEach(trailingComments, emitTrailingSynthesizedComment);
|
||||
|
||||
if (extendedDiagnostics) {
|
||||
performance.measure("commentTime", "postEmitNodeWithSynthesizedComments");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitLeadingSynthesizedComment(comment: SynthesizedComment) {
|
||||
if (comment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
||||
writer.writeLine();
|
||||
}
|
||||
writeSynthesizedComment(comment);
|
||||
if (comment.hasTrailingNewLine || comment.kind === SyntaxKind.SingleLineCommentTrivia) {
|
||||
writer.writeLine();
|
||||
}
|
||||
else {
|
||||
writer.write(" ");
|
||||
}
|
||||
}
|
||||
|
||||
function emitTrailingSynthesizedComment(comment: SynthesizedComment) {
|
||||
if (!writer.isAtStartOfLine()) {
|
||||
writer.write(" ");
|
||||
}
|
||||
writeSynthesizedComment(comment);
|
||||
if (comment.hasTrailingNewLine) {
|
||||
writer.writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
function writeSynthesizedComment(comment: SynthesizedComment) {
|
||||
const text = formatSynthesizedComment(comment);
|
||||
const lineMap = comment.kind === SyntaxKind.MultiLineCommentTrivia ? computeLineStarts(text) : undefined;
|
||||
writeCommentRange(text, lineMap, writer, 0, text.length, newLine);
|
||||
}
|
||||
|
||||
function formatSynthesizedComment(comment: SynthesizedComment) {
|
||||
return comment.kind === SyntaxKind.MultiLineCommentTrivia
|
||||
? `/*${comment.text}*/`
|
||||
: `//${comment.text}`;
|
||||
}
|
||||
|
||||
function emitNodeWithNestedComments(hint: EmitHint, node: Node, emitFlags: EmitFlags, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (emitFlags & EmitFlags.NoNestedComments) {
|
||||
disabled = true;
|
||||
emitCallback(hint, node);
|
||||
disabled = false;
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
}
|
||||
|
||||
function emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void) {
|
||||
if (extendedDiagnostics) {
|
||||
performance.mark("preEmitBodyWithDetachedComments");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace ts {
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = "2.2.0";
|
||||
export const version = "2.3.0";
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
@@ -190,6 +190,7 @@ namespace ts {
|
||||
const writer = <EmitTextWriterWithSymbolWriter>createTextWriter(newLine);
|
||||
writer.trackSymbol = trackSymbol;
|
||||
writer.reportInaccessibleThisError = reportInaccessibleThisError;
|
||||
writer.reportIllegalExtends = reportIllegalExtends;
|
||||
writer.writeKeyword = writer.write;
|
||||
writer.writeOperator = writer.write;
|
||||
writer.writePunctuation = writer.write;
|
||||
@@ -313,6 +314,14 @@ namespace ts {
|
||||
recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning));
|
||||
}
|
||||
|
||||
function reportIllegalExtends() {
|
||||
if (errorNameNode) {
|
||||
reportedDeclarationError = true;
|
||||
emitterDiagnostics.add(createDiagnosticForNode(errorNameNode, Diagnostics.extends_clause_of_exported_class_0_refers_to_a_type_whose_name_cannot_be_referenced,
|
||||
declarationNameToString(errorNameNode)));
|
||||
}
|
||||
}
|
||||
|
||||
function reportInaccessibleThisError() {
|
||||
if (errorNameNode) {
|
||||
reportedDeclarationError = true;
|
||||
@@ -1010,6 +1019,23 @@ namespace ts {
|
||||
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.constraint, getTypeParameterConstraintVisibilityError);
|
||||
}
|
||||
}
|
||||
if (node.default && !isPrivateMethodTypeParameter(node)) {
|
||||
write(" = ");
|
||||
if (node.parent.kind === SyntaxKind.FunctionType ||
|
||||
node.parent.kind === SyntaxKind.ConstructorType ||
|
||||
(node.parent.parent && node.parent.parent.kind === SyntaxKind.TypeLiteral)) {
|
||||
Debug.assert(node.parent.kind === SyntaxKind.MethodDeclaration ||
|
||||
node.parent.kind === SyntaxKind.MethodSignature ||
|
||||
node.parent.kind === SyntaxKind.FunctionType ||
|
||||
node.parent.kind === SyntaxKind.ConstructorType ||
|
||||
node.parent.kind === SyntaxKind.CallSignature ||
|
||||
node.parent.kind === SyntaxKind.ConstructSignature);
|
||||
emitType(node.default);
|
||||
}
|
||||
else {
|
||||
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.default, getTypeParameterConstraintVisibilityError);
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeParameterConstraintVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
// Type parameter constraints are named by user so we should always be able to name it
|
||||
@@ -1071,7 +1097,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitHeritageClause(typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) {
|
||||
function emitHeritageClause(className: Identifier, typeReferences: ExpressionWithTypeArguments[], isImplementsList: boolean) {
|
||||
if (typeReferences) {
|
||||
write(isImplementsList ? " implements " : " extends ");
|
||||
emitCommaList(typeReferences, emitTypeOfTypeReference);
|
||||
@@ -1086,7 +1112,9 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
writer.getSymbolAccessibilityDiagnostic = getHeritageClauseVisibilityError;
|
||||
errorNameNode = className;
|
||||
resolver.writeBaseConstructorTypeOfClass(<ClassLikeDeclaration>enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
errorNameNode = undefined;
|
||||
}
|
||||
|
||||
function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
@@ -1096,11 +1124,11 @@ namespace ts {
|
||||
// Class or Interface implemented/extended is inaccessible
|
||||
diagnosticMessage = isImplementsList ?
|
||||
Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 :
|
||||
Diagnostics.Extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
|
||||
Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1;
|
||||
}
|
||||
else {
|
||||
// interface is inaccessible
|
||||
diagnosticMessage = Diagnostics.Extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
|
||||
diagnosticMessage = Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -1136,9 +1164,10 @@ namespace ts {
|
||||
emitTypeParameters(node.typeParameters);
|
||||
const baseTypeNode = getClassExtendsHeritageClauseElement(node);
|
||||
if (baseTypeNode) {
|
||||
emitHeritageClause([baseTypeNode], /*isImplementsList*/ false);
|
||||
node.name
|
||||
emitHeritageClause(node.name, [baseTypeNode], /*isImplementsList*/ false);
|
||||
}
|
||||
emitHeritageClause(getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true);
|
||||
emitHeritageClause(node.name, getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true);
|
||||
write(" {");
|
||||
writeLine();
|
||||
increaseIndent();
|
||||
@@ -1160,7 +1189,7 @@ namespace ts {
|
||||
emitTypeParameters(node.typeParameters);
|
||||
const interfaceExtendsTypes = filter(getInterfaceBaseTypeNodes(node), base => isEntityNameExpression(base.expression));
|
||||
if (interfaceExtendsTypes && interfaceExtendsTypes.length) {
|
||||
emitHeritageClause(interfaceExtendsTypes, /*isImplementsList*/ false);
|
||||
emitHeritageClause(node.name, interfaceExtendsTypes, /*isImplementsList*/ false);
|
||||
}
|
||||
write(" {");
|
||||
writeLine();
|
||||
|
||||
@@ -175,15 +175,15 @@
|
||||
"category": "Error",
|
||||
"code": 1057
|
||||
},
|
||||
"Operand for 'await' does not have a valid callable 'then' member.": {
|
||||
"Type used as operand to 'await' or the return type of an async function must either be a valid promise or must not contain a callable 'then' member.": {
|
||||
"category": "Error",
|
||||
"code": 1058
|
||||
},
|
||||
"Return expression in async function does not have a valid callable 'then' member.": {
|
||||
"A promise must have a 'then' method.": {
|
||||
"category": "Error",
|
||||
"code": 1059
|
||||
},
|
||||
"Expression body for async arrow function does not have a valid callable 'then' member.": {
|
||||
"The first parameter of the 'then' method of a promise must be a callback.": {
|
||||
"category": "Error",
|
||||
"code": 1060
|
||||
},
|
||||
@@ -191,7 +191,7 @@
|
||||
"category": "Error",
|
||||
"code": 1061
|
||||
},
|
||||
"{0} is referenced directly or indirectly in the fulfillment callback of its own 'then' method.": {
|
||||
"Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method.": {
|
||||
"category": "Error",
|
||||
"code": 1062
|
||||
},
|
||||
@@ -291,6 +291,10 @@
|
||||
"category": "Error",
|
||||
"code": 1102
|
||||
},
|
||||
"A 'for-await-of' statement is only allowed within an async function or async generator.": {
|
||||
"category": "Error",
|
||||
"code": 1103
|
||||
},
|
||||
"A 'continue' statement can only be used within an enclosing iteration statement.": {
|
||||
"category": "Error",
|
||||
"code": 1104
|
||||
@@ -319,7 +323,7 @@
|
||||
"category": "Error",
|
||||
"code": 1113
|
||||
},
|
||||
"Duplicate label '{0}'": {
|
||||
"Duplicate label '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 1114
|
||||
},
|
||||
@@ -447,7 +451,7 @@
|
||||
"category": "Error",
|
||||
"code": 1148
|
||||
},
|
||||
"File name '{0}' differs from already included file name '{1}' only in casing": {
|
||||
"File name '{0}' differs from already included file name '{1}' only in casing.": {
|
||||
"category": "Error",
|
||||
"code": 1149
|
||||
},
|
||||
@@ -455,7 +459,7 @@
|
||||
"category": "Error",
|
||||
"code": 1150
|
||||
},
|
||||
"'const' declarations must be initialized": {
|
||||
"'const' declarations must be initialized.": {
|
||||
"category": "Error",
|
||||
"code": 1155
|
||||
},
|
||||
@@ -651,11 +655,11 @@
|
||||
"category": "Error",
|
||||
"code": 1210
|
||||
},
|
||||
"A class declaration without the 'default' modifier must have a name": {
|
||||
"A class declaration without the 'default' modifier must have a name.": {
|
||||
"category": "Error",
|
||||
"code": 1211
|
||||
},
|
||||
"Identifier expected. '{0}' is a reserved word in strict mode": {
|
||||
"Identifier expected. '{0}' is a reserved word in strict mode.": {
|
||||
"category": "Error",
|
||||
"code": 1212
|
||||
},
|
||||
@@ -1107,7 +1111,7 @@
|
||||
"category": "Error",
|
||||
"code": 2360
|
||||
},
|
||||
"The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter": {
|
||||
"The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter.": {
|
||||
"category": "Error",
|
||||
"code": 2361
|
||||
},
|
||||
@@ -1131,7 +1135,7 @@
|
||||
"category": "Error",
|
||||
"code": 2366
|
||||
},
|
||||
"Type parameter name cannot be '{0}'": {
|
||||
"Type parameter name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2368
|
||||
},
|
||||
@@ -1291,7 +1295,7 @@
|
||||
"category": "Error",
|
||||
"code": 2408
|
||||
},
|
||||
"Return type of constructor signature must be assignable to the instance type of the class": {
|
||||
"Return type of constructor signature must be assignable to the instance type of the class.": {
|
||||
"category": "Error",
|
||||
"code": 2409
|
||||
},
|
||||
@@ -1311,7 +1315,7 @@
|
||||
"category": "Error",
|
||||
"code": 2413
|
||||
},
|
||||
"Class name cannot be '{0}'": {
|
||||
"Class name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2414
|
||||
},
|
||||
@@ -1347,7 +1351,7 @@
|
||||
"category": "Error",
|
||||
"code": 2426
|
||||
},
|
||||
"Interface name cannot be '{0}'": {
|
||||
"Interface name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2427
|
||||
},
|
||||
@@ -1359,7 +1363,7 @@
|
||||
"category": "Error",
|
||||
"code": 2430
|
||||
},
|
||||
"Enum name cannot be '{0}'": {
|
||||
"Enum name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2431
|
||||
},
|
||||
@@ -1367,11 +1371,11 @@
|
||||
"category": "Error",
|
||||
"code": 2432
|
||||
},
|
||||
"A namespace declaration cannot be in a different file from a class or function with which it is merged": {
|
||||
"A namespace declaration cannot be in a different file from a class or function with which it is merged.": {
|
||||
"category": "Error",
|
||||
"code": 2433
|
||||
},
|
||||
"A namespace declaration cannot be located prior to a class or function with which it is merged": {
|
||||
"A namespace declaration cannot be located prior to a class or function with which it is merged.": {
|
||||
"category": "Error",
|
||||
"code": 2434
|
||||
},
|
||||
@@ -1383,11 +1387,11 @@
|
||||
"category": "Error",
|
||||
"code": 2436
|
||||
},
|
||||
"Module '{0}' is hidden by a local declaration with the same name": {
|
||||
"Module '{0}' is hidden by a local declaration with the same name.": {
|
||||
"category": "Error",
|
||||
"code": 2437
|
||||
},
|
||||
"Import name cannot be '{0}'": {
|
||||
"Import name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2438
|
||||
},
|
||||
@@ -1395,7 +1399,7 @@
|
||||
"category": "Error",
|
||||
"code": 2439
|
||||
},
|
||||
"Import declaration conflicts with local declaration of '{0}'": {
|
||||
"Import declaration conflicts with local declaration of '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2440
|
||||
},
|
||||
@@ -1455,7 +1459,7 @@
|
||||
"category": "Error",
|
||||
"code": 2456
|
||||
},
|
||||
"Type alias name cannot be '{0}'": {
|
||||
"Type alias name cannot be '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2457
|
||||
},
|
||||
@@ -1475,7 +1479,7 @@
|
||||
"category": "Error",
|
||||
"code": 2461
|
||||
},
|
||||
"A rest element must be last in a destructuring pattern": {
|
||||
"A rest element must be last in a destructuring pattern.": {
|
||||
"category": "Error",
|
||||
"code": 2462
|
||||
},
|
||||
@@ -1559,7 +1563,7 @@
|
||||
"category": "Error",
|
||||
"code": 2483
|
||||
},
|
||||
"Export declaration conflicts with exported declaration of '{0}'": {
|
||||
"Export declaration conflicts with exported declaration of '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2484
|
||||
},
|
||||
@@ -1583,7 +1587,7 @@
|
||||
"category": "Error",
|
||||
"code": 2491
|
||||
},
|
||||
"Cannot redeclare identifier '{0}' in catch clause": {
|
||||
"Cannot redeclare identifier '{0}' in catch clause.": {
|
||||
"category": "Error",
|
||||
"code": 2492
|
||||
},
|
||||
@@ -1631,6 +1635,10 @@
|
||||
"category": "Error",
|
||||
"code": 2503
|
||||
},
|
||||
"Type must have a '[Symbol.asyncIterator]()' method that returns an async iterator.": {
|
||||
"category": "Error",
|
||||
"code": 2504
|
||||
},
|
||||
"A generator cannot have a 'void' type annotation.": {
|
||||
"category": "Error",
|
||||
"code": 2505
|
||||
@@ -1687,6 +1695,10 @@
|
||||
"category": "Error",
|
||||
"code": 2518
|
||||
},
|
||||
"An async iterator must have a 'next()' method.": {
|
||||
"category": "Error",
|
||||
"code": 2519
|
||||
},
|
||||
"Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": {
|
||||
"category": "Error",
|
||||
"code": 2520
|
||||
@@ -1795,6 +1807,18 @@
|
||||
"category": "Error",
|
||||
"code": 2546
|
||||
},
|
||||
"The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property.": {
|
||||
"category": "Error",
|
||||
"code": 2547
|
||||
},
|
||||
"Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator.": {
|
||||
"category": "Error",
|
||||
"code": 2548
|
||||
},
|
||||
"Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator.": {
|
||||
"category": "Error",
|
||||
"code": 2549
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -1807,7 +1831,7 @@
|
||||
"category": "Error",
|
||||
"code": 2602
|
||||
},
|
||||
"Property '{0}' in type '{1}' is not assignable to type '{2}'": {
|
||||
"Property '{0}' in type '{1}' is not assignable to type '{2}'.": {
|
||||
"category": "Error",
|
||||
"code": 2603
|
||||
},
|
||||
@@ -1823,11 +1847,11 @@
|
||||
"category": "Error",
|
||||
"code": 2606
|
||||
},
|
||||
"JSX element class does not support attributes because it does not have a '{0}' property": {
|
||||
"JSX element class does not support attributes because it does not have a '{0}' property.": {
|
||||
"category": "Error",
|
||||
"code": 2607
|
||||
},
|
||||
"The global type 'JSX.{0}' may not have more than one property": {
|
||||
"The global type 'JSX.{0}' may not have more than one property.": {
|
||||
"category": "Error",
|
||||
"code": 2608
|
||||
},
|
||||
@@ -1839,7 +1863,7 @@
|
||||
"category": "Error",
|
||||
"code": 2649
|
||||
},
|
||||
"Cannot emit namespaced JSX elements in React": {
|
||||
"Cannot emit namespaced JSX elements in React.": {
|
||||
"category": "Error",
|
||||
"code": 2650
|
||||
},
|
||||
@@ -1863,11 +1887,11 @@
|
||||
"category": "Error",
|
||||
"code": 2656
|
||||
},
|
||||
"JSX expressions must have one parent element": {
|
||||
"JSX expressions must have one parent element.": {
|
||||
"category": "Error",
|
||||
"code": 2657
|
||||
},
|
||||
"Type '{0}' provides no match for the signature '{1}'": {
|
||||
"Type '{0}' provides no match for the signature '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2658
|
||||
},
|
||||
@@ -2047,14 +2071,26 @@
|
||||
"category": "Error",
|
||||
"code": 2702
|
||||
},
|
||||
"The operand of a delete operator must be a property reference": {
|
||||
"The operand of a delete operator must be a property reference.": {
|
||||
"category": "Error",
|
||||
"code": 2703
|
||||
},
|
||||
"The operand of a delete operator cannot be a read-only property": {
|
||||
"The operand of a delete operator cannot be a read-only property.": {
|
||||
"category": "Error",
|
||||
"code": 2704
|
||||
},
|
||||
"An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option.": {
|
||||
"category": "Error",
|
||||
"code": 2705
|
||||
},
|
||||
"Required type parameters may not follow optional type parameters.": {
|
||||
"category": "Error",
|
||||
"code": 2706
|
||||
},
|
||||
"Generic type '{0}' requires between {1} and {2} type arguments.": {
|
||||
"category": "Error",
|
||||
"code": 2707
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@@ -2096,11 +2132,11 @@
|
||||
"category": "Error",
|
||||
"code": 4019
|
||||
},
|
||||
"Extends clause of exported class '{0}' has or is using private name '{1}'.": {
|
||||
"'extends' clause of exported class '{0}' has or is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4020
|
||||
},
|
||||
"Extends clause of exported interface '{0}' has or is using private name '{1}'.": {
|
||||
"'extends' clause of exported interface '{0}' has or is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4022
|
||||
},
|
||||
@@ -2352,6 +2388,10 @@
|
||||
"category": "Error",
|
||||
"code": 4092
|
||||
},
|
||||
"'extends' clause of exported class '{0}' refers to a type whose name cannot be referenced.": {
|
||||
"category": "Error",
|
||||
"code": 4093
|
||||
},
|
||||
|
||||
"The current host does not support the '{0}' option.": {
|
||||
"category": "Error",
|
||||
@@ -2369,7 +2409,7 @@
|
||||
"category": "Error",
|
||||
"code": 5011
|
||||
},
|
||||
"Cannot read file '{0}': {1}": {
|
||||
"Cannot read file '{0}': {1}.": {
|
||||
"category": "Error",
|
||||
"code": 5012
|
||||
},
|
||||
@@ -2389,7 +2429,7 @@
|
||||
"category": "Error",
|
||||
"code": 5024
|
||||
},
|
||||
"Could not write file '{0}': {1}": {
|
||||
"Could not write file '{0}': {1}.": {
|
||||
"category": "Error",
|
||||
"code": 5033
|
||||
},
|
||||
@@ -2425,11 +2465,11 @@
|
||||
"category": "Error",
|
||||
"code": 5056
|
||||
},
|
||||
"Cannot find a tsconfig.json file at the specified directory: '{0}'": {
|
||||
"Cannot find a tsconfig.json file at the specified directory: '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 5057
|
||||
},
|
||||
"The specified path does not exist: '{0}'": {
|
||||
"The specified path does not exist: '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 5058
|
||||
},
|
||||
@@ -2441,11 +2481,11 @@
|
||||
"category": "Error",
|
||||
"code": 5060
|
||||
},
|
||||
"Pattern '{0}' can have at most one '*' character": {
|
||||
"Pattern '{0}' can have at most one '*' character.": {
|
||||
"category": "Error",
|
||||
"code": 5061
|
||||
},
|
||||
"Substitution '{0}' in pattern '{1}' in can have at most one '*' character": {
|
||||
"Substitution '{0}' in pattern '{1}' in can have at most one '*' character.": {
|
||||
"category": "Error",
|
||||
"code": 5062
|
||||
},
|
||||
@@ -2517,11 +2557,11 @@
|
||||
"category": "Message",
|
||||
"code": 6012
|
||||
},
|
||||
"Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'": {
|
||||
"Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'.": {
|
||||
"category": "Message",
|
||||
"code": 6015
|
||||
},
|
||||
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'": {
|
||||
"Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'.": {
|
||||
"category": "Message",
|
||||
"code": 6016
|
||||
},
|
||||
@@ -2533,7 +2573,7 @@
|
||||
"category": "Message",
|
||||
"code": 6019
|
||||
},
|
||||
"Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'": {
|
||||
"Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.": {
|
||||
"category": "Message",
|
||||
"code": 6020
|
||||
},
|
||||
@@ -2613,7 +2653,7 @@
|
||||
"category": "Error",
|
||||
"code": 6045
|
||||
},
|
||||
"Argument for '{0}' option must be: {1}": {
|
||||
"Argument for '{0}' option must be: {1}.": {
|
||||
"category": "Error",
|
||||
"code": 6046
|
||||
},
|
||||
@@ -2701,7 +2741,7 @@
|
||||
"category": "Message",
|
||||
"code": 6072
|
||||
},
|
||||
"Stylize errors and messages using color and context. (experimental)": {
|
||||
"Stylize errors and messages using color and context (experimental).": {
|
||||
"category": "Message",
|
||||
"code": 6073
|
||||
},
|
||||
@@ -2729,7 +2769,7 @@
|
||||
"category": "Message",
|
||||
"code": 6079
|
||||
},
|
||||
"Specify JSX code generation: 'preserve', 'react-native', or 'react'": {
|
||||
"Specify JSX code generation: 'preserve', 'react-native', or 'react'.": {
|
||||
"category": "Message",
|
||||
"code": 6080
|
||||
},
|
||||
@@ -2745,7 +2785,7 @@
|
||||
"category": "Message",
|
||||
"code": 6083
|
||||
},
|
||||
"Specify the object invoked for createElement and __spread when targeting 'react' JSX emit": {
|
||||
"Specify the object invoked for createElement and __spread when targeting 'react' JSX emit.": {
|
||||
"category": "Message",
|
||||
"code": 6084
|
||||
},
|
||||
@@ -2833,27 +2873,27 @@
|
||||
"category": "Message",
|
||||
"code": 6105
|
||||
},
|
||||
"'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'": {
|
||||
"'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'.": {
|
||||
"category": "Message",
|
||||
"code": 6106
|
||||
},
|
||||
"'rootDirs' option is set, using it to resolve relative module name '{0}'": {
|
||||
"'rootDirs' option is set, using it to resolve relative module name '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6107
|
||||
},
|
||||
"Longest matching prefix for '{0}' is '{1}'": {
|
||||
"Longest matching prefix for '{0}' is '{1}'.": {
|
||||
"category": "Message",
|
||||
"code": 6108
|
||||
},
|
||||
"Loading '{0}' from the root dir '{1}', candidate location '{2}'": {
|
||||
"Loading '{0}' from the root dir '{1}', candidate location '{2}'.": {
|
||||
"category": "Message",
|
||||
"code": 6109
|
||||
},
|
||||
"Trying other entries in 'rootDirs'": {
|
||||
"Trying other entries in 'rootDirs'.": {
|
||||
"category": "Message",
|
||||
"code": 6110
|
||||
},
|
||||
"Module resolution using 'rootDirs' has failed": {
|
||||
"Module resolution using 'rootDirs' has failed.": {
|
||||
"category": "Message",
|
||||
"code": 6111
|
||||
},
|
||||
@@ -2893,7 +2933,7 @@
|
||||
"category": "Message",
|
||||
"code": 6120
|
||||
},
|
||||
"Resolving with primary search path '{0}'": {
|
||||
"Resolving with primary search path '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6121
|
||||
},
|
||||
@@ -2909,7 +2949,7 @@
|
||||
"category": "Message",
|
||||
"code": 6124
|
||||
},
|
||||
"Looking up in 'node_modules' folder, initial location '{0}'": {
|
||||
"Looking up in 'node_modules' folder, initial location '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6125
|
||||
},
|
||||
@@ -2929,7 +2969,7 @@
|
||||
"category": "Error",
|
||||
"code": 6129
|
||||
},
|
||||
"Resolving real path for '{0}', result '{1}'": {
|
||||
"Resolving real path for '{0}', result '{1}'.": {
|
||||
"category": "Message",
|
||||
"code": 6130
|
||||
},
|
||||
@@ -2937,7 +2977,7 @@
|
||||
"category": "Error",
|
||||
"code": 6131
|
||||
},
|
||||
"File name '{0}' has a '{1}' extension - stripping it": {
|
||||
"File name '{0}' has a '{1}' extension - stripping it.": {
|
||||
"category": "Message",
|
||||
"code": 6132
|
||||
},
|
||||
@@ -2953,7 +2993,7 @@
|
||||
"category": "Message",
|
||||
"code": 6135
|
||||
},
|
||||
"The maximum dependency depth to search under node_modules and load JavaScript files": {
|
||||
"The maximum dependency depth to search under node_modules and load JavaScript files.": {
|
||||
"category": "Message",
|
||||
"code": 6136
|
||||
},
|
||||
@@ -2969,7 +3009,7 @@
|
||||
"category": "Error",
|
||||
"code": 6140
|
||||
},
|
||||
"Parse in strict mode and emit \"use strict\" for each source file": {
|
||||
"Parse in strict mode and emit \"use strict\" for each source file.": {
|
||||
"category": "Message",
|
||||
"code": 6141
|
||||
},
|
||||
@@ -3001,6 +3041,10 @@
|
||||
"category": "Message",
|
||||
"code": 6148
|
||||
},
|
||||
"Use full down-level iteration for iterables and arrays for 'for-of', spread, and destructuring in ES5/3.": {
|
||||
"category": "Message",
|
||||
"code": 6149
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
@@ -3069,7 +3113,7 @@
|
||||
"category": "Error",
|
||||
"code": 7025
|
||||
},
|
||||
"JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists": {
|
||||
"JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists.": {
|
||||
"category": "Error",
|
||||
"code": 7026
|
||||
},
|
||||
@@ -3165,7 +3209,7 @@
|
||||
"category": "Error",
|
||||
"code": 8016
|
||||
},
|
||||
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses.": {
|
||||
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": {
|
||||
"category": "Error",
|
||||
"code": 9002
|
||||
},
|
||||
@@ -3197,7 +3241,7 @@
|
||||
"category": "Error",
|
||||
"code": 17004
|
||||
},
|
||||
"A constructor cannot contain a 'super' call when its class extends 'null'": {
|
||||
"A constructor cannot contain a 'super' call when its class extends 'null'.": {
|
||||
"category": "Error",
|
||||
"code": 17005
|
||||
},
|
||||
@@ -3225,7 +3269,7 @@
|
||||
"category": "Error",
|
||||
"code": 17011
|
||||
},
|
||||
"'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{0}'?": {
|
||||
"'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?": {
|
||||
"category": "Error",
|
||||
"code": 17012
|
||||
},
|
||||
@@ -3263,7 +3307,7 @@
|
||||
"category": "Message",
|
||||
"code": 90003
|
||||
},
|
||||
"Remove declaration for: {0}": {
|
||||
"Remove declaration for: '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 90004
|
||||
},
|
||||
@@ -3279,7 +3323,7 @@
|
||||
"category": "Message",
|
||||
"code": 90008
|
||||
},
|
||||
"Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig": {
|
||||
"Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.": {
|
||||
"category": "Error",
|
||||
"code": 90009
|
||||
},
|
||||
@@ -3287,18 +3331,26 @@
|
||||
"category": "Error",
|
||||
"code": 90010
|
||||
},
|
||||
"Import {0} from {1}": {
|
||||
"Import {0} from {1}.": {
|
||||
"category": "Message",
|
||||
"code": 90013
|
||||
},
|
||||
"Change {0} to {1}": {
|
||||
"Change {0} to {1}.": {
|
||||
"category": "Message",
|
||||
"code": 90014
|
||||
},
|
||||
"Add {0} to existing import declaration from {1}": {
|
||||
"Add {0} to existing import declaration from {1}.": {
|
||||
"category": "Message",
|
||||
"code": 90015
|
||||
},
|
||||
"Add declaration for missing property '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 90016
|
||||
},
|
||||
"Add index signature for missing property '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 90017
|
||||
},
|
||||
"Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 8017
|
||||
|
||||
+31
-29
@@ -10,14 +10,13 @@ namespace ts {
|
||||
|
||||
/*@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): EmitResult {
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<SourceFile>[]): EmitResult {
|
||||
const compilerOptions = host.getCompilerOptions();
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
const sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined;
|
||||
const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined;
|
||||
const emitterDiagnostics = createDiagnosticCollection();
|
||||
const newLine = host.getNewLine();
|
||||
const transformers = emitOnlyDtsFiles ? [] : getTransformers(compilerOptions);
|
||||
const writer = createTextWriter(newLine);
|
||||
const sourceMap = createSourceMapWriter(host, writer);
|
||||
|
||||
@@ -29,7 +28,7 @@ namespace ts {
|
||||
const sourceFiles = getSourceFilesToEmit(host, targetSourceFile);
|
||||
|
||||
// Transform the source files
|
||||
const transform = transformFiles(resolver, host, sourceFiles, transformers);
|
||||
const transform = transformNodes(resolver, host, compilerOptions, sourceFiles, transformers, /*allowDtsFiles*/ false);
|
||||
|
||||
// Create a printer to print the nodes
|
||||
const printer = createPrinter(compilerOptions, {
|
||||
@@ -38,7 +37,7 @@ namespace ts {
|
||||
|
||||
// transform hooks
|
||||
onEmitNode: transform.emitNodeWithNotification,
|
||||
onSubstituteNode: transform.emitNodeWithSubstitution,
|
||||
substituteNode: transform.substituteNode,
|
||||
|
||||
// sourcemap hooks
|
||||
onEmitSourceMapOfNode: sourceMap.emitNodeWithSourceMap,
|
||||
@@ -56,9 +55,7 @@ namespace ts {
|
||||
performance.measure("printTime", "beforePrint");
|
||||
|
||||
// Clean up emit nodes on parse tree
|
||||
for (const sourceFile of sourceFiles) {
|
||||
disposeEmitNodes(sourceFile);
|
||||
}
|
||||
transform.dispose();
|
||||
|
||||
return {
|
||||
emitSkipped,
|
||||
@@ -201,7 +198,7 @@ namespace ts {
|
||||
onEmitNode,
|
||||
onEmitHelpers,
|
||||
onSetSourceFile,
|
||||
onSubstituteNode,
|
||||
substituteNode,
|
||||
} = handlers;
|
||||
|
||||
const newLine = getNewLineCharacter(printerOptions);
|
||||
@@ -331,8 +328,8 @@ namespace ts {
|
||||
setWriter(/*output*/ undefined);
|
||||
}
|
||||
|
||||
function emit(node: Node, hint = EmitHint.Unspecified) {
|
||||
pipelineEmitWithNotification(hint, node);
|
||||
function emit(node: Node) {
|
||||
pipelineEmitWithNotification(EmitHint.Unspecified, node);
|
||||
}
|
||||
|
||||
function emitIdentifierName(node: Identifier) {
|
||||
@@ -353,6 +350,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function pipelineEmitWithComments(hint: EmitHint, node: Node) {
|
||||
node = trySubstituteNode(hint, node);
|
||||
if (emitNodeWithComments && hint !== EmitHint.SourceFile) {
|
||||
emitNodeWithComments(hint, node, pipelineEmitWithSourceMap);
|
||||
}
|
||||
@@ -363,16 +361,7 @@ namespace ts {
|
||||
|
||||
function pipelineEmitWithSourceMap(hint: EmitHint, node: Node) {
|
||||
if (onEmitSourceMapOfNode && hint !== EmitHint.SourceFile && hint !== EmitHint.IdentifierName) {
|
||||
onEmitSourceMapOfNode(hint, node, pipelineEmitWithSubstitution);
|
||||
}
|
||||
else {
|
||||
pipelineEmitWithSubstitution(hint, node);
|
||||
}
|
||||
}
|
||||
|
||||
function pipelineEmitWithSubstitution(hint: EmitHint, node: Node) {
|
||||
if (onSubstituteNode) {
|
||||
onSubstituteNode(hint, node, pipelineEmitWithHint);
|
||||
onEmitSourceMapOfNode(hint, node, pipelineEmitWithHint);
|
||||
}
|
||||
else {
|
||||
pipelineEmitWithHint(hint, node);
|
||||
@@ -604,6 +593,8 @@ namespace ts {
|
||||
return emitJsxClosingElement(<JsxClosingElement>node);
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return emitJsxAttribute(<JsxAttribute>node);
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return emitJsxAttributes(<JsxAttributes>node);
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
return emitJsxSpreadAttribute(<JsxSpreadAttribute>node);
|
||||
case SyntaxKind.JsxExpression:
|
||||
@@ -638,7 +629,7 @@ namespace ts {
|
||||
// If the node is an expression, try to emit it as an expression with
|
||||
// substitution.
|
||||
if (isExpression(node)) {
|
||||
return pipelineEmitWithSubstitution(EmitHint.Expression, node);
|
||||
return pipelineEmitExpression(trySubstituteNode(EmitHint.Expression, node));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -735,6 +726,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function trySubstituteNode(hint: EmitHint, node: Node) {
|
||||
return node && substituteNode && substituteNode(hint, node) || node;
|
||||
}
|
||||
|
||||
function emitBodyIndirect(node: Node, elements: NodeArray<Node>, emitCallback: (node: Node) => void): void {
|
||||
if (emitBodyWithDetachedComments) {
|
||||
emitBodyWithDetachedComments(node, elements, emitCallback);
|
||||
@@ -757,9 +752,6 @@ namespace ts {
|
||||
// SyntaxKind.NumericLiteral
|
||||
function emitNumericLiteral(node: NumericLiteral) {
|
||||
emitLiteral(node);
|
||||
if (node.trailingComment) {
|
||||
write(` /*${node.trailingComment}*/`);
|
||||
}
|
||||
}
|
||||
|
||||
// SyntaxKind.StringLiteral
|
||||
@@ -1448,6 +1440,7 @@ namespace ts {
|
||||
function emitForOfStatement(node: ForOfStatement) {
|
||||
const openParenPos = writeToken(SyntaxKind.ForKeyword, node.pos);
|
||||
write(" ");
|
||||
emitWithSuffix(node.awaitModifier, " ");
|
||||
writeToken(SyntaxKind.OpenParenToken, openParenPos);
|
||||
emitForBinding(node.initializer);
|
||||
write(" of ");
|
||||
@@ -1760,7 +1753,6 @@ namespace ts {
|
||||
else {
|
||||
pushNameGenerationScope();
|
||||
write("{");
|
||||
increaseIndent();
|
||||
emitBlockStatements(node);
|
||||
write("}");
|
||||
popNameGenerationScope();
|
||||
@@ -1891,15 +1883,21 @@ namespace ts {
|
||||
write("<");
|
||||
emitJsxTagName(node.tagName);
|
||||
write(" ");
|
||||
emitList(node, node.attributes, ListFormat.JsxElementAttributes);
|
||||
// We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap
|
||||
if (node.attributes.properties && node.attributes.properties.length > 0) {
|
||||
emit(node.attributes);
|
||||
}
|
||||
write("/>");
|
||||
}
|
||||
|
||||
function emitJsxOpeningElement(node: JsxOpeningElement) {
|
||||
write("<");
|
||||
emitJsxTagName(node.tagName);
|
||||
writeIfAny(node.attributes, " ");
|
||||
emitList(node, node.attributes, ListFormat.JsxElementAttributes);
|
||||
writeIfAny(node.attributes.properties, " ");
|
||||
// We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap
|
||||
if (node.attributes.properties && node.attributes.properties.length > 0) {
|
||||
emit(node.attributes);
|
||||
}
|
||||
write(">");
|
||||
}
|
||||
|
||||
@@ -1913,6 +1911,10 @@ namespace ts {
|
||||
write(">");
|
||||
}
|
||||
|
||||
function emitJsxAttributes(node: JsxAttributes) {
|
||||
emitList(node, node.properties, ListFormat.JsxElementAttributes);
|
||||
}
|
||||
|
||||
function emitJsxAttribute(node: JsxAttribute) {
|
||||
emit(node.name);
|
||||
emitWithPrefix("=", node.initializer);
|
||||
@@ -2903,4 +2905,4 @@ namespace ts {
|
||||
Parameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | Parenthesis,
|
||||
IndexSignatureParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | SquareBrackets,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+283
-96
@@ -215,7 +215,7 @@ namespace ts {
|
||||
|
||||
// Signature elements
|
||||
|
||||
export function createParameter(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) {
|
||||
export function createParameter(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: string | BindingName, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression) {
|
||||
const node = <ParameterDeclaration>createSynthesizedNode(SyntaxKind.Parameter);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -227,7 +227,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: BindingName, type: TypeNode, initializer: Expression) {
|
||||
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, dotDotDotToken: DotDotDotToken | undefined, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.dotDotDotToken !== dotDotDotToken
|
||||
@@ -252,7 +252,7 @@ namespace ts {
|
||||
|
||||
// Type members
|
||||
|
||||
export function createProperty(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, questionToken: QuestionToken, type: TypeNode, initializer: Expression) {
|
||||
export function createProperty(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined, type: TypeNode | undefined, initializer: Expression) {
|
||||
const node = <PropertyDeclaration>createSynthesizedNode(SyntaxKind.PropertyDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -263,7 +263,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateProperty(node: PropertyDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, type: TypeNode, initializer: Expression) {
|
||||
export function updateProperty(node: PropertyDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: PropertyName, type: TypeNode | undefined, initializer: Expression) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
@@ -273,7 +273,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createMethod(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function createMethod(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | PropertyName, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
const node = <MethodDeclaration>createSynthesizedNode(SyntaxKind.MethodDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -286,19 +286,20 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateMethod(node: MethodDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function updateMethod(node: MethodDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: PropertyName, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.asteriskToken !== asteriskToken
|
||||
|| node.name !== name
|
||||
|| node.typeParameters !== typeParameters
|
||||
|| node.parameters !== parameters
|
||||
|| node.type !== type
|
||||
|| node.body !== body
|
||||
? updateNode(createMethod(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body), node)
|
||||
? updateNode(createMethod(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createConstructor(decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block) {
|
||||
export function createConstructor(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], body: Block | undefined) {
|
||||
const node = <ConstructorDeclaration>createSynthesizedNode(SyntaxKind.Constructor);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -309,7 +310,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateConstructor(node: ConstructorDeclaration, decorators: Decorator[], modifiers: Modifier[], parameters: ParameterDeclaration[], body: Block) {
|
||||
export function updateConstructor(node: ConstructorDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, parameters: ParameterDeclaration[], body: Block | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.parameters !== parameters
|
||||
@@ -318,7 +319,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createGetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function createGetAccessor(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
const node = <GetAccessorDeclaration>createSynthesizedNode(SyntaxKind.GetAccessor);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -330,7 +331,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateGetAccessor(node: GetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function updateGetAccessor(node: GetAccessorDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: PropertyName, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
@@ -341,7 +342,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createSetAccessor(decorators: Decorator[], modifiers: Modifier[], name: string | PropertyName, parameters: ParameterDeclaration[], body: Block) {
|
||||
export function createSetAccessor(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | PropertyName, parameters: ParameterDeclaration[], body: Block | undefined) {
|
||||
const node = <SetAccessorDeclaration>createSynthesizedNode(SyntaxKind.SetAccessor);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -352,7 +353,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateSetAccessor(node: SetAccessorDeclaration, decorators: Decorator[], modifiers: Modifier[], name: PropertyName, parameters: ParameterDeclaration[], body: Block) {
|
||||
export function updateSetAccessor(node: SetAccessorDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: PropertyName, parameters: ParameterDeclaration[], body: Block | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
@@ -388,21 +389,21 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createBindingElement(propertyName: string | PropertyName, dotDotDotToken: DotDotDotToken, name: string | BindingName, initializer?: Expression) {
|
||||
export function createBindingElement(dotDotDotToken: DotDotDotToken | undefined, propertyName: string | PropertyName | undefined, name: string | BindingName, initializer?: Expression) {
|
||||
const node = <BindingElement>createSynthesizedNode(SyntaxKind.BindingElement);
|
||||
node.propertyName = asName(propertyName);
|
||||
node.dotDotDotToken = dotDotDotToken;
|
||||
node.propertyName = asName(propertyName);
|
||||
node.name = asName(name);
|
||||
node.initializer = initializer;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken, propertyName: PropertyName, name: BindingName, initializer: Expression) {
|
||||
export function updateBindingElement(node: BindingElement, dotDotDotToken: DotDotDotToken | undefined, propertyName: PropertyName | undefined, name: BindingName, initializer: Expression | undefined) {
|
||||
return node.propertyName !== propertyName
|
||||
|| node.dotDotDotToken !== dotDotDotToken
|
||||
|| node.name !== name
|
||||
|| node.initializer !== initializer
|
||||
? updateNode(createBindingElement(propertyName, dotDotDotToken, name, initializer), node)
|
||||
? updateNode(createBindingElement(dotDotDotToken, propertyName, name, initializer), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -470,7 +471,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createCall(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) {
|
||||
export function createCall(expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[]) {
|
||||
const node = <CallExpression>createSynthesizedNode(SyntaxKind.CallExpression);
|
||||
node.expression = parenthesizeForAccess(expression);
|
||||
node.typeArguments = asNodeArray(typeArguments);
|
||||
@@ -478,7 +479,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateCall(node: CallExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) {
|
||||
export function updateCall(node: CallExpression, expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[]) {
|
||||
return expression !== node.expression
|
||||
|| typeArguments !== node.typeArguments
|
||||
|| argumentsArray !== node.arguments
|
||||
@@ -486,7 +487,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createNew(expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) {
|
||||
export function createNew(expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[] | undefined) {
|
||||
const node = <NewExpression>createSynthesizedNode(SyntaxKind.NewExpression);
|
||||
node.expression = parenthesizeForNew(expression);
|
||||
node.typeArguments = asNodeArray(typeArguments);
|
||||
@@ -494,7 +495,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateNew(node: NewExpression, expression: Expression, typeArguments: TypeNode[], argumentsArray: Expression[]) {
|
||||
export function updateNew(node: NewExpression, expression: Expression, typeArguments: TypeNode[] | undefined, argumentsArray: Expression[] | undefined) {
|
||||
return node.expression !== expression
|
||||
|| node.typeArguments !== typeArguments
|
||||
|| node.arguments !== argumentsArray
|
||||
@@ -542,7 +543,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createFunctionExpression(modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function createFunctionExpression(modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block) {
|
||||
const node = <FunctionExpression>createSynthesizedNode(SyntaxKind.FunctionExpression);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
node.asteriskToken = asteriskToken;
|
||||
@@ -554,18 +555,19 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateFunctionExpression(node: FunctionExpression, modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function updateFunctionExpression(node: FunctionExpression, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block) {
|
||||
return node.name !== name
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.asteriskToken !== asteriskToken
|
||||
|| node.typeParameters !== typeParameters
|
||||
|| node.parameters !== parameters
|
||||
|| node.type !== type
|
||||
|| node.body !== body
|
||||
? updateNode(createFunctionExpression(modifiers, node.asteriskToken, name, typeParameters, parameters, type, body), node)
|
||||
? updateNode(createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createArrowFunction(modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, equalsGreaterThanToken: EqualsGreaterThanToken, body: ConciseBody) {
|
||||
export function createArrowFunction(modifiers: Modifier[] | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, equalsGreaterThanToken: EqualsGreaterThanToken | undefined, body: ConciseBody) {
|
||||
const node = <ArrowFunction>createSynthesizedNode(SyntaxKind.ArrowFunction);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
node.typeParameters = asNodeArray(typeParameters);
|
||||
@@ -576,7 +578,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateArrowFunction(node: ArrowFunction, modifiers: Modifier[], typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: ConciseBody) {
|
||||
export function updateArrowFunction(node: ArrowFunction, modifiers: Modifier[] | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: ConciseBody) {
|
||||
return node.modifiers !== modifiers
|
||||
|| node.typeParameters !== typeParameters
|
||||
|| node.parameters !== parameters
|
||||
@@ -720,9 +722,10 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateYield(node: YieldExpression, expression: Expression) {
|
||||
export function updateYield(node: YieldExpression, asteriskToken: AsteriskToken | undefined, expression: Expression) {
|
||||
return node.expression !== expression
|
||||
? updateNode(createYield(node.asteriskToken, expression), node)
|
||||
|| node.asteriskToken !== asteriskToken
|
||||
? updateNode(createYield(asteriskToken, expression), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -738,7 +741,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createClassExpression(modifiers: Modifier[], name: string | Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
export function createClassExpression(modifiers: Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
const node = <ClassExpression>createSynthesizedNode(SyntaxKind.ClassExpression);
|
||||
node.decorators = undefined;
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -749,7 +752,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateClassExpression(node: ClassExpression, modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
export function updateClassExpression(node: ClassExpression, modifiers: Modifier[] | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
return node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
|| node.typeParameters !== typeParameters
|
||||
@@ -834,7 +837,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createVariableStatement(modifiers: Modifier[], declarationList: VariableDeclarationList | VariableDeclaration[]): VariableStatement {
|
||||
export function createVariableStatement(modifiers: Modifier[] | undefined, declarationList: VariableDeclarationList | VariableDeclaration[]) {
|
||||
const node = <VariableStatement>createSynthesizedNode(SyntaxKind.VariableStatement);
|
||||
node.decorators = undefined;
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -842,14 +845,14 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateVariableStatement(node: VariableStatement, modifiers: Modifier[], declarationList: VariableDeclarationList): VariableStatement {
|
||||
export function updateVariableStatement(node: VariableStatement, modifiers: Modifier[] | undefined, declarationList: VariableDeclarationList) {
|
||||
return node.modifiers !== modifiers
|
||||
|| node.declarationList !== declarationList
|
||||
? updateNode(createVariableStatement(modifiers, declarationList), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createVariableDeclarationList(declarations: VariableDeclaration[], flags?: NodeFlags): VariableDeclarationList {
|
||||
export function createVariableDeclarationList(declarations: VariableDeclaration[], flags?: NodeFlags) {
|
||||
const node = <VariableDeclarationList>createSynthesizedNode(SyntaxKind.VariableDeclarationList);
|
||||
node.flags |= flags;
|
||||
node.declarations = createNodeArray(declarations);
|
||||
@@ -862,7 +865,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression): VariableDeclaration {
|
||||
export function createVariableDeclaration(name: string | BindingName, type?: TypeNode, initializer?: Expression) {
|
||||
const node = <VariableDeclaration>createSynthesizedNode(SyntaxKind.VariableDeclaration);
|
||||
node.name = asName(name);
|
||||
node.type = type;
|
||||
@@ -870,7 +873,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode, initializer: Expression) {
|
||||
export function updateVariableDeclaration(node: VariableDeclaration, name: BindingName, type: TypeNode | undefined, initializer: Expression | undefined) {
|
||||
return node.name !== name
|
||||
|| node.type !== type
|
||||
|| node.initializer !== initializer
|
||||
@@ -882,7 +885,7 @@ namespace ts {
|
||||
return <EmptyStatement>createSynthesizedNode(SyntaxKind.EmptyStatement);
|
||||
}
|
||||
|
||||
export function createStatement(expression: Expression): ExpressionStatement {
|
||||
export function createStatement(expression: Expression) {
|
||||
const node = <ExpressionStatement>createSynthesizedNode(SyntaxKind.ExpressionStatement);
|
||||
node.expression = parenthesizeExpressionForExpressionStatement(expression);
|
||||
return node;
|
||||
@@ -902,7 +905,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement) {
|
||||
export function updateIf(node: IfStatement, expression: Expression, thenStatement: Statement, elseStatement: Statement | undefined) {
|
||||
return node.expression !== expression
|
||||
|| node.thenStatement !== thenStatement
|
||||
|| node.elseStatement !== elseStatement
|
||||
@@ -938,7 +941,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createFor(initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement) {
|
||||
export function createFor(initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) {
|
||||
const node = <ForStatement>createSynthesizedNode(SyntaxKind.ForStatement);
|
||||
node.initializer = initializer;
|
||||
node.condition = condition;
|
||||
@@ -947,7 +950,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateFor(node: ForStatement, initializer: ForInitializer, condition: Expression, incrementor: Expression, statement: Statement) {
|
||||
export function updateFor(node: ForStatement, initializer: ForInitializer | undefined, condition: Expression | undefined, incrementor: Expression | undefined, statement: Statement) {
|
||||
return node.initializer !== initializer
|
||||
|| node.condition !== condition
|
||||
|| node.incrementor !== incrementor
|
||||
@@ -972,19 +975,21 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createForOf(initializer: ForInitializer, expression: Expression, statement: Statement) {
|
||||
export function createForOf(awaitModifier: AwaitKeywordToken, initializer: ForInitializer, expression: Expression, statement: Statement) {
|
||||
const node = <ForOfStatement>createSynthesizedNode(SyntaxKind.ForOfStatement);
|
||||
node.awaitModifier = awaitModifier;
|
||||
node.initializer = initializer;
|
||||
node.expression = expression;
|
||||
node.statement = statement;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateForOf(node: ForOfStatement, initializer: ForInitializer, expression: Expression, statement: Statement) {
|
||||
return node.initializer !== initializer
|
||||
export function updateForOf(node: ForOfStatement, awaitModifier: AwaitKeywordToken, initializer: ForInitializer, expression: Expression, statement: Statement) {
|
||||
return node.awaitModifier !== awaitModifier
|
||||
|| node.initializer !== initializer
|
||||
|| node.expression !== expression
|
||||
|| node.statement !== statement
|
||||
? updateNode(createForOf(initializer, expression, statement), node)
|
||||
? updateNode(createForOf(awaitModifier, initializer, expression, statement), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -994,7 +999,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateContinue(node: ContinueStatement, label: Identifier) {
|
||||
export function updateContinue(node: ContinueStatement, label: Identifier | undefined) {
|
||||
return node.label !== label
|
||||
? updateNode(createContinue(label), node)
|
||||
: node;
|
||||
@@ -1006,7 +1011,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateBreak(node: BreakStatement, label: Identifier) {
|
||||
export function updateBreak(node: BreakStatement, label: Identifier | undefined) {
|
||||
return node.label !== label
|
||||
? updateNode(createBreak(label), node)
|
||||
: node;
|
||||
@@ -1018,7 +1023,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateReturn(node: ReturnStatement, expression: Expression) {
|
||||
export function updateReturn(node: ReturnStatement, expression: Expression | undefined) {
|
||||
return node.expression !== expression
|
||||
? updateNode(createReturn(expression), node)
|
||||
: node;
|
||||
@@ -1078,7 +1083,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createTry(tryBlock: Block, catchClause: CatchClause, finallyBlock: Block) {
|
||||
export function createTry(tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) {
|
||||
const node = <TryStatement>createSynthesizedNode(SyntaxKind.TryStatement);
|
||||
node.tryBlock = tryBlock;
|
||||
node.catchClause = catchClause;
|
||||
@@ -1086,7 +1091,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause, finallyBlock: Block) {
|
||||
export function updateTry(node: TryStatement, tryBlock: Block, catchClause: CatchClause | undefined, finallyBlock: Block | undefined) {
|
||||
return node.tryBlock !== tryBlock
|
||||
|| node.catchClause !== catchClause
|
||||
|| node.finallyBlock !== finallyBlock
|
||||
@@ -1094,7 +1099,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createFunctionDeclaration(decorators: Decorator[], modifiers: Modifier[], asteriskToken: AsteriskToken, name: string | Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function createFunctionDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
const node = <FunctionDeclaration>createSynthesizedNode(SyntaxKind.FunctionDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -1107,19 +1112,20 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateFunctionDeclaration(node: FunctionDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], parameters: ParameterDeclaration[], type: TypeNode, body: Block) {
|
||||
export function updateFunctionDeclaration(node: FunctionDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, asteriskToken: AsteriskToken | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, body: Block | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.asteriskToken !== asteriskToken
|
||||
|| node.name !== name
|
||||
|| node.typeParameters !== typeParameters
|
||||
|| node.parameters !== parameters
|
||||
|| node.type !== type
|
||||
|| node.body !== body
|
||||
? updateNode(createFunctionDeclaration(decorators, modifiers, node.asteriskToken, name, typeParameters, parameters, type, body), node)
|
||||
? updateNode(createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createClassDeclaration(decorators: Decorator[], modifiers: Modifier[], name: string | Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
export function createClassDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
const node = <ClassDeclaration>createSynthesizedNode(SyntaxKind.ClassDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -1130,7 +1136,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateClassDeclaration(node: ClassDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, typeParameters: TypeParameterDeclaration[], heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
export function updateClassDeclaration(node: ClassDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier | undefined, typeParameters: TypeParameterDeclaration[] | undefined, heritageClauses: HeritageClause[], members: ClassElement[]) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
@@ -1141,7 +1147,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createEnumDeclaration(decorators: Decorator[], modifiers: Modifier[], name: string | Identifier, members: EnumMember[]) {
|
||||
export function createEnumDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier, members: EnumMember[]) {
|
||||
const node = <EnumDeclaration>createSynthesizedNode(SyntaxKind.EnumDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -1150,7 +1156,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateEnumDeclaration(node: EnumDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, members: EnumMember[]) {
|
||||
export function updateEnumDeclaration(node: EnumDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier, members: EnumMember[]) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
@@ -1159,7 +1165,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createModuleDeclaration(decorators: Decorator[], modifiers: Modifier[], name: ModuleName, body: ModuleBody, flags?: NodeFlags) {
|
||||
export function createModuleDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined, flags?: NodeFlags) {
|
||||
const node = <ModuleDeclaration>createSynthesizedNode(SyntaxKind.ModuleDeclaration);
|
||||
node.flags |= flags;
|
||||
node.decorators = asNodeArray(decorators);
|
||||
@@ -1169,7 +1175,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateModuleDeclaration(node: ModuleDeclaration, decorators: Decorator[], modifiers: Modifier[], name: ModuleName, body: ModuleBody) {
|
||||
export function updateModuleDeclaration(node: ModuleDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: ModuleName, body: ModuleBody | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
@@ -1179,7 +1185,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createModuleBlock(statements: Statement[]) {
|
||||
const node = <ModuleBlock>createSynthesizedNode(SyntaxKind.CaseBlock);
|
||||
const node = <ModuleBlock>createSynthesizedNode(SyntaxKind.ModuleBlock);
|
||||
node.statements = createNodeArray(statements);
|
||||
return node;
|
||||
}
|
||||
@@ -1202,7 +1208,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createImportEqualsDeclaration(decorators: Decorator[], modifiers: Modifier[], name: string | Identifier, moduleReference: ModuleReference) {
|
||||
export function createImportEqualsDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: string | Identifier, moduleReference: ModuleReference) {
|
||||
const node = <ImportEqualsDeclaration>createSynthesizedNode(SyntaxKind.ImportEqualsDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -1211,7 +1217,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Decorator[], modifiers: Modifier[], name: Identifier, moduleReference: ModuleReference) {
|
||||
export function updateImportEqualsDeclaration(node: ImportEqualsDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, name: Identifier, moduleReference: ModuleReference) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.name !== name
|
||||
@@ -1220,7 +1226,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createImportDeclaration(decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier?: Expression): ImportDeclaration {
|
||||
export function createImportDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier?: Expression): ImportDeclaration {
|
||||
const node = <ImportDeclaration>createSynthesizedNode(SyntaxKind.ImportDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -1229,7 +1235,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateImportDeclaration(node: ImportDeclaration, decorators: Decorator[], modifiers: Modifier[], importClause: ImportClause, moduleSpecifier: Expression) {
|
||||
export function updateImportDeclaration(node: ImportDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, importClause: ImportClause | undefined, moduleSpecifier: Expression | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier
|
||||
@@ -1275,21 +1281,21 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createImportSpecifier(propertyName: Identifier, name: Identifier) {
|
||||
export function createImportSpecifier(propertyName: Identifier | undefined, name: Identifier) {
|
||||
const node = <ImportSpecifier>createSynthesizedNode(SyntaxKind.ImportSpecifier);
|
||||
node.propertyName = propertyName;
|
||||
node.name = name;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier, name: Identifier) {
|
||||
export function updateImportSpecifier(node: ImportSpecifier, propertyName: Identifier | undefined, name: Identifier) {
|
||||
return node.propertyName !== propertyName
|
||||
|| node.name !== name
|
||||
? updateNode(createImportSpecifier(propertyName, name), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createExportAssignment(decorators: Decorator[], modifiers: Modifier[], isExportEquals: boolean, expression: Expression) {
|
||||
export function createExportAssignment(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, isExportEquals: boolean, expression: Expression) {
|
||||
const node = <ExportAssignment>createSynthesizedNode(SyntaxKind.ExportAssignment);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -1298,7 +1304,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateExportAssignment(node: ExportAssignment, decorators: Decorator[], modifiers: Modifier[], expression: Expression) {
|
||||
export function updateExportAssignment(node: ExportAssignment, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, expression: Expression) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.expression !== expression
|
||||
@@ -1306,7 +1312,7 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createExportDeclaration(decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier?: Expression) {
|
||||
export function createExportDeclaration(decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, exportClause: NamedExports | undefined, moduleSpecifier?: Expression) {
|
||||
const node = <ExportDeclaration>createSynthesizedNode(SyntaxKind.ExportDeclaration);
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
@@ -1315,7 +1321,7 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateExportDeclaration(node: ExportDeclaration, decorators: Decorator[], modifiers: Modifier[], exportClause: NamedExports, moduleSpecifier: Expression) {
|
||||
export function updateExportDeclaration(node: ExportDeclaration, decorators: Decorator[] | undefined, modifiers: Modifier[] | undefined, exportClause: NamedExports | undefined, moduleSpecifier: Expression | undefined) {
|
||||
return node.decorators !== decorators
|
||||
|| node.modifiers !== modifiers
|
||||
|| node.exportClause !== exportClause
|
||||
@@ -1336,16 +1342,17 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createExportSpecifier(name: string | Identifier, propertyName?: string | Identifier) {
|
||||
export function createExportSpecifier(propertyName: string | Identifier | undefined, name: string | Identifier) {
|
||||
const node = <ExportSpecifier>createSynthesizedNode(SyntaxKind.ExportSpecifier);
|
||||
node.name = asName(name);
|
||||
node.propertyName = asName(propertyName);
|
||||
node.name = asName(name);
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateExportSpecifier(node: ExportSpecifier, name: Identifier, propertyName: Identifier) {
|
||||
return node.name !== name || node.propertyName !== propertyName
|
||||
? updateNode(createExportSpecifier(name, propertyName), node)
|
||||
export function updateExportSpecifier(node: ExportSpecifier, propertyName: Identifier | undefined, name: Identifier) {
|
||||
return node.propertyName !== propertyName
|
||||
|| node.name !== name
|
||||
? updateNode(createExportSpecifier(propertyName, name), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -1381,28 +1388,28 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) {
|
||||
export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributes) {
|
||||
const node = <JsxSelfClosingElement>createSynthesizedNode(SyntaxKind.JsxSelfClosingElement);
|
||||
node.tagName = tagName;
|
||||
node.attributes = createNodeArray(attributes);
|
||||
node.attributes = attributes;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) {
|
||||
export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributes) {
|
||||
return node.tagName !== tagName
|
||||
|| node.attributes !== attributes
|
||||
? updateNode(createJsxSelfClosingElement(tagName, attributes), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) {
|
||||
export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributes) {
|
||||
const node = <JsxOpeningElement>createSynthesizedNode(SyntaxKind.JsxOpeningElement);
|
||||
node.tagName = tagName;
|
||||
node.attributes = createNodeArray(attributes);
|
||||
node.attributes = attributes;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) {
|
||||
export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributes) {
|
||||
return node.tagName !== tagName
|
||||
|| node.attributes !== attributes
|
||||
? updateNode(createJsxOpeningElement(tagName, attributes), node)
|
||||
@@ -1421,6 +1428,19 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createJsxAttributes(properties: JsxAttributeLike[]) {
|
||||
const jsxAttributes = <JsxAttributes>createSynthesizedNode(SyntaxKind.JsxAttributes);
|
||||
jsxAttributes.properties = createNodeArray(properties);
|
||||
return jsxAttributes;
|
||||
}
|
||||
|
||||
export function updateJsxAttributes(jsxAttributes: JsxAttributes, properties: JsxAttributeLike[]) {
|
||||
if (jsxAttributes.properties !== properties) {
|
||||
return updateNode(createJsxAttributes(properties), jsxAttributes);
|
||||
}
|
||||
return jsxAttributes;
|
||||
}
|
||||
|
||||
export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression) {
|
||||
const node = <JsxAttribute>createSynthesizedNode(SyntaxKind.JsxAttribute);
|
||||
node.name = name;
|
||||
@@ -1447,16 +1467,16 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
export function createJsxExpression(expression: Expression, dotDotDotToken: DotDotDotToken) {
|
||||
export function createJsxExpression(dotDotDotToken: DotDotDotToken | undefined, expression: Expression | undefined) {
|
||||
const node = <JsxExpression>createSynthesizedNode(SyntaxKind.JsxExpression);
|
||||
node.dotDotDotToken = dotDotDotToken;
|
||||
node.expression = expression;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateJsxExpression(node: JsxExpression, expression: Expression) {
|
||||
export function updateJsxExpression(node: JsxExpression, expression: Expression | undefined) {
|
||||
return node.expression !== expression
|
||||
? updateNode(createJsxExpression(expression, node.dotDotDotToken), node)
|
||||
? updateNode(createJsxExpression(node.dotDotDotToken, expression), node)
|
||||
: node;
|
||||
}
|
||||
|
||||
@@ -1534,26 +1554,26 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer: Expression) {
|
||||
export function createShorthandPropertyAssignment(name: string | Identifier, objectAssignmentInitializer?: Expression) {
|
||||
const node = <ShorthandPropertyAssignment>createSynthesizedNode(SyntaxKind.ShorthandPropertyAssignment);
|
||||
node.name = asName(name);
|
||||
node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? parenthesizeExpressionForList(objectAssignmentInitializer) : undefined;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createSpreadAssignment(expression: Expression) {
|
||||
const node = <SpreadAssignment>createSynthesizedNode(SyntaxKind.SpreadAssignment);
|
||||
node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression) {
|
||||
export function updateShorthandPropertyAssignment(node: ShorthandPropertyAssignment, name: Identifier, objectAssignmentInitializer: Expression | undefined) {
|
||||
if (node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer) {
|
||||
return updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createSpreadAssignment(expression: Expression) {
|
||||
const node = <SpreadAssignment>createSynthesizedNode(SyntaxKind.SpreadAssignment);
|
||||
node.expression = expression !== undefined ? parenthesizeExpressionForList(expression) : undefined;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateSpreadAssignment(node: SpreadAssignment, expression: Expression) {
|
||||
if (node.expression !== expression) {
|
||||
return updateNode(createSpreadAssignment(expression), node);
|
||||
@@ -1761,7 +1781,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function createExternalModuleExport(exportName: Identifier) {
|
||||
return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(exportName)]));
|
||||
return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(/*propertyName*/ undefined, exportName)]));
|
||||
}
|
||||
|
||||
// Utilities
|
||||
@@ -1842,7 +1862,7 @@ namespace ts {
|
||||
/**
|
||||
* Gets flags that control emit behavior of a node.
|
||||
*/
|
||||
export function getEmitFlags(node: Node) {
|
||||
export function getEmitFlags(node: Node): EmitFlags | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
return emitNode && emitNode.flags;
|
||||
}
|
||||
@@ -1866,7 +1886,7 @@ namespace ts {
|
||||
/**
|
||||
* Sets a custom text range to use when emitting source maps.
|
||||
*/
|
||||
export function setSourceMapRange<T extends Node>(node: T, range: TextRange) {
|
||||
export function setSourceMapRange<T extends Node>(node: T, range: TextRange | undefined) {
|
||||
getOrCreateEmitNode(node).sourceMapRange = range;
|
||||
return node;
|
||||
}
|
||||
@@ -1874,7 +1894,7 @@ namespace ts {
|
||||
/**
|
||||
* Gets the TextRange to use for source maps for a token of a node.
|
||||
*/
|
||||
export function getTokenSourceMapRange(node: Node, token: SyntaxKind) {
|
||||
export function getTokenSourceMapRange(node: Node, token: SyntaxKind): TextRange | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
const tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges;
|
||||
return tokenSourceMapRanges && tokenSourceMapRanges[token];
|
||||
@@ -1883,7 +1903,7 @@ namespace ts {
|
||||
/**
|
||||
* Sets the TextRange to use for source maps for a token of a node.
|
||||
*/
|
||||
export function setTokenSourceMapRange<T extends Node>(node: T, token: SyntaxKind, range: TextRange) {
|
||||
export function setTokenSourceMapRange<T extends Node>(node: T, token: SyntaxKind, range: TextRange | undefined) {
|
||||
const emitNode = getOrCreateEmitNode(node);
|
||||
const tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []);
|
||||
tokenSourceMapRanges[token] = range;
|
||||
@@ -1906,6 +1926,34 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
return emitNode && emitNode.leadingComments;
|
||||
}
|
||||
|
||||
export function setSyntheticLeadingComments<T extends Node>(node: T, comments: SynthesizedComment[]) {
|
||||
getOrCreateEmitNode(node).leadingComments = comments;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function addSyntheticLeadingComment<T extends Node>(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) {
|
||||
return setSyntheticLeadingComments(node, append(getSyntheticLeadingComments(node), <SynthesizedComment>{ kind, pos: -1, end: -1, hasTrailingNewLine, text }));
|
||||
}
|
||||
|
||||
export function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | undefined {
|
||||
const emitNode = node.emitNode;
|
||||
return emitNode && emitNode.trailingComments;
|
||||
}
|
||||
|
||||
export function setSyntheticTrailingComments<T extends Node>(node: T, comments: SynthesizedComment[]) {
|
||||
getOrCreateEmitNode(node).trailingComments = comments;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function addSyntheticTrailingComment<T extends Node>(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) {
|
||||
return setSyntheticTrailingComments(node, append(getSyntheticTrailingComments(node), <SynthesizedComment>{ kind, pos: -1, end: -1, hasTrailingNewLine, text }));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the constant value to emit for an expression.
|
||||
*/
|
||||
@@ -2006,7 +2054,7 @@ namespace ts {
|
||||
return compareValues(x.priority, y.priority);
|
||||
}
|
||||
|
||||
export function setOriginalNode<T extends Node>(node: T, original: Node): T {
|
||||
export function setOriginalNode<T extends Node>(node: T, original: Node | undefined): T {
|
||||
node.original = original;
|
||||
if (original) {
|
||||
const emitNode = original.emitNode;
|
||||
@@ -2018,6 +2066,8 @@ namespace ts {
|
||||
function mergeEmitNode(sourceEmitNode: EmitNode, destEmitNode: EmitNode) {
|
||||
const {
|
||||
flags,
|
||||
leadingComments,
|
||||
trailingComments,
|
||||
commentRange,
|
||||
sourceMapRange,
|
||||
tokenSourceMapRanges,
|
||||
@@ -2025,6 +2075,8 @@ namespace ts {
|
||||
helpers
|
||||
} = sourceEmitNode;
|
||||
if (!destEmitNode) destEmitNode = {};
|
||||
if (leadingComments) destEmitNode.leadingComments = addRange(leadingComments.slice(), destEmitNode.leadingComments);
|
||||
if (trailingComments) destEmitNode.trailingComments = addRange(trailingComments.slice(), destEmitNode.trailingComments);
|
||||
if (flags) destEmitNode.flags = flags;
|
||||
if (commentRange) destEmitNode.commentRange = commentRange;
|
||||
if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange;
|
||||
@@ -2198,8 +2250,129 @@ namespace ts {
|
||||
return setEmitFlags(createIdentifier(name), EmitFlags.HelperName | EmitFlags.AdviseOnEmitNode);
|
||||
}
|
||||
|
||||
const valuesHelper: EmitHelper = {
|
||||
name: "typescript:values",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __values = (this && this.__values) || function (o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
if (m) return m.call(o);
|
||||
return {
|
||||
next: function () {
|
||||
if (o && i >= o.length) o = void 0;
|
||||
return { value: o && o[i++], done: !o };
|
||||
}
|
||||
};
|
||||
};
|
||||
`
|
||||
};
|
||||
|
||||
export function createValuesHelper(context: TransformationContext, expression: Expression, location?: TextRange) {
|
||||
context.requestEmitHelper(valuesHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__values"),
|
||||
/*typeArguments*/ undefined,
|
||||
[expression]
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
const readHelper: EmitHelper = {
|
||||
name: "typescript:read",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __read = (this && this.__read) || function (o, n) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
||||
if (!m) return o;
|
||||
var i = m.call(o), r, ar = [], e;
|
||||
try {
|
||||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
||||
}
|
||||
catch (error) { e = { error: error }; }
|
||||
finally {
|
||||
try {
|
||||
if (r && !r.done && (m = i["return"])) m.call(i);
|
||||
}
|
||||
finally { if (e) throw e.error; }
|
||||
}
|
||||
return ar;
|
||||
};
|
||||
`
|
||||
};
|
||||
|
||||
export function createReadHelper(context: TransformationContext, iteratorRecord: Expression, count: number | undefined, location?: TextRange) {
|
||||
context.requestEmitHelper(readHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__read"),
|
||||
/*typeArguments*/ undefined,
|
||||
count !== undefined
|
||||
? [iteratorRecord, createLiteral(count)]
|
||||
: [iteratorRecord]
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
const spreadHelper: EmitHelper = {
|
||||
name: "typescript:spread",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __spread = (this && this.__spread) || function () {
|
||||
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
|
||||
return ar;
|
||||
};`
|
||||
};
|
||||
|
||||
export function createSpreadHelper(context: TransformationContext, argumentList: Expression[], location?: TextRange) {
|
||||
context.requestEmitHelper(readHelper);
|
||||
context.requestEmitHelper(spreadHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__spread"),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentList
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
// Utilities
|
||||
|
||||
export function createForOfBindingStatement(node: ForInitializer, boundValue: Expression): Statement {
|
||||
if (isVariableDeclarationList(node)) {
|
||||
const firstDeclaration = firstOrUndefined(node.declarations);
|
||||
const updatedDeclaration = updateVariableDeclaration(
|
||||
firstDeclaration,
|
||||
firstDeclaration.name,
|
||||
/*typeNode*/ undefined,
|
||||
boundValue
|
||||
);
|
||||
return setTextRange(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
updateVariableDeclarationList(node, [updatedDeclaration])
|
||||
),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
else {
|
||||
const updatedExpression = setTextRange(createAssignment(node, boundValue), /*location*/ node);
|
||||
return setTextRange(createStatement(updatedExpression), /*location*/ node);
|
||||
}
|
||||
}
|
||||
|
||||
export function insertLeadingStatement(dest: Statement, source: Statement) {
|
||||
if (isBlock(dest)) {
|
||||
return updateBlock(dest, setTextRange(createNodeArray([source, ...dest.statements]), dest.statements));
|
||||
}
|
||||
else {
|
||||
return createBlock(createNodeArray([dest, source]), /*multiLine*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
export function restoreEnclosingLabel(node: Statement, outermostLabeledStatement: LabeledStatement, afterRestoreLabelCallback?: (node: LabeledStatement) => void): Statement {
|
||||
if (!outermostLabeledStatement) {
|
||||
return node;
|
||||
@@ -2258,6 +2431,10 @@ namespace ts {
|
||||
? setTextRange(createIdentifier("_super"), callee)
|
||||
: <PrimaryExpression>callee;
|
||||
}
|
||||
else if (getEmitFlags(callee) & EmitFlags.HelperName) {
|
||||
thisArg = createVoidZero();
|
||||
target = parenthesizeForAccess(callee);
|
||||
}
|
||||
else {
|
||||
switch (callee.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression: {
|
||||
@@ -2671,6 +2848,16 @@ namespace ts {
|
||||
return statements;
|
||||
}
|
||||
|
||||
export function parenthesizeConditionalHead(condition: Expression) {
|
||||
const conditionalPrecedence = getOperatorPrecedence(SyntaxKind.ConditionalExpression, SyntaxKind.QuestionToken);
|
||||
const emittedCondition = skipPartiallyEmittedExpressions(condition);
|
||||
const conditionPrecedence = getExpressionPrecedence(emittedCondition);
|
||||
if (compareValues(conditionPrecedence, conditionalPrecedence) === Comparison.LessThan) {
|
||||
return createParen(condition);
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended
|
||||
* order of operations.
|
||||
|
||||
@@ -135,7 +135,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
let typeRoots: string[];
|
||||
forEachAncestorDirectory(currentDirectory, directory => {
|
||||
forEachAncestorDirectory(ts.normalizePath(currentDirectory), directory => {
|
||||
const atTypes = combinePaths(directory, nodeModulesAtTypes);
|
||||
if (host.directoryExists(atTypes)) {
|
||||
(typeRoots || (typeRoots = [])).push(atTypes);
|
||||
@@ -675,13 +675,18 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, containingFile, compilerOptions, host, cache, /* jsOnly*/ false);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function nodeModuleNameResolverWorker(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, jsOnly = false): ResolvedModuleWithFailedLookupLocations {
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
|
||||
const failedLookupLocations: string[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
|
||||
|
||||
const result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
|
||||
const result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript));
|
||||
if (result && result.value) {
|
||||
const { resolved, isExternalLibraryImport } = result.value;
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations);
|
||||
@@ -1055,4 +1060,4 @@ namespace ts {
|
||||
directory = parentPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
-12
@@ -66,6 +66,7 @@ namespace ts {
|
||||
case SyntaxKind.TypeParameter:
|
||||
return visitNode(cbNode, (<TypeParameterDeclaration>node).name) ||
|
||||
visitNode(cbNode, (<TypeParameterDeclaration>node).constraint) ||
|
||||
visitNode(cbNode, (<TypeParameterDeclaration>node).default) ||
|
||||
visitNode(cbNode, (<TypeParameterDeclaration>node).expression);
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
return visitNodes(cbNodes, node.decorators) ||
|
||||
@@ -242,7 +243,8 @@ namespace ts {
|
||||
visitNode(cbNode, (<ForInStatement>node).expression) ||
|
||||
visitNode(cbNode, (<ForInStatement>node).statement);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitNode(cbNode, (<ForOfStatement>node).initializer) ||
|
||||
return visitNode(cbNode, (<ForOfStatement>node).awaitModifier) ||
|
||||
visitNode(cbNode, (<ForOfStatement>node).initializer) ||
|
||||
visitNode(cbNode, (<ForOfStatement>node).expression) ||
|
||||
visitNode(cbNode, (<ForOfStatement>node).statement);
|
||||
case SyntaxKind.ContinueStatement:
|
||||
@@ -368,7 +370,9 @@ namespace ts {
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
return visitNode(cbNode, (<JsxOpeningLikeElement>node).tagName) ||
|
||||
visitNodes(cbNodes, (<JsxOpeningLikeElement>node).attributes);
|
||||
visitNode(cbNode, (<JsxOpeningLikeElement>node).attributes);
|
||||
case SyntaxKind.JsxAttributes:
|
||||
return visitNodes(cbNodes, (<JsxAttributes>node).properties);
|
||||
case SyntaxKind.JsxAttribute:
|
||||
return visitNode(cbNode, (<JsxAttribute>node).name) ||
|
||||
visitNode(cbNode, (<JsxAttribute>node).initializer);
|
||||
@@ -2102,6 +2106,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (parseOptional(SyntaxKind.EqualsToken)) {
|
||||
node.default = parseType();
|
||||
}
|
||||
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
@@ -3865,14 +3873,20 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function parseJsxAttributes(): JsxAttributes {
|
||||
const jsxAttributes = <JsxAttributes>createNode(SyntaxKind.JsxAttributes);
|
||||
jsxAttributes.properties = parseList(ParsingContext.JsxAttributes, parseJsxAttribute);
|
||||
return finishNode(jsxAttributes);
|
||||
}
|
||||
|
||||
function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement | JsxSelfClosingElement {
|
||||
const fullStart = scanner.getStartPos();
|
||||
|
||||
parseExpected(SyntaxKind.LessThanToken);
|
||||
|
||||
const tagName = parseJsxElementName();
|
||||
const attributes = parseJsxAttributes();
|
||||
|
||||
const attributes = parseList(ParsingContext.JsxAttributes, parseJsxAttribute);
|
||||
let node: JsxOpeningLikeElement;
|
||||
|
||||
if (token() === SyntaxKind.GreaterThanToken) {
|
||||
@@ -4448,6 +4462,7 @@ namespace ts {
|
||||
function parseForOrForInOrForOfStatement(): Statement {
|
||||
const pos = getNodePos();
|
||||
parseExpected(SyntaxKind.ForKeyword);
|
||||
const awaitToken = parseOptionalToken(SyntaxKind.AwaitKeyword);
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
|
||||
let initializer: VariableDeclarationList | Expression = undefined;
|
||||
@@ -4460,20 +4475,21 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
let forOrForInOrForOfStatement: IterationStatement;
|
||||
if (parseOptional(SyntaxKind.InKeyword)) {
|
||||
if (awaitToken ? parseExpected(SyntaxKind.OfKeyword) : parseOptional(SyntaxKind.OfKeyword)) {
|
||||
const forOfStatement = <ForOfStatement>createNode(SyntaxKind.ForOfStatement, pos);
|
||||
forOfStatement.awaitModifier = awaitToken;
|
||||
forOfStatement.initializer = initializer;
|
||||
forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
forOrForInOrForOfStatement = forOfStatement;
|
||||
}
|
||||
else if (parseOptional(SyntaxKind.InKeyword)) {
|
||||
const forInStatement = <ForInStatement>createNode(SyntaxKind.ForInStatement, pos);
|
||||
forInStatement.initializer = initializer;
|
||||
forInStatement.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
forOrForInOrForOfStatement = forInStatement;
|
||||
}
|
||||
else if (parseOptional(SyntaxKind.OfKeyword)) {
|
||||
const forOfStatement = <ForOfStatement>createNode(SyntaxKind.ForOfStatement, pos);
|
||||
forOfStatement.initializer = initializer;
|
||||
forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
forOrForInOrForOfStatement = forOfStatement;
|
||||
}
|
||||
else {
|
||||
const forStatement = <ForStatement>createNode(SyntaxKind.ForStatement, pos);
|
||||
forStatement.initializer = initializer;
|
||||
@@ -5816,7 +5832,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const range = { pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), kind: triviaScanner.getToken() };
|
||||
const range = {
|
||||
kind: <SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia>triviaScanner.getToken(),
|
||||
pos: triviaScanner.getTokenPos(),
|
||||
end: triviaScanner.getTextPos(),
|
||||
};
|
||||
|
||||
const comment = sourceText.substring(range.pos, range.end);
|
||||
const referencePathMatchResult = getFileReferenceFromReferencePath(comment, range);
|
||||
|
||||
@@ -754,15 +754,15 @@ namespace ts {
|
||||
return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = createTypeChecker(program, /*produceDiagnostics:*/ false));
|
||||
}
|
||||
|
||||
function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
return runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles));
|
||||
function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers): EmitResult {
|
||||
return runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers));
|
||||
}
|
||||
|
||||
function isEmitBlocked(emitFileName: string): boolean {
|
||||
return hasEmitBlockingDiagnostics.contains(toPath(emitFileName, currentDirectory, getCanonicalFileName));
|
||||
}
|
||||
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
function emitWorker(program: Program, sourceFile: SourceFile, writeFileCallback: WriteFileCallback, cancellationToken: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult {
|
||||
let declarationDiagnostics: Diagnostic[] = [];
|
||||
|
||||
if (options.noEmit) {
|
||||
@@ -804,11 +804,13 @@ namespace ts {
|
||||
|
||||
performance.mark("beforeEmit");
|
||||
|
||||
const transformers = emitOnlyDtsFiles ? [] : getTransformers(options, customTransformers);
|
||||
const emitResult = emitFiles(
|
||||
emitResolver,
|
||||
getEmitHost(writeFileCallback),
|
||||
sourceFile,
|
||||
emitOnlyDtsFiles);
|
||||
emitOnlyDtsFiles,
|
||||
transformers);
|
||||
|
||||
performance.mark("afterEmit");
|
||||
performance.measure("Emit", "beforeEmit", "afterEmit");
|
||||
|
||||
@@ -608,10 +608,10 @@ namespace ts {
|
||||
* @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy
|
||||
* return value of the callback.
|
||||
*/
|
||||
function iterateCommentRanges<T, U>(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial?: U): U {
|
||||
function iterateCommentRanges<T, U>(reduce: boolean, text: string, pos: number, trailing: boolean, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial?: U): U {
|
||||
let pendingPos: number;
|
||||
let pendingEnd: number;
|
||||
let pendingKind: SyntaxKind;
|
||||
let pendingKind: CommentKind;
|
||||
let pendingHasTrailingNewLine: boolean;
|
||||
let hasPendingCommentRange = false;
|
||||
let collecting = trailing || pos === 0;
|
||||
@@ -707,28 +707,28 @@ namespace ts {
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
export function forEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state);
|
||||
}
|
||||
|
||||
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
export function forEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T) {
|
||||
return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state);
|
||||
}
|
||||
|
||||
export function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
export function reduceEachLeadingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial);
|
||||
}
|
||||
|
||||
export function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
export function reduceEachTrailingCommentRange<T, U>(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) {
|
||||
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
|
||||
}
|
||||
|
||||
function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) {
|
||||
function appendCommentRange(pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) {
|
||||
if (!comments) {
|
||||
comments = [];
|
||||
}
|
||||
|
||||
comments.push({ pos, end, hasTrailingNewLine, kind });
|
||||
comments.push({ kind, pos, end, hasTrailingNewLine });
|
||||
return comments;
|
||||
}
|
||||
|
||||
|
||||
+20
-12
@@ -59,6 +59,21 @@ namespace ts {
|
||||
declare var global: any;
|
||||
declare var __filename: string;
|
||||
|
||||
export function getNodeMajorVersion() {
|
||||
if (typeof process === "undefined") {
|
||||
return undefined;
|
||||
}
|
||||
const version: string = process.version;
|
||||
if (!version) {
|
||||
return undefined;
|
||||
}
|
||||
const dot = version.indexOf(".");
|
||||
if (dot === -1) {
|
||||
return undefined;
|
||||
}
|
||||
return parseInt(version.substring(1, dot));
|
||||
}
|
||||
|
||||
declare class Enumerator {
|
||||
public atEnd(): boolean;
|
||||
public moveNext(): boolean;
|
||||
@@ -315,9 +330,8 @@ namespace ts {
|
||||
}
|
||||
const watchedFileSet = createWatchedFileSet();
|
||||
|
||||
function isNode4OrLater(): boolean {
|
||||
return parseInt(process.version.charAt(1)) >= 4;
|
||||
}
|
||||
const nodeVersion = getNodeMajorVersion();
|
||||
const isNode4OrLater = nodeVersion >= 4;
|
||||
|
||||
function isFileSystemCaseSensitive(): boolean {
|
||||
// win32\win64 are case insensitive platforms
|
||||
@@ -485,14 +499,12 @@ namespace ts {
|
||||
// Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows
|
||||
// (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643)
|
||||
let options: any;
|
||||
if (!directoryExists(directoryName) || (isUNCPath(directoryName) && process.platform === "win32")) {
|
||||
// do nothing if either
|
||||
// - target folder does not exist
|
||||
// - this is UNC path on Windows (https://github.com/Microsoft/TypeScript/issues/13874)
|
||||
if (!directoryExists(directoryName)) {
|
||||
// do nothing if target folder does not exist
|
||||
return noOpFileWatcher;
|
||||
}
|
||||
|
||||
if (isNode4OrLater() && (process.platform === "win32" || process.platform === "darwin")) {
|
||||
if (isNode4OrLater && (process.platform === "win32" || process.platform === "darwin")) {
|
||||
options = { persistent: true, recursive: !!recursive };
|
||||
}
|
||||
else {
|
||||
@@ -512,10 +524,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
function isUNCPath(s: string): boolean {
|
||||
return s.length > 2 && s.charCodeAt(0) === CharacterCodes.slash && s.charCodeAt(1) === CharacterCodes.slash;
|
||||
}
|
||||
},
|
||||
resolvePath: function(path: string): string {
|
||||
return _path.resolve(path);
|
||||
|
||||
+99
-49
@@ -13,7 +13,7 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
function getModuleTransformer(moduleKind: ModuleKind): Transformer {
|
||||
function getModuleTransformer(moduleKind: ModuleKind): TransformerFactory<SourceFile> {
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.ES2015:
|
||||
return transformES2015Module;
|
||||
@@ -24,16 +24,25 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const enum TransformationState {
|
||||
Uninitialized,
|
||||
Initialized,
|
||||
Completed,
|
||||
Disposed
|
||||
}
|
||||
|
||||
const enum SyntaxKindFeatureFlags {
|
||||
Substitution = 1 << 0,
|
||||
EmitNotifications = 1 << 1,
|
||||
}
|
||||
|
||||
export function getTransformers(compilerOptions: CompilerOptions) {
|
||||
export function getTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers) {
|
||||
const jsx = compilerOptions.jsx;
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
const transformers: Transformer[] = [];
|
||||
const transformers: TransformerFactory<SourceFile>[] = [];
|
||||
|
||||
addRange(transformers, customTransformers && customTransformers.before);
|
||||
|
||||
transformers.push(transformTypeScript);
|
||||
|
||||
@@ -66,6 +75,8 @@ namespace ts {
|
||||
transformers.push(transformES5);
|
||||
}
|
||||
|
||||
addRange(transformers, customTransformers && customTransformers.after);
|
||||
|
||||
return transformers;
|
||||
}
|
||||
|
||||
@@ -73,28 +84,29 @@ namespace ts {
|
||||
* Transforms an array of SourceFiles by passing them through each transformer.
|
||||
*
|
||||
* @param resolver The emit resolver provided by the checker.
|
||||
* @param host The emit host.
|
||||
* @param sourceFiles An array of source files
|
||||
* @param transforms An array of Transformers.
|
||||
* @param host The emit host object used to interact with the file system.
|
||||
* @param options Compiler options to surface in the `TransformationContext`.
|
||||
* @param nodes An array of nodes to transform.
|
||||
* @param transforms An array of `TransformerFactory` callbacks.
|
||||
* @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files.
|
||||
*/
|
||||
export function transformFiles(resolver: EmitResolver, host: EmitHost, sourceFiles: SourceFile[], transformers: Transformer[]): TransformationResult {
|
||||
export function transformNodes<T extends Node>(resolver: EmitResolver, host: EmitHost, options: CompilerOptions, nodes: T[], transformers: TransformerFactory<T>[], allowDtsFiles: boolean): TransformationResult<T> {
|
||||
const enabledSyntaxKindFeatures = new Array<SyntaxKindFeatureFlags>(SyntaxKind.Count);
|
||||
|
||||
let lexicalEnvironmentDisabled = false;
|
||||
|
||||
let lexicalEnvironmentVariableDeclarations: VariableDeclaration[];
|
||||
let lexicalEnvironmentFunctionDeclarations: FunctionDeclaration[];
|
||||
let lexicalEnvironmentVariableDeclarationsStack: VariableDeclaration[][] = [];
|
||||
let lexicalEnvironmentFunctionDeclarationsStack: FunctionDeclaration[][] = [];
|
||||
let lexicalEnvironmentStackOffset = 0;
|
||||
let lexicalEnvironmentSuspended = false;
|
||||
|
||||
let emitHelpers: EmitHelper[];
|
||||
let onSubstituteNode: TransformationContext["onSubstituteNode"] = (_, node) => node;
|
||||
let onEmitNode: TransformationContext["onEmitNode"] = (hint, node, callback) => callback(hint, node);
|
||||
let state = TransformationState.Uninitialized;
|
||||
|
||||
// The transformation context is provided to each transformer as part of transformer
|
||||
// initialization.
|
||||
const context: TransformationContext = {
|
||||
getCompilerOptions: () => host.getCompilerOptions(),
|
||||
getCompilerOptions: () => options,
|
||||
getEmitResolver: () => resolver,
|
||||
getEmitHost: () => host,
|
||||
startLexicalEnvironment,
|
||||
@@ -105,51 +117,62 @@ namespace ts {
|
||||
hoistFunctionDeclaration,
|
||||
requestEmitHelper,
|
||||
readEmitHelpers,
|
||||
onSubstituteNode: (_, node) => node,
|
||||
enableSubstitution,
|
||||
isSubstitutionEnabled,
|
||||
onEmitNode: (hint, node, callback) => callback(hint, node),
|
||||
enableEmitNotification,
|
||||
isEmitNotificationEnabled
|
||||
isSubstitutionEnabled,
|
||||
isEmitNotificationEnabled,
|
||||
get onSubstituteNode() { return onSubstituteNode },
|
||||
set onSubstituteNode(value) {
|
||||
Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed.");
|
||||
Debug.assert(value !== undefined, "Value must not be 'undefined'");
|
||||
onSubstituteNode = value;
|
||||
},
|
||||
get onEmitNode() { return onEmitNode },
|
||||
set onEmitNode(value) {
|
||||
Debug.assert(state < TransformationState.Initialized, "Cannot modify transformation hooks after initialization has completed.");
|
||||
Debug.assert(value !== undefined, "Value must not be 'undefined'");
|
||||
onEmitNode = value;
|
||||
}
|
||||
};
|
||||
|
||||
// Ensure the parse tree is clean before applying transformations
|
||||
for (const node of nodes) {
|
||||
disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node)));
|
||||
}
|
||||
|
||||
performance.mark("beforeTransform");
|
||||
|
||||
// Chain together and initialize each transformer.
|
||||
const transformation = chain(...transformers)(context);
|
||||
|
||||
// Transform each source file.
|
||||
const transformed = map(sourceFiles, transformSourceFile);
|
||||
// prevent modification of transformation hooks.
|
||||
state = TransformationState.Initialized;
|
||||
|
||||
// Disable modification of the lexical environment.
|
||||
lexicalEnvironmentDisabled = true;
|
||||
// Transform each node.
|
||||
const transformed = map(nodes, allowDtsFiles ? transformation : transformRoot);
|
||||
|
||||
// prevent modification of the lexical environment.
|
||||
state = TransformationState.Completed;
|
||||
|
||||
performance.mark("afterTransform");
|
||||
performance.measure("transformTime", "beforeTransform", "afterTransform");
|
||||
|
||||
return {
|
||||
transformed,
|
||||
emitNodeWithSubstitution,
|
||||
emitNodeWithNotification
|
||||
substituteNode,
|
||||
emitNodeWithNotification,
|
||||
dispose
|
||||
};
|
||||
|
||||
/**
|
||||
* Transforms a source file.
|
||||
*
|
||||
* @param sourceFile The source file to transform.
|
||||
*/
|
||||
function transformSourceFile(sourceFile: SourceFile) {
|
||||
if (isDeclarationFile(sourceFile)) {
|
||||
return sourceFile;
|
||||
}
|
||||
|
||||
return transformation(sourceFile);
|
||||
function transformRoot(node: T) {
|
||||
return node && (!isSourceFile(node) || !isDeclarationFile(node)) ? transformation(node) : node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables expression substitutions in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
function enableSubstitution(kind: SyntaxKind) {
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
enabledSyntaxKindFeatures[kind] |= SyntaxKindFeatureFlags.Substitution;
|
||||
}
|
||||
|
||||
@@ -168,19 +191,16 @@ namespace ts {
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback The callback used to emit the node or its substitute.
|
||||
*/
|
||||
function emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
if (node) {
|
||||
if (isSubstitutionEnabled(node)) {
|
||||
node = context.onSubstituteNode(hint, node) || node;
|
||||
}
|
||||
emitCallback(hint, node);
|
||||
}
|
||||
function substituteNode(hint: EmitHint, node: Node) {
|
||||
Debug.assert(state < TransformationState.Disposed, "Cannot substitute a node after the result is disposed.");
|
||||
return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
function enableEmitNotification(kind: SyntaxKind) {
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
enabledSyntaxKindFeatures[kind] |= SyntaxKindFeatureFlags.EmitNotifications;
|
||||
}
|
||||
|
||||
@@ -201,9 +221,10 @@ namespace ts {
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
Debug.assert(state < TransformationState.Disposed, "Cannot invoke TransformationResult callbacks after the result is disposed.");
|
||||
if (node) {
|
||||
if (isEmitNotificationEnabled(node)) {
|
||||
context.onEmitNode(hint, node, emitCallback);
|
||||
onEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
else {
|
||||
emitCallback(hint, node);
|
||||
@@ -215,7 +236,8 @@ namespace ts {
|
||||
* Records a hoisted variable declaration for the provided name within a lexical environment.
|
||||
*/
|
||||
function hoistVariableDeclaration(name: Identifier): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
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);
|
||||
if (!lexicalEnvironmentVariableDeclarations) {
|
||||
lexicalEnvironmentVariableDeclarations = [decl];
|
||||
@@ -229,7 +251,8 @@ namespace ts {
|
||||
* Records a hoisted function declaration within a lexical environment.
|
||||
*/
|
||||
function hoistFunctionDeclaration(func: FunctionDeclaration): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
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.");
|
||||
if (!lexicalEnvironmentFunctionDeclarations) {
|
||||
lexicalEnvironmentFunctionDeclarations = [func];
|
||||
}
|
||||
@@ -243,7 +266,8 @@ namespace ts {
|
||||
* are pushed onto a stack, and the related storage variables are reset.
|
||||
*/
|
||||
function startLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot start a lexical environment during the print phase.");
|
||||
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.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
|
||||
|
||||
// Save the current lexical environment. Rather than resizing the array we adjust the
|
||||
@@ -259,14 +283,16 @@ namespace ts {
|
||||
|
||||
/** Suspends the current lexical environment, usually after visiting a parameter list. */
|
||||
function suspendLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot suspend a lexical environment during the print phase.");
|
||||
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.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended.");
|
||||
lexicalEnvironmentSuspended = true;
|
||||
}
|
||||
|
||||
/** Resumes a suspended lexical environment, usually before visiting a function body. */
|
||||
function resumeLexicalEnvironment(): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot resume a lexical environment during the print phase.");
|
||||
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.");
|
||||
Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended.");
|
||||
lexicalEnvironmentSuspended = false;
|
||||
}
|
||||
@@ -276,7 +302,8 @@ namespace ts {
|
||||
* any hoisted declarations added in this environment are returned.
|
||||
*/
|
||||
function endLexicalEnvironment(): Statement[] {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot end a lexical environment during the print phase.");
|
||||
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.");
|
||||
Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended.");
|
||||
|
||||
let statements: Statement[];
|
||||
@@ -312,16 +339,39 @@ namespace ts {
|
||||
}
|
||||
|
||||
function requestEmitHelper(helper: EmitHelper): void {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
Debug.assert(!helper.scoped, "Cannot request a scoped emit helper.");
|
||||
emitHelpers = append(emitHelpers, helper);
|
||||
}
|
||||
|
||||
function readEmitHelpers(): EmitHelper[] | undefined {
|
||||
Debug.assert(!lexicalEnvironmentDisabled, "Cannot modify the lexical environment during the print phase.");
|
||||
Debug.assert(state > TransformationState.Uninitialized, "Cannot modify the transformation context during initialization.");
|
||||
Debug.assert(state < TransformationState.Completed, "Cannot modify the transformation context after transformation has completed.");
|
||||
const helpers = emitHelpers;
|
||||
emitHelpers = undefined;
|
||||
return helpers;
|
||||
}
|
||||
|
||||
function dispose() {
|
||||
if (state < TransformationState.Disposed) {
|
||||
// Clean up emit nodes on parse tree
|
||||
for (const node of nodes) {
|
||||
disposeEmitNodes(getSourceFileOfNode(getParseTreeNode(node)));
|
||||
}
|
||||
|
||||
// Release references to external entries for GC purposes.
|
||||
lexicalEnvironmentVariableDeclarations = undefined;
|
||||
lexicalEnvironmentVariableDeclarationsStack = undefined;
|
||||
lexicalEnvironmentFunctionDeclarations = undefined;
|
||||
lexicalEnvironmentFunctionDeclarationsStack = undefined;
|
||||
onSubstituteNode = undefined;
|
||||
onEmitNode = undefined;
|
||||
emitHelpers = undefined;
|
||||
|
||||
// Prevent further use of the transformation result.
|
||||
state = TransformationState.Disposed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace ts {
|
||||
interface FlattenContext {
|
||||
context: TransformationContext;
|
||||
level: FlattenLevel;
|
||||
downlevelIteration: boolean;
|
||||
hoistTempVariables: boolean;
|
||||
emitExpression: (value: Expression) => void;
|
||||
emitBindingOrAssignment: (target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node) => void;
|
||||
@@ -57,6 +58,7 @@ namespace ts {
|
||||
const flattenContext: FlattenContext = {
|
||||
context,
|
||||
level,
|
||||
downlevelIteration: context.getCompilerOptions().downlevelIteration,
|
||||
hoistTempVariables: true,
|
||||
emitExpression,
|
||||
emitBindingOrAssignment,
|
||||
@@ -146,6 +148,7 @@ namespace ts {
|
||||
const flattenContext: FlattenContext = {
|
||||
context,
|
||||
level,
|
||||
downlevelIteration: context.getCompilerOptions().downlevelIteration,
|
||||
hoistTempVariables,
|
||||
emitExpression,
|
||||
emitBindingOrAssignment,
|
||||
@@ -312,7 +315,23 @@ namespace ts {
|
||||
function flattenArrayBindingOrAssignmentPattern(flattenContext: FlattenContext, parent: BindingOrAssignmentElement, pattern: ArrayBindingOrAssignmentPattern, value: Expression, location: TextRange) {
|
||||
const elements = getElementsOfBindingOrAssignmentPattern(pattern);
|
||||
const numElements = elements.length;
|
||||
if (numElements !== 1 && (flattenContext.level < FlattenLevel.ObjectRest || numElements === 0)) {
|
||||
if (flattenContext.level < FlattenLevel.ObjectRest && flattenContext.downlevelIteration) {
|
||||
// Read the elements of the iterable into an array
|
||||
value = ensureIdentifier(
|
||||
flattenContext,
|
||||
createReadHelper(
|
||||
flattenContext.context,
|
||||
value,
|
||||
numElements > 0 && getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1])
|
||||
? undefined
|
||||
: numElements,
|
||||
location
|
||||
),
|
||||
/*reuseIdentifierExpressions*/ false,
|
||||
location
|
||||
);
|
||||
}
|
||||
else if (numElements !== 1 && (flattenContext.level < FlattenLevel.ObjectRest || numElements === 0)) {
|
||||
// For anything other than a single-element destructuring we need to generate a temporary
|
||||
// to ensure value is evaluated exactly once. Additionally, if we have zero elements
|
||||
// we need to emit *something* to ensure that in case a 'var' keyword was already emitted,
|
||||
@@ -448,7 +467,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function makeBindingElement(name: Identifier) {
|
||||
return createBindingElement(/*propertyName*/ undefined, /*dotDotDotToken*/ undefined, name);
|
||||
return createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name);
|
||||
}
|
||||
|
||||
function makeAssignmentElement(name: Identifier) {
|
||||
|
||||
+244
-119
@@ -1,5 +1,6 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
/// <reference path="./destructuring.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
@@ -268,6 +269,7 @@ namespace ts {
|
||||
hoistVariableDeclaration,
|
||||
} = context;
|
||||
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const resolver = context.getEmitResolver();
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
@@ -1716,6 +1718,7 @@ namespace ts {
|
||||
return updateFunctionExpression(
|
||||
node,
|
||||
/*modifiers*/ undefined,
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
@@ -1747,6 +1750,7 @@ namespace ts {
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
name,
|
||||
/*typeParameters*/ undefined,
|
||||
parameters,
|
||||
@@ -1939,6 +1943,9 @@ namespace ts {
|
||||
function visitParenthesizedExpression(node: ParenthesizedExpression, needsDestructuringValue: boolean): ParenthesizedExpression {
|
||||
// If we are here it is most likely because our expression is a destructuring assignment.
|
||||
if (!needsDestructuringValue) {
|
||||
// By default we always emit the RHS at the end of a flattened destructuring
|
||||
// expression. If we are in a state where we do not need the destructuring value,
|
||||
// we pass that information along to the children that care about it.
|
||||
switch (node.expression.kind) {
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return updateParen(node, visitParenthesizedExpression(<ParenthesizedExpression>node.expression, /*needsDestructuringValue*/ false));
|
||||
@@ -1990,7 +1997,8 @@ namespace ts {
|
||||
else {
|
||||
assignment = createBinary(<Identifier>decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression));
|
||||
}
|
||||
(assignments || (assignments = [])).push(assignment);
|
||||
|
||||
assignments = append(assignments, assignment);
|
||||
}
|
||||
}
|
||||
if (assignments) {
|
||||
@@ -2172,12 +2180,26 @@ namespace ts {
|
||||
if (convertedLoopState && !convertedLoopState.labels) {
|
||||
convertedLoopState.labels = createMap<string>();
|
||||
}
|
||||
const statement = unwrapInnermostStatmentOfLabel(node, convertedLoopState && recordLabel);
|
||||
return isIterationStatement(statement, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(statement)
|
||||
const statement = unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel);
|
||||
return isIterationStatement(statement, /*lookInLabeledStatements*/ false)
|
||||
? visitIterationStatement(statement, /*outermostLabeledStatement*/ node)
|
||||
: restoreEnclosingLabel(visitNode(statement, visitor, isStatement), node, convertedLoopState && resetLabel);
|
||||
}
|
||||
|
||||
function visitIterationStatement(node: IterationStatement, outermostLabeledStatement: LabeledStatement) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
return visitDoOrWhileStatement(<DoStatement | WhileStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForStatement:
|
||||
return visitForStatement(<ForStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForInStatement:
|
||||
return visitForInStatement(<ForInStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitForOfStatement(<ForOfStatement>node, outermostLabeledStatement);
|
||||
}
|
||||
}
|
||||
|
||||
function visitIterationStatementWithFacts(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts, node: IterationStatement, outermostLabeledStatement: LabeledStatement, convert?: LoopConverter) {
|
||||
const ancestorFacts = enterSubtree(excludeFacts, includeFacts);
|
||||
const updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, convert);
|
||||
@@ -2215,54 +2237,17 @@ namespace ts {
|
||||
HierarchyFacts.ForInOrForOfStatementIncludes,
|
||||
node,
|
||||
outermostLabeledStatement,
|
||||
convertForOfToFor);
|
||||
compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray);
|
||||
}
|
||||
|
||||
function convertForOfToFor(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[]): Statement {
|
||||
// The following ES6 code:
|
||||
//
|
||||
// for (let v of expr) { }
|
||||
//
|
||||
// should be emitted as
|
||||
//
|
||||
// for (var _i = 0, _a = expr; _i < _a.length; _i++) {
|
||||
// var v = _a[_i];
|
||||
// }
|
||||
//
|
||||
// where _a and _i are temps emitted to capture the RHS and the counter,
|
||||
// respectively.
|
||||
// When the left hand side is an expression instead of a let declaration,
|
||||
// the "let v" is not emitted.
|
||||
// When the left hand side is a let/const, the v is renamed if there is
|
||||
// another v in scope.
|
||||
// Note that all assignments to the LHS are emitted in the body, including
|
||||
// all destructuring.
|
||||
// Note also that because an extra statement is needed to assign to the LHS,
|
||||
// for-of bodies are always emitted as blocks.
|
||||
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const initializer = node.initializer;
|
||||
function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression, convertedLoopBodyStatements: Statement[]) {
|
||||
const statements: Statement[] = [];
|
||||
|
||||
// In the case where the user wrote an identifier as the RHS, like this:
|
||||
//
|
||||
// for (let v of arr) { }
|
||||
//
|
||||
// we don't want to emit a temporary variable for the RHS, just use it directly.
|
||||
const counter = createLoopVariable();
|
||||
const rhsReference = expression.kind === SyntaxKind.Identifier
|
||||
? createUniqueName(unescapeIdentifier((<Identifier>expression).text))
|
||||
: createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const elementAccess = createElementAccess(rhsReference, counter);
|
||||
|
||||
// Initialize LHS
|
||||
// var v = _a[_i];
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
if (initializer.flags & NodeFlags.BlockScoped) {
|
||||
if (isVariableDeclarationList(node.initializer)) {
|
||||
if (node.initializer.flags & NodeFlags.BlockScoped) {
|
||||
enableSubstitutionsForBlockScopedBindings();
|
||||
}
|
||||
|
||||
const firstOriginalDeclaration = firstOrUndefined(initializer.declarations);
|
||||
const firstOriginalDeclaration = firstOrUndefined(node.initializer.declarations);
|
||||
if (firstOriginalDeclaration && isBindingPattern(firstOriginalDeclaration.name)) {
|
||||
// This works whether the declaration is a var, let, or const.
|
||||
// It will use rhsIterationValue _a[_i] as the initializer.
|
||||
@@ -2271,12 +2256,11 @@ namespace ts {
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.All,
|
||||
elementAccess
|
||||
boundValue
|
||||
);
|
||||
|
||||
const declarationList = createVariableDeclarationList(declarations);
|
||||
setOriginalNode(declarationList, initializer);
|
||||
setTextRange(declarationList, initializer);
|
||||
const declarationList = setTextRange(createVariableDeclarationList(declarations), node.initializer);
|
||||
setOriginalNode(declarationList, node.initializer);
|
||||
|
||||
// Adjust the source map range for the first declaration to align with the old
|
||||
// emitter.
|
||||
@@ -2304,15 +2288,15 @@ namespace ts {
|
||||
createVariableDeclaration(
|
||||
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
|
||||
/*type*/ undefined,
|
||||
createElementAccess(rhsReference, counter)
|
||||
boundValue
|
||||
)
|
||||
]),
|
||||
moveRangePos(initializer, -1)
|
||||
moveRangePos(node.initializer, -1)
|
||||
),
|
||||
initializer
|
||||
node.initializer
|
||||
)
|
||||
),
|
||||
moveRangeEnd(initializer, -1)
|
||||
moveRangeEnd(node.initializer, -1)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -2320,25 +2304,14 @@ namespace ts {
|
||||
else {
|
||||
// Initializer is an expression. Emit the expression in the body, so that it's
|
||||
// evaluated on every iteration.
|
||||
const assignment = createAssignment(initializer, elementAccess);
|
||||
const assignment = createAssignment(node.initializer, boundValue);
|
||||
if (isDestructuringAssignment(assignment)) {
|
||||
// This is a destructuring pattern, so we flatten the destructuring instead.
|
||||
statements.push(
|
||||
createStatement(
|
||||
flattenDestructuringAssignment(
|
||||
assignment,
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.All
|
||||
)
|
||||
)
|
||||
);
|
||||
aggregateTransformFlags(assignment);
|
||||
statements.push(createStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false)));
|
||||
}
|
||||
else {
|
||||
// Currently there is not way to check that assignment is binary expression of destructing assignment
|
||||
// so we have to cast never type to binaryExpression
|
||||
(<BinaryExpression>assignment).end = initializer.end;
|
||||
statements.push(setTextRange(createStatement(assignment), moveRangeEnd(initializer, -1)));
|
||||
assignment.end = node.initializer.end;
|
||||
statements.push(setTextRange(createStatement(visitNode(assignment, visitor, isExpression)), moveRangeEnd(node.initializer, -1)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2348,7 +2321,7 @@ namespace ts {
|
||||
addRange(statements, convertedLoopBodyStatements);
|
||||
}
|
||||
else {
|
||||
const statement = visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock);
|
||||
const statement = visitNode(node.statement, visitor, isStatement, liftToBlock);
|
||||
if (isBlock(statement)) {
|
||||
addRange(statements, statement.statements);
|
||||
bodyLocation = statement;
|
||||
@@ -2359,38 +2332,82 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// The old emitter does not emit source maps for the block.
|
||||
// We add the location to preserve comments.
|
||||
return setEmitFlags(
|
||||
setTextRange(
|
||||
createBlock(
|
||||
setTextRange(createNodeArray(statements), statementsLocation),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
bodyLocation,
|
||||
),
|
||||
EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps
|
||||
);
|
||||
}
|
||||
|
||||
function convertForOfStatementForArray(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[]): Statement {
|
||||
// The following ES6 code:
|
||||
//
|
||||
// for (let v of expr) { }
|
||||
//
|
||||
// should be emitted as
|
||||
//
|
||||
// for (var _i = 0, _a = expr; _i < _a.length; _i++) {
|
||||
// var v = _a[_i];
|
||||
// }
|
||||
//
|
||||
// where _a and _i are temps emitted to capture the RHS and the counter,
|
||||
// respectively.
|
||||
// When the left hand side is an expression instead of a let declaration,
|
||||
// the "let v" is not emitted.
|
||||
// When the left hand side is a let/const, the v is renamed if there is
|
||||
// another v in scope.
|
||||
// Note that all assignments to the LHS are emitted in the body, including
|
||||
// all destructuring.
|
||||
// Note also that because an extra statement is needed to assign to the LHS,
|
||||
// for-of bodies are always emitted as blocks.
|
||||
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
|
||||
// In the case where the user wrote an identifier as the RHS, like this:
|
||||
//
|
||||
// for (let v of arr) { }
|
||||
//
|
||||
// we don't want to emit a temporary variable for the RHS, just use it directly.
|
||||
const counter = createLoopVariable();
|
||||
const rhsReference = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
|
||||
// The old emitter does not emit source maps for the expression
|
||||
setEmitFlags(expression, EmitFlags.NoSourceMap | getEmitFlags(expression));
|
||||
|
||||
// The old emitter does not emit source maps for the block.
|
||||
// We add the location to preserve comments.
|
||||
const body = createBlock(setTextRange(createNodeArray(statements), /*location*/ statementsLocation));
|
||||
setTextRange(body, bodyLocation);
|
||||
setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps);
|
||||
|
||||
const forStatement = createFor(
|
||||
setEmitFlags(
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0)), moveRangePos(node.expression, -1)),
|
||||
setTextRange(createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
|
||||
]),
|
||||
const forStatement = setTextRange(
|
||||
createFor(
|
||||
/*initializer*/ setEmitFlags(
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0)), moveRangePos(node.expression, -1)),
|
||||
setTextRange(createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression)
|
||||
]),
|
||||
node.expression
|
||||
),
|
||||
EmitFlags.NoHoisting
|
||||
),
|
||||
/*condition*/ setTextRange(
|
||||
createLessThan(
|
||||
counter,
|
||||
createPropertyAccess(rhsReference, "length")
|
||||
),
|
||||
node.expression
|
||||
),
|
||||
EmitFlags.NoHoisting
|
||||
/*incrementor*/ setTextRange(createPostfixIncrement(counter), node.expression),
|
||||
/*statement*/ convertForOfStatementHead(
|
||||
node,
|
||||
createElementAccess(rhsReference, counter),
|
||||
convertedLoopBodyStatements
|
||||
)
|
||||
),
|
||||
setTextRange(
|
||||
createLessThan(
|
||||
counter,
|
||||
createPropertyAccess(rhsReference, "length")
|
||||
),
|
||||
node.expression
|
||||
),
|
||||
setTextRange(
|
||||
createPostfixIncrement(counter),
|
||||
node.expression
|
||||
),
|
||||
body
|
||||
/*location*/ node
|
||||
);
|
||||
|
||||
// Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter.
|
||||
@@ -2399,18 +2416,110 @@ namespace ts {
|
||||
return restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel);
|
||||
}
|
||||
|
||||
function visitIterationStatement(node: IterationStatement, outermostLabeledStatement: LabeledStatement) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.DoStatement:
|
||||
case SyntaxKind.WhileStatement:
|
||||
return visitDoOrWhileStatement(<DoStatement | WhileStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForStatement:
|
||||
return visitForStatement(<ForStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForInStatement:
|
||||
return visitForInStatement(<ForInStatement>node, outermostLabeledStatement);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitForOfStatement(<ForOfStatement>node, outermostLabeledStatement);
|
||||
}
|
||||
function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[]): Statement {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const iterator = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const result = isIdentifier(expression) ? getGeneratedNameForNode(iterator) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const errorRecord = createUniqueName("e");
|
||||
const catchVariable = getGeneratedNameForNode(errorRecord);
|
||||
const returnMethod = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const values = createValuesHelper(context, expression, node.expression);
|
||||
const next = createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, []);
|
||||
|
||||
hoistVariableDeclaration(errorRecord);
|
||||
hoistVariableDeclaration(returnMethod);
|
||||
|
||||
const forStatement = setEmitFlags(
|
||||
setTextRange(
|
||||
createFor(
|
||||
/*initializer*/ setEmitFlags(
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(iterator, /*type*/ undefined, values), node.expression),
|
||||
createVariableDeclaration(result, /*type*/ undefined, next)
|
||||
]),
|
||||
node.expression
|
||||
),
|
||||
EmitFlags.NoHoisting
|
||||
),
|
||||
/*condition*/ createLogicalNot(createPropertyAccess(result, "done")),
|
||||
/*incrementor*/ createAssignment(result, next),
|
||||
/*statement*/ convertForOfStatementHead(
|
||||
node,
|
||||
createPropertyAccess(result, "value"),
|
||||
convertedLoopBodyStatements
|
||||
)
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
EmitFlags.NoTokenTrailingSourceMaps
|
||||
);
|
||||
|
||||
return createTry(
|
||||
createBlock([
|
||||
restoreEnclosingLabel(
|
||||
forStatement,
|
||||
outermostLabeledStatement,
|
||||
convertedLoopState && resetLabel
|
||||
)
|
||||
]),
|
||||
createCatchClause(createVariableDeclaration(catchVariable),
|
||||
setEmitFlags(
|
||||
createBlock([
|
||||
createStatement(
|
||||
createAssignment(
|
||||
errorRecord,
|
||||
createObjectLiteral([
|
||||
createPropertyAssignment("error", catchVariable)
|
||||
])
|
||||
)
|
||||
)
|
||||
]),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
),
|
||||
createBlock([
|
||||
createTry(
|
||||
/*tryBlock*/ createBlock([
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
createLogicalAnd(
|
||||
createLogicalAnd(
|
||||
result,
|
||||
createLogicalNot(
|
||||
createPropertyAccess(result, "done")
|
||||
)
|
||||
),
|
||||
createAssignment(
|
||||
returnMethod,
|
||||
createPropertyAccess(iterator, "return")
|
||||
)
|
||||
),
|
||||
createStatement(
|
||||
createFunctionCall(returnMethod, iterator, [])
|
||||
)
|
||||
),
|
||||
EmitFlags.SingleLine
|
||||
),
|
||||
]),
|
||||
/*catchClause*/ undefined,
|
||||
/*finallyBlock*/ setEmitFlags(
|
||||
createBlock([
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
errorRecord,
|
||||
createThrow(
|
||||
createPropertyAccess(errorRecord, "error")
|
||||
)
|
||||
),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
]),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2570,7 +2679,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
startLexicalEnvironment();
|
||||
let loopBody = visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock);
|
||||
let loopBody = visitNode(node.statement, visitor, isStatement, liftToBlock);
|
||||
const lexicalEnvironment = endLexicalEnvironment();
|
||||
|
||||
const currentState = convertedLoopState;
|
||||
@@ -2712,6 +2821,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState, isAsyncBlockContainingAwait);
|
||||
|
||||
let loop: Statement;
|
||||
if (convert) {
|
||||
loop = convert(node, outermostLabeledStatement, convertedLoopBodyStatements);
|
||||
@@ -3239,15 +3349,30 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
if (segments.length === 1) {
|
||||
const firstElement = elements[0];
|
||||
return needsUniqueCopy && isSpreadExpression(firstElement) && firstElement.expression.kind !== SyntaxKind.ArrayLiteralExpression
|
||||
? createArraySlice(segments[0])
|
||||
: segments[0];
|
||||
}
|
||||
if (compilerOptions.downlevelIteration) {
|
||||
if (segments.length === 1) {
|
||||
const firstSegment = segments[0];
|
||||
if (isCallExpression(firstSegment)
|
||||
&& isIdentifier(firstSegment.expression)
|
||||
&& (getEmitFlags(firstSegment.expression) & EmitFlags.HelperName)
|
||||
&& firstSegment.expression.text === "___spread") {
|
||||
return segments[0];
|
||||
}
|
||||
}
|
||||
|
||||
// Rewrite using the pattern <segment0>.concat(<segment1>, <segment2>, ...)
|
||||
return createArrayConcat(segments.shift(), segments);
|
||||
return createSpreadHelper(context, segments);
|
||||
}
|
||||
else {
|
||||
if (segments.length === 1) {
|
||||
const firstElement = elements[0];
|
||||
return needsUniqueCopy && isSpreadExpression(firstElement) && firstElement.expression.kind !== SyntaxKind.ArrayLiteralExpression
|
||||
? createArraySlice(segments[0])
|
||||
: segments[0];
|
||||
}
|
||||
|
||||
// Rewrite using the pattern <segment0>.concat(<segment1>, <segment2>, ...)
|
||||
return createArrayConcat(segments.shift(), segments);
|
||||
}
|
||||
}
|
||||
|
||||
function partitionSpread(node: Expression) {
|
||||
@@ -3549,7 +3674,7 @@ namespace ts {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
|
||||
const original = getParseTreeNode(node, isIdentifier);
|
||||
if (original && isNameOfDeclarationWithCollidingName(original)) {
|
||||
return getGeneratedNameForNode(original);
|
||||
return setTextRange(getGeneratedNameForNode(original), node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3602,7 +3727,7 @@ namespace ts {
|
||||
if (enabledSubstitutions & ES2015SubstitutionFlags.BlockScopedBindings) {
|
||||
const declaration = resolver.getReferencedDeclarationWithCollidingName(node);
|
||||
if (declaration) {
|
||||
return getGeneratedNameForNode(declaration.name);
|
||||
return setTextRange(getGeneratedNameForNode(declaration.name), node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace ts {
|
||||
const {
|
||||
startLexicalEnvironment,
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
endLexicalEnvironment
|
||||
} = context;
|
||||
|
||||
const resolver = context.getEmitResolver();
|
||||
@@ -34,7 +34,7 @@ namespace ts {
|
||||
* This keeps track of containers where `super` is valid, for use with
|
||||
* just-in-time substitution for `super` expressions inside of async methods.
|
||||
*/
|
||||
let currentSuperContainer: SuperContainer;
|
||||
let enclosingSuperContainerFlags: NodeCheckFlags = 0;
|
||||
|
||||
// Save the previous transformation hooks.
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
@@ -71,23 +71,18 @@ namespace ts {
|
||||
return undefined;
|
||||
|
||||
case SyntaxKind.AwaitExpression:
|
||||
// ES2017 'await' expressions must be transformed for targets < ES2017.
|
||||
return visitAwaitExpression(<AwaitExpression>node);
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
// ES2017 method declarations may be 'async'
|
||||
return visitMethodDeclaration(<MethodDeclaration>node);
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
// ES2017 function declarations may be 'async'
|
||||
return visitFunctionDeclaration(<FunctionDeclaration>node);
|
||||
|
||||
case SyntaxKind.FunctionExpression:
|
||||
// ES2017 function expressions may be 'async'
|
||||
return visitFunctionExpression(<FunctionExpression>node);
|
||||
|
||||
case SyntaxKind.ArrowFunction:
|
||||
// ES2017 arrow functions may be 'async'
|
||||
return visitArrowFunction(<ArrowFunction>node);
|
||||
|
||||
default:
|
||||
@@ -128,11 +123,12 @@ namespace ts {
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
isAsyncFunctionLike(node)
|
||||
getFunctionFlags(node) & FunctionFlags.Async
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
@@ -151,11 +147,12 @@ namespace ts {
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
isAsyncFunctionLike(node)
|
||||
getFunctionFlags(node) & FunctionFlags.Async
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
@@ -170,17 +167,15 @@ namespace ts {
|
||||
* @param node The node to visit.
|
||||
*/
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
if (nodeIsMissing(node.body)) {
|
||||
return createOmittedExpression();
|
||||
}
|
||||
return updateFunctionExpression(
|
||||
node,
|
||||
/*modifiers*/ undefined,
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
isAsyncFunctionLike(node)
|
||||
getFunctionFlags(node) & FunctionFlags.Async
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
@@ -201,7 +196,7 @@ namespace ts {
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
isAsyncFunctionLike(node)
|
||||
getFunctionFlags(node) & FunctionFlags.Async
|
||||
? transformAsyncFunctionBody(node)
|
||||
: visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
@@ -320,6 +315,44 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
// If we need to support substitutions for `super` in an async method,
|
||||
// we should track it here.
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
|
||||
const superContainerFlags = resolver.getNodeCheckFlags(node) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
|
||||
if (superContainerFlags !== enclosingSuperContainerFlags) {
|
||||
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
|
||||
enclosingSuperContainerFlags = superContainerFlags;
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression && enclosingSuperContainerFlags) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteExpression(node: Expression) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
@@ -327,62 +360,45 @@ namespace ts {
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return substituteElementAccessExpression(<ElementAccessExpression>node);
|
||||
case SyntaxKind.CallExpression:
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper) {
|
||||
return substituteCallExpression(<CallExpression>node);
|
||||
}
|
||||
break;
|
||||
return substituteCallExpression(<CallExpression>node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
flags,
|
||||
node
|
||||
);
|
||||
}
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteElementAccessExpression(node: ElementAccessExpression) {
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
node.argumentExpression,
|
||||
flags,
|
||||
node
|
||||
);
|
||||
}
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
node.argumentExpression,
|
||||
node
|
||||
);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteCallExpression(node: CallExpression): Expression {
|
||||
const expression = node.expression;
|
||||
if (isSuperProperty(expression)) {
|
||||
const flags = getSuperContainerAsyncMethodFlags();
|
||||
if (flags) {
|
||||
const argumentExpression = isPropertyAccessExpression(expression)
|
||||
? substitutePropertyAccessExpression(expression)
|
||||
: substituteElementAccessExpression(expression);
|
||||
return createCall(
|
||||
createPropertyAccess(argumentExpression, "call"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
...node.arguments
|
||||
]
|
||||
);
|
||||
}
|
||||
const argumentExpression = isPropertyAccessExpression(expression)
|
||||
? substitutePropertyAccessExpression(expression)
|
||||
: substituteElementAccessExpression(expression);
|
||||
return createCall(
|
||||
createPropertyAccess(argumentExpression, "call"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
...node.arguments
|
||||
]
|
||||
);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -396,44 +412,8 @@ namespace ts {
|
||||
|| kind === SyntaxKind.SetAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook for node emit.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emit A callback used to emit the node in the printer.
|
||||
*/
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
// If we need to support substitutions for `super` in an async method,
|
||||
// we should track it here.
|
||||
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
|
||||
const savedCurrentSuperContainer = currentSuperContainer;
|
||||
currentSuperContainer = node;
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
currentSuperContainer = savedCurrentSuperContainer;
|
||||
}
|
||||
else {
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, flags: NodeCheckFlags, location: TextRange): LeftHandSideExpression {
|
||||
if (flags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
|
||||
if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createCall(
|
||||
@@ -457,15 +437,26 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getSuperContainerAsyncMethodFlags() {
|
||||
return currentSuperContainer !== undefined
|
||||
&& resolver.getNodeCheckFlags(currentSuperContainer) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
|
||||
}
|
||||
}
|
||||
|
||||
const awaiterHelper: EmitHelper = {
|
||||
name: "typescript:awaiter",
|
||||
scoped: false,
|
||||
priority: 5,
|
||||
text: `
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};`
|
||||
};
|
||||
|
||||
function createAwaiterHelper(context: TransformationContext, hasLexicalArguments: boolean, promiseConstructor: EntityName | Expression, body: Block) {
|
||||
context.requestEmitHelper(awaiterHelper);
|
||||
|
||||
const generatorFunc = createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
@@ -491,35 +482,22 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const awaiterHelper: EmitHelper = {
|
||||
name: "typescript:awaiter",
|
||||
scoped: false,
|
||||
priority: 5,
|
||||
text: `
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};`
|
||||
};
|
||||
|
||||
const asyncSuperHelper: EmitHelper = {
|
||||
export const asyncSuperHelper: EmitHelper = {
|
||||
name: "typescript:async-super",
|
||||
scoped: true,
|
||||
text: `
|
||||
const _super = name => super[name];`
|
||||
const _super = name => super[name];
|
||||
`
|
||||
};
|
||||
|
||||
const advancedAsyncSuperHelper: EmitHelper = {
|
||||
export const advancedAsyncSuperHelper: EmitHelper = {
|
||||
name: "typescript:advanced-async-super",
|
||||
scoped: true,
|
||||
text: `
|
||||
const _super = (function (geti, seti) {
|
||||
const cache = Object.create(null);
|
||||
return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });
|
||||
})(name => super[name], (name, value) => super[name] = value);`
|
||||
})(name => super[name], (name, value) => super[name] = value);
|
||||
`
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,13 +1,35 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
/// <reference path="es2017.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
const enum ESNextSubstitutionFlags {
|
||||
/** Enables substitutions for async methods with `super` calls. */
|
||||
AsyncMethodsWithSuper = 1 << 0
|
||||
}
|
||||
|
||||
export function transformESNext(context: TransformationContext) {
|
||||
const {
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment
|
||||
endLexicalEnvironment,
|
||||
hoistVariableDeclaration
|
||||
} = context;
|
||||
|
||||
const resolver = context.getEmitResolver();
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
context.onEmitNode = onEmitNode;
|
||||
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
|
||||
let enabledSubstitutions: ESNextSubstitutionFlags;
|
||||
let enclosingFunctionFlags: FunctionFlags;
|
||||
let enclosingSuperContainerFlags: NodeCheckFlags = 0;
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
@@ -28,12 +50,25 @@ namespace ts {
|
||||
return visitorWorker(node, /*noDestructuringValue*/ true);
|
||||
}
|
||||
|
||||
function visitorNoAsyncModifier(node: Node): VisitResult<Node> {
|
||||
if (node.kind === SyntaxKind.AsyncKeyword) {
|
||||
return undefined;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node, noDestructuringValue: boolean): VisitResult<Node> {
|
||||
if ((node.transformFlags & TransformFlags.ContainsESNext) === 0) {
|
||||
return node;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.AwaitExpression:
|
||||
return visitAwaitExpression(node as AwaitExpression);
|
||||
case SyntaxKind.YieldExpression:
|
||||
return visitYieldExpression(node as YieldExpression);
|
||||
case SyntaxKind.LabeledStatement:
|
||||
return visitLabeledStatement(node as LabeledStatement);
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return visitObjectLiteralExpression(node as ObjectLiteralExpression);
|
||||
case SyntaxKind.BinaryExpression:
|
||||
@@ -41,7 +76,7 @@ namespace ts {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return visitVariableDeclaration(node as VariableDeclaration);
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return visitForOfStatement(node as ForOfStatement);
|
||||
return visitForOfStatement(node as ForOfStatement, /*outermostLabeledStatement*/ undefined);
|
||||
case SyntaxKind.ForStatement:
|
||||
return visitForStatement(node as ForStatement);
|
||||
case SyntaxKind.VoidExpression:
|
||||
@@ -71,6 +106,52 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function visitAwaitExpression(node: AwaitExpression) {
|
||||
if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
return setOriginalNode(
|
||||
setTextRange(
|
||||
createYield(
|
||||
/*asteriskToken*/ undefined,
|
||||
createArrayLiteral([createLiteral("await"), expression])
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
node
|
||||
);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitYieldExpression(node: YieldExpression) {
|
||||
if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
return updateYield(
|
||||
node,
|
||||
node.asteriskToken,
|
||||
node.asteriskToken
|
||||
? createAsyncDelegatorHelper(context, expression, expression)
|
||||
: createArrayLiteral(
|
||||
expression
|
||||
? [createLiteral("yield"), expression]
|
||||
: [createLiteral("yield")]
|
||||
)
|
||||
);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function visitLabeledStatement(node: LabeledStatement) {
|
||||
if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) {
|
||||
const statement = unwrapInnermostStatementOfLabel(node);
|
||||
if (statement.kind === SyntaxKind.ForOfStatement && (<ForOfStatement>statement).awaitModifier) {
|
||||
return visitForOfStatement(<ForOfStatement>statement, node);
|
||||
}
|
||||
return restoreEnclosingLabel(visitEachChild(node, visitor, context), node);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
|
||||
function chunkObjectLiteralElements(elements: ObjectLiteralElement[]): Expression[] {
|
||||
let chunkObject: (ShorthandPropertyAssignment | PropertyAssignment)[];
|
||||
const objects: Expression[] = [];
|
||||
@@ -189,67 +270,199 @@ namespace ts {
|
||||
*
|
||||
* @param node A ForOfStatement.
|
||||
*/
|
||||
function visitForOfStatement(node: ForOfStatement): VisitResult<Statement> {
|
||||
let leadingStatements: Statement[];
|
||||
let temp: Identifier;
|
||||
const initializer = skipParentheses(node.initializer);
|
||||
if (initializer.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
if (isVariableDeclarationList(initializer)) {
|
||||
temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const firstDeclaration = firstOrUndefined(initializer.declarations);
|
||||
const declarations = flattenDestructuringBinding(
|
||||
firstDeclaration,
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.ObjectRest,
|
||||
temp,
|
||||
/*doNotRecordTempVariablesInLine*/ false,
|
||||
/*skipInitializer*/ true,
|
||||
);
|
||||
if (some(declarations)) {
|
||||
const statement = createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
updateVariableDeclarationList(initializer, declarations),
|
||||
);
|
||||
setTextRange(statement, initializer);
|
||||
leadingStatements = append(leadingStatements, statement);
|
||||
}
|
||||
}
|
||||
else if (isAssignmentPattern(initializer)) {
|
||||
temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const expression = flattenDestructuringAssignment(
|
||||
aggregateTransformFlags(
|
||||
setTextRange(
|
||||
createAssignment(initializer, temp),
|
||||
node.initializer
|
||||
)
|
||||
),
|
||||
visitor,
|
||||
context,
|
||||
FlattenLevel.ObjectRest
|
||||
);
|
||||
leadingStatements = append(leadingStatements, setTextRange(createStatement(expression), node.initializer));
|
||||
}
|
||||
function visitForOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement): VisitResult<Statement> {
|
||||
if (node.initializer.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
node = transformForOfStatementWithObjectRest(node);
|
||||
}
|
||||
if (temp) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const statement = visitNode(node.statement, visitor, isStatement);
|
||||
const block = isBlock(statement)
|
||||
? updateBlock(statement, setTextRange(createNodeArray(concatenate(leadingStatements, statement.statements)), statement.statements))
|
||||
: setTextRange(createBlock(append(leadingStatements, statement), /*multiLine*/ true), statement);
|
||||
if (node.awaitModifier) {
|
||||
return transformForAwaitOfStatement(node, outermostLabeledStatement);
|
||||
}
|
||||
else {
|
||||
return restoreEnclosingLabel(visitEachChild(node, visitor, context), outermostLabeledStatement);
|
||||
}
|
||||
}
|
||||
|
||||
function transformForOfStatementWithObjectRest(node: ForOfStatement) {
|
||||
const initializerWithoutParens = skipParentheses(node.initializer) as ForInitializer;
|
||||
if (isVariableDeclarationList(initializerWithoutParens) || isAssignmentPattern(initializerWithoutParens)) {
|
||||
let bodyLocation: TextRange;
|
||||
let statementsLocation: TextRange;
|
||||
const temp = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const statements: Statement[] = [createForOfBindingStatement(initializerWithoutParens, temp)];
|
||||
if (isBlock(node.statement)) {
|
||||
addRange(statements, node.statement.statements);
|
||||
bodyLocation = node.statement;
|
||||
statementsLocation = node.statement.statements;
|
||||
}
|
||||
return updateForOf(
|
||||
node,
|
||||
node.awaitModifier,
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(temp), node.initializer)
|
||||
], NodeFlags.Let),
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
setTextRange(createVariableDeclaration(temp), node.initializer)
|
||||
],
|
||||
NodeFlags.Let
|
||||
),
|
||||
node.initializer
|
||||
),
|
||||
expression,
|
||||
block
|
||||
node.expression,
|
||||
setTextRange(
|
||||
createBlock(
|
||||
setTextRange(createNodeArray(statements), statementsLocation),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
bodyLocation
|
||||
)
|
||||
);
|
||||
}
|
||||
return visitEachChild(node, visitor, context);
|
||||
return node;
|
||||
}
|
||||
|
||||
function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression) {
|
||||
const binding = createForOfBindingStatement(node.initializer, boundValue);
|
||||
|
||||
let bodyLocation: TextRange;
|
||||
let statementsLocation: TextRange;
|
||||
const statements: Statement[] = [visitNode(binding, visitor, isStatement)];
|
||||
const statement = visitNode(node.statement, visitor, isStatement);
|
||||
if (isBlock(statement)) {
|
||||
addRange(statements, statement.statements);
|
||||
bodyLocation = statement;
|
||||
statementsLocation = statement.statements;
|
||||
}
|
||||
else {
|
||||
statements.push(statement);
|
||||
}
|
||||
|
||||
return setEmitFlags(
|
||||
setTextRange(
|
||||
createBlock(
|
||||
setTextRange(createNodeArray(statements), statementsLocation),
|
||||
/*multiLine*/ true
|
||||
),
|
||||
bodyLocation
|
||||
),
|
||||
EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps
|
||||
);
|
||||
}
|
||||
|
||||
function transformForAwaitOfStatement(node: ForOfStatement, outermostLabeledStatement: LabeledStatement) {
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
const iterator = isIdentifier(expression) ? getGeneratedNameForNode(expression) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const result = isIdentifier(expression) ? getGeneratedNameForNode(iterator) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const errorRecord = createUniqueName("e");
|
||||
const catchVariable = getGeneratedNameForNode(errorRecord);
|
||||
const returnMethod = createTempVariable(/*recordTempVariable*/ undefined);
|
||||
const values = createAsyncValuesHelper(context, expression, /*location*/ node.expression);
|
||||
const next = createYield(
|
||||
/*asteriskToken*/ undefined,
|
||||
enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? createArrayLiteral([
|
||||
createLiteral("await"),
|
||||
createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, [])
|
||||
])
|
||||
: createCall(createPropertyAccess(iterator, "next" ), /*typeArguments*/ undefined, [])
|
||||
);
|
||||
|
||||
hoistVariableDeclaration(errorRecord);
|
||||
hoistVariableDeclaration(returnMethod);
|
||||
|
||||
const forStatement = setEmitFlags(
|
||||
setTextRange(
|
||||
createFor(
|
||||
/*initializer*/ setEmitFlags(
|
||||
setTextRange(
|
||||
createVariableDeclarationList([
|
||||
setTextRange(createVariableDeclaration(iterator, /*type*/ undefined, values), node.expression),
|
||||
createVariableDeclaration(result, /*type*/ undefined, next)
|
||||
]),
|
||||
node.expression
|
||||
),
|
||||
EmitFlags.NoHoisting
|
||||
),
|
||||
/*condition*/ createLogicalNot(createPropertyAccess(result, "done")),
|
||||
/*incrementor*/ createAssignment(result, next),
|
||||
/*statement*/ convertForOfStatementHead(node, createPropertyAccess(result, "value"))
|
||||
),
|
||||
/*location*/ node
|
||||
),
|
||||
EmitFlags.NoTokenTrailingSourceMaps
|
||||
);
|
||||
|
||||
return createTry(
|
||||
createBlock([
|
||||
restoreEnclosingLabel(
|
||||
forStatement,
|
||||
outermostLabeledStatement
|
||||
)
|
||||
]),
|
||||
createCatchClause(
|
||||
createVariableDeclaration(catchVariable),
|
||||
setEmitFlags(
|
||||
createBlock([
|
||||
createStatement(
|
||||
createAssignment(
|
||||
errorRecord,
|
||||
createObjectLiteral([
|
||||
createPropertyAssignment("error", catchVariable)
|
||||
])
|
||||
)
|
||||
)
|
||||
]),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
),
|
||||
createBlock([
|
||||
createTry(
|
||||
/*tryBlock*/ createBlock([
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
createLogicalAnd(
|
||||
createLogicalAnd(
|
||||
result,
|
||||
createLogicalNot(
|
||||
createPropertyAccess(result, "done")
|
||||
)
|
||||
),
|
||||
createAssignment(
|
||||
returnMethod,
|
||||
createPropertyAccess(iterator, "return")
|
||||
)
|
||||
),
|
||||
createStatement(
|
||||
createYield(
|
||||
/*asteriskToken*/ undefined,
|
||||
enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? createArrayLiteral([
|
||||
createLiteral("await"),
|
||||
createFunctionCall(returnMethod, iterator, [])
|
||||
])
|
||||
: createFunctionCall(returnMethod, iterator, [])
|
||||
)
|
||||
)
|
||||
),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
]),
|
||||
/*catchClause*/ undefined,
|
||||
/*finallyBlock*/ setEmitFlags(
|
||||
createBlock([
|
||||
setEmitFlags(
|
||||
createIf(
|
||||
errorRecord,
|
||||
createThrow(
|
||||
createPropertyAccess(errorRecord, "error")
|
||||
)
|
||||
),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
]),
|
||||
EmitFlags.SingleLine
|
||||
)
|
||||
)
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
function visitParameter(node: ParameterDeclaration): ParameterDeclaration {
|
||||
@@ -270,17 +483,23 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitConstructorDeclaration(node: ConstructorDeclaration) {
|
||||
return updateConstructor(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = FunctionFlags.Normal;
|
||||
const updated = updateConstructor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitGetAccessorDeclaration(node: GetAccessorDeclaration) {
|
||||
return updateGetAccessor(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = FunctionFlags.Normal;
|
||||
const updated = updateGetAccessor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
@@ -289,10 +508,14 @@ namespace ts {
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitSetAccessorDeclaration(node: SetAccessorDeclaration) {
|
||||
return updateSetAccessor(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = FunctionFlags.Normal;
|
||||
const updated = updateSetAccessor(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
@@ -300,36 +523,62 @@ namespace ts {
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitMethodDeclaration(node: MethodDeclaration) {
|
||||
return updateMethod(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = getFunctionFlags(node);
|
||||
const updated = updateMethod(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? visitNodes(node.modifiers, visitorNoAsyncModifier, isModifier)
|
||||
: node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Async
|
||||
? undefined
|
||||
: node.asteriskToken,
|
||||
visitNode(node.name, visitor, isPropertyName),
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? transformAsyncGeneratorFunctionBody(node)
|
||||
: transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration) {
|
||||
return updateFunctionDeclaration(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = getFunctionFlags(node);
|
||||
const updated = updateFunctionDeclaration(
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? visitNodes(node.modifiers, visitorNoAsyncModifier, isModifier)
|
||||
: node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Async
|
||||
? undefined
|
||||
: node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? transformAsyncGeneratorFunctionBody(node)
|
||||
: transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitArrowFunction(node: ArrowFunction) {
|
||||
return updateArrowFunction(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = getFunctionFlags(node);
|
||||
const updated = updateArrowFunction(
|
||||
node,
|
||||
node.modifiers,
|
||||
/*typeParameters*/ undefined,
|
||||
@@ -337,25 +586,92 @@ namespace ts {
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function visitFunctionExpression(node: FunctionExpression) {
|
||||
return updateFunctionExpression(
|
||||
const savedEnclosingFunctionFlags = enclosingFunctionFlags;
|
||||
enclosingFunctionFlags = getFunctionFlags(node);
|
||||
const updated = updateFunctionExpression(
|
||||
node,
|
||||
node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? visitNodes(node.modifiers, visitorNoAsyncModifier, isModifier)
|
||||
: node.modifiers,
|
||||
enclosingFunctionFlags & FunctionFlags.Async
|
||||
? undefined
|
||||
: node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
transformFunctionBody(node)
|
||||
enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator
|
||||
? transformAsyncGeneratorFunctionBody(node)
|
||||
: transformFunctionBody(node)
|
||||
);
|
||||
enclosingFunctionFlags = savedEnclosingFunctionFlags;
|
||||
return updated;
|
||||
}
|
||||
|
||||
function transformAsyncGeneratorFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody {
|
||||
resumeLexicalEnvironment();
|
||||
const statements: Statement[] = [];
|
||||
const statementOffset = addPrologueDirectives(statements, node.body.statements, /*ensureUseStrict*/ false, visitor);
|
||||
appendObjectRestAssignmentsIfNeeded(statements, node);
|
||||
|
||||
statements.push(
|
||||
createReturn(
|
||||
createAsyncGeneratorHelper(
|
||||
context,
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
createToken(SyntaxKind.AsteriskToken),
|
||||
node.name && getGeneratedNameForNode(node.name),
|
||||
/*typeParameters*/ undefined,
|
||||
/*parameters*/ [],
|
||||
/*type*/ undefined,
|
||||
updateBlock(
|
||||
node.body,
|
||||
visitLexicalEnvironment(node.body.statements, visitor, context, statementOffset)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
const block = updateBlock(node.body, statements);
|
||||
|
||||
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
|
||||
// This step isn't needed if we eventually transform this to ES5.
|
||||
if (languageVersion >= ScriptTarget.ES2015) {
|
||||
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
addEmitHelper(block, advancedAsyncSuperHelper);
|
||||
}
|
||||
else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.AsyncMethodWithSuper) {
|
||||
enableSubstitutionForAsyncMethodsWithSuper();
|
||||
addEmitHelper(block, asyncSuperHelper);
|
||||
}
|
||||
}
|
||||
return block;
|
||||
}
|
||||
|
||||
function transformFunctionBody(node: FunctionDeclaration | FunctionExpression | ConstructorDeclaration | MethodDeclaration | AccessorDeclaration): FunctionBody;
|
||||
function transformFunctionBody(node: ArrowFunction): ConciseBody;
|
||||
function transformFunctionBody(node: FunctionLikeDeclaration): ConciseBody {
|
||||
resumeLexicalEnvironment();
|
||||
let leadingStatements: Statement[];
|
||||
const leadingStatements = appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node);
|
||||
const body = visitNode(node.body, visitor, isConciseBody);
|
||||
const trailingStatements = endLexicalEnvironment();
|
||||
if (some(leadingStatements) || some(trailingStatements)) {
|
||||
const block = convertToFunctionBody(body, /*multiLine*/ true);
|
||||
return updateBlock(block, setTextRange(createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements)), block.statements));
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
function appendObjectRestAssignmentsIfNeeded(statements: Statement[], node: FunctionLikeDeclaration): Statement[] {
|
||||
for (const parameter of node.parameters) {
|
||||
if (parameter.transformFlags & TransformFlags.ContainsObjectRest) {
|
||||
const temp = getGeneratedNameForNode(parameter);
|
||||
@@ -376,17 +692,153 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
setEmitFlags(statement, EmitFlags.CustomPrologue);
|
||||
leadingStatements = append(leadingStatements, statement);
|
||||
statements = append(statements, statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
const body = visitNode(node.body, visitor, isConciseBody);
|
||||
const trailingStatements = endLexicalEnvironment();
|
||||
if (some(leadingStatements) || some(trailingStatements)) {
|
||||
const block = convertToFunctionBody(body, /*multiLine*/ true);
|
||||
return updateBlock(block, setTextRange(createNodeArray(concatenate(concatenate(leadingStatements, block.statements), trailingStatements)), block.statements));
|
||||
return statements;
|
||||
}
|
||||
|
||||
function enableSubstitutionForAsyncMethodsWithSuper() {
|
||||
if ((enabledSubstitutions & ESNextSubstitutionFlags.AsyncMethodsWithSuper) === 0) {
|
||||
enabledSubstitutions |= ESNextSubstitutionFlags.AsyncMethodsWithSuper;
|
||||
|
||||
// We need to enable substitutions for call, property access, and element access
|
||||
// if we need to rewrite super calls.
|
||||
context.enableSubstitution(SyntaxKind.CallExpression);
|
||||
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
|
||||
context.enableSubstitution(SyntaxKind.ElementAccessExpression);
|
||||
|
||||
// We need to be notified when entering and exiting declarations that bind super.
|
||||
context.enableEmitNotification(SyntaxKind.ClassDeclaration);
|
||||
context.enableEmitNotification(SyntaxKind.MethodDeclaration);
|
||||
context.enableEmitNotification(SyntaxKind.GetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.SetAccessor);
|
||||
context.enableEmitNotification(SyntaxKind.Constructor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the printer just before a node is printed.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to be printed.
|
||||
* @param emitCallback The callback used to emit the node.
|
||||
*/
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) {
|
||||
// If we need to support substitutions for `super` in an async method,
|
||||
// we should track it here.
|
||||
if (enabledSubstitutions & ESNextSubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
|
||||
const superContainerFlags = resolver.getNodeCheckFlags(node) & (NodeCheckFlags.AsyncMethodWithSuper | NodeCheckFlags.AsyncMethodWithSuperBinding);
|
||||
if (superContainerFlags !== enclosingSuperContainerFlags) {
|
||||
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
|
||||
enclosingSuperContainerFlags = superContainerFlags;
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param hint The context for the emitter.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(hint: EmitHint, node: Node) {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression && enclosingSuperContainerFlags) {
|
||||
return substituteExpression(<Expression>node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteExpression(node: Expression) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return substitutePropertyAccessExpression(<PropertyAccessExpression>node);
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
return substituteElementAccessExpression(<ElementAccessExpression>node);
|
||||
case SyntaxKind.CallExpression:
|
||||
return substituteCallExpression(<CallExpression>node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
createLiteral(node.name.text),
|
||||
node
|
||||
);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteElementAccessExpression(node: ElementAccessExpression) {
|
||||
if (node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
return createSuperAccessInAsyncMethod(
|
||||
node.argumentExpression,
|
||||
node
|
||||
);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function substituteCallExpression(node: CallExpression): Expression {
|
||||
const expression = node.expression;
|
||||
if (isSuperProperty(expression)) {
|
||||
const argumentExpression = isPropertyAccessExpression(expression)
|
||||
? substitutePropertyAccessExpression(expression)
|
||||
: substituteElementAccessExpression(expression);
|
||||
return createCall(
|
||||
createPropertyAccess(argumentExpression, "call"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
...node.arguments
|
||||
]
|
||||
);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function isSuperContainer(node: Node) {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.ClassDeclaration
|
||||
|| kind === SyntaxKind.Constructor
|
||||
|| kind === SyntaxKind.MethodDeclaration
|
||||
|| kind === SyntaxKind.GetAccessor
|
||||
|| kind === SyntaxKind.SetAccessor;
|
||||
}
|
||||
|
||||
function createSuperAccessInAsyncMethod(argumentExpression: Expression, location: TextRange): LeftHandSideExpression {
|
||||
if (enclosingSuperContainerFlags & NodeCheckFlags.AsyncMethodWithSuperBinding) {
|
||||
return setTextRange(
|
||||
createPropertyAccess(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
"value"
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
else {
|
||||
return setTextRange(
|
||||
createCall(
|
||||
createIdentifier("_super"),
|
||||
/*typeArguments*/ undefined,
|
||||
[argumentExpression]
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,4 +870,89 @@ namespace ts {
|
||||
attributesSegments
|
||||
);
|
||||
}
|
||||
|
||||
const asyncGeneratorHelper: EmitHelper = {
|
||||
name: "typescript:asyncGenerator",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var g = generator.apply(thisArg, _arguments || []), q = [], c, i;
|
||||
return i = { next: verb("next"), "throw": verb("throw"), "return": verb("return") }, i[Symbol.asyncIterator] = function () { return this; }, i;
|
||||
function verb(n) { return function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]), next(); }); }; }
|
||||
function next() { if (!c && q.length) resume((c = q.shift())[0], c[1]); }
|
||||
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(c[3], e); } }
|
||||
function step(r) { r.done ? settle(c[2], r) : r.value[0] === "yield" ? settle(c[2], { value: r.value[1], done: false }) : Promise.resolve(r.value[1]).then(r.value[0] === "delegate" ? delegate : fulfill, reject); }
|
||||
function delegate(r) { step(r.done ? r : { value: ["yield", r.value], done: false }); }
|
||||
function fulfill(value) { resume("next", value); }
|
||||
function reject(value) { resume("throw", value); }
|
||||
function settle(f, v) { c = void 0, f(v), next(); }
|
||||
};
|
||||
`
|
||||
};
|
||||
|
||||
function createAsyncGeneratorHelper(context: TransformationContext, generatorFunc: FunctionExpression) {
|
||||
context.requestEmitHelper(asyncGeneratorHelper);
|
||||
|
||||
// Mark this node as originally an async function
|
||||
(generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= EmitFlags.AsyncFunctionBody;
|
||||
|
||||
return createCall(
|
||||
getHelperName("__asyncGenerator"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createThis(),
|
||||
createIdentifier("arguments"),
|
||||
generatorFunc
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const asyncDelegator: EmitHelper = {
|
||||
name: "typescript:asyncDelegator",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
|
||||
var i = { next: verb("next"), "throw": verb("throw", function (e) { throw e; }), "return": verb("return", function (v) { return { value: v, done: true }; }) };
|
||||
return o = __asyncValues(o), i[Symbol.iterator] = function () { return this; }, i;
|
||||
function verb(n, f) { return function (v) { return { value: ["delegate", (o[n] || f).call(o, v)], done: false }; }; }
|
||||
};
|
||||
`
|
||||
};
|
||||
|
||||
function createAsyncDelegatorHelper(context: TransformationContext, expression: Expression, location?: TextRange) {
|
||||
context.requestEmitHelper(asyncDelegator);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__asyncDelegator"),
|
||||
/*typeArguments*/ undefined,
|
||||
[expression]
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
const asyncValues: EmitHelper = {
|
||||
name: "typescript:asyncValues",
|
||||
scoped: false,
|
||||
text: `
|
||||
var __asyncValues = (this && this.__asyncIterator) || function (o) {
|
||||
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
||||
var m = o[Symbol.asyncIterator];
|
||||
return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator]();
|
||||
};
|
||||
`
|
||||
};
|
||||
|
||||
function createAsyncValuesHelper(context: TransformationContext, expression: Expression, location?: TextRange) {
|
||||
context.requestEmitHelper(asyncValues);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__asyncValues"),
|
||||
/*typeArguments*/ undefined,
|
||||
[expression]
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ namespace ts {
|
||||
resumeLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
hoistFunctionDeclaration,
|
||||
hoistVariableDeclaration,
|
||||
hoistVariableDeclaration
|
||||
} = context;
|
||||
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
@@ -448,7 +448,7 @@ namespace ts {
|
||||
*/
|
||||
function visitFunctionDeclaration(node: FunctionDeclaration): Statement {
|
||||
// Currently, we only support generators that were originally async functions.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken) {
|
||||
node = setOriginalNode(
|
||||
setTextRange(
|
||||
createFunctionDeclaration(
|
||||
@@ -498,7 +498,7 @@ namespace ts {
|
||||
*/
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
// Currently, we only support generators that were originally async functions.
|
||||
if (node.asteriskToken && getEmitFlags(node) & EmitFlags.AsyncFunctionBody) {
|
||||
if (node.asteriskToken) {
|
||||
node = setOriginalNode(
|
||||
setTextRange(
|
||||
createFunctionExpression(
|
||||
@@ -936,11 +936,10 @@ namespace ts {
|
||||
// .mark resumeLabel
|
||||
// x = %sent%;
|
||||
|
||||
// NOTE: we are explicitly not handling YieldStar at this time.
|
||||
const resumeLabel = defineLabel();
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
if (node.asteriskToken) {
|
||||
emitYieldStar(expression, /*location*/ node);
|
||||
emitYieldStar(createValuesHelper(context, expression, /*location*/ node), /*location*/ node);
|
||||
}
|
||||
else {
|
||||
emitYield(expression, /*location*/ node);
|
||||
@@ -978,9 +977,10 @@ namespace ts {
|
||||
// ar = _a.concat([%sent%, 2]);
|
||||
|
||||
const numInitialElements = countInitialNodesWithoutYield(elements);
|
||||
const temp = declareLocal();
|
||||
let hasAssignedTemp = false;
|
||||
|
||||
let temp: Identifier;
|
||||
if (numInitialElements > 0) {
|
||||
temp = declareLocal();
|
||||
const initialElements = visitNodes(elements, visitor, isExpression, 0, numInitialElements);
|
||||
emitAssignment(temp,
|
||||
createArrayLiteral(
|
||||
@@ -990,11 +990,10 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
leadingElement = undefined;
|
||||
hasAssignedTemp = true;
|
||||
}
|
||||
|
||||
const expressions = reduceLeft(elements, reduceElement, <Expression[]>[], numInitialElements);
|
||||
return hasAssignedTemp
|
||||
return temp
|
||||
? createArrayConcat(temp, [createArrayLiteral(expressions, multiLine)])
|
||||
: setTextRange(
|
||||
createArrayLiteral(leadingElement ? [leadingElement, ...expressions] : expressions, multiLine),
|
||||
@@ -1003,6 +1002,11 @@ namespace ts {
|
||||
|
||||
function reduceElement(expressions: Expression[], element: Expression) {
|
||||
if (containsYield(element) && expressions.length > 0) {
|
||||
const hasAssignedTemp = temp !== undefined;
|
||||
if (!temp) {
|
||||
temp = declareLocal();
|
||||
}
|
||||
|
||||
emitAssignment(
|
||||
temp,
|
||||
hasAssignedTemp
|
||||
@@ -1015,7 +1019,6 @@ namespace ts {
|
||||
multiLine
|
||||
)
|
||||
);
|
||||
hasAssignedTemp = true;
|
||||
leadingElement = undefined;
|
||||
expressions = [];
|
||||
}
|
||||
@@ -1227,7 +1230,7 @@ namespace ts {
|
||||
case SyntaxKind.TryStatement:
|
||||
return transformAndEmitTryStatement(<TryStatement>node);
|
||||
default:
|
||||
return emitStatement(visitNode(node, visitor, isStatement, /*optional*/ true));
|
||||
return emitStatement(visitNode(node, visitor, isStatement));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1485,9 +1488,9 @@ namespace ts {
|
||||
variables.length > 0
|
||||
? inlineExpressions(map(variables, transformInitializedVariable))
|
||||
: undefined,
|
||||
visitNode(node.condition, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.incrementor, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.condition, visitor, isExpression),
|
||||
visitNode(node.incrementor, visitor, isExpression),
|
||||
visitNode(node.statement, visitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
else {
|
||||
@@ -1609,7 +1612,7 @@ namespace ts {
|
||||
node = updateForIn(node,
|
||||
<Identifier>initializer.declarations[0].name,
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
visitNode(node.statement, visitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, visitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
else {
|
||||
@@ -1659,14 +1662,14 @@ namespace ts {
|
||||
|
||||
function transformAndEmitReturnStatement(node: ReturnStatement): void {
|
||||
emitReturn(
|
||||
visitNode(node.expression, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
|
||||
function visitReturnStatement(node: ReturnStatement) {
|
||||
return createInlineReturn(
|
||||
visitNode(node.expression, visitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.expression, visitor, isExpression),
|
||||
/*location*/ node
|
||||
);
|
||||
}
|
||||
@@ -1939,7 +1942,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function substituteExpressionIdentifier(node: Identifier) {
|
||||
if (renamedCatchVariables && renamedCatchVariables.has(node.text)) {
|
||||
if (!isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(node.text)) {
|
||||
const original = getOriginalNode(node);
|
||||
if (isIdentifier(original) && original.parent) {
|
||||
const declaration = resolver.getReferencedValueDeclaration(original);
|
||||
@@ -1960,7 +1963,7 @@ namespace ts {
|
||||
|
||||
function cacheExpression(node: Expression): Identifier {
|
||||
let temp: Identifier;
|
||||
if (isGeneratedIdentifier(node)) {
|
||||
if (isGeneratedIdentifier(node) || getEmitFlags(node) & EmitFlags.HelperName) {
|
||||
return <Identifier>node;
|
||||
}
|
||||
|
||||
@@ -2105,17 +2108,24 @@ namespace ts {
|
||||
function beginCatchBlock(variable: VariableDeclaration): void {
|
||||
Debug.assert(peekBlockKind() === CodeBlockKind.Exception);
|
||||
|
||||
const text = (<Identifier>variable.name).text;
|
||||
const name = declareLocal(text);
|
||||
|
||||
if (!renamedCatchVariables) {
|
||||
renamedCatchVariables = createMap<boolean>();
|
||||
renamedCatchVariableDeclarations = [];
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
// generated identifiers should already be unique within a file
|
||||
let name: Identifier;
|
||||
if (isGeneratedIdentifier(variable.name)) {
|
||||
name = variable.name;
|
||||
hoistVariableDeclaration(variable.name);
|
||||
}
|
||||
else {
|
||||
const text = (<Identifier>variable.name).text;
|
||||
name = declareLocal(text);
|
||||
if (!renamedCatchVariables) {
|
||||
renamedCatchVariables = createMap<boolean>();
|
||||
renamedCatchVariableDeclarations = [];
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
}
|
||||
|
||||
renamedCatchVariables.set(text, true);
|
||||
renamedCatchVariableDeclarations[getOriginalNodeId(variable)] = name;
|
||||
renamedCatchVariables.set(text, true);
|
||||
renamedCatchVariableDeclarations[getOriginalNodeId(variable)] = name;
|
||||
}
|
||||
|
||||
const exception = <ExceptionBlock>peekBlock();
|
||||
Debug.assert(exception.state < ExceptionBlockState.Catch);
|
||||
@@ -2419,7 +2429,7 @@ namespace ts {
|
||||
*/
|
||||
function createInstruction(instruction: Instruction): NumericLiteral {
|
||||
const literal = createLiteral(instruction);
|
||||
literal.trailingComment = getInstructionName(instruction);
|
||||
addSyntheticTrailingComment(literal, SyntaxKind.MultiLineCommentTrivia, getInstructionName(instruction));
|
||||
return literal;
|
||||
}
|
||||
|
||||
@@ -3229,8 +3239,8 @@ namespace ts {
|
||||
priority: 6,
|
||||
text: `
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t;
|
||||
return { next: verb(0), "throw": verb(1), "return": verb(2) };
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
namespace ts {
|
||||
export function transformJsx(context: TransformationContext) {
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
let currentSourceFile: SourceFile;
|
||||
|
||||
return transformSourceFile;
|
||||
|
||||
@@ -20,12 +19,8 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
currentSourceFile = node;
|
||||
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined;
|
||||
return visited;
|
||||
}
|
||||
|
||||
@@ -85,7 +80,7 @@ namespace ts {
|
||||
function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[], isChild: boolean, location: TextRange) {
|
||||
const tagName = getTagName(node);
|
||||
let objectProperties: Expression;
|
||||
const attrs = node.attributes;
|
||||
const attrs = node.attributes.properties;
|
||||
if (attrs.length === 0) {
|
||||
// When there are no attributes, React wants "null"
|
||||
objectProperties = createNull();
|
||||
|
||||
@@ -101,6 +101,7 @@ namespace ts {
|
||||
if (isIdentifier(node) && hint === EmitHint.Expression) {
|
||||
return substituteExpressionIdentifier(node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../visitor.ts" />
|
||||
/// <reference path="../destructuring.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
@@ -88,13 +89,15 @@ namespace ts {
|
||||
append(statements, createUnderscoreUnderscoreESModule());
|
||||
}
|
||||
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true));
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false);
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
||||
const updated = updateSourceFileNode(node, setTextRange(createNodeArray(statements), node.statements));
|
||||
if (currentModuleInfo.hasExportStarsToExportValues) {
|
||||
// If we have any `export * from ...` declarations
|
||||
// we need to inform the emitter to add the __export helper.
|
||||
addEmitHelper(updated, exportStarHelper);
|
||||
}
|
||||
return updated;
|
||||
@@ -380,16 +383,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Visit each statement of the module body.
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true));
|
||||
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement));
|
||||
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
|
||||
|
||||
// Append the 'export =' statement if provided.
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
|
||||
|
||||
// End the lexical environment for the module body
|
||||
// and merge any new lexical declarations.
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
|
||||
// Append the 'export =' statement if provided.
|
||||
addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true);
|
||||
|
||||
const body = createBlock(statements, /*multiLine*/ true);
|
||||
if (currentModuleInfo.hasExportStarsToExportValues) {
|
||||
// If we have any `export * from ...` declarations
|
||||
@@ -1334,6 +1337,7 @@ namespace ts {
|
||||
if (externalHelpersModuleName) {
|
||||
return createPropertyAccess(externalHelpersModuleName, node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/// <reference path="../../factory.ts" />
|
||||
/// <reference path="../../visitor.ts" />
|
||||
/// <reference path="../destructuring.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
@@ -136,7 +137,6 @@ namespace ts {
|
||||
contextObject = undefined;
|
||||
hoistedStatements = undefined;
|
||||
enclosingBlockScopedContainer = undefined;
|
||||
|
||||
return aggregateTransformFlags(updated);
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace ts {
|
||||
);
|
||||
|
||||
// Visit the synthetic external helpers import declaration if present
|
||||
visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement, /*optional*/ true);
|
||||
visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement);
|
||||
|
||||
// Visit the statements of the source file, emitting any transformations into
|
||||
// the `executeStatements` array. We do this *before* we fill the `setters` array
|
||||
@@ -669,6 +669,7 @@ namespace ts {
|
||||
node,
|
||||
node.decorators,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true),
|
||||
/*typeParameters*/ undefined,
|
||||
visitNodes(node.parameters, destructuringVisitor, isParameterDeclaration),
|
||||
@@ -1218,8 +1219,8 @@ namespace ts {
|
||||
node = updateFor(
|
||||
node,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.condition, destructuringVisitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.incrementor, destructuringVisitor, isExpression, /*optional*/ true),
|
||||
visitNode(node.condition, destructuringVisitor, isExpression),
|
||||
visitNode(node.incrementor, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement)
|
||||
);
|
||||
|
||||
@@ -1240,7 +1241,7 @@ namespace ts {
|
||||
node,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
|
||||
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
|
||||
@@ -1258,9 +1259,10 @@ namespace ts {
|
||||
|
||||
node = updateForOf(
|
||||
node,
|
||||
node.awaitModifier,
|
||||
visitForInitializer(node.initializer),
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
|
||||
enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer;
|
||||
@@ -1305,7 +1307,7 @@ namespace ts {
|
||||
function visitDoStatement(node: DoStatement): VisitResult<Statement> {
|
||||
return updateDo(
|
||||
node,
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock),
|
||||
visitNode(node.expression, destructuringVisitor, isExpression)
|
||||
);
|
||||
}
|
||||
@@ -1319,7 +1321,7 @@ namespace ts {
|
||||
return updateWhile(
|
||||
node,
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1332,7 +1334,7 @@ namespace ts {
|
||||
return updateLabel(
|
||||
node,
|
||||
node.label,
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1345,7 +1347,7 @@ namespace ts {
|
||||
return updateWith(
|
||||
node,
|
||||
visitNode(node.expression, destructuringVisitor, isExpression),
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, /*optional*/ false, liftToBlock)
|
||||
visitNode(node.statement, nestedElementVisitor, isStatement, liftToBlock)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1492,7 +1494,7 @@ namespace ts {
|
||||
* @param node The destructuring target.
|
||||
*/
|
||||
function hasExportedReferenceInDestructuringTarget(node: Expression | ObjectLiteralElementLike): boolean {
|
||||
if (isAssignmentExpression(node)) {
|
||||
if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) {
|
||||
return hasExportedReferenceInDestructuringTarget(node.left);
|
||||
}
|
||||
else if (isSpreadExpression(node)) {
|
||||
@@ -1625,6 +1627,7 @@ namespace ts {
|
||||
if (externalHelpersModuleName) {
|
||||
return createPropertyAccess(externalHelpersModuleName, node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
@@ -872,7 +872,7 @@ namespace ts {
|
||||
* @param hasExtendsClause A value indicating whether the class has an extends clause.
|
||||
*/
|
||||
function transformConstructorBody(node: ClassExpression | ClassDeclaration, constructor: ConstructorDeclaration, hasExtendsClause: boolean) {
|
||||
const statements: Statement[] = [];
|
||||
let statements: Statement[] = [];
|
||||
let indexOfFirstStatement = 0;
|
||||
|
||||
resumeLexicalEnvironment();
|
||||
@@ -930,7 +930,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// End the lexical environment.
|
||||
addRange(statements, endLexicalEnvironment());
|
||||
statements = mergeLexicalEnvironment(statements, endLexicalEnvironment());
|
||||
return setTextRange(
|
||||
createBlock(
|
||||
setTextRange(
|
||||
@@ -1651,7 +1651,7 @@ namespace ts {
|
||||
if (isFunctionLike(node) && node.type) {
|
||||
return serializeTypeNode(node.type);
|
||||
}
|
||||
else if (isAsyncFunctionLike(node)) {
|
||||
else if (isAsyncFunction(node)) {
|
||||
return createIdentifier("Promise");
|
||||
}
|
||||
|
||||
@@ -2019,7 +2019,13 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return visitEachChild(node, visitor, context);
|
||||
return updateConstructor(
|
||||
node,
|
||||
visitNodes(node.decorators, visitor, isDecorator),
|
||||
visitNodes(node.modifiers, visitor, isModifier),
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
visitFunctionBody(node.body, visitor, context)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2040,6 +2046,7 @@ namespace ts {
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
visitPropertyNameOfClassElement(node),
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
@@ -2144,6 +2151,7 @@ namespace ts {
|
||||
node,
|
||||
/*decorators*/ undefined,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
@@ -2167,17 +2175,18 @@ namespace ts {
|
||||
* @param node The function expression node.
|
||||
*/
|
||||
function visitFunctionExpression(node: FunctionExpression): Expression {
|
||||
if (nodeIsMissing(node.body)) {
|
||||
if (!shouldEmitFunctionLikeDeclaration(node)) {
|
||||
return createOmittedExpression();
|
||||
}
|
||||
const updated = updateFunctionExpression(
|
||||
node,
|
||||
visitNodes(node.modifiers, modifierVisitor, isModifier),
|
||||
node.asteriskToken,
|
||||
node.name,
|
||||
/*typeParameters*/ undefined,
|
||||
visitParameterList(node.parameters, visitor, context),
|
||||
/*type*/ undefined,
|
||||
visitFunctionBody(node.body, visitor, context)
|
||||
visitFunctionBody(node.body, visitor, context) || createBlock([])
|
||||
);
|
||||
return updated;
|
||||
}
|
||||
@@ -2833,7 +2842,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Elide the declaration if the import clause was elided.
|
||||
const importClause = visitNode(node.importClause, visitImportClause, isImportClause, /*optional*/ true);
|
||||
const importClause = visitNode(node.importClause, visitImportClause, isImportClause);
|
||||
return importClause
|
||||
? updateImportDeclaration(
|
||||
node,
|
||||
@@ -2852,7 +2861,7 @@ namespace ts {
|
||||
function visitImportClause(node: ImportClause): VisitResult<ImportClause> {
|
||||
// Elide the import clause if we elide both its name and its named bindings.
|
||||
const name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined;
|
||||
const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings, /*optional*/ true);
|
||||
const namedBindings = visitNode(node.namedBindings, visitNamedImportBindings, isNamedImportBindings);
|
||||
return (name || namedBindings) ? updateImportClause(node, name, namedBindings) : undefined;
|
||||
}
|
||||
|
||||
@@ -2914,7 +2923,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Elide the export declaration if all of its named exports are elided.
|
||||
const exportClause = visitNode(node.exportClause, visitNamedExports, isNamedExports, /*optional*/ true);
|
||||
const exportClause = visitNode(node.exportClause, visitNamedExports, isNamedExports);
|
||||
return exportClause
|
||||
? updateExportDeclaration(
|
||||
node,
|
||||
@@ -3187,6 +3196,11 @@ namespace ts {
|
||||
*/
|
||||
function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void {
|
||||
const savedApplicableSubstitutions = applicableSubstitutions;
|
||||
const savedCurrentSourceFile = currentSourceFile;
|
||||
|
||||
if (isSourceFile(node)) {
|
||||
currentSourceFile = node;
|
||||
}
|
||||
|
||||
if (enabledSubstitutions & TypeScriptSubstitutionFlags.NamespaceExports && isTransformedModuleDeclaration(node)) {
|
||||
applicableSubstitutions |= TypeScriptSubstitutionFlags.NamespaceExports;
|
||||
@@ -3199,6 +3213,7 @@ namespace ts {
|
||||
previousOnEmitNode(hint, node, emitCallback);
|
||||
|
||||
applicableSubstitutions = savedApplicableSubstitutions;
|
||||
currentSourceFile = savedCurrentSourceFile;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3312,17 +3327,18 @@ namespace ts {
|
||||
function substituteConstantValue(node: PropertyAccessExpression | ElementAccessExpression): LeftHandSideExpression {
|
||||
const constantValue = tryGetConstEnumValue(node);
|
||||
if (constantValue !== undefined) {
|
||||
// track the constant value on the node for the printer in needsDotDotForPropertyAccess
|
||||
setConstantValue(node, constantValue);
|
||||
|
||||
const substitute = createLiteral(constantValue);
|
||||
setSourceMapRange(substitute, node);
|
||||
setCommentRange(substitute, node);
|
||||
if (!compilerOptions.removeComments) {
|
||||
const propertyName = isPropertyAccessExpression(node)
|
||||
? declarationNameToString(node.name)
|
||||
: getTextOfNode(node.argumentExpression);
|
||||
substitute.trailingComment = ` ${propertyName} `;
|
||||
|
||||
addSyntheticTrailingComment(substitute, SyntaxKind.MultiLineCommentTrivia, ` ${propertyName} `);
|
||||
}
|
||||
|
||||
setConstantValue(node, constantValue);
|
||||
return substitute;
|
||||
}
|
||||
|
||||
@@ -3340,13 +3356,60 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const paramHelper: EmitHelper = {
|
||||
name: "typescript:param",
|
||||
function createDecorateHelper(context: TransformationContext, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) {
|
||||
const argumentsArray: Expression[] = [];
|
||||
argumentsArray.push(createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
|
||||
argumentsArray.push(target);
|
||||
if (memberName) {
|
||||
argumentsArray.push(memberName);
|
||||
if (descriptor) {
|
||||
argumentsArray.push(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
context.requestEmitHelper(decorateHelper);
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__decorate"),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentsArray
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
const decorateHelper: EmitHelper = {
|
||||
name: "typescript:decorate",
|
||||
scoped: false,
|
||||
priority: 4,
|
||||
priority: 2,
|
||||
text: `
|
||||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};`
|
||||
};
|
||||
|
||||
function createMetadataHelper(context: TransformationContext, metadataKey: string, metadataValue: Expression) {
|
||||
context.requestEmitHelper(metadataHelper);
|
||||
return createCall(
|
||||
getHelperName("__metadata"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(metadataKey),
|
||||
metadataValue
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const metadataHelper: EmitHelper = {
|
||||
name: "typescript:metadata",
|
||||
scoped: false,
|
||||
priority: 3,
|
||||
text: `
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};`
|
||||
};
|
||||
|
||||
@@ -3365,60 +3428,13 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
const metadataHelper: EmitHelper = {
|
||||
name: "typescript:metadata",
|
||||
const paramHelper: EmitHelper = {
|
||||
name: "typescript:param",
|
||||
scoped: false,
|
||||
priority: 3,
|
||||
priority: 4,
|
||||
text: `
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
return function (target, key) { decorator(target, key, paramIndex); }
|
||||
};`
|
||||
};
|
||||
|
||||
function createMetadataHelper(context: TransformationContext, metadataKey: string, metadataValue: Expression) {
|
||||
context.requestEmitHelper(metadataHelper);
|
||||
return createCall(
|
||||
getHelperName("__metadata"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
createLiteral(metadataKey),
|
||||
metadataValue
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const decorateHelper: EmitHelper = {
|
||||
name: "typescript:decorate",
|
||||
scoped: false,
|
||||
priority: 2,
|
||||
text: `
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};`
|
||||
};
|
||||
|
||||
function createDecorateHelper(context: TransformationContext, decoratorExpressions: Expression[], target: Expression, memberName?: Expression, descriptor?: Expression, location?: TextRange) {
|
||||
context.requestEmitHelper(decorateHelper);
|
||||
const argumentsArray: Expression[] = [];
|
||||
argumentsArray.push(createArrayLiteral(decoratorExpressions, /*multiLine*/ true));
|
||||
argumentsArray.push(target);
|
||||
if (memberName) {
|
||||
argumentsArray.push(memberName);
|
||||
if (descriptor) {
|
||||
argumentsArray.push(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return setTextRange(
|
||||
createCall(
|
||||
getHelperName("__decorate"),
|
||||
/*typeArguments*/ undefined,
|
||||
argumentsArray
|
||||
),
|
||||
location
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+190
-74
@@ -330,6 +330,7 @@
|
||||
JsxOpeningElement,
|
||||
JsxClosingElement,
|
||||
JsxAttribute,
|
||||
JsxAttributes,
|
||||
JsxSpreadAttribute,
|
||||
JsxExpression,
|
||||
|
||||
@@ -380,9 +381,6 @@
|
||||
JSDocPropertyTag,
|
||||
JSDocTypeLiteral,
|
||||
JSDocLiteralType,
|
||||
JSDocNullKeyword,
|
||||
JSDocUndefinedKeyword,
|
||||
JSDocNeverKeyword,
|
||||
|
||||
// Synthesized list
|
||||
SyntaxList,
|
||||
@@ -422,9 +420,9 @@
|
||||
LastBinaryOperator = CaretEqualsToken,
|
||||
FirstNode = QualifiedName,
|
||||
FirstJSDocNode = JSDocTypeExpression,
|
||||
LastJSDocNode = JSDocNeverKeyword,
|
||||
LastJSDocNode = JSDocLiteralType,
|
||||
FirstJSDocTagNode = JSDocComment,
|
||||
LastJSDocTagNode = JSDocNeverKeyword
|
||||
LastJSDocTagNode = JSDocLiteralType
|
||||
}
|
||||
|
||||
export const enum NodeFlags {
|
||||
@@ -541,6 +539,7 @@
|
||||
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken>;
|
||||
export type AtToken = Token<SyntaxKind.AtToken>;
|
||||
export type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
|
||||
export type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
|
||||
|
||||
export type Modifier
|
||||
= Token<SyntaxKind.AbstractKeyword>
|
||||
@@ -622,8 +621,10 @@
|
||||
|
||||
export interface TypeParameterDeclaration extends Declaration {
|
||||
kind: SyntaxKind.TypeParameter;
|
||||
parent?: DeclarationWithTypeParameters;
|
||||
name: Identifier;
|
||||
constraint?: TypeNode;
|
||||
default?: TypeNode;
|
||||
|
||||
// For error recovery purposes.
|
||||
expression?: Expression;
|
||||
@@ -648,7 +649,7 @@
|
||||
|
||||
export interface VariableDeclaration extends Declaration {
|
||||
kind: SyntaxKind.VariableDeclaration;
|
||||
parent?: VariableDeclarationList;
|
||||
parent?: VariableDeclarationList | CatchClause;
|
||||
name: BindingName; // Declared variable name
|
||||
type?: TypeNode; // Optional type annotation
|
||||
initializer?: Expression; // Optional initializer
|
||||
@@ -656,11 +657,13 @@
|
||||
|
||||
export interface VariableDeclarationList extends Node {
|
||||
kind: SyntaxKind.VariableDeclarationList;
|
||||
parent?: VariableStatement | ForStatement | ForOfStatement | ForInStatement;
|
||||
declarations: NodeArray<VariableDeclaration>;
|
||||
}
|
||||
|
||||
export interface ParameterDeclaration extends Declaration {
|
||||
kind: SyntaxKind.Parameter;
|
||||
parent?: SignatureDeclaration;
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
|
||||
name: BindingName; // Declared parameter name
|
||||
questionToken?: QuestionToken; // Present on optional parameter
|
||||
@@ -670,6 +673,7 @@
|
||||
|
||||
export interface BindingElement extends Declaration {
|
||||
kind: SyntaxKind.BindingElement;
|
||||
parent?: BindingPattern;
|
||||
propertyName?: PropertyName; // Binding property name (in object binding pattern)
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest element (in object binding pattern)
|
||||
name: BindingName; // Declared binding element name
|
||||
@@ -697,7 +701,13 @@
|
||||
name?: PropertyName;
|
||||
}
|
||||
|
||||
export type ObjectLiteralElementLike = PropertyAssignment | ShorthandPropertyAssignment | MethodDeclaration | AccessorDeclaration | SpreadAssignment;
|
||||
export type ObjectLiteralElementLike
|
||||
= PropertyAssignment
|
||||
| ShorthandPropertyAssignment
|
||||
| SpreadAssignment
|
||||
| MethodDeclaration
|
||||
| AccessorDeclaration
|
||||
;
|
||||
|
||||
export interface PropertyAssignment extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.PropertyAssignment;
|
||||
@@ -726,6 +736,7 @@
|
||||
// SyntaxKind.BindingElement
|
||||
// SyntaxKind.Property
|
||||
// SyntaxKind.PropertyAssignment
|
||||
// SyntaxKind.JsxAttribute
|
||||
// SyntaxKind.ShorthandPropertyAssignment
|
||||
// SyntaxKind.EnumMember
|
||||
// SyntaxKind.JSDocPropertyTag
|
||||
@@ -744,11 +755,13 @@
|
||||
|
||||
export interface ObjectBindingPattern extends Node {
|
||||
kind: SyntaxKind.ObjectBindingPattern;
|
||||
parent?: VariableDeclaration | ParameterDeclaration | BindingElement;
|
||||
elements: NodeArray<BindingElement>;
|
||||
}
|
||||
|
||||
export interface ArrayBindingPattern extends Node {
|
||||
kind: SyntaxKind.ArrayBindingPattern;
|
||||
parent?: VariableDeclaration | ParameterDeclaration | BindingElement;
|
||||
elements: NodeArray<ArrayBindingElement>;
|
||||
}
|
||||
|
||||
@@ -1313,19 +1326,21 @@
|
||||
|
||||
export interface NumericLiteral extends LiteralExpression {
|
||||
kind: SyntaxKind.NumericLiteral;
|
||||
trailingComment?: string;
|
||||
}
|
||||
|
||||
export interface TemplateHead extends LiteralLikeNode {
|
||||
kind: SyntaxKind.TemplateHead;
|
||||
parent?: TemplateExpression;
|
||||
}
|
||||
|
||||
export interface TemplateMiddle extends LiteralLikeNode {
|
||||
kind: SyntaxKind.TemplateMiddle;
|
||||
parent?: TemplateSpan;
|
||||
}
|
||||
|
||||
export interface TemplateTail extends LiteralLikeNode {
|
||||
kind: SyntaxKind.TemplateTail;
|
||||
parent?: TemplateSpan;
|
||||
}
|
||||
|
||||
export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral;
|
||||
@@ -1340,6 +1355,7 @@
|
||||
// The template literal must have kind TemplateMiddleLiteral or TemplateTailLiteral.
|
||||
export interface TemplateSpan extends Node {
|
||||
kind: SyntaxKind.TemplateSpan;
|
||||
parent?: TemplateExpression;
|
||||
expression: Expression;
|
||||
literal: TemplateMiddle | TemplateTail;
|
||||
}
|
||||
@@ -1427,6 +1443,7 @@
|
||||
|
||||
export interface ExpressionWithTypeArguments extends TypeNode {
|
||||
kind: SyntaxKind.ExpressionWithTypeArguments;
|
||||
parent?: HeritageClause;
|
||||
expression: LeftHandSideExpression;
|
||||
typeArguments?: NodeArray<TypeNode>;
|
||||
}
|
||||
@@ -1444,7 +1461,7 @@
|
||||
template: TemplateLiteral;
|
||||
}
|
||||
|
||||
export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator;
|
||||
export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator | JsxOpeningLikeElement;
|
||||
|
||||
export interface AsExpression extends Expression {
|
||||
kind: SyntaxKind.AsExpression;
|
||||
@@ -1481,52 +1498,61 @@
|
||||
closingElement: JsxClosingElement;
|
||||
}
|
||||
|
||||
/// Either the opening tag in a <Tag>...</Tag> pair, or the lone <Tag /> in a self-closing form
|
||||
export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement;
|
||||
|
||||
export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute;
|
||||
|
||||
export type JsxTagNameExpression = PrimaryExpression | PropertyAccessExpression;
|
||||
|
||||
export interface JsxAttributes extends ObjectLiteralExpressionBase<JsxAttributeLike> {
|
||||
}
|
||||
|
||||
/// The opening element of a <Tag>...</Tag> JsxElement
|
||||
export interface JsxOpeningElement extends Expression {
|
||||
kind: SyntaxKind.JsxOpeningElement;
|
||||
parent?: JsxElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
attributes: NodeArray<JsxAttribute | JsxSpreadAttribute>;
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
|
||||
/// A JSX expression of the form <TagName attrs />
|
||||
export interface JsxSelfClosingElement extends PrimaryExpression {
|
||||
kind: SyntaxKind.JsxSelfClosingElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
attributes: NodeArray<JsxAttribute | JsxSpreadAttribute>;
|
||||
attributes: JsxAttributes;
|
||||
}
|
||||
|
||||
/// Either the opening tag in a <Tag>...</Tag> pair, or the lone <Tag /> in a self-closing form
|
||||
export type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement;
|
||||
|
||||
export type JsxAttributeLike = JsxAttribute | JsxSpreadAttribute;
|
||||
|
||||
export interface JsxAttribute extends Node {
|
||||
export interface JsxAttribute extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.JsxAttribute;
|
||||
parent?: JsxOpeningLikeElement;
|
||||
name: Identifier;
|
||||
/// JSX attribute initializers are optional; <X y /> is sugar for <X y={true} />
|
||||
initializer?: StringLiteral | JsxExpression;
|
||||
}
|
||||
|
||||
export interface JsxSpreadAttribute extends Node {
|
||||
export interface JsxSpreadAttribute extends ObjectLiteralElement {
|
||||
kind: SyntaxKind.JsxSpreadAttribute;
|
||||
parent?: JsxOpeningLikeElement;
|
||||
expression: Expression;
|
||||
}
|
||||
|
||||
export interface JsxClosingElement extends Node {
|
||||
kind: SyntaxKind.JsxClosingElement;
|
||||
parent?: JsxElement;
|
||||
tagName: JsxTagNameExpression;
|
||||
}
|
||||
|
||||
export interface JsxExpression extends Expression {
|
||||
kind: SyntaxKind.JsxExpression;
|
||||
parent?: JsxElement | JsxAttributeLike;
|
||||
dotDotDotToken?: Token<SyntaxKind.DotDotDotToken>;
|
||||
expression?: Expression;
|
||||
}
|
||||
|
||||
export interface JsxText extends Node {
|
||||
kind: SyntaxKind.JsxText;
|
||||
parent?: JsxElement;
|
||||
}
|
||||
|
||||
export type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement;
|
||||
@@ -1631,6 +1657,7 @@
|
||||
|
||||
export interface ForOfStatement extends IterationStatement {
|
||||
kind: SyntaxKind.ForOfStatement;
|
||||
awaitModifier?: AwaitKeywordToken;
|
||||
initializer: ForInitializer;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -1667,17 +1694,20 @@
|
||||
|
||||
export interface CaseBlock extends Node {
|
||||
kind: SyntaxKind.CaseBlock;
|
||||
parent?: SwitchStatement;
|
||||
clauses: NodeArray<CaseOrDefaultClause>;
|
||||
}
|
||||
|
||||
export interface CaseClause extends Node {
|
||||
kind: SyntaxKind.CaseClause;
|
||||
parent?: CaseBlock;
|
||||
expression: Expression;
|
||||
statements: NodeArray<Statement>;
|
||||
}
|
||||
|
||||
export interface DefaultClause extends Node {
|
||||
kind: SyntaxKind.DefaultClause;
|
||||
parent?: CaseBlock;
|
||||
statements: NodeArray<Statement>;
|
||||
}
|
||||
|
||||
@@ -1703,6 +1733,7 @@
|
||||
|
||||
export interface CatchClause extends Node {
|
||||
kind: SyntaxKind.CatchClause;
|
||||
parent?: TryStatement;
|
||||
variableDeclaration: VariableDeclaration;
|
||||
block: Block;
|
||||
}
|
||||
@@ -1746,6 +1777,7 @@
|
||||
|
||||
export interface HeritageClause extends Node {
|
||||
kind: SyntaxKind.HeritageClause;
|
||||
parent?: InterfaceDeclaration | ClassDeclaration | ClassExpression;
|
||||
token: SyntaxKind;
|
||||
types?: NodeArray<ExpressionWithTypeArguments>;
|
||||
}
|
||||
@@ -1759,6 +1791,7 @@
|
||||
|
||||
export interface EnumMember extends Declaration {
|
||||
kind: SyntaxKind.EnumMember;
|
||||
parent?: EnumDeclaration;
|
||||
// This does include ComputedPropertyName, but the parser will give an error
|
||||
// if it parses a ComputedPropertyName in an EnumMember
|
||||
name: PropertyName;
|
||||
@@ -1777,7 +1810,8 @@
|
||||
|
||||
export interface ModuleDeclaration extends DeclarationStatement {
|
||||
kind: SyntaxKind.ModuleDeclaration;
|
||||
name: Identifier | StringLiteral;
|
||||
parent?: ModuleBody | SourceFile;
|
||||
name: ModuleName;
|
||||
body?: ModuleBody | JSDocNamespaceDeclaration | Identifier;
|
||||
}
|
||||
|
||||
@@ -1797,6 +1831,7 @@
|
||||
|
||||
export interface ModuleBlock extends Node, Statement {
|
||||
kind: SyntaxKind.ModuleBlock;
|
||||
parent?: ModuleDeclaration;
|
||||
statements: NodeArray<Statement>;
|
||||
}
|
||||
|
||||
@@ -1804,6 +1839,7 @@
|
||||
|
||||
export interface ImportEqualsDeclaration extends DeclarationStatement {
|
||||
kind: SyntaxKind.ImportEqualsDeclaration;
|
||||
parent?: SourceFile | ModuleBlock;
|
||||
name: Identifier;
|
||||
|
||||
// 'EntityName' for an internal module reference, 'ExternalModuleReference' for an external
|
||||
@@ -1813,6 +1849,7 @@
|
||||
|
||||
export interface ExternalModuleReference extends Node {
|
||||
kind: SyntaxKind.ExternalModuleReference;
|
||||
parent?: ImportEqualsDeclaration;
|
||||
expression?: Expression;
|
||||
}
|
||||
|
||||
@@ -1822,6 +1859,7 @@
|
||||
// ImportClause information is shown at its declaration below.
|
||||
export interface ImportDeclaration extends Statement {
|
||||
kind: SyntaxKind.ImportDeclaration;
|
||||
parent?: SourceFile | ModuleBlock;
|
||||
importClause?: ImportClause;
|
||||
moduleSpecifier: Expression;
|
||||
}
|
||||
@@ -1836,12 +1874,14 @@
|
||||
// import d, { a, b as x } from "mod" => name = d, namedBinding: NamedImports = { elements: [{ name: a }, { name: x, propertyName: b}]}
|
||||
export interface ImportClause extends Declaration {
|
||||
kind: SyntaxKind.ImportClause;
|
||||
parent?: ImportDeclaration;
|
||||
name?: Identifier; // Default binding
|
||||
namedBindings?: NamedImportBindings;
|
||||
}
|
||||
|
||||
export interface NamespaceImport extends Declaration {
|
||||
kind: SyntaxKind.NamespaceImport;
|
||||
parent?: ImportClause;
|
||||
name: Identifier;
|
||||
}
|
||||
|
||||
@@ -1853,17 +1893,20 @@
|
||||
|
||||
export interface ExportDeclaration extends DeclarationStatement {
|
||||
kind: SyntaxKind.ExportDeclaration;
|
||||
parent?: SourceFile | ModuleBlock;
|
||||
exportClause?: NamedExports;
|
||||
moduleSpecifier?: Expression;
|
||||
}
|
||||
|
||||
export interface NamedImports extends Node {
|
||||
kind: SyntaxKind.NamedImports;
|
||||
parent?: ImportClause;
|
||||
elements: NodeArray<ImportSpecifier>;
|
||||
}
|
||||
|
||||
export interface NamedExports extends Node {
|
||||
kind: SyntaxKind.NamedExports;
|
||||
parent?: ExportDeclaration;
|
||||
elements: NodeArray<ExportSpecifier>;
|
||||
}
|
||||
|
||||
@@ -1871,12 +1914,14 @@
|
||||
|
||||
export interface ImportSpecifier extends Declaration {
|
||||
kind: SyntaxKind.ImportSpecifier;
|
||||
parent?: NamedImports;
|
||||
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
|
||||
name: Identifier; // Declared name
|
||||
}
|
||||
|
||||
export interface ExportSpecifier extends Declaration {
|
||||
kind: SyntaxKind.ExportSpecifier;
|
||||
parent?: NamedExports;
|
||||
propertyName?: Identifier; // Name preceding "as" keyword (or undefined when "as" is absent)
|
||||
name: Identifier; // Declared name
|
||||
}
|
||||
@@ -1885,6 +1930,7 @@
|
||||
|
||||
export interface ExportAssignment extends DeclarationStatement {
|
||||
kind: SyntaxKind.ExportAssignment;
|
||||
parent?: SourceFile;
|
||||
isExportEquals?: boolean;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -1893,9 +1939,17 @@
|
||||
fileName: string;
|
||||
}
|
||||
|
||||
export type CommentKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia;
|
||||
|
||||
export interface CommentRange extends TextRange {
|
||||
hasTrailingNewLine?: boolean;
|
||||
kind: SyntaxKind;
|
||||
kind: CommentKind;
|
||||
}
|
||||
|
||||
export interface SynthesizedComment extends CommentRange {
|
||||
text: string;
|
||||
pos: -1;
|
||||
end: -1;
|
||||
}
|
||||
|
||||
// represents a top level: { type } expression in a JSDoc comment.
|
||||
@@ -2280,7 +2334,7 @@
|
||||
* used for writing the JavaScript and declaration files. Otherwise, the writeFile parameter
|
||||
* will be invoked when writing the JavaScript and declaration files.
|
||||
*/
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean): EmitResult;
|
||||
emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers): EmitResult;
|
||||
|
||||
getOptionsDiagnostics(cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getGlobalDiagnostics(cancellationToken?: CancellationToken): Diagnostic[];
|
||||
@@ -2314,6 +2368,13 @@
|
||||
/* @internal */ structureIsReused?: boolean;
|
||||
}
|
||||
|
||||
export interface CustomTransformers {
|
||||
/** Custom transformers to evaluate before built-in transformations. */
|
||||
before?: TransformerFactory<SourceFile>[];
|
||||
/** Custom transformers to evaluate after built-in transformations. */
|
||||
after?: TransformerFactory<SourceFile>[];
|
||||
}
|
||||
|
||||
export interface SourceMapSpan {
|
||||
/** Line number in the .js file. */
|
||||
emittedLine: number;
|
||||
@@ -2382,6 +2443,8 @@
|
||||
getSignaturesOfType(type: Type, kind: SignatureKind): Signature[];
|
||||
getIndexTypeOfType(type: Type, kind: IndexKind): Type;
|
||||
getBaseTypes(type: InterfaceType): BaseType[];
|
||||
getBaseTypeOfLiteralType(type: Type): Type;
|
||||
getWidenedType(type: Type): Type;
|
||||
getReturnTypeOfSignature(signature: Signature): Type;
|
||||
/**
|
||||
* Gets the type of a parameter at a given position in a signature.
|
||||
@@ -2420,7 +2483,7 @@
|
||||
/** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */
|
||||
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
|
||||
getJsxElementAttributesType(elementNode: JsxOpeningLikeElement): Type;
|
||||
getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type;
|
||||
getJsxIntrinsicTagNames(): Symbol[];
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
getAmbientModules(): Symbol[];
|
||||
@@ -2474,6 +2537,7 @@
|
||||
// with import statements it previously saw (but chose not to emit).
|
||||
trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void;
|
||||
reportInaccessibleThisError(): void;
|
||||
reportIllegalExtends(): void;
|
||||
}
|
||||
|
||||
export const enum TypeFormatFlags {
|
||||
@@ -2736,6 +2800,7 @@
|
||||
isDiscriminantProperty?: boolean; // True if discriminant synthetic property
|
||||
resolvedExports?: SymbolTable; // Resolved exports of module
|
||||
exportsChecked?: boolean; // True if exports of external module have been checked
|
||||
typeParametersChecked?: boolean; // True if type parameters of merged class and interface declarations have been checked.
|
||||
isDeclarationWithCollidingName?: boolean; // True if symbol is block scoped redeclaration
|
||||
bindingElement?: BindingElement; // Binding element associated with property symbol
|
||||
exportsSomeValue?: boolean; // True if module exports some value (not just types)
|
||||
@@ -2812,7 +2877,7 @@
|
||||
isVisible?: boolean; // Is this node visible
|
||||
hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context
|
||||
jsxFlags?: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with
|
||||
resolvedJsxType?: Type; // resolved element attributes type of a JSX openinglike element
|
||||
resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element
|
||||
hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt.
|
||||
superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing
|
||||
switchTypes?: Type[]; // Cached array of switch case expression types
|
||||
@@ -2848,6 +2913,8 @@
|
||||
/* @internal */
|
||||
ContainsAnyFunctionType = 1 << 23, // Type is or contains object literal type
|
||||
NonPrimitive = 1 << 24, // intrinsic object type
|
||||
/* @internal */
|
||||
JsxAttributes = 1 << 25, // Jsx attributes type
|
||||
|
||||
/* @internal */
|
||||
Nullable = Undefined | Null,
|
||||
@@ -3037,7 +3104,7 @@
|
||||
|
||||
/* @internal */
|
||||
// Object literals are initially marked fresh. Freshness disappears following an assignment,
|
||||
// before a type assertion, or when when an object literal's type is widened. The regular
|
||||
// before a type assertion, or when an object literal's type is widened. The regular
|
||||
// version of a fresh type is identical except for the TypeFlags.FreshObjectLiteral flag.
|
||||
export interface FreshObjectLiteralType extends ResolvedType {
|
||||
regularType: ResolvedType; // Regular version of fresh type
|
||||
@@ -3046,8 +3113,17 @@
|
||||
// Just a place to cache element types of iterables and iterators
|
||||
/* @internal */
|
||||
export interface IterableOrIteratorType extends ObjectType, UnionType {
|
||||
iterableElementType?: Type;
|
||||
iteratorElementType?: Type;
|
||||
iteratedTypeOfIterable?: Type;
|
||||
iteratedTypeOfIterator?: Type;
|
||||
iteratedTypeOfAsyncIterable?: Type;
|
||||
iteratedTypeOfAsyncIterator?: Type;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface PromiseOrAwaitableType extends ObjectType, UnionType {
|
||||
promiseTypeOfPromiseConstructor?: Type;
|
||||
promisedTypeOfPromise?: Type;
|
||||
awaitedTypeOfType?: Type;
|
||||
}
|
||||
|
||||
export interface TypeVariable extends Type {
|
||||
@@ -3060,12 +3136,15 @@
|
||||
// Type parameters (TypeFlags.TypeParameter)
|
||||
export interface TypeParameter extends TypeVariable {
|
||||
constraint: Type; // Constraint
|
||||
default?: Type;
|
||||
/* @internal */
|
||||
target?: TypeParameter; // Instantiation target
|
||||
/* @internal */
|
||||
mapper?: TypeMapper; // Instantiation mapper
|
||||
/* @internal */
|
||||
isThisType?: boolean;
|
||||
/* @internal */
|
||||
resolvedDefaultType?: Type;
|
||||
}
|
||||
|
||||
// Indexed access types (TypeFlags.IndexedAccess)
|
||||
@@ -3167,7 +3246,9 @@
|
||||
/// className.prototype.name = expr
|
||||
PrototypeProperty,
|
||||
/// this.name = expr
|
||||
ThisProperty
|
||||
ThisProperty,
|
||||
// F.name = expr
|
||||
Property
|
||||
}
|
||||
|
||||
export interface JsFileExtensionInfo {
|
||||
@@ -3215,7 +3296,11 @@
|
||||
NodeJs = 2
|
||||
}
|
||||
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]>;
|
||||
export interface PluginImport {
|
||||
name: string
|
||||
}
|
||||
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[];
|
||||
|
||||
export interface CompilerOptions {
|
||||
allowJs?: boolean;
|
||||
@@ -3232,6 +3317,7 @@
|
||||
/* @internal */ diagnostics?: boolean;
|
||||
/* @internal */ extendedDiagnostics?: boolean;
|
||||
disableSizeLimit?: boolean;
|
||||
downlevelIteration?: boolean;
|
||||
emitBOM?: boolean;
|
||||
emitDecoratorMetadata?: boolean;
|
||||
experimentalDecorators?: boolean;
|
||||
@@ -3270,6 +3356,7 @@
|
||||
outDir?: string;
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
/*@internal*/ plugins?: PluginImport[];
|
||||
preserveConstEnums?: boolean;
|
||||
project?: string;
|
||||
/* @internal */ pretty?: DiagnosticStyle;
|
||||
@@ -3353,7 +3440,8 @@
|
||||
JS = 1,
|
||||
JSX = 2,
|
||||
TS = 3,
|
||||
TSX = 4
|
||||
TSX = 4,
|
||||
External = 5
|
||||
}
|
||||
|
||||
export const enum ScriptTarget {
|
||||
@@ -3428,7 +3516,7 @@
|
||||
/* @internal */
|
||||
export interface CommandLineOptionOfListType extends CommandLineOptionBase {
|
||||
type: "list";
|
||||
element: CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType;
|
||||
element: CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType | TsConfigOnlyOption;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3748,9 +3836,11 @@
|
||||
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
|
||||
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
|
||||
tokenSourceMapRanges?: TextRange[]; // The text range to use when emitting source mappings for tokens
|
||||
constantValue?: number; // The constant value of an expression
|
||||
externalHelpersModuleName?: Identifier; // The local name for an imported helpers module
|
||||
helpers?: EmitHelper[]; // Emit helpers for the node
|
||||
@@ -3786,7 +3876,7 @@
|
||||
|
||||
export interface EmitHelper {
|
||||
readonly name: string; // A unique name for this helper.
|
||||
readonly scoped: boolean; // Indicates whether ther helper MUST be emitted in the current scope.
|
||||
readonly scoped: boolean; // Indicates whether the helper MUST be emitted in the current scope.
|
||||
readonly text: string; // ES3-compatible raw script text.
|
||||
readonly priority?: number; // Helpers with a higher priority are emitted earlier than other helpers on the node.
|
||||
}
|
||||
@@ -3805,9 +3895,24 @@
|
||||
Param = 1 << 5, // __param (used by TypeScript decorators transformation)
|
||||
Awaiter = 1 << 6, // __awaiter (used by ES2017 async functions transformation)
|
||||
Generator = 1 << 7, // __generator (used by ES2015 generator transformation)
|
||||
Values = 1 << 8, // __values (used by ES2015 for..of and yield* transformations)
|
||||
Read = 1 << 9, // __read (used by ES2015 iterator destructuring transformation)
|
||||
Spread = 1 << 10, // __spread (used by ES2015 array spread and argument list spread transformations)
|
||||
AsyncGenerator = 1 << 11, // __asyncGenerator (used by ES2017 async generator transformation)
|
||||
AsyncDelegator = 1 << 12, // __asyncDelegator (used by ES2017 async generator yield* transformation)
|
||||
AsyncValues = 1 << 13, // __asyncValues (used by ES2017 for..await..of transformation)
|
||||
|
||||
// Helpers included by ES2015 for..of
|
||||
ForOfIncludes = Values,
|
||||
|
||||
// Helpers included by ES2017 for..await..of
|
||||
ForAwaitOfIncludes = AsyncValues,
|
||||
|
||||
// Helpers included by ES2015 spread
|
||||
SpreadIncludes = Read | Spread,
|
||||
|
||||
FirstEmitHelper = Extends,
|
||||
LastEmitHelper = Generator
|
||||
LastEmitHelper = AsyncValues
|
||||
}
|
||||
|
||||
export const enum EmitHint {
|
||||
@@ -3833,11 +3938,12 @@
|
||||
writeFile: WriteFileCallback;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TransformationContext {
|
||||
/*@internal*/ getEmitResolver(): EmitResolver;
|
||||
/*@internal*/ getEmitHost(): EmitHost;
|
||||
|
||||
/** Gets the compiler options supplied to the transformer. */
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
getEmitResolver(): EmitResolver;
|
||||
getEmitHost(): EmitHost;
|
||||
|
||||
/** Starts a new lexical environment. */
|
||||
startLexicalEnvironment(): void;
|
||||
@@ -3851,41 +3957,32 @@
|
||||
/** Ends a lexical environment, returning any declarations. */
|
||||
endLexicalEnvironment(): Statement[];
|
||||
|
||||
/**
|
||||
* Hoists a function declaration to the containing scope.
|
||||
*/
|
||||
/** Hoists a function declaration to the containing scope. */
|
||||
hoistFunctionDeclaration(node: FunctionDeclaration): void;
|
||||
|
||||
/**
|
||||
* Hoists a variable declaration to the containing scope.
|
||||
*/
|
||||
/** Hoists a variable declaration to the containing scope. */
|
||||
hoistVariableDeclaration(node: Identifier): void;
|
||||
|
||||
/**
|
||||
* Records a request for a non-scoped emit helper in the current context.
|
||||
*/
|
||||
/** Records a request for a non-scoped emit helper in the current context. */
|
||||
requestEmitHelper(helper: EmitHelper): void;
|
||||
|
||||
/**
|
||||
* Gets and resets the requested non-scoped emit helpers.
|
||||
*/
|
||||
/** Gets and resets the requested non-scoped emit helpers. */
|
||||
readEmitHelpers(): EmitHelper[] | undefined;
|
||||
|
||||
/**
|
||||
* Enables expression substitutions in the pretty printer for the provided SyntaxKind.
|
||||
*/
|
||||
/** Enables expression substitutions in the pretty printer for the provided SyntaxKind. */
|
||||
enableSubstitution(kind: SyntaxKind): void;
|
||||
|
||||
/**
|
||||
* Determines whether expression substitutions are enabled for the provided node.
|
||||
*/
|
||||
/** Determines whether expression substitutions are enabled for the provided node. */
|
||||
isSubstitutionEnabled(node: Node): boolean;
|
||||
|
||||
/**
|
||||
* Hook used by transformers to substitute expressions just before they
|
||||
* are emitted by the pretty printer.
|
||||
*
|
||||
* NOTE: Transformation hooks should only be modified during `Transformer` initialization,
|
||||
* before returning the `NodeTransformer` callback.
|
||||
*/
|
||||
onSubstituteNode?: (hint: EmitHint, node: Node) => Node;
|
||||
onSubstituteNode: (hint: EmitHint, node: Node) => Node;
|
||||
|
||||
/**
|
||||
* Enables before/after emit notifications in the pretty printer for the provided
|
||||
@@ -3902,25 +3999,27 @@
|
||||
/**
|
||||
* Hook used to allow transformers to capture state before or after
|
||||
* the printer emits a node.
|
||||
*
|
||||
* NOTE: Transformation hooks should only be modified during `Transformer` initialization,
|
||||
* before returning the `NodeTransformer` callback.
|
||||
*/
|
||||
onEmitNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
onEmitNode: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TransformationResult {
|
||||
/**
|
||||
* Gets the transformed source files.
|
||||
*/
|
||||
transformed: SourceFile[];
|
||||
export interface TransformationResult<T extends Node> {
|
||||
/** Gets the transformed source files. */
|
||||
transformed: T[];
|
||||
|
||||
/** Gets diagnostics for the transformation. */
|
||||
diagnostics?: Diagnostic[];
|
||||
|
||||
/**
|
||||
* Emits the substitute for a node, if one is available; otherwise, emits the node.
|
||||
* Gets a substitute for a node, if one is available; otherwise, returns the original node.
|
||||
*
|
||||
* @param hint A hint as to the intended usage of the node.
|
||||
* @param node The node to substitute.
|
||||
* @param emitCallback A callback used to emit the node or its substitute.
|
||||
*/
|
||||
emitNodeWithSubstitution(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
substituteNode(hint: EmitHint, node: Node): Node;
|
||||
|
||||
/**
|
||||
* Emits a node with possible notification.
|
||||
@@ -3930,10 +4029,30 @@
|
||||
* @param emitCallback A callback used to emit the node.
|
||||
*/
|
||||
emitNodeWithNotification(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
|
||||
/**
|
||||
* Clean up EmitNode entries on any parse-tree nodes.
|
||||
*/
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type Transformer = (context: TransformationContext) => (node: SourceFile) => SourceFile;
|
||||
/**
|
||||
* A function that is used to initialize and return a `Transformer` callback, which in turn
|
||||
* will be used to transform one or more nodes.
|
||||
*/
|
||||
export type TransformerFactory<T extends Node> = (context: TransformationContext) => Transformer<T>;
|
||||
|
||||
/**
|
||||
* A function that transforms a node.
|
||||
*/
|
||||
export type Transformer<T extends Node> = (node: T) => T;
|
||||
|
||||
/**
|
||||
* A function that accepts and possible transforms a node.
|
||||
*/
|
||||
export type Visitor = (node: Node) => VisitResult<Node>;
|
||||
|
||||
export type VisitResult<T extends Node> = T | T[];
|
||||
|
||||
export interface Printer {
|
||||
/**
|
||||
@@ -3991,23 +4110,20 @@
|
||||
/**
|
||||
* A hook used by the Printer to perform just-in-time substitution of a node. This is
|
||||
* primarily used by node transformations that need to substitute one node for another,
|
||||
* such as replacing `myExportedVar` with `exports.myExportedVar`. A compatible
|
||||
* implementation **must** invoke `emitCallback` eith the provided `hint` and either
|
||||
* the provided `node`, or its substitute.
|
||||
* such as replacing `myExportedVar` with `exports.myExportedVar`.
|
||||
* @param hint A hint indicating the intended purpose of the node.
|
||||
* @param node The node to emit.
|
||||
* @param emitCallback A callback that, when invoked, will emit the node.
|
||||
* @example
|
||||
* ```ts
|
||||
* var printer = createPrinter(printerOptions, {
|
||||
* onSubstituteNode(hint, node, emitCallback) {
|
||||
* substituteNode(hint, node) {
|
||||
* // perform substitution if necessary...
|
||||
* emitCallback(hint, node);
|
||||
* return node;
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
onSubstituteNode?(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void): void;
|
||||
substituteNode?(hint: EmitHint, node: Node): Node;
|
||||
/*@internal*/ onEmitSourceMapOfNode?: (hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) => void;
|
||||
/*@internal*/ onEmitSourceMapOfToken?: (node: Node, token: SyntaxKind, pos: number, emitCallback: (token: SyntaxKind, pos: number) => number) => number;
|
||||
/*@internal*/ onEmitSourceMapOfPosition?: (pos: number) => void;
|
||||
|
||||
+118
-16
@@ -24,6 +24,20 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function findDeclaration<T extends Declaration>(symbol: Symbol, predicate: (node: Declaration) => node is T): T | undefined;
|
||||
export function findDeclaration(symbol: Symbol, predicate: (node: Declaration) => boolean): Declaration | undefined;
|
||||
export function findDeclaration(symbol: Symbol, predicate: (node: Declaration) => boolean): Declaration | undefined {
|
||||
const declarations = symbol.declarations;
|
||||
if (declarations) {
|
||||
for (const declaration of declarations) {
|
||||
if (predicate(declaration)) {
|
||||
return declaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export interface StringSymbolWriter extends SymbolWriter {
|
||||
string(): string;
|
||||
}
|
||||
@@ -53,7 +67,8 @@ namespace ts {
|
||||
decreaseIndent: noop,
|
||||
clear: () => str = "",
|
||||
trackSymbol: noop,
|
||||
reportInaccessibleThisError: noop
|
||||
reportInaccessibleThisError: noop,
|
||||
reportIllegalExtends: noop
|
||||
};
|
||||
}
|
||||
|
||||
@@ -398,11 +413,6 @@ namespace ts {
|
||||
return identifier.length >= 2 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ ? "_" + identifier : identifier;
|
||||
}
|
||||
|
||||
// Remove extra underscore from escaped identifier
|
||||
export function unescapeIdentifier(identifier: string): string {
|
||||
return identifier.length >= 3 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ && identifier.charCodeAt(2) === CharacterCodes._ ? identifier.substr(1) : identifier;
|
||||
}
|
||||
|
||||
// Make an identifier from an external module name by extracting the string after the last "/" and replacing
|
||||
// all non-alphanumeric characters with underscores
|
||||
export function makeIdentifierFromModuleName(moduleName: string): string {
|
||||
@@ -425,8 +435,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Given a symbol for a module, checks that it is either an untyped import or a shorthand ambient module. */
|
||||
export function isShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean {
|
||||
return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
|
||||
export function isUntypedOrShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean {
|
||||
return !moduleSymbol.declarations || isShorthandAmbientModule(moduleSymbol.valueDeclaration);
|
||||
}
|
||||
|
||||
function isShorthandAmbientModule(node: Node): boolean {
|
||||
@@ -950,7 +960,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function unwrapInnermostStatmentOfLabel(node: LabeledStatement, beforeUnwrapLabelCallback?: (node: LabeledStatement) => void) {
|
||||
export function unwrapInnermostStatementOfLabel(node: LabeledStatement, beforeUnwrapLabelCallback?: (node: LabeledStatement) => void) {
|
||||
while (true) {
|
||||
if (beforeUnwrapLabelCallback) {
|
||||
beforeUnwrapLabelCallback(node);
|
||||
@@ -1169,6 +1179,8 @@ namespace ts {
|
||||
|
||||
export function isCallLikeExpression(node: Node): node is CallLikeExpression {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
@@ -1183,6 +1195,9 @@ namespace ts {
|
||||
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
|
||||
return (<TaggedTemplateExpression>node).tag;
|
||||
}
|
||||
else if (isJsxOpeningLikeElement(node)) {
|
||||
return node.tagName;
|
||||
}
|
||||
|
||||
// Will either be a CallExpression, NewExpression, or Decorator.
|
||||
return (<CallExpression | Decorator>node).expression;
|
||||
@@ -1402,10 +1417,10 @@ namespace ts {
|
||||
* Returns true if the node is a variable declaration whose initializer is a function expression.
|
||||
* This function does not test if the node is in a JavaScript file or not.
|
||||
*/
|
||||
export function isDeclarationOfFunctionExpression(s: Symbol) {
|
||||
export function isDeclarationOfFunctionOrClassExpression(s: Symbol) {
|
||||
if (s.valueDeclaration && s.valueDeclaration.kind === SyntaxKind.VariableDeclaration) {
|
||||
const declaration = s.valueDeclaration as VariableDeclaration;
|
||||
return declaration.initializer && declaration.initializer.kind === SyntaxKind.FunctionExpression;
|
||||
return declaration.initializer && (declaration.initializer.kind === SyntaxKind.FunctionExpression || declaration.initializer.kind === SyntaxKind.ClassExpression);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1434,6 +1449,10 @@ namespace ts {
|
||||
// module.exports = expr
|
||||
return SpecialPropertyAssignmentKind.ModuleExports;
|
||||
}
|
||||
else {
|
||||
// F.x = expr
|
||||
return SpecialPropertyAssignmentKind.Property;
|
||||
}
|
||||
}
|
||||
else if (lhs.expression.kind === SyntaxKind.ThisKeyword) {
|
||||
return SpecialPropertyAssignmentKind.ThisProperty;
|
||||
@@ -1453,6 +1472,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return SpecialPropertyAssignmentKind.None;
|
||||
}
|
||||
|
||||
@@ -1534,7 +1554,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.push(...filter((doc as JSDoc).tags, tag => tag.kind === kind));
|
||||
const tags = (doc as JSDoc).tags;
|
||||
if (tags) {
|
||||
result.push(...filter(tags, tag => tag.kind === kind));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
@@ -1930,8 +1953,51 @@ namespace ts {
|
||||
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
|
||||
}
|
||||
|
||||
export function isAsyncFunctionLike(node: Node): boolean {
|
||||
return isFunctionLike(node) && hasModifier(node, ModifierFlags.Async) && !isAccessor(node);
|
||||
export const enum FunctionFlags {
|
||||
Normal = 0,
|
||||
Generator = 1 << 0,
|
||||
Async = 1 << 1,
|
||||
AsyncOrAsyncGenerator = Async | Generator,
|
||||
Invalid = 1 << 2,
|
||||
InvalidAsyncOrAsyncGenerator = AsyncOrAsyncGenerator | Invalid,
|
||||
InvalidGenerator = Generator | Invalid,
|
||||
}
|
||||
|
||||
export function getFunctionFlags(node: FunctionLikeDeclaration) {
|
||||
let flags = FunctionFlags.Normal;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
if (node.asteriskToken) {
|
||||
flags |= FunctionFlags.Generator;
|
||||
}
|
||||
// fall through
|
||||
case SyntaxKind.ArrowFunction:
|
||||
if (hasModifier(node, ModifierFlags.Async)) {
|
||||
flags |= FunctionFlags.Async;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!node.body) {
|
||||
flags |= FunctionFlags.Invalid;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
export function isAsyncFunction(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
return (<FunctionLikeDeclaration>node).body !== undefined
|
||||
&& (<FunctionLikeDeclaration>node).asteriskToken === undefined
|
||||
&& hasModifier(node, ModifierFlags.Async);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isStringOrNumericLiteral(node: Node): node is StringLiteral | NumericLiteral {
|
||||
@@ -3063,6 +3129,15 @@ namespace ts {
|
||||
return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
|
||||
}
|
||||
|
||||
export function isExpressionWithTypeArgumentsInClassImplementsClause(node: Node): node is ExpressionWithTypeArguments {
|
||||
return node.kind === SyntaxKind.ExpressionWithTypeArguments
|
||||
&& isEntityNameExpression((node as ExpressionWithTypeArguments).expression)
|
||||
&& node.parent
|
||||
&& (<HeritageClause>node.parent).token === SyntaxKind.ImplementsKeyword
|
||||
&& node.parent.parent
|
||||
&& isClassLike(node.parent.parent);
|
||||
}
|
||||
|
||||
export function isEntityNameExpression(node: Expression): node is EntityNameExpression {
|
||||
return node.kind === SyntaxKind.Identifier ||
|
||||
node.kind === SyntaxKind.PropertyAccessExpression && isEntityNameExpression((<PropertyAccessExpression>node).expression);
|
||||
@@ -3736,6 +3811,12 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.PropertyAccessExpression;
|
||||
}
|
||||
|
||||
export function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.PropertyAccessExpression
|
||||
|| kind === SyntaxKind.QualifiedName;
|
||||
}
|
||||
|
||||
export function isElementAccessExpression(node: Node): node is ElementAccessExpression {
|
||||
return node.kind === SyntaxKind.ElementAccessExpression;
|
||||
}
|
||||
@@ -3954,6 +4035,7 @@ namespace ts {
|
||||
|| kind === SyntaxKind.ImportEqualsDeclaration
|
||||
|| kind === SyntaxKind.ImportSpecifier
|
||||
|| kind === SyntaxKind.InterfaceDeclaration
|
||||
|| kind === SyntaxKind.JsxAttribute
|
||||
|| kind === SyntaxKind.MethodDeclaration
|
||||
|| kind === SyntaxKind.MethodSignature
|
||||
|| kind === SyntaxKind.ModuleDeclaration
|
||||
@@ -4066,6 +4148,11 @@ namespace ts {
|
||||
|| kind === SyntaxKind.JsxText;
|
||||
}
|
||||
|
||||
export function isJsxAttributes(node: Node): node is JsxAttributes {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.JsxAttributes;
|
||||
}
|
||||
|
||||
export function isJsxAttributeLike(node: Node): node is JsxAttributeLike {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.JsxAttribute
|
||||
@@ -4086,6 +4173,12 @@ namespace ts {
|
||||
|| kind === SyntaxKind.JsxExpression;
|
||||
}
|
||||
|
||||
export function isJsxOpeningLikeElement(node: Node): node is JsxOpeningLikeElement {
|
||||
const kind = node.kind;
|
||||
return kind === SyntaxKind.JsxOpeningElement
|
||||
|| kind === SyntaxKind.JsxSelfClosingElement;
|
||||
}
|
||||
|
||||
// Clauses
|
||||
|
||||
export function isCaseOrDefaultClause(node: Node): node is CaseOrDefaultClause {
|
||||
@@ -4140,7 +4233,6 @@ namespace ts {
|
||||
return "lib.es2016.d.ts";
|
||||
case ScriptTarget.ES2015:
|
||||
return "lib.es6.d.ts";
|
||||
|
||||
default:
|
||||
return "lib.d.ts";
|
||||
}
|
||||
@@ -4536,7 +4628,7 @@ namespace ts {
|
||||
*/
|
||||
export function getParseTreeNode<T extends Node>(node: Node, nodeTest?: (node: Node) => node is T): T;
|
||||
export function getParseTreeNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
|
||||
if (isParseTreeNode(node)) {
|
||||
if (node == undefined || isParseTreeNode(node)) {
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -4548,4 +4640,14 @@ namespace ts {
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove extra underscore from escaped identifier text content.
|
||||
*
|
||||
* @param identifier The escaped identifier text.
|
||||
* @returns The unescaped identifier text.
|
||||
*/
|
||||
export function unescapeIdentifier(identifier: string): string {
|
||||
return identifier.length >= 3 && identifier.charCodeAt(0) === CharacterCodes._ && identifier.charCodeAt(1) === CharacterCodes._ && identifier.charCodeAt(2) === CharacterCodes._ ? identifier.substr(1) : identifier;
|
||||
}
|
||||
}
|
||||
|
||||
+763
-747
File diff suppressed because it is too large
Load Diff
+46
-12
@@ -263,6 +263,20 @@ namespace FourSlash {
|
||||
// Create map between fileName and its content for easily looking up when resolveReference flag is specified
|
||||
this.inputFiles.set(file.fileName, file.content);
|
||||
if (ts.getBaseFileName(file.fileName).toLowerCase() === "tsconfig.json") {
|
||||
const configJson = ts.parseConfigFileTextToJson(file.fileName, file.content);
|
||||
if (configJson.config === undefined) {
|
||||
throw new Error(`Failed to parse test tsconfig.json: ${configJson.error.messageText}`);
|
||||
}
|
||||
|
||||
// Extend our existing compiler options so that we can also support tsconfig only options
|
||||
if (configJson.config.compilerOptions) {
|
||||
const baseDirectory = ts.normalizePath(ts.getDirectoryPath(file.fileName));
|
||||
const tsConfig = ts.convertCompilerOptionsFromJson(configJson.config.compilerOptions, baseDirectory, file.fileName);
|
||||
|
||||
if (!tsConfig.errors || !tsConfig.errors.length) {
|
||||
compilationOptions = ts.extend(compilationOptions, tsConfig.options);
|
||||
}
|
||||
}
|
||||
configFileName = file.fileName;
|
||||
}
|
||||
|
||||
@@ -2108,7 +2122,7 @@ namespace FourSlash {
|
||||
* Because codefixes are only applied on the working file, it is unsafe
|
||||
* to apply this more than once (consider a refactoring across files).
|
||||
*/
|
||||
public verifyRangeAfterCodeFix(expectedText: string, errorCode?: number) {
|
||||
public verifyRangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number) {
|
||||
const ranges = this.getRanges();
|
||||
if (ranges.length !== 1) {
|
||||
this.raiseError("Exactly one range should be specified in the testfile.");
|
||||
@@ -2116,11 +2130,15 @@ namespace FourSlash {
|
||||
|
||||
const fileName = this.activeFile.fileName;
|
||||
|
||||
this.applyCodeFixActions(fileName, this.getCodeFixActions(fileName, errorCode));
|
||||
this.applyCodeAction(fileName, this.getCodeFixActions(fileName, errorCode), index);
|
||||
|
||||
const actualText = this.rangeText(ranges[0]);
|
||||
|
||||
if (this.removeWhitespace(actualText) !== this.removeWhitespace(expectedText)) {
|
||||
const result = includeWhiteSpace
|
||||
? actualText === expectedText
|
||||
: this.removeWhitespace(actualText) === this.removeWhitespace(expectedText)
|
||||
|
||||
if (!result) {
|
||||
this.raiseError(`Actual text doesn't match expected text. Actual:\n'${actualText}'\nExpected:\n'${expectedText}'`);
|
||||
}
|
||||
}
|
||||
@@ -2137,7 +2155,7 @@ namespace FourSlash {
|
||||
public verifyFileAfterCodeFix(expectedContents: string, fileName?: string) {
|
||||
fileName = fileName ? fileName : this.activeFile.fileName;
|
||||
|
||||
this.applyCodeFixActions(fileName, this.getCodeFixActions(fileName));
|
||||
this.applyCodeAction(fileName, this.getCodeFixActions(fileName));
|
||||
|
||||
const actualContents: string = this.getFileContent(fileName);
|
||||
if (this.removeWhitespace(actualContents) !== this.removeWhitespace(expectedContents)) {
|
||||
@@ -2150,10 +2168,18 @@ namespace FourSlash {
|
||||
* @param fileName Path to file where error should be retrieved from.
|
||||
*/
|
||||
private getCodeFixActions(fileName: string, errorCode?: number): ts.CodeAction[] {
|
||||
const diagnostics: ts.Diagnostic[] = this.getDiagnostics(fileName);
|
||||
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 diagnostics) {
|
||||
|
||||
for (const diagnostic of dedupedDiagnositcs) {
|
||||
|
||||
if (errorCode && errorCode !== diagnostic.code) {
|
||||
continue;
|
||||
@@ -2167,12 +2193,20 @@ namespace FourSlash {
|
||||
return actions;
|
||||
}
|
||||
|
||||
private applyCodeFixActions(fileName: string, actions: ts.CodeAction[]): void {
|
||||
if (!(actions && actions.length === 1)) {
|
||||
this.raiseError(`Should find exactly one codefix, but ${actions ? actions.length : "none"} found.`);
|
||||
private applyCodeAction(fileName: string, 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.`);
|
||||
}
|
||||
index = 0;
|
||||
}
|
||||
else {
|
||||
if (!(actions && actions.length >= index + 1)) {
|
||||
this.raiseError(`Should find at least ${index + 1} codefix(es), but ${actions ? actions.length : "none"} found.`);
|
||||
}
|
||||
}
|
||||
|
||||
const fileChanges = ts.find(actions[0].changes, change => change.fileName === fileName);
|
||||
const fileChanges = ts.find(actions[index].changes, change => change.fileName === fileName);
|
||||
if (!fileChanges) {
|
||||
this.raiseError("The CodeFix found doesn't provide any changes in this file.");
|
||||
}
|
||||
@@ -3509,8 +3543,8 @@ namespace FourSlashInterface {
|
||||
this.DocCommentTemplate(/*expectedText*/ undefined, /*expectedOffset*/ undefined, /*empty*/ true);
|
||||
}
|
||||
|
||||
public rangeAfterCodeFix(expectedText: string, errorCode?: number): void {
|
||||
this.state.verifyRangeAfterCodeFix(expectedText, errorCode);
|
||||
public rangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number): void {
|
||||
this.state.verifyRangeAfterCodeFix(expectedText, includeWhiteSpace, errorCode, index);
|
||||
}
|
||||
|
||||
public importFixAtPosition(expectedTextArray: string[], errorCode?: number): void {
|
||||
|
||||
+32
-3
@@ -922,10 +922,15 @@ namespace Harness {
|
||||
export const defaultLibFileName = "lib.d.ts";
|
||||
export const es2015DefaultLibFileName = "lib.es2015.d.ts";
|
||||
|
||||
// Cache of lib files from "built/local"
|
||||
const libFileNameSourceFileMap = ts.createMapFromTemplate<ts.SourceFile>({
|
||||
[defaultLibFileName]: createSourceFileAndAssertInvariants(defaultLibFileName, IO.readFile(libFolder + "lib.es5.d.ts"), /*languageVersion*/ ts.ScriptTarget.Latest)
|
||||
});
|
||||
|
||||
// Cache of lib files from "tests/lib/"
|
||||
const testLibFileNameSourceFileMap = ts.createMap<ts.SourceFile>();
|
||||
const es6TestLibFileNameSourceFileMap = ts.createMap<ts.SourceFile>();
|
||||
|
||||
export function getDefaultLibrarySourceFile(fileName = defaultLibFileName): ts.SourceFile {
|
||||
if (!isDefaultLibraryFile(fileName)) {
|
||||
return undefined;
|
||||
@@ -967,7 +972,8 @@ namespace Harness {
|
||||
useCaseSensitiveFileNames: boolean,
|
||||
// the currentDirectory is needed for rwcRunner to passed in specified current directory to compiler host
|
||||
currentDirectory: string,
|
||||
newLineKind?: ts.NewLineKind): ts.CompilerHost {
|
||||
newLineKind?: ts.NewLineKind,
|
||||
libFiles?: string): ts.CompilerHost {
|
||||
|
||||
// Local get canonical file name function, that depends on passed in parameter for useCaseSensitiveFileNames
|
||||
const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
@@ -999,6 +1005,24 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
if (libFiles) {
|
||||
// Because @libFiles don't change between execution. We would cache the result of the files and reuse it to speed help compilation
|
||||
for (const fileName of libFiles.split(",")) {
|
||||
const libFileName = "tests/lib/" + fileName;
|
||||
|
||||
if (scriptTarget <= ts.ScriptTarget.ES5) {
|
||||
if (!testLibFileNameSourceFileMap.get(libFileName)) {
|
||||
testLibFileNameSourceFileMap.set(libFileName, createSourceFileAndAssertInvariants(libFileName, IO.readFile(libFileName), scriptTarget));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!es6TestLibFileNameSourceFileMap.get(libFileName)) {
|
||||
es6TestLibFileNameSourceFileMap.set(libFileName, createSourceFileAndAssertInvariants(libFileName, IO.readFile(libFileName), scriptTarget))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceFile(fileName: string) {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
const fromFileMap = fileMap.get(toPath(fileName));
|
||||
@@ -1010,6 +1034,9 @@ namespace Harness {
|
||||
fourslashSourceFile = fourslashSourceFile || createSourceFileAndAssertInvariants(tsFn, Harness.IO.readFile(tsFn), scriptTarget);
|
||||
return fourslashSourceFile;
|
||||
}
|
||||
else if (ts.startsWith(fileName, "tests/lib/")) {
|
||||
return scriptTarget <= ts.ScriptTarget.ES5 ? testLibFileNameSourceFileMap.get(fileName) : es6TestLibFileNameSourceFileMap.get(fileName);
|
||||
}
|
||||
else {
|
||||
// Don't throw here -- the compiler might be looking for a test that actually doesn't exist as part of the TC
|
||||
// Return if it is other library file, otherwise return undefined
|
||||
@@ -1221,7 +1248,8 @@ namespace Harness {
|
||||
if (options.libFiles) {
|
||||
for (const fileName of options.libFiles.split(",")) {
|
||||
const libFileName = "tests/lib/" + fileName;
|
||||
programFiles.push({ unitName: libFileName, content: normalizeLineEndings(IO.readFile(libFileName), Harness.IO.newLine()) });
|
||||
// Content is undefined here because in createCompilerHost we will create sourceFile for the lib file and cache the result
|
||||
programFiles.push({ unitName: libFileName, content: undefined });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1234,7 +1262,8 @@ namespace Harness {
|
||||
options.target,
|
||||
useCaseSensitiveFileNames,
|
||||
currentDirectory,
|
||||
options.newLine);
|
||||
options.newLine,
|
||||
options.libFiles);
|
||||
|
||||
let traceResults: string[];
|
||||
if (options.traceResolution) {
|
||||
|
||||
@@ -126,7 +126,7 @@ namespace Harness.LanguageService {
|
||||
protected virtualFileSystem: Utils.VirtualFileSystem = new Utils.VirtualFileSystem(virtualFileSystemRoot, /*useCaseSensitiveFilenames*/false);
|
||||
|
||||
constructor(protected cancellationToken = DefaultHostCancellationToken.Instance,
|
||||
protected settings = ts.getDefaultCompilerOptions()) {
|
||||
protected settings = ts.getDefaultCompilerOptions()) {
|
||||
}
|
||||
|
||||
public getNewLine(): string {
|
||||
@@ -135,7 +135,7 @@ namespace Harness.LanguageService {
|
||||
|
||||
public getFilenames(): string[] {
|
||||
const fileNames: string[] = [];
|
||||
for (const virtualEntry of this.virtualFileSystem.getAllFileEntries()){
|
||||
for (const virtualEntry of this.virtualFileSystem.getAllFileEntries()) {
|
||||
const scriptInfo = virtualEntry.content;
|
||||
if (scriptInfo.isRootFile) {
|
||||
// only include root files here
|
||||
@@ -211,8 +211,8 @@ namespace Harness.LanguageService {
|
||||
readDirectory(path: string, extensions?: string[], exclude?: string[], include?: string[]): string[] {
|
||||
return ts.matchFiles(path, extensions, exclude, include,
|
||||
/*useCaseSensitiveFileNames*/false,
|
||||
this.getCurrentDirectory(),
|
||||
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
|
||||
this.getCurrentDirectory(),
|
||||
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
|
||||
}
|
||||
readFile(path: string): string {
|
||||
const snapshot = this.getScriptSnapshot(path);
|
||||
@@ -724,6 +724,87 @@ namespace Harness.LanguageService {
|
||||
createHash(s: string) {
|
||||
return s;
|
||||
}
|
||||
|
||||
require(_initialDir: string, _moduleName: string): ts.server.RequireResult {
|
||||
switch (_moduleName) {
|
||||
// Adds to the Quick Info a fixed string and a string from the config file
|
||||
// and replaces the first display part
|
||||
case "quickinfo-augmeneter":
|
||||
return {
|
||||
module: () => ({
|
||||
create(info: ts.server.PluginCreateInfo) {
|
||||
const proxy = makeDefaultProxy(info);
|
||||
const langSvc: any = info.languageService;
|
||||
proxy.getQuickInfoAtPosition = function () {
|
||||
const parts = langSvc.getQuickInfoAtPosition.apply(langSvc, arguments);
|
||||
if (parts.displayParts.length > 0) {
|
||||
parts.displayParts[0].text = "Proxied";
|
||||
}
|
||||
parts.displayParts.push({ text: info.config.message, kind: "punctuation" });
|
||||
return parts;
|
||||
};
|
||||
|
||||
return proxy;
|
||||
}
|
||||
}),
|
||||
error: undefined
|
||||
};
|
||||
|
||||
// Throws during initialization
|
||||
case "create-thrower":
|
||||
return {
|
||||
module: () => ({
|
||||
create() {
|
||||
throw new Error("I am not a well-behaved plugin");
|
||||
}
|
||||
}),
|
||||
error: undefined
|
||||
};
|
||||
|
||||
// Adds another diagnostic
|
||||
case "diagnostic-adder":
|
||||
return {
|
||||
module: () => ({
|
||||
create(info: ts.server.PluginCreateInfo) {
|
||||
const proxy = makeDefaultProxy(info);
|
||||
proxy.getSemanticDiagnostics = function (filename: string) {
|
||||
const prev = info.languageService.getSemanticDiagnostics(filename);
|
||||
const sourceFile: ts.SourceFile = info.languageService.getSourceFile(filename);
|
||||
prev.push({
|
||||
category: ts.DiagnosticCategory.Warning,
|
||||
file: sourceFile,
|
||||
code: 9999,
|
||||
length: 3,
|
||||
messageText: `Plugin diagnostic`,
|
||||
start: 0
|
||||
});
|
||||
return prev;
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
}),
|
||||
error: undefined
|
||||
};
|
||||
|
||||
default:
|
||||
return {
|
||||
module: undefined,
|
||||
error: "Could not resolve module"
|
||||
};
|
||||
}
|
||||
|
||||
function makeDefaultProxy(info: ts.server.PluginCreateInfo) {
|
||||
// tslint:disable-next-line:no-null-keyword
|
||||
const proxy = Object.create(null);
|
||||
const langSvc: any = info.languageService;
|
||||
for (const k of Object.keys(langSvc)) {
|
||||
proxy[k] = function () {
|
||||
return langSvc[k].apply(langSvc, arguments);
|
||||
};
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerLanguageServiceAdapter implements LanguageServiceAdapter {
|
||||
@@ -738,7 +819,7 @@ namespace Harness.LanguageService {
|
||||
// host to answer server queries about files on disk
|
||||
const serverHost = new SessionServerHost(clientHost);
|
||||
const server = new ts.server.Session(serverHost,
|
||||
{ isCancellationRequested: () => false },
|
||||
ts.server.nullCancellationToken,
|
||||
/*useOneInferredProject*/ false,
|
||||
/*typingsInstaller*/ undefined,
|
||||
Utils.byteLength,
|
||||
|
||||
@@ -77,8 +77,8 @@
|
||||
"../services/codefixes/helpers.ts",
|
||||
"../services/codefixes/importFixes.ts",
|
||||
"../services/codefixes/unusedIdentifierFixes.ts",
|
||||
"../services/harness.ts",
|
||||
|
||||
"harness.ts",
|
||||
"sourceMapRecorder.ts",
|
||||
"harnessLanguageService.ts",
|
||||
"fourslash.ts",
|
||||
@@ -119,6 +119,8 @@
|
||||
"./unittests/compileOnSave.ts",
|
||||
"./unittests/typingsInstaller.ts",
|
||||
"./unittests/projectErrors.ts",
|
||||
"./unittests/printer.ts"
|
||||
"./unittests/printer.ts",
|
||||
"./unittests/transform.ts",
|
||||
"./unittests/customTransforms.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace ts {
|
||||
assertParseResult(["--lib", "es5,invalidOption", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'",
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'esnext'",
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'esnext'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -191,7 +191,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace ts {
|
||||
assertParseResult(["--lib", "es5,", "es7", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -283,7 +283,7 @@ namespace ts {
|
||||
assertParseResult(["--lib", "es5, ", "es7", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
namespace ts.projectSystem {
|
||||
import CommandNames = server.CommandNames;
|
||||
const nullCancellationToken = server.nullCancellationToken;
|
||||
|
||||
function createTestTypingsInstaller(host: server.ServerHost) {
|
||||
return new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'",
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react-native', 'react'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -122,7 +122,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -150,7 +150,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -176,7 +176,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'esnext'",
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'esnext'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -202,7 +202,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -233,7 +233,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -264,7 +264,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -295,7 +295,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -326,7 +326,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'esnext', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'esnext.asynciterable'.",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/// <reference path="..\..\compiler\emitter.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("customTransforms", () => {
|
||||
function emitsCorrectly(name: string, sources: { file: string, text: string }[], customTransformers: CustomTransformers) {
|
||||
it(name, () => {
|
||||
const roots = sources.map(source => createSourceFile(source.file, source.text, ScriptTarget.ES2015));
|
||||
const fileMap = arrayToMap(roots, file => file.fileName);
|
||||
const outputs = createMap<string>();
|
||||
const options: CompilerOptions = {};
|
||||
const host: CompilerHost = {
|
||||
getSourceFile: (fileName) => fileMap.get(fileName),
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
getCurrentDirectory: () => "",
|
||||
getDirectories: () => [],
|
||||
getCanonicalFileName: (fileName) => fileName,
|
||||
useCaseSensitiveFileNames: () => true,
|
||||
getNewLine: () => "\n",
|
||||
fileExists: (fileName) => fileMap.has(fileName),
|
||||
readFile: (fileName) => fileMap.has(fileName) ? fileMap.get(fileName).text : undefined,
|
||||
writeFile: (fileName, text) => outputs.set(fileName, text),
|
||||
};
|
||||
|
||||
const program = createProgram(arrayFrom(fileMap.keys()), options, host);
|
||||
program.emit(/*targetSourceFile*/ undefined, host.writeFile, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ false, customTransformers);
|
||||
Harness.Baseline.runBaseline(`customTransforms/${name}.js`, () => {
|
||||
let content = "";
|
||||
for (const [file, text] of arrayFrom(outputs.entries())) {
|
||||
if (content) content += "\n\n";
|
||||
content += `// [${file}]\n`;
|
||||
content += text;
|
||||
}
|
||||
return content;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const sources = [{
|
||||
file: "source.ts",
|
||||
text: `
|
||||
function f1() { }
|
||||
class c() { }
|
||||
enum e { }
|
||||
// leading
|
||||
function f2() { } // trailing
|
||||
`
|
||||
}];
|
||||
|
||||
const before: TransformerFactory<SourceFile> = context => {
|
||||
return file => visitEachChild(file, visit, context);
|
||||
function visit(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return visitFunction(<FunctionDeclaration>node);
|
||||
default:
|
||||
return visitEachChild(node, visit, context);
|
||||
}
|
||||
}
|
||||
function visitFunction(node: FunctionDeclaration) {
|
||||
addSyntheticLeadingComment(node, SyntaxKind.MultiLineCommentTrivia, "@before", /*hasTrailingNewLine*/ true);
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
const after: TransformerFactory<SourceFile> = context => {
|
||||
return file => visitEachChild(file, visit, context);
|
||||
function visit(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
return visitVariableStatement(<VariableStatement>node);
|
||||
default:
|
||||
return visitEachChild(node, visit, context);
|
||||
}
|
||||
}
|
||||
function visitVariableStatement(node: VariableStatement) {
|
||||
addSyntheticLeadingComment(node, SyntaxKind.SingleLineCommentTrivia, "@after");
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
emitsCorrectly("before", sources, { before: [before] });
|
||||
emitsCorrectly("after", sources, { after: [after] });
|
||||
emitsCorrectly("both", sources, { before: [before], after: [after] });
|
||||
});
|
||||
}
|
||||
@@ -27,7 +27,7 @@ namespace ts.server {
|
||||
clearImmediate: noop,
|
||||
createHash: s => s
|
||||
};
|
||||
const nullCancellationToken: HostCancellationToken = { isCancellationRequested: () => false };
|
||||
|
||||
const mockLogger: Logger = {
|
||||
close: noop,
|
||||
hasLevel(): boolean { return false; },
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/// <reference path="..\..\services\transform.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe("TransformAPI", () => {
|
||||
function transformsCorrectly(name: string, source: string, transformers: TransformerFactory<SourceFile>[]) {
|
||||
it(name, () => {
|
||||
Harness.Baseline.runBaseline(`transformApi/transformsCorrectly.${name}.js`, () => {
|
||||
const transformed = transform(createSourceFile("source.ts", source, ScriptTarget.ES2015), transformers);
|
||||
const printer = createPrinter({ newLine: NewLineKind.CarriageReturnLineFeed }, {
|
||||
onEmitNode: transformed.emitNodeWithNotification,
|
||||
substituteNode: transformed.substituteNode
|
||||
});
|
||||
const result = printer.printBundle(createBundle(transformed.transformed));
|
||||
transformed.dispose();
|
||||
return result;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
transformsCorrectly("substitution", `
|
||||
var a = undefined;
|
||||
`, [
|
||||
context => {
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
context.enableSubstitution(SyntaxKind.Identifier);
|
||||
context.onSubstituteNode = (hint, node) => {
|
||||
node = previousOnSubstituteNode(hint, node);
|
||||
if (hint === EmitHint.Expression && node.kind === SyntaxKind.Identifier && (<Identifier>node).text === "undefined") {
|
||||
node = createPartiallyEmittedExpression(
|
||||
addSyntheticTrailingComment(
|
||||
setTextRange(
|
||||
createVoidZero(),
|
||||
node),
|
||||
SyntaxKind.MultiLineCommentTrivia, "undefined"));
|
||||
}
|
||||
return node;
|
||||
};
|
||||
return file => file;
|
||||
}
|
||||
]);
|
||||
});
|
||||
}
|
||||
@@ -34,10 +34,6 @@ namespace ts.projectSystem {
|
||||
getLogFileName: (): string => undefined
|
||||
};
|
||||
|
||||
export const nullCancellationToken: HostCancellationToken = {
|
||||
isCancellationRequested: () => false
|
||||
};
|
||||
|
||||
export const { content: libFileContent } = Harness.getDefaultLibraryFile(Harness.IO);
|
||||
export const libFile: FileOrFolder = {
|
||||
path: "/a/lib/lib.d.ts",
|
||||
@@ -158,17 +154,33 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
class TestSession extends server.Session {
|
||||
private seq = 0;
|
||||
|
||||
getProjectService() {
|
||||
return this.projectService;
|
||||
}
|
||||
|
||||
public getSeq() {
|
||||
return this.seq;
|
||||
}
|
||||
|
||||
public getNextSeq() {
|
||||
return this.seq + 1;
|
||||
}
|
||||
|
||||
public executeCommandSeq<T extends server.protocol.Request>(request: Partial<T>) {
|
||||
this.seq++;
|
||||
request.seq = this.seq;
|
||||
request.type = "request";
|
||||
return this.executeCommand(<T>request);
|
||||
}
|
||||
};
|
||||
|
||||
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler) {
|
||||
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler, cancellationToken?: server.ServerCancellationToken) {
|
||||
if (typingsInstaller === undefined) {
|
||||
typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
|
||||
}
|
||||
|
||||
return new TestSession(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
|
||||
return new TestSession(host, cancellationToken || server.nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
|
||||
}
|
||||
|
||||
export interface CreateProjectServiceParameters {
|
||||
@@ -191,7 +203,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
}
|
||||
export function createProjectService(host: server.ServerHost, parameters: CreateProjectServiceParameters = {}) {
|
||||
const cancellationToken = parameters.cancellationToken || nullCancellationToken;
|
||||
const cancellationToken = parameters.cancellationToken || server.nullCancellationToken;
|
||||
const logger = parameters.logger || nullLogger;
|
||||
const useSingleInferredProject = parameters.useSingleInferredProject !== undefined ? parameters.useSingleInferredProject : false;
|
||||
return new TestProjectService(host, logger, cancellationToken, useSingleInferredProject, parameters.typingsInstaller, parameters.eventHandler);
|
||||
@@ -328,6 +340,8 @@ namespace ts.projectSystem {
|
||||
export class TestServerHost implements server.ServerHost {
|
||||
args: string[] = [];
|
||||
|
||||
private readonly output: string[] = [];
|
||||
|
||||
private fs: ts.FileMap<FSEntry>;
|
||||
private getCanonicalFileName: (s: string) => string;
|
||||
private toPath: (f: string) => Path;
|
||||
@@ -477,6 +491,10 @@ namespace ts.projectSystem {
|
||||
this.timeoutCallbacks.invoke();
|
||||
}
|
||||
|
||||
runQueuedImmediateCallbacks() {
|
||||
this.immediateCallbacks.invoke();
|
||||
}
|
||||
|
||||
setImmediate(callback: TimeOutCallback, _time: number, ...args: any[]) {
|
||||
return this.immediateCallbacks.register(callback, args);
|
||||
}
|
||||
@@ -509,7 +527,17 @@ namespace ts.projectSystem {
|
||||
this.reloadFS(filesOrFolders);
|
||||
}
|
||||
|
||||
write() { }
|
||||
write(message: string) {
|
||||
this.output.push(message);
|
||||
}
|
||||
|
||||
getOutput(): ReadonlyArray<string> {
|
||||
return this.output;
|
||||
}
|
||||
|
||||
clearOutput() {
|
||||
this.output.length = 0;
|
||||
}
|
||||
|
||||
readonly readFile = (s: string) => (<File>this.fs.get(this.toPath(s))).content;
|
||||
readonly resolvePath = (s: string) => s;
|
||||
@@ -1685,6 +1713,115 @@ namespace ts.projectSystem {
|
||||
assert(completions && completions.entries[0].name !== "hello", `unexpected hello entry in completion list`);
|
||||
});
|
||||
|
||||
it("no tsconfig script block diagnostic errors", () => {
|
||||
|
||||
// #1. Ensure no diagnostic errors when allowJs is true
|
||||
const file1 = {
|
||||
path: "/a/b/f1.ts",
|
||||
content: ` `
|
||||
};
|
||||
const file2 = {
|
||||
path: "/a/b/f2.html",
|
||||
content: `var hello = "hello";`
|
||||
};
|
||||
const config1 = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({ compilerOptions: { allowJs: true } })
|
||||
};
|
||||
|
||||
let host = createServerHost([file1, file2, config1, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
|
||||
let session = createSession(host);
|
||||
|
||||
// Specify .html extension as mixed content in a configure host request
|
||||
const extraFileExtensions = [{ extension: ".html", scriptKind: ScriptKind.JS, isMixedContent: true }];
|
||||
const configureHostRequest = makeSessionRequest<protocol.ConfigureRequestArguments>(CommandNames.Configure, { extraFileExtensions });
|
||||
session.executeCommand(configureHostRequest).response;
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
let projectService = session.getProjectService();
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
|
||||
let diagnostics = projectService.configuredProjects[0].getLanguageService().getCompilerOptionsDiagnostics();
|
||||
assert.deepEqual(diagnostics, []);
|
||||
|
||||
// #2. Ensure no errors when allowJs is false
|
||||
const config2 = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({ compilerOptions: { allowJs: false } })
|
||||
};
|
||||
|
||||
host = createServerHost([file1, file2, config2, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
|
||||
session = createSession(host);
|
||||
|
||||
session.executeCommand(configureHostRequest).response;
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
projectService = session.getProjectService();
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
|
||||
diagnostics = projectService.configuredProjects[0].getLanguageService().getCompilerOptionsDiagnostics();
|
||||
assert.deepEqual(diagnostics, []);
|
||||
|
||||
// #3. Ensure no errors when compiler options aren't specified
|
||||
const config3 = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({ })
|
||||
};
|
||||
|
||||
host = createServerHost([file1, file2, config3, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
|
||||
session = createSession(host);
|
||||
|
||||
session.executeCommand(configureHostRequest).response;
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
projectService = session.getProjectService();
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
|
||||
diagnostics = projectService.configuredProjects[0].getLanguageService().getCompilerOptionsDiagnostics();
|
||||
assert.deepEqual(diagnostics, []);
|
||||
|
||||
// #4. Ensure no errors when files are explicitly specified in tsconfig
|
||||
const config4 = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({ compilerOptions: { allowJs: true }, files: [file1.path, file2.path] })
|
||||
};
|
||||
|
||||
host = createServerHost([file1, file2, config4, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
|
||||
session = createSession(host);
|
||||
|
||||
session.executeCommand(configureHostRequest).response;
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
projectService = session.getProjectService();
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
|
||||
diagnostics = projectService.configuredProjects[0].getLanguageService().getCompilerOptionsDiagnostics();
|
||||
assert.deepEqual(diagnostics, []);
|
||||
|
||||
// #4. Ensure no errors when files are explicitly excluded in tsconfig
|
||||
const config5 = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
content: JSON.stringify({ compilerOptions: { allowJs: true }, exclude: [file2.path] })
|
||||
};
|
||||
|
||||
host = createServerHost([file1, file2, config5, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
|
||||
session = createSession(host);
|
||||
|
||||
session.executeCommand(configureHostRequest).response;
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
projectService = session.getProjectService();
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
|
||||
diagnostics = projectService.configuredProjects[0].getLanguageService().getCompilerOptionsDiagnostics();
|
||||
assert.deepEqual(diagnostics, []);
|
||||
});
|
||||
|
||||
it("project structure update is deferred if files are not added\removed", () => {
|
||||
const file1 = {
|
||||
path: "/a/b/f1.ts",
|
||||
@@ -2898,6 +3035,33 @@ namespace ts.projectSystem {
|
||||
const inferredProject = projectService.inferredProjects[0];
|
||||
assert.isTrue(inferredProject.containsFile(<server.NormalizedPath>file1.path));
|
||||
});
|
||||
|
||||
it("should be able to handle @types if input file list is empty", () => {
|
||||
const f = {
|
||||
path: "/a/app.ts",
|
||||
content: "let x = 1"
|
||||
};
|
||||
const config = {
|
||||
path: "/a/tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compiler: {},
|
||||
files: []
|
||||
})
|
||||
};
|
||||
const t1 = {
|
||||
path: "/a/node_modules/@types/typings/index.d.ts",
|
||||
content: `export * from "./lib"`
|
||||
};
|
||||
const t2 = {
|
||||
path: "/a/node_modules/@types/typings/lib.d.ts",
|
||||
content: `export const x: number`
|
||||
};
|
||||
const host = createServerHost([f, config, t1, t2], { currentDirectory: getDirectoryPath(f.path) });
|
||||
const projectService = createProjectService(host);
|
||||
|
||||
projectService.openClientFile(f.path);
|
||||
projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: 1 });
|
||||
});
|
||||
});
|
||||
|
||||
describe("reload", () => {
|
||||
@@ -3131,6 +3295,200 @@ namespace ts.projectSystem {
|
||||
});
|
||||
});
|
||||
|
||||
describe("cancellationToken", () => {
|
||||
it("is attached to request", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let xyz = 1;"
|
||||
};
|
||||
const host = createServerHost([f1]);
|
||||
let expectedRequestId: number;
|
||||
const cancellationToken: server.ServerCancellationToken = {
|
||||
isCancellationRequested: () => false,
|
||||
setRequest: requestId => {
|
||||
if (expectedRequestId === undefined) {
|
||||
assert.isTrue(false, "unexpected call")
|
||||
}
|
||||
assert.equal(requestId, expectedRequestId);
|
||||
},
|
||||
resetRequest: noop
|
||||
}
|
||||
const session = createSession(host, /*typingsInstaller*/ undefined, /*projectServiceEventHandler*/ undefined, cancellationToken);
|
||||
|
||||
expectedRequestId = session.getNextSeq();
|
||||
session.executeCommandSeq(<server.protocol.OpenRequest>{
|
||||
command: "open",
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
|
||||
expectedRequestId = session.getNextSeq();
|
||||
session.executeCommandSeq(<server.protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
|
||||
expectedRequestId = session.getNextSeq();
|
||||
session.executeCommandSeq(<server.protocol.OccurrencesRequest>{
|
||||
command: "occurrences",
|
||||
arguments: { file: f1.path, line: 1, offset: 6 }
|
||||
});
|
||||
|
||||
expectedRequestId = 2;
|
||||
host.runQueuedImmediateCallbacks();
|
||||
expectedRequestId = 2;
|
||||
host.runQueuedImmediateCallbacks();
|
||||
});
|
||||
|
||||
it("Geterr is cancellable", () => {
|
||||
const f1 = {
|
||||
path: "/a/app.ts",
|
||||
content: "let x = 1"
|
||||
};
|
||||
const config = {
|
||||
path: "/a/tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {}
|
||||
})
|
||||
};
|
||||
|
||||
let requestToCancel = -1;
|
||||
const cancellationToken: server.ServerCancellationToken = (function(){
|
||||
let currentId: number;
|
||||
return <server.ServerCancellationToken>{
|
||||
setRequest(requestId) {
|
||||
currentId = requestId;
|
||||
},
|
||||
resetRequest(requestId) {
|
||||
assert.equal(requestId, currentId, "unexpected request id in cancellation")
|
||||
currentId = undefined;
|
||||
},
|
||||
isCancellationRequested() {
|
||||
return requestToCancel === currentId;
|
||||
}
|
||||
}
|
||||
})();
|
||||
const host = createServerHost([f1, config]);
|
||||
const session = createSession(host, /*typingsInstaller*/ undefined, () => {}, cancellationToken);
|
||||
{
|
||||
session.executeCommandSeq(<protocol.OpenRequest>{
|
||||
command: "open",
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
// send geterr for missing file
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: ["/a/missing"] }
|
||||
});
|
||||
// no files - expect 'completed' event
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 message");
|
||||
verifyRequestCompleted(session.getSeq(), 0);
|
||||
}
|
||||
{
|
||||
const getErrId = session.getNextSeq();
|
||||
// send geterr for a valid file
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
|
||||
assert.equal(host.getOutput().length, 0, "expect 0 messages");
|
||||
|
||||
// run new request
|
||||
session.executeCommandSeq(<protocol.ProjectInfoRequest>{
|
||||
command: "projectInfo",
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
host.clearOutput();
|
||||
|
||||
// cancel previously issued Geterr
|
||||
requestToCancel = getErrId;
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 message");
|
||||
verifyRequestCompleted(getErrId, 0);
|
||||
|
||||
requestToCancel = -1;
|
||||
}
|
||||
{
|
||||
const getErrId = session.getNextSeq();
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
assert.equal(host.getOutput().length, 0, "expect 0 messages");
|
||||
|
||||
// run first step
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 messages");
|
||||
const e1 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e1.event, "syntaxDiag");
|
||||
host.clearOutput();
|
||||
|
||||
requestToCancel = getErrId;
|
||||
host.runQueuedImmediateCallbacks();
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 message");
|
||||
verifyRequestCompleted(getErrId, 0);
|
||||
|
||||
requestToCancel = -1;
|
||||
}
|
||||
{
|
||||
const getErrId = session.getNextSeq();
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
assert.equal(host.getOutput().length, 0, "expect 0 messages");
|
||||
|
||||
// run first step
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 messages");
|
||||
const e1 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e1.event, "syntaxDiag");
|
||||
host.clearOutput();
|
||||
|
||||
host.runQueuedImmediateCallbacks();
|
||||
assert.equal(host.getOutput().length, 2, "expect 2 messages");
|
||||
const e2 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e2.event, "semanticDiag");
|
||||
verifyRequestCompleted(getErrId, 1);
|
||||
|
||||
requestToCancel = -1;
|
||||
}
|
||||
{
|
||||
const getErr1 = session.getNextSeq();
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
assert.equal(host.getOutput().length, 0, "expect 0 messages");
|
||||
// run first step
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
assert.equal(host.getOutput().length, 1, "expect 1 messages");
|
||||
const e1 = <protocol.Event>getMessage(0);
|
||||
assert.equal(e1.event, "syntaxDiag");
|
||||
host.clearOutput();
|
||||
|
||||
session.executeCommandSeq(<protocol.GeterrRequest>{
|
||||
command: "geterr",
|
||||
arguments: { files: [f1.path] }
|
||||
});
|
||||
// make sure that getErr1 is completed
|
||||
verifyRequestCompleted(getErr1, 0);
|
||||
}
|
||||
|
||||
function verifyRequestCompleted(expectedSeq: number, n: number) {
|
||||
const event = <protocol.RequestCompletedEvent>getMessage(n);
|
||||
assert.equal(event.event, "requestCompleted");
|
||||
assert.equal(event.body.request_seq, expectedSeq, "expectedSeq");
|
||||
host.clearOutput();
|
||||
}
|
||||
|
||||
function getMessage(n: number) {
|
||||
return JSON.parse(server.extractMessage(host.getOutput()[n]));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("maxNodeModuleJsDepth for inferred projects", () => {
|
||||
it("should be set to 2 if the project has js root files", () => {
|
||||
const file1: FileOrFolder = {
|
||||
@@ -3184,5 +3542,4 @@ namespace ts.projectSystem {
|
||||
assert.isUndefined(project.getCompilerOptions().maxNodeModuleJsDepth);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
Vendored
+65
-65
@@ -1331,7 +1331,7 @@ interface AudioContextBase extends EventTarget {
|
||||
onstatechange: (this: AudioContext, ev: Event) => any;
|
||||
readonly sampleRate: number;
|
||||
readonly state: string;
|
||||
close(): PromiseLike<void>;
|
||||
close(): Promise<void>;
|
||||
createAnalyser(): AnalyserNode;
|
||||
createBiquadFilter(): BiquadFilterNode;
|
||||
createBuffer(numberOfChannels: number, length: number, sampleRate: number): AudioBuffer;
|
||||
@@ -1351,14 +1351,14 @@ interface AudioContextBase extends EventTarget {
|
||||
createScriptProcessor(bufferSize?: number, numberOfInputChannels?: number, numberOfOutputChannels?: number): ScriptProcessorNode;
|
||||
createStereoPanner(): StereoPannerNode;
|
||||
createWaveShaper(): WaveShaperNode;
|
||||
decodeAudioData(audioData: ArrayBuffer, successCallback?: DecodeSuccessCallback, errorCallback?: DecodeErrorCallback): PromiseLike<AudioBuffer>;
|
||||
resume(): PromiseLike<void>;
|
||||
decodeAudioData(audioData: ArrayBuffer, successCallback?: DecodeSuccessCallback, errorCallback?: DecodeErrorCallback): Promise<AudioBuffer>;
|
||||
resume(): Promise<void>;
|
||||
addEventListener<K extends keyof AudioContextEventMap>(type: K, listener: (this: AudioContext, ev: AudioContextEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
interface AudioContext extends AudioContextBase {
|
||||
suspend(): PromiseLike<void>;
|
||||
suspend(): Promise<void>;
|
||||
}
|
||||
|
||||
declare var AudioContext: {
|
||||
@@ -2076,13 +2076,13 @@ declare var CSSSupportsRule: {
|
||||
}
|
||||
|
||||
interface Cache {
|
||||
add(request: RequestInfo): PromiseLike<void>;
|
||||
addAll(requests: RequestInfo[]): PromiseLike<void>;
|
||||
delete(request: RequestInfo, options?: CacheQueryOptions): PromiseLike<boolean>;
|
||||
add(request: RequestInfo): Promise<void>;
|
||||
addAll(requests: RequestInfo[]): Promise<void>;
|
||||
delete(request: RequestInfo, options?: CacheQueryOptions): Promise<boolean>;
|
||||
keys(request?: RequestInfo, options?: CacheQueryOptions): any;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): PromiseLike<Response>;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): Promise<Response>;
|
||||
matchAll(request?: RequestInfo, options?: CacheQueryOptions): any;
|
||||
put(request: RequestInfo, response: Response): PromiseLike<void>;
|
||||
put(request: RequestInfo, response: Response): Promise<void>;
|
||||
}
|
||||
|
||||
declare var Cache: {
|
||||
@@ -2091,11 +2091,11 @@ declare var Cache: {
|
||||
}
|
||||
|
||||
interface CacheStorage {
|
||||
delete(cacheName: string): PromiseLike<boolean>;
|
||||
has(cacheName: string): PromiseLike<boolean>;
|
||||
delete(cacheName: string): Promise<boolean>;
|
||||
has(cacheName: string): Promise<boolean>;
|
||||
keys(): any;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): PromiseLike<any>;
|
||||
open(cacheName: string): PromiseLike<Cache>;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): Promise<any>;
|
||||
open(cacheName: string): Promise<Cache>;
|
||||
}
|
||||
|
||||
declare var CacheStorage: {
|
||||
@@ -5716,7 +5716,7 @@ interface HTMLMediaElement extends HTMLElement {
|
||||
* Loads and starts playback of a media resource.
|
||||
*/
|
||||
play(): void;
|
||||
setMediaKeys(mediaKeys: MediaKeys | null): PromiseLike<void>;
|
||||
setMediaKeys(mediaKeys: MediaKeys | null): Promise<void>;
|
||||
readonly HAVE_CURRENT_DATA: number;
|
||||
readonly HAVE_ENOUGH_DATA: number;
|
||||
readonly HAVE_FUTURE_DATA: number;
|
||||
@@ -7294,7 +7294,7 @@ interface MSApp {
|
||||
execAsyncAtPriority(asynchronousCallback: MSExecAtPriorityFunctionCallback, priority: string, ...args: any[]): void;
|
||||
execAtPriority(synchronousCallback: MSExecAtPriorityFunctionCallback, priority: string, ...args: any[]): any;
|
||||
getCurrentPriority(): string;
|
||||
getHtmlPrintDocumentSourceAsync(htmlDoc: any): PromiseLike<any>;
|
||||
getHtmlPrintDocumentSourceAsync(htmlDoc: any): Promise<any>;
|
||||
getViewId(view: any): any;
|
||||
isTaskScheduledAtPriorityOrHigher(priority: string): boolean;
|
||||
pageHandlesAllApplicationActivations(enabled: boolean): void;
|
||||
@@ -7355,8 +7355,8 @@ declare var MSBlobBuilder: {
|
||||
}
|
||||
|
||||
interface MSCredentials {
|
||||
getAssertion(challenge: string, filter?: MSCredentialFilter, params?: MSSignatureParameters): PromiseLike<MSAssertion>;
|
||||
makeCredential(accountInfo: MSAccountInfo, params: MSCredentialParameters[], challenge?: string): PromiseLike<MSAssertion>;
|
||||
getAssertion(challenge: string, filter?: MSCredentialFilter, params?: MSSignatureParameters): Promise<MSAssertion>;
|
||||
makeCredential(accountInfo: MSAccountInfo, params: MSCredentialParameters[], challenge?: string): Promise<MSAssertion>;
|
||||
}
|
||||
|
||||
declare var MSCredentials: {
|
||||
@@ -7744,7 +7744,7 @@ interface MediaDevices extends EventTarget {
|
||||
ondevicechange: (this: MediaDevices, ev: Event) => any;
|
||||
enumerateDevices(): any;
|
||||
getSupportedConstraints(): MediaTrackSupportedConstraints;
|
||||
getUserMedia(constraints: MediaStreamConstraints): PromiseLike<MediaStream>;
|
||||
getUserMedia(constraints: MediaStreamConstraints): Promise<MediaStream>;
|
||||
addEventListener<K extends keyof MediaDevicesEventMap>(type: K, listener: (this: MediaDevices, ev: MediaDevicesEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
@@ -7803,15 +7803,15 @@ declare var MediaKeyMessageEvent: {
|
||||
}
|
||||
|
||||
interface MediaKeySession extends EventTarget {
|
||||
readonly closed: PromiseLike<void>;
|
||||
readonly closed: Promise<void>;
|
||||
readonly expiration: number;
|
||||
readonly keyStatuses: MediaKeyStatusMap;
|
||||
readonly sessionId: string;
|
||||
close(): PromiseLike<void>;
|
||||
generateRequest(initDataType: string, initData: any): PromiseLike<void>;
|
||||
load(sessionId: string): PromiseLike<boolean>;
|
||||
remove(): PromiseLike<void>;
|
||||
update(response: any): PromiseLike<void>;
|
||||
close(): Promise<void>;
|
||||
generateRequest(initDataType: string, initData: any): Promise<void>;
|
||||
load(sessionId: string): Promise<boolean>;
|
||||
remove(): Promise<void>;
|
||||
update(response: any): Promise<void>;
|
||||
}
|
||||
|
||||
declare var MediaKeySession: {
|
||||
@@ -7833,7 +7833,7 @@ declare var MediaKeyStatusMap: {
|
||||
|
||||
interface MediaKeySystemAccess {
|
||||
readonly keySystem: string;
|
||||
createMediaKeys(): PromiseLike<MediaKeys>;
|
||||
createMediaKeys(): Promise<MediaKeys>;
|
||||
getConfiguration(): MediaKeySystemConfiguration;
|
||||
}
|
||||
|
||||
@@ -7844,7 +7844,7 @@ declare var MediaKeySystemAccess: {
|
||||
|
||||
interface MediaKeys {
|
||||
createSession(sessionType?: string): MediaKeySession;
|
||||
setServerCertificate(serverCertificate: any): PromiseLike<void>;
|
||||
setServerCertificate(serverCertificate: any): Promise<void>;
|
||||
}
|
||||
|
||||
declare var MediaKeys: {
|
||||
@@ -7983,7 +7983,7 @@ interface MediaStreamTrack extends EventTarget {
|
||||
readonly readonly: boolean;
|
||||
readonly readyState: string;
|
||||
readonly remote: boolean;
|
||||
applyConstraints(constraints: MediaTrackConstraints): PromiseLike<void>;
|
||||
applyConstraints(constraints: MediaTrackConstraints): Promise<void>;
|
||||
clone(): MediaStreamTrack;
|
||||
getCapabilities(): MediaTrackCapabilities;
|
||||
getConstraints(): MediaTrackConstraints;
|
||||
@@ -8217,7 +8217,7 @@ interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorConte
|
||||
getGamepads(): Gamepad[];
|
||||
javaEnabled(): boolean;
|
||||
msLaunchUri(uri: string, successCallback?: MSLaunchUriCallback, noHandlerCallback?: MSLaunchUriCallback): void;
|
||||
requestMediaKeySystemAccess(keySystem: string, supportedConfigurations: MediaKeySystemConfiguration[]): PromiseLike<MediaKeySystemAccess>;
|
||||
requestMediaKeySystemAccess(keySystem: string, supportedConfigurations: MediaKeySystemConfiguration[]): Promise<MediaKeySystemAccess>;
|
||||
vibrate(pattern: number | number[]): boolean;
|
||||
}
|
||||
|
||||
@@ -8377,7 +8377,7 @@ interface Notification extends EventTarget {
|
||||
declare var Notification: {
|
||||
prototype: Notification;
|
||||
new(title: string, options?: NotificationOptions): Notification;
|
||||
requestPermission(callback?: NotificationPermissionCallback): PromiseLike<string>;
|
||||
requestPermission(callback?: NotificationPermissionCallback): Promise<string>;
|
||||
}
|
||||
|
||||
interface OES_element_index_uint {
|
||||
@@ -8448,8 +8448,8 @@ interface OfflineAudioContextEventMap extends AudioContextEventMap {
|
||||
interface OfflineAudioContext extends AudioContextBase {
|
||||
readonly length: number;
|
||||
oncomplete: (this: OfflineAudioContext, ev: OfflineAudioCompletionEvent) => any;
|
||||
startRendering(): PromiseLike<AudioBuffer>;
|
||||
suspend(suspendTime: number): PromiseLike<void>;
|
||||
startRendering(): Promise<AudioBuffer>;
|
||||
suspend(suspendTime: number): Promise<void>;
|
||||
addEventListener<K extends keyof OfflineAudioContextEventMap>(type: K, listener: (this: OfflineAudioContext, ev: OfflineAudioContextEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
@@ -8564,8 +8564,8 @@ interface PaymentRequest extends EventTarget {
|
||||
readonly shippingAddress: PaymentAddress | null;
|
||||
readonly shippingOption: string | null;
|
||||
readonly shippingType: string | null;
|
||||
abort(): PromiseLike<void>;
|
||||
show(): PromiseLike<PaymentResponse>;
|
||||
abort(): Promise<void>;
|
||||
show(): Promise<PaymentResponse>;
|
||||
addEventListener<K extends keyof PaymentRequestEventMap>(type: K, listener: (this: PaymentRequest, ev: PaymentRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
@@ -8576,7 +8576,7 @@ declare var PaymentRequest: {
|
||||
}
|
||||
|
||||
interface PaymentRequestUpdateEvent extends Event {
|
||||
updateWith(d: PromiseLike<PaymentDetails>): void;
|
||||
updateWith(d: Promise<PaymentDetails>): void;
|
||||
}
|
||||
|
||||
declare var PaymentRequestUpdateEvent: {
|
||||
@@ -8592,7 +8592,7 @@ interface PaymentResponse {
|
||||
readonly payerPhone: string | null;
|
||||
readonly shippingAddress: PaymentAddress | null;
|
||||
readonly shippingOption: string | null;
|
||||
complete(result?: string): PromiseLike<void>;
|
||||
complete(result?: string): Promise<void>;
|
||||
toJSON(): any;
|
||||
}
|
||||
|
||||
@@ -8918,9 +8918,9 @@ declare var ProgressEvent: {
|
||||
}
|
||||
|
||||
interface PushManager {
|
||||
getSubscription(): PromiseLike<PushSubscription>;
|
||||
permissionState(options?: PushSubscriptionOptionsInit): PromiseLike<string>;
|
||||
subscribe(options?: PushSubscriptionOptionsInit): PromiseLike<PushSubscription>;
|
||||
getSubscription(): Promise<PushSubscription>;
|
||||
permissionState(options?: PushSubscriptionOptionsInit): Promise<string>;
|
||||
subscribe(options?: PushSubscriptionOptionsInit): Promise<PushSubscription>;
|
||||
}
|
||||
|
||||
declare var PushManager: {
|
||||
@@ -8933,7 +8933,7 @@ interface PushSubscription {
|
||||
readonly options: PushSubscriptionOptions;
|
||||
getKey(name: string): ArrayBuffer | null;
|
||||
toJSON(): any;
|
||||
unsubscribe(): PromiseLike<boolean>;
|
||||
unsubscribe(): Promise<boolean>;
|
||||
}
|
||||
|
||||
declare var PushSubscription: {
|
||||
@@ -9127,19 +9127,19 @@ interface RTCPeerConnection extends EventTarget {
|
||||
onsignalingstatechange: (this: RTCPeerConnection, ev: Event) => any;
|
||||
readonly remoteDescription: RTCSessionDescription | null;
|
||||
readonly signalingState: string;
|
||||
addIceCandidate(candidate: RTCIceCandidate, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): PromiseLike<void>;
|
||||
addIceCandidate(candidate: RTCIceCandidate, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): Promise<void>;
|
||||
addStream(stream: MediaStream): void;
|
||||
close(): void;
|
||||
createAnswer(successCallback?: RTCSessionDescriptionCallback, failureCallback?: RTCPeerConnectionErrorCallback): PromiseLike<RTCSessionDescription>;
|
||||
createOffer(successCallback?: RTCSessionDescriptionCallback, failureCallback?: RTCPeerConnectionErrorCallback, options?: RTCOfferOptions): PromiseLike<RTCSessionDescription>;
|
||||
createAnswer(successCallback?: RTCSessionDescriptionCallback, failureCallback?: RTCPeerConnectionErrorCallback): Promise<RTCSessionDescription>;
|
||||
createOffer(successCallback?: RTCSessionDescriptionCallback, failureCallback?: RTCPeerConnectionErrorCallback, options?: RTCOfferOptions): Promise<RTCSessionDescription>;
|
||||
getConfiguration(): RTCConfiguration;
|
||||
getLocalStreams(): MediaStream[];
|
||||
getRemoteStreams(): MediaStream[];
|
||||
getStats(selector: MediaStreamTrack | null, successCallback?: RTCStatsCallback, failureCallback?: RTCPeerConnectionErrorCallback): PromiseLike<RTCStatsReport>;
|
||||
getStats(selector: MediaStreamTrack | null, successCallback?: RTCStatsCallback, failureCallback?: RTCPeerConnectionErrorCallback): Promise<RTCStatsReport>;
|
||||
getStreamById(streamId: string): MediaStream | null;
|
||||
removeStream(stream: MediaStream): void;
|
||||
setLocalDescription(description: RTCSessionDescription, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): PromiseLike<void>;
|
||||
setRemoteDescription(description: RTCSessionDescription, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): PromiseLike<void>;
|
||||
setLocalDescription(description: RTCSessionDescription, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): Promise<void>;
|
||||
setRemoteDescription(description: RTCSessionDescription, successCallback?: VoidFunction, failureCallback?: RTCPeerConnectionErrorCallback): Promise<void>;
|
||||
addEventListener<K extends keyof RTCPeerConnectionEventMap>(type: K, listener: (this: RTCPeerConnection, ev: RTCPeerConnectionEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
@@ -9245,8 +9245,8 @@ declare var RTCSsrcConflictEvent: {
|
||||
}
|
||||
|
||||
interface RTCStatsProvider extends EventTarget {
|
||||
getStats(): PromiseLike<RTCStatsReport>;
|
||||
msGetStats(): PromiseLike<RTCStatsReport>;
|
||||
getStats(): Promise<RTCStatsReport>;
|
||||
msGetStats(): Promise<RTCStatsReport>;
|
||||
}
|
||||
|
||||
declare var RTCStatsProvider: {
|
||||
@@ -9300,7 +9300,7 @@ declare var Range: {
|
||||
|
||||
interface ReadableStream {
|
||||
readonly locked: boolean;
|
||||
cancel(): PromiseLike<void>;
|
||||
cancel(): Promise<void>;
|
||||
getReader(): ReadableStreamReader;
|
||||
}
|
||||
|
||||
@@ -9310,8 +9310,8 @@ declare var ReadableStream: {
|
||||
}
|
||||
|
||||
interface ReadableStreamReader {
|
||||
cancel(): PromiseLike<void>;
|
||||
read(): PromiseLike<any>;
|
||||
cancel(): Promise<void>;
|
||||
read(): Promise<any>;
|
||||
releaseLock(): void;
|
||||
}
|
||||
|
||||
@@ -11285,10 +11285,10 @@ interface ServiceWorkerContainer extends EventTarget {
|
||||
readonly controller: ServiceWorker | null;
|
||||
oncontrollerchange: (this: ServiceWorkerContainer, ev: Event) => any;
|
||||
onmessage: (this: ServiceWorkerContainer, ev: ServiceWorkerMessageEvent) => any;
|
||||
readonly ready: PromiseLike<ServiceWorkerRegistration>;
|
||||
getRegistration(clientURL?: USVString): PromiseLike<any>;
|
||||
readonly ready: Promise<ServiceWorkerRegistration>;
|
||||
getRegistration(clientURL?: USVString): Promise<any>;
|
||||
getRegistrations(): any;
|
||||
register(scriptURL: USVString, options?: RegistrationOptions): PromiseLike<ServiceWorkerRegistration>;
|
||||
register(scriptURL: USVString, options?: RegistrationOptions): Promise<ServiceWorkerRegistration>;
|
||||
addEventListener<K extends keyof ServiceWorkerContainerEventMap>(type: K, listener: (this: ServiceWorkerContainer, ev: ServiceWorkerContainerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
@@ -11324,9 +11324,9 @@ interface ServiceWorkerRegistration extends EventTarget {
|
||||
readonly sync: SyncManager;
|
||||
readonly waiting: ServiceWorker | null;
|
||||
getNotifications(filter?: GetNotificationOptions): any;
|
||||
showNotification(title: string, options?: NotificationOptions): PromiseLike<void>;
|
||||
unregister(): PromiseLike<boolean>;
|
||||
update(): PromiseLike<void>;
|
||||
showNotification(title: string, options?: NotificationOptions): Promise<void>;
|
||||
unregister(): Promise<boolean>;
|
||||
update(): Promise<void>;
|
||||
addEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
@@ -11561,7 +11561,7 @@ declare var SubtleCrypto: {
|
||||
|
||||
interface SyncManager {
|
||||
getTags(): any;
|
||||
register(tag: string): PromiseLike<void>;
|
||||
register(tag: string): Promise<void>;
|
||||
}
|
||||
|
||||
declare var SyncManager: {
|
||||
@@ -11975,8 +11975,8 @@ declare var WaveShaperNode: {
|
||||
}
|
||||
|
||||
interface WebAuthentication {
|
||||
getAssertion(assertionChallenge: any, options?: AssertionOptions): PromiseLike<WebAuthnAssertion>;
|
||||
makeCredential(accountInformation: Account, cryptoParameters: ScopedCredentialParameters[], attestationChallenge: any, options?: ScopedCredentialOptions): PromiseLike<ScopedCredentialInfo>;
|
||||
getAssertion(assertionChallenge: any, options?: AssertionOptions): Promise<WebAuthnAssertion>;
|
||||
makeCredential(accountInformation: Account, cryptoParameters: ScopedCredentialParameters[], attestationChallenge: any, options?: ScopedCredentialOptions): Promise<ScopedCredentialInfo>;
|
||||
}
|
||||
|
||||
declare var WebAuthentication: {
|
||||
@@ -13469,10 +13469,10 @@ interface AbstractWorker {
|
||||
|
||||
interface Body {
|
||||
readonly bodyUsed: boolean;
|
||||
arrayBuffer(): PromiseLike<ArrayBuffer>;
|
||||
blob(): PromiseLike<Blob>;
|
||||
json(): PromiseLike<any>;
|
||||
text(): PromiseLike<string>;
|
||||
arrayBuffer(): Promise<ArrayBuffer>;
|
||||
blob(): Promise<Blob>;
|
||||
json(): Promise<any>;
|
||||
text(): Promise<string>;
|
||||
}
|
||||
|
||||
interface CanvasPathMethods {
|
||||
@@ -13613,7 +13613,7 @@ interface GlobalEventHandlers {
|
||||
}
|
||||
|
||||
interface GlobalFetch {
|
||||
fetch(input: RequestInfo, init?: RequestInit): PromiseLike<Response>;
|
||||
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
}
|
||||
|
||||
interface HTMLTableAlignment {
|
||||
@@ -14870,7 +14870,7 @@ declare var onwheel: (this: Window, ev: WheelEvent) => any;
|
||||
declare var indexedDB: IDBFactory;
|
||||
declare function atob(encodedString: string): string;
|
||||
declare function btoa(rawString: string): string;
|
||||
declare function fetch(input: RequestInfo, init?: RequestInit): PromiseLike<Response>;
|
||||
declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
declare function addEventListener<K extends keyof WindowEventMap>(type: K, listener: (this: Window, ev: WindowEventMap[K]) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
type AAGUID = string;
|
||||
|
||||
Vendored
+47
-47
@@ -1,8 +1,8 @@
|
||||
/// <reference path="lib.es2015.symbol.d.ts" />
|
||||
|
||||
interface SymbolConstructor {
|
||||
/**
|
||||
* A method that returns the default iterator for an object. Called by the semantics of the
|
||||
/**
|
||||
* A method that returns the default iterator for an object. Called by the semantics of the
|
||||
* for-of statement.
|
||||
*/
|
||||
readonly iterator: symbol;
|
||||
@@ -31,17 +31,17 @@ interface Array<T> {
|
||||
/** Iterator */
|
||||
[Symbol.iterator](): IterableIterator<T>;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, T]>;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<T>;
|
||||
@@ -55,7 +55,7 @@ interface ArrayConstructor {
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from<T, U>(iterable: Iterable<T>, mapfn: (v: T, k: number) => U, thisArg?: any): Array<U>;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an array from an iterable object.
|
||||
* @param iterable An iterable object to convert to an array.
|
||||
@@ -67,17 +67,17 @@ interface ReadonlyArray<T> {
|
||||
/** Iterator */
|
||||
[Symbol.iterator](): IterableIterator<T>;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, T]>;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<T>;
|
||||
@@ -126,15 +126,15 @@ interface Promise<T> { }
|
||||
|
||||
interface PromiseConstructor {
|
||||
/**
|
||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises
|
||||
* Creates a Promise that is resolved with an array of results when all of the provided Promises
|
||||
* resolve, or rejected when any Promise is rejected.
|
||||
* @param values An array of Promises.
|
||||
* @returns A new Promise.
|
||||
*/
|
||||
all<TAll>(values: Iterable<TAll | PromiseLike<TAll>>): Promise<TAll[]>;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
|
||||
* Creates a Promise that is resolved or rejected when any of the provided Promises are resolved
|
||||
* or rejected.
|
||||
* @param values An array of Promises.
|
||||
* @returns A new Promise.
|
||||
@@ -152,20 +152,20 @@ interface String {
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested
|
||||
* A typed array of 8-bit integer values. The contents are initialized to 0. If the requested
|
||||
* number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Int8Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, number]>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<number>;
|
||||
@@ -184,20 +184,20 @@ interface Int8ArrayConstructor {
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* A typed array of 8-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint8Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, number]>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<number>;
|
||||
@@ -216,22 +216,22 @@ interface Uint8ArrayConstructor {
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.
|
||||
* A typed array of 8-bit unsigned integer (clamped) values. The contents are initialized to 0.
|
||||
* If the requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint8ClampedArray {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, number]>;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<number>;
|
||||
@@ -251,22 +251,22 @@ interface Uint8ClampedArrayConstructor {
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 16-bit signed integer values. The contents are initialized to 0. If the
|
||||
* A typed array of 16-bit signed integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Int16Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, number]>;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<number>;
|
||||
@@ -285,20 +285,20 @@ interface Int16ArrayConstructor {
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* A typed array of 16-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint16Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, number]>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<number>;
|
||||
@@ -317,20 +317,20 @@ interface Uint16ArrayConstructor {
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 32-bit signed integer values. The contents are initialized to 0. If the
|
||||
* A typed array of 32-bit signed integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Int32Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, number]>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<number>;
|
||||
@@ -349,20 +349,20 @@ interface Int32ArrayConstructor {
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* A typed array of 32-bit unsigned integer values. The contents are initialized to 0. If the
|
||||
* requested number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Uint32Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, number]>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<number>;
|
||||
@@ -386,15 +386,15 @@ interface Uint32ArrayConstructor {
|
||||
*/
|
||||
interface Float32Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, number]>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<number>;
|
||||
@@ -413,20 +413,20 @@ interface Float32ArrayConstructor {
|
||||
}
|
||||
|
||||
/**
|
||||
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested
|
||||
* A typed array of 64-bit float values. The contents are initialized to 0. If the requested
|
||||
* number of bytes could not be allocated an exception is raised.
|
||||
*/
|
||||
interface Float64Array {
|
||||
[Symbol.iterator](): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an array of key, value pairs for every entry in the array
|
||||
*/
|
||||
entries(): IterableIterator<[number, number]>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of keys in the array
|
||||
*/
|
||||
keys(): IterableIterator<number>;
|
||||
/**
|
||||
/**
|
||||
* Returns an list of values in the array
|
||||
*/
|
||||
values(): IterableIterator<number>;
|
||||
|
||||
Vendored
-51
@@ -1,54 +1,3 @@
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
interface Promise<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then(onfulfilled?: ((value: T) => T | PromiseLike<T>) | undefined | null, onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: ((value: T) => T | PromiseLike<T>) | undefined | null, onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: (value: T) => TResult | PromiseLike<TResult>, onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult1, TResult2>(onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): Promise<TResult1 | TResult2>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch(onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): Promise<T>;
|
||||
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch<TResult>(onrejected: (reason: any) => TResult | PromiseLike<TResult>): Promise<T | TResult>;
|
||||
}
|
||||
|
||||
interface PromiseConstructor {
|
||||
/**
|
||||
* A reference to the prototype.
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
/// <reference path="lib.es2016.d.ts" />
|
||||
/// <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.string.d.ts" />
|
||||
Vendored
+15
-33
@@ -137,16 +137,10 @@ interface ObjectConstructor {
|
||||
getOwnPropertyNames(o: any): string[];
|
||||
|
||||
/**
|
||||
* Creates an object that has null prototype.
|
||||
* @param o Object to use as a prototype. May be null
|
||||
* Creates an object that has the specified prototype or that has null prototype.
|
||||
* @param o Object to use as a prototype. May be null.
|
||||
*/
|
||||
create(o: null): any;
|
||||
|
||||
/**
|
||||
* Creates an object that has the specified prototype, and that optionally contains specified properties.
|
||||
* @param o Object to use as a prototype. May be null
|
||||
*/
|
||||
create<T extends object>(o: T): T;
|
||||
create(o: object | null): any;
|
||||
|
||||
/**
|
||||
* Creates an object that has the specified prototype, and that optionally contains specified properties.
|
||||
@@ -341,14 +335,14 @@ interface String {
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using a regular expression or search string.
|
||||
* @param searchValue A string that represents the regular expression.
|
||||
* @param searchValue A string to search for.
|
||||
* @param replaceValue A string containing the text to replace for every successful match of searchValue in this string.
|
||||
*/
|
||||
replace(searchValue: string, replaceValue: string): string;
|
||||
|
||||
/**
|
||||
* Replaces text in a string, using a regular expression or search string.
|
||||
* @param searchValue A string that represents the regular expression.
|
||||
* @param searchValue A string to search for.
|
||||
* @param replacer A function that returns the replacement text.
|
||||
*/
|
||||
replace(searchValue: string, replacer: (substring: string, ...args: any[]) => string): string;
|
||||
@@ -1316,39 +1310,27 @@ interface PromiseLike<T> {
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then(
|
||||
onfulfilled?: ((value: T) => T | PromiseLike<T>) | undefined | null,
|
||||
onrejected?: ((reason: any) => T | PromiseLike<T>) | undefined | null): PromiseLike<T>;
|
||||
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
interface Promise<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(
|
||||
onfulfilled: ((value: T) => T | PromiseLike<T>) | undefined | null,
|
||||
onrejected: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<T | TResult>;
|
||||
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
then<TResult>(
|
||||
onfulfilled: (value: T) => TResult | PromiseLike<TResult>,
|
||||
onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): PromiseLike<TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult1, TResult2>(
|
||||
onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>,
|
||||
onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
|
||||
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
|
||||
}
|
||||
|
||||
interface ArrayLike<T> {
|
||||
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
/// <reference path="lib.es2015.symbol.d.ts" />
|
||||
/// <reference path="lib.es2015.iterable.d.ts" />
|
||||
|
||||
interface SymbolConstructor {
|
||||
/**
|
||||
* A method that returns the default async iterator for an object. Called by the semantics of
|
||||
* the for-await-of statement.
|
||||
*/
|
||||
readonly asyncIterator: symbol;
|
||||
}
|
||||
|
||||
interface AsyncIterator<T> {
|
||||
next(value?: any): Promise<IteratorResult<T>>;
|
||||
return?(value?: any): Promise<IteratorResult<T>>;
|
||||
throw?(e?: any): Promise<IteratorResult<T>>;
|
||||
}
|
||||
|
||||
interface AsyncIterable<T> {
|
||||
[Symbol.asyncIterator](): AsyncIterator<T>;
|
||||
}
|
||||
|
||||
interface AsyncIterableIterator<T> extends AsyncIterator<T> {
|
||||
[Symbol.asyncIterator](): AsyncIterableIterator<T>;
|
||||
}
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
/// <reference path="lib.es2017.d.ts" />
|
||||
/// <reference path="lib.esnext.asynciterable.d.ts" />
|
||||
Vendored
+35
-35
@@ -168,13 +168,13 @@ declare var Blob: {
|
||||
}
|
||||
|
||||
interface Cache {
|
||||
add(request: RequestInfo): PromiseLike<void>;
|
||||
addAll(requests: RequestInfo[]): PromiseLike<void>;
|
||||
delete(request: RequestInfo, options?: CacheQueryOptions): PromiseLike<boolean>;
|
||||
add(request: RequestInfo): Promise<void>;
|
||||
addAll(requests: RequestInfo[]): Promise<void>;
|
||||
delete(request: RequestInfo, options?: CacheQueryOptions): Promise<boolean>;
|
||||
keys(request?: RequestInfo, options?: CacheQueryOptions): any;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): PromiseLike<Response>;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): Promise<Response>;
|
||||
matchAll(request?: RequestInfo, options?: CacheQueryOptions): any;
|
||||
put(request: RequestInfo, response: Response): PromiseLike<void>;
|
||||
put(request: RequestInfo, response: Response): Promise<void>;
|
||||
}
|
||||
|
||||
declare var Cache: {
|
||||
@@ -183,11 +183,11 @@ declare var Cache: {
|
||||
}
|
||||
|
||||
interface CacheStorage {
|
||||
delete(cacheName: string): PromiseLike<boolean>;
|
||||
has(cacheName: string): PromiseLike<boolean>;
|
||||
delete(cacheName: string): Promise<boolean>;
|
||||
has(cacheName: string): Promise<boolean>;
|
||||
keys(): any;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): PromiseLike<any>;
|
||||
open(cacheName: string): PromiseLike<Cache>;
|
||||
match(request: RequestInfo, options?: CacheQueryOptions): Promise<any>;
|
||||
open(cacheName: string): Promise<Cache>;
|
||||
}
|
||||
|
||||
declare var CacheStorage: {
|
||||
@@ -746,7 +746,7 @@ interface Notification extends EventTarget {
|
||||
declare var Notification: {
|
||||
prototype: Notification;
|
||||
new(title: string, options?: NotificationOptions): Notification;
|
||||
requestPermission(callback?: NotificationPermissionCallback): PromiseLike<string>;
|
||||
requestPermission(callback?: NotificationPermissionCallback): Promise<string>;
|
||||
}
|
||||
|
||||
interface Performance {
|
||||
@@ -862,9 +862,9 @@ declare var ProgressEvent: {
|
||||
}
|
||||
|
||||
interface PushManager {
|
||||
getSubscription(): PromiseLike<PushSubscription>;
|
||||
permissionState(options?: PushSubscriptionOptionsInit): PromiseLike<string>;
|
||||
subscribe(options?: PushSubscriptionOptionsInit): PromiseLike<PushSubscription>;
|
||||
getSubscription(): Promise<PushSubscription>;
|
||||
permissionState(options?: PushSubscriptionOptionsInit): Promise<string>;
|
||||
subscribe(options?: PushSubscriptionOptionsInit): Promise<PushSubscription>;
|
||||
}
|
||||
|
||||
declare var PushManager: {
|
||||
@@ -877,7 +877,7 @@ interface PushSubscription {
|
||||
readonly options: PushSubscriptionOptions;
|
||||
getKey(name: string): ArrayBuffer | null;
|
||||
toJSON(): any;
|
||||
unsubscribe(): PromiseLike<boolean>;
|
||||
unsubscribe(): Promise<boolean>;
|
||||
}
|
||||
|
||||
declare var PushSubscription: {
|
||||
@@ -897,7 +897,7 @@ declare var PushSubscriptionOptions: {
|
||||
|
||||
interface ReadableStream {
|
||||
readonly locked: boolean;
|
||||
cancel(): PromiseLike<void>;
|
||||
cancel(): Promise<void>;
|
||||
getReader(): ReadableStreamReader;
|
||||
}
|
||||
|
||||
@@ -907,8 +907,8 @@ declare var ReadableStream: {
|
||||
}
|
||||
|
||||
interface ReadableStreamReader {
|
||||
cancel(): PromiseLike<void>;
|
||||
read(): PromiseLike<any>;
|
||||
cancel(): Promise<void>;
|
||||
read(): Promise<any>;
|
||||
releaseLock(): void;
|
||||
}
|
||||
|
||||
@@ -986,9 +986,9 @@ interface ServiceWorkerRegistration extends EventTarget {
|
||||
readonly sync: SyncManager;
|
||||
readonly waiting: ServiceWorker | null;
|
||||
getNotifications(filter?: GetNotificationOptions): any;
|
||||
showNotification(title: string, options?: NotificationOptions): PromiseLike<void>;
|
||||
unregister(): PromiseLike<boolean>;
|
||||
update(): PromiseLike<void>;
|
||||
showNotification(title: string, options?: NotificationOptions): Promise<void>;
|
||||
unregister(): Promise<boolean>;
|
||||
update(): Promise<void>;
|
||||
addEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
@@ -1000,7 +1000,7 @@ declare var ServiceWorkerRegistration: {
|
||||
|
||||
interface SyncManager {
|
||||
getTags(): any;
|
||||
register(tag: string): PromiseLike<void>;
|
||||
register(tag: string): Promise<void>;
|
||||
}
|
||||
|
||||
declare var SyncManager: {
|
||||
@@ -1130,14 +1130,14 @@ interface AbstractWorker {
|
||||
|
||||
interface Body {
|
||||
readonly bodyUsed: boolean;
|
||||
arrayBuffer(): PromiseLike<ArrayBuffer>;
|
||||
blob(): PromiseLike<Blob>;
|
||||
json(): PromiseLike<any>;
|
||||
text(): PromiseLike<string>;
|
||||
arrayBuffer(): Promise<ArrayBuffer>;
|
||||
blob(): Promise<Blob>;
|
||||
json(): Promise<any>;
|
||||
text(): Promise<string>;
|
||||
}
|
||||
|
||||
interface GlobalFetch {
|
||||
fetch(input: RequestInfo, init?: RequestInit): PromiseLike<Response>;
|
||||
fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
}
|
||||
|
||||
interface MSBaseReaderEventMap {
|
||||
@@ -1234,10 +1234,10 @@ declare var Client: {
|
||||
}
|
||||
|
||||
interface Clients {
|
||||
claim(): PromiseLike<void>;
|
||||
get(id: string): PromiseLike<any>;
|
||||
claim(): Promise<void>;
|
||||
get(id: string): Promise<any>;
|
||||
matchAll(options?: ClientQueryOptions): any;
|
||||
openWindow(url: USVString): PromiseLike<WindowClient>;
|
||||
openWindow(url: USVString): Promise<WindowClient>;
|
||||
}
|
||||
|
||||
declare var Clients: {
|
||||
@@ -1263,7 +1263,7 @@ declare var DedicatedWorkerGlobalScope: {
|
||||
}
|
||||
|
||||
interface ExtendableEvent extends Event {
|
||||
waitUntil(f: PromiseLike<any>): void;
|
||||
waitUntil(f: Promise<any>): void;
|
||||
}
|
||||
|
||||
declare var ExtendableEvent: {
|
||||
@@ -1288,7 +1288,7 @@ interface FetchEvent extends ExtendableEvent {
|
||||
readonly clientId: string | null;
|
||||
readonly isReload: boolean;
|
||||
readonly request: Request;
|
||||
respondWith(r: PromiseLike<Response>): void;
|
||||
respondWith(r: Promise<Response>): void;
|
||||
}
|
||||
|
||||
declare var FetchEvent: {
|
||||
@@ -1363,7 +1363,7 @@ interface ServiceWorkerGlobalScope extends WorkerGlobalScope {
|
||||
onpushsubscriptionchange: (this: ServiceWorkerGlobalScope, ev: ExtendableEvent) => any;
|
||||
onsync: (this: ServiceWorkerGlobalScope, ev: SyncEvent) => any;
|
||||
readonly registration: ServiceWorkerRegistration;
|
||||
skipWaiting(): PromiseLike<void>;
|
||||
skipWaiting(): Promise<void>;
|
||||
addEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
@@ -1386,8 +1386,8 @@ declare var SyncEvent: {
|
||||
interface WindowClient extends Client {
|
||||
readonly focused: boolean;
|
||||
readonly visibilityState: string;
|
||||
focus(): PromiseLike<WindowClient>;
|
||||
navigate(url: USVString): PromiseLike<WindowClient>;
|
||||
focus(): Promise<WindowClient>;
|
||||
navigate(url: USVString): Promise<WindowClient>;
|
||||
}
|
||||
|
||||
declare var WindowClient: {
|
||||
@@ -1715,7 +1715,7 @@ declare function setTimeout(handler: any, timeout?: any, ...args: any[]): number
|
||||
declare function atob(encodedString: string): string;
|
||||
declare function btoa(rawString: string): string;
|
||||
declare var console: Console;
|
||||
declare function fetch(input: RequestInfo, init?: RequestInit): PromiseLike<Response>;
|
||||
declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
declare function dispatchEvent(evt: Event): boolean;
|
||||
declare function removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
declare function addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
|
||||
// TODO: extract services types
|
||||
interface HostCancellationToken {
|
||||
isCancellationRequested(): boolean;
|
||||
}
|
||||
/// <reference types="node"/>
|
||||
|
||||
import fs = require("fs");
|
||||
|
||||
function createCancellationToken(args: string[]): HostCancellationToken {
|
||||
interface ServerCancellationToken {
|
||||
isCancellationRequested(): boolean;
|
||||
setRequest(requestId: number): void;
|
||||
resetRequest(requestId: number): void;
|
||||
}
|
||||
|
||||
function pipeExists(name: string): boolean {
|
||||
try {
|
||||
fs.statSync(name);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function createCancellationToken(args: string[]): ServerCancellationToken {
|
||||
let cancellationPipeName: string;
|
||||
for (let i = 0; i < args.length - 1; i++) {
|
||||
if (args[i] === "--cancellationPipeName") {
|
||||
@@ -17,18 +27,44 @@ function createCancellationToken(args: string[]): HostCancellationToken {
|
||||
}
|
||||
}
|
||||
if (!cancellationPipeName) {
|
||||
return { isCancellationRequested: () => false };
|
||||
return {
|
||||
isCancellationRequested: () => false,
|
||||
setRequest: (_requestId: number): void => void 0,
|
||||
resetRequest: (_requestId: number): void => void 0
|
||||
};
|
||||
}
|
||||
return {
|
||||
isCancellationRequested() {
|
||||
try {
|
||||
fs.statSync(cancellationPipeName);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
// cancellationPipeName is a string without '*' inside that can optionally end with '*'
|
||||
// when client wants to signal cancellation it should create a named pipe with name=<cancellationPipeName>
|
||||
// server will synchronously check the presence of the pipe and treat its existance as indicator that current request should be canceled.
|
||||
// in case if client prefers to use more fine-grained schema than one name for all request it can add '*' to the end of cancelellationPipeName.
|
||||
// in this case pipe name will be build dynamically as <cancellationPipeName><request_seq>.
|
||||
if (cancellationPipeName.charAt(cancellationPipeName.length - 1) === "*") {
|
||||
const namePrefix = cancellationPipeName.slice(0, -1);
|
||||
if (namePrefix.length === 0 || namePrefix.indexOf("*") >= 0) {
|
||||
throw new Error("Invalid name for template cancellation pipe: it should have length greater than 2 characters and contain only one '*'.");
|
||||
}
|
||||
};
|
||||
let perRequestPipeName: string;
|
||||
let currentRequestId: number;
|
||||
return {
|
||||
isCancellationRequested: () => perRequestPipeName !== undefined && pipeExists(perRequestPipeName),
|
||||
setRequest(requestId: number) {
|
||||
currentRequestId = currentRequestId;
|
||||
perRequestPipeName = namePrefix + requestId;
|
||||
},
|
||||
resetRequest(requestId: number) {
|
||||
if (currentRequestId !== requestId) {
|
||||
throw new Error(`Mismatched request id, expected ${currentRequestId}, actual ${requestId}`);
|
||||
}
|
||||
perRequestPipeName = undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return {
|
||||
isCancellationRequested: () => pipeExists(cancellationPipeName),
|
||||
setRequest: (_requestId: number): void => void 0,
|
||||
resetRequest: (_requestId: number): void => void 0
|
||||
};
|
||||
}
|
||||
}
|
||||
export = createCancellationToken;
|
||||
+20
-19
@@ -13,6 +13,25 @@ namespace ts.server {
|
||||
findInComments: boolean;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function extractMessage(message: string) {
|
||||
// Read the content length
|
||||
const contentLengthPrefix = "Content-Length: ";
|
||||
const lines = message.split(/\r?\n/);
|
||||
Debug.assert(lines.length >= 2, "Malformed response: Expected 3 lines in the response.");
|
||||
|
||||
const contentLengthText = lines[0];
|
||||
Debug.assert(contentLengthText.indexOf(contentLengthPrefix) === 0, "Malformed response: Response text did not contain content-length header.");
|
||||
const contentLength = parseInt(contentLengthText.substring(contentLengthPrefix.length));
|
||||
|
||||
// Read the body
|
||||
const responseBody = lines[2];
|
||||
|
||||
// Verify content length
|
||||
Debug.assert(responseBody.length + 1 === contentLength, "Malformed response: Content length did not match the response's body length.");
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
export class SessionClient implements LanguageService {
|
||||
private sequence: number = 0;
|
||||
private lineMaps: ts.Map<number[]> = ts.createMap<number[]>();
|
||||
@@ -84,7 +103,7 @@ namespace ts.server {
|
||||
while (!foundResponseMessage) {
|
||||
lastMessage = this.messages.shift();
|
||||
Debug.assert(!!lastMessage, "Did not receive any responses.");
|
||||
const responseBody = processMessage(lastMessage);
|
||||
const responseBody = extractMessage(lastMessage);
|
||||
try {
|
||||
response = JSON.parse(responseBody);
|
||||
// the server may emit events before emitting the response. We
|
||||
@@ -109,24 +128,6 @@ namespace ts.server {
|
||||
Debug.assert(!!response.body, "Malformed response: Unexpected empty response body.");
|
||||
|
||||
return response;
|
||||
|
||||
function processMessage(message: string) {
|
||||
// Read the content length
|
||||
const contentLengthPrefix = "Content-Length: ";
|
||||
const lines = message.split("\r\n");
|
||||
Debug.assert(lines.length >= 2, "Malformed response: Expected 3 lines in the response.");
|
||||
|
||||
const contentLengthText = lines[0];
|
||||
Debug.assert(contentLengthText.indexOf(contentLengthPrefix) === 0, "Malformed response: Response text did not contain content-length header.");
|
||||
const contentLength = parseInt(contentLengthText.substring(contentLengthPrefix.length));
|
||||
|
||||
// Read the body
|
||||
const responseBody = lines[2];
|
||||
|
||||
// Verify content length
|
||||
Debug.assert(responseBody.length + 1 === contentLength, "Malformed response: Content length did not match the response's body length.");
|
||||
return responseBody;
|
||||
}
|
||||
}
|
||||
|
||||
openFile(fileName: string, content?: string, scriptKindName?: "TS" | "JS" | "TSX" | "JSX"): void {
|
||||
|
||||
@@ -948,9 +948,9 @@ namespace ts.server {
|
||||
|
||||
private openConfigFile(configFileName: NormalizedPath, clientFileName?: string): OpenConfigFileResult {
|
||||
const conversionResult = this.convertConfigFileContentToProjectOptions(configFileName);
|
||||
const projectOptions = conversionResult.success
|
||||
const projectOptions: ProjectOptions = conversionResult.success
|
||||
? conversionResult.projectOptions
|
||||
: { files: [], compilerOptions: {} };
|
||||
: { files: [], compilerOptions: {}, typeAcquisition: { enable: false } };
|
||||
const project = this.createAndAddConfiguredProject(configFileName, projectOptions, conversionResult.configFileErrors, clientFileName);
|
||||
return {
|
||||
success: conversionResult.success,
|
||||
|
||||
+108
-5
@@ -91,19 +91,38 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
export interface PluginCreateInfo {
|
||||
project: Project;
|
||||
languageService: LanguageService;
|
||||
languageServiceHost: LanguageServiceHost;
|
||||
serverHost: ServerHost;
|
||||
config: any;
|
||||
}
|
||||
|
||||
export interface PluginModule {
|
||||
create(createInfo: PluginCreateInfo): LanguageService;
|
||||
getExternalFiles?(proj: Project): string[];
|
||||
}
|
||||
|
||||
export interface PluginModuleFactory {
|
||||
(mod: { typescript: typeof ts }): PluginModule;
|
||||
}
|
||||
|
||||
export abstract class Project {
|
||||
private rootFiles: ScriptInfo[] = [];
|
||||
private rootFilesMap: FileMap<ScriptInfo> = createFileMap<ScriptInfo>();
|
||||
private lsHost: LSHost;
|
||||
private program: ts.Program;
|
||||
|
||||
private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap();
|
||||
private lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
|
||||
|
||||
private readonly languageService: LanguageService;
|
||||
// wrapper over the real language service that will suppress all semantic operations
|
||||
protected languageService: LanguageService;
|
||||
|
||||
public languageServiceEnabled = true;
|
||||
|
||||
protected readonly lsHost: LSHost;
|
||||
|
||||
builder: Builder;
|
||||
/**
|
||||
* Set of files names that were updated since the last call to getChangesSinceVersion.
|
||||
@@ -150,6 +169,17 @@ namespace ts.server {
|
||||
return this.cachedUnresolvedImportsPerFile;
|
||||
}
|
||||
|
||||
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} {
|
||||
const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules")));
|
||||
log(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`);
|
||||
const result = host.require(resolvedPath, moduleName);
|
||||
if (result.error) {
|
||||
log(`Failed to load module: ${JSON.stringify(result.error)}`);
|
||||
return undefined;
|
||||
}
|
||||
return result.module;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly projectName: string,
|
||||
readonly projectKind: ProjectKind,
|
||||
@@ -165,8 +195,8 @@ namespace ts.server {
|
||||
this.compilerOptions.allowNonTsExtensions = true;
|
||||
this.compilerOptions.allowJs = true;
|
||||
}
|
||||
else if (hasExplicitListOfFiles) {
|
||||
// If files are listed explicitly, allow all extensions
|
||||
else if (hasExplicitListOfFiles || this.compilerOptions.allowJs) {
|
||||
// If files are listed explicitly or allowJs is specified, allow all extensions
|
||||
this.compilerOptions.allowNonTsExtensions = true;
|
||||
}
|
||||
|
||||
@@ -237,6 +267,10 @@ namespace ts.server {
|
||||
abstract getProjectRootPath(): string | undefined;
|
||||
abstract getTypeAcquisition(): TypeAcquisition;
|
||||
|
||||
getExternalFiles(): string[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
getSourceFile(path: Path) {
|
||||
if (!this.program) {
|
||||
return undefined;
|
||||
@@ -804,10 +838,12 @@ namespace ts.server {
|
||||
private typeRootsWatchers: FileWatcher[];
|
||||
readonly canonicalConfigFilePath: NormalizedPath;
|
||||
|
||||
private plugins: PluginModule[] = [];
|
||||
|
||||
/** Used for configured projects which may have multiple open roots */
|
||||
openRefCount = 0;
|
||||
|
||||
constructor(configFileName: NormalizedPath,
|
||||
constructor(private configFileName: NormalizedPath,
|
||||
projectService: ProjectService,
|
||||
documentRegistry: ts.DocumentRegistry,
|
||||
hasExplicitListOfFiles: boolean,
|
||||
@@ -817,12 +853,64 @@ namespace ts.server {
|
||||
public compileOnSaveEnabled: boolean) {
|
||||
super(configFileName, ProjectKind.Configured, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions, compileOnSaveEnabled);
|
||||
this.canonicalConfigFilePath = asNormalizedPath(projectService.toCanonicalFileName(configFileName));
|
||||
this.enablePlugins();
|
||||
}
|
||||
|
||||
getConfigFilePath() {
|
||||
return this.getProjectName();
|
||||
}
|
||||
|
||||
enablePlugins() {
|
||||
const host = this.projectService.host;
|
||||
const options = this.getCompilerOptions();
|
||||
const log = (message: string) => {
|
||||
this.projectService.logger.info(message);
|
||||
};
|
||||
|
||||
if (!(options.plugins && options.plugins.length)) {
|
||||
this.projectService.logger.info("No plugins exist");
|
||||
// No plugins
|
||||
return;
|
||||
}
|
||||
|
||||
if (!host.require) {
|
||||
this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded");
|
||||
return;
|
||||
}
|
||||
|
||||
for (const pluginConfigEntry of options.plugins) {
|
||||
const searchPath = getDirectoryPath(this.configFileName);
|
||||
const resolvedModule = <PluginModuleFactory>Project.resolveModule(pluginConfigEntry.name, searchPath, host, log);
|
||||
if (resolvedModule) {
|
||||
this.enableProxy(resolvedModule, pluginConfigEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport) {
|
||||
try {
|
||||
if (typeof pluginModuleFactory !== "function") {
|
||||
this.projectService.logger.info(`Skipped loading plugin ${configEntry.name} because it did expose a proper factory function`);
|
||||
return;
|
||||
}
|
||||
|
||||
const info: PluginCreateInfo = {
|
||||
config: configEntry,
|
||||
project: this,
|
||||
languageService: this.languageService,
|
||||
languageServiceHost: this.lsHost,
|
||||
serverHost: this.projectService.host
|
||||
};
|
||||
|
||||
const pluginModule = pluginModuleFactory({ typescript: ts });
|
||||
this.languageService = pluginModule.create(info);
|
||||
this.plugins.push(pluginModule);
|
||||
}
|
||||
catch (e) {
|
||||
this.projectService.logger.info(`Plugin activation failed: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
getProjectRootPath() {
|
||||
return getDirectoryPath(this.getConfigFilePath());
|
||||
}
|
||||
@@ -839,6 +927,21 @@ namespace ts.server {
|
||||
return this.typeAcquisition;
|
||||
}
|
||||
|
||||
getExternalFiles(): string[] {
|
||||
const items: string[] = [];
|
||||
for (const plugin of this.plugins) {
|
||||
if (typeof plugin.getExternalFiles === "function") {
|
||||
try {
|
||||
items.push(...plugin.getExternalFiles(this));
|
||||
}
|
||||
catch (e) {
|
||||
this.projectService.logger.info(`A plugin threw an exception in getExternalFiles: ${e}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
watchConfigFile(callback: (project: ConfiguredProject) => void) {
|
||||
this.projectFileWatcher = this.projectService.host.watchFile(this.getConfigFilePath(), _ => callback(this));
|
||||
}
|
||||
|
||||
+17
-1
@@ -820,7 +820,7 @@ namespace ts.server.protocol {
|
||||
* Represents a file in external project.
|
||||
* External project is project whose set of files, compilation options and open\close state
|
||||
* is maintained by the client (i.e. if all this data come from .csproj file in Visual Studio).
|
||||
* External project will exist even if all files in it are closed and should be closed explicity.
|
||||
* External project will exist even if all files in it are closed and should be closed explicitly.
|
||||
* If external project includes one or more tsconfig.json/jsconfig.json files then tsserver will
|
||||
* create configured project for every config file but will maintain a link that these projects were created
|
||||
* as a result of opening external project so they should be removed once external project is closed.
|
||||
@@ -1766,6 +1766,20 @@ namespace ts.server.protocol {
|
||||
arguments: GeterrRequestArgs;
|
||||
}
|
||||
|
||||
export type RequestCompletedEventName = "requestCompleted";
|
||||
|
||||
/**
|
||||
* Event that is sent when server have finished processing request with specified id.
|
||||
*/
|
||||
export interface RequestCompletedEvent extends Event {
|
||||
event: RequestCompletedEventName;
|
||||
body: RequestCompletedEventBody;
|
||||
}
|
||||
|
||||
export interface RequestCompletedEventBody {
|
||||
request_seq: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Item of diagnostic information found in a DiagnosticEvent message.
|
||||
*/
|
||||
@@ -2204,6 +2218,7 @@ namespace ts.server.protocol {
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
insertSpaceBeforeFunctionParenthesis?: boolean;
|
||||
@@ -2253,6 +2268,7 @@ namespace ts.server.protocol {
|
||||
outDir?: string;
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
plugins?: PluginImport[];
|
||||
preserveConstEnums?: boolean;
|
||||
project?: string;
|
||||
reactNamespace?: string;
|
||||
|
||||
+94
-6
@@ -12,6 +12,7 @@ namespace ts.server {
|
||||
|
||||
const childProcess: {
|
||||
fork(modulePath: string, args: string[], options?: { execArgv: string[], env?: MapLike<string> }): NodeChildProcess;
|
||||
execFileSync(file: string, args: string[], options: { stdio: "ignore", env: MapLike<string> }): string | Buffer;
|
||||
} = require("child_process");
|
||||
|
||||
const os: {
|
||||
@@ -59,7 +60,7 @@ namespace ts.server {
|
||||
|
||||
interface NodeChildProcess {
|
||||
send(message: any, sendHandle?: any): void;
|
||||
on(message: "message", f: (m: any) => void): void;
|
||||
on(message: "message" | "exit", f: (m: any) => void): void;
|
||||
kill(): void;
|
||||
pid: number;
|
||||
}
|
||||
@@ -99,6 +100,8 @@ namespace ts.server {
|
||||
birthtime: Date;
|
||||
}
|
||||
|
||||
type RequireResult = { module: {}, error: undefined } | { module: undefined, error: {} };
|
||||
|
||||
const readline: {
|
||||
createInterface(options: ReadLineOptions): NodeJS.EventEmitter;
|
||||
} = require("readline");
|
||||
@@ -354,7 +357,7 @@ namespace ts.server {
|
||||
class IOSession extends Session {
|
||||
constructor(
|
||||
host: ServerHost,
|
||||
cancellationToken: HostCancellationToken,
|
||||
cancellationToken: ServerCancellationToken,
|
||||
installerEventPort: number,
|
||||
canUseEvents: boolean,
|
||||
useSingleInferredProject: boolean,
|
||||
@@ -574,7 +577,84 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
function extractWatchDirectoryCacheKey(path: string, currentDriveKey: string) {
|
||||
path = normalizeSlashes(path);
|
||||
if (isUNCPath(path)) {
|
||||
// UNC path: extract server name
|
||||
// //server/location
|
||||
// ^ <- from 0 to this position
|
||||
const firstSlash = path.indexOf(directorySeparator, 2);
|
||||
return firstSlash !== -1 ? path.substring(0, firstSlash).toLowerCase() : path;
|
||||
}
|
||||
const rootLength = getRootLength(path);
|
||||
if (rootLength === 0) {
|
||||
// relative path - assume file is on the current drive
|
||||
return currentDriveKey;
|
||||
}
|
||||
if (path.charCodeAt(1) === CharacterCodes.colon && path.charCodeAt(2) === CharacterCodes.slash) {
|
||||
// rooted path that starts with c:/... - extract drive letter
|
||||
return path.charAt(0).toLowerCase();
|
||||
}
|
||||
if (path.charCodeAt(0) === CharacterCodes.slash && path.charCodeAt(1) !== CharacterCodes.slash) {
|
||||
// rooted path that starts with slash - /somename - use key for current drive
|
||||
return currentDriveKey;
|
||||
}
|
||||
// do not cache any other cases
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isUNCPath(s: string): boolean {
|
||||
return s.length > 2 && s.charCodeAt(0) === CharacterCodes.slash && s.charCodeAt(1) === CharacterCodes.slash;
|
||||
}
|
||||
|
||||
const sys = <ServerHost>ts.sys;
|
||||
// use watchGuard process on Windows when node version is 4 or later
|
||||
const useWatchGuard = process.platform === "win32" && getNodeMajorVersion() >= 4;
|
||||
if (useWatchGuard) {
|
||||
const currentDrive = extractWatchDirectoryCacheKey(sys.resolvePath(sys.getCurrentDirectory()), /*currentDriveKey*/ undefined);
|
||||
const statusCache = createMap<boolean>();
|
||||
const originalWatchDirectory = sys.watchDirectory;
|
||||
sys.watchDirectory = function (path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher {
|
||||
const cacheKey = extractWatchDirectoryCacheKey(path, currentDrive);
|
||||
let status = cacheKey && statusCache.get(cacheKey);
|
||||
if (status === undefined) {
|
||||
if (logger.hasLevel(LogLevel.verbose)) {
|
||||
logger.info(`${cacheKey} for path ${path} not found in cache...`);
|
||||
}
|
||||
try {
|
||||
const args = [combinePaths(__dirname, "watchGuard.js"), path];
|
||||
if (logger.hasLevel(LogLevel.verbose)) {
|
||||
logger.info(`Starting ${process.execPath} with args ${JSON.stringify(args)}`);
|
||||
}
|
||||
childProcess.execFileSync(process.execPath, args, { stdio: "ignore", env: { "ELECTRON_RUN_AS_NODE": "1" } });
|
||||
status = true;
|
||||
if (logger.hasLevel(LogLevel.verbose)) {
|
||||
logger.info(`WatchGuard for path ${path} returned: OK`);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
status = false;
|
||||
if (logger.hasLevel(LogLevel.verbose)) {
|
||||
logger.info(`WatchGuard for path ${path} returned: ${e.message}`);
|
||||
}
|
||||
}
|
||||
if (cacheKey) {
|
||||
statusCache.set(cacheKey, status);
|
||||
}
|
||||
}
|
||||
else if (logger.hasLevel(LogLevel.verbose)) {
|
||||
logger.info(`watchDirectory for ${path} uses cached drive information.`);
|
||||
}
|
||||
if (status) {
|
||||
// this drive is safe to use - call real 'watchDirectory'
|
||||
return originalWatchDirectory.call(sys, path, callback, recursive);
|
||||
}
|
||||
else {
|
||||
// this drive is unsafe - return no-op watcher
|
||||
return { close() { } };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override sys.write because fs.writeSync is not reliable on Node 4
|
||||
sys.write = (s: string) => writeMessage(new Buffer(s, "utf8"));
|
||||
@@ -593,15 +673,23 @@ namespace ts.server {
|
||||
sys.gc = () => global.gc();
|
||||
}
|
||||
|
||||
let cancellationToken: HostCancellationToken;
|
||||
sys.require = (initialDir: string, moduleName: string): RequireResult => {
|
||||
const result = nodeModuleNameResolverWorker(moduleName, initialDir + "/program.ts", { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, sys, undefined, /*jsOnly*/ true);
|
||||
try {
|
||||
return { module: require(result.resolvedModule.resolvedFileName), error: undefined };
|
||||
}
|
||||
catch (e) {
|
||||
return { module: undefined, error: e };
|
||||
}
|
||||
};
|
||||
|
||||
let cancellationToken: ServerCancellationToken;
|
||||
try {
|
||||
const factory = require("./cancellationToken");
|
||||
cancellationToken = factory(sys.args);
|
||||
}
|
||||
catch (e) {
|
||||
cancellationToken = {
|
||||
isCancellationRequested: () => false
|
||||
};
|
||||
cancellationToken = nullCancellationToken;
|
||||
};
|
||||
|
||||
let eventPort: number;
|
||||
|
||||
+193
-33
@@ -8,6 +8,17 @@ namespace ts.server {
|
||||
stack?: string;
|
||||
}
|
||||
|
||||
export interface ServerCancellationToken extends HostCancellationToken {
|
||||
setRequest(requestId: number): void;
|
||||
resetRequest(requestId: number): void;
|
||||
}
|
||||
|
||||
export const nullCancellationToken: ServerCancellationToken = {
|
||||
isCancellationRequested: () => false,
|
||||
setRequest: () => void 0,
|
||||
resetRequest: () => void 0
|
||||
};
|
||||
|
||||
function hrTimeToMilliseconds(time: number[]): number {
|
||||
const seconds = time[0];
|
||||
const nanoseconds = time[1];
|
||||
@@ -193,18 +204,134 @@ namespace ts.server {
|
||||
return `Content-Length: ${1 + len}\r\n\r\n${json}${newLine}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to schedule next step in multistep operation
|
||||
*/
|
||||
interface NextStep {
|
||||
immediate(action: () => void): void;
|
||||
delay(ms: number, action: () => void): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* External capabilities used by multistep operation
|
||||
*/
|
||||
interface MultistepOperationHost {
|
||||
getCurrentRequestId(): number;
|
||||
sendRequestCompletedEvent(requestId: number): void;
|
||||
getServerHost(): ServerHost;
|
||||
isCancellationRequested(): boolean;
|
||||
executeWithRequestId(requestId: number, action: () => void): void;
|
||||
logError(error: Error, message: string): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents operation that can schedule its next step to be executed later.
|
||||
* Scheduling is done via instance of NextStep. If on current step subsequent step was not scheduled - operation is assumed to be completed.
|
||||
*/
|
||||
class MultistepOperation {
|
||||
private requestId: number;
|
||||
private timerHandle: any;
|
||||
private immediateId: any;
|
||||
private completed = true;
|
||||
private readonly next: NextStep;
|
||||
|
||||
constructor(private readonly operationHost: MultistepOperationHost) {
|
||||
this.next = {
|
||||
immediate: action => this.immediate(action),
|
||||
delay: (ms, action) => this.delay(ms, action)
|
||||
}
|
||||
}
|
||||
|
||||
public startNew(action: (next: NextStep) => void) {
|
||||
this.complete();
|
||||
this.requestId = this.operationHost.getCurrentRequestId();
|
||||
this.completed = false;
|
||||
this.executeAction(action);
|
||||
}
|
||||
|
||||
private complete() {
|
||||
if (!this.completed) {
|
||||
if (this.requestId) {
|
||||
this.operationHost.sendRequestCompletedEvent(this.requestId);
|
||||
}
|
||||
this.completed = true;
|
||||
}
|
||||
this.setTimerHandle(undefined);
|
||||
this.setImmediateId(undefined);
|
||||
}
|
||||
|
||||
private immediate(action: () => void) {
|
||||
const requestId = this.requestId;
|
||||
Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id")
|
||||
this.setImmediateId(this.operationHost.getServerHost().setImmediate(() => {
|
||||
this.immediateId = undefined;
|
||||
this.operationHost.executeWithRequestId(requestId, () => this.executeAction(action));
|
||||
}));
|
||||
}
|
||||
|
||||
private delay(ms: number, action: () => void) {
|
||||
const requestId = this.requestId;
|
||||
Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id")
|
||||
this.setTimerHandle(this.operationHost.getServerHost().setTimeout(() => {
|
||||
this.timerHandle = undefined;
|
||||
this.operationHost.executeWithRequestId(requestId, () => this.executeAction(action));
|
||||
}, ms));
|
||||
}
|
||||
|
||||
private executeAction(action: (next: NextStep) => void) {
|
||||
let stop = false;
|
||||
try {
|
||||
if (this.operationHost.isCancellationRequested()) {
|
||||
stop = true;
|
||||
}
|
||||
else {
|
||||
action(this.next);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
stop = true;
|
||||
// ignore cancellation request
|
||||
if (!(e instanceof OperationCanceledException)) {
|
||||
this.operationHost.logError(e, `delayed processing of request ${this.requestId}`);
|
||||
}
|
||||
}
|
||||
if (stop || !this.hasPendingWork()) {
|
||||
this.complete();
|
||||
}
|
||||
}
|
||||
|
||||
private setTimerHandle(timerHandle: any) {;
|
||||
if (this.timerHandle !== undefined) {
|
||||
this.operationHost.getServerHost().clearTimeout(this.timerHandle);
|
||||
}
|
||||
this.timerHandle = timerHandle;
|
||||
}
|
||||
|
||||
private setImmediateId(immediateId: number) {
|
||||
if (this.immediateId !== undefined) {
|
||||
this.operationHost.getServerHost().clearImmediate(this.immediateId);
|
||||
}
|
||||
this.immediateId = immediateId;
|
||||
}
|
||||
|
||||
private hasPendingWork() {
|
||||
return !!this.timerHandle || !!this.immediateId;
|
||||
}
|
||||
}
|
||||
|
||||
export class Session implements EventSender {
|
||||
private readonly gcTimer: GcTimer;
|
||||
protected projectService: ProjectService;
|
||||
private errorTimer: any; /*NodeJS.Timer | number*/
|
||||
private immediateId: any;
|
||||
private changeSeq = 0;
|
||||
|
||||
private currentRequestId: number;
|
||||
private errorCheck: MultistepOperation;
|
||||
|
||||
private eventHander: ProjectServiceEventHandler;
|
||||
|
||||
constructor(
|
||||
private host: ServerHost,
|
||||
cancellationToken: HostCancellationToken,
|
||||
private readonly cancellationToken: ServerCancellationToken,
|
||||
useSingleInferredProject: boolean,
|
||||
protected readonly typingsInstaller: ITypingsInstaller,
|
||||
private byteLength: (buf: string, encoding?: string) => number,
|
||||
@@ -217,17 +344,35 @@ namespace ts.server {
|
||||
? eventHandler || (event => this.defaultEventHandler(event))
|
||||
: undefined;
|
||||
|
||||
const multistepOperationHost: MultistepOperationHost = {
|
||||
executeWithRequestId: (requestId, action) => this.executeWithRequestId(requestId, action),
|
||||
getCurrentRequestId: () => this.currentRequestId,
|
||||
getServerHost: () => this.host,
|
||||
logError: (err, cmd) => this.logError(err, cmd),
|
||||
sendRequestCompletedEvent: requestId => this.sendRequestCompletedEvent(requestId),
|
||||
isCancellationRequested: () => cancellationToken.isCancellationRequested()
|
||||
}
|
||||
this.errorCheck = new MultistepOperation(multistepOperationHost);
|
||||
this.projectService = new ProjectService(host, logger, cancellationToken, useSingleInferredProject, typingsInstaller, this.eventHander);
|
||||
this.gcTimer = new GcTimer(host, /*delay*/ 7000, logger);
|
||||
}
|
||||
|
||||
private sendRequestCompletedEvent(requestId: number): void {
|
||||
const event: protocol.RequestCompletedEvent = {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: "requestCompleted",
|
||||
body: { request_seq: requestId }
|
||||
};
|
||||
this.send(event);
|
||||
}
|
||||
|
||||
private defaultEventHandler(event: ProjectServiceEvent) {
|
||||
switch (event.eventName) {
|
||||
case ContextEvent:
|
||||
const { project, fileName } = event.data;
|
||||
this.projectService.logger.info(`got context event, updating diagnostics for ${fileName}`);
|
||||
this.updateErrorCheck([{ fileName, project }], this.changeSeq,
|
||||
(n) => n === this.changeSeq, 100);
|
||||
this.errorCheck.startNew(next => this.updateErrorCheck(next, [{ fileName, project }], this.changeSeq, (n) => n === this.changeSeq, 100));
|
||||
break;
|
||||
case ConfigFileDiagEvent:
|
||||
const { triggerFile, configFileName, diagnostics } = event.data;
|
||||
@@ -284,7 +429,7 @@ namespace ts.server {
|
||||
seq: 0,
|
||||
type: "event",
|
||||
event: eventName,
|
||||
body: info,
|
||||
body: info
|
||||
};
|
||||
this.send(ev);
|
||||
}
|
||||
@@ -342,18 +487,11 @@ namespace ts.server {
|
||||
}, ms);
|
||||
}
|
||||
|
||||
private updateErrorCheck(checkList: PendingErrorCheck[], seq: number,
|
||||
matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200, requireOpen = true) {
|
||||
private updateErrorCheck(next: NextStep, checkList: PendingErrorCheck[], seq: number, matchSeq: (seq: number) => boolean, ms = 1500, followMs = 200, requireOpen = true) {
|
||||
if (followMs > ms) {
|
||||
followMs = ms;
|
||||
}
|
||||
if (this.errorTimer) {
|
||||
this.host.clearTimeout(this.errorTimer);
|
||||
}
|
||||
if (this.immediateId) {
|
||||
this.host.clearImmediate(this.immediateId);
|
||||
this.immediateId = undefined;
|
||||
}
|
||||
|
||||
let index = 0;
|
||||
const checkOne = () => {
|
||||
if (matchSeq(seq)) {
|
||||
@@ -361,21 +499,18 @@ namespace ts.server {
|
||||
index++;
|
||||
if (checkSpec.project.containsFile(checkSpec.fileName, requireOpen)) {
|
||||
this.syntacticCheck(checkSpec.fileName, checkSpec.project);
|
||||
this.immediateId = this.host.setImmediate(() => {
|
||||
next.immediate(() => {
|
||||
this.semanticCheck(checkSpec.fileName, checkSpec.project);
|
||||
this.immediateId = undefined;
|
||||
if (checkList.length > index) {
|
||||
this.errorTimer = this.host.setTimeout(checkOne, followMs);
|
||||
}
|
||||
else {
|
||||
this.errorTimer = undefined;
|
||||
next.delay(followMs, checkOne);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if ((checkList.length > index) && (matchSeq(seq))) {
|
||||
this.errorTimer = this.host.setTimeout(checkOne, ms);
|
||||
next.delay(ms, checkOne);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1087,7 +1222,7 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private getDiagnostics(delay: number, fileNames: string[]) {
|
||||
private getDiagnostics(next: NextStep, delay: number, fileNames: string[]): void {
|
||||
const checkList = fileNames.reduce((accum: PendingErrorCheck[], uncheckedFileName: string) => {
|
||||
const fileName = toNormalizedPath(uncheckedFileName);
|
||||
const project = this.projectService.getDefaultProjectForFile(fileName, /*refreshInferredProjects*/ true);
|
||||
@@ -1098,7 +1233,7 @@ namespace ts.server {
|
||||
}, []);
|
||||
|
||||
if (checkList.length > 0) {
|
||||
this.updateErrorCheck(checkList, this.changeSeq, (n) => n === this.changeSeq, delay);
|
||||
this.updateErrorCheck(next, checkList, this.changeSeq, (n) => n === this.changeSeq, delay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1277,6 +1412,9 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): protocol.CodeAction[] | CodeAction[] {
|
||||
if (args.errorCodes.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const { file, project } = this.getFileAndProjectWithoutRefreshingInferredProjects(args);
|
||||
|
||||
const scriptInfo = project.getScriptInfoForNormalizedPath(file);
|
||||
@@ -1335,7 +1473,7 @@ namespace ts.server {
|
||||
: spans;
|
||||
}
|
||||
|
||||
getDiagnosticsForProject(delay: number, fileName: string) {
|
||||
private getDiagnosticsForProject(next: NextStep, delay: number, fileName: string): void {
|
||||
const { fileNames, languageServiceDisabled } = this.getProjectInfoWorker(fileName, /*projectFileName*/ undefined, /*needFileNameList*/ true);
|
||||
if (languageServiceDisabled) {
|
||||
return;
|
||||
@@ -1373,7 +1511,7 @@ namespace ts.server {
|
||||
const checkList = fileNamesInProject.map(fileName => ({ fileName, project }));
|
||||
// Project level error analysis runs on background files too, therefore
|
||||
// doesn't require the file to be opened
|
||||
this.updateErrorCheck(checkList, this.changeSeq, (n) => n == this.changeSeq, delay, 200, /*requireOpen*/ false);
|
||||
this.updateErrorCheck(next, checkList, this.changeSeq, (n) => n == this.changeSeq, delay, 200, /*requireOpen*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1550,13 +1688,13 @@ namespace ts.server {
|
||||
[CommandNames.SyntacticDiagnosticsSync]: (request: protocol.SyntacticDiagnosticsSyncRequest) => {
|
||||
return this.requiredResponse(this.getSyntacticDiagnosticsSync(request.arguments));
|
||||
},
|
||||
[CommandNames.Geterr]: (request: protocol.Request) => {
|
||||
const geterrArgs = <protocol.GeterrRequestArgs>request.arguments;
|
||||
return { response: this.getDiagnostics(geterrArgs.delay, geterrArgs.files), responseRequired: false };
|
||||
[CommandNames.Geterr]: (request: protocol.GeterrRequest) => {
|
||||
this.errorCheck.startNew(next => this.getDiagnostics(next, request.arguments.delay, request.arguments.files));
|
||||
return this.notRequired();
|
||||
},
|
||||
[CommandNames.GeterrForProject]: (request: protocol.Request) => {
|
||||
const { file, delay } = <protocol.GeterrForProjectRequestArgs>request.arguments;
|
||||
return { response: this.getDiagnosticsForProject(delay, file), responseRequired: false };
|
||||
[CommandNames.GeterrForProject]: (request: protocol.GeterrForProjectRequest) => {
|
||||
this.errorCheck.startNew(next => this.getDiagnosticsForProject(next, request.arguments.delay, request.arguments.file));
|
||||
return this.notRequired();
|
||||
},
|
||||
[CommandNames.Change]: (request: protocol.ChangeRequest) => {
|
||||
this.change(request.arguments);
|
||||
@@ -1643,10 +1781,32 @@ namespace ts.server {
|
||||
this.handlers.set(command, handler);
|
||||
}
|
||||
|
||||
private setCurrentRequest(requestId: number): void {
|
||||
Debug.assert(this.currentRequestId === undefined);
|
||||
this.currentRequestId = requestId;
|
||||
this.cancellationToken.setRequest(requestId);
|
||||
}
|
||||
|
||||
private resetCurrentRequest(requestId: number): void {
|
||||
Debug.assert(this.currentRequestId === requestId);
|
||||
this.currentRequestId = undefined;
|
||||
this.cancellationToken.resetRequest(requestId);
|
||||
}
|
||||
|
||||
public executeWithRequestId<T>(requestId: number, f: () => T) {
|
||||
try {
|
||||
this.setCurrentRequest(requestId);
|
||||
return f();
|
||||
}
|
||||
finally {
|
||||
this.resetCurrentRequest(requestId);
|
||||
}
|
||||
}
|
||||
|
||||
public executeCommand(request: protocol.Request): { response?: any, responseRequired?: boolean } {
|
||||
const handler = this.handlers.get(request.command);
|
||||
if (handler) {
|
||||
return handler(request);
|
||||
return this.executeWithRequestId(request.seq, () => handler(request));
|
||||
}
|
||||
else {
|
||||
this.logger.msg(`Unrecognized JSON command: ${JSON.stringify(request)}`, Msg.Err);
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"compilerOptions": {
|
||||
"removeComments": true,
|
||||
"outFile": "../../built/local/tsserver.js",
|
||||
"preserveConstEnums": true,
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
|
||||
@@ -9,6 +9,7 @@ declare namespace ts.server {
|
||||
data: any;
|
||||
}
|
||||
|
||||
type RequireResult = { module: {}, error: undefined } | { module: undefined, error: {} };
|
||||
export interface ServerHost extends System {
|
||||
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
clearTimeout(timeoutId: any): void;
|
||||
@@ -16,6 +17,7 @@ declare namespace ts.server {
|
||||
clearImmediate(timeoutId: any): void;
|
||||
gc?(): void;
|
||||
trace?(s: string): void;
|
||||
require?(initialPath: string, moduleName: string): RequireResult;
|
||||
}
|
||||
|
||||
export interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../../tsconfig-base",
|
||||
"compilerOptions": {
|
||||
"removeComments": true,
|
||||
"outFile": "../../../built/local/watchGuard.js"
|
||||
},
|
||||
"files": [
|
||||
"watchGuard.ts"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/// <reference types="node" />
|
||||
|
||||
if (process.argv.length < 3) {
|
||||
process.exit(1);
|
||||
}
|
||||
const directoryName = process.argv[2];
|
||||
const fs: { watch(directoryName: string, options: any, callback: () => {}): any } = require("fs");
|
||||
// main reason why we need separate process to check if it is safe to watch some path
|
||||
// is to guard against crashes that cannot be intercepted with protected blocks and
|
||||
// code in tsserver already can handle normal cases, like non-existing folders.
|
||||
// This means that here we treat any result (success or exception) from fs.watch as success since it does not tear down the process.
|
||||
// The only case that should be considered as failure - when watchGuard process crashes.
|
||||
try {
|
||||
const watcher = fs.watch(directoryName, { recursive: true }, () => ({}))
|
||||
watcher.close();
|
||||
}
|
||||
catch (_e) {
|
||||
}
|
||||
process.exit(0);
|
||||
@@ -370,8 +370,8 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
|
||||
function textSpanFromVariableDeclaration(variableDeclaration: VariableDeclaration): TextSpan {
|
||||
const declarations = variableDeclaration.parent.declarations;
|
||||
if (declarations && declarations[0] === variableDeclaration) {
|
||||
if (variableDeclaration.parent.kind === SyntaxKind.VariableDeclarationList &&
|
||||
variableDeclaration.parent.declarations[0] === variableDeclaration) {
|
||||
// First declaration - include let keyword
|
||||
return textSpan(findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration);
|
||||
}
|
||||
@@ -400,8 +400,8 @@ namespace ts.BreakpointResolver {
|
||||
return textSpanFromVariableDeclaration(variableDeclaration);
|
||||
}
|
||||
|
||||
const declarations = variableDeclaration.parent.declarations;
|
||||
if (declarations && declarations[0] !== variableDeclaration) {
|
||||
if (variableDeclaration.parent.kind === SyntaxKind.VariableDeclarationList &&
|
||||
variableDeclaration.parent.declarations[0] !== variableDeclaration) {
|
||||
// If we cannot set breakpoint on this declaration, set it on previous one
|
||||
// Because the variable declaration may be binding pattern and
|
||||
// we would like to set breakpoint in last binding element if that's the case,
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.Property_0_does_not_exist_on_type_1.code],
|
||||
getCodeActions: getActionsForAddMissingMember
|
||||
});
|
||||
|
||||
function getActionsForAddMissingMember(context: CodeFixContext): CodeAction[] | undefined {
|
||||
|
||||
const sourceFile = context.sourceFile;
|
||||
const start = context.span.start;
|
||||
// This is the identifier of the missing property. eg:
|
||||
// this.missing = 1;
|
||||
// ^^^^^^^
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
|
||||
if (token.kind != SyntaxKind.Identifier) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const classDeclaration = getContainingClass(token);
|
||||
if (!classDeclaration) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!(token.parent && token.parent.kind === SyntaxKind.PropertyAccessExpression)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if ((token.parent as PropertyAccessExpression).expression.kind !== SyntaxKind.ThisKeyword) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let typeString = "any";
|
||||
|
||||
if (token.parent.parent.kind === SyntaxKind.BinaryExpression) {
|
||||
const binaryExpression = token.parent.parent as BinaryExpression;
|
||||
|
||||
const checker = context.program.getTypeChecker();
|
||||
const widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(binaryExpression.right)));
|
||||
typeString = checker.typeToString(widenedType);
|
||||
}
|
||||
|
||||
const startPos = classDeclaration.members.pos;
|
||||
|
||||
return [{
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_declaration_for_missing_property_0), [token.getText()]),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: [{
|
||||
span: { start: startPos, length: 0 },
|
||||
newText: `${token.getFullText(sourceFile)}: ${typeString};`
|
||||
}]
|
||||
}]
|
||||
},
|
||||
{
|
||||
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_index_signature_for_missing_property_0), [token.getText()]),
|
||||
changes: [{
|
||||
fileName: sourceFile.fileName,
|
||||
textChanges: [{
|
||||
span: { start: startPos, length: 0 },
|
||||
newText: `[name: string]: ${typeString};`
|
||||
}]
|
||||
}]
|
||||
}];
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,8 @@ namespace ts.codefix {
|
||||
const classDecl = token.parent as ClassLikeDeclaration;
|
||||
const startPos = classDecl.members.pos;
|
||||
|
||||
const classType = checker.getTypeAtLocation(classDecl) as InterfaceType;
|
||||
const instantiatedExtendsType = checker.getBaseTypes(classType)[0];
|
||||
const extendsNode = getClassExtendsHeritageClauseElement(classDecl);
|
||||
const instantiatedExtendsType = checker.getTypeAtLocation(extendsNode);
|
||||
|
||||
// Note that this is ultimately derived from a map indexed by symbol names,
|
||||
// so duplicates cannot occur.
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
const startPos: number = classDecl.members.pos;
|
||||
const classType = checker.getTypeAtLocation(classDecl);
|
||||
const classType = checker.getTypeAtLocation(classDecl) as InterfaceType;
|
||||
const implementedTypeNodes = getClassImplementsHeritageClauseElements(classDecl);
|
||||
|
||||
const hasNumericIndexSignature = !!checker.getIndexTypeOfType(classType, IndexKind.Number);
|
||||
@@ -25,9 +25,9 @@ namespace ts.codefix {
|
||||
|
||||
const result: CodeAction[] = [];
|
||||
for (const implementedTypeNode of implementedTypeNodes) {
|
||||
const implementedType = checker.getTypeFromTypeNode(implementedTypeNode) as InterfaceType;
|
||||
// Note that this is ultimately derived from a map indexed by symbol names,
|
||||
// so duplicates cannot occur.
|
||||
const implementedType = checker.getTypeAtLocation(implementedTypeNode) as InterfaceType;
|
||||
const implementedTypeSymbols = checker.getPropertiesOfType(implementedType);
|
||||
const nonPrivateMembers = implementedTypeSymbols.filter(symbol => !(getModifierFlags(symbol.valueDeclaration) & ModifierFlags.Private));
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/// <reference path="fixClassIncorrectlyImplementsInterface.ts" />
|
||||
/// <reference path="fixAddMissingMember.ts" />
|
||||
/// <reference path="fixClassDoesntImplementInheritedAbstractMember.ts" />
|
||||
/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
|
||||
/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />
|
||||
|
||||
@@ -23,8 +23,6 @@ namespace ts.codefix {
|
||||
* @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`.
|
||||
*/
|
||||
function getInsertionForMemberSymbol(symbol: Symbol, enclosingDeclaration: ClassLikeDeclaration, checker: TypeChecker, newlineChar: string): string {
|
||||
// const name = symbol.getName();
|
||||
const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration);
|
||||
const declarations = symbol.getDeclarations();
|
||||
if (!(declarations && declarations.length)) {
|
||||
return "";
|
||||
@@ -32,7 +30,9 @@ namespace ts.codefix {
|
||||
|
||||
const declaration = declarations[0] as Declaration;
|
||||
const name = declaration.name ? declaration.name.getText() : undefined;
|
||||
const visibility = getVisibilityPrefix(getModifierFlags(declaration));
|
||||
const visibility = getVisibilityPrefixWithSpace(getModifierFlags(declaration));
|
||||
|
||||
const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration);
|
||||
|
||||
switch (declaration.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
@@ -58,7 +58,7 @@ namespace ts.codefix {
|
||||
if (declarations.length === 1) {
|
||||
Debug.assert(signatures.length === 1);
|
||||
const sigString = checker.signatureToString(signatures[0], enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call);
|
||||
return `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`;
|
||||
return getStubbedMethod(visibility, name, sigString, newlineChar);
|
||||
}
|
||||
|
||||
let result = "";
|
||||
@@ -78,7 +78,7 @@ namespace ts.codefix {
|
||||
bodySig = createBodySignatureWithAnyTypes(signatures, enclosingDeclaration, checker);
|
||||
}
|
||||
const sigString = checker.signatureToString(bodySig, enclosingDeclaration, TypeFormatFlags.SuppressAnyReturnType, SignatureKind.Call);
|
||||
result += `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`;
|
||||
result += getStubbedMethod(visibility, name, sigString, newlineChar);
|
||||
|
||||
return result;
|
||||
default:
|
||||
@@ -138,11 +138,15 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function getMethodBodyStub(newLineChar: string) {
|
||||
return ` {${newLineChar}throw new Error('Method not implemented.');${newLineChar}}${newLineChar}`;
|
||||
export function getStubbedMethod(visibility: string, name: string, sigString = "()", newlineChar: string): string {
|
||||
return `${visibility}${name}${sigString}${getMethodBodyStub(newlineChar)}`;
|
||||
}
|
||||
|
||||
function getVisibilityPrefix(flags: ModifierFlags): string {
|
||||
function getMethodBodyStub(newlineChar: string) {
|
||||
return ` {${newlineChar}throw new Error('Method not implemented.');${newlineChar}}${newlineChar}`;
|
||||
}
|
||||
|
||||
function getVisibilityPrefixWithSpace(flags: ModifierFlags): string {
|
||||
if (flags & ModifierFlags.Public) {
|
||||
return "public ";
|
||||
}
|
||||
|
||||
@@ -150,7 +150,20 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function createCodeFixToRemoveNode(node: Node) {
|
||||
return createCodeFix("", node.getStart(), node.getWidth());
|
||||
let end = node.getEnd();
|
||||
const endCharCode = sourceFile.text.charCodeAt(end);
|
||||
const afterEndCharCode = sourceFile.text.charCodeAt(end + 1);
|
||||
if (isLineBreak(endCharCode)) {
|
||||
end += 1;
|
||||
}
|
||||
// in the case of CR LF, you could have two consecutive new line characters for one new line.
|
||||
// this needs to be differenciated from two LF LF chars that actually mean two new lines.
|
||||
if (isLineBreak(afterEndCharCode) && endCharCode !== afterEndCharCode) {
|
||||
end += 1;
|
||||
}
|
||||
|
||||
const start = node.getStart();
|
||||
return createCodeFix("", start, end - start);
|
||||
}
|
||||
|
||||
function findFirstNonSpaceCharPosStarting(start: number) {
|
||||
|
||||
+91
-28
@@ -16,11 +16,16 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isJsDocTagName } = completionData;
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, requestJsDocTagName, requestJsDocTag } = completionData;
|
||||
|
||||
if (isJsDocTagName) {
|
||||
if (requestJsDocTagName) {
|
||||
// If the current position is a jsDoc tag name, only tag names should be provided for completion
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getAllJsDocCompletionEntries() };
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getJSDocTagNameCompletions() };
|
||||
}
|
||||
|
||||
if (requestJsDocTag) {
|
||||
// If the current position is a jsDoc tag, only tags should be provided for completion
|
||||
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: JsDoc.getJSDocTagCompletions() };
|
||||
}
|
||||
|
||||
const entries: CompletionEntry[] = [];
|
||||
@@ -54,7 +59,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
// Add keywords if this is not a member completion list
|
||||
if (!isMemberCompletion && !isJsDocTagName) {
|
||||
if (!isMemberCompletion && !requestJsDocTag && !requestJsDocTagName) {
|
||||
addRange(entries, keywordCompletions);
|
||||
}
|
||||
|
||||
@@ -814,7 +819,10 @@ namespace ts.Completions {
|
||||
function getCompletionData(typeChecker: TypeChecker, log: (message: string) => void, sourceFile: SourceFile, position: number) {
|
||||
const isJavaScriptFile = isSourceFileJavaScript(sourceFile);
|
||||
|
||||
let isJsDocTagName = false;
|
||||
// JsDoc tag-name is just the name of the JSDoc tagname (exclude "@")
|
||||
let requestJsDocTagName = false;
|
||||
// JsDoc tag includes both "@" and tag-name
|
||||
let requestJsDocTag = false;
|
||||
|
||||
let start = timestamp();
|
||||
const currentToken = getTokenAtPosition(sourceFile, position);
|
||||
@@ -826,10 +834,32 @@ namespace ts.Completions {
|
||||
log("getCompletionData: Is inside comment: " + (timestamp() - start));
|
||||
|
||||
if (insideComment) {
|
||||
// The current position is next to the '@' sign, when no tag name being provided yet.
|
||||
// Provide a full list of tag names
|
||||
if (hasDocComment(sourceFile, position) && sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) {
|
||||
isJsDocTagName = true;
|
||||
if (hasDocComment(sourceFile, position)) {
|
||||
// The current position is next to the '@' sign, when no tag name being provided yet.
|
||||
// Provide a full list of tag names
|
||||
if (sourceFile.text.charCodeAt(position - 1) === CharacterCodes.at) {
|
||||
requestJsDocTagName = true;
|
||||
}
|
||||
else {
|
||||
// When completion is requested without "@", we will have check to make sure that
|
||||
// there are no comments prefix the request position. We will only allow "*" and space.
|
||||
// e.g
|
||||
// /** |c| /*
|
||||
//
|
||||
// /**
|
||||
// |c|
|
||||
// */
|
||||
//
|
||||
// /**
|
||||
// * |c|
|
||||
// */
|
||||
//
|
||||
// /**
|
||||
// * |c|
|
||||
// */
|
||||
const lineStart = getLineStartPositionForPosition(position, sourceFile);
|
||||
requestJsDocTag = !(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/));
|
||||
}
|
||||
}
|
||||
|
||||
// Completion should work inside certain JsDoc tags. For example:
|
||||
@@ -839,7 +869,7 @@ namespace ts.Completions {
|
||||
const tag = getJsDocTagAtPosition(sourceFile, position);
|
||||
if (tag) {
|
||||
if (tag.tagName.pos <= position && position <= tag.tagName.end) {
|
||||
isJsDocTagName = true;
|
||||
requestJsDocTagName = true;
|
||||
}
|
||||
|
||||
switch (tag.kind) {
|
||||
@@ -854,8 +884,8 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
if (isJsDocTagName) {
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, isJsDocTagName };
|
||||
if (requestJsDocTagName || requestJsDocTag) {
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, requestJsDocTagName, requestJsDocTag };
|
||||
}
|
||||
|
||||
if (!insideJsDocTagExpression) {
|
||||
@@ -915,13 +945,29 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
else if (sourceFile.languageVariant === LanguageVariant.JSX) {
|
||||
if (kind === SyntaxKind.LessThanToken) {
|
||||
isRightOfOpenTag = true;
|
||||
location = contextToken;
|
||||
}
|
||||
else if (kind === SyntaxKind.SlashToken && contextToken.parent.kind === SyntaxKind.JsxClosingElement) {
|
||||
isStartingCloseTag = true;
|
||||
location = contextToken;
|
||||
switch (contextToken.parent.kind) {
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
if (kind === SyntaxKind.SlashToken) {
|
||||
isStartingCloseTag = true;
|
||||
location = contextToken;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.BinaryExpression:
|
||||
if (!((contextToken.parent as BinaryExpression).left.flags & NodeFlags.ThisNodeHasError)) {
|
||||
// It has a left-hand side, so we're not in an opening JSX tag.
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
if (kind === SyntaxKind.LessThanToken) {
|
||||
isRightOfOpenTag = true;
|
||||
location = contextToken;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -967,7 +1013,7 @@ namespace ts.Completions {
|
||||
|
||||
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
||||
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), isJsDocTagName };
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), requestJsDocTagName, requestJsDocTag };
|
||||
|
||||
function getTypeScriptMemberSymbols(): void {
|
||||
// Right of dot member completion list
|
||||
@@ -1040,10 +1086,10 @@ namespace ts.Completions {
|
||||
let attrsType: Type;
|
||||
if ((jsxContainer.kind === SyntaxKind.JsxSelfClosingElement) || (jsxContainer.kind === SyntaxKind.JsxOpeningElement)) {
|
||||
// Cursor is inside a JSX self-closing element or opening element
|
||||
attrsType = typeChecker.getJsxElementAttributesType(<JsxOpeningLikeElement>jsxContainer);
|
||||
attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(<JsxOpeningLikeElement>jsxContainer);
|
||||
|
||||
if (attrsType) {
|
||||
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (<JsxOpeningLikeElement>jsxContainer).attributes);
|
||||
symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), (<JsxOpeningLikeElement>jsxContainer).attributes.properties);
|
||||
isMemberCompletion = true;
|
||||
isNewIdentifierLocation = false;
|
||||
return true;
|
||||
@@ -1385,13 +1431,18 @@ namespace ts.Completions {
|
||||
case SyntaxKind.LessThanSlashToken:
|
||||
case SyntaxKind.SlashToken:
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.JsxAttributes:
|
||||
case SyntaxKind.JsxAttribute:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
if (parent && (parent.kind === SyntaxKind.JsxSelfClosingElement || parent.kind === SyntaxKind.JsxOpeningElement)) {
|
||||
return <JsxOpeningLikeElement>parent;
|
||||
}
|
||||
else if (parent.kind === SyntaxKind.JsxAttribute) {
|
||||
return <JsxOpeningLikeElement>parent.parent;
|
||||
// Currently we parse JsxOpeningLikeElement as:
|
||||
// JsxOpeningLikeElement
|
||||
// attributes: JsxAttributes
|
||||
// properties: NodeArray<JsxAttributeLike>
|
||||
return parent.parent.parent as JsxOpeningLikeElement;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1400,7 +1451,11 @@ namespace ts.Completions {
|
||||
// whose parent is a JsxOpeningLikeElement
|
||||
case SyntaxKind.StringLiteral:
|
||||
if (parent && ((parent.kind === SyntaxKind.JsxAttribute) || (parent.kind === SyntaxKind.JsxSpreadAttribute))) {
|
||||
return <JsxOpeningLikeElement>parent.parent;
|
||||
// Currently we parse JsxOpeningLikeElement as:
|
||||
// JsxOpeningLikeElement
|
||||
// attributes: JsxAttributes
|
||||
// properties: NodeArray<JsxAttributeLike>
|
||||
return parent.parent.parent as JsxOpeningLikeElement;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1408,13 +1463,21 @@ namespace ts.Completions {
|
||||
case SyntaxKind.CloseBraceToken:
|
||||
if (parent &&
|
||||
parent.kind === SyntaxKind.JsxExpression &&
|
||||
parent.parent &&
|
||||
(parent.parent.kind === SyntaxKind.JsxAttribute)) {
|
||||
return <JsxOpeningLikeElement>parent.parent.parent;
|
||||
parent.parent && parent.parent.kind === SyntaxKind.JsxAttribute) {
|
||||
// Currently we parse JsxOpeningLikeElement as:
|
||||
// JsxOpeningLikeElement
|
||||
// attributes: JsxAttributes
|
||||
// properties: NodeArray<JsxAttributeLike>
|
||||
// each JsxAttribute can have initializer as JsxExpression
|
||||
return parent.parent.parent.parent as JsxOpeningLikeElement;
|
||||
}
|
||||
|
||||
if (parent && parent.kind === SyntaxKind.JsxSpreadAttribute) {
|
||||
return <JsxOpeningLikeElement>parent.parent;
|
||||
// Currently we parse JsxOpeningLikeElement as:
|
||||
// JsxOpeningLikeElement
|
||||
// attributes: JsxAttributes
|
||||
// properties: NodeArray<JsxAttributeLike>
|
||||
return parent.parent.parent as JsxOpeningLikeElement;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -133,7 +133,7 @@ namespace ts.FindAllReferences {
|
||||
return { symbol };
|
||||
}
|
||||
|
||||
if (ts.isShorthandAmbientModuleSymbol(aliasedSymbol)) {
|
||||
if (ts.isUntypedOrShorthandAmbientModuleSymbol(aliasedSymbol)) {
|
||||
return { symbol, shorthandModuleSymbol: aliasedSymbol };
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace ts.FindAllReferences {
|
||||
const importDecl = importSpecifier.parent as ts.ImportDeclaration;
|
||||
Debug.assert(importDecl.moduleSpecifier === importSpecifier);
|
||||
const defaultName = importDecl.importClause.name;
|
||||
const defaultReferencedSymbol = checker.getAliasedSymbol(checker.getSymbolAtLocation(defaultName));
|
||||
const defaultReferencedSymbol = defaultName && checker.getAliasedSymbol(checker.getSymbolAtLocation(defaultName));
|
||||
if (symbol === defaultReferencedSymbol) {
|
||||
return defaultName.text;
|
||||
}
|
||||
@@ -406,21 +406,24 @@ namespace ts.FindAllReferences {
|
||||
|
||||
function getAllReferencesForKeyword(sourceFiles: SourceFile[], keywordKind: ts.SyntaxKind, cancellationToken: CancellationToken): ReferencedSymbol[] {
|
||||
const name = tokenToString(keywordKind);
|
||||
const definition: ReferencedSymbolDefinitionInfo = {
|
||||
containerKind: "",
|
||||
containerName: "",
|
||||
fileName: "",
|
||||
kind: ScriptElementKind.keyword,
|
||||
name,
|
||||
textSpan: createTextSpan(0, 1),
|
||||
displayParts: [{ text: name, kind: ScriptElementKind.keyword }]
|
||||
}
|
||||
const references: ReferenceEntry[] = [];
|
||||
for (const sourceFile of sourceFiles) {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
addReferencesForKeywordInFile(sourceFile, keywordKind, name, cancellationToken, references);
|
||||
}
|
||||
|
||||
if (!references.length) return undefined;
|
||||
|
||||
const definition: ReferencedSymbolDefinitionInfo = {
|
||||
containerKind: "",
|
||||
containerName: "",
|
||||
fileName: references[0].fileName,
|
||||
kind: ScriptElementKind.keyword,
|
||||
name,
|
||||
textSpan: references[0].textSpan,
|
||||
displayParts: [{ text: name, kind: ScriptElementKind.keyword }]
|
||||
}
|
||||
|
||||
return [{ definition, references }];
|
||||
}
|
||||
|
||||
@@ -1413,35 +1416,6 @@ namespace ts.FindAllReferences {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
|
||||
*/
|
||||
function getContainingObjectLiteralElement(node: Node): ObjectLiteralElement {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
if (node.parent.kind === SyntaxKind.ComputedPropertyName) {
|
||||
return isObjectLiteralPropertyDeclaration(node.parent.parent) ? node.parent.parent : undefined;
|
||||
}
|
||||
// intential fall through
|
||||
case SyntaxKind.Identifier:
|
||||
return isObjectLiteralPropertyDeclaration(node.parent) && node.parent.name === node ? node.parent : undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isObjectLiteralPropertyDeclaration(node: Node): node is ObjectLiteralElement {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Get `C` given `N` if `N` is in the position `class C extends N` or `class C extends foo.N` where `N` is an identifier. */
|
||||
function tryGetClassByExtendingIdentifier(node: Node): ClassLikeDeclaration | undefined {
|
||||
return tryGetClassExtendingExpressionWithTypeArguments(climbPastPropertyAccess(node).parent);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* @internal */
|
||||
/* @internal */
|
||||
namespace ts.GoToDefinition {
|
||||
export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile, position: number): DefinitionInfo[] {
|
||||
/// Triple slash reference comments
|
||||
@@ -85,6 +85,37 @@ namespace ts.GoToDefinition {
|
||||
declaration => createDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName));
|
||||
}
|
||||
|
||||
if (isJsxOpeningLikeElement(node.parent)) {
|
||||
// If there are errors when trying to figure out stateless component function, just return the first declaration
|
||||
// For example:
|
||||
// declare function /*firstSource*/MainButton(buttonProps: ButtonProps): JSX.Element;
|
||||
// declare function /*secondSource*/MainButton(linkProps: LinkProps): JSX.Element;
|
||||
// declare function /*thirdSource*/MainButton(props: ButtonProps | LinkProps): JSX.Element;
|
||||
// let opt = <Main/*firstTarget*/Button />; // Error - We get undefined for resolved signature indicating an error, then just return the first declaration
|
||||
const {symbolName, symbolKind, containerName} = getSymbolInfo(typeChecker, symbol, node);
|
||||
return [createDefinitionInfo(symbol.valueDeclaration, symbolKind, symbolName, containerName)];
|
||||
}
|
||||
|
||||
// If the current location we want to find its definition is in an object literal, try to get the contextual type for the
|
||||
// object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
|
||||
// For example
|
||||
// interface Props{
|
||||
// /*first*/prop1: number
|
||||
// prop2: boolean
|
||||
// }
|
||||
// function Foo(arg: Props) {}
|
||||
// Foo( { pr/*1*/op1: 10, prop2: true })
|
||||
const element = getContainingObjectLiteralElement(node);
|
||||
if (element) {
|
||||
if (typeChecker.getContextualType(element.parent as Expression)) {
|
||||
const result: DefinitionInfo[] = [];
|
||||
const propertySymbols = getPropertySymbolsFromContextualType(typeChecker, element);
|
||||
for (const propertySymbol of propertySymbols) {
|
||||
result.push(...getDefinitionFromSymbol(typeChecker, propertySymbol, node));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return getDefinitionFromSymbol(typeChecker, symbol, node);
|
||||
}
|
||||
|
||||
@@ -167,7 +198,11 @@ namespace ts.GoToDefinition {
|
||||
return false;
|
||||
}
|
||||
|
||||
function tryAddSignature(signatureDeclarations: Declaration[], selectConstructors: boolean, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
function tryAddSignature(signatureDeclarations: Declaration[] | undefined, selectConstructors: boolean, symbolKind: string, symbolName: string, containerName: string, result: DefinitionInfo[]) {
|
||||
if (!signatureDeclarations) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const declarations: Declaration[] = [];
|
||||
let definition: Declaration | undefined;
|
||||
|
||||
@@ -262,9 +297,12 @@ namespace ts.GoToDefinition {
|
||||
|
||||
function tryGetSignatureDeclaration(typeChecker: TypeChecker, node: Node): SignatureDeclaration | undefined {
|
||||
const callLike = getAncestorCallLikeExpression(node);
|
||||
const decl = callLike && typeChecker.getResolvedSignature(callLike).declaration;
|
||||
if (decl && isSignatureDeclaration(decl)) {
|
||||
return decl;
|
||||
const signature = callLike && typeChecker.getResolvedSignature(callLike);
|
||||
if (signature) {
|
||||
const decl = signature.declaration;
|
||||
if (decl && isSignatureDeclaration(decl)) {
|
||||
return decl;
|
||||
}
|
||||
}
|
||||
// Don't go to a function type, go to the value having that type.
|
||||
return undefined;
|
||||
|
||||
+15
-3
@@ -42,7 +42,8 @@ namespace ts.JsDoc {
|
||||
"prop",
|
||||
"version"
|
||||
];
|
||||
let jsDocCompletionEntries: CompletionEntry[];
|
||||
let jsDocTagNameCompletionEntries: CompletionEntry[];
|
||||
let jsDocTagCompletionEntries: CompletionEntry[];
|
||||
|
||||
export function getJsDocCommentsFromDeclarations(declarations: Declaration[]) {
|
||||
// Only collect doc comments from duplicate declarations once:
|
||||
@@ -88,8 +89,8 @@ namespace ts.JsDoc {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getAllJsDocCompletionEntries(): CompletionEntry[] {
|
||||
return jsDocCompletionEntries || (jsDocCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
export function getJSDocTagNameCompletions(): CompletionEntry[] {
|
||||
return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
return {
|
||||
name: tagName,
|
||||
kind: ScriptElementKind.keyword,
|
||||
@@ -99,6 +100,17 @@ namespace ts.JsDoc {
|
||||
}));
|
||||
}
|
||||
|
||||
export function getJSDocTagCompletions(): CompletionEntry[] {
|
||||
return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
return {
|
||||
name: `@${tagName}`,
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: "",
|
||||
sortText: "0"
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if position points to a valid position to add JSDoc comments, and if so,
|
||||
* returns the appropriate template. Otherwise returns an empty string.
|
||||
|
||||
@@ -67,10 +67,10 @@ namespace ts.OutliningElementsCollector {
|
||||
|
||||
// Only outline spans of two or more consecutive single line comments
|
||||
if (count > 1) {
|
||||
const multipleSingleLineComments = {
|
||||
const multipleSingleLineComments: CommentRange = {
|
||||
kind: SyntaxKind.SingleLineCommentTrivia,
|
||||
pos: start,
|
||||
end: end,
|
||||
kind: SyntaxKind.SingleLineCommentTrivia
|
||||
};
|
||||
|
||||
addOutliningSpanComments(multipleSingleLineComments, /*autoCollapse*/ false);
|
||||
|
||||
@@ -397,6 +397,7 @@ namespace ts {
|
||||
parameters: Symbol[];
|
||||
thisParameter: Symbol;
|
||||
resolvedReturnType: Type;
|
||||
minTypeArgumentCount: number;
|
||||
minArgumentCount: number;
|
||||
hasRestParameter: boolean;
|
||||
hasLiteralTypes: boolean;
|
||||
@@ -411,7 +412,7 @@ namespace ts {
|
||||
getDeclaration(): SignatureDeclaration {
|
||||
return this.declaration;
|
||||
}
|
||||
getTypeParameters(): Type[] {
|
||||
getTypeParameters(): TypeParameter[] {
|
||||
return this.typeParameters;
|
||||
}
|
||||
getParameters(): Symbol[] {
|
||||
@@ -1446,7 +1447,8 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
const emitOutput = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles);
|
||||
const customTransformers = host.getCustomTransformers && host.getCustomTransformers();
|
||||
const emitOutput = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
|
||||
|
||||
return {
|
||||
outputFiles,
|
||||
@@ -1688,7 +1690,7 @@ namespace ts {
|
||||
|
||||
let allFixes: CodeAction[] = [];
|
||||
|
||||
forEach(errorCodes, error => {
|
||||
forEach(deduplicate(errorCodes), error => {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
const context = {
|
||||
@@ -1990,6 +1992,66 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isObjectLiteralElement(node: Node): node is ObjectLiteralElement {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.JsxAttribute:
|
||||
case SyntaxKind.JsxSpreadAttribute:
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
|
||||
*/
|
||||
/* @internal */
|
||||
export function getContainingObjectLiteralElement(node: Node): ObjectLiteralElement {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
if (node.parent.kind === SyntaxKind.ComputedPropertyName) {
|
||||
return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
|
||||
}
|
||||
// intentionally fall through
|
||||
case SyntaxKind.Identifier:
|
||||
return isObjectLiteralElement(node.parent) &&
|
||||
(node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === SyntaxKind.JsxAttributes) &&
|
||||
(<ObjectLiteralElement>node.parent).name === node ? node.parent as ObjectLiteralElement : undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getPropertySymbolsFromContextualType(typeChecker: TypeChecker, node: ObjectLiteralElement): Symbol[] {
|
||||
const objectLiteral = <ObjectLiteralExpression | JsxAttributes>node.parent;
|
||||
const contextualType = typeChecker.getContextualType(objectLiteral);
|
||||
const name = getTextOfPropertyName(node.name);
|
||||
if (name && contextualType) {
|
||||
const result: Symbol[] = [];
|
||||
const symbol = contextualType.getProperty(name);
|
||||
if (contextualType.flags & TypeFlags.Union) {
|
||||
forEach((<UnionType>contextualType).types, t => {
|
||||
const symbol = t.getProperty(name);
|
||||
if (symbol) {
|
||||
result.push(symbol);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
if (symbol) {
|
||||
result.push(symbol);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isArgumentOfElementAccessExpression(node: Node) {
|
||||
return node &&
|
||||
node.parent &&
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user