mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into release-3.0
This commit is contained in:
+139
-57
@@ -24,6 +24,10 @@ const baselineAccept = require("./scripts/build/baselineAccept");
|
||||
const cmdLineOptions = require("./scripts/build/options");
|
||||
const exec = require("./scripts/build/exec");
|
||||
const browserify = require("./scripts/build/browserify");
|
||||
const debounce = require("./scripts/build/debounce");
|
||||
const prepend = require("./scripts/build/prepend");
|
||||
const { removeSourceMaps } = require("./scripts/build/sourcemaps");
|
||||
const { CancelSource, CancelError } = require("./scripts/build/cancellation");
|
||||
const { libraryTargets, generateLibs } = require("./scripts/build/lib");
|
||||
const { runConsoleTests, cleanTestDirs, writeTestConfigFile, refBaseline, localBaseline, refRwcBaseline, localRwcBaseline } = require("./scripts/build/tests");
|
||||
|
||||
@@ -44,17 +48,9 @@ const generateLocalizedDiagnosticMessagesJs = "scripts/generateLocalizedDiagnost
|
||||
const buildProtocolJs = "scripts/buildProtocol.js";
|
||||
const produceLKGJs = "scripts/produceLKG.js";
|
||||
const word2mdJs = "scripts/word2md.js";
|
||||
gulp.task("scripts", /*help*/ false, () => project.compile(scriptsProject), {
|
||||
aliases: [
|
||||
configurePrereleaseJs,
|
||||
processDiagnosticMessagesJs,
|
||||
generateLocalizedDiagnosticMessagesJs,
|
||||
produceLKGJs,
|
||||
buildProtocolJs,
|
||||
word2mdJs
|
||||
]
|
||||
});
|
||||
gulp.task("clean-scripts", /*help*/ false, () => project.clean(scriptsProject));
|
||||
const scriptsTaskAliases = [configurePrereleaseJs, processDiagnosticMessagesJs, generateLocalizedDiagnosticMessagesJs, produceLKGJs, buildProtocolJs, word2mdJs];
|
||||
gulp.task("scripts", /*help*/ false, () => project.compile(scriptsProject), { aliases: scriptsTaskAliases });
|
||||
gulp.task("clean:scripts", /*help*/ false, () => project.clean(scriptsProject), { aliases: scriptsTaskAliases.map(alias => `clean:${alias}`)});
|
||||
|
||||
// Nightly management tasks
|
||||
gulp.task(
|
||||
@@ -73,7 +69,7 @@ gulp.task(
|
||||
const importDefinitelyTypedTestsProject = "scripts/importDefinitelyTypedTests/tsconfig.json";
|
||||
const importDefinitelyTypedTestsJs = "scripts/importDefinitelyTypedTests/importDefinitelyTypedTests.js";
|
||||
gulp.task(importDefinitelyTypedTestsJs, /*help*/ false, () => project.compile(importDefinitelyTypedTestsProject));
|
||||
gulp.task("clean:" + importDefinitelyTypedTestsJs, /*help*/ false, () => project.clean(importDefinitelyTypedTestsProject));
|
||||
gulp.task(`clean:${importDefinitelyTypedTestsJs}`, /*help*/ false, () => project.clean(importDefinitelyTypedTestsProject));
|
||||
|
||||
gulp.task(
|
||||
"importDefinitelyTypedTests",
|
||||
@@ -95,7 +91,7 @@ gulp.task(diagnosticInformationMapTs, /*help*/ false, [processDiagnosticMessages
|
||||
return exec(host, [processDiagnosticMessagesJs, diagnosticMessagesJson]);
|
||||
}
|
||||
});
|
||||
gulp.task("clean:" + diagnosticInformationMapTs, /*help*/ false, () => del([diagnosticInformationMapTs, diagnosticMessagesGeneratedJson]));
|
||||
gulp.task(`clean:${diagnosticInformationMapTs}`, /*help*/ false, () => del([diagnosticInformationMapTs, diagnosticMessagesGeneratedJson]));
|
||||
|
||||
const builtGeneratedDiagnosticMessagesJson = "built/local/diagnosticMessages.generated.json";
|
||||
gulp.task(builtGeneratedDiagnosticMessagesJson, /*help*/ false, [diagnosticInformationMapTs], () =>
|
||||
@@ -140,9 +136,10 @@ gulp.task(typescriptServicesProject, /*help*/ false, () => {
|
||||
// NOTE: flatten services so that we can properly strip @internal
|
||||
project.flatten(servicesProject, typescriptServicesProject, {
|
||||
compilerOptions: {
|
||||
"removeComments": true,
|
||||
"removeComments": false,
|
||||
"stripInternal": true,
|
||||
"outFile": "typescriptServices.js"
|
||||
"declarationMap": false,
|
||||
"outFile": "typescriptServices.out.js" // must align with same task in jakefile. We fix this name below.
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -150,7 +147,16 @@ gulp.task(typescriptServicesProject, /*help*/ false, () => {
|
||||
const typescriptServicesJs = "built/local/typescriptServices.js";
|
||||
const typescriptServicesDts = "built/local/typescriptServices.d.ts";
|
||||
gulp.task(typescriptServicesJs, /*help*/ false, ["lib", "generate-diagnostics", typescriptServicesProject], () =>
|
||||
project.compile(typescriptServicesProject, { dts: files => files.pipe(convertConstEnums()) }),
|
||||
project.compile(typescriptServicesProject, {
|
||||
js: files => files
|
||||
.pipe(prepend.file(copyright))
|
||||
.pipe(rename("typescriptServices.js")),
|
||||
dts: files => files
|
||||
.pipe(removeSourceMaps())
|
||||
.pipe(prepend.file(copyright))
|
||||
.pipe(convertConstEnums())
|
||||
.pipe(rename("typescriptServices.d.ts"))
|
||||
}),
|
||||
{ aliases: [typescriptServicesDts] });
|
||||
|
||||
const typescriptJs = "built/local/typescript.js";
|
||||
@@ -179,29 +185,39 @@ gulp.task(typescriptStandaloneDts, /*help*/ false, [typescriptServicesDts], () =
|
||||
// build all 'typescriptServices'-related outputs
|
||||
gulp.task("services", /*help*/ false, [typescriptServicesJs, typescriptServicesDts, typescriptJs, typescriptDts, typescriptStandaloneDts]);
|
||||
|
||||
const useCompiler = cmdLineOptions.lkg ? "lkg" : "built";
|
||||
const useCompilerDeps = cmdLineOptions.lkg ? ["lib", "generate-diagnostics"] : [typescriptServicesJs];
|
||||
|
||||
const tscProject = "src/tsc/tsconfig.json";
|
||||
const tscJs = "built/local/tsc.js";
|
||||
gulp.task(tscJs, /*help*/ false, [typescriptServicesJs], () => project.compile(tscProject, { typescript: "built" }));
|
||||
gulp.task(tscJs, /*help*/ false, useCompilerDeps, () =>
|
||||
project.compile(tscProject, {
|
||||
typescript: useCompiler,
|
||||
js: files => files.pipe(prepend.file(copyright))
|
||||
}));
|
||||
|
||||
const tscReleaseProject = "src/tsc/tsconfig.release.json";
|
||||
const tscReleaseJs = "built/local/tsc.release.js";
|
||||
gulp.task(tscReleaseJs, /*help*/ false, () => project.compile(tscReleaseProject));
|
||||
gulp.task(tscReleaseJs, /*help*/ false, () =>
|
||||
project.compile(tscReleaseProject, {
|
||||
js: files => files.pipe(prepend.file(copyright))
|
||||
}));
|
||||
|
||||
const cancellationTokenProject = "src/cancellationToken/tsconfig.json";
|
||||
const cancellationTokenJs = "built/local/cancellationToken.js";
|
||||
gulp.task(cancellationTokenJs, /*help*/ false, [typescriptServicesJs], () => project.compile(cancellationTokenProject, { typescript: "built" }));
|
||||
gulp.task(cancellationTokenJs, /*help*/ false, useCompilerDeps, () => project.compile(cancellationTokenProject, { typescript: useCompiler }));
|
||||
|
||||
const typingsInstallerProject = "src/typingsInstaller/tsconfig.json";
|
||||
const typingsInstallerJs = "built/local/typingsInstaller.js";
|
||||
gulp.task(typingsInstallerJs, /*help*/ false, [typescriptServicesJs], () => project.compile(typingsInstallerProject, { typescript: "built" }));
|
||||
gulp.task(typingsInstallerJs, /*help*/ false, useCompilerDeps, () => project.compile(typingsInstallerProject, { typescript: useCompiler }));
|
||||
|
||||
const tsserverProject = "src/tsserver/tsconfig.json";
|
||||
const tsserverJs = "built/local/tsserver.js";
|
||||
gulp.task(tsserverJs, /*help*/ false, [typescriptServicesJs], () => project.compile(tsserverProject, { typescript: "built" }));
|
||||
gulp.task(tsserverJs, /*help*/ false, useCompilerDeps, () => project.compile(tsserverProject, { typescript: useCompiler }));
|
||||
|
||||
const watchGuardProject = "src/watchGuard/tsconfig.json";
|
||||
const watchGuardJs = "built/local/watchGuard.js";
|
||||
gulp.task(watchGuardJs, /*help*/ false, [typescriptServicesJs], () => project.compile(watchGuardProject, { typescript: "built" }));
|
||||
gulp.task(watchGuardJs, /*help*/ false, useCompilerDeps, () => project.compile(watchGuardProject, { typescript: useCompiler }));
|
||||
|
||||
const typesMapJson = "built/local/typesMap.json";
|
||||
gulp.task(typesMapJson, /*help*/ false, [], () =>
|
||||
@@ -216,21 +232,28 @@ gulp.task(tsserverlibraryProject, /*help*/ false, () => {
|
||||
project.flatten("src/tsserver/tsconfig.json", tsserverlibraryProject, {
|
||||
exclude: ["src/tsserver/server.ts"],
|
||||
compilerOptions: {
|
||||
"removeComments": true,
|
||||
"removeComments": false,
|
||||
"stripInternal": true,
|
||||
"outFile": "tsserverlibrary.js"
|
||||
"declarationMap": false,
|
||||
"outFile": "tsserverlibrary.out.js" // must align with same task in jakefile. We fix this name below.
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const tsserverlibraryJs = "built/local/tsserverlibrary.js";
|
||||
const tsserverlibraryDts = "built/local/tsserverlibrary.d.ts";
|
||||
gulp.task(tsserverlibraryJs, /*help*/ false, [typescriptServicesJs, tsserverlibraryProject], () =>
|
||||
gulp.task(tsserverlibraryJs, /*help*/ false, useCompilerDeps.concat([tsserverlibraryProject]), () =>
|
||||
project.compile(tsserverlibraryProject, {
|
||||
js: files => files
|
||||
.pipe(prepend.file(copyright))
|
||||
.pipe(rename("tsserverlibrary.js")),
|
||||
dts: files => files
|
||||
.pipe(removeSourceMaps())
|
||||
.pipe(prepend.file(copyright))
|
||||
.pipe(convertConstEnums())
|
||||
.pipe(append("\nexport = ts;\nexport as namespace ts;")),
|
||||
typescript: "built"
|
||||
.pipe(append("\nexport = ts;\nexport as namespace ts;"))
|
||||
.pipe(rename("tsserverlibrary.d.ts")),
|
||||
typescript: useCompiler
|
||||
}), { aliases: [tsserverlibraryDts] });
|
||||
|
||||
gulp.task(
|
||||
@@ -294,29 +317,29 @@ gulp.task(
|
||||
// Task to build the tests infrastructure using the built compiler
|
||||
const testRunnerProject = "src/testRunner/tsconfig.json";
|
||||
const runJs = "built/local/run.js";
|
||||
gulp.task(runJs, /*help*/ false, [typescriptServicesJs, tsserverlibraryDts], () => project.compile(testRunnerProject, { typescript: "built" }));
|
||||
gulp.task(runJs, /*help*/ false, useCompilerDeps, () => project.compile(testRunnerProject, { typescript: useCompiler }));
|
||||
|
||||
gulp.task(
|
||||
"tests",
|
||||
"Builds the test infrastructure using the built compiler",
|
||||
[runJs]);
|
||||
[runJs, tsserverlibraryDts]);
|
||||
|
||||
gulp.task(
|
||||
"runtests-parallel",
|
||||
"Runs all the tests in parallel using the built run.js file. Optional arguments are: --t[ests]=category1|category2|... --d[ebug]=true.",
|
||||
["build-rules", "tests"],
|
||||
() => runConsoleTests(runJs, "min", /*runInParallel*/ true));
|
||||
["build-rules", "tests", "services", tsserverlibraryDts],
|
||||
() => runConsoleTests(runJs, "min", /*runInParallel*/ true, /*watchMode*/ false));
|
||||
|
||||
gulp.task(
|
||||
"runtests",
|
||||
"Runs the tests using the built run.js file. Optional arguments are: --t[ests]=regex --r[eporter]=[list|spec|json|<more>] --d[ebug]=true --color[s]=false --lint=true.",
|
||||
["build-rules", "tests"],
|
||||
() => runConsoleTests(runJs, "mocha-fivemat-progress-reporter", /*runInParallel*/ false));
|
||||
["build-rules", "tests", "services", tsserverlibraryDts],
|
||||
() => runConsoleTests(runJs, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ false));
|
||||
|
||||
const webTestServerProject = "tests/webTestServer.tsconfig.json";
|
||||
const webTestServerJs = "tests/webTestServer.js";
|
||||
gulp.task(webTestServerJs, /*help*/ false, [typescriptServicesJs], () => project.compile(webTestServerProject, { typescript: "built" }));
|
||||
gulp.task("clean:" + webTestServerJs, /*help*/ false, () => project.clean(webTestServerProject));
|
||||
gulp.task(webTestServerJs, /*help*/ false, useCompilerDeps, () => project.compile(webTestServerProject, { typescript: useCompiler }));
|
||||
gulp.task(`clean:${webTestServerJs}`, /*help*/ false, () => project.clean(webTestServerProject));
|
||||
|
||||
const bundlePath = path.resolve("built/local/bundle.js");
|
||||
|
||||
@@ -392,8 +415,8 @@ gulp.task(
|
||||
// Webhost
|
||||
const webtscProject = "tests/webhost/webtsc.tsconfig.json";
|
||||
const webtscJs = "tests/webhost/webtsc.js";
|
||||
gulp.task(webtscJs, /*help*/ false, [typescriptServicesJs], () => project.compile(webtscProject, { typescript: "built" }));
|
||||
gulp.task("clean:" + webtscJs, /*help*/ false, () => project.clean(webtscProject));
|
||||
gulp.task(webtscJs, /*help*/ false, useCompilerDeps, () => project.compile(webtscProject, { typescript: useCompiler }));
|
||||
gulp.task(`clean:${webtscJs}`, /*help*/ false, () => project.clean(webtscProject));
|
||||
|
||||
gulp.task("webhost", "Builds the tsc web host", [webtscJs], () =>
|
||||
gulp.src("built/local/lib.d.ts")
|
||||
@@ -402,8 +425,8 @@ gulp.task("webhost", "Builds the tsc web host", [webtscJs], () =>
|
||||
// Perf compiler
|
||||
const perftscProject = "tests/perftsc.tsconfig.json";
|
||||
const perftscJs = "built/local/perftsc.js";
|
||||
gulp.task(perftscJs, /*help*/ false, [typescriptServicesJs], () => project.compile(perftscProject, { typescript: "built" }));
|
||||
gulp.task("clean:" + perftscJs, /*help*/ false, () => project.clean(perftscProject));
|
||||
gulp.task(perftscJs, /*help*/ false, useCompilerDeps, () => project.compile(perftscProject, { typescript: useCompiler }));
|
||||
gulp.task(`clean:${perftscJs}`, /*help*/ false, () => project.clean(perftscProject));
|
||||
|
||||
gulp.task(
|
||||
"perftsc",
|
||||
@@ -423,7 +446,7 @@ gulp.task(loggedIOJs, /*help*/ false, [], (done) => {
|
||||
const instrumenterProject = "src/instrumenter/tsconfig.json";
|
||||
const instrumenterJs = "built/local/instrumenter.js";
|
||||
gulp.task(instrumenterJs, /*help*/ false, () => project.compile(instrumenterProject));
|
||||
gulp.task("clean:" + instrumenterJs, /*help*/ false, () => project.clean(instrumenterProject));
|
||||
gulp.task(`clean:${instrumenterJs}`, /*help*/ false, () => project.clean(instrumenterProject));
|
||||
|
||||
gulp.task(
|
||||
"tsc-instrumented",
|
||||
@@ -479,20 +502,37 @@ gulp.task(
|
||||
gulp.task(
|
||||
"watch-tsc",
|
||||
/*help*/ false,
|
||||
["watch-diagnostics", "watch-lib", typescriptServicesJs],
|
||||
() => project.watch(tscProject, { typescript: "built" }));
|
||||
["watch-diagnostics", "watch-lib"].concat(useCompilerDeps),
|
||||
() => project.watch(tscProject, { typescript: useCompiler }));
|
||||
|
||||
const watchServicesPatterns = [
|
||||
"src/compiler/**/*",
|
||||
"src/jsTypings/**/*",
|
||||
"src/services/**/*"
|
||||
];
|
||||
|
||||
gulp.task(
|
||||
"watch-services",
|
||||
/*help*/ false,
|
||||
["watch-diagnostics", "watch-lib", typescriptServicesJs],
|
||||
() => project.watch(servicesProject, { typescript: "built" }));
|
||||
["watch-diagnostics", "watch-lib"],
|
||||
() => gulp.watch(watchServicesPatterns, ["services"]));
|
||||
|
||||
const watchLsslPatterns = [
|
||||
...watchServicesPatterns,
|
||||
"src/server/**/*",
|
||||
"src/tsserver/tsconfig.json"
|
||||
];
|
||||
|
||||
gulp.task(
|
||||
"watch-lssl",
|
||||
/*help*/ false,
|
||||
() => gulp.watch(watchLsslPatterns, ["lssl"]));
|
||||
|
||||
gulp.task(
|
||||
"watch-server",
|
||||
/*help*/ false,
|
||||
["watch-diagnostics", "watch-lib", typescriptServicesJs],
|
||||
() => project.watch(tsserverProject, { typescript: "built" }));
|
||||
["watch-diagnostics", "watch-lib"].concat(useCompilerDeps),
|
||||
() => project.watch(tsserverProject, { typescript: useCompiler }));
|
||||
|
||||
gulp.task(
|
||||
"watch-local",
|
||||
@@ -500,22 +540,64 @@ gulp.task(
|
||||
["watch-lib", "watch-tsc", "watch-services", "watch-server"]);
|
||||
|
||||
gulp.task(
|
||||
"watch",
|
||||
"Watches for changes to the build inputs for built/local/run.js executes runtests-parallel.",
|
||||
[typescriptServicesJs],
|
||||
() => project.watch(testRunnerProject, { typescript: "built" }, ["runtests-parallel"]));
|
||||
"watch-runner",
|
||||
/*help*/ false,
|
||||
useCompilerDeps,
|
||||
() => project.watch(testRunnerProject, { typescript: useCompiler }));
|
||||
|
||||
gulp.task("clean-built", /*help*/ false, ["clean:" + diagnosticInformationMapTs], () => del(["built"]));
|
||||
const watchPatterns = [
|
||||
runJs,
|
||||
typescriptDts,
|
||||
tsserverlibraryDts
|
||||
];
|
||||
|
||||
gulp.task(
|
||||
"watch",
|
||||
"Watches for changes to the build inputs for built/local/run.js, then executes runtests-parallel.",
|
||||
["build-rules", "watch-runner", "watch-services", "watch-lssl"],
|
||||
() => {
|
||||
/** @type {CancelSource | undefined} */
|
||||
let runTestsSource;
|
||||
|
||||
const fn = debounce(() => {
|
||||
runTests().catch(error => {
|
||||
if (error instanceof CancelError) {
|
||||
log.warn("Operation was canceled");
|
||||
}
|
||||
else {
|
||||
log.error(error);
|
||||
}
|
||||
});
|
||||
}, /*timeout*/ 100, { max: 500 });
|
||||
|
||||
gulp.watch(watchPatterns, () => project.wait().then(fn));
|
||||
|
||||
// NOTE: gulp.watch is far too slow when watching tests/cases/**/* as it first enumerates *every* file
|
||||
const testFilePattern = /(\.ts|[\\/]tsconfig\.json)$/;
|
||||
fs.watch("tests/cases", { recursive: true }, (_, file) => {
|
||||
if (testFilePattern.test(file)) project.wait().then(fn);
|
||||
});
|
||||
|
||||
function runTests() {
|
||||
if (runTestsSource) runTestsSource.cancel();
|
||||
runTestsSource = new CancelSource();
|
||||
return cmdLineOptions.tests || cmdLineOptions.failed
|
||||
? runConsoleTests(runJs, "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ true, runTestsSource.token)
|
||||
: runConsoleTests(runJs, "min", /*runInParallel*/ true, /*watchMode*/ true, runTestsSource.token);
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task("clean-built", /*help*/ false, [`clean:${diagnosticInformationMapTs}`], () => del(["built"]));
|
||||
gulp.task(
|
||||
"clean",
|
||||
"Cleans the compiler output, declare files, and tests",
|
||||
[
|
||||
"clean:" + importDefinitelyTypedTestsJs,
|
||||
"clean:" + webtscJs,
|
||||
"clean:" + perftscJs,
|
||||
"clean:" + instrumenterJs,
|
||||
"clean:" + webTestServerJs,
|
||||
"clean-scripts",
|
||||
`clean:${importDefinitelyTypedTestsJs}`,
|
||||
`clean:${webtscJs}`,
|
||||
`clean:${perftscJs}`,
|
||||
`clean:${instrumenterJs}`,
|
||||
`clean:${webTestServerJs}`,
|
||||
"clean:scripts",
|
||||
"clean-rules",
|
||||
"clean-built"
|
||||
]);
|
||||
+150
-50
@@ -9,6 +9,9 @@ const fold = require("travis-fold");
|
||||
const ts = require("./lib/typescript");
|
||||
const del = require("del");
|
||||
const getDirSize = require("./scripts/build/getDirSize");
|
||||
const { base64VLQFormatEncode } = require("./scripts/build/sourcemaps");
|
||||
const needsUpdate = require("./scripts/build/needsUpdate");
|
||||
const { flatten } = require("./scripts/build/project");
|
||||
|
||||
// add node_modules to path so we don't need global modules, prefer the modules by adding them first
|
||||
var nodeModulesPathPrefix = path.resolve("./node_modules/.bin/") + path.delimiter;
|
||||
@@ -64,9 +67,14 @@ Paths.typesMapOutput = "built/local/typesMap.json";
|
||||
Paths.typescriptFile = "built/local/typescript.js";
|
||||
Paths.servicesFile = "built/local/typescriptServices.js";
|
||||
Paths.servicesDefinitionFile = "built/local/typescriptServices.d.ts";
|
||||
Paths.servicesOutFile = "built/local/typescriptServices.out.js";
|
||||
Paths.servicesDefinitionOutFile = "built/local/typescriptServices.out.d.ts";
|
||||
Paths.typescriptDefinitionFile = "built/local/typescript.d.ts";
|
||||
Paths.typescriptStandaloneDefinitionFile = "built/local/typescript_standalone.d.ts";
|
||||
Paths.tsserverLibraryFile = "built/local/tsserverlibrary.js";
|
||||
Paths.tsserverLibraryDefinitionFile = "built/local/tsserverlibrary.d.ts";
|
||||
Paths.tsserverLibraryOutFile = "built/local/tsserverlibrary.out.js";
|
||||
Paths.tsserverLibraryDefinitionOutFile = "built/local/tsserverlibrary.out.d.ts";
|
||||
Paths.baselines = {};
|
||||
Paths.baselines.local = "tests/baselines/local";
|
||||
Paths.baselines.localTest262 = "tests/baselines/test262/local";
|
||||
@@ -101,7 +109,9 @@ const ConfigFileFor = {
|
||||
runjs: "src/testRunner",
|
||||
lint: "scripts/tslint",
|
||||
scripts: "scripts",
|
||||
all: "src"
|
||||
all: "src",
|
||||
typescriptServices: "built/local/typescriptServices.tsconfig.json",
|
||||
tsserverLibrary: "built/local/tsserverlibrary.tsconfig.json",
|
||||
};
|
||||
|
||||
const ExpectedLKGFiles = [
|
||||
@@ -124,13 +134,18 @@ desc("Builds the full compiler and services");
|
||||
task(TaskNames.local, [
|
||||
TaskNames.buildFoldStart,
|
||||
TaskNames.coreBuild,
|
||||
Paths.servicesDefinitionFile,
|
||||
Paths.typescriptFile,
|
||||
Paths.typescriptDefinitionFile,
|
||||
Paths.typescriptStandaloneDefinitionFile,
|
||||
Paths.tsserverLibraryDefinitionFile,
|
||||
TaskNames.localize,
|
||||
TaskNames.buildFoldEnd
|
||||
]);
|
||||
|
||||
task("default", [TaskNames.local]);
|
||||
|
||||
const RunTestsPrereqs = [TaskNames.lib, Paths.servicesDefinitionFile, Paths.tsserverLibraryDefinitionFile];
|
||||
const RunTestsPrereqs = [TaskNames.lib, Paths.servicesDefinitionFile, Paths.typescriptDefinitionFile, Paths.tsserverLibraryDefinitionFile];
|
||||
desc("Runs all the tests in parallel using the built run.js file. Optional arguments are: t[ests]=category1|category2|... d[ebug]=true.");
|
||||
task(TaskNames.runtestsParallel, RunTestsPrereqs, function () {
|
||||
tsbuild([ConfigFileFor.runjs], true, () => {
|
||||
@@ -172,6 +187,9 @@ task(TaskNames.lkg, [
|
||||
TaskNames.release,
|
||||
TaskNames.local,
|
||||
Paths.servicesDefinitionFile,
|
||||
Paths.typescriptFile,
|
||||
Paths.typescriptDefinitionFile,
|
||||
Paths.typescriptStandaloneDefinitionFile,
|
||||
Paths.tsserverLibraryDefinitionFile,
|
||||
Paths.releaseCompiler,
|
||||
...libraryTargets
|
||||
@@ -333,64 +351,146 @@ file(Paths.diagnosticInformationMap, [Paths.diagnosticMessagesJson], function ()
|
||||
});
|
||||
}, { async: true });
|
||||
|
||||
// tsserverlibrary.d.ts
|
||||
file(Paths.tsserverLibraryDefinitionFile, [TaskNames.coreBuild], function() {
|
||||
const sources = ["compiler.d.ts", "jsTyping.d.ts", "services.d.ts", "server.d.ts"].map(f => path.join(Paths.builtLocal, f));
|
||||
let output = "";
|
||||
for (const f of sources) {
|
||||
output = output + "\n" + removeConstModifierFromEnumDeclarations(readFileSync(f));
|
||||
}
|
||||
output = output + "\nexport = ts;\nexport as namespace ts;";
|
||||
fs.writeFileSync(Paths.tsserverLibraryDefinitionFile, output, { encoding: "utf-8" });
|
||||
file(ConfigFileFor.tsserverLibrary, [], function () {
|
||||
flatten("src/tsserver/tsconfig.json", ConfigFileFor.tsserverLibrary, {
|
||||
exclude: ["src/tsserver/server.ts"],
|
||||
compilerOptions: {
|
||||
"removeComments": false,
|
||||
"stripInternal": true,
|
||||
"declarationMap": false,
|
||||
"outFile": "tsserverlibrary.out.js"
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// typescriptservices.d.ts
|
||||
file(Paths.servicesDefinitionFile, [TaskNames.coreBuild], function() {
|
||||
// Generate a config file
|
||||
const files = [];
|
||||
recur(`src/services/tsconfig.json`);
|
||||
// tsserverlibrary.js
|
||||
// tsserverlibrary.d.ts
|
||||
file(Paths.tsserverLibraryFile, [TaskNames.coreBuild, ConfigFileFor.tsserverLibrary], function() {
|
||||
tsbuild(ConfigFileFor.tsserverLibrary, false, () => {
|
||||
if (needsUpdate([Paths.tsserverLibraryOutFile, Paths.tsserverLibraryDefinitionOutFile], [Paths.tsserverLibraryFile, Paths.tsserverLibraryDefinitionFile])) {
|
||||
const copyright = readFileSync(Paths.copyright);
|
||||
|
||||
const config = {
|
||||
extends: "../../src/tsconfig-base",
|
||||
let libraryDefinitionContent = readFileSync(Paths.tsserverLibraryDefinitionOutFile);
|
||||
libraryDefinitionContent = copyright + removeConstModifierFromEnumDeclarations(libraryDefinitionContent);
|
||||
libraryDefinitionContent += "\nexport = ts;\nexport as namespace ts;";
|
||||
fs.writeFileSync(Paths.tsserverLibraryDefinitionFile, libraryDefinitionContent, "utf8");
|
||||
|
||||
let libraryContent = readFileSync(Paths.tsserverLibraryOutFile);
|
||||
libraryContent = copyright + libraryContent;
|
||||
fs.writeFileSync(Paths.tsserverLibraryFile, libraryContent, "utf8");
|
||||
|
||||
// adjust source map for tsserverlibrary.js
|
||||
let libraryMapContent = readFileSync(Paths.tsserverLibraryOutFile + ".map");
|
||||
const map = JSON.parse(libraryMapContent);
|
||||
const lineStarts = /**@type {*}*/(ts).computeLineStarts(copyright);
|
||||
let prependMappings = "";
|
||||
for (let i = 1; i < lineStarts.length; i++) {
|
||||
prependMappings += ";";
|
||||
}
|
||||
|
||||
const offset = copyright.length - lineStarts[lineStarts.length - 1];
|
||||
if (offset > 0) {
|
||||
prependMappings += base64VLQFormatEncode(offset) + ",";
|
||||
}
|
||||
|
||||
const outputMap = {
|
||||
version: map.version,
|
||||
file: map.file,
|
||||
sources: map.sources,
|
||||
sourceRoot: map.sourceRoot,
|
||||
mappings: prependMappings + map.mappings,
|
||||
names: map.names,
|
||||
sourcesContent: map.sourcesContent
|
||||
};
|
||||
|
||||
libraryMapContent = JSON.stringify(outputMap);
|
||||
fs.writeFileSync(Paths.tsserverLibraryFile + ".map", libraryMapContent);
|
||||
}
|
||||
complete();
|
||||
});
|
||||
}, { async: true });
|
||||
task(Paths.tsserverLibraryDefinitionFile, [Paths.tsserverLibraryFile]);
|
||||
|
||||
file(ConfigFileFor.typescriptServices, [], function () {
|
||||
flatten("src/services/tsconfig.json", ConfigFileFor.typescriptServices, {
|
||||
compilerOptions: {
|
||||
"removeComments": false,
|
||||
"stripInternal": true,
|
||||
"outFile": "typescriptServices.js"
|
||||
},
|
||||
files
|
||||
};
|
||||
"declarationMap": false,
|
||||
"outFile": "typescriptServices.out.js"
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const configFilePath = `built/local/typescriptServices.tsconfig.json`;
|
||||
fs.writeFileSync(configFilePath, JSON.stringify(config, undefined, 2));
|
||||
tsbuild(configFilePath, false, () => {
|
||||
const servicesContent = readFileSync(Paths.servicesDefinitionFile);
|
||||
const servicesContentWithoutConstEnums = removeConstModifierFromEnumDeclarations(servicesContent);
|
||||
fs.writeFileSync(Paths.servicesDefinitionFile, servicesContentWithoutConstEnums);
|
||||
|
||||
// Also build typescript.js, typescript.js.map, and typescript.d.ts
|
||||
// typescriptServices.js
|
||||
// typescriptServices.d.ts
|
||||
file(Paths.servicesFile, [TaskNames.coreBuild, ConfigFileFor.typescriptServices], function() {
|
||||
tsbuild(ConfigFileFor.typescriptServices, false, () => {
|
||||
if (needsUpdate([Paths.servicesOutFile, Paths.servicesDefinitionOutFile], [Paths.servicesFile, Paths.servicesDefinitionFile])) {
|
||||
const copyright = readFileSync(Paths.copyright);
|
||||
|
||||
let servicesDefinitionContent = readFileSync(Paths.servicesDefinitionOutFile);
|
||||
servicesDefinitionContent = copyright + removeConstModifierFromEnumDeclarations(servicesDefinitionContent);
|
||||
fs.writeFileSync(Paths.servicesDefinitionFile, servicesDefinitionContent, "utf8");
|
||||
|
||||
let servicesContent = readFileSync(Paths.servicesOutFile);
|
||||
servicesContent = copyright + servicesContent;
|
||||
fs.writeFileSync(Paths.servicesFile, servicesContent, "utf8");
|
||||
|
||||
// adjust source map for typescriptServices.js
|
||||
let servicesMapContent = readFileSync(Paths.servicesOutFile + ".map");
|
||||
const map = JSON.parse(servicesMapContent);
|
||||
const lineStarts = /**@type {*}*/(ts).computeLineStarts(copyright);
|
||||
let prependMappings = "";
|
||||
for (let i = 1; i < lineStarts.length; i++) {
|
||||
prependMappings += ";";
|
||||
}
|
||||
|
||||
const offset = copyright.length - lineStarts[lineStarts.length - 1];
|
||||
if (offset > 0) {
|
||||
prependMappings += base64VLQFormatEncode(offset) + ",";
|
||||
}
|
||||
|
||||
const outputMap = {
|
||||
version: map.version,
|
||||
file: map.file,
|
||||
sources: map.sources,
|
||||
sourceRoot: map.sourceRoot,
|
||||
mappings: prependMappings + map.mappings,
|
||||
names: map.names,
|
||||
sourcesContent: map.sourcesContent
|
||||
};
|
||||
|
||||
servicesMapContent = JSON.stringify(outputMap);
|
||||
fs.writeFileSync(Paths.servicesFile + ".map", servicesMapContent);
|
||||
}
|
||||
|
||||
complete();
|
||||
});
|
||||
}, { async: true });
|
||||
task(Paths.servicesDefinitionFile, [Paths.servicesFile]);
|
||||
|
||||
// typescript.js
|
||||
// typescript.d.ts
|
||||
file(Paths.typescriptFile, [Paths.servicesFile], function() {
|
||||
if (needsUpdate([Paths.servicesFile, Paths.servicesDefinitionFile], [Paths.typescriptFile, Paths.typescriptDefinitionFile])) {
|
||||
jake.cpR(Paths.servicesFile, Paths.typescriptFile);
|
||||
if (fs.existsSync(Paths.servicesFile + ".map")) {
|
||||
jake.cpR(Paths.servicesFile + ".map", Paths.typescriptFile + ".map");
|
||||
}
|
||||
|
||||
fs.writeFileSync(Paths.typescriptDefinitionFile, servicesContentWithoutConstEnums + "\r\nexport = ts", { encoding: "utf-8" });
|
||||
// And typescript_standalone.d.ts
|
||||
fs.writeFileSync(Paths.typescriptStandaloneDefinitionFile, servicesContentWithoutConstEnums.replace(/declare (namespace|module) ts(\..+)? \{/g, 'declare module "typescript" {'), { encoding: "utf-8"});
|
||||
|
||||
complete();
|
||||
});
|
||||
|
||||
function recur(configPath) {
|
||||
const cfgFile = readJson(configPath);
|
||||
if (cfgFile.references) {
|
||||
for (const ref of cfgFile.references) {
|
||||
recur(path.join(path.dirname(configPath), ref.path, "tsconfig.json"));
|
||||
}
|
||||
}
|
||||
for (const file of cfgFile.files) {
|
||||
files.push(path.join(`../../`, path.dirname(configPath), file));
|
||||
}
|
||||
const content = readFileSync(Paths.servicesDefinitionFile);
|
||||
fs.writeFileSync(Paths.typescriptDefinitionFile, content + "\r\nexport = ts;", { encoding: "utf-8" });
|
||||
}
|
||||
}, { async: true });
|
||||
});
|
||||
task(Paths.typescriptDefinitionFile, [Paths.typescriptFile]);
|
||||
|
||||
// typescript_standalone.d.ts
|
||||
file(Paths.typescriptStandaloneDefinitionFile, [Paths.servicesDefinitionFile], function() {
|
||||
if (needsUpdate(Paths.servicesDefinitionFile, Paths.typescriptStandaloneDefinitionFile)) {
|
||||
const content = readFileSync(Paths.servicesDefinitionFile);
|
||||
fs.writeFileSync(Paths.typescriptStandaloneDefinitionFile, content.replace(/declare (namespace|module) ts(\..+)? \{/g, 'declare module "typescript" {'), { encoding: "utf-8"});
|
||||
}
|
||||
});
|
||||
|
||||
function getLibraryTargets() {
|
||||
/** @type {{ libs: string[], paths?: Record<string, string>, sources?: Record<string, string[]> }} */
|
||||
@@ -765,4 +865,4 @@ function getDiffTool() {
|
||||
*/
|
||||
function removeConstModifierFromEnumDeclarations(text) {
|
||||
return text.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4');
|
||||
}
|
||||
}
|
||||
Generated
+1181
-1180
File diff suppressed because it is too large
Load Diff
+15
-101
@@ -1,120 +1,34 @@
|
||||
// @ts-check
|
||||
const Browserify = require("browserify");
|
||||
const Vinyl = require("vinyl");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const convertMap = require("convert-source-map");
|
||||
const applySourceMap = require("vinyl-sourcemaps-apply");
|
||||
const { Transform, Readable } = require("stream");
|
||||
const browserify = require("browserify");
|
||||
const Vinyl = require("./vinyl");
|
||||
const { Transform } = require("stream");
|
||||
const { streamFromFile } = require("./utils");
|
||||
const { replaceContents } = require("./sourcemaps");
|
||||
|
||||
module.exports = browserify;
|
||||
module.exports = browserifyFile;
|
||||
|
||||
/**
|
||||
* @param {import("browserify").Options} [opts]
|
||||
*/
|
||||
function browserify(opts) {
|
||||
function browserifyFile(opts) {
|
||||
return new Transform({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {string | Buffer | File} input
|
||||
* @param {string | Buffer | Vinyl} input
|
||||
*/
|
||||
transform(input, _, cb) {
|
||||
if (typeof input === "string" || Buffer.isBuffer(input)) return cb(new Error("Only Vinyl files are supported."));
|
||||
try {
|
||||
const sourceMap = input.sourceMap;
|
||||
const cwd = input.cwd || process.cwd();
|
||||
const base = input.base || cwd;
|
||||
const output = /**@type {File}*/(new Vinyl({ path: input.path, base: input.base }));
|
||||
const stream = streamFromFile(input);
|
||||
const b = new Browserify(Object.assign({}, opts, { debug: !!sourceMap, basedir: input.base }));
|
||||
b.add(stream, { file: input.path, basedir: input.base });
|
||||
b.bundle((err, contents) => {
|
||||
if (err) return cb(err);
|
||||
output.contents = contents;
|
||||
if (sourceMap) {
|
||||
output.sourceMap = typeof sourceMap === "string" ? JSON.parse(sourceMap) : sourceMap;
|
||||
const sourceRoot = output.sourceMap.sourceRoot;
|
||||
makeAbsoluteSourceMap(cwd, base, output.sourceMap);
|
||||
const stringContents = contents.toString("utf8");
|
||||
const newSourceMapConverter = convertMap.fromSource(stringContents);
|
||||
if (newSourceMapConverter) {
|
||||
const newSourceMap = newSourceMapConverter.toObject();
|
||||
makeAbsoluteSourceMap(cwd, base, newSourceMap);
|
||||
applySourceMap(output, newSourceMap);
|
||||
makeRelativeSourceMap(cwd, base, sourceRoot, output.sourceMap);
|
||||
output.contents = new Buffer(convertMap.removeComments(stringContents), "utf8");
|
||||
}
|
||||
}
|
||||
cb(null, output);
|
||||
});
|
||||
browserify(Object.assign({}, opts, { debug: !!input.sourceMap, basedir: input.base }))
|
||||
.add(streamFromFile(input), { file: input.path, basedir: input.base })
|
||||
.bundle((err, contents) => {
|
||||
if (err) return cb(err);
|
||||
cb(null, replaceContents(input, contents));
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
cb(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @param {string | undefined} base
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*
|
||||
* @typedef RawSourceMap
|
||||
* @property {string} version
|
||||
* @property {string} file
|
||||
* @property {string} [sourceRoot]
|
||||
* @property {string[]} sources
|
||||
* @property {string[]} [sourcesContents]
|
||||
* @property {string} mappings
|
||||
* @property {string[]} [names]
|
||||
*/
|
||||
function makeAbsoluteSourceMap(cwd = process.cwd(), base = "", sourceMap) {
|
||||
const sourceRoot = sourceMap.sourceRoot || "";
|
||||
const resolvedBase = path.resolve(cwd, base);
|
||||
const resolvedSourceRoot = path.resolve(resolvedBase, sourceRoot);
|
||||
sourceMap.file = path.resolve(resolvedBase, sourceMap.file).replace(/\\/g, "/");
|
||||
sourceMap.sources = sourceMap.sources.map(source => path.resolve(resolvedSourceRoot, source).replace(/\\/g, "/"));
|
||||
sourceMap.sourceRoot = "";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @param {string | undefined} base
|
||||
* @param {string} sourceRoot
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*/
|
||||
function makeRelativeSourceMap(cwd = process.cwd(), base = "", sourceRoot, sourceMap) {
|
||||
makeAbsoluteSourceMap(cwd, base, sourceMap);
|
||||
const resolvedBase = path.resolve(cwd, base);
|
||||
const resolvedSourceRoot = path.resolve(resolvedBase, sourceRoot);
|
||||
sourceMap.file = path.relative(resolvedBase, sourceMap.file).replace(/\\/g, "/");
|
||||
sourceMap.sources = sourceMap.sources.map(source => path.relative(resolvedSourceRoot, source).replace(/\\/g, "/"));
|
||||
sourceMap.sourceRoot = sourceRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {File} file
|
||||
*/
|
||||
function streamFromFile(file) {
|
||||
return file.isBuffer() ? streamFromBuffer(file.contents) :
|
||||
file.isStream() ? file.contents :
|
||||
fs.createReadStream(file.path, { autoClose: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Buffer} buffer
|
||||
*/
|
||||
function streamFromBuffer(buffer) {
|
||||
return new Readable({
|
||||
read() {
|
||||
this.push(buffer);
|
||||
this.push(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import("vinyl") & { sourceMap?: any }} File
|
||||
*/
|
||||
void 0;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// @ts-check
|
||||
const symSource = Symbol("CancelToken.source");
|
||||
const symToken = Symbol("CancelSource.token");
|
||||
const symCancellationRequested = Symbol("CancelSource.cancellationRequested");
|
||||
const symCancellationCallbacks = Symbol("CancelSource.cancellationCallbacks");
|
||||
|
||||
class CancelSource {
|
||||
constructor() {
|
||||
this[symCancellationRequested] = false;
|
||||
this[symCancellationCallbacks] = [];
|
||||
}
|
||||
|
||||
/** @type {CancelToken} */
|
||||
get token() {
|
||||
return this[symToken] || (this[symToken] = new CancelToken(this));
|
||||
}
|
||||
|
||||
cancel() {
|
||||
if (!this[symCancellationRequested]) {
|
||||
this[symCancellationRequested] = true;
|
||||
for (const callback of this[symCancellationCallbacks]) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.CancelSource = CancelSource;
|
||||
|
||||
class CancelToken {
|
||||
/**
|
||||
* @param {CancelSource} source
|
||||
*/
|
||||
constructor(source) {
|
||||
if (source[symToken]) return source[symToken];
|
||||
this[symSource] = source;
|
||||
}
|
||||
|
||||
/** @type {boolean} */
|
||||
get cancellationRequested() {
|
||||
return this[symSource][symCancellationRequested];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {() => void} callback
|
||||
*/
|
||||
subscribe(callback) {
|
||||
const source = this[symSource];
|
||||
if (source[symCancellationRequested]) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
source[symCancellationCallbacks].push(callback);
|
||||
|
||||
return {
|
||||
unsubscribe() {
|
||||
const index = source[symCancellationCallbacks].indexOf(callback);
|
||||
if (index !== -1) source[symCancellationCallbacks].splice(index, 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.CancelToken = CancelToken;
|
||||
|
||||
class CancelError extends Error {
|
||||
constructor(message = "Operation was canceled") {
|
||||
super(message);
|
||||
this.name = "CancelError";
|
||||
}
|
||||
}
|
||||
exports.CancelError = CancelError;
|
||||
@@ -0,0 +1,31 @@
|
||||
// @ts-check
|
||||
module.exports = debounce;
|
||||
|
||||
/**
|
||||
* @param {() => void} cb
|
||||
* @param {number} timeout
|
||||
* @param {DebounceOptions} [opts]
|
||||
*
|
||||
* @typedef DebounceOptions
|
||||
* @property {number} [max]
|
||||
*/
|
||||
function debounce(cb, timeout, opts = {}) {
|
||||
if (timeout < 10) timeout = 10;
|
||||
let max = opts.max || 10;
|
||||
if (max < timeout) max = timeout;
|
||||
let minTimer;
|
||||
let maxTimer;
|
||||
return trigger;
|
||||
|
||||
function trigger() {
|
||||
if (max > timeout && !maxTimer) maxTimer = setTimeout(done, max);
|
||||
if (minTimer) clearTimeout(minTimer);
|
||||
minTimer = setTimeout(done, timeout);
|
||||
}
|
||||
|
||||
function done() {
|
||||
if (maxTimer) maxTimer = void clearTimeout(maxTimer);
|
||||
if (minTimer) minTimer = void clearTimeout(minTimer);
|
||||
cb();
|
||||
}
|
||||
}
|
||||
+16
-3
@@ -3,6 +3,7 @@ const cp = require("child_process");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
const isWin = /^win/.test(process.platform);
|
||||
const chalk = require("./chalk");
|
||||
const { CancelToken, CancelError } = require("./cancellation");
|
||||
|
||||
module.exports = exec;
|
||||
|
||||
@@ -10,8 +11,11 @@ module.exports = exec;
|
||||
* Executes the provided command once with the supplied arguments.
|
||||
* @param {string} cmd
|
||||
* @param {string[]} args
|
||||
* @param {object} [options]
|
||||
* @param {boolean} [options.ignoreExitCode]
|
||||
* @param {ExecOptions} [options]
|
||||
*
|
||||
* @typedef ExecOptions
|
||||
* @property {boolean} [ignoreExitCode]
|
||||
* @property {CancelToken} [cancelToken]
|
||||
*/
|
||||
function exec(cmd, args, options = {}) {
|
||||
return /**@type {Promise<{exitCode: number}>}*/(new Promise((resolve, reject) => {
|
||||
@@ -20,7 +24,13 @@ function exec(cmd, args, options = {}) {
|
||||
const subshellFlag = isWin ? "/c" : "-c";
|
||||
const command = isWin ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`];
|
||||
const ex = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true });
|
||||
const subscription = options.cancelToken && options.cancelToken.subscribe(() => {
|
||||
ex.kill("SIGINT");
|
||||
ex.kill("SIGTERM");
|
||||
reject(new CancelError());
|
||||
});
|
||||
ex.on("exit", exitCode => {
|
||||
subscription && subscription.unsubscribe();
|
||||
if (exitCode === 0 || options.ignoreExitCode) {
|
||||
resolve({ exitCode });
|
||||
}
|
||||
@@ -28,7 +38,10 @@ function exec(cmd, args, options = {}) {
|
||||
reject(new Error(`Process exited with code: ${exitCode}`));
|
||||
}
|
||||
});
|
||||
ex.on("error", reject);
|
||||
ex.on("error", error => {
|
||||
subscription && subscription.unsubscribe();
|
||||
reject(error);
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ const os = require("os");
|
||||
|
||||
/** @type {CommandLineOptions} */
|
||||
module.exports = minimist(process.argv.slice(2), {
|
||||
boolean: ["debug", "inspect", "light", "colors", "lint", "soft", "fix", "failed", "keepFailed"],
|
||||
boolean: ["debug", "dirty", "inspect", "light", "colors", "lint", "lkg", "soft", "fix", "failed", "keepFailed"],
|
||||
string: ["browser", "tests", "host", "reporter", "stackTraceLimit", "timeout"],
|
||||
alias: {
|
||||
"b": "browser",
|
||||
@@ -33,17 +33,21 @@ module.exports = minimist(process.argv.slice(2), {
|
||||
fix: process.env.fix || process.env.f,
|
||||
workers: process.env.workerCount || os.cpus().length,
|
||||
failed: false,
|
||||
keepFailed: false
|
||||
keepFailed: false,
|
||||
lkg: false,
|
||||
dirty: false
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @typedef TypedOptions
|
||||
* @property {boolean} debug
|
||||
* @property {boolean} dirty
|
||||
* @property {boolean} inspect
|
||||
* @property {boolean} light
|
||||
* @property {boolean} colors
|
||||
* @property {boolean} lint
|
||||
* @property {boolean} lkg
|
||||
* @property {boolean} soft
|
||||
* @property {boolean} fix
|
||||
* @property {string} browser
|
||||
@@ -56,7 +60,7 @@ module.exports = minimist(process.argv.slice(2), {
|
||||
* @property {string|number} timeout
|
||||
* @property {boolean} failed
|
||||
* @property {boolean} keepFailed
|
||||
*
|
||||
*
|
||||
* @typedef {import("minimist").ParsedArgs & TypedOptions} CommandLineOptions
|
||||
*/
|
||||
void 0;
|
||||
@@ -0,0 +1,66 @@
|
||||
// @ts-check
|
||||
const stream = require("stream");
|
||||
const Vinyl = require("./vinyl");
|
||||
const ts = require("../../lib/typescript");
|
||||
const fs = require("fs");
|
||||
const { base64VLQFormatEncode } = require("./sourcemaps");
|
||||
|
||||
module.exports = exports = prepend;
|
||||
|
||||
/**
|
||||
* @param {string | ((file: Vinyl) => string)} data
|
||||
*/
|
||||
function prepend(data) {
|
||||
return new stream.Transform({
|
||||
objectMode: true,
|
||||
/**
|
||||
* @param {string | Buffer | Vinyl} input
|
||||
* @param {(error: Error, data?: any) => void} cb
|
||||
*/
|
||||
transform(input, _, cb) {
|
||||
if (typeof input === "string" || Buffer.isBuffer(input)) return cb(new Error("Only Vinyl files are supported."));
|
||||
if (!input.isBuffer()) return cb(new Error("Streams not supported."));
|
||||
try {
|
||||
const output = input.clone();
|
||||
const prependContent = typeof data === "function" ? data(input) : data;
|
||||
output.contents = Buffer.concat([Buffer.from(prependContent, "utf8"), input.contents]);
|
||||
if (input.sourceMap) {
|
||||
if (typeof input.sourceMap === "string") input.sourceMap = /**@type {import("./sourcemaps").RawSourceMap}*/(JSON.parse(input.sourceMap));
|
||||
const lineStarts = /**@type {*}*/(ts).computeLineStarts(prependContent);
|
||||
let prependMappings = "";
|
||||
for (let i = 1; i < lineStarts.length; i++) {
|
||||
prependMappings += ";";
|
||||
}
|
||||
const offset = prependContent.length - lineStarts[lineStarts.length - 1];
|
||||
if (offset > 0) {
|
||||
prependMappings += base64VLQFormatEncode(offset) + ",";
|
||||
}
|
||||
output.sourceMap = {
|
||||
version: input.sourceMap.version,
|
||||
file: input.sourceMap.file,
|
||||
sources: input.sourceMap.sources,
|
||||
sourceRoot: input.sourceMap.sourceRoot,
|
||||
mappings: prependMappings + input.sourceMap.mappings,
|
||||
names: input.names,
|
||||
sourcesContent: input.sourcesContent
|
||||
};
|
||||
}
|
||||
return cb(null, output);
|
||||
}
|
||||
catch (e) {
|
||||
return cb(e);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
exports.prepend = prepend;
|
||||
|
||||
/**
|
||||
* @param {string | ((file: Vinyl) => string)} file
|
||||
*/
|
||||
function prependFile(file) {
|
||||
const data = typeof file === "string" ? fs.readFileSync(file, "utf8") :
|
||||
vinyl => fs.readFileSync(file(vinyl), "utf8");
|
||||
return prepend(data)
|
||||
}
|
||||
exports.file = prependFile;
|
||||
@@ -209,6 +209,27 @@ function flatten(projectSpec, flattenedProjectSpec, options = {}) {
|
||||
}
|
||||
exports.flatten = flatten;
|
||||
|
||||
/**
|
||||
* Returns a Promise that resolves when all pending build tasks have completed
|
||||
*/
|
||||
function wait() {
|
||||
return new Promise(resolve => {
|
||||
if (compilationGulp.allDone()) {
|
||||
resolve();
|
||||
}
|
||||
else {
|
||||
const onDone = () => {
|
||||
compilationGulp.removeListener("onDone", onDone);
|
||||
compilationGulp.removeListener("err", onDone);
|
||||
resolve();
|
||||
};
|
||||
compilationGulp.on("stop", onDone);
|
||||
compilationGulp.on("err", onDone);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.wait = wait;
|
||||
|
||||
/**
|
||||
* Resolve a TypeScript specifier into a fully-qualified module specifier and any requisite dependencies.
|
||||
* @param {string} typescript An unresolved module specifier to a TypeScript version.
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
// @ts-check
|
||||
const path = require("path");
|
||||
const Vinyl = require("./vinyl");
|
||||
const convertMap = require("convert-source-map");
|
||||
const applySourceMap = require("vinyl-sourcemaps-apply");
|
||||
const through2 = require("through2");
|
||||
|
||||
/**
|
||||
* @param {Vinyl} input
|
||||
* @param {string | Buffer} contents
|
||||
* @param {string | RawSourceMap} [sourceMap]
|
||||
*/
|
||||
function replaceContents(input, contents, sourceMap) {
|
||||
const output = input.clone();
|
||||
output.contents = typeof contents === "string" ? Buffer.from(contents, "utf8") : contents;
|
||||
if (input.sourceMap) {
|
||||
output.sourceMap = typeof input.sourceMap === "string" ? /**@type {RawSourceMap}*/(JSON.parse(input.sourceMap)) : input.sourceMap;
|
||||
if (typeof sourceMap === "string") {
|
||||
sourceMap = /**@type {RawSourceMap}*/(JSON.parse(sourceMap));
|
||||
}
|
||||
else if (sourceMap === undefined) {
|
||||
const stringContents = typeof contents === "string" ? contents : contents.toString("utf8");
|
||||
const newSourceMapConverter = convertMap.fromSource(stringContents);
|
||||
if (newSourceMapConverter) {
|
||||
sourceMap = /**@type {RawSourceMap}*/(newSourceMapConverter.toObject());
|
||||
output.contents = new Buffer(convertMap.removeMapFileComments(stringContents), "utf8");
|
||||
}
|
||||
}
|
||||
if (sourceMap) {
|
||||
const cwd = input.cwd || process.cwd();
|
||||
const base = input.base || cwd;
|
||||
const sourceRoot = output.sourceMap.sourceRoot;
|
||||
makeAbsoluteSourceMap(cwd, base, output.sourceMap);
|
||||
makeAbsoluteSourceMap(cwd, base, sourceMap);
|
||||
applySourceMap(output, sourceMap);
|
||||
makeRelativeSourceMap(cwd, base, sourceRoot, output.sourceMap);
|
||||
}
|
||||
else {
|
||||
output.sourceMap = undefined;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
exports.replaceContents = replaceContents;
|
||||
|
||||
function removeSourceMaps() {
|
||||
return through2.obj((/**@type {Vinyl}*/file, _, cb) => {
|
||||
if (file.sourceMap && file.isBuffer()) {
|
||||
file.contents = Buffer.from(convertMap.removeMapFileComments(file.contents.toString("utf8")), "utf8");
|
||||
file.sourceMap = undefined;
|
||||
}
|
||||
cb(null, file);
|
||||
});
|
||||
}
|
||||
exports.removeSourceMaps = removeSourceMaps;
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @param {string | undefined} base
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*
|
||||
* @typedef RawSourceMap
|
||||
* @property {string} version
|
||||
* @property {string} file
|
||||
* @property {string} [sourceRoot]
|
||||
* @property {string[]} sources
|
||||
* @property {string[]} [sourcesContent]
|
||||
* @property {string} mappings
|
||||
* @property {string[]} [names]
|
||||
*/
|
||||
function makeAbsoluteSourceMap(cwd = process.cwd(), base = "", sourceMap) {
|
||||
const sourceRoot = sourceMap.sourceRoot || "";
|
||||
const resolvedBase = path.resolve(cwd, base);
|
||||
const resolvedSourceRoot = path.resolve(resolvedBase, sourceRoot);
|
||||
sourceMap.file = path.resolve(resolvedBase, sourceMap.file).replace(/\\/g, "/");
|
||||
sourceMap.sources = sourceMap.sources.map(source => path.resolve(resolvedSourceRoot, source).replace(/\\/g, "/"));
|
||||
sourceMap.sourceRoot = "";
|
||||
}
|
||||
exports.makeAbsoluteSourceMap = makeAbsoluteSourceMap;
|
||||
|
||||
/**
|
||||
* @param {string | undefined} cwd
|
||||
* @param {string | undefined} base
|
||||
* @param {string} sourceRoot
|
||||
* @param {RawSourceMap} sourceMap
|
||||
*/
|
||||
function makeRelativeSourceMap(cwd = process.cwd(), base = "", sourceRoot, sourceMap) {
|
||||
makeAbsoluteSourceMap(cwd, base, sourceMap);
|
||||
const resolvedBase = path.resolve(cwd, base);
|
||||
const resolvedSourceRoot = path.resolve(resolvedBase, sourceRoot);
|
||||
sourceMap.file = path.relative(resolvedBase, sourceMap.file).replace(/\\/g, "/");
|
||||
sourceMap.sources = sourceMap.sources.map(source => path.relative(resolvedSourceRoot, source).replace(/\\/g, "/"));
|
||||
sourceMap.sourceRoot = sourceRoot;
|
||||
}
|
||||
exports.makeRelativeSourceMap = makeRelativeSourceMap;
|
||||
|
||||
/**
|
||||
* @param {string} message
|
||||
* @returns {never}
|
||||
*/
|
||||
function fail(message) {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
*/
|
||||
function base64FormatEncode(value) {
|
||||
return value < 0 ? fail("Invalid value") :
|
||||
value < 26 ? 0x41 /*A*/ + value :
|
||||
value < 52 ? 0x61 /*a*/ + value - 26 :
|
||||
value < 62 ? 0x30 /*0*/ + value - 52 :
|
||||
value === 62 ? 0x2B /*+*/ :
|
||||
value === 63 ? 0x2F /*/*/ :
|
||||
fail("Invalid value");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
*/
|
||||
function base64VLQFormatEncode(value) {
|
||||
if (value < 0) {
|
||||
value = ((-value) << 1) + 1;
|
||||
}
|
||||
else {
|
||||
value = value << 1;
|
||||
}
|
||||
|
||||
// Encode 5 bits at a time starting from least significant bits
|
||||
let result = "";
|
||||
do {
|
||||
let currentDigit = value & 31; // 11111
|
||||
value = value >> 5;
|
||||
if (value > 0) {
|
||||
// There are still more digits to decode, set the msb (6th bit)
|
||||
currentDigit = currentDigit | 32;
|
||||
}
|
||||
result += String.fromCharCode(base64FormatEncode(currentDigit));
|
||||
} while (value > 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
exports.base64VLQFormatEncode = base64VLQFormatEncode;
|
||||
+108
-106
@@ -1,4 +1,5 @@
|
||||
// @ts-check
|
||||
const gulp = require("./gulp");
|
||||
const del = require("del");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
@@ -6,13 +7,8 @@ const path = require("path");
|
||||
const mkdirP = require("./mkdirp");
|
||||
const cmdLineOptions = require("./options");
|
||||
const exec = require("./exec");
|
||||
const runSequence = require("run-sequence");
|
||||
const finished = require("./finished");
|
||||
const log = require("fancy-log"); // was `require("gulp-util").log (see https://github.com/gulpjs/gulp-util)
|
||||
|
||||
const nodeModulesPathPrefix = path.resolve("./node_modules/.bin/");
|
||||
const isWin = /^win/.test(process.platform);
|
||||
const mocha = path.join(nodeModulesPathPrefix, "mocha") + (isWin ? ".cmd" : "");
|
||||
const mochaJs = require.resolve("mocha/bin/_mocha");
|
||||
|
||||
exports.localBaseline = "tests/baselines/local/";
|
||||
exports.refBaseline = "tests/baselines/reference/";
|
||||
@@ -24,8 +20,10 @@ exports.localTest262Baseline = "internal/baselines/test262/local";
|
||||
* @param {string} runJs
|
||||
* @param {string} defaultReporter
|
||||
* @param {boolean} runInParallel
|
||||
* @param {boolean} watchMode
|
||||
* @param {InstanceType<typeof import("./cancellation").CancelToken>} [cancelToken]
|
||||
*/
|
||||
function runConsoleTests(runJs, defaultReporter, runInParallel) {
|
||||
async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, cancelToken) {
|
||||
let testTimeout = cmdLineOptions.timeout;
|
||||
let tests = cmdLineOptions.tests;
|
||||
const lintFlag = cmdLineOptions.lint;
|
||||
@@ -36,112 +34,116 @@ function runConsoleTests(runJs, defaultReporter, runInParallel) {
|
||||
const stackTraceLimit = cmdLineOptions.stackTraceLimit;
|
||||
const testConfigFile = "test.config";
|
||||
const failed = cmdLineOptions.failed;
|
||||
const keepFailed = cmdLineOptions.keepFailed || failed;
|
||||
return cleanTestDirs()
|
||||
.then(() => {
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
fs.unlinkSync(testConfigFile);
|
||||
}
|
||||
|
||||
let workerCount, taskConfigsFolder;
|
||||
if (runInParallel) {
|
||||
// generate name to store task configuration files
|
||||
const prefix = os.tmpdir() + "/ts-tests";
|
||||
let i = 1;
|
||||
do {
|
||||
taskConfigsFolder = prefix + i;
|
||||
i++;
|
||||
} while (fs.existsSync(taskConfigsFolder));
|
||||
fs.mkdirSync(taskConfigsFolder);
|
||||
|
||||
workerCount = cmdLineOptions.workers;
|
||||
}
|
||||
|
||||
if (tests && tests.toLocaleLowerCase() === "rwc") {
|
||||
testTimeout = 400000;
|
||||
}
|
||||
|
||||
if (tests || runners || light || testTimeout || taskConfigsFolder || keepFailed) {
|
||||
writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, testTimeout, keepFailed);
|
||||
}
|
||||
|
||||
const colors = cmdLineOptions.colors;
|
||||
const reporter = cmdLineOptions.reporter || defaultReporter;
|
||||
|
||||
/** @type {string} */
|
||||
let host = "node";
|
||||
|
||||
/** @type {string[]} */
|
||||
let args = [];
|
||||
|
||||
// timeout normally isn"t necessary but Travis-CI has been timing out on compiler baselines occasionally
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
args.push("-R", "scripts/failed-tests");
|
||||
args.push("-O", '"reporter=' + reporter + (keepFailed ? ",keepFailed=true" : "") + '"');
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
}
|
||||
if (colors) {
|
||||
args.push("--colors");
|
||||
}
|
||||
else {
|
||||
args.push("--no-colors");
|
||||
}
|
||||
if (inspect) {
|
||||
args.unshift("--inspect-brk");
|
||||
}
|
||||
else if (debug) {
|
||||
args.unshift("--debug-brk");
|
||||
}
|
||||
else {
|
||||
args.push("-t", "" + testTimeout);
|
||||
}
|
||||
args.push(runJs);
|
||||
host = mocha;
|
||||
}
|
||||
else {
|
||||
// run task to load all tests and partition them between workers
|
||||
host = "node";
|
||||
args.push(runJs);
|
||||
}
|
||||
setNodeEnvToDevelopment();
|
||||
if (failed) {
|
||||
return exec(host, ["scripts/run-failed-tests.js"].concat(args));
|
||||
}
|
||||
else {
|
||||
return exec(host, args);
|
||||
}
|
||||
})
|
||||
.then(({ exitCode }) => {
|
||||
if (exitCode !== 0) return finish(undefined, exitCode);
|
||||
if (lintFlag) return finished(runSequence("lint")).then(() => finish(), finish);
|
||||
return finish();
|
||||
}, finish);
|
||||
|
||||
/**
|
||||
* @param {any=} error
|
||||
* @param {number=} errorStatus
|
||||
*/
|
||||
function finish(error, errorStatus) {
|
||||
restoreSavedNodeEnv();
|
||||
return deleteTestConfig()
|
||||
.then(deleteTemporaryProjectOutput)
|
||||
.then(() => {
|
||||
if (error !== undefined || errorStatus !== undefined) {
|
||||
process.exit(typeof errorStatus === "number" ? errorStatus : 2);
|
||||
}
|
||||
});
|
||||
const keepFailed = cmdLineOptions.keepFailed;
|
||||
if (!cmdLineOptions.dirty) {
|
||||
await cleanTestDirs();
|
||||
}
|
||||
|
||||
function deleteTestConfig() {
|
||||
return del("test.config");
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
fs.unlinkSync(testConfigFile);
|
||||
}
|
||||
|
||||
let workerCount, taskConfigsFolder;
|
||||
if (runInParallel) {
|
||||
// generate name to store task configuration files
|
||||
const prefix = os.tmpdir() + "/ts-tests";
|
||||
let i = 1;
|
||||
do {
|
||||
taskConfigsFolder = prefix + i;
|
||||
i++;
|
||||
} while (fs.existsSync(taskConfigsFolder));
|
||||
fs.mkdirSync(taskConfigsFolder);
|
||||
|
||||
workerCount = cmdLineOptions.workers;
|
||||
}
|
||||
|
||||
if (tests && tests.toLocaleLowerCase() === "rwc") {
|
||||
testTimeout = 400000;
|
||||
}
|
||||
|
||||
if (tests || runners || light || testTimeout || taskConfigsFolder || keepFailed) {
|
||||
writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, testTimeout, keepFailed);
|
||||
}
|
||||
|
||||
const colors = cmdLineOptions.colors;
|
||||
const reporter = cmdLineOptions.reporter || defaultReporter;
|
||||
|
||||
/** @type {string[]} */
|
||||
let args = [];
|
||||
|
||||
// timeout normally isn"t necessary but Travis-CI has been timing out on compiler baselines occasionally
|
||||
// default timeout is 2sec which really should be enough, but maybe we just need a small amount longer
|
||||
if (!runInParallel) {
|
||||
args.push(failed ? "scripts/run-failed-tests.js" : mochaJs);
|
||||
args.push("-R", "scripts/failed-tests");
|
||||
args.push("-O", '"reporter=' + reporter + (keepFailed ? ",keepFailed=true" : "") + '"');
|
||||
if (tests) {
|
||||
args.push("-g", `"${tests}"`);
|
||||
}
|
||||
if (colors) {
|
||||
args.push("--colors");
|
||||
}
|
||||
else {
|
||||
args.push("--no-colors");
|
||||
}
|
||||
if (inspect) {
|
||||
args.unshift("--inspect-brk");
|
||||
}
|
||||
else if (debug) {
|
||||
args.unshift("--debug-brk");
|
||||
}
|
||||
else {
|
||||
args.push("-t", "" + testTimeout);
|
||||
}
|
||||
args.push(runJs);
|
||||
}
|
||||
else {
|
||||
// run task to load all tests and partition them between workers
|
||||
args.push(runJs);
|
||||
}
|
||||
|
||||
/** @type {number | undefined} */
|
||||
let errorStatus;
|
||||
|
||||
/** @type {Error | undefined} */
|
||||
let error;
|
||||
|
||||
try {
|
||||
setNodeEnvToDevelopment();
|
||||
const { exitCode } = await exec("node", args, { cancelToken });
|
||||
if (exitCode !== 0) {
|
||||
errorStatus = exitCode;
|
||||
error = new Error(`Process exited with status code ${errorStatus}.`);
|
||||
}
|
||||
else if (lintFlag) {
|
||||
await new Promise((resolve, reject) => gulp.start(["lint"], error => error ? reject(error) : resolve()));
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
errorStatus = undefined;
|
||||
error = e;
|
||||
}
|
||||
finally {
|
||||
restoreSavedNodeEnv();
|
||||
}
|
||||
|
||||
await del("test.config");
|
||||
await deleteTemporaryProjectOutput();
|
||||
|
||||
if (error !== undefined) {
|
||||
if (watchMode) {
|
||||
throw error;
|
||||
}
|
||||
else {
|
||||
log.error(error);
|
||||
process.exit(typeof errorStatus === "number" ? errorStatus : 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.runConsoleTests = runConsoleTests;
|
||||
|
||||
function cleanTestDirs() {
|
||||
return del([exports.localBaseline, exports.localRwcBaseline,])
|
||||
return del([exports.localBaseline, exports.localRwcBaseline])
|
||||
.then(() => mkdirP(exports.localRwcBaseline))
|
||||
.then(() => mkdirP(exports.localBaseline));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// @ts-check
|
||||
const fs = require("fs");
|
||||
const File = require("./vinyl");
|
||||
const { Readable } = require("stream");
|
||||
|
||||
/**
|
||||
* @param {File} file
|
||||
*/
|
||||
function streamFromFile(file) {
|
||||
return file.isBuffer() ? streamFromBuffer(file.contents) :
|
||||
file.isStream() ? file.contents :
|
||||
fs.createReadStream(file.path, { autoClose: true });
|
||||
}
|
||||
exports.streamFromFile = streamFromFile;
|
||||
|
||||
/**
|
||||
* @param {Buffer} buffer
|
||||
*/
|
||||
function streamFromBuffer(buffer) {
|
||||
return new Readable({
|
||||
read() {
|
||||
this.push(buffer);
|
||||
this.push(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
exports.streamFromBuffer = streamFromBuffer;
|
||||
Vendored
+60
@@ -0,0 +1,60 @@
|
||||
// NOTE: This makes it possible to correctly type vinyl Files under @ts-check.
|
||||
export = File;
|
||||
|
||||
declare class File<T extends File.Contents = File.Contents> {
|
||||
constructor(options?: File.VinylOptions<T>);
|
||||
|
||||
cwd: string;
|
||||
base: string;
|
||||
path: string;
|
||||
readonly history: ReadonlyArray<string>;
|
||||
contents: T;
|
||||
relative: string;
|
||||
dirname: string;
|
||||
basename: string;
|
||||
stem: string;
|
||||
extname: string;
|
||||
symlink: string | null;
|
||||
stat: import("fs").Stats | null;
|
||||
sourceMap?: import("./sourcemaps").RawSourceMap | string;
|
||||
|
||||
[custom: string]: any;
|
||||
|
||||
isBuffer(): this is T extends Buffer ? File<Buffer> : never;
|
||||
isStream(): this is T extends NodeJS.ReadableStream ? File<NodeJS.ReadableStream> : never;
|
||||
isNull(): this is T extends null ? File<null> : never;
|
||||
isDirectory(): this is T extends null ? File.Directory : never;
|
||||
isSymbolic(): this is T extends null ? File.Symbolic : never;
|
||||
clone(opts?: { contents?: boolean, deep?: boolean }): this;
|
||||
}
|
||||
|
||||
namespace File {
|
||||
export interface VinylOptions<T extends Contents = Contents> {
|
||||
cwd?: string;
|
||||
base?: string;
|
||||
path?: string;
|
||||
history?: ReadonlyArray<string>;
|
||||
stat?: import("fs").Stats;
|
||||
contents?: T;
|
||||
sourceMap?: import("./sourcemaps").RawSourceMap | string;
|
||||
[custom: string]: any;
|
||||
}
|
||||
|
||||
export type Contents = Buffer | NodeJS.ReadableStream | null;
|
||||
export type File = import("./vinyl");
|
||||
export type NullFile = File<null>;
|
||||
export type BufferFile = File<Buffer>;
|
||||
export type StreamFile = File<NodeJS.ReadableStream>;
|
||||
|
||||
export interface Directory extends NullFile {
|
||||
isNull(): true;
|
||||
isDirectory(): true;
|
||||
isSymbolic(): this is never;
|
||||
}
|
||||
|
||||
export interface Symbolic extends NullFile {
|
||||
isNull(): true;
|
||||
isDirectory(): this is never;
|
||||
isSymbolic(): true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = require("vinyl");
|
||||
+42
-17
@@ -4,9 +4,11 @@ const path = require("path");
|
||||
const fs = require("fs");
|
||||
const os = require("os");
|
||||
|
||||
const failingHookRegExp = /^(.*) "(before|after) (all|each)" hook$/;
|
||||
|
||||
/**
|
||||
* .failed-tests reporter
|
||||
*
|
||||
*
|
||||
* @typedef {Object} ReporterOptions
|
||||
* @property {string} [file]
|
||||
* @property {boolean} [keepFailed]
|
||||
@@ -15,7 +17,7 @@ const os = require("os");
|
||||
*/
|
||||
class FailedTestsReporter extends Mocha.reporters.Base {
|
||||
/**
|
||||
* @param {Mocha.Runner} runner
|
||||
* @param {Mocha.Runner} runner
|
||||
* @param {{ reporterOptions?: ReporterOptions }} [options]
|
||||
*/
|
||||
constructor(runner, options) {
|
||||
@@ -49,35 +51,58 @@ class FailedTestsReporter extends Mocha.reporters.Base {
|
||||
|
||||
/** @type {Mocha.Test[]} */
|
||||
this.passes = [];
|
||||
|
||||
/** @type {Mocha.Test[]} */
|
||||
|
||||
/** @type {(Mocha.Test)[]} */
|
||||
this.failures = [];
|
||||
|
||||
|
||||
runner.on("pass", test => this.passes.push(test));
|
||||
runner.on("fail", test => this.failures.push(test));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} file
|
||||
* @param {ReadonlyArray<Mocha.Test>} passes
|
||||
* @param {ReadonlyArray<Mocha.Test>} failures
|
||||
* @param {boolean} keepFailed
|
||||
* @param {(err?: NodeJS.ErrnoException) => void} done
|
||||
* @param {string} file
|
||||
* @param {ReadonlyArray<Mocha.Test>} passes
|
||||
* @param {ReadonlyArray<Mocha.Test | Mocha.Hook>} failures
|
||||
* @param {boolean} keepFailed
|
||||
* @param {(err?: NodeJS.ErrnoException) => void} done
|
||||
*/
|
||||
static writeFailures(file, passes, failures, keepFailed, done) {
|
||||
const failingTests = new Set(fs.existsSync(file) ? readTests() : undefined);
|
||||
if (failingTests.size > 0) {
|
||||
const possiblyPassingSuites = /**@type {Set<string>}*/(new Set());
|
||||
|
||||
// Remove tests that are now passing and track suites that are now
|
||||
// possibly passing.
|
||||
if (failingTests.size > 0 && !keepFailed) {
|
||||
for (const test of passes) {
|
||||
const title = test.fullTitle().trim();
|
||||
if (title) failingTests.delete(title);
|
||||
failingTests.delete(test.fullTitle().trim());
|
||||
possiblyPassingSuites.add(test.parent.fullTitle().trim());
|
||||
}
|
||||
}
|
||||
|
||||
// Add tests that are now failing. If a hook failed, track its
|
||||
// containing suite as failing. If the suite for a test or hook was
|
||||
// possibly passing then it is now definitely failing.
|
||||
for (const test of failures) {
|
||||
const title = test.fullTitle().trim();
|
||||
if (title) failingTests.add(title);
|
||||
const suiteTitle = test.parent.fullTitle().trim();
|
||||
if (test.type === "test") {
|
||||
failingTests.add(test.fullTitle().trim());
|
||||
}
|
||||
else {
|
||||
failingTests.add(suiteTitle);
|
||||
}
|
||||
possiblyPassingSuites.delete(suiteTitle);
|
||||
}
|
||||
|
||||
// Remove all definitely passing suites.
|
||||
for (const suite of possiblyPassingSuites) {
|
||||
failingTests.delete(suite);
|
||||
}
|
||||
|
||||
if (failingTests.size > 0) {
|
||||
const failed = Array.from(failingTests).join(os.EOL);
|
||||
const failed = Array
|
||||
.from(failingTests)
|
||||
.sort()
|
||||
.join(os.EOL);
|
||||
fs.writeFile(file, failed, "utf8", done);
|
||||
}
|
||||
else if (!keepFailed && fs.existsSync(file)) {
|
||||
@@ -96,7 +121,7 @@ class FailedTestsReporter extends Mocha.reporters.Base {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} failures
|
||||
* @param {number} failures
|
||||
* @param {(failures: number) => void} [fn]
|
||||
*/
|
||||
done(failures, fn) {
|
||||
|
||||
@@ -54,16 +54,17 @@ async function copyScriptOutputs() {
|
||||
await copyWithCopyright("cancellationToken.js");
|
||||
await copyWithCopyright("tsc.release.js", "tsc.js");
|
||||
await copyWithCopyright("tsserver.js");
|
||||
await copyWithCopyright("typescript.js");
|
||||
await copyWithCopyright("typescriptServices.js");
|
||||
await copyFromBuiltLocal("tsserverlibrary.js"); // copyright added by build
|
||||
await copyFromBuiltLocal("typescript.js"); // copyright added by build
|
||||
await copyFromBuiltLocal("typescriptServices.js"); // copyright added by build
|
||||
await copyWithCopyright("typingsInstaller.js");
|
||||
await copyWithCopyright("watchGuard.js");
|
||||
}
|
||||
|
||||
async function copyDeclarationOutputs() {
|
||||
await copyWithCopyright("tsserverlibrary.d.ts");
|
||||
await copyWithCopyright("typescript.d.ts");
|
||||
await copyWithCopyright("typescriptServices.d.ts");
|
||||
await copyFromBuiltLocal("tsserverlibrary.d.ts"); // copyright added by build
|
||||
await copyFromBuiltLocal("typescript.d.ts"); // copyright added by build
|
||||
await copyFromBuiltLocal("typescriptServices.d.ts"); // copyright added by build
|
||||
}
|
||||
|
||||
async function writeGitAttributes() {
|
||||
|
||||
@@ -69,7 +69,12 @@ const proc = spawn(process.execPath, args, {
|
||||
proc.on('exit', (code, signal) => {
|
||||
process.on('exit', () => {
|
||||
if (grepFile) {
|
||||
fs.unlinkSync(grepFile);
|
||||
try {
|
||||
fs.unlinkSync(grepFile);
|
||||
}
|
||||
catch (e) {
|
||||
if (e.code !== "ENOENT") throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (signal) {
|
||||
|
||||
+44
-5
@@ -1211,7 +1211,7 @@ namespace ts {
|
||||
bind(node.statement);
|
||||
popActiveLabel();
|
||||
if (!activeLabel.referenced && !options.allowUnusedLabels) {
|
||||
errorOrSuggestionOnFirstToken(unusedLabelIsError(options), node, Diagnostics.Unused_label);
|
||||
errorOrSuggestionOnNode(unusedLabelIsError(options), node.label, Diagnostics.Unused_label);
|
||||
}
|
||||
if (!node.statement || node.statement.kind !== SyntaxKind.DoStatement) {
|
||||
// do statement sets current flow inside bindDoStatement
|
||||
@@ -1918,9 +1918,16 @@ namespace ts {
|
||||
file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2));
|
||||
}
|
||||
|
||||
function errorOrSuggestionOnFirstToken(isError: boolean, node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) {
|
||||
const span = getSpanOfTokenAtPosition(file, node.pos);
|
||||
const diag = createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2);
|
||||
function errorOrSuggestionOnNode(isError: boolean, node: Node, message: DiagnosticMessage): void {
|
||||
errorOrSuggestionOnRange(isError, node, node, message);
|
||||
}
|
||||
|
||||
function errorOrSuggestionOnRange(isError: boolean, startNode: Node, endNode: Node, message: DiagnosticMessage): void {
|
||||
addErrorOrSuggestionDiagnostic(isError, { pos: getTokenPosOfNode(startNode, file), end: endNode.end }, message);
|
||||
}
|
||||
|
||||
function addErrorOrSuggestionDiagnostic(isError: boolean, range: TextRange, message: DiagnosticMessage): void {
|
||||
const diag = createFileDiagnostic(file, range.pos, range.end - range.pos, message);
|
||||
if (isError) {
|
||||
file.bindDiagnostics.push(diag);
|
||||
}
|
||||
@@ -2792,7 +2799,7 @@ namespace ts {
|
||||
node.declarationList.declarations.some(d => !!d.initializer)
|
||||
);
|
||||
|
||||
errorOrSuggestionOnFirstToken(isError, node, Diagnostics.Unreachable_code_detected);
|
||||
eachUnreachableRange(node, (start, end) => errorOrSuggestionOnRange(isError, start, end, Diagnostics.Unreachable_code_detected));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2800,6 +2807,38 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function eachUnreachableRange(node: Node, cb: (start: Node, last: Node) => void): void {
|
||||
if (isStatement(node) && isExecutableStatement(node) && isBlock(node.parent)) {
|
||||
const { statements } = node.parent;
|
||||
const slice = sliceAfter(statements, node);
|
||||
getRangesWhere(slice, isExecutableStatement, (start, afterEnd) => cb(slice[start], slice[afterEnd - 1]));
|
||||
}
|
||||
else {
|
||||
cb(node, node);
|
||||
}
|
||||
}
|
||||
// As opposed to a pure declaration like an `interface`
|
||||
function isExecutableStatement(s: Statement): boolean {
|
||||
// Don't remove statements that can validly be used before they appear.
|
||||
return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) &&
|
||||
// `var x;` may declare a variable used above
|
||||
!(isVariableStatement(s) && !(getCombinedNodeFlags(s) & (NodeFlags.Let | NodeFlags.Const)) && s.declarationList.declarations.some(d => !d.initializer));
|
||||
}
|
||||
|
||||
function isPurelyTypeDeclaration(s: Statement): boolean {
|
||||
switch (s.kind) {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
return true;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return getModuleInstanceState(s as ModuleDeclaration) !== ModuleInstanceState.Instantiated;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return hasModifier(s, ModifierFlags.Const);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean {
|
||||
return isExportsIdentifier(node) ||
|
||||
|
||||
+251
-97
@@ -295,7 +295,7 @@ namespace ts {
|
||||
getAllPossiblePropertiesOfTypes,
|
||||
getSuggestionForNonexistentProperty: (node, type) => getSuggestionForNonexistentProperty(node, type),
|
||||
getSuggestionForNonexistentSymbol: (location, name, meaning) => getSuggestionForNonexistentSymbol(location, escapeLeadingUnderscores(name), meaning),
|
||||
getSuggestionForNonexistentModule: (node, target) => getSuggestionForNonexistentModule(node, target),
|
||||
getSuggestionForNonexistentExport: (node, target) => getSuggestionForNonexistentExport(node, target),
|
||||
getBaseConstraintOfType,
|
||||
getDefaultFromTypeParameter: type => type && type.flags & TypeFlags.TypeParameter ? getDefaultFromTypeParameter(type as TypeParameter) : undefined,
|
||||
resolveName(name, location, meaning, excludeGlobals) {
|
||||
@@ -710,7 +710,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function addRelatedInfo(diagnostic: Diagnostic, ...relatedInformation: DiagnosticRelatedInformation[]) {
|
||||
function addRelatedInfo(diagnostic: Diagnostic, ...relatedInformation: [DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]]) {
|
||||
if (!diagnostic.relatedInformation) {
|
||||
diagnostic.relatedInformation = [];
|
||||
}
|
||||
@@ -1059,6 +1059,7 @@ namespace ts {
|
||||
// 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ)
|
||||
// or if usage is in a type context:
|
||||
// 1. inside a type query (typeof in type position)
|
||||
// 2. inside a jsdoc comment
|
||||
if (usage.parent.kind === SyntaxKind.ExportSpecifier || (usage.parent.kind === SyntaxKind.ExportAssignment && (usage.parent as ExportAssignment).isExportEquals)) {
|
||||
// export specifiers do not use the variable, they only make it available for use
|
||||
return true;
|
||||
@@ -1069,7 +1070,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const container = getEnclosingBlockScopeContainer(declaration);
|
||||
return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container);
|
||||
return !!(usage.flags & NodeFlags.JSDoc) || isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container);
|
||||
|
||||
function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration: VariableDeclaration, usage: Node): boolean {
|
||||
const container = getEnclosingBlockScopeContainer(declaration);
|
||||
@@ -1434,11 +1435,18 @@ namespace ts {
|
||||
!checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
|
||||
!checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) &&
|
||||
!checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) {
|
||||
let suggestion: string | undefined;
|
||||
let suggestion: Symbol | undefined;
|
||||
if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) {
|
||||
suggestion = getSuggestionForNonexistentSymbol(originalLocation, name, meaning);
|
||||
suggestion = getSuggestedSymbolForNonexistentSymbol(originalLocation, name, meaning);
|
||||
if (suggestion) {
|
||||
error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg!), suggestion);
|
||||
const suggestionName = symbolToString(suggestion);
|
||||
const diagnostic = error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg!), suggestionName);
|
||||
if (suggestion.valueDeclaration) {
|
||||
addRelatedInfo(
|
||||
diagnostic,
|
||||
createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestionName)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!suggestion) {
|
||||
@@ -1674,7 +1682,7 @@ namespace ts {
|
||||
|
||||
if (diagnosticMessage) {
|
||||
addRelatedInfo(diagnosticMessage,
|
||||
createDiagnosticForNode(declaration, Diagnostics._0_was_declared_here, declarationName)
|
||||
createDiagnosticForNode(declaration, Diagnostics._0_is_declared_here, declarationName)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1866,9 +1874,15 @@ namespace ts {
|
||||
if (!symbol) {
|
||||
const moduleName = getFullyQualifiedName(moduleSymbol);
|
||||
const declarationName = declarationNameToString(name);
|
||||
const suggestion = getSuggestionForNonexistentModule(name, targetSymbol);
|
||||
const suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol);
|
||||
if (suggestion !== undefined) {
|
||||
error(name, Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestion);
|
||||
const suggestionName = symbolToString(suggestion);
|
||||
const diagnostic = error(name, Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_2, moduleName, declarationName, suggestionName);
|
||||
if (suggestion.valueDeclaration) {
|
||||
addRelatedInfo(diagnostic,
|
||||
createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestionName)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(name, Diagnostics.Module_0_has_no_exported_member_1, moduleName, declarationName);
|
||||
@@ -2993,7 +3007,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function typeToString(type: Type, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer: EmitTextWriter = createTextWriter("")): string {
|
||||
const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors, writer);
|
||||
const noTruncation = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation;
|
||||
const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | (noTruncation ? NodeBuilderFlags.NoTruncation : 0), writer);
|
||||
if (typeNode === undefined) return Debug.fail("should always get typenode");
|
||||
const options = { removeComments: true };
|
||||
const printer = createPrinter(options);
|
||||
@@ -3001,7 +3016,7 @@ namespace ts {
|
||||
printer.writeNode(EmitHint.Unspecified, typeNode, /*sourceFile*/ sourceFile, writer);
|
||||
const result = writer.getText();
|
||||
|
||||
const maxLength = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation ? undefined : 100;
|
||||
const maxLength = noTruncation ? undefined : defaultMaximumTruncationLength * 2;
|
||||
if (maxLength && result && result.length >= maxLength) {
|
||||
return result.substr(0, maxLength - "...".length) + "...";
|
||||
}
|
||||
@@ -3040,12 +3055,18 @@ namespace ts {
|
||||
tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: noop },
|
||||
encounteredError: false,
|
||||
visitedSymbols: undefined,
|
||||
inferTypeParameters: undefined
|
||||
inferTypeParameters: undefined,
|
||||
approximateLength: 0
|
||||
};
|
||||
const resultingNode = cb(context);
|
||||
return context.encounteredError ? undefined : resultingNode;
|
||||
}
|
||||
|
||||
function checkTruncationLength(context: NodeBuilderContext): boolean {
|
||||
if (context.truncating) return context.truncating;
|
||||
return context.truncating = !(context.flags & NodeBuilderFlags.NoTruncation) && context.approximateLength > defaultMaximumTruncationLength;
|
||||
}
|
||||
|
||||
function typeToTypeNodeHelper(type: Type, context: NodeBuilderContext): TypeNode {
|
||||
if (cancellationToken && cancellationToken.throwIfCancellationRequested) {
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
@@ -3059,66 +3080,83 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (type.flags & TypeFlags.Any) {
|
||||
context.approximateLength += 3;
|
||||
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.Unknown) {
|
||||
return createKeywordTypeNode(SyntaxKind.UnknownKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.String) {
|
||||
context.approximateLength += 6;
|
||||
return createKeywordTypeNode(SyntaxKind.StringKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.Number) {
|
||||
context.approximateLength += 6;
|
||||
return createKeywordTypeNode(SyntaxKind.NumberKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.Boolean) {
|
||||
context.approximateLength += 7;
|
||||
return createKeywordTypeNode(SyntaxKind.BooleanKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.EnumLiteral && !(type.flags & TypeFlags.Union)) {
|
||||
const parentSymbol = getParentOfSymbol(type.symbol)!;
|
||||
const parentName = symbolToName(parentSymbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false);
|
||||
const enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type ? parentName : createQualifiedName(parentName, symbolName(type.symbol));
|
||||
context.approximateLength += symbolName(type.symbol).length;
|
||||
return createTypeReferenceNode(enumLiteralName, /*typeArguments*/ undefined);
|
||||
}
|
||||
if (type.flags & TypeFlags.EnumLike) {
|
||||
const name = symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false);
|
||||
context.approximateLength += symbolName(type.symbol).length;
|
||||
return createTypeReferenceNode(name, /*typeArguments*/ undefined);
|
||||
}
|
||||
if (type.flags & (TypeFlags.StringLiteral)) {
|
||||
if (type.flags & TypeFlags.StringLiteral) {
|
||||
context.approximateLength += ((<StringLiteralType>type).value.length + 2);
|
||||
return createLiteralTypeNode(setEmitFlags(createLiteral((<StringLiteralType>type).value), EmitFlags.NoAsciiEscaping));
|
||||
}
|
||||
if (type.flags & (TypeFlags.NumberLiteral)) {
|
||||
if (type.flags & TypeFlags.NumberLiteral) {
|
||||
context.approximateLength += (("" + (<NumberLiteralType>type).value).length);
|
||||
return createLiteralTypeNode((createLiteral((<NumberLiteralType>type).value)));
|
||||
}
|
||||
if (type.flags & TypeFlags.BooleanLiteral) {
|
||||
context.approximateLength += (<IntrinsicType>type).intrinsicName.length;
|
||||
return (<IntrinsicType>type).intrinsicName === "true" ? createTrue() : createFalse();
|
||||
}
|
||||
if (type.flags & TypeFlags.UniqueESSymbol) {
|
||||
if (!(context.flags & NodeBuilderFlags.AllowUniqueESSymbolType)) {
|
||||
if (isValueSymbolAccessible(type.symbol, context.enclosingDeclaration!)) {
|
||||
context.approximateLength += 6;
|
||||
return symbolToTypeNode(type.symbol, context, SymbolFlags.Value);
|
||||
}
|
||||
if (context.tracker.reportInaccessibleUniqueSymbolError) {
|
||||
context.tracker.reportInaccessibleUniqueSymbolError();
|
||||
}
|
||||
}
|
||||
context.approximateLength += 13;
|
||||
return createTypeOperatorNode(SyntaxKind.UniqueKeyword, createKeywordTypeNode(SyntaxKind.SymbolKeyword));
|
||||
}
|
||||
if (type.flags & TypeFlags.Void) {
|
||||
context.approximateLength += 4;
|
||||
return createKeywordTypeNode(SyntaxKind.VoidKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.Undefined) {
|
||||
context.approximateLength += 9;
|
||||
return createKeywordTypeNode(SyntaxKind.UndefinedKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.Null) {
|
||||
context.approximateLength += 4;
|
||||
return createKeywordTypeNode(SyntaxKind.NullKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.Never) {
|
||||
context.approximateLength += 5;
|
||||
return createKeywordTypeNode(SyntaxKind.NeverKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.ESSymbol) {
|
||||
context.approximateLength += 6;
|
||||
return createKeywordTypeNode(SyntaxKind.SymbolKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.NonPrimitive) {
|
||||
context.approximateLength += 6;
|
||||
return createKeywordTypeNode(SyntaxKind.ObjectKeyword);
|
||||
}
|
||||
if (type.flags & TypeFlags.TypeParameter && (type as TypeParameter).isThisType) {
|
||||
@@ -3130,6 +3168,7 @@ namespace ts {
|
||||
context.tracker.reportInaccessibleThisError();
|
||||
}
|
||||
}
|
||||
context.approximateLength += 4;
|
||||
return createThis();
|
||||
}
|
||||
|
||||
@@ -3141,6 +3180,7 @@ namespace ts {
|
||||
}
|
||||
if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) {
|
||||
if (type.flags & TypeFlags.TypeParameter && contains(context.inferTypeParameters, type)) {
|
||||
context.approximateLength += (symbolName(type.symbol).length + 6);
|
||||
return createInferTypeNode(typeParameterToDeclarationWithConstraint(type as TypeParameter, context, /*constraintNode*/ undefined));
|
||||
}
|
||||
if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams &&
|
||||
@@ -3149,7 +3189,9 @@ namespace ts {
|
||||
isTypeParameterDeclaration(type.symbol.declarations[0]) &&
|
||||
typeParameterShadowsNameInScope(type, context) &&
|
||||
!isTypeSymbolAccessible(type.symbol, context.enclosingDeclaration)) {
|
||||
return createTypeReferenceNode(getGeneratedNameForNode((type.symbol.declarations[0] as TypeParameterDeclaration).name, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.ReservedInNestedScopes), /*typeArguments*/ undefined);
|
||||
const name = (type.symbol.declarations[0] as TypeParameterDeclaration).name;
|
||||
context.approximateLength += idText(name).length;
|
||||
return createTypeReferenceNode(getGeneratedNameForNode(name, GeneratedIdentifierFlags.Optimistic | GeneratedIdentifierFlags.ReservedInNestedScopes), /*typeArguments*/ undefined);
|
||||
}
|
||||
// Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter.
|
||||
return type.symbol
|
||||
@@ -3163,7 +3205,7 @@ namespace ts {
|
||||
}
|
||||
if (type.flags & (TypeFlags.Union | TypeFlags.Intersection)) {
|
||||
const types = type.flags & TypeFlags.Union ? formatUnionTypes((<UnionType>type).types) : (<IntersectionType>type).types;
|
||||
const typeNodes = mapToTypeNodes(types, context);
|
||||
const typeNodes = mapToTypeNodes(types, context, /*isBareList*/ true);
|
||||
if (typeNodes && typeNodes.length > 0) {
|
||||
const unionOrIntersectionTypeNode = createUnionOrIntersectionTypeNode(type.flags & TypeFlags.Union ? SyntaxKind.UnionType : SyntaxKind.IntersectionType, typeNodes);
|
||||
return unionOrIntersectionTypeNode;
|
||||
@@ -3182,12 +3224,14 @@ namespace ts {
|
||||
}
|
||||
if (type.flags & TypeFlags.Index) {
|
||||
const indexedType = (<IndexType>type).type;
|
||||
context.approximateLength += 6;
|
||||
const indexTypeNode = typeToTypeNodeHelper(indexedType, context);
|
||||
return createTypeOperatorNode(indexTypeNode);
|
||||
}
|
||||
if (type.flags & TypeFlags.IndexedAccess) {
|
||||
const objectTypeNode = typeToTypeNodeHelper((<IndexedAccessType>type).objectType, context);
|
||||
const indexTypeNode = typeToTypeNodeHelper((<IndexedAccessType>type).indexType, context);
|
||||
context.approximateLength += 2;
|
||||
return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
|
||||
}
|
||||
if (type.flags & TypeFlags.Conditional) {
|
||||
@@ -3198,6 +3242,7 @@ namespace ts {
|
||||
context.inferTypeParameters = saveInferTypeParameters;
|
||||
const trueTypeNode = typeToTypeNodeHelper(getTrueTypeFromConditionalType(<ConditionalType>type), context);
|
||||
const falseTypeNode = typeToTypeNodeHelper(getFalseTypeFromConditionalType(<ConditionalType>type), context);
|
||||
context.approximateLength += 15;
|
||||
return createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode);
|
||||
}
|
||||
if (type.flags & TypeFlags.Substitution) {
|
||||
@@ -3222,6 +3267,7 @@ namespace ts {
|
||||
const typeParameterNode = typeParameterToDeclarationWithConstraint(getTypeParameterFromMappedType(type), context, appropriateConstraintTypeNode);
|
||||
const templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context);
|
||||
const mappedTypeNode = createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode);
|
||||
context.approximateLength += 10;
|
||||
return setEmitFlags(mappedTypeNode, EmitFlags.SingleLine);
|
||||
}
|
||||
|
||||
@@ -3250,6 +3296,7 @@ namespace ts {
|
||||
return symbolToTypeNode(typeAlias, context, SymbolFlags.Type);
|
||||
}
|
||||
else {
|
||||
context.approximateLength += 3;
|
||||
return createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
}
|
||||
}
|
||||
@@ -3294,6 +3341,7 @@ namespace ts {
|
||||
const resolved = resolveStructuredTypeMembers(type);
|
||||
if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) {
|
||||
if (!resolved.callSignatures.length && !resolved.constructSignatures.length) {
|
||||
context.approximateLength += 2;
|
||||
return setEmitFlags(createTypeLiteralNode(/*members*/ undefined), EmitFlags.SingleLine);
|
||||
}
|
||||
|
||||
@@ -3316,6 +3364,7 @@ namespace ts {
|
||||
const members = createTypeNodesFromResolvedType(resolved);
|
||||
context.flags = savedFlags;
|
||||
const typeLiteralNode = createTypeLiteralNode(members);
|
||||
context.approximateLength += 2;
|
||||
return setEmitFlags(typeLiteralNode, (context.flags & NodeBuilderFlags.MultilineObjectLiterals) ? 0 : EmitFlags.SingleLine);
|
||||
}
|
||||
|
||||
@@ -3437,6 +3486,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function createTypeNodesFromResolvedType(resolvedType: ResolvedType): TypeElement[] | undefined {
|
||||
if (checkTruncationLength(context)) {
|
||||
return [createPropertySignature(/*modifiers*/ undefined, "...", /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined)];
|
||||
}
|
||||
const typeElements: TypeElement[] = [];
|
||||
for (const signature of resolvedType.callSignatures) {
|
||||
typeElements.push(<CallSignatureDeclaration>signatureToSignatureDeclarationHelper(signature, SyntaxKind.CallSignature, context));
|
||||
@@ -3459,7 +3511,9 @@ namespace ts {
|
||||
return typeElements;
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
for (const propertySymbol of properties) {
|
||||
i++;
|
||||
if (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) {
|
||||
if (propertySymbol.flags & SymbolFlags.Prototype) {
|
||||
continue;
|
||||
@@ -3468,65 +3522,102 @@ namespace ts {
|
||||
context.tracker.reportPrivateInBaseOfClassExpression(unescapeLeadingUnderscores(propertySymbol.escapedName));
|
||||
}
|
||||
}
|
||||
const propertyType = getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped && context.flags & NodeBuilderFlags.InReverseMappedType ?
|
||||
anyType : getTypeOfSymbol(propertySymbol);
|
||||
const saveEnclosingDeclaration = context.enclosingDeclaration;
|
||||
context.enclosingDeclaration = undefined;
|
||||
if (getCheckFlags(propertySymbol) & CheckFlags.Late) {
|
||||
const decl = first(propertySymbol.declarations);
|
||||
if (context.tracker.trackSymbol && hasLateBindableName(decl)) {
|
||||
// get symbol of the first identifier of the entityName
|
||||
const firstIdentifier = getFirstIdentifier(decl.name.expression);
|
||||
const name = resolveName(firstIdentifier, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
|
||||
if (name) {
|
||||
context.tracker.trackSymbol(name, saveEnclosingDeclaration, SymbolFlags.Value);
|
||||
}
|
||||
}
|
||||
if (checkTruncationLength(context) && (i + 2 < properties.length - 1)) {
|
||||
typeElements.push(createPropertySignature(/*modifiers*/ undefined, `... ${properties.length - i} more ...`, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined));
|
||||
addPropertyToElementList(properties[properties.length - 1], context, typeElements);
|
||||
break;
|
||||
}
|
||||
const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true);
|
||||
context.enclosingDeclaration = saveEnclosingDeclaration;
|
||||
const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;
|
||||
if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) {
|
||||
const signatures = getSignaturesOfType(propertyType, SignatureKind.Call);
|
||||
for (const signature of signatures) {
|
||||
const methodDeclaration = <MethodSignature>signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, context);
|
||||
methodDeclaration.name = propertyName;
|
||||
methodDeclaration.questionToken = optionalToken;
|
||||
if (propertySymbol.valueDeclaration) {
|
||||
// Copy comments to node for declaration emit
|
||||
setCommentRange(methodDeclaration, propertySymbol.valueDeclaration);
|
||||
}
|
||||
typeElements.push(methodDeclaration);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const savedFlags = context.flags;
|
||||
context.flags |= !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped) ? NodeBuilderFlags.InReverseMappedType : 0;
|
||||
const propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType, context) : createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
context.flags = savedFlags;
|
||||
addPropertyToElementList(propertySymbol, context, typeElements);
|
||||
|
||||
const modifiers = isReadonlySymbol(propertySymbol) ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined;
|
||||
const propertySignature = createPropertySignature(
|
||||
modifiers,
|
||||
propertyName,
|
||||
optionalToken,
|
||||
propertyTypeNode,
|
||||
/*initializer*/ undefined);
|
||||
if (propertySymbol.valueDeclaration) {
|
||||
// Copy comments to node for declaration emit
|
||||
setCommentRange(propertySignature, propertySymbol.valueDeclaration);
|
||||
}
|
||||
typeElements.push(propertySignature);
|
||||
}
|
||||
}
|
||||
return typeElements.length ? typeElements : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function mapToTypeNodes(types: ReadonlyArray<Type> | undefined, context: NodeBuilderContext): TypeNode[] | undefined {
|
||||
function addPropertyToElementList(propertySymbol: Symbol, context: NodeBuilderContext, typeElements: TypeElement[]) {
|
||||
const propertyType = getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped && context.flags & NodeBuilderFlags.InReverseMappedType ?
|
||||
anyType : getTypeOfSymbol(propertySymbol);
|
||||
const saveEnclosingDeclaration = context.enclosingDeclaration;
|
||||
context.enclosingDeclaration = undefined;
|
||||
if (getCheckFlags(propertySymbol) & CheckFlags.Late) {
|
||||
const decl = first(propertySymbol.declarations);
|
||||
if (context.tracker.trackSymbol && hasLateBindableName(decl)) {
|
||||
// get symbol of the first identifier of the entityName
|
||||
const firstIdentifier = getFirstIdentifier(decl.name.expression);
|
||||
const name = resolveName(firstIdentifier, firstIdentifier.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true);
|
||||
if (name) {
|
||||
context.tracker.trackSymbol(name, saveEnclosingDeclaration, SymbolFlags.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true);
|
||||
context.approximateLength += (symbolName(propertySymbol).length + 1);
|
||||
context.enclosingDeclaration = saveEnclosingDeclaration;
|
||||
const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;
|
||||
if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length) {
|
||||
const signatures = getSignaturesOfType(propertyType, SignatureKind.Call);
|
||||
for (const signature of signatures) {
|
||||
const methodDeclaration = <MethodSignature>signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, context);
|
||||
methodDeclaration.name = propertyName;
|
||||
methodDeclaration.questionToken = optionalToken;
|
||||
if (propertySymbol.valueDeclaration) {
|
||||
// Copy comments to node for declaration emit
|
||||
setCommentRange(methodDeclaration, propertySymbol.valueDeclaration);
|
||||
}
|
||||
typeElements.push(methodDeclaration);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const savedFlags = context.flags;
|
||||
context.flags |= !!(getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped) ? NodeBuilderFlags.InReverseMappedType : 0;
|
||||
const propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType, context) : createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
context.flags = savedFlags;
|
||||
|
||||
const modifiers = isReadonlySymbol(propertySymbol) ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined;
|
||||
if (modifiers) {
|
||||
context.approximateLength += 9;
|
||||
}
|
||||
const propertySignature = createPropertySignature(
|
||||
modifiers,
|
||||
propertyName,
|
||||
optionalToken,
|
||||
propertyTypeNode,
|
||||
/*initializer*/ undefined);
|
||||
if (propertySymbol.valueDeclaration) {
|
||||
// Copy comments to node for declaration emit
|
||||
setCommentRange(propertySignature, propertySymbol.valueDeclaration);
|
||||
}
|
||||
typeElements.push(propertySignature);
|
||||
}
|
||||
}
|
||||
|
||||
function mapToTypeNodes(types: ReadonlyArray<Type> | undefined, context: NodeBuilderContext, isBareList?: boolean): TypeNode[] | undefined {
|
||||
if (some(types)) {
|
||||
if (checkTruncationLength(context)) {
|
||||
if (!isBareList) {
|
||||
return [createTypeReferenceNode("...", /*typeArguments*/ undefined)];
|
||||
}
|
||||
else if (types.length > 2) {
|
||||
return [
|
||||
typeToTypeNodeHelper(types[0], context),
|
||||
createTypeReferenceNode(`... ${types.length - 2} more ...`, /*typeArguments*/ undefined),
|
||||
typeToTypeNodeHelper(types[types.length - 1], context)
|
||||
];
|
||||
}
|
||||
}
|
||||
const result = [];
|
||||
let i = 0;
|
||||
for (const type of types) {
|
||||
i++;
|
||||
if (checkTruncationLength(context) && (i + 2 < types.length - 1)) {
|
||||
result.push(createTypeReferenceNode(`... ${types.length - i} more ...`, /*typeArguments*/ undefined));
|
||||
const typeNode = typeToTypeNodeHelper(types[types.length - 1], context);
|
||||
if (typeNode) {
|
||||
result.push(typeNode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
context.approximateLength += 2; // Account for whitespace + separator
|
||||
const typeNode = typeToTypeNodeHelper(type, context);
|
||||
if (typeNode) {
|
||||
result.push(typeNode);
|
||||
@@ -3553,6 +3644,7 @@ namespace ts {
|
||||
if (!indexInfo.type && !(context.flags & NodeBuilderFlags.AllowEmptyIndexInfoType)) {
|
||||
context.encounteredError = true;
|
||||
}
|
||||
context.approximateLength += (name.length + 4);
|
||||
return createIndexSignature(
|
||||
/*decorators*/ undefined,
|
||||
indexInfo.isReadonly ? [createToken(SyntaxKind.ReadonlyKeyword)] : undefined,
|
||||
@@ -3597,6 +3689,7 @@ namespace ts {
|
||||
else if (!returnTypeNode) {
|
||||
returnTypeNode = createKeywordTypeNode(SyntaxKind.AnyKeyword);
|
||||
}
|
||||
context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum
|
||||
return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode, typeArguments);
|
||||
}
|
||||
|
||||
@@ -3658,6 +3751,7 @@ namespace ts {
|
||||
questionToken,
|
||||
parameterTypeNode,
|
||||
/*initializer*/ undefined);
|
||||
context.approximateLength += symbolName(parameterSymbol).length + 3;
|
||||
return parameterNode;
|
||||
|
||||
function cloneBindingName(node: BindingName): BindingName {
|
||||
@@ -3812,7 +3906,9 @@ namespace ts {
|
||||
// module is root, must use `ImportTypeNode`
|
||||
const nonRootParts = chain.length > 1 ? createAccessFromSymbolChain(chain, chain.length - 1, 1) : undefined;
|
||||
const typeParameterNodes = overrideTypeArguments || lookupTypeParameterNodes(chain, 0, context);
|
||||
const lit = createLiteralTypeNode(createLiteral(getSpecifierForModuleSymbol(chain[0], context)));
|
||||
const specifier = getSpecifierForModuleSymbol(chain[0], context);
|
||||
const lit = createLiteralTypeNode(createLiteral(specifier));
|
||||
context.approximateLength += specifier.length + 10; // specifier + import("")
|
||||
if (!nonRootParts || isEntityName(nonRootParts)) {
|
||||
if (nonRootParts) {
|
||||
const lastId = isIdentifier(nonRootParts) ? nonRootParts : nonRootParts.right;
|
||||
@@ -3849,6 +3945,7 @@ namespace ts {
|
||||
context.flags |= NodeBuilderFlags.InInitialEntityName;
|
||||
}
|
||||
const symbolName = getNameOfSymbolAsWritten(symbol, context);
|
||||
context.approximateLength += symbolName.length + 1;
|
||||
if (index === 0) {
|
||||
context.flags ^= NodeBuilderFlags.InInitialEntityName;
|
||||
}
|
||||
@@ -4033,6 +4130,8 @@ namespace ts {
|
||||
encounteredError: boolean;
|
||||
visitedSymbols: Map<true> | undefined;
|
||||
inferTypeParameters: TypeParameter[] | undefined;
|
||||
approximateLength: number;
|
||||
truncating?: boolean;
|
||||
}
|
||||
|
||||
function isDefaultBindingContext(location: Node) {
|
||||
@@ -5904,6 +6003,12 @@ namespace ts {
|
||||
&& isTypeUsableAsLateBoundName(checkComputedPropertyName(node));
|
||||
}
|
||||
|
||||
function isLateBoundName(name: __String): boolean {
|
||||
return (name as string).charCodeAt(0) === CharacterCodes._ &&
|
||||
(name as string).charCodeAt(1) === CharacterCodes._ &&
|
||||
(name as string).charCodeAt(2) === CharacterCodes.at;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether a declaration has a late-bindable dynamic name.
|
||||
*/
|
||||
@@ -7010,6 +7115,7 @@ namespace ts {
|
||||
|
||||
function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined {
|
||||
let props: Symbol[] | undefined;
|
||||
let indexTypes: Type[] | undefined;
|
||||
const isUnion = containingType.flags & TypeFlags.Union;
|
||||
const excludeModifiers = isUnion ? ModifierFlags.NonPublicAccessibilityModifier : 0;
|
||||
// Flags we want to propagate to the result if they exist in all source symbols
|
||||
@@ -7034,14 +7140,21 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (isUnion) {
|
||||
checkFlags |= CheckFlags.Partial;
|
||||
const index = !isLateBoundName(name) && ((isNumericLiteralName(name) && getIndexInfoOfType(type, IndexKind.Number)) || getIndexInfoOfType(type, IndexKind.String));
|
||||
if (index) {
|
||||
checkFlags |= index.isReadonly ? CheckFlags.Readonly : 0;
|
||||
indexTypes = append(indexTypes, index.type);
|
||||
}
|
||||
else {
|
||||
checkFlags |= CheckFlags.Partial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!props) {
|
||||
return undefined;
|
||||
}
|
||||
if (props.length === 1 && !(checkFlags & CheckFlags.Partial)) {
|
||||
if (props.length === 1 && !(checkFlags & CheckFlags.Partial) && !indexTypes) {
|
||||
return props[0];
|
||||
}
|
||||
let declarations: Declaration[] | undefined;
|
||||
@@ -7072,6 +7185,7 @@ namespace ts {
|
||||
}
|
||||
propTypes.push(type);
|
||||
}
|
||||
addRange(propTypes, indexTypes);
|
||||
const result = createSymbol(SymbolFlags.Property | commonFlags, name, syntheticFlag | checkFlags);
|
||||
result.containingType = containingType;
|
||||
if (!hasNonUniformValueDeclaration && commonValueDeclaration) {
|
||||
@@ -8137,7 +8251,7 @@ namespace ts {
|
||||
// The expression is processed as an identifier expression (section 4.3)
|
||||
// or property access expression(section 4.10),
|
||||
// the widened type(section 3.9) of which becomes the result.
|
||||
links.resolvedType = getWidenedType(checkExpression(node.exprName));
|
||||
links.resolvedType = getRegularTypeOfLiteralType(getWidenedType(checkExpression(node.exprName)));
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
@@ -10254,9 +10368,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (!issuedElaboration && (length(targetProp && targetProp.declarations) || length(target.symbol && target.symbol.declarations))) {
|
||||
if (!issuedElaboration && (targetProp && length(targetProp.declarations) || target.symbol && length(target.symbol.declarations))) {
|
||||
addRelatedInfo(reportedDiag, createDiagnosticForNode(
|
||||
targetProp ? targetProp.declarations[0] : target.symbol.declarations[0],
|
||||
targetProp && length(targetProp.declarations) ? targetProp.declarations[0] : target.symbol.declarations[0],
|
||||
Diagnostics.The_expected_type_comes_from_property_0_which_is_declared_here_on_type_1,
|
||||
propertyName && !(nameType.flags & TypeFlags.UniqueESSymbol) ? unescapeLeadingUnderscores(propertyName) : typeToString(nameType),
|
||||
typeToString(target)
|
||||
@@ -17661,7 +17775,7 @@ namespace ts {
|
||||
|
||||
if (diagnosticMessage) {
|
||||
addRelatedInfo(diagnosticMessage,
|
||||
createDiagnosticForNode(valueDeclaration, Diagnostics._0_was_declared_here, declarationName)
|
||||
createDiagnosticForNode(valueDeclaration, Diagnostics._0_is_declared_here, declarationName)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -17711,6 +17825,7 @@ namespace ts {
|
||||
|
||||
function reportNonexistentProperty(propNode: Identifier, containingType: Type) {
|
||||
let errorInfo: DiagnosticMessageChain | undefined;
|
||||
let relatedInfo: Diagnostic | undefined;
|
||||
if (containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) {
|
||||
for (const subtype of (containingType as UnionType).types) {
|
||||
if (!getPropertyOfType(subtype, propNode.escapedText)) {
|
||||
@@ -17724,30 +17839,34 @@ namespace ts {
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await, declarationNameToString(propNode), typeToString(containingType));
|
||||
}
|
||||
else {
|
||||
const suggestion = getSuggestionForNonexistentProperty(propNode, containingType);
|
||||
const suggestion = getSuggestedSymbolForNonexistentProperty(propNode, containingType);
|
||||
if (suggestion !== undefined) {
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestion);
|
||||
const suggestedName = symbolName(suggestion);
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestedName);
|
||||
relatedInfo = suggestion.valueDeclaration && createDiagnosticForNode(suggestion.valueDeclaration, Diagnostics._0_is_declared_here, suggestedName);
|
||||
}
|
||||
else {
|
||||
const suggestion = getSuggestionForNonexistentProperty(propNode, containingType);
|
||||
if (suggestion !== undefined) {
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, declarationNameToString(propNode), typeToString(containingType), suggestion);
|
||||
}
|
||||
else {
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType));
|
||||
}
|
||||
errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Property_0_does_not_exist_on_type_1, declarationNameToString(propNode), typeToString(containingType));
|
||||
}
|
||||
}
|
||||
|
||||
diagnostics.add(createDiagnosticForNodeFromMessageChain(propNode, errorInfo));
|
||||
const resultDiagnostic = createDiagnosticForNodeFromMessageChain(propNode, errorInfo);
|
||||
if (relatedInfo) {
|
||||
addRelatedInfo(resultDiagnostic, relatedInfo);
|
||||
}
|
||||
diagnostics.add(resultDiagnostic);
|
||||
}
|
||||
|
||||
function getSuggestedSymbolForNonexistentProperty(name: Identifier | string, containingType: Type): Symbol | undefined {
|
||||
return getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value);
|
||||
}
|
||||
|
||||
function getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined {
|
||||
const suggestion = getSpellingSuggestionForName(isString(name) ? name : idText(name), getPropertiesOfType(containingType), SymbolFlags.Value);
|
||||
const suggestion = getSuggestedSymbolForNonexistentProperty(name, containingType);
|
||||
return suggestion && symbolName(suggestion);
|
||||
}
|
||||
|
||||
function getSuggestionForNonexistentSymbol(location: Node | undefined, outerName: __String, meaning: SymbolFlags): string | undefined {
|
||||
function getSuggestedSymbolForNonexistentSymbol(location: Node | undefined, outerName: __String, meaning: SymbolFlags): Symbol | undefined {
|
||||
Debug.assert(outerName !== undefined, "outername should always be defined");
|
||||
const result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, /*excludeGlobals*/ false, (symbols, name, meaning) => {
|
||||
Debug.assertEqual(outerName, name, "name should equal outerName");
|
||||
@@ -17757,11 +17876,20 @@ namespace ts {
|
||||
// However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion.
|
||||
return symbol || getSpellingSuggestionForName(unescapeLeadingUnderscores(name), arrayFrom(symbols.values()), meaning);
|
||||
});
|
||||
return result && symbolName(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function getSuggestionForNonexistentModule(name: Identifier, targetModule: Symbol): string | undefined {
|
||||
const suggestion = targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember);
|
||||
function getSuggestionForNonexistentSymbol(location: Node | undefined, outerName: __String, meaning: SymbolFlags): string | undefined {
|
||||
const symbolResult = getSuggestedSymbolForNonexistentSymbol(location, outerName, meaning);
|
||||
return symbolResult && symbolName(symbolResult);
|
||||
}
|
||||
|
||||
function getSuggestedSymbolForNonexistentModule(name: Identifier, targetModule: Symbol): Symbol | undefined {
|
||||
return targetModule.exports && getSpellingSuggestionForName(idText(name), getExportsOfModuleAsArray(targetModule), SymbolFlags.ModuleMember);
|
||||
}
|
||||
|
||||
function getSuggestionForNonexistentExport(name: Identifier, targetModule: Symbol): string | undefined {
|
||||
const suggestion = getSuggestedSymbolForNonexistentModule(name, targetModule);
|
||||
return suggestion && symbolName(suggestion);
|
||||
}
|
||||
|
||||
@@ -19218,6 +19346,38 @@ namespace ts {
|
||||
return resolveErrorCall(node);
|
||||
}
|
||||
|
||||
function typeHasProtectedAccessibleBase(target: Symbol, type: InterfaceType): boolean {
|
||||
const baseTypes = getBaseTypes(type);
|
||||
if (!length(baseTypes)) {
|
||||
return false;
|
||||
}
|
||||
const firstBase = baseTypes[0];
|
||||
if (firstBase.flags & TypeFlags.Intersection) {
|
||||
const types = (firstBase as IntersectionType).types;
|
||||
const mixinCount = countWhere(types, isMixinConstructorType);
|
||||
let i = 0;
|
||||
for (const intersectionMember of (firstBase as IntersectionType).types) {
|
||||
i++;
|
||||
// We want to ignore mixin ctors
|
||||
if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(intersectionMember)) {
|
||||
if (getObjectFlags(intersectionMember) & (ObjectFlags.Class | ObjectFlags.Interface)) {
|
||||
if (intersectionMember.symbol === target) {
|
||||
return true;
|
||||
}
|
||||
if (typeHasProtectedAccessibleBase(target, intersectionMember as InterfaceType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (firstBase.symbol === target) {
|
||||
return true;
|
||||
}
|
||||
return typeHasProtectedAccessibleBase(target, firstBase as InterfaceType);
|
||||
}
|
||||
|
||||
function isConstructorAccessible(node: NewExpression, signature: Signature) {
|
||||
if (!signature || !signature.declaration) {
|
||||
return true;
|
||||
@@ -19237,16 +19397,10 @@ namespace ts {
|
||||
// A private or protected constructor can only be instantiated within its own class (or a subclass, for protected)
|
||||
if (!isNodeWithinClass(node, declaringClassDeclaration)) {
|
||||
const containingClass = getContainingClass(node);
|
||||
if (containingClass) {
|
||||
if (containingClass && modifiers & ModifierFlags.Protected) {
|
||||
const containingType = getTypeOfNode(containingClass);
|
||||
let baseTypes = getBaseTypes(containingType as InterfaceType);
|
||||
while (baseTypes.length) {
|
||||
const baseType = baseTypes[0];
|
||||
if (modifiers & ModifierFlags.Protected &&
|
||||
baseType.symbol === declaration.parent.symbol) {
|
||||
return true;
|
||||
}
|
||||
baseTypes = getBaseTypes(baseType as InterfaceType);
|
||||
if (typeHasProtectedAccessibleBase(declaration.parent.symbol, containingType as InterfaceType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (modifiers & ModifierFlags.Private) {
|
||||
@@ -20975,7 +21129,7 @@ namespace ts {
|
||||
getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], UnionReduction.Subtype) :
|
||||
leftType;
|
||||
case SyntaxKind.EqualsToken:
|
||||
const special = getSpecialPropertyAssignmentKind(left.parent as BinaryExpression);
|
||||
const special = isBinaryExpression(left.parent) ? getSpecialPropertyAssignmentKind(left.parent) : SpecialPropertyAssignmentKind.None;
|
||||
checkSpecialAssignment(special, right);
|
||||
if (isJSSpecialPropertyAssignment(special)) {
|
||||
return leftType;
|
||||
|
||||
@@ -2401,8 +2401,8 @@
|
||||
"category": "Error",
|
||||
"code": 2727
|
||||
},
|
||||
"'{0}' was declared here.": {
|
||||
"category": "Error",
|
||||
"'{0}' is declared here.": {
|
||||
"category": "Message",
|
||||
"code": 2728
|
||||
},
|
||||
"Property '{0}' is used before its initialization.": {
|
||||
@@ -2864,6 +2864,10 @@
|
||||
"category": "Error",
|
||||
"code": 5070
|
||||
},
|
||||
"Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.": {
|
||||
"category": "Error",
|
||||
"code": 5071
|
||||
},
|
||||
|
||||
"Generates a sourcemap for each corresponding '.d.ts' file.": {
|
||||
"category": "Message",
|
||||
@@ -3886,7 +3890,7 @@
|
||||
"code": 7037
|
||||
},
|
||||
"Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.": {
|
||||
"category": "Error",
|
||||
"category": "Message",
|
||||
"code": 7038
|
||||
},
|
||||
"Mapped object type implicitly has an 'any' template type.": {
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace ts {
|
||||
if (sourceFile.kind === SyntaxKind.Bundle) {
|
||||
const jsFilePath = options.outFile || options.out!;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = (forceDtsPaths || options.declaration) ? removeFileExtension(jsFilePath) + Extension.Dts : undefined;
|
||||
const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(jsFilePath) + Extension.Dts : undefined;
|
||||
const declarationMapPath = getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
const bundleInfoPath = options.references && jsFilePath ? (removeFileExtension(jsFilePath) + infoExtension) : undefined;
|
||||
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath };
|
||||
@@ -53,7 +53,7 @@ namespace ts {
|
||||
const sourceMapFilePath = isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options);
|
||||
// For legacy reasons (ie, we have baselines capturing the behavior), js files don't report a .d.ts output path - this would only matter if `declaration` and `allowJs` were both on, which is currently an error
|
||||
const isJs = isSourceFileJavaScript(sourceFile);
|
||||
const declarationFilePath = ((forceDtsPaths || options.declaration) && !isJs) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
|
||||
const declarationFilePath = ((forceDtsPaths || getEmitDeclarations(options)) && !isJs) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
|
||||
const declarationMapPath = getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath: undefined };
|
||||
}
|
||||
@@ -192,7 +192,7 @@ namespace ts {
|
||||
// Setup and perform the transformation to retrieve declarations from the input files
|
||||
const nonJsFiles = filter(sourceFiles, isSourceFileNotJavaScript);
|
||||
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(nonJsFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : nonJsFiles;
|
||||
if (emitOnlyDtsFiles && !compilerOptions.declaration) {
|
||||
if (emitOnlyDtsFiles && !getEmitDeclarations(compilerOptions)) {
|
||||
// Checker wont collect the linked aliases since thats only done when declaration is enabled.
|
||||
// Do that here when emitting only dts files
|
||||
nonJsFiles.forEach(collectLinkedAliases);
|
||||
|
||||
@@ -4183,11 +4183,15 @@ namespace ts {
|
||||
*/
|
||||
export function parenthesizeDefaultExpression(e: Expression) {
|
||||
const check = skipPartiallyEmittedExpressions(e);
|
||||
return check.kind === SyntaxKind.ClassExpression ||
|
||||
check.kind === SyntaxKind.FunctionExpression ||
|
||||
isCommaSequence(check)
|
||||
? createParen(e)
|
||||
: e;
|
||||
let needsParens = isCommaSequence(check);
|
||||
if (!needsParens) {
|
||||
switch (getLeftmostExpression(check, /*stopAtCallExpression*/ false).kind) {
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
needsParens = true;
|
||||
}
|
||||
}
|
||||
return needsParens ? createParen(e) : e;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2329,7 +2329,7 @@ namespace ts {
|
||||
if (!sourceFile.isDeclarationFile) {
|
||||
const absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
|
||||
if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, options.rootDir));
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, rootDirectory));
|
||||
allFilesBelongToPath = false;
|
||||
}
|
||||
}
|
||||
@@ -2500,7 +2500,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (options.declarationMap && !options.declaration) {
|
||||
if (options.declarationMap && !getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationMap", "declaration");
|
||||
}
|
||||
|
||||
@@ -2548,6 +2548,10 @@ namespace ts {
|
||||
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule");
|
||||
}
|
||||
// Any emit other than common js is error
|
||||
else if (getEmitModuleKind(options) !== ModuleKind.CommonJS) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs, "resolveJsonModule", "module");
|
||||
}
|
||||
}
|
||||
|
||||
// there has to be common source directory if user specified --outdir || --sourceRoot
|
||||
|
||||
@@ -81,6 +81,7 @@ namespace ts {
|
||||
let filesWithInvalidatedResolutions: Map<true> | undefined;
|
||||
let filesWithInvalidatedNonRelativeUnresolvedImports: Map<ReadonlyArray<string>> | undefined;
|
||||
let allFilesHaveInvalidatedResolution = false;
|
||||
const nonRelativeExternalModuleResolutions = createMultiMap<ResolutionWithFailedLookupLocations>();
|
||||
|
||||
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory!()); // TODO: GH#18217
|
||||
const cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
|
||||
@@ -154,6 +155,7 @@ namespace ts {
|
||||
function clear() {
|
||||
clearMap(directoryWatchesOfFailedLookups, closeFileWatcherOf);
|
||||
customFailedLookupPaths.clear();
|
||||
nonRelativeExternalModuleResolutions.clear();
|
||||
closeTypeRootsWatch();
|
||||
resolvedModuleNames.clear();
|
||||
resolvedTypeReferenceDirectives.clear();
|
||||
@@ -199,19 +201,20 @@ namespace ts {
|
||||
perDirectoryResolvedModuleNames.clear();
|
||||
nonRelaticeModuleNameCache.clear();
|
||||
perDirectoryResolvedTypeReferenceDirectives.clear();
|
||||
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
|
||||
nonRelativeExternalModuleResolutions.clear();
|
||||
}
|
||||
|
||||
function finishCachingPerDirectoryResolution() {
|
||||
allFilesHaveInvalidatedResolution = false;
|
||||
filesWithInvalidatedNonRelativeUnresolvedImports = undefined;
|
||||
clearPerDirectoryResolutions();
|
||||
directoryWatchesOfFailedLookups.forEach((watcher, path) => {
|
||||
if (watcher.refCount === 0) {
|
||||
directoryWatchesOfFailedLookups.delete(path);
|
||||
watcher.watcher.close();
|
||||
}
|
||||
});
|
||||
|
||||
clearPerDirectoryResolutions();
|
||||
}
|
||||
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): CachedResolvedModuleWithFailedLookupLocations {
|
||||
@@ -275,7 +278,7 @@ namespace ts {
|
||||
perDirectoryResolution.set(name, resolution);
|
||||
}
|
||||
resolutionsInFile.set(name, resolution);
|
||||
watchFailedLookupLocationOfResolution(resolution);
|
||||
watchFailedLookupLocationsOfExternalModuleResolutions(name, resolution);
|
||||
if (existingResolution) {
|
||||
stopWatchFailedLookupLocationOfResolution(existingResolution);
|
||||
}
|
||||
@@ -441,18 +444,27 @@ namespace ts {
|
||||
return fileExtensionIsOneOf(path, failedLookupDefaultExtensions);
|
||||
}
|
||||
|
||||
function watchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) {
|
||||
function watchFailedLookupLocationsOfExternalModuleResolutions(name: string, resolution: ResolutionWithFailedLookupLocations) {
|
||||
// No need to set the resolution refCount
|
||||
if (!resolution.failedLookupLocations || !resolution.failedLookupLocations.length) {
|
||||
return;
|
||||
if (resolution.failedLookupLocations && resolution.failedLookupLocations.length) {
|
||||
if (resolution.refCount) {
|
||||
resolution.refCount++;
|
||||
}
|
||||
else {
|
||||
resolution.refCount = 1;
|
||||
if (isExternalModuleNameRelative(name)) {
|
||||
watchFailedLookupLocationOfResolution(resolution);
|
||||
}
|
||||
else {
|
||||
nonRelativeExternalModuleResolutions.add(name, resolution);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resolution.refCount !== undefined) {
|
||||
resolution.refCount++;
|
||||
return;
|
||||
}
|
||||
function watchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) {
|
||||
Debug.assert(!!resolution.refCount);
|
||||
|
||||
resolution.refCount = 1;
|
||||
const { failedLookupLocations } = resolution;
|
||||
let setAtRoot = false;
|
||||
for (const failedLookupLocation of failedLookupLocations) {
|
||||
@@ -480,6 +492,16 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function setRefCountToUndefined(resolution: ResolutionWithFailedLookupLocations) {
|
||||
resolution.refCount = undefined;
|
||||
}
|
||||
|
||||
function watchFailedLookupLocationOfNonRelativeModuleResolutions(resolutions: ResolutionWithFailedLookupLocations[], name: string) {
|
||||
const updateResolution = resolutionHost.getCurrentProgram().getTypeChecker().tryFindAmbientModuleWithoutAugmentations(name) ?
|
||||
setRefCountToUndefined : watchFailedLookupLocationOfResolution;
|
||||
resolutions.forEach(updateResolution);
|
||||
}
|
||||
|
||||
function setDirectoryWatcher(dir: string, dirPath: Path, nonRecursive?: boolean) {
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
if (dirWatcher) {
|
||||
@@ -492,11 +514,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function stopWatchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) {
|
||||
if (!resolution.failedLookupLocations || !resolution.failedLookupLocations.length) {
|
||||
if (!resolution.refCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
resolution.refCount!--;
|
||||
resolution.refCount--;
|
||||
if (resolution.refCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
+65
-31
@@ -332,9 +332,9 @@ namespace ts {
|
||||
/*@internal*/
|
||||
export interface RecursiveDirectoryWatcherHost {
|
||||
watchDirectory: HostWatchDirectory;
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
getAccessibleSortedChildDirectories(path: string): ReadonlyArray<string>;
|
||||
directoryExists(dir: string): boolean;
|
||||
filePathComparer: Comparer<string>;
|
||||
realpath(s: string): string;
|
||||
}
|
||||
|
||||
@@ -345,60 +345,94 @@ namespace ts {
|
||||
*/
|
||||
/*@internal*/
|
||||
export function createRecursiveDirectoryWatcher(host: RecursiveDirectoryWatcherHost): (directoryName: string, callback: DirectoryWatcherCallback) => FileWatcher {
|
||||
type ChildWatches = ReadonlyArray<DirectoryWatcher>;
|
||||
interface DirectoryWatcher extends FileWatcher {
|
||||
childWatches: ChildWatches;
|
||||
interface ChildDirectoryWatcher extends FileWatcher {
|
||||
dirName: string;
|
||||
}
|
||||
type ChildWatches = ReadonlyArray<ChildDirectoryWatcher>;
|
||||
interface HostDirectoryWatcher {
|
||||
watcher: FileWatcher;
|
||||
childWatches: ChildWatches;
|
||||
refCount: number;
|
||||
}
|
||||
|
||||
const cache = createMap<HostDirectoryWatcher>();
|
||||
const callbackCache = createMultiMap<DirectoryWatcherCallback>();
|
||||
const filePathComparer = getStringComparer(!host.useCaseSensitiveFileNames);
|
||||
const toCanonicalFilePath = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
|
||||
|
||||
return createDirectoryWatcher;
|
||||
|
||||
/**
|
||||
* Create the directory watcher for the dirPath.
|
||||
*/
|
||||
function createDirectoryWatcher(dirName: string, callback: DirectoryWatcherCallback): DirectoryWatcher {
|
||||
const watcher = host.watchDirectory(dirName, fileName => {
|
||||
// Call the actual callback
|
||||
callback(fileName);
|
||||
function createDirectoryWatcher(dirName: string, callback?: DirectoryWatcherCallback): ChildDirectoryWatcher {
|
||||
const dirPath = toCanonicalFilePath(dirName) as Path;
|
||||
let directoryWatcher = cache.get(dirPath);
|
||||
if (directoryWatcher) {
|
||||
directoryWatcher.refCount++;
|
||||
}
|
||||
else {
|
||||
directoryWatcher = {
|
||||
watcher: host.watchDirectory(dirName, fileName => {
|
||||
// Call the actual callback
|
||||
callbackCache.forEach((callbacks, rootDirName) => {
|
||||
if (rootDirName === dirPath || (startsWith(dirPath, rootDirName) && dirPath[rootDirName.length] === directorySeparator)) {
|
||||
callbacks.forEach(callback => callback(fileName));
|
||||
}
|
||||
});
|
||||
|
||||
// Iterate through existing children and update the watches if needed
|
||||
updateChildWatches(result, callback);
|
||||
});
|
||||
// Iterate through existing children and update the watches if needed
|
||||
updateChildWatches(dirName, dirPath);
|
||||
}),
|
||||
refCount: 1,
|
||||
childWatches: emptyArray
|
||||
};
|
||||
cache.set(dirPath, directoryWatcher);
|
||||
updateChildWatches(dirName, dirPath);
|
||||
}
|
||||
|
||||
let result: DirectoryWatcher = {
|
||||
close: () => {
|
||||
watcher.close();
|
||||
result.childWatches.forEach(closeFileWatcher);
|
||||
result = undefined!;
|
||||
},
|
||||
if (callback) {
|
||||
callbackCache.add(dirPath, callback);
|
||||
}
|
||||
|
||||
return {
|
||||
dirName,
|
||||
childWatches: emptyArray
|
||||
close: () => {
|
||||
const directoryWatcher = Debug.assertDefined(cache.get(dirPath));
|
||||
if (callback) callbackCache.remove(dirPath, callback);
|
||||
directoryWatcher.refCount--;
|
||||
|
||||
if (directoryWatcher.refCount) return;
|
||||
|
||||
cache.delete(dirPath);
|
||||
closeFileWatcherOf(directoryWatcher);
|
||||
directoryWatcher.childWatches.forEach(closeFileWatcher);
|
||||
}
|
||||
};
|
||||
updateChildWatches(result, callback);
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateChildWatches(watcher: DirectoryWatcher, callback: DirectoryWatcherCallback) {
|
||||
function updateChildWatches(dirName: string, dirPath: Path) {
|
||||
// Iterate through existing children and update the watches if needed
|
||||
if (watcher) {
|
||||
watcher.childWatches = watchChildDirectories(watcher.dirName, watcher.childWatches, callback);
|
||||
const parentWatcher = cache.get(dirPath);
|
||||
if (parentWatcher) {
|
||||
parentWatcher.childWatches = watchChildDirectories(dirName, parentWatcher.childWatches);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Watch the directories in the parentDir
|
||||
*/
|
||||
function watchChildDirectories(parentDir: string, existingChildWatches: ChildWatches, callback: DirectoryWatcherCallback): ChildWatches {
|
||||
let newChildWatches: DirectoryWatcher[] | undefined;
|
||||
enumerateInsertsAndDeletes<string, DirectoryWatcher>(
|
||||
function watchChildDirectories(parentDir: string, existingChildWatches: ChildWatches): ChildWatches {
|
||||
let newChildWatches: ChildDirectoryWatcher[] | undefined;
|
||||
enumerateInsertsAndDeletes<string, ChildDirectoryWatcher>(
|
||||
host.directoryExists(parentDir) ? mapDefined(host.getAccessibleSortedChildDirectories(parentDir), child => {
|
||||
const childFullName = getNormalizedAbsolutePath(child, parentDir);
|
||||
// Filter our the symbolic link directories since those arent included in recursive watch
|
||||
// which is same behaviour when recursive: true is passed to fs.watch
|
||||
return host.filePathComparer(childFullName, host.realpath(childFullName)) === Comparison.EqualTo ? childFullName : undefined;
|
||||
return filePathComparer(childFullName, normalizePath(host.realpath(childFullName))) === Comparison.EqualTo ? childFullName : undefined;
|
||||
}) : emptyArray,
|
||||
existingChildWatches,
|
||||
(child, childWatcher) => host.filePathComparer(child, childWatcher.dirName),
|
||||
(child, childWatcher) => filePathComparer(child, childWatcher.dirName),
|
||||
createAndAddChildDirectoryWatcher,
|
||||
closeFileWatcher,
|
||||
addChildDirectoryWatcher
|
||||
@@ -410,14 +444,14 @@ namespace ts {
|
||||
* Create new childDirectoryWatcher and add it to the new ChildDirectoryWatcher list
|
||||
*/
|
||||
function createAndAddChildDirectoryWatcher(childName: string) {
|
||||
const result = createDirectoryWatcher(childName, callback);
|
||||
const result = createDirectoryWatcher(childName);
|
||||
addChildDirectoryWatcher(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add child directory watcher to the new ChildDirectoryWatcher list
|
||||
*/
|
||||
function addChildDirectoryWatcher(childWatcher: DirectoryWatcher) {
|
||||
function addChildDirectoryWatcher(childWatcher: ChildDirectoryWatcher) {
|
||||
(newChildWatches || (newChildWatches = [])).push(childWatcher);
|
||||
}
|
||||
}
|
||||
@@ -710,7 +744,7 @@ namespace ts {
|
||||
createWatchDirectoryUsing(dynamicPollingWatchFile || createDynamicPriorityPollingWatchFile({ getModifiedTime, setTimeout })) :
|
||||
watchDirectoryUsingFsWatch;
|
||||
const watchDirectoryRecursively = createRecursiveDirectoryWatcher({
|
||||
filePathComparer: getStringComparer(!useCaseSensitiveFileNames),
|
||||
useCaseSensitiveFileNames,
|
||||
directoryExists,
|
||||
getAccessibleSortedChildDirectories: path => getAccessibleFileSystemEntries(path).directories,
|
||||
watchDirectory,
|
||||
|
||||
@@ -11,11 +11,12 @@ namespace ts {
|
||||
|
||||
const declarationEmitNodeBuilderFlags =
|
||||
NodeBuilderFlags.MultilineObjectLiterals |
|
||||
TypeFormatFlags.WriteClassExpressionAsTypeLiteral |
|
||||
NodeBuilderFlags.WriteClassExpressionAsTypeLiteral |
|
||||
NodeBuilderFlags.UseTypeOfFunction |
|
||||
NodeBuilderFlags.UseStructuralFallback |
|
||||
NodeBuilderFlags.AllowEmptyTuple |
|
||||
NodeBuilderFlags.GenerateNamesForShadowedTypeParams;
|
||||
NodeBuilderFlags.GenerateNamesForShadowedTypeParams |
|
||||
NodeBuilderFlags.NoTruncation;
|
||||
|
||||
/**
|
||||
* Transforms a ts file into a .d.ts file
|
||||
|
||||
@@ -1982,18 +1982,16 @@ namespace ts {
|
||||
const kind = resolver.getTypeReferenceSerializationKind(node.typeName, currentNameScope || currentLexicalScope);
|
||||
switch (kind) {
|
||||
case TypeReferenceSerializationKind.Unknown:
|
||||
const serialized = serializeEntityNameAsExpression(node.typeName, /*useFallback*/ true);
|
||||
const serialized = serializeEntityNameAsExpressionFallback(node.typeName);
|
||||
const temp = createTempVariable(hoistVariableDeclaration);
|
||||
return createLogicalOr(
|
||||
createLogicalAnd(
|
||||
createTypeCheck(createAssignment(temp, serialized), "function"),
|
||||
temp
|
||||
),
|
||||
return createConditional(
|
||||
createTypeCheck(createAssignment(temp, serialized), "function"),
|
||||
temp,
|
||||
createIdentifier("Object")
|
||||
);
|
||||
|
||||
case TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue:
|
||||
return serializeEntityNameAsExpression(node.typeName, /*useFallback*/ false);
|
||||
return serializeEntityNameAsExpression(node.typeName);
|
||||
|
||||
case TypeReferenceSerializationKind.VoidNullableOrNeverType:
|
||||
return createVoidZero();
|
||||
@@ -2028,14 +2026,46 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createCheckedValue(left: Expression, right: Expression) {
|
||||
return createLogicalAnd(
|
||||
createStrictInequality(createTypeOf(left), createLiteral("undefined")),
|
||||
right
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes an entity name which may not exist at runtime, but whose access shouldn't throw
|
||||
*
|
||||
* @param node The entity name to serialize.
|
||||
*/
|
||||
function serializeEntityNameAsExpressionFallback(node: EntityName): BinaryExpression {
|
||||
if (node.kind === SyntaxKind.Identifier) {
|
||||
// A -> typeof A !== undefined && A
|
||||
const copied = serializeEntityNameAsExpression(node);
|
||||
return createCheckedValue(copied, copied);
|
||||
}
|
||||
if (node.left.kind === SyntaxKind.Identifier) {
|
||||
// A.B -> typeof A !== undefined && A.B
|
||||
return createCheckedValue(serializeEntityNameAsExpression(node.left), serializeEntityNameAsExpression(node));
|
||||
}
|
||||
// A.B.C -> typeof A !== undefined && (_a = A.B) !== void 0 && _a.C
|
||||
const left = serializeEntityNameAsExpressionFallback(node.left);
|
||||
const temp = createTempVariable(hoistVariableDeclaration);
|
||||
return createLogicalAnd(
|
||||
createLogicalAnd(
|
||||
left.left,
|
||||
createStrictInequality(createAssignment(temp, left.right), createVoidZero())
|
||||
),
|
||||
createPropertyAccess(temp, node.right)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes an entity name as an expression for decorator type metadata.
|
||||
*
|
||||
* @param node The entity name to serialize.
|
||||
* @param useFallback A value indicating whether to use logical operators to test for the
|
||||
* entity name at runtime.
|
||||
*/
|
||||
function serializeEntityNameAsExpression(node: EntityName, useFallback: boolean): SerializedEntityNameAsExpression {
|
||||
function serializeEntityNameAsExpression(node: EntityName): SerializedEntityNameAsExpression {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
// Create a clone of the name with a new parent, and treat it as if it were
|
||||
@@ -2044,20 +2074,11 @@ namespace ts {
|
||||
name.flags &= ~NodeFlags.Synthesized;
|
||||
name.original = undefined;
|
||||
name.parent = getParseTreeNode(currentLexicalScope); // ensure the parent is set to a parse tree node.
|
||||
if (useFallback) {
|
||||
return createLogicalAnd(
|
||||
createStrictInequality(
|
||||
createTypeOf(name),
|
||||
createLiteral("undefined")
|
||||
),
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
return name;
|
||||
|
||||
case SyntaxKind.QualifiedName:
|
||||
return serializeQualifiedNameAsExpression(node, useFallback);
|
||||
return serializeQualifiedNameAsExpression(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2068,26 +2089,8 @@ namespace ts {
|
||||
* @param useFallback A value indicating whether to use logical operators to test for the
|
||||
* qualified name at runtime.
|
||||
*/
|
||||
function serializeQualifiedNameAsExpression(node: QualifiedName, useFallback: boolean): PropertyAccessExpression {
|
||||
let left: SerializedEntityNameAsExpression;
|
||||
if (node.left.kind === SyntaxKind.Identifier) {
|
||||
left = serializeEntityNameAsExpression(node.left, useFallback);
|
||||
}
|
||||
else if (useFallback) {
|
||||
const temp = createTempVariable(hoistVariableDeclaration);
|
||||
left = createLogicalAnd(
|
||||
createAssignment(
|
||||
temp,
|
||||
serializeEntityNameAsExpression(node.left, /*useFallback*/ true)
|
||||
),
|
||||
temp
|
||||
);
|
||||
}
|
||||
else {
|
||||
left = serializeEntityNameAsExpression(node.left, /*useFallback*/ false);
|
||||
}
|
||||
|
||||
return createPropertyAccess(left, node.right);
|
||||
function serializeQualifiedNameAsExpression(node: QualifiedName): SerializedEntityNameAsExpression {
|
||||
return createPropertyAccess(serializeEntityNameAsExpression(node.left), node.right);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -304,7 +304,7 @@ namespace ts {
|
||||
|
||||
const outputs: string[] = [];
|
||||
outputs.push(getOutputJavaScriptFileName(inputFileName, configFile));
|
||||
if (configFile.options.declaration && !fileExtensionIs(inputFileName, Extension.Json)) {
|
||||
if (getEmitDeclarations(configFile.options) && !fileExtensionIs(inputFileName, Extension.Json)) {
|
||||
const dts = getOutputDeclarationFileName(inputFileName, configFile);
|
||||
outputs.push(dts);
|
||||
if (configFile.options.declarationMap) {
|
||||
@@ -320,7 +320,7 @@ namespace ts {
|
||||
}
|
||||
const outputs: string[] = [];
|
||||
outputs.push(project.options.outFile);
|
||||
if (project.options.declaration) {
|
||||
if (getEmitDeclarations(project.options)) {
|
||||
const dts = changeExtension(project.options.outFile, Extension.Dts);
|
||||
outputs.push(dts);
|
||||
if (project.options.declarationMap) {
|
||||
@@ -769,7 +769,10 @@ namespace ts {
|
||||
const program = createProgram(programOptions);
|
||||
|
||||
// Don't emit anything in the presence of syntactic errors or options diagnostics
|
||||
const syntaxDiagnostics = [...program.getOptionsDiagnostics(), ...program.getSyntacticDiagnostics()];
|
||||
const syntaxDiagnostics = [
|
||||
...program.getOptionsDiagnostics(),
|
||||
...program.getConfigFileParsingDiagnostics(),
|
||||
...program.getSyntacticDiagnostics()];
|
||||
if (syntaxDiagnostics.length) {
|
||||
resultFlags |= BuildResultFlags.SyntaxErrors;
|
||||
for (const diag of syntaxDiagnostics) {
|
||||
@@ -780,7 +783,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Don't emit .d.ts if there are decl file errors
|
||||
if (program.getCompilerOptions().declaration) {
|
||||
if (getEmitDeclarations(program.getCompilerOptions())) {
|
||||
const declDiagnostics = program.getDeclarationDiagnostics();
|
||||
if (declDiagnostics.length) {
|
||||
resultFlags |= BuildResultFlags.DeclarationEmitErrors;
|
||||
|
||||
@@ -2994,9 +2994,9 @@ namespace ts {
|
||||
*/
|
||||
/* @internal */ tryGetMemberInModuleExportsAndProperties(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
getApparentType(type: Type): Type;
|
||||
getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined;
|
||||
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
getSuggestionForNonexistentModule(node: Identifier, target: Symbol): string | undefined;
|
||||
/* @internal */ getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined;
|
||||
/* @internal */ getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
/* @internal */ getSuggestionForNonexistentExport(node: Identifier, target: Symbol): string | undefined;
|
||||
getBaseConstraintOfType(type: Type): Type | undefined;
|
||||
getDefaultFromTypeParameter(type: Type): Type | undefined;
|
||||
|
||||
|
||||
+40
-58
@@ -21,6 +21,8 @@ namespace ts {
|
||||
|
||||
export const externalHelpersModuleNameText = "tslib";
|
||||
|
||||
export const defaultMaximumTruncationLength = 160;
|
||||
|
||||
export function getDeclarationOfKind<T extends Declaration>(symbol: Symbol, kind: T["kind"]): T | undefined {
|
||||
const declarations = symbol.declarations;
|
||||
if (declarations) {
|
||||
@@ -3351,21 +3353,6 @@ namespace ts {
|
||||
return node.type || (isInJavaScriptFile(node) ? getJSDocReturnType(node) : undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the effective type parameters. If the node was parsed in a
|
||||
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
|
||||
*/
|
||||
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration> {
|
||||
if (isJSDocSignature(node)) {
|
||||
return emptyArray;
|
||||
}
|
||||
if (isJSDocTypeAlias(node)) {
|
||||
Debug.assert(node.parent.kind === SyntaxKind.JSDocComment);
|
||||
return flatMap(node.parent.tags, tag => isJSDocTemplateTag(tag) ? tag.typeParameters : undefined) as ReadonlyArray<TypeParameterDeclaration>;
|
||||
}
|
||||
return node.typeParameters || (isInJavaScriptFile(node) ? getJSDocTypeParameterDeclarations(node) : emptyArray);
|
||||
}
|
||||
|
||||
export function getJSDocTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration> {
|
||||
return flatMap(getJSDocTags(node), tag => isNonTypeAliasTemplate(tag) ? tag.typeParameters : undefined);
|
||||
}
|
||||
@@ -5022,14 +5009,27 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the return type node for the node if provided via JSDoc's return tag.
|
||||
* Gets the return type node for the node if provided via JSDoc return tag or type tag.
|
||||
*
|
||||
* @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
|
||||
* gets the type from inside the braces.
|
||||
* gets the type from inside the braces, after the fat arrow, etc.
|
||||
*/
|
||||
export function getJSDocReturnType(node: Node): TypeNode | undefined {
|
||||
const returnTag = getJSDocReturnTag(node);
|
||||
return returnTag && returnTag.typeExpression && returnTag.typeExpression.type;
|
||||
if (returnTag && returnTag.typeExpression) {
|
||||
return returnTag.typeExpression.type;
|
||||
}
|
||||
const typeTag = getJSDocTypeTag(node);
|
||||
if (typeTag && typeTag.typeExpression) {
|
||||
const type = typeTag.typeExpression.type;
|
||||
if (isTypeLiteralNode(type)) {
|
||||
const sig = find(type.members, isCallSignatureDeclaration);
|
||||
return sig && sig.type;
|
||||
}
|
||||
if (isFunctionTypeNode(type)) {
|
||||
return type.type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Get all JSDoc tags related to a node, including those on parent nodes. */
|
||||
@@ -5053,6 +5053,21 @@ namespace ts {
|
||||
export function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): ReadonlyArray<JSDocTag> {
|
||||
return getJSDocTags(node).filter(doc => doc.kind === kind);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the effective type parameters. If the node was parsed in a
|
||||
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
|
||||
*/
|
||||
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration> {
|
||||
if (isJSDocSignature(node)) {
|
||||
return emptyArray;
|
||||
}
|
||||
if (isJSDocTypeAlias(node)) {
|
||||
Debug.assert(node.parent.kind === SyntaxKind.JSDocComment);
|
||||
return flatMap(node.parent.tags, tag => isJSDocTemplateTag(tag) ? tag.typeParameters : undefined) as ReadonlyArray<TypeParameterDeclaration>;
|
||||
}
|
||||
return node.typeParameters || (isInJavaScriptFile(node) ? getJSDocTypeParameterDeclarations(node) : emptyArray);
|
||||
}
|
||||
}
|
||||
|
||||
// Simple node tests of the form `node.kind === SyntaxKind.Foo`.
|
||||
@@ -6572,45 +6587,6 @@ namespace ts {
|
||||
return !!(node as HasType).type;
|
||||
}
|
||||
|
||||
/* True if the node could have a type node a `.type` */
|
||||
/* @internal */
|
||||
export function couldHaveType(node: Node): node is HasType {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Parameter:
|
||||
case SyntaxKind.PropertySignature:
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.TypePredicate:
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
case SyntaxKind.TypeOperator:
|
||||
case SyntaxKind.MappedType:
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.AsExpression:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.JSDocTypeExpression:
|
||||
case SyntaxKind.JSDocNullableType:
|
||||
case SyntaxKind.JSDocNonNullableType:
|
||||
case SyntaxKind.JSDocOptionalType:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.JSDocVariadicType:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** True if has initializer node attached to it. */
|
||||
/* @internal */
|
||||
export function hasInitializer(node: Node): node is HasInitializer {
|
||||
@@ -6939,7 +6915,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getAreDeclarationMapsEnabled(options: CompilerOptions) {
|
||||
return !!(options.declaration && options.declarationMap);
|
||||
return !!(getEmitDeclarations(options) && options.declarationMap);
|
||||
}
|
||||
|
||||
export function getAllowSyntheticDefaultImports(compilerOptions: CompilerOptions) {
|
||||
@@ -8108,4 +8084,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
export type Mutable<T extends object> = { -readonly [K in keyof T]: T[K] };
|
||||
|
||||
export function sliceAfter<T>(arr: ReadonlyArray<T>, value: T): ReadonlyArray<T> {
|
||||
const index = arr.indexOf(value);
|
||||
Debug.assert(index !== -1);
|
||||
return arr.slice(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ namespace ts {
|
||||
case WatchLogLevel.TriggerOnly:
|
||||
return createFileWatcherWithTriggerLogging;
|
||||
case WatchLogLevel.Verbose:
|
||||
return createFileWatcherWithLogging;
|
||||
return addWatch === <any>watchDirectory ? createDirectoryWatcherWithLogging : createFileWatcherWithLogging;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,6 +413,25 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function createDirectoryWatcherWithLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, undefined>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
|
||||
const watchInfo = `${watchCaption}:: Added:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
|
||||
log(watchInfo);
|
||||
const start = timestamp();
|
||||
const watcher = createFileWatcherWithTriggerLogging(host, file, cb, flags, passThrough, detailInfo1, detailInfo2, addWatch, log, watchCaption, getDetailWatchInfo);
|
||||
const elapsed = timestamp() - start;
|
||||
log(`Elapsed:: ${elapsed}ms ${watchInfo}`);
|
||||
return {
|
||||
close: () => {
|
||||
const watchInfo = `${watchCaption}:: Close:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
|
||||
log(watchInfo);
|
||||
const start = timestamp();
|
||||
watcher.close();
|
||||
const elapsed = timestamp() - start;
|
||||
log(`Elapsed:: ${elapsed}ms ${watchInfo}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function createFileWatcherWithTriggerLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, undefined>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
|
||||
return addWatch(host, file, (fileName, cbOptional) => {
|
||||
const triggerredInfo = `${watchCaption}:: Triggered with ${fileName}${cbOptional !== undefined ? cbOptional : ""}:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
|
||||
|
||||
@@ -1515,7 +1515,9 @@ Actual: ${stringify(fullActual)}`);
|
||||
"argumentCount",
|
||||
];
|
||||
for (const key in options) {
|
||||
ts.Debug.assert(ts.contains(allKeys, key));
|
||||
if (!ts.contains(allKeys, key)) {
|
||||
ts.Debug.fail("Unexpected key " + key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3367,7 +3369,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
|
||||
this.languageServiceAdapterHost.renameFileOrDirectory(oldPath, newPath);
|
||||
this.languageService.cleanupSemanticCache();
|
||||
const pathUpdater = ts.getPathUpdater(oldPath, newPath, ts.createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ false));
|
||||
const pathUpdater = ts.getPathUpdater(oldPath, newPath, ts.createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ false), /*sourceMapper*/ undefined);
|
||||
test(renameKeys(newFileContents, key => pathUpdater(key) || key), "with file moved");
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace Harness.LanguageService {
|
||||
this.vfs.mkdirpSync(ts.getDirectoryPath(newPath));
|
||||
this.vfs.renameSync(oldPath, newPath);
|
||||
|
||||
const updater = ts.getPathUpdater(oldPath, newPath, ts.createGetCanonicalFileName(this.useCaseSensitiveFileNames()));
|
||||
const updater = ts.getPathUpdater(oldPath, newPath, ts.createGetCanonicalFileName(this.useCaseSensitiveFileNames()), /*sourceMapper*/ undefined);
|
||||
this.scriptInfos.forEach((scriptInfo, key) => {
|
||||
const newFileName = updater(key);
|
||||
if (newFileName !== undefined) {
|
||||
|
||||
@@ -352,9 +352,9 @@ interface Array<T> {}`
|
||||
if (tscWatchDirectory === Tsc_WatchDirectory.WatchFile) {
|
||||
const watchDirectory: HostWatchDirectory = (directory, cb) => this.watchFile(directory, () => cb(directory), PollingInterval.Medium);
|
||||
this.customRecursiveWatchDirectory = createRecursiveDirectoryWatcher({
|
||||
useCaseSensitiveFileNames: this.useCaseSensitiveFileNames,
|
||||
directoryExists: path => this.directoryExists(path),
|
||||
getAccessibleSortedChildDirectories: path => this.getDirectories(path),
|
||||
filePathComparer: this.useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
|
||||
watchDirectory,
|
||||
realpath: s => this.realpath(s)
|
||||
});
|
||||
@@ -362,9 +362,9 @@ interface Array<T> {}`
|
||||
else if (tscWatchDirectory === Tsc_WatchDirectory.NonRecursiveWatchDirectory) {
|
||||
const watchDirectory: HostWatchDirectory = (directory, cb) => this.watchDirectory(directory, fileName => cb(fileName), /*recursive*/ false);
|
||||
this.customRecursiveWatchDirectory = createRecursiveDirectoryWatcher({
|
||||
useCaseSensitiveFileNames: this.useCaseSensitiveFileNames,
|
||||
directoryExists: path => this.directoryExists(path),
|
||||
getAccessibleSortedChildDirectories: path => this.getDirectories(path),
|
||||
filePathComparer: this.useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
|
||||
watchDirectory,
|
||||
realpath: s => this.realpath(s)
|
||||
});
|
||||
@@ -373,9 +373,9 @@ interface Array<T> {}`
|
||||
const watchFile = createDynamicPriorityPollingWatchFile(this);
|
||||
const watchDirectory: HostWatchDirectory = (directory, cb) => watchFile(directory, () => cb(directory), PollingInterval.Medium);
|
||||
this.customRecursiveWatchDirectory = createRecursiveDirectoryWatcher({
|
||||
useCaseSensitiveFileNames: this.useCaseSensitiveFileNames,
|
||||
directoryExists: path => this.directoryExists(path),
|
||||
getAccessibleSortedChildDirectories: path => this.getDirectories(path),
|
||||
filePathComparer: this.useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive,
|
||||
watchDirectory,
|
||||
realpath: s => this.realpath(s)
|
||||
});
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* @internal */
|
||||
declare namespace ts.server {
|
||||
export type ActionSet = "action::set";
|
||||
export type ActionInvalidate = "action::invalidate";
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
namespace ts.server {
|
||||
/*@internal*/
|
||||
export interface ScriptInfoVersion {
|
||||
svc: number;
|
||||
text: number;
|
||||
|
||||
+40
-18
@@ -286,6 +286,16 @@ namespace ts.server {
|
||||
: deduplicate(outputs, areEqual);
|
||||
}
|
||||
|
||||
function combineProjectOutputFromEveryProject<T>(projectService: ProjectService, action: (project: Project) => ReadonlyArray<T>, areEqual: (a: T, b: T) => boolean) {
|
||||
const outputs: T[] = [];
|
||||
projectService.forEachProject(project => {
|
||||
if (project.isOrphan() || !project.languageServiceEnabled) return;
|
||||
const theseOutputs = action(project);
|
||||
outputs.push(...theseOutputs.filter(output => !outputs.some(o => areEqual(o, output))));
|
||||
});
|
||||
return outputs;
|
||||
}
|
||||
|
||||
function combineProjectOutputWhileOpeningReferencedProjects<T>(
|
||||
projects: Projects,
|
||||
projectService: ProjectService,
|
||||
@@ -1147,7 +1157,9 @@ namespace ts.server {
|
||||
const refs: protocol.ReferencesResponseItem[] = flatMap(references, referencedSymbol =>
|
||||
referencedSymbol.references.map(({ fileName, textSpan, isWriteAccess, isDefinition }): protocol.ReferencesResponseItem => {
|
||||
const scriptInfo = Debug.assertDefined(this.projectService.getScriptInfo(fileName));
|
||||
const lineText = scriptInfo.getSnapshot().getText(textSpan.start, textSpanEnd(textSpan));
|
||||
const start = scriptInfo.positionToLineOffset(textSpan.start);
|
||||
const lineSpan = scriptInfo.lineToTextSpan(start.line - 1);
|
||||
const lineText = scriptInfo.getSnapshot().getText(lineSpan.start, textSpanEnd(lineSpan)).replace(/\r|\n/g, "");
|
||||
return { ...toFileSpan(fileName, textSpan, scriptInfo), lineText, isWriteAccess, isDefinition };
|
||||
}));
|
||||
const result: protocol.ReferencesResponseBody = { refs, symbolName, symbolStartOffset, symbolDisplayString };
|
||||
@@ -1747,19 +1759,11 @@ namespace ts.server {
|
||||
const newPath = toNormalizedPath(args.newFilePath);
|
||||
const formatOptions = this.getHostFormatOptions();
|
||||
const preferences = this.getHostPreferences();
|
||||
|
||||
const changes: (protocol.FileCodeEdits | FileTextChanges)[] = [];
|
||||
this.projectService.forEachProject(project => {
|
||||
if (project.isOrphan() || !project.languageServiceEnabled) return;
|
||||
for (const fileTextChanges of project.getLanguageService().getEditsForFileRename(oldPath, newPath, formatOptions, preferences)) {
|
||||
// Subsequent projects may make conflicting edits to the same file -- just go with the first.
|
||||
if (!changes.some(f => f.fileName === fileTextChanges.fileName)) {
|
||||
changes.push(simplifiedResult ? this.mapTextChangeToCodeEdit(project, fileTextChanges) : fileTextChanges);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return changes as ReadonlyArray<protocol.FileCodeEdits> | ReadonlyArray<FileTextChanges>;
|
||||
const changes = combineProjectOutputFromEveryProject(
|
||||
this.projectService,
|
||||
project => project.getLanguageService().getEditsForFileRename(oldPath, newPath, formatOptions, preferences),
|
||||
(a, b) => a.fileName === b.fileName);
|
||||
return simplifiedResult ? changes.map(c => this.mapTextChangeToCodeEditUsingScriptInfo(c)) : changes;
|
||||
}
|
||||
|
||||
private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CodeFixAction> | ReadonlyArray<CodeFixAction> | undefined {
|
||||
@@ -1833,8 +1837,15 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private mapTextChangeToCodeEdit(project: Project, change: FileTextChanges): protocol.FileCodeEdits {
|
||||
const path = normalizedPathToPath(toNormalizedPath(change.fileName), this.host.getCurrentDirectory(), fileName => this.getCanonicalFileName(fileName));
|
||||
return mapTextChangesToCodeEdits(change, project.getSourceFileOrConfigFile(path));
|
||||
return mapTextChangesToCodeEditsForFile(change, project.getSourceFileOrConfigFile(this.normalizePath(change.fileName)));
|
||||
}
|
||||
|
||||
private mapTextChangeToCodeEditUsingScriptInfo(change: FileTextChanges): protocol.FileCodeEdits {
|
||||
return mapTextChangesToCodeEditsUsingScriptInfo(change, this.projectService.getScriptInfo(this.normalizePath(change.fileName)));
|
||||
}
|
||||
|
||||
private normalizePath(fileName: string) {
|
||||
return normalizedPathToPath(toNormalizedPath(fileName), this.host.getCurrentDirectory(), fileName => this.getCanonicalFileName(fileName));
|
||||
}
|
||||
|
||||
private convertTextChangeToCodeEdit(change: TextChange, scriptInfo: ScriptInfo): protocol.CodeEdit {
|
||||
@@ -2346,8 +2357,8 @@ namespace ts.server {
|
||||
return { file: fileName, start: scriptInfo.positionToLineOffset(textSpan.start), end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan)) };
|
||||
}
|
||||
|
||||
function mapTextChangesToCodeEdits(textChanges: FileTextChanges, sourceFile: SourceFile | undefined): protocol.FileCodeEdits {
|
||||
Debug.assert(!!textChanges.isNewFile === !sourceFile);
|
||||
function mapTextChangesToCodeEditsForFile(textChanges: FileTextChanges, sourceFile: SourceFile | undefined): protocol.FileCodeEdits {
|
||||
Debug.assert(!!textChanges.isNewFile === !sourceFile, "Expected isNewFile for (only) new files", () => JSON.stringify({ isNewFile: textChanges.isNewFile, hasSourceFile: !!sourceFile }));
|
||||
if (sourceFile) {
|
||||
return {
|
||||
fileName: textChanges.fileName,
|
||||
@@ -2359,6 +2370,13 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
function mapTextChangesToCodeEditsUsingScriptInfo(textChanges: FileTextChanges, scriptInfo: ScriptInfo | undefined): protocol.FileCodeEdits {
|
||||
Debug.assert(!!textChanges.isNewFile === !scriptInfo);
|
||||
return scriptInfo
|
||||
? { fileName: textChanges.fileName, textChanges: textChanges.textChanges.map(textChange => convertTextChangeToCodeEditUsingScriptInfo(textChange, scriptInfo)) }
|
||||
: convertNewFileTextChangeToCodeEdit(textChanges);
|
||||
}
|
||||
|
||||
function convertTextChangeToCodeEdit(change: TextChange, sourceFile: SourceFile): protocol.CodeEdit {
|
||||
return {
|
||||
start: convertToLocation(sourceFile.getLineAndCharacterOfPosition(change.span.start)),
|
||||
@@ -2367,6 +2385,10 @@ namespace ts.server {
|
||||
};
|
||||
}
|
||||
|
||||
function convertTextChangeToCodeEditUsingScriptInfo(change: TextChange, scriptInfo: ScriptInfo) {
|
||||
return { start: scriptInfo.positionToLineOffset(change.span.start), end: scriptInfo.positionToLineOffset(textSpanEnd(change.span)), newText: change.newText };
|
||||
}
|
||||
|
||||
function convertNewFileTextChangeToCodeEdit(textChanges: FileTextChanges): protocol.FileCodeEdits {
|
||||
Debug.assert(textChanges.textChanges.length === 1);
|
||||
const change = first(textChanges.textChanges);
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace ts.codefix {
|
||||
const importDeclaration = findAncestor(node, isImportDeclaration)!;
|
||||
const resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration);
|
||||
if (resolvedSourceFile && resolvedSourceFile.symbol) {
|
||||
suggestion = checker.getSuggestionForNonexistentModule(node as Identifier, resolvedSourceFile.symbol);
|
||||
suggestion = checker.getSuggestionForNonexistentExport(node as Identifier, resolvedSourceFile.symbol);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -5,14 +5,14 @@ namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions(context) {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start));
|
||||
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, context.sourceFile, context.span.start, context.span.length));
|
||||
return [createCodeFixAction(fixId, changes, Diagnostics.Remove_unreachable_code, fixId, Diagnostics.Remove_all_unreachable_code)];
|
||||
},
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => doChange(changes, diag.file, diag.start)),
|
||||
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => doChange(changes, diag.file, diag.start, diag.length)),
|
||||
});
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, start: number): void {
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, start: number, length: number): void {
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
const statement = findAncestor(token, isStatement)!;
|
||||
Debug.assert(statement.getStart(sourceFile) === token.getStart(sourceFile));
|
||||
@@ -36,7 +36,9 @@ namespace ts.codefix {
|
||||
break;
|
||||
default:
|
||||
if (isBlock(statement.parent)) {
|
||||
split(sliceAfter(statement.parent.statements, statement), shouldRemove, (start, end) => changes.deleteNodeRange(sourceFile, start, end));
|
||||
const end = start + length;
|
||||
const lastStatement = Debug.assertDefined(lastWhere(sliceAfter(statement.parent.statements, statement), s => s.pos < end));
|
||||
changes.deleteNodeRange(sourceFile, statement, lastStatement);
|
||||
}
|
||||
else {
|
||||
changes.delete(sourceFile, statement);
|
||||
@@ -44,35 +46,12 @@ namespace ts.codefix {
|
||||
}
|
||||
}
|
||||
|
||||
function shouldRemove(s: Statement): boolean {
|
||||
// Don't remove statements that can validly be used before they appear.
|
||||
return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) &&
|
||||
// `var x;` may declare a variable used above
|
||||
!(isVariableStatement(s) && !(getCombinedNodeFlags(s) & (NodeFlags.Let | NodeFlags.Const)) && s.declarationList.declarations.some(d => !d.initializer));
|
||||
}
|
||||
|
||||
function isPurelyTypeDeclaration(s: Statement): boolean {
|
||||
switch (s.kind) {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
return true;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return getModuleInstanceState(s as ModuleDeclaration) !== ModuleInstanceState.Instantiated;
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
return hasModifier(s, ModifierFlags.Const);
|
||||
default:
|
||||
return false;
|
||||
function lastWhere<T>(a: ReadonlyArray<T>, pred: (value: T) => boolean): T | undefined {
|
||||
let last: T | undefined;
|
||||
for (const value of a) {
|
||||
if (!pred(value)) break;
|
||||
last = value;
|
||||
}
|
||||
}
|
||||
|
||||
function sliceAfter<T>(arr: ReadonlyArray<T>, value: T): ReadonlyArray<T> {
|
||||
const index = arr.indexOf(value);
|
||||
Debug.assert(index !== -1);
|
||||
return arr.slice(index);
|
||||
}
|
||||
|
||||
// Calls 'cb' with the start and end of each range where 'pred' is true.
|
||||
function split<T>(arr: ReadonlyArray<T>, pred: (t: T) => boolean, cb: (start: T, end: T) => void): void {
|
||||
getRangesWhere(arr, pred, (start, afterEnd) => cb(arr[start], arr[afterEnd - 1]));
|
||||
return last;
|
||||
}
|
||||
}
|
||||
|
||||
+33
-21
@@ -2,12 +2,20 @@
|
||||
namespace ts.Completions {
|
||||
export type Log = (message: string) => void;
|
||||
|
||||
type SymbolOriginInfo = { type: "this-type" } | { type: "symbol-member" } | SymbolOriginInfoExport;
|
||||
const enum SymbolOriginInfoKind { ThisType, SymbolMemberNoExport, SymbolMemberExport, Export }
|
||||
type SymbolOriginInfo = { kind: SymbolOriginInfoKind.ThisType } | { kind: SymbolOriginInfoKind.SymbolMemberNoExport } | SymbolOriginInfoExport;
|
||||
interface SymbolOriginInfoExport {
|
||||
type: "export";
|
||||
kind: SymbolOriginInfoKind.SymbolMemberExport | SymbolOriginInfoKind.Export;
|
||||
moduleSymbol: Symbol;
|
||||
isDefaultExport: boolean;
|
||||
}
|
||||
function originIsSymbolMember(origin: SymbolOriginInfo): boolean {
|
||||
return origin.kind === SymbolOriginInfoKind.SymbolMemberExport || origin.kind === SymbolOriginInfoKind.SymbolMemberNoExport;
|
||||
}
|
||||
function originIsExport(origin: SymbolOriginInfo): origin is SymbolOriginInfoExport {
|
||||
return origin.kind === SymbolOriginInfoKind.SymbolMemberExport || origin.kind === SymbolOriginInfoKind.Export;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map from symbol id -> SymbolOriginInfo.
|
||||
* Only populated for symbols that come from other modules.
|
||||
@@ -103,20 +111,22 @@ namespace ts.Completions {
|
||||
function completionInfoFromData(sourceFile: SourceFile, typeChecker: TypeChecker, compilerOptions: CompilerOptions, log: Log, completionData: CompletionData, preferences: UserPreferences): CompletionInfo | undefined {
|
||||
const { symbols, completionKind, isInSnippetScope, isNewIdentifierLocation, location, propertyAccessToConvert, keywordFilters, literals, symbolToOriginInfoMap, recommendedCompletion, isJsxInitializer } = completionData;
|
||||
|
||||
if (sourceFile.languageVariant === LanguageVariant.JSX && location && location.parent && isJsxClosingElement(location.parent)) {
|
||||
if (location && location.parent && isJsxClosingElement(location.parent)) {
|
||||
// In the TypeScript JSX element, if such element is not defined. When users query for completion at closing tag,
|
||||
// instead of simply giving unknown value, the completion will return the tag-name of an associated opening-element.
|
||||
// For example:
|
||||
// var x = <div> </ /*1*/>
|
||||
// The completion list at "1" will contain "div" with type any
|
||||
// var x = <div> </ /*1*/
|
||||
// The completion list at "1" will contain "div>" with type any
|
||||
// And at `<div> </ /*1*/ >` (with a closing `>`), the completion list will contain "div".
|
||||
const tagName = location.parent.parent.openingElement.tagName;
|
||||
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false,
|
||||
entries: [{
|
||||
name: tagName.getFullText(),
|
||||
kind: ScriptElementKind.classElement,
|
||||
kindModifiers: undefined,
|
||||
sortText: "0",
|
||||
}]};
|
||||
const hasClosingAngleBracket = !!findChildOfKind(location.parent, SyntaxKind.GreaterThanToken, sourceFile);
|
||||
const entry: CompletionEntry = {
|
||||
name: tagName.getFullText(sourceFile) + (hasClosingAngleBracket ? "" : ">"),
|
||||
kind: ScriptElementKind.classElement,
|
||||
kindModifiers: undefined,
|
||||
sortText: "0",
|
||||
};
|
||||
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false, entries: [entry] };
|
||||
}
|
||||
|
||||
const entries: CompletionEntry[] = [];
|
||||
@@ -214,12 +224,12 @@ namespace ts.Completions {
|
||||
|
||||
let insertText: string | undefined;
|
||||
let replacementSpan: TextSpan | undefined;
|
||||
if (origin && origin.type === "this-type") {
|
||||
if (origin && origin.kind === SymbolOriginInfoKind.ThisType) {
|
||||
insertText = needsConvertPropertyAccess ? `this[${quote(name, preferences)}]` : `this.${name}`;
|
||||
}
|
||||
// We should only have needsConvertPropertyAccess if there's a property access to convert. But see #21790.
|
||||
// Somehow there was a global with a non-identifier name. Hopefully someone will complain about getting a "foo bar" global completion and provide a repro.
|
||||
else if ((origin && origin.type === "symbol-member" || needsConvertPropertyAccess) && propertyAccessToConvert) {
|
||||
else if ((origin && originIsSymbolMember(origin) || needsConvertPropertyAccess) && propertyAccessToConvert) {
|
||||
insertText = needsConvertPropertyAccess ? `[${quote(name, preferences)}]` : `[${name}]`;
|
||||
const dot = findChildOfKind(propertyAccessToConvert, SyntaxKind.DotToken, sourceFile)!;
|
||||
// If the text after the '.' starts with this name, write over it. Else, add new text.
|
||||
@@ -253,7 +263,7 @@ namespace ts.Completions {
|
||||
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
|
||||
sortText: "0",
|
||||
source: getSourceFromOrigin(origin),
|
||||
hasAction: trueOrUndefined(!!origin && origin.type === "export"),
|
||||
hasAction: trueOrUndefined(!!origin && originIsExport(origin)),
|
||||
isRecommended: trueOrUndefined(isRecommendedCompletionMatch(symbol, recommendedCompletion, typeChecker)),
|
||||
insertText,
|
||||
replacementSpan,
|
||||
@@ -283,7 +293,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function getSourceFromOrigin(origin: SymbolOriginInfo | undefined): string | undefined {
|
||||
return origin && origin.type === "export" ? stripQuotes(origin.moduleSymbol.name) : undefined;
|
||||
return origin && originIsExport(origin) ? stripQuotes(origin.moduleSymbol.name) : undefined;
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromSymbols(
|
||||
@@ -529,7 +539,7 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string {
|
||||
return origin && origin.type === "export" && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default
|
||||
return origin && originIsExport(origin) && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default
|
||||
// Name of "export default foo;" is "foo". Name of "export default 0" is the filename converted to camelCase.
|
||||
? firstDefined(symbol.declarations, d => isExportAssignment(d) && isIdentifier(d.expression) ? d.expression.text : undefined)
|
||||
|| codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target)
|
||||
@@ -648,7 +658,7 @@ namespace ts.Completions {
|
||||
preferences: UserPreferences,
|
||||
): CodeActionsAndSourceDisplay {
|
||||
const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)];
|
||||
if (!symbolOriginInfo || symbolOriginInfo.type !== "export") {
|
||||
if (!symbolOriginInfo || !originIsExport(symbolOriginInfo)) {
|
||||
return { codeActions: undefined, sourceDisplay: undefined };
|
||||
}
|
||||
|
||||
@@ -1124,7 +1134,9 @@ namespace ts.Completions {
|
||||
const firstAccessibleSymbol = nameSymbol && getFirstSymbolInChain(nameSymbol, contextToken, typeChecker);
|
||||
if (firstAccessibleSymbol && !symbolToOriginInfoMap[getSymbolId(firstAccessibleSymbol)]) {
|
||||
symbols.push(firstAccessibleSymbol);
|
||||
symbolToOriginInfoMap[getSymbolId(firstAccessibleSymbol)] = { type: "symbol-member" };
|
||||
const moduleSymbol = firstAccessibleSymbol.parent;
|
||||
symbolToOriginInfoMap[getSymbolId(firstAccessibleSymbol)] =
|
||||
!moduleSymbol || !isExternalModuleSymbol(moduleSymbol) ? { kind: SymbolOriginInfoKind.SymbolMemberNoExport } : { kind: SymbolOriginInfoKind.SymbolMemberExport, moduleSymbol, isDefaultExport: false };
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1222,7 +1234,7 @@ namespace ts.Completions {
|
||||
const thisType = typeChecker.tryGetThisTypeAt(scopeNode);
|
||||
if (thisType) {
|
||||
for (const symbol of getPropertiesForCompletion(thisType, typeChecker)) {
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = { type: "this-type" };
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = { kind: SymbolOriginInfoKind.ThisType };
|
||||
symbols.push(symbol);
|
||||
}
|
||||
}
|
||||
@@ -1374,7 +1386,7 @@ namespace ts.Completions {
|
||||
symbol = getLocalSymbolForExportDefault(symbol) || symbol;
|
||||
}
|
||||
|
||||
const origin: SymbolOriginInfo = { type: "export", moduleSymbol, isDefaultExport };
|
||||
const origin: SymbolOriginInfoExport = { kind: SymbolOriginInfoKind.Export, moduleSymbol, isDefaultExport };
|
||||
if (detailsEntryId || stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) {
|
||||
symbols.push(symbol);
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = origin;
|
||||
|
||||
@@ -234,7 +234,8 @@ namespace ts.FindAllReferences.Core {
|
||||
export function getReferencedSymbolsForNode(position: number, node: Node, program: Program, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken, options: Options = {}, sourceFilesSet: ReadonlyMap<true> = arrayToSet(sourceFiles, f => f.fileName)): SymbolAndEntries[] | undefined {
|
||||
if (isSourceFile(node)) {
|
||||
const reference = GoToDefinition.getReferenceAtPosition(node, position, program);
|
||||
return reference && getReferencedSymbolsForModule(program, program.getTypeChecker().getMergedSymbol(reference.file.symbol), /*excludeImportTypeOfExportEquals*/ false, sourceFiles, sourceFilesSet);
|
||||
const moduleSymbol = reference && program.getTypeChecker().getMergedSymbol(reference.file.symbol);
|
||||
return moduleSymbol && getReferencedSymbolsForModule(program, moduleSymbol, /*excludeImportTypeOfExportEquals*/ false, sourceFiles, sourceFilesSet);
|
||||
}
|
||||
|
||||
if (!options.implementations) {
|
||||
@@ -703,7 +704,7 @@ namespace ts.FindAllReferences.Core {
|
||||
- But if the parent has `export as namespace`, the symbol is globally visible through that namespace.
|
||||
*/
|
||||
const exposedByParent = parent && !(symbol.flags & SymbolFlags.TypeParameter);
|
||||
if (exposedByParent && !((parent!.flags & SymbolFlags.Module) && isExternalModuleSymbol(parent!) && !parent!.globalExports)) {
|
||||
if (exposedByParent && !(isExternalModuleSymbol(parent!) && !parent!.globalExports)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -1462,12 +1463,14 @@ namespace ts.FindAllReferences.Core {
|
||||
}
|
||||
|
||||
/** Gets all symbols for one property. Does not get symbols for every property. */
|
||||
function getPropertySymbolsFromContextualType(node: ObjectLiteralElement, checker: TypeChecker): ReadonlyArray<Symbol> {
|
||||
function getPropertySymbolsFromContextualType(node: ObjectLiteralElementWithName, checker: TypeChecker): ReadonlyArray<Symbol> {
|
||||
const contextualType = checker.getContextualType(<ObjectLiteralExpression>node.parent);
|
||||
const name = getNameFromPropertyName(node.name!);
|
||||
const symbol = contextualType && name && contextualType.getProperty(name);
|
||||
if (!contextualType) return emptyArray;
|
||||
const name = getNameFromPropertyName(node.name);
|
||||
if (!name) return emptyArray;
|
||||
const symbol = contextualType.getProperty(name);
|
||||
return symbol ? [symbol] :
|
||||
contextualType && contextualType.isUnion() ? mapDefined(contextualType.types, t => t.getProperty(name!)) : emptyArray; // TODO: GH#18217
|
||||
contextualType.isUnion() ? mapDefined(contextualType.types, t => t.getProperty(name)) : emptyArray;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export function getEditsForFileRename(program: Program, oldFileOrDirPath: string, newFileOrDirPath: string, host: LanguageServiceHost, formatContext: formatting.FormatContext, preferences: UserPreferences): ReadonlyArray<FileTextChanges> {
|
||||
export function getEditsForFileRename(
|
||||
program: Program,
|
||||
oldFileOrDirPath: string,
|
||||
newFileOrDirPath: string,
|
||||
host: LanguageServiceHost,
|
||||
formatContext: formatting.FormatContext,
|
||||
preferences: UserPreferences,
|
||||
sourceMapper: SourceMapper,
|
||||
): ReadonlyArray<FileTextChanges> {
|
||||
const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host);
|
||||
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
const oldToNew = getPathUpdater(oldFileOrDirPath, newFileOrDirPath, getCanonicalFileName);
|
||||
const newToOld = getPathUpdater(newFileOrDirPath, oldFileOrDirPath, getCanonicalFileName);
|
||||
const oldToNew = getPathUpdater(oldFileOrDirPath, newFileOrDirPath, getCanonicalFileName, sourceMapper);
|
||||
const newToOld = getPathUpdater(newFileOrDirPath, oldFileOrDirPath, getCanonicalFileName, sourceMapper);
|
||||
return textChanges.ChangeTracker.with({ host, formatContext }, changeTracker => {
|
||||
updateTsconfigFiles(program, changeTracker, oldToNew, newFileOrDirPath, host.getCurrentDirectory(), useCaseSensitiveFileNames);
|
||||
updateImports(program, changeTracker, oldToNew, newToOld, host, getCanonicalFileName, preferences);
|
||||
@@ -14,13 +22,27 @@ namespace ts {
|
||||
/** If 'path' refers to an old directory, returns path in the new directory. */
|
||||
type PathUpdater = (path: string) => string | undefined;
|
||||
// exported for tests
|
||||
export function getPathUpdater(oldFileOrDirPath: string, newFileOrDirPath: string, getCanonicalFileName: GetCanonicalFileName): PathUpdater {
|
||||
export function getPathUpdater(oldFileOrDirPath: string, newFileOrDirPath: string, getCanonicalFileName: GetCanonicalFileName, sourceMapper: SourceMapper | undefined): PathUpdater {
|
||||
const canonicalOldPath = getCanonicalFileName(oldFileOrDirPath);
|
||||
return path => {
|
||||
if (getCanonicalFileName(path) === canonicalOldPath) return newFileOrDirPath;
|
||||
const suffix = tryRemoveDirectoryPrefix(path, canonicalOldPath, getCanonicalFileName);
|
||||
return suffix === undefined ? undefined : newFileOrDirPath + "/" + suffix;
|
||||
const originalPath = sourceMapper && sourceMapper.tryGetOriginalLocation({ fileName: path, position: 0 });
|
||||
const updatedPath = getUpdatedPath(originalPath ? originalPath.fileName : path);
|
||||
return originalPath
|
||||
? updatedPath === undefined ? undefined : makeCorrespondingRelativeChange(originalPath.fileName, updatedPath, path, getCanonicalFileName)
|
||||
: updatedPath;
|
||||
};
|
||||
|
||||
function getUpdatedPath(pathToUpdate: string): string | undefined {
|
||||
if (getCanonicalFileName(pathToUpdate) === canonicalOldPath) return newFileOrDirPath;
|
||||
const suffix = tryRemoveDirectoryPrefix(pathToUpdate, canonicalOldPath, getCanonicalFileName);
|
||||
return suffix === undefined ? undefined : newFileOrDirPath + "/" + suffix;
|
||||
}
|
||||
}
|
||||
|
||||
// Relative path from a0 to b0 should be same as relative path from a1 to b1. Returns b1.
|
||||
function makeCorrespondingRelativeChange(a0: string, b0: string, a1: string, getCanonicalFileName: GetCanonicalFileName): string {
|
||||
const rel = getRelativePathFromFile(a0, b0, getCanonicalFileName);
|
||||
return combinePathsSafe(getDirectoryPath(a1), rel);
|
||||
}
|
||||
|
||||
function updateTsconfigFiles(program: Program, changeTracker: textChanges.ChangeTracker, oldToNew: PathUpdater, newFileOrDirPath: string, currentDirectory: string, useCaseSensitiveFileNames: boolean): void {
|
||||
|
||||
@@ -183,6 +183,26 @@ namespace ts.OutliningElementsCollector {
|
||||
return spanForObjectOrArrayLiteral(n);
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
return spanForObjectOrArrayLiteral(n, SyntaxKind.OpenBracketToken);
|
||||
case SyntaxKind.JsxElement:
|
||||
return spanForJSXElement(<JsxElement>n);
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
return spanForJSXAttributes((<JsxOpeningLikeElement>n).attributes);
|
||||
}
|
||||
|
||||
function spanForJSXElement(node: JsxElement): OutliningSpan | undefined {
|
||||
const textSpan = createTextSpanFromBounds(node.openingElement.getStart(sourceFile), node.closingElement.getEnd());
|
||||
const tagName = node.openingElement.tagName.getText(sourceFile);
|
||||
const bannerText = "<" + tagName + ">...</" + tagName + ">";
|
||||
return createOutliningSpan(textSpan, OutliningSpanKind.Code, textSpan, /*autoCollapse*/ false, bannerText);
|
||||
}
|
||||
|
||||
function spanForJSXAttributes(node: JsxAttributes): OutliningSpan | undefined {
|
||||
if (node.properties.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return createOutliningSpanFromBounds(node.getStart(sourceFile), node.getEnd(), OutliningSpanKind.Code);
|
||||
}
|
||||
|
||||
function spanForObjectOrArrayLiteral(node: Node, open: SyntaxKind.OpenBraceToken | SyntaxKind.OpenBracketToken = SyntaxKind.OpenBraceToken): OutliningSpan | undefined {
|
||||
|
||||
@@ -1537,7 +1537,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getDocumentHighlights(fileName: string, position: number, filesToSearch: ReadonlyArray<string>): DocumentHighlights[] | undefined {
|
||||
Debug.assert(filesToSearch.some(f => normalizePath(f) === fileName));
|
||||
const normalizedFileName = normalizePath(fileName);
|
||||
Debug.assert(filesToSearch.some(f => normalizePath(f) === normalizedFileName));
|
||||
synchronizeHostData();
|
||||
const sourceFilesToSearch = map(filesToSearch, f => Debug.assertDefined(program.getSourceFile(f)));
|
||||
const sourceFile = getValidSourceFile(fileName);
|
||||
@@ -1812,7 +1813,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences = emptyOptions): ReadonlyArray<FileTextChanges> {
|
||||
return ts.getEditsForFileRename(getProgram()!, oldFilePath, newFilePath, host, formatting.getFormatContext(formatOptions), preferences);
|
||||
return ts.getEditsForFileRename(getProgram()!, oldFilePath, newFilePath, host, formatting.getFormatContext(formatOptions), preferences, sourceMapper);
|
||||
}
|
||||
|
||||
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
|
||||
@@ -1883,11 +1884,16 @@ namespace ts {
|
||||
if (!token) return undefined;
|
||||
const element = token.kind === SyntaxKind.GreaterThanToken && isJsxOpeningElement(token.parent) ? token.parent.parent
|
||||
: isJsxText(token) ? token.parent : undefined;
|
||||
if (element && !tagNamesAreEquivalent(element.openingElement.tagName, element.closingElement.tagName)) {
|
||||
if (element && isUnclosedTag(element)) {
|
||||
return { newText: `</${element.openingElement.tagName.getText(sourceFile)}>` };
|
||||
}
|
||||
}
|
||||
|
||||
function isUnclosedTag({ openingElement, closingElement, parent }: JsxElement): boolean {
|
||||
return !tagNamesAreEquivalent(openingElement.tagName, closingElement.tagName) ||
|
||||
isJsxElement(parent) && tagNamesAreEquivalent(openingElement.tagName, parent.openingElement.tagName) && isUnclosedTag(parent);
|
||||
}
|
||||
|
||||
function getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined {
|
||||
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
const range = formatting.getRangeOfEnclosingComment(sourceFile, position);
|
||||
@@ -2180,21 +2186,23 @@ namespace ts {
|
||||
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
|
||||
*/
|
||||
/* @internal */
|
||||
export function getContainingObjectLiteralElement(node: Node): ObjectLiteralElement | undefined {
|
||||
export function getContainingObjectLiteralElement(node: Node): ObjectLiteralElementWithName | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
if (node.parent.kind === SyntaxKind.ComputedPropertyName) {
|
||||
return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
|
||||
return isObjectLiteralElement(node.parent.parent) ? node.parent.parent as ObjectLiteralElementWithName : undefined;
|
||||
}
|
||||
// falls through
|
||||
case SyntaxKind.Identifier:
|
||||
return isObjectLiteralElement(node.parent) &&
|
||||
(node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === SyntaxKind.JsxAttributes) &&
|
||||
node.parent.name === node ? node.parent : undefined;
|
||||
node.parent.name === node ? node.parent as ObjectLiteralElementWithName : undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/* @internal */
|
||||
export type ObjectLiteralElementWithName = ObjectLiteralElement & { name: PropertyName };
|
||||
|
||||
/* @internal */
|
||||
export function getPropertySymbolsFromContextualType(typeChecker: TypeChecker, node: ObjectLiteralElement): Symbol[] {
|
||||
|
||||
@@ -29,9 +29,12 @@ namespace ts.SignatureHelp {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (shouldCarefullyCheckContext(triggerReason)) {
|
||||
// In the middle of a string, don't provide signature help unless the user explicitly requested it.
|
||||
if (isInString(sourceFile, position, startingToken)) {
|
||||
// Only need to be careful if the user typed a character and signature help wasn't showing.
|
||||
const shouldCarefullyCheckContext = !!triggerReason && triggerReason.kind === "characterTyped";
|
||||
|
||||
// Bail out quickly in the middle of a string or comment, don't provide signature help unless the user explicitly requested it.
|
||||
if (shouldCarefullyCheckContext) {
|
||||
if (isInString(sourceFile, position, startingToken) || isInComment(sourceFile, position)) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -41,8 +44,8 @@ namespace ts.SignatureHelp {
|
||||
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
// Semantic filtering of signature help
|
||||
const candidateInfo = getCandidateInfo(argumentInfo, typeChecker);
|
||||
// Extra syntactic and semantic filtering of signature help
|
||||
const candidateInfo = getCandidateInfo(argumentInfo, typeChecker, sourceFile, startingToken, shouldCarefullyCheckContext);
|
||||
cancellationToken.throwIfCancellationRequested();
|
||||
|
||||
if (!candidateInfo) {
|
||||
@@ -57,24 +60,57 @@ namespace ts.SignatureHelp {
|
||||
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidateInfo.candidates, candidateInfo.resolvedSignature, argumentInfo, sourceFile, typeChecker));
|
||||
}
|
||||
|
||||
function shouldCarefullyCheckContext(reason: SignatureHelpTriggerReason | undefined) {
|
||||
// Only need to be careful if the user typed a character and signature help wasn't showing.
|
||||
return !!reason && reason.kind === "characterTyped";
|
||||
}
|
||||
function getCandidateInfo(
|
||||
argumentInfo: ArgumentListInfo, checker: TypeChecker, sourceFile: SourceFile, startingToken: Node, onlyUseSyntacticOwners: boolean):
|
||||
{ readonly candidates: ReadonlyArray<Signature>, readonly resolvedSignature: Signature } | undefined {
|
||||
|
||||
function getCandidateInfo(argumentInfo: ArgumentListInfo, checker: TypeChecker): { readonly candidates: ReadonlyArray<Signature>, readonly resolvedSignature: Signature } | undefined {
|
||||
const { invocation } = argumentInfo;
|
||||
if (invocation.kind === InvocationKind.Call) {
|
||||
if (onlyUseSyntacticOwners) {
|
||||
if (isCallOrNewExpression(invocation.node)) {
|
||||
const invocationChildren = invocation.node.getChildren(sourceFile);
|
||||
switch (startingToken.kind) {
|
||||
case SyntaxKind.OpenParenToken:
|
||||
if (!contains(invocationChildren, startingToken)) {
|
||||
return undefined;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.CommaToken:
|
||||
const containingList = findContainingList(startingToken);
|
||||
if (!containingList || !contains(invocationChildren, findContainingList(startingToken))) {
|
||||
return undefined;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.LessThanToken:
|
||||
if (!lessThanFollowsCalledExpression(startingToken, sourceFile, invocation.node.expression)) {
|
||||
return undefined;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const candidates: Signature[] = [];
|
||||
const resolvedSignature = checker.getResolvedSignature(invocation.node, candidates, argumentInfo.argumentCount)!; // TODO: GH#18217
|
||||
return candidates.length === 0 ? undefined : { candidates, resolvedSignature };
|
||||
}
|
||||
else {
|
||||
else if (invocation.kind === InvocationKind.TypeArgs) {
|
||||
if (onlyUseSyntacticOwners && !lessThanFollowsCalledExpression(startingToken, sourceFile, invocation.called)) {
|
||||
return undefined;
|
||||
}
|
||||
const type = checker.getTypeAtLocation(invocation.called)!; // TODO: GH#18217
|
||||
const signatures = isNewExpression(invocation.called.parent) ? type.getConstructSignatures() : type.getCallSignatures();
|
||||
const candidates = signatures.filter(candidate => !!candidate.typeParameters && candidate.typeParameters.length >= argumentInfo.argumentCount);
|
||||
return candidates.length === 0 ? undefined : { candidates, resolvedSignature: first(candidates) };
|
||||
}
|
||||
else {
|
||||
Debug.assertNever(invocation);
|
||||
}
|
||||
}
|
||||
|
||||
function createJavaScriptSignatureHelpItems(argumentInfo: ArgumentListInfo, program: Program, cancellationToken: CancellationToken): SignatureHelpItems | undefined {
|
||||
@@ -107,6 +143,14 @@ namespace ts.SignatureHelp {
|
||||
}
|
||||
}
|
||||
|
||||
function lessThanFollowsCalledExpression(startingToken: Node, sourceFile: SourceFile, calledExpression: Expression) {
|
||||
const precedingToken = Debug.assertDefined(
|
||||
findPrecedingToken(startingToken.getFullStart(), sourceFile, startingToken.parent, /*excludeJsdoc*/ true)
|
||||
);
|
||||
|
||||
return rangeContainsRange(calledExpression, precedingToken);
|
||||
}
|
||||
|
||||
export interface ArgumentInfoForCompletions {
|
||||
readonly invocation: CallLikeExpression;
|
||||
readonly argumentIndex: number;
|
||||
|
||||
@@ -679,7 +679,7 @@ namespace ts {
|
||||
let current: Node = sourceFile;
|
||||
outer: while (true) {
|
||||
// find the child that contains 'position'
|
||||
for (const child of current.getChildren()) {
|
||||
for (const child of current.getChildren(sourceFile)) {
|
||||
const start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, /*includeJsDoc*/ true);
|
||||
if (start > position) {
|
||||
// If this child begins after position, then all subsequent children will as well.
|
||||
@@ -1184,8 +1184,7 @@ namespace ts {
|
||||
|
||||
/** True if the symbol is for an external module, as opposed to a namespace. */
|
||||
export function isExternalModuleSymbol(moduleSymbol: Symbol): boolean {
|
||||
Debug.assert(!!(moduleSymbol.flags & SymbolFlags.Module));
|
||||
return moduleSymbol.name.charCodeAt(0) === CharacterCodes.doubleQuote;
|
||||
return !!(moduleSymbol.flags & SymbolFlags.Module) && moduleSymbol.name.charCodeAt(0) === CharacterCodes.doubleQuote;
|
||||
}
|
||||
|
||||
/** Returns `true` the first time it encounters a node and `false` afterwards. */
|
||||
@@ -1435,14 +1434,25 @@ namespace ts {
|
||||
|
||||
const displayPartWriter = getDisplayPartWriter();
|
||||
function getDisplayPartWriter(): DisplayPartsSymbolWriter {
|
||||
const absoluteMaximumLength = defaultMaximumTruncationLength * 10; // A hard cutoff to avoid overloading the messaging channel in worst-case scenarios
|
||||
let displayParts: SymbolDisplayPart[];
|
||||
let lineStart: boolean;
|
||||
let indent: number;
|
||||
let length: number;
|
||||
|
||||
resetWriter();
|
||||
const unknownWrite = (text: string) => writeKind(text, SymbolDisplayPartKind.text);
|
||||
return {
|
||||
displayParts: () => displayParts,
|
||||
displayParts: () => {
|
||||
const finalText = displayParts.length && displayParts[displayParts.length - 1].text;
|
||||
if (length > absoluteMaximumLength && finalText && finalText !== "...") {
|
||||
if (!isWhiteSpaceLike(finalText.charCodeAt(finalText.length - 1))) {
|
||||
displayParts.push(displayPart(" ", SymbolDisplayPartKind.space));
|
||||
}
|
||||
displayParts.push(displayPart("...", SymbolDisplayPartKind.punctuation));
|
||||
}
|
||||
return displayParts;
|
||||
},
|
||||
writeKeyword: text => writeKind(text, SymbolDisplayPartKind.keyword),
|
||||
writeOperator: text => writeKind(text, SymbolDisplayPartKind.operator),
|
||||
writePunctuation: text => writeKind(text, SymbolDisplayPartKind.punctuation),
|
||||
@@ -1472,9 +1482,11 @@ namespace ts {
|
||||
};
|
||||
|
||||
function writeIndent() {
|
||||
if (length > absoluteMaximumLength) return;
|
||||
if (lineStart) {
|
||||
const indentString = getIndentString(indent);
|
||||
if (indentString) {
|
||||
length += indentString.length;
|
||||
displayParts.push(displayPart(indentString, SymbolDisplayPartKind.space));
|
||||
}
|
||||
lineStart = false;
|
||||
@@ -1482,16 +1494,22 @@ namespace ts {
|
||||
}
|
||||
|
||||
function writeKind(text: string, kind: SymbolDisplayPartKind) {
|
||||
if (length > absoluteMaximumLength) return;
|
||||
writeIndent();
|
||||
length += text.length;
|
||||
displayParts.push(displayPart(text, kind));
|
||||
}
|
||||
|
||||
function writeSymbol(text: string, symbol: Symbol) {
|
||||
if (length > absoluteMaximumLength) return;
|
||||
writeIndent();
|
||||
length += text.length;
|
||||
displayParts.push(symbolPart(text, symbol));
|
||||
}
|
||||
|
||||
function writeLine() {
|
||||
if (length > absoluteMaximumLength) return;
|
||||
length += 1;
|
||||
displayParts.push(lineBreakPart());
|
||||
lineStart = true;
|
||||
}
|
||||
@@ -1500,6 +1518,7 @@ namespace ts {
|
||||
displayParts = [];
|
||||
lineStart = true;
|
||||
indent = 0;
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
namespace ts {
|
||||
describe("FactoryAPI", () => {
|
||||
describe("createExportAssignment", () => {
|
||||
it("parenthesizes default export if necessary", () => {
|
||||
function checkExpression(expression: Expression) {
|
||||
const node = createExportAssignment(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*isExportEquals*/ false,
|
||||
expression,
|
||||
);
|
||||
assert.strictEqual(node.expression.kind, SyntaxKind.ParenthesizedExpression);
|
||||
}
|
||||
|
||||
const clazz = createClassExpression(/*modifiers*/ undefined, "C", /*typeParameters*/ undefined, /*heritageClauses*/ undefined, [
|
||||
createProperty(/*decorators*/ undefined, [createToken(SyntaxKind.StaticKeyword)], "prop", /*questionOrExclamationToken*/ undefined, /*type*/ undefined, createLiteral("1")),
|
||||
]);
|
||||
checkExpression(clazz);
|
||||
checkExpression(createPropertyAccess(clazz, "prop"));
|
||||
|
||||
const func = createFunctionExpression(/*modifiers*/ undefined, /*asteriskToken*/ undefined, "fn", /*typeParameters*/ undefined, /*parameters*/ undefined, /*type*/ undefined, createBlock([]));
|
||||
checkExpression(func);
|
||||
checkExpression(createCall(func, /*typeArguments*/ undefined, /*argumentsArray*/ undefined));
|
||||
|
||||
checkExpression(createBinary(createLiteral("a"), SyntaxKind.CommaToken, createLiteral("b")));
|
||||
checkExpression(createCommaList([createLiteral("a"), createLiteral("b")]));
|
||||
});
|
||||
});
|
||||
|
||||
describe("createArrowFunction", () => {
|
||||
it("parenthesizes concise body if necessary", () => {
|
||||
function checkBody(body: ConciseBody) {
|
||||
|
||||
@@ -285,4 +285,23 @@ namespace ts {
|
||||
});
|
||||
});
|
||||
|
||||
describe("errors when a file in a composite project occurs outside the root", () => {
|
||||
it("Errors when a file is outside the rootdir", () => {
|
||||
const spec: TestSpecification = {
|
||||
"/alpha": {
|
||||
files: { "/alpha/src/a.ts": "import * from '../../beta/b'", "/beta/b.ts": "export { }" },
|
||||
options: {
|
||||
declaration: true,
|
||||
outDir: "bin"
|
||||
},
|
||||
references: []
|
||||
}
|
||||
};
|
||||
testProjectReferences(spec, "/alpha/tsconfig.json", (program) => {
|
||||
assertHasError("Issues an error about the rootDir", program.getOptionsDiagnostics(), Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files);
|
||||
assertHasError("Issues an error about the fileList", program.getOptionsDiagnostics(), Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@@ -8486,7 +8486,7 @@ new C();`
|
||||
});
|
||||
});
|
||||
|
||||
it("when watching directories for failed lookup locations in amd resolution", () => {
|
||||
describe("when watching directories for failed lookup locations in amd resolution", () => {
|
||||
const projectRoot = "/user/username/projects/project";
|
||||
const nodeFile: File = {
|
||||
path: `${projectRoot}/src/typings/node.d.ts`,
|
||||
@@ -8530,19 +8530,35 @@ export const x = 10;`
|
||||
}
|
||||
})
|
||||
};
|
||||
const files = [nodeFile, electronFile, srcFile, moduleFile, configFile, libFile];
|
||||
const host = createServerHost(files);
|
||||
const service = createProjectService(host);
|
||||
service.openClientFile(srcFile.path, srcFile.content, ScriptKind.TS, projectRoot);
|
||||
checkProjectActualFiles(service.configuredProjects.get(configFile.path)!, files.map(f => f.path));
|
||||
checkWatchedFilesDetailed(host, mapDefined(files, f => f === srcFile ? undefined : f.path), 1);
|
||||
checkWatchedDirectoriesDetailed(host, [`${projectRoot}`], 1, /*recursive*/ false); // failed lookup for fs
|
||||
const expectedWatchedDirectories = createMap<number>();
|
||||
expectedWatchedDirectories.set(`${projectRoot}/src`, 2); // Wild card and failed lookup
|
||||
expectedWatchedDirectories.set(`${projectRoot}/somefolder`, 1); // failed lookup for somefolder/module2
|
||||
expectedWatchedDirectories.set(`${projectRoot}/node_modules`, 1); // failed lookup for with node_modules/@types/fs
|
||||
expectedWatchedDirectories.set(`${projectRoot}/src/typings`, 1); // typeroot directory
|
||||
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectories, /*recursive*/ true);
|
||||
|
||||
function verifyModuleResolution(useNodeFile: boolean) {
|
||||
const files = [...(useNodeFile ? [nodeFile] : []), electronFile, srcFile, moduleFile, configFile, libFile];
|
||||
const host = createServerHost(files);
|
||||
const service = createProjectService(host);
|
||||
service.openClientFile(srcFile.path, srcFile.content, ScriptKind.TS, projectRoot);
|
||||
checkProjectActualFiles(service.configuredProjects.get(configFile.path)!, files.map(f => f.path));
|
||||
checkWatchedFilesDetailed(host, mapDefined(files, f => f === srcFile ? undefined : f.path), 1);
|
||||
if (useNodeFile) {
|
||||
checkWatchedDirectories(host, emptyArray, /*recursive*/ false); // since fs resolves to ambient module, shouldnt watch failed lookup
|
||||
}
|
||||
else {
|
||||
checkWatchedDirectoriesDetailed(host, [`${projectRoot}`], 1, /*recursive*/ false); // failed lookup for fs
|
||||
}
|
||||
const expectedWatchedDirectories = createMap<number>();
|
||||
expectedWatchedDirectories.set(`${projectRoot}/src`, 2); // Wild card and failed lookup
|
||||
expectedWatchedDirectories.set(`${projectRoot}/somefolder`, 1); // failed lookup for somefolder/module2
|
||||
expectedWatchedDirectories.set(`${projectRoot}/node_modules`, 1); // failed lookup for with node_modules/@types/fs
|
||||
expectedWatchedDirectories.set(`${projectRoot}/src/typings`, 1); // typeroot directory
|
||||
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectories, /*recursive*/ true);
|
||||
}
|
||||
|
||||
it("when resolves to ambient module", () => {
|
||||
verifyModuleResolution(/*useNodeFile*/ true);
|
||||
});
|
||||
|
||||
it("when resolution fails", () => {
|
||||
verifyModuleResolution(/*useNodeFile*/ false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8573,10 +8589,10 @@ export const x = 10;`
|
||||
tscWatchDirectory === Tsc_WatchDirectory.WatchFile ?
|
||||
expectedWatchedFiles :
|
||||
createMap();
|
||||
// For failed resolution lookup and tsconfig files
|
||||
mapOfDirectories.set(projectFolder, 2);
|
||||
// For failed resolution lookup and tsconfig files => cached so only watched only once
|
||||
mapOfDirectories.set(projectFolder, 1);
|
||||
// Through above recursive watches
|
||||
mapOfDirectories.set(projectSrcFolder, 2);
|
||||
mapOfDirectories.set(projectSrcFolder, 1);
|
||||
// node_modules/@types folder
|
||||
mapOfDirectories.set(`${projectFolder}/${nodeModulesAtTypes}`, 1);
|
||||
const expectedCompletions = ["file1"];
|
||||
@@ -9042,9 +9058,9 @@ export function Test2() {
|
||||
const response = executeSessionRequest<protocol.ReferencesRequest, protocol.ReferencesResponse>(session, protocol.CommandTypes.References, protocolFileLocationFromSubstring(userTs, "fnA()"));
|
||||
assert.deepEqual<protocol.ReferencesResponseBody | undefined>(response, {
|
||||
refs: [
|
||||
makeReferenceItem(userTs, /*isDefinition*/ true, "fnA"),
|
||||
makeReferenceItem(userTs, /*isDefinition*/ false, "fnA", { index: 1 }),
|
||||
makeReferenceItem(aTs, /*isDefinition*/ true, "fnA"),
|
||||
makeReferenceItem(userTs, /*isDefinition*/ true, "fnA", "import { fnA, instanceA } from \"../a/bin/a\";"),
|
||||
makeReferenceItem(userTs, /*isDefinition*/ false, "fnA", "export function fnUser() { fnA(); fnB(); instanceA; }", { index: 1 }),
|
||||
makeReferenceItem(aTs, /*isDefinition*/ true, "fnA", "export function fnA() {}"),
|
||||
],
|
||||
symbolName: "fnA",
|
||||
symbolStartOffset: protocolLocationFromSubstring(userTs.content, "fnA()").offset,
|
||||
@@ -9118,9 +9134,9 @@ export function Test2() {
|
||||
const response = executeSessionRequest<protocol.ReferencesRequest, protocol.ReferencesResponse>(session, protocol.CommandTypes.References, protocolFileLocationFromSubstring(userTs, "fnB()"));
|
||||
assert.deepEqual<protocol.ReferencesResponseBody | undefined>(response, {
|
||||
refs: [
|
||||
makeReferenceItem(userTs, /*isDefinition*/ true, "fnB"),
|
||||
makeReferenceItem(userTs, /*isDefinition*/ false, "fnB", { index: 1 }),
|
||||
makeReferenceItem(bDts, /*isDefinition*/ true, "fnB"),
|
||||
makeReferenceItem(userTs, /*isDefinition*/ true, "fnB", "import { fnB } from \"../b/bin/b\";"),
|
||||
makeReferenceItem(userTs, /*isDefinition*/ false, "fnB", "export function fnUser() { fnA(); fnB(); instanceA; }", { index: 1 }),
|
||||
makeReferenceItem(bDts, /*isDefinition*/ true, "fnB", "export declare function fnB(): void;"),
|
||||
],
|
||||
symbolName: "fnB",
|
||||
symbolStartOffset: protocolLocationFromSubstring(userTs.content, "fnB()").offset,
|
||||
@@ -9194,14 +9210,30 @@ export function Test2() {
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("getEditsForFileRename", () => {
|
||||
const { session, aTs, userTs } = makeSampleProjects();
|
||||
const response = executeSessionRequest<protocol.GetEditsForFileRenameRequest, protocol.GetEditsForFileRenameResponse>(session, protocol.CommandTypes.GetEditsForFileRename, {
|
||||
oldFilePath: aTs.path,
|
||||
newFilePath: "/a/aNew.ts",
|
||||
});
|
||||
assert.deepEqual<ReadonlyArray<protocol.FileCodeEdits>>(response, [
|
||||
{
|
||||
fileName: userTs.path,
|
||||
textChanges: [
|
||||
{ ...protocolTextSpanFromSubstring(userTs.content, "../a/bin/a"), newText: "../a/bin/aNew" },
|
||||
],
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
function makeReferenceItem(file: File, isDefinition: boolean, text: string, options?: SpanFromSubstringOptions): protocol.ReferencesResponseItem {
|
||||
function makeReferenceItem(file: File, isDefinition: boolean, text: string, lineText: string, options?: SpanFromSubstringOptions): protocol.ReferencesResponseItem {
|
||||
return {
|
||||
...protocolFileSpanFromSubstring(file, text, options),
|
||||
isDefinition,
|
||||
isWriteAccess: isDefinition,
|
||||
lineText: text,
|
||||
lineText,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-of17.ts(3,20): error
|
||||
for (let v of [v]) {
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'v' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/statements/for-ofStatements/ES5For-of17.ts:3:14: 'v' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/statements/for-ofStatements/ES5For-of17.ts:3:14: 'v' is declared here.
|
||||
var x = v;
|
||||
v++;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-of20.ts(4,15): error
|
||||
for (let v of [v]) {
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'v' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/statements/for-ofStatements/ES5For-of20.ts:3:14: 'v' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/statements/for-ofStatements/ES5For-of20.ts:3:14: 'v' is declared here.
|
||||
const v;
|
||||
~
|
||||
!!! error TS1155: 'const' declarations must be initialized.
|
||||
|
||||
@@ -32,7 +32,7 @@ tests/cases/conformance/internalModules/DeclarationMerging/simple.ts(2,31): erro
|
||||
export var Instance = new A();
|
||||
~
|
||||
!!! error TS2449: Class 'A' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/internalModules/DeclarationMerging/simple.ts:6:7: 'A' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/internalModules/DeclarationMerging/simple.ts:6:7: 'A' is declared here.
|
||||
}
|
||||
|
||||
// duplicate identifier
|
||||
|
||||
@@ -35,4 +35,5 @@ tests/cases/conformance/internalModules/exportDeclarations/ModuleWithExportedAnd
|
||||
!!! error TS2339: Property 'fn2' does not exist on type 'typeof A'.
|
||||
var fng2 = A.fng2;
|
||||
~~~~
|
||||
!!! error TS2551: Property 'fng2' does not exist on type 'typeof A'. Did you mean 'fng'?
|
||||
!!! error TS2551: Property 'fng2' does not exist on type 'typeof A'. Did you mean 'fng'?
|
||||
!!! related TS2728 tests/cases/conformance/internalModules/exportDeclarations/ModuleWithExportedAndNonExportedFunctions.ts:7:21: 'fng' is declared here.
|
||||
@@ -17,6 +17,7 @@ tests/cases/compiler/anonymousClassExpression2.ts(13,18): error TS2551: Property
|
||||
this.methodA; // error
|
||||
~~~~~~~
|
||||
!!! error TS2551: Property 'methodA' does not exist on type 'B'. Did you mean 'methodB'?
|
||||
!!! related TS2728 tests/cases/compiler/anonymousClassExpression2.ts:12:9: 'methodB' is declared here.
|
||||
this.methodB; // ok
|
||||
}
|
||||
}
|
||||
|
||||
+1484
-6943
File diff suppressed because it is too large
Load Diff
+98
-7
@@ -1,3 +1,18 @@
|
||||
/*! *****************************************************************************
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
||||
this file except in compliance with the License. You may obtain a copy of the
|
||||
License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
||||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
||||
MERCHANTABLITY OR NON-INFRINGEMENT.
|
||||
|
||||
See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
declare namespace ts {
|
||||
const versionMajorMinor = "3.0";
|
||||
/** The version of the TypeScript compiler release */
|
||||
@@ -1918,9 +1933,6 @@ declare namespace ts {
|
||||
getAmbientModules(): Symbol[];
|
||||
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
|
||||
getApparentType(type: Type): Type;
|
||||
getSuggestionForNonexistentProperty(name: Identifier | string, containingType: Type): string | undefined;
|
||||
getSuggestionForNonexistentSymbol(location: Node, name: string, meaning: SymbolFlags): string | undefined;
|
||||
getSuggestionForNonexistentModule(node: Identifier, target: Symbol): string | undefined;
|
||||
getBaseConstraintOfType(type: Type): Type | undefined;
|
||||
getDefaultFromTypeParameter(type: Type): Type | undefined;
|
||||
/**
|
||||
@@ -3227,16 +3239,21 @@ declare namespace ts {
|
||||
*/
|
||||
function getJSDocType(node: Node): TypeNode | undefined;
|
||||
/**
|
||||
* Gets the return type node for the node if provided via JSDoc's return tag.
|
||||
* Gets the return type node for the node if provided via JSDoc return tag or type tag.
|
||||
*
|
||||
* @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function
|
||||
* gets the type from inside the braces.
|
||||
* gets the type from inside the braces, after the fat arrow, etc.
|
||||
*/
|
||||
function getJSDocReturnType(node: Node): TypeNode | undefined;
|
||||
/** Get all JSDoc tags related to a node, including those on parent nodes. */
|
||||
function getJSDocTags(node: Node): ReadonlyArray<JSDocTag>;
|
||||
/** Gets all JSDoc tags of a specified kind, or undefined if not present. */
|
||||
function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): ReadonlyArray<JSDocTag>;
|
||||
/**
|
||||
* Gets the effective type parameters. If the node was parsed in a
|
||||
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
|
||||
*/
|
||||
function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration>;
|
||||
}
|
||||
declare namespace ts {
|
||||
function isNumericLiteral(node: Node): node is NumericLiteral;
|
||||
@@ -4565,6 +4582,80 @@ declare namespace ts {
|
||||
function getAllProjectOutputs(project: ParsedCommandLine): ReadonlyArray<string>;
|
||||
function formatUpToDateStatus<T>(configFileName: string, status: UpToDateStatus, relName: (fileName: string) => string, formatMessage: (message: DiagnosticMessage, ...args: string[]) => T): T | undefined;
|
||||
}
|
||||
declare namespace ts.server {
|
||||
type ActionSet = "action::set";
|
||||
type ActionInvalidate = "action::invalidate";
|
||||
type ActionPackageInstalled = "action::packageInstalled";
|
||||
type EventTypesRegistry = "event::typesRegistry";
|
||||
type EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
type EventEndInstallTypes = "event::endInstallTypes";
|
||||
type EventInitializationFailed = "event::initializationFailed";
|
||||
interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
}
|
||||
interface TypingInstallerRequestWithProjectName {
|
||||
readonly projectName: string;
|
||||
}
|
||||
interface DiscoverTypings extends TypingInstallerRequestWithProjectName {
|
||||
readonly fileNames: string[];
|
||||
readonly projectRootPath: Path;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
readonly typeAcquisition: TypeAcquisition;
|
||||
readonly unresolvedImports: SortedReadonlyArray<string>;
|
||||
readonly cachePath?: string;
|
||||
readonly kind: "discover";
|
||||
}
|
||||
interface CloseProject extends TypingInstallerRequestWithProjectName {
|
||||
readonly kind: "closeProject";
|
||||
}
|
||||
interface TypesRegistryRequest {
|
||||
readonly kind: "typesRegistry";
|
||||
}
|
||||
interface InstallPackageRequest extends TypingInstallerRequestWithProjectName {
|
||||
readonly kind: "installPackage";
|
||||
readonly fileName: Path;
|
||||
readonly packageName: string;
|
||||
readonly projectRootPath: Path;
|
||||
}
|
||||
interface PackageInstalledResponse extends ProjectResponse {
|
||||
readonly kind: ActionPackageInstalled;
|
||||
readonly success: boolean;
|
||||
readonly message: string;
|
||||
}
|
||||
interface InitializationFailedResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventInitializationFailed;
|
||||
readonly message: string;
|
||||
}
|
||||
interface ProjectResponse extends TypingInstallerResponse {
|
||||
readonly projectName: string;
|
||||
}
|
||||
interface InvalidateCachedTypings extends ProjectResponse {
|
||||
readonly kind: ActionInvalidate;
|
||||
}
|
||||
interface InstallTypes extends ProjectResponse {
|
||||
readonly kind: EventBeginInstallTypes | EventEndInstallTypes;
|
||||
readonly eventId: number;
|
||||
readonly typingsInstallerVersion: string;
|
||||
readonly packagesToInstall: ReadonlyArray<string>;
|
||||
}
|
||||
interface BeginInstallTypes extends InstallTypes {
|
||||
readonly kind: EventBeginInstallTypes;
|
||||
}
|
||||
interface EndInstallTypes extends InstallTypes {
|
||||
readonly kind: EventEndInstallTypes;
|
||||
readonly installSuccess: boolean;
|
||||
}
|
||||
interface SetTypings extends ProjectResponse {
|
||||
readonly typeAcquisition: TypeAcquisition;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
readonly typings: string[];
|
||||
readonly unresolvedImports: SortedReadonlyArray<string>;
|
||||
readonly kind: ActionSet;
|
||||
}
|
||||
}
|
||||
declare namespace ts {
|
||||
interface Node {
|
||||
getSourceFile(): SourceFile;
|
||||
@@ -5569,5 +5660,5 @@ declare namespace ts {
|
||||
*/
|
||||
function transform<T extends Node>(source: T | T[], transformers: TransformerFactory<T>[], compilerOptions?: CompilerOptions): TransformationResult<T>;
|
||||
}
|
||||
//# sourceMappingURL=typescriptServices.d.ts.map
|
||||
export = ts
|
||||
|
||||
export = ts;
|
||||
@@ -8,4 +8,5 @@ tests/cases/compiler/assignmentRestElementWithErrorSourceType.ts(2,10): error TS
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'c'.
|
||||
~~~~~
|
||||
!!! error TS2552: Cannot find name 'tupel'. Did you mean 'tuple'?
|
||||
!!! error TS2552: Cannot find name 'tupel'. Did you mean 'tuple'?
|
||||
!!! related TS2728 tests/cases/compiler/assignmentRestElementWithErrorSourceType.ts:1:5: 'tuple' is declared here.
|
||||
@@ -21,6 +21,7 @@ tests/cases/compiler/baseCheck.ts(26,9): error TS2304: Cannot find name 'x'.
|
||||
super(0, loc);
|
||||
~~~
|
||||
!!! error TS2552: Cannot find name 'loc'. Did you mean 'ELoc'?
|
||||
!!! related TS2728 tests/cases/compiler/baseCheck.ts:2:7: 'ELoc' is declared here.
|
||||
}
|
||||
|
||||
m() {
|
||||
|
||||
@@ -8,16 +8,16 @@ tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(8,7): error TS2448: Bloc
|
||||
for (let {[a]: a} of [{ }]) continue;
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:2:16: 'a' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:2:16: 'a' is declared here.
|
||||
|
||||
// 2:
|
||||
for (let {[a]: a} = { }; false; ) continue;
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:5:16: 'a' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:5:16: 'a' is declared here.
|
||||
|
||||
// 3:
|
||||
let {[b]: b} = { };
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'b' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:8:11: 'b' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:8:11: 'b' is declared here.
|
||||
@@ -9,7 +9,7 @@ tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448:
|
||||
let a = x;
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'x' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:3:9: 'x' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:3:9: 'x' is declared here.
|
||||
let x;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448:
|
||||
static a = x;
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'x' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:60:9: 'x' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:60:9: 'x' is declared here.
|
||||
}
|
||||
let x;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448:
|
||||
static a = x;
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'x' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:67:9: 'x' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:67:9: 'x' is declared here.
|
||||
}
|
||||
let x;
|
||||
}
|
||||
@@ -116,7 +116,7 @@ tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448:
|
||||
a: x
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'x' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:102:9: 'x' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:102:9: 'x' is declared here.
|
||||
}
|
||||
let x
|
||||
}
|
||||
@@ -14,7 +14,7 @@ tests/cases/compiler/cf.ts(36,13): error TS7027: Unreachable code detected.
|
||||
if (y==7) {
|
||||
continue L1;
|
||||
x=11;
|
||||
~
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
if (y==3) {
|
||||
@@ -28,7 +28,7 @@ tests/cases/compiler/cf.ts(36,13): error TS7027: Unreachable code detected.
|
||||
if (y==20) {
|
||||
break;
|
||||
x=12;
|
||||
~
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
} while (y<41);
|
||||
@@ -41,13 +41,13 @@ tests/cases/compiler/cf.ts(36,13): error TS7027: Unreachable code detected.
|
||||
L3: if (x<y) {
|
||||
break L2;
|
||||
x=13;
|
||||
~
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
else {
|
||||
break L3;
|
||||
x=14;
|
||||
~
|
||||
~~~~~
|
||||
!!! error TS7027: Unreachable code detected.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
tests/cases/compiler/bug25434.js(4,9): error TS2304: Cannot find name 'b'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/bug25434.js (1 errors) ====
|
||||
// should not crash while checking
|
||||
function Test({ b = '' } = {}) {}
|
||||
|
||||
Test(({ b = '5' } = {}));
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'b'.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
=== tests/cases/compiler/bug25434.js ===
|
||||
// should not crash while checking
|
||||
function Test({ b = '' } = {}) {}
|
||||
>Test : Symbol(Test, Decl(bug25434.js, 0, 0))
|
||||
>b : Symbol(b, Decl(bug25434.js, 1, 15))
|
||||
|
||||
Test(({ b = '5' } = {}));
|
||||
>Test : Symbol(Test, Decl(bug25434.js, 0, 0))
|
||||
>b : Symbol(b, Decl(bug25434.js, 3, 7))
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
=== tests/cases/compiler/bug25434.js ===
|
||||
// should not crash while checking
|
||||
function Test({ b = '' } = {}) {}
|
||||
>Test : ({ b }?: { [x: string]: any; }) => void
|
||||
>b : string
|
||||
>'' : ""
|
||||
>{} : { b?: string; }
|
||||
|
||||
Test(({ b = '5' } = {}));
|
||||
>Test(({ b = '5' } = {})) : void
|
||||
>Test : ({ b }?: { [x: string]: any; }) => void
|
||||
>({ b = '5' } = {}) : { b?: any; }
|
||||
>{ b = '5' } = {} : { b?: any; }
|
||||
>{ b = '5' } : { [x: string]: any; b?: any; }
|
||||
>b : any
|
||||
>{} : { b?: any; }
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
tests/cases/conformance/jsdoc/test.js(3,17): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/test.js(5,14): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/test.js(7,24): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/test.js(10,17): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/test.js(12,14): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
tests/cases/conformance/jsdoc/test.js(14,24): error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/jsdoc/test.js (6 errors) ====
|
||||
// all 6 should error on return statement/expression
|
||||
/** @type {(x: number) => string} */
|
||||
function h(x) { return x }
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
/** @type {(x: number) => string} */
|
||||
var f = x => x
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
/** @type {(x: number) => string} */
|
||||
var g = function (x) { return x }
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
/** @type {{ (x: number): string }} */
|
||||
function i(x) { return x }
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
/** @type {{ (x: number): string }} */
|
||||
var j = x => x
|
||||
~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
/** @type {{ (x: number): string }} */
|
||||
var k = function (x) { return x }
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'number' is not assignable to type 'string'.
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
=== tests/cases/conformance/jsdoc/test.js ===
|
||||
// all 6 should error on return statement/expression
|
||||
/** @type {(x: number) => string} */
|
||||
function h(x) { return x }
|
||||
>h : Symbol(h, Decl(test.js, 0, 0))
|
||||
>x : Symbol(x, Decl(test.js, 2, 11))
|
||||
>x : Symbol(x, Decl(test.js, 2, 11))
|
||||
|
||||
/** @type {(x: number) => string} */
|
||||
var f = x => x
|
||||
>f : Symbol(f, Decl(test.js, 4, 3))
|
||||
>x : Symbol(x, Decl(test.js, 4, 7))
|
||||
>x : Symbol(x, Decl(test.js, 4, 7))
|
||||
|
||||
/** @type {(x: number) => string} */
|
||||
var g = function (x) { return x }
|
||||
>g : Symbol(g, Decl(test.js, 6, 3))
|
||||
>x : Symbol(x, Decl(test.js, 6, 18))
|
||||
>x : Symbol(x, Decl(test.js, 6, 18))
|
||||
|
||||
/** @type {{ (x: number): string }} */
|
||||
function i(x) { return x }
|
||||
>i : Symbol(i, Decl(test.js, 6, 33))
|
||||
>x : Symbol(x, Decl(test.js, 9, 11))
|
||||
>x : Symbol(x, Decl(test.js, 9, 11))
|
||||
|
||||
/** @type {{ (x: number): string }} */
|
||||
var j = x => x
|
||||
>j : Symbol(j, Decl(test.js, 11, 3))
|
||||
>x : Symbol(x, Decl(test.js, 11, 7))
|
||||
>x : Symbol(x, Decl(test.js, 11, 7))
|
||||
|
||||
/** @type {{ (x: number): string }} */
|
||||
var k = function (x) { return x }
|
||||
>k : Symbol(k, Decl(test.js, 13, 3))
|
||||
>x : Symbol(x, Decl(test.js, 13, 18))
|
||||
>x : Symbol(x, Decl(test.js, 13, 18))
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
=== tests/cases/conformance/jsdoc/test.js ===
|
||||
// all 6 should error on return statement/expression
|
||||
/** @type {(x: number) => string} */
|
||||
function h(x) { return x }
|
||||
>h : (x: number) => string
|
||||
>x : number
|
||||
>x : number
|
||||
|
||||
/** @type {(x: number) => string} */
|
||||
var f = x => x
|
||||
>f : (x: number) => string
|
||||
>x => x : (x: number) => string
|
||||
>x : number
|
||||
>x : number
|
||||
|
||||
/** @type {(x: number) => string} */
|
||||
var g = function (x) { return x }
|
||||
>g : (x: number) => string
|
||||
>function (x) { return x } : (x: number) => string
|
||||
>x : number
|
||||
>x : number
|
||||
|
||||
/** @type {{ (x: number): string }} */
|
||||
function i(x) { return x }
|
||||
>i : (x: number) => string
|
||||
>x : number
|
||||
>x : number
|
||||
|
||||
/** @type {{ (x: number): string }} */
|
||||
var j = x => x
|
||||
>j : (x: number) => string
|
||||
>x => x : (x: number) => string
|
||||
>x : number
|
||||
>x : number
|
||||
|
||||
/** @type {{ (x: number): string }} */
|
||||
var k = function (x) { return x }
|
||||
>k : (x: number) => string
|
||||
>function (x) { return x } : (x: number) => string
|
||||
>x : number
|
||||
>x : number
|
||||
|
||||
@@ -32,6 +32,7 @@ tests/cases/conformance/jsx/file.tsx(32,10): error TS2322: Type '{ children: ((u
|
||||
<h1>{ user.NAme }</h1>
|
||||
~~~~
|
||||
!!! error TS2551: Property 'NAme' does not exist on type 'IUser'. Did you mean 'Name'?
|
||||
!!! related TS2728 tests/cases/conformance/jsx/file.tsx:4:5: 'Name' is declared here.
|
||||
) }
|
||||
</FetchUser>
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.t
|
||||
export class D extends a.C {
|
||||
~
|
||||
!!! error TS2449: Class 'C' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.ts:11:18: 'C' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.ts:11:18: 'C' is declared here.
|
||||
id: number;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
|
||||
var x : any = C;
|
||||
~
|
||||
!!! error TS2449: Class 'C' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts:26:7: 'C' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts:26:7: 'C' is declared here.
|
||||
new x; // okay -- undefined behavior at runtime
|
||||
|
||||
class C extends B { } // error -- not declared abstract
|
||||
|
||||
+4
-4
@@ -12,18 +12,18 @@ tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts(8,6):
|
||||
static readonly [A.p1] = 0;
|
||||
~
|
||||
!!! error TS2449: Class 'A' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' is declared here.
|
||||
static [A.p2]() { return 0 };
|
||||
~
|
||||
!!! error TS2449: Class 'A' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' is declared here.
|
||||
[A.p1]() { }
|
||||
~
|
||||
!!! error TS2449: Class 'A' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' is declared here.
|
||||
[A.p2] = 0
|
||||
~
|
||||
!!! error TS2449: Class 'A' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' is declared here.
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla
|
||||
!!! error TS2506: 'C' is referenced directly or indirectly in its own base expression.
|
||||
~
|
||||
!!! error TS2449: Class 'E' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts:5:7: 'E' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts:5:7: 'E' is declared here.
|
||||
|
||||
class D extends C { bar: string; }
|
||||
~
|
||||
@@ -29,7 +29,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla
|
||||
!!! error TS2506: 'C2' is referenced directly or indirectly in its own base expression.
|
||||
~~
|
||||
!!! error TS2449: Class 'E2' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts:11:7: 'E2' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts:11:7: 'E2' is declared here.
|
||||
|
||||
class D2<T> extends C2<T> { bar: T; }
|
||||
~~
|
||||
|
||||
@@ -14,7 +14,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla
|
||||
!!! error TS2506: 'C' is referenced directly or indirectly in its own base expression.
|
||||
~
|
||||
!!! error TS2449: Class 'E' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts:9:18: 'E' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts:9:18: 'E' is declared here.
|
||||
|
||||
module M {
|
||||
export class D extends C { bar: string; }
|
||||
@@ -35,7 +35,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla
|
||||
!!! error TS2506: 'C2' is referenced directly or indirectly in its own base expression.
|
||||
~~
|
||||
!!! error TS2449: Class 'E2' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts:20:22: 'E2' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts:20:22: 'E2' is declared here.
|
||||
|
||||
module P {
|
||||
export class D2<T> extends C2<T> { bar: T; }
|
||||
|
||||
@@ -6,7 +6,7 @@ tests/cases/compiler/classInheritence.ts(2,7): error TS2506: 'A' is referenced d
|
||||
class B extends A { }
|
||||
~
|
||||
!!! error TS2449: Class 'A' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/classInheritence.ts:2:7: 'A' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classInheritence.ts:2:7: 'A' is declared here.
|
||||
class A extends A { }
|
||||
~
|
||||
!!! error TS2506: 'A' is referenced directly or indirectly in its own base expression.
|
||||
@@ -12,6 +12,6 @@ tests/cases/compiler/classMergedWithInterfaceMultipleBasesNoError.ts(8,30): erro
|
||||
readonly observer = this.handleIntersection;
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2729: Property 'handleIntersection' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classMergedWithInterfaceMultipleBasesNoError.ts:9:14: 'handleIntersection' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classMergedWithInterfaceMultipleBasesNoError.ts:9:14: 'handleIntersection' is declared here.
|
||||
readonly handleIntersection = () => { }
|
||||
}
|
||||
@@ -5,7 +5,7 @@ tests/cases/compiler/classOrder2.ts(1,17): error TS2449: Class 'B' used before i
|
||||
class A extends B {
|
||||
~
|
||||
!!! error TS2449: Class 'B' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/classOrder2.ts:7:7: 'B' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classOrder2.ts:7:7: 'B' is declared here.
|
||||
|
||||
foo() { this.bar(); }
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ tests/cases/compiler/classSideInheritance2.ts(7,23): error TS2449: Class 'TextBa
|
||||
class SubText extends TextBase {
|
||||
~~~~~~~~
|
||||
!!! error TS2449: Class 'TextBase' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/classSideInheritance2.ts:14:7: 'TextBase' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classSideInheritance2.ts:14:7: 'TextBase' is declared here.
|
||||
|
||||
constructor(text: IText, span: TextSpan) {
|
||||
super();
|
||||
|
||||
+5
-5
@@ -10,21 +10,21 @@ tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts(4,
|
||||
static enumMember = Enum.A;
|
||||
~~~~
|
||||
!!! error TS2450: Enum 'Enum' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:7:6: 'Enum' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:7:6: 'Enum' is declared here.
|
||||
~
|
||||
!!! error TS2729: Property 'A' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:8:5: 'A' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:8:5: 'A' is declared here.
|
||||
static objLiteralMember = ObjLiteral.A;
|
||||
~~~~~~~~~~
|
||||
!!! error TS2448: Block-scoped variable 'ObjLiteral' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:11:7: 'ObjLiteral' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:11:7: 'ObjLiteral' is declared here.
|
||||
~
|
||||
!!! error TS2729: Property 'A' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:12:5: 'A' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:12:5: 'A' is declared here.
|
||||
static namespaceMember = Namespace.A;
|
||||
~
|
||||
!!! error TS2729: Property 'A' is used before its initialization.
|
||||
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:16:16: 'A' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:16:16: 'A' is declared here.
|
||||
}
|
||||
|
||||
enum Enum {
|
||||
|
||||
@@ -6,7 +6,7 @@ tests/cases/compiler/complexClassRelationships.ts(2,23): error TS2449: Class 'Ba
|
||||
class Derived extends Base {
|
||||
~~~~
|
||||
!!! error TS2449: Class 'Base' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/complexClassRelationships.ts:13:7: 'Base' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/complexClassRelationships.ts:13:7: 'Base' is declared here.
|
||||
public static createEmpty(): Derived {
|
||||
var item = new Derived();
|
||||
return item;
|
||||
|
||||
@@ -9,17 +9,17 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticPr
|
||||
get [C.staticProp]() {
|
||||
~
|
||||
!!! error TS2449: Class 'C' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts:1:7: 'C' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts:1:7: 'C' is declared here.
|
||||
return "hello";
|
||||
}
|
||||
set [C.staticProp](x: string) {
|
||||
~
|
||||
!!! error TS2449: Class 'C' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts:1:7: 'C' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts:1:7: 'C' is declared here.
|
||||
var y = x;
|
||||
}
|
||||
[C.staticProp]() { }
|
||||
~
|
||||
!!! error TS2449: Class 'C' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts:1:7: 'C' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts:1:7: 'C' is declared here.
|
||||
}
|
||||
@@ -7,7 +7,7 @@ tests/cases/compiler/constDeclarations-useBeforeDefinition.ts(8,5): error TS2448
|
||||
c1;
|
||||
~~
|
||||
!!! error TS2448: Block-scoped variable 'c1' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/constDeclarations-useBeforeDefinition.ts:3:11: 'c1' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/constDeclarations-useBeforeDefinition.ts:3:11: 'c1' is declared here.
|
||||
const c1 = 0;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ tests/cases/compiler/constDeclarations-useBeforeDefinition.ts(8,5): error TS2448
|
||||
v1;
|
||||
~~
|
||||
!!! error TS2448: Block-scoped variable 'v1' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/constDeclarations-useBeforeDefinition.ts:9:11: 'v1' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/constDeclarations-useBeforeDefinition.ts:9:11: 'v1' is declared here.
|
||||
const v1 = 0;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ tests/cases/compiler/file1.ts(1,1): error TS2448: Block-scoped variable 'c' used
|
||||
c;
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'c' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/file2.ts:1:7: 'c' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/file2.ts:1:7: 'c' is declared here.
|
||||
|
||||
==== tests/cases/compiler/file2.ts (0 errors) ====
|
||||
const c = 0;
|
||||
@@ -466,6 +466,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(261,1): error TS
|
||||
return this.method1(2);
|
||||
~~~~~~~
|
||||
!!! error TS2551: Property 'method1' does not exist on type 'B'. Did you mean 'method2'?
|
||||
!!! related TS2728 tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts:245:16: 'method2' is declared here.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ var B = /** @class */ (function () {
|
||||
var _a;
|
||||
__decorate([
|
||||
Decorate,
|
||||
__metadata("design:type", typeof (_a = typeof Map !== "undefined" && Map) === "function" && _a || Object)
|
||||
__metadata("design:type", typeof (_a = typeof Map !== "undefined" && Map) === "function" ? _a : Object)
|
||||
], B.prototype, "member");
|
||||
return B;
|
||||
}());
|
||||
|
||||
@@ -49,7 +49,7 @@ var MyClass = /** @class */ (function () {
|
||||
var _a;
|
||||
MyClass = __decorate([
|
||||
someDecorator,
|
||||
__metadata("design:paramtypes", [typeof (_a = (typeof db_1.default !== "undefined" && db_1.default).db) === "function" && _a || Object])
|
||||
__metadata("design:paramtypes", [typeof (_a = typeof db_1.default !== "undefined" && db_1.default.db) === "function" ? _a : Object])
|
||||
], MyClass);
|
||||
return MyClass;
|
||||
}());
|
||||
|
||||
@@ -49,7 +49,7 @@ var MyClass = /** @class */ (function () {
|
||||
var _a;
|
||||
MyClass = __decorate([
|
||||
someDecorator,
|
||||
__metadata("design:paramtypes", [typeof (_a = (typeof db_1.default !== "undefined" && db_1.default).db) === "function" && _a || Object])
|
||||
__metadata("design:paramtypes", [typeof (_a = typeof db_1.default !== "undefined" && db_1.default.db) === "function" ? _a : Object])
|
||||
], MyClass);
|
||||
return MyClass;
|
||||
}());
|
||||
|
||||
@@ -5,7 +5,7 @@ tests/cases/compiler/derivedClasses.ts(1,19): error TS2449: Class 'Color' used b
|
||||
class Red extends Color {
|
||||
~~~~~
|
||||
!!! error TS2449: Class 'Color' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/derivedClasses.ts:8:7: 'Color' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/derivedClasses.ts:8:7: 'Color' is declared here.
|
||||
public shade() {
|
||||
var getHue = () => { return this.hue(); };
|
||||
return getHue() + " red";
|
||||
|
||||
@@ -9,11 +9,11 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss
|
||||
const [c, d = c, e = e] = [1]; // error for e = e
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'e' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts:2:18: 'e' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts:2:18: 'e' is declared here.
|
||||
const [f, g = f, h = i, i = f] = [1]; // error for h = i
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'i' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts:3:25: 'i' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts:3:25: 'i' is declared here.
|
||||
|
||||
(function ([a, b = a]) { // ok
|
||||
})([1]);
|
||||
|
||||
+2
-2
@@ -11,10 +11,10 @@ tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAs
|
||||
e = f, // error
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'f' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment4.ts:7:5: 'f' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment4.ts:7:5: 'f' is declared here.
|
||||
f = f // error
|
||||
~
|
||||
!!! error TS2448: Block-scoped variable 'f' used before its declaration.
|
||||
!!! related TS2728 tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment4.ts:7:5: 'f' was declared here.
|
||||
!!! related TS2728 tests/cases/conformance/es6/destructuring/destructuringObjectBindingPatternAndAssignment4.ts:7:5: 'f' is declared here.
|
||||
} = { } as any;
|
||||
|
||||
@@ -48,6 +48,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(
|
||||
a1(...array2); // Error parameter type is (number|string)[]
|
||||
~~~~~~
|
||||
!!! error TS2552: Cannot find name 'array2'. Did you mean 'Array'?
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:1298:15: 'Array' is declared here.
|
||||
a5([1, 2, "string", false, true]); // Error, parameter type is [any, any, [[any]]]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '[number, number, string, boolean, boolean]' is not assignable to parameter of type '[any, any, [[any]]]'.
|
||||
|
||||
@@ -5,7 +5,7 @@ tests/cases/compiler/enumUsedBeforeDeclaration.ts(1,18): error TS2450: Enum 'Col
|
||||
const v: Color = Color.Green;
|
||||
~~~~~
|
||||
!!! error TS2450: Enum 'Color' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/enumUsedBeforeDeclaration.ts:3:6: 'Color' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/enumUsedBeforeDeclaration.ts:3:6: 'Color' is declared here.
|
||||
const v2: ConstColor = ConstColor.Green;
|
||||
enum Color { Red, Green, Blue }
|
||||
const enum ConstColor { Red, Green, Blue }
|
||||
|
||||
@@ -2,9 +2,10 @@ tests/cases/compiler/errorElaboration.ts(12,5): error TS2345: Argument of type '
|
||||
Type 'Container<Ref<string>>' is not assignable to type 'Container<Ref<number>>'.
|
||||
Type 'Ref<string>' is not assignable to type 'Ref<number>'.
|
||||
Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/compiler/errorElaboration.ts(17,11): error TS2322: Type '"bar"' is not assignable to type '"foo"'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/errorElaboration.ts (1 errors) ====
|
||||
==== tests/cases/compiler/errorElaboration.ts (2 errors) ====
|
||||
// Repro for #5712
|
||||
|
||||
interface Ref<T> {
|
||||
@@ -22,4 +23,13 @@ tests/cases/compiler/errorElaboration.ts(12,5): error TS2345: Argument of type '
|
||||
!!! error TS2345: Type 'Container<Ref<string>>' is not assignable to type 'Container<Ref<number>>'.
|
||||
!!! error TS2345: Type 'Ref<string>' is not assignable to type 'Ref<number>'.
|
||||
!!! error TS2345: Type 'string' is not assignable to type 'number'.
|
||||
|
||||
// Repro for #25498
|
||||
|
||||
function test(): {[A in "foo"]: A} {
|
||||
return {foo: "bar"};
|
||||
~~~
|
||||
!!! error TS2322: Type '"bar"' is not assignable to type '"foo"'.
|
||||
!!! related TS6500 tests/cases/compiler/errorElaboration.ts:16:18: The expected type comes from property 'foo' which is declared here on type '{ foo: "foo"; }'
|
||||
}
|
||||
|
||||
@@ -11,9 +11,19 @@ interface Container<T> {
|
||||
declare function foo(x: () => Container<Ref<number>>): void;
|
||||
let a: () => Container<Ref<string>>;
|
||||
foo(a);
|
||||
|
||||
// Repro for #25498
|
||||
|
||||
function test(): {[A in "foo"]: A} {
|
||||
return {foo: "bar"};
|
||||
}
|
||||
|
||||
|
||||
//// [errorElaboration.js]
|
||||
// Repro for #5712
|
||||
var a;
|
||||
foo(a);
|
||||
// Repro for #25498
|
||||
function test() {
|
||||
return { foo: "bar" };
|
||||
}
|
||||
|
||||
@@ -38,3 +38,14 @@ foo(a);
|
||||
>foo : Symbol(foo, Decl(errorElaboration.ts, 8, 1))
|
||||
>a : Symbol(a, Decl(errorElaboration.ts, 10, 3))
|
||||
|
||||
// Repro for #25498
|
||||
|
||||
function test(): {[A in "foo"]: A} {
|
||||
>test : Symbol(test, Decl(errorElaboration.ts, 11, 7))
|
||||
>A : Symbol(A, Decl(errorElaboration.ts, 15, 19))
|
||||
>A : Symbol(A, Decl(errorElaboration.ts, 15, 19))
|
||||
|
||||
return {foo: "bar"};
|
||||
>foo : Symbol(foo, Decl(errorElaboration.ts, 16, 10))
|
||||
}
|
||||
|
||||
|
||||
@@ -39,3 +39,16 @@ foo(a);
|
||||
>foo : (x: () => Container<Ref<number>>) => void
|
||||
>a : () => Container<Ref<string>>
|
||||
|
||||
// Repro for #25498
|
||||
|
||||
function test(): {[A in "foo"]: A} {
|
||||
>test : () => { foo: "foo"; }
|
||||
>A : A
|
||||
>A : A
|
||||
|
||||
return {foo: "bar"};
|
||||
>{foo: "bar"} : { foo: "bar"; }
|
||||
>foo : "bar"
|
||||
>"bar" : "bar"
|
||||
}
|
||||
|
||||
|
||||
@@ -12,4 +12,5 @@ tests/cases/compiler/errorMessageOnObjectLiteralType.ts(6,8): error TS2551: Prop
|
||||
!!! error TS2339: Property 'getOwnPropertyNamess' does not exist on type '{ a: string; b: number; }'.
|
||||
Object.getOwnPropertyNamess(null);
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2551: Property 'getOwnPropertyNamess' does not exist on type 'ObjectConstructor'. Did you mean 'getOwnPropertyNames'?
|
||||
!!! error TS2551: Property 'getOwnPropertyNamess' does not exist on type 'ObjectConstructor'. Did you mean 'getOwnPropertyNames'?
|
||||
!!! related TS2728 /.ts/lib.es5.d.ts:179:5: 'getOwnPropertyNames' is declared here.
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/compiler/errorWithTruncatedType.ts(10,5): error TS2322: Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propert...' is not assignable to type 'string'.
|
||||
tests/cases/compiler/errorWithTruncatedType.ts(10,5): error TS2322: Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; }' is not assignable to type 'string'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/errorWithTruncatedType.ts (1 errors) ====
|
||||
@@ -13,5 +13,5 @@ tests/cases/compiler/errorWithTruncatedType.ts(10,5): error TS2322: Type '{ prop
|
||||
// String representation of type of 'x' should be truncated in error message
|
||||
var s: string = x;
|
||||
~
|
||||
!!! error TS2322: Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propert...' is not assignable to type 'string'.
|
||||
!!! error TS2322: Type '{ propertyWithAnExceedinglyLongName1: string; propertyWithAnExceedinglyLongName2: string; propertyWithAnExceedinglyLongName3: string; propertyWithAnExceedinglyLongName4: string; propertyWithAnExceedinglyLongName5: string; }' is not assignable to type 'string'.
|
||||
|
||||
@@ -5,7 +5,7 @@ tests/cases/compiler/es5ExportDefaultClassDeclaration3.ts(1,21): error TS2449: C
|
||||
var before: C = new C();
|
||||
~
|
||||
!!! error TS2449: Class 'C' used before its declaration.
|
||||
!!! related TS2728 tests/cases/compiler/es5ExportDefaultClassDeclaration3.ts:3:22: 'C' was declared here.
|
||||
!!! related TS2728 tests/cases/compiler/es5ExportDefaultClassDeclaration3.ts:3:22: 'C' is declared here.
|
||||
|
||||
export default class C {
|
||||
method(): C {
|
||||
|
||||
@@ -13,4 +13,5 @@ tests/cases/compiler/exactSpellingSuggestion.ts(9,4): error TS2551: Property 'bi
|
||||
U8.bit_2
|
||||
~~~~~
|
||||
!!! error TS2551: Property 'bit_2' does not exist on type 'typeof U8'. Did you mean 'BIT_2'?
|
||||
!!! related TS2728 tests/cases/compiler/exactSpellingSuggestion.ts:6:5: 'BIT_2' is declared here.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user