mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into jsxFragment
This commit is contained in:
+42
-27
@@ -64,7 +64,7 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
|
||||
browser: process.env.browser || process.env.b || "IE",
|
||||
timeout: process.env.timeout || 40000,
|
||||
tests: process.env.test || process.env.tests || process.env.t,
|
||||
light: process.env.light || false,
|
||||
light: process.env.light === undefined || process.env.light !== "false",
|
||||
reporter: process.env.reporter || process.env.r,
|
||||
lint: process.env.lint || true,
|
||||
files: process.env.f || process.env.file || process.env.files || "",
|
||||
@@ -87,7 +87,7 @@ function possiblyQuote(cmd: string) {
|
||||
}
|
||||
|
||||
let useDebugMode = true;
|
||||
let host = cmdLineOptions["host"];
|
||||
let host = cmdLineOptions.host;
|
||||
|
||||
// Constants
|
||||
const compilerDirectory = "src/compiler/";
|
||||
@@ -171,15 +171,32 @@ const librarySourceMap = [
|
||||
// JavaScript + all host library
|
||||
{ target: "lib.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(hostsLibrarySources) },
|
||||
{ target: "lib.es6.d.ts", sources: ["header.d.ts", "es5.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.es2016.full.d.ts", sources: ["header.d.ts", "es2016.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.es2017.full.d.ts", sources: ["header.d.ts", "es2017.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.esnext.full.d.ts", sources: ["header.d.ts", "esnext.d.ts"].concat(es2015LibrarySources, hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.es2016.full.d.ts", sources: ["header.d.ts", "es2016.d.ts"].concat(hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.es2017.full.d.ts", sources: ["header.d.ts", "es2017.d.ts"].concat(hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
{ target: "lib.esnext.full.d.ts", sources: ["header.d.ts", "esnext.d.ts"].concat(hostsLibrarySources, "dom.iterable.d.ts") },
|
||||
].concat(es2015LibrarySourceMap, es2016LibrarySourceMap, es2017LibrarySourceMap, esnextLibrarySourceMap);
|
||||
|
||||
const libraryTargets = librarySourceMap.map(function(f) {
|
||||
return path.join(builtLocalDirectory, f.target);
|
||||
});
|
||||
|
||||
/**
|
||||
* .lcg file is what localization team uses to know what messages to localize.
|
||||
* The file is always generated in 'enu\diagnosticMessages.generated.json.lcg'
|
||||
*/
|
||||
const generatedLCGFile = path.join(builtLocalDirectory, "enu", "diagnosticMessages.generated.json.lcg");
|
||||
|
||||
/**
|
||||
* The localization target produces the two following transformations:
|
||||
* 1. 'src\loc\lcl\<locale>\diagnosticMessages.generated.json.lcl' => 'built\local\<locale>\diagnosticMessages.generated.json'
|
||||
* convert localized resources into a .json file the compiler can understand
|
||||
* 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg'
|
||||
* generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json
|
||||
*/
|
||||
const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map(function (f) {
|
||||
return path.join(builtLocalDirectory, f, "diagnosticMessages.generated.json");
|
||||
}).concat(generatedLCGFile);
|
||||
|
||||
for (const i in libraryTargets) {
|
||||
const entry = librarySourceMap[i];
|
||||
const target = libraryTargets[i];
|
||||
@@ -398,7 +415,6 @@ gulp.task(generateLocalizedDiagnosticMessagesJs, /*help*/ false, [], () => {
|
||||
});
|
||||
|
||||
// Localize diagnostics
|
||||
const generatedLCGFile = path.join(builtLocalDirectory, "enu", "diagnosticMessages.generated.json.lcg");
|
||||
gulp.task(generatedLCGFile, [generateLocalizedDiagnosticMessagesJs, diagnosticInfoMapTs], (done) => {
|
||||
if (fs.existsSync(builtLocalDirectory) && needsUpdate(generatedDiagnosticMessagesJSON, generatedLCGFile)) {
|
||||
exec(host, [generateLocalizedDiagnosticMessagesJs, lclDirectory, builtLocalDirectory, generatedDiagnosticMessagesJSON], done, done);
|
||||
@@ -576,8 +592,7 @@ gulp.task("dontUseDebugMode", /*help*/ false, [], (done) => { useDebugMode = fal
|
||||
gulp.task("VerifyLKG", /*help*/ false, [], () => {
|
||||
const expectedFiles = [builtLocalCompiler, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, typingsInstallerJs, cancellationTokenJs].concat(libraryTargets);
|
||||
const missingFiles = expectedFiles.
|
||||
concat(fs.readdirSync(lclDirectory).map(function (d) { return path.join(builtLocalDirectory, d, "diagnosticMessages.generated.json"); })).
|
||||
concat(generatedLCGFile).
|
||||
concat(localizationTargets).
|
||||
filter(f => !fs.existsSync(f));
|
||||
if (missingFiles.length > 0) {
|
||||
throw new Error("Cannot replace the LKG unless all built targets are present in directory " + builtLocalDirectory +
|
||||
@@ -636,15 +651,15 @@ function restoreSavedNodeEnv() {
|
||||
}
|
||||
|
||||
function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: (e?: any) => void) {
|
||||
const lintFlag = cmdLineOptions["lint"];
|
||||
const lintFlag = cmdLineOptions.lint;
|
||||
cleanTestDirs((err) => {
|
||||
if (err) { console.error(err); failWithStatus(err, 1); }
|
||||
let testTimeout = cmdLineOptions["timeout"];
|
||||
const debug = cmdLineOptions["debug"];
|
||||
const inspect = cmdLineOptions["inspect"];
|
||||
const tests = cmdLineOptions["tests"];
|
||||
const light = cmdLineOptions["light"];
|
||||
const stackTraceLimit = cmdLineOptions["stackTraceLimit"];
|
||||
let testTimeout = cmdLineOptions.timeout;
|
||||
const debug = cmdLineOptions.debug;
|
||||
const inspect = cmdLineOptions.inspect;
|
||||
const tests = cmdLineOptions.tests;
|
||||
const light = cmdLineOptions.light;
|
||||
const stackTraceLimit = cmdLineOptions.stackTraceLimit;
|
||||
const testConfigFile = "test.config";
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
fs.unlinkSync(testConfigFile);
|
||||
@@ -660,7 +675,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
} while (fs.existsSync(taskConfigsFolder));
|
||||
fs.mkdirSync(taskConfigsFolder);
|
||||
|
||||
workerCount = cmdLineOptions["workers"];
|
||||
workerCount = cmdLineOptions.workers;
|
||||
}
|
||||
|
||||
if (tests || light || taskConfigsFolder) {
|
||||
@@ -671,8 +686,8 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
testTimeout = 400000;
|
||||
}
|
||||
|
||||
const colors = cmdLineOptions["colors"];
|
||||
const reporter = cmdLineOptions["reporter"] || defaultReporter;
|
||||
const colors = cmdLineOptions.colors;
|
||||
const reporter = cmdLineOptions.reporter || defaultReporter;
|
||||
|
||||
// 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
|
||||
@@ -860,7 +875,7 @@ function cleanTestDirs(done: (e?: any) => void) {
|
||||
|
||||
// used to pass data from jake command line directly to run.js
|
||||
function writeTestConfigFile(tests: string, light: boolean, taskConfigsFolder?: string, workerCount?: number, stackTraceLimit?: string) {
|
||||
const testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, light, workerCount, stackTraceLimit, taskConfigsFolder, noColor: !cmdLineOptions["colors"] });
|
||||
const testConfigContents = JSON.stringify({ test: tests ? [tests] : undefined, light, workerCount, stackTraceLimit, taskConfigsFolder, noColor: !cmdLineOptions.colors });
|
||||
console.log("Running tests with config: " + testConfigContents);
|
||||
fs.writeFileSync("test.config", testConfigContents);
|
||||
}
|
||||
@@ -870,8 +885,8 @@ gulp.task("runtests-browser", "Runs the tests using the built run.js file like '
|
||||
cleanTestDirs((err) => {
|
||||
if (err) { console.error(err); done(err); process.exit(1); }
|
||||
host = "node";
|
||||
const tests = cmdLineOptions["tests"];
|
||||
const light = cmdLineOptions["light"];
|
||||
const tests = cmdLineOptions.tests;
|
||||
const light = cmdLineOptions.light;
|
||||
const testConfigFile = "test.config";
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
fs.unlinkSync(testConfigFile);
|
||||
@@ -881,8 +896,8 @@ gulp.task("runtests-browser", "Runs the tests using the built run.js file like '
|
||||
}
|
||||
|
||||
const args = [nodeServerOutFile];
|
||||
if (cmdLineOptions["browser"]) {
|
||||
args.push(cmdLineOptions["browser"]);
|
||||
if (cmdLineOptions.browser) {
|
||||
args.push(cmdLineOptions.browser);
|
||||
}
|
||||
if (tests) {
|
||||
args.push(JSON.stringify(tests));
|
||||
@@ -892,13 +907,13 @@ gulp.task("runtests-browser", "Runs the tests using the built run.js file like '
|
||||
});
|
||||
|
||||
gulp.task("generate-code-coverage", "Generates code coverage data via istanbul", ["tests"], (done) => {
|
||||
const testTimeout = cmdLineOptions["timeout"];
|
||||
const testTimeout = cmdLineOptions.timeout;
|
||||
exec("istanbul", ["cover", "node_modules/mocha/bin/_mocha", "--", "-R", "min", "-t", testTimeout.toString(), run], done, done);
|
||||
});
|
||||
|
||||
|
||||
function getDiffTool() {
|
||||
const program = process.env["DIFF"];
|
||||
const program = process.env.DIFF;
|
||||
if (!program) {
|
||||
console.error("Add the 'DIFF' environment variable to the path of the program you want to use.");
|
||||
process.exit(1);
|
||||
@@ -1019,7 +1034,7 @@ gulp.task(instrumenterJsPath, /*help*/ false, [servicesFile], () => {
|
||||
});
|
||||
|
||||
gulp.task("tsc-instrumented", "Builds an instrumented tsc.js - run with --test=[testname]", ["local", loggedIOJsPath, instrumenterJsPath, servicesFile], (done) => {
|
||||
const test = cmdLineOptions["tests"] || "iocapture";
|
||||
const test = cmdLineOptions.tests || "iocapture";
|
||||
exec(host, [instrumenterJsPath, "record", test, builtLocalCompiler], done, done);
|
||||
});
|
||||
|
||||
@@ -1088,7 +1103,7 @@ function spawnLintWorker(files: {path: string}[], callback: (failures: number) =
|
||||
|
||||
gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: --f[iles]=regex", ["build-rules"], () => {
|
||||
if (fold.isTravis()) console.log(fold.start("lint"));
|
||||
const fileMatcher = cmdLineOptions["files"];
|
||||
const fileMatcher = cmdLineOptions.files;
|
||||
const files = fileMatcher
|
||||
? `src/**/${fileMatcher}`
|
||||
: "Gulpfile.ts 'scripts/generateLocalizedDiagnosticMessages.ts' 'scripts/tslint/**/*.ts' 'src/**/*.ts' --exclude src/lib/es5.d.ts --exclude 'src/lib/*.generated.d.ts'";
|
||||
|
||||
+20
-4
@@ -154,6 +154,7 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"symbolWalker.ts",
|
||||
"languageService.ts",
|
||||
"publicApi.ts",
|
||||
"hostNewLineSupport.ts",
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
@@ -238,6 +239,23 @@ var libraryTargets = librarySourceMap.map(function (f) {
|
||||
return path.join(builtLocalDirectory, f.target);
|
||||
});
|
||||
|
||||
/**
|
||||
* .lcg file is what localization team uses to know what messages to localize.
|
||||
* The file is always generated in 'enu\diagnosticMessages.generated.json.lcg'
|
||||
*/
|
||||
var generatedLCGFile = path.join(builtLocalDirectory, "enu", "diagnosticMessages.generated.json.lcg");
|
||||
|
||||
/**
|
||||
* The localization target produces the two following transformations:
|
||||
* 1. 'src\loc\lcl\<locale>\diagnosticMessages.generated.json.lcl' => 'built\local\<locale>\diagnosticMessages.generated.json'
|
||||
* convert localized resources into a .json file the compiler can understand
|
||||
* 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg'
|
||||
* generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json
|
||||
*/
|
||||
var localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map(function (f) {
|
||||
return path.join(builtLocalDirectory, f);
|
||||
}).concat(path.dirname(generatedLCGFile));
|
||||
|
||||
// Prepends the contents of prefixFile to destinationFile
|
||||
function prependFile(prefixFile, destinationFile) {
|
||||
if (!fs.existsSync(prefixFile)) {
|
||||
@@ -443,7 +461,6 @@ compileFile(generateLocalizedDiagnosticMessagesJs,
|
||||
/*useBuiltCompiler*/ false, { noOutFile: true, types: ["node", "xml2js"] });
|
||||
|
||||
// Localize diagnostics
|
||||
var generatedLCGFile = path.join(builtLocalDirectory, "enu", "diagnosticMessages.generated.json.lcg");
|
||||
file(generatedLCGFile, [generateLocalizedDiagnosticMessagesJs, diagnosticInfoMapTs, generatedDiagnosticMessagesJSON], function () {
|
||||
var cmd = host + " " + generateLocalizedDiagnosticMessagesJs + " " + lclDirectory + " " + builtLocalDirectory + " " + generatedDiagnosticMessagesJSON;
|
||||
console.log(cmd);
|
||||
@@ -735,8 +752,7 @@ desc("Makes a new LKG out of the built js files");
|
||||
task("LKG", ["clean", "release", "local"].concat(libraryTargets), function () {
|
||||
var expectedFiles = [tscFile, servicesFile, serverFile, nodePackageFile, nodeDefinitionsFile, standaloneDefinitionsFile, tsserverLibraryFile, tsserverLibraryDefinitionFile, cancellationTokenFile, typingsInstallerFile, buildProtocolDts, watchGuardFile].
|
||||
concat(libraryTargets).
|
||||
concat(fs.readdirSync(lclDirectory).map(function (d) { return path.join(builtLocalDirectory, d) })).
|
||||
concat(path.dirname(generatedLCGFile));
|
||||
concat(localizationTargets);
|
||||
var missingFiles = expectedFiles.filter(function (f) {
|
||||
return !fs.existsSync(f);
|
||||
});
|
||||
@@ -855,7 +871,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
var inspect = process.env.inspect || process.env["inspect-brk"] || process.env.i;
|
||||
var testTimeout = process.env.timeout || defaultTestTimeout;
|
||||
var tests = process.env.test || process.env.tests || process.env.t;
|
||||
var light = process.env.light || false;
|
||||
var light = process.env.light === undefined || process.env.light !== "false";
|
||||
var stackTraceLimit = process.env.stackTraceLimit;
|
||||
var testConfigFile = 'test.config';
|
||||
if (fs.existsSync(testConfigFile)) {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
<!-- SUGGESTIONS: See https://github.com/Microsoft/TypeScript-wiki/blob/master/Writing-Good-Design-Proposals.md -->
|
||||
|
||||
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
|
||||
**TypeScript Version:** 2.6.0-dev.201xxxxx
|
||||
**TypeScript Version:** 2.7.0-dev.201xxxxx
|
||||
|
||||
**Code**
|
||||
|
||||
|
||||
Generated
+115
-77
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "typescript",
|
||||
"version": "2.6.0",
|
||||
"version": "2.7.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -42,7 +42,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/insert-module-globals": "7.0.0",
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/chai": {
|
||||
@@ -79,7 +79,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/minimatch": "3.0.1",
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/gulp": {
|
||||
@@ -88,7 +88,7 @@
|
||||
"integrity": "sha512-3UpA2pkKO40cNPe/8bxMQFWSASR9Jx67JfN9Z2Cf6ogfDMwXgEHm2XjKmuLYEtrp1IHYApOWlYMLYNgtTJgSAw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34",
|
||||
"@types/node": "8.0.46",
|
||||
"@types/orchestrator": "0.3.0",
|
||||
"@types/vinyl": "2.0.1"
|
||||
}
|
||||
@@ -99,7 +99,7 @@
|
||||
"integrity": "sha512-F14zRcKn15HC59RXRlHpcxj79WoLjkJBJBPfN0NBZOgkRCfDZYVu8rs0Y/CH4CJGUbbc/nHczD2LmepDS+ARaA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/gulp-help": {
|
||||
@@ -109,7 +109,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/gulp": "3.8.33",
|
||||
"@types/node": "8.0.34",
|
||||
"@types/node": "8.0.46",
|
||||
"@types/orchestrator": "0.3.0"
|
||||
}
|
||||
},
|
||||
@@ -119,7 +119,7 @@
|
||||
"integrity": "sha1-bqn7oVsFdr5CTpl31IlCAEZKFR4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/gulp-sourcemaps": {
|
||||
@@ -128,7 +128,7 @@
|
||||
"integrity": "sha512-kJD1byVNx+sdQlaBzZpSGeFH/4l99TXTY4XSGW+aRk27eOnVyk6VknXJpsb1Jk5E4ThKxZ8GYy6ais7MtprK1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/insert-module-globals": {
|
||||
@@ -137,7 +137,7 @@
|
||||
"integrity": "sha512-zudCJPwluh1VUDB6Gl/OQdRp+fYy3+47huJB/JMQubMS2p+sH18MCVK4WUz3FqaWLB12yh5ELxVR/+tqwlm/qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/merge2": {
|
||||
@@ -146,7 +146,7 @@
|
||||
"integrity": "sha512-Xy54xPmFQ8oAx0S3ku46i/zXE4dvfxl5M8n4p2M62IwxPau8IpobiRtL4jkrUzX6Kgeyb34BHOh0i70SDjKHeA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/minimatch": {
|
||||
@@ -167,7 +167,7 @@
|
||||
"integrity": "sha512-XA4vNO6GCBz8Smq0hqSRo4yRWMqr4FPQrWjhJt6nKskzly4/p87SfuJMFYGRyYb6jo2WNIQU2FDBsY5r1BibUA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/mocha": {
|
||||
@@ -177,9 +177,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "8.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.34.tgz",
|
||||
"integrity": "sha512-Jnmm57+nHqvJUPwUzt1CLoLzFtF2B2vgG7cWFut+a4nqTp9/L6pL0N+o0Jt3V7AQnCKMsPEqQpLFZYleBCdq3w==",
|
||||
"version": "8.0.46",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.46.tgz",
|
||||
"integrity": "sha512-rRkP4kb5JYIfAoRKaDbcdPZBcTNOgzSApyzhPN9e6rhViSJAWQGlSXIX5gc75iR02jikhpzy3usu31wMHllfFw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/orchestrator": {
|
||||
@@ -188,7 +188,7 @@
|
||||
"integrity": "sha1-v4ShaZyTMNT+ic2BJj6PwJ+zKXg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34",
|
||||
"@types/node": "8.0.46",
|
||||
"@types/q": "0.0.37"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -213,7 +213,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/gulp": "3.8.33",
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/through2": {
|
||||
@@ -222,7 +222,7 @@
|
||||
"integrity": "sha1-H/LoihAN+1sUDnu5h5HxGUQA0TE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/vinyl": {
|
||||
@@ -231,7 +231,7 @@
|
||||
"integrity": "sha512-Joudabfn2ZofU2usW04y8OLmN75u7ZQkW0MCT3AnoBf5oUBp5iQ3Pgfz9+y1RdWkzhCPZo9/wBJ7FMWW2JrY0g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"@types/xml2js": {
|
||||
@@ -240,17 +240,7 @@
|
||||
"integrity": "sha512-3gw0UqFMq7PsfMDwsawD0/L48soXfzOEh0NSAWVO99IZXnhx9LD3nOldHIpGYzZBsrS9NV2vaRFvEdWe+UweXQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.34"
|
||||
}
|
||||
},
|
||||
"JSONStream": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz",
|
||||
"integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsonparse": "1.3.1",
|
||||
"through": "2.3.8"
|
||||
"@types/node": "8.0.46"
|
||||
}
|
||||
},
|
||||
"abbrev": {
|
||||
@@ -508,9 +498,9 @@
|
||||
"integrity": "sha1-+GzWzvT1MAyOY+B6TVEvZfv/RTE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"JSONStream": "1.3.1",
|
||||
"combine-source-map": "0.7.2",
|
||||
"defined": "1.0.0",
|
||||
"JSONStream": "1.3.1",
|
||||
"through2": "2.0.3",
|
||||
"umd": "3.0.1"
|
||||
}
|
||||
@@ -531,16 +521,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"browserify": {
|
||||
"version": "14.4.0",
|
||||
"resolved": "https://registry.npmjs.org/browserify/-/browserify-14.4.0.tgz",
|
||||
"integrity": "sha1-CJo0Y69Y0OSNjNQHCz90ZU1avKk=",
|
||||
"version": "14.5.0",
|
||||
"resolved": "https://registry.npmjs.org/browserify/-/browserify-14.5.0.tgz",
|
||||
"integrity": "sha512-gKfOsNQv/toWz+60nSPfYzuwSEdzvV2WdxrVPUbPD/qui44rAkB3t3muNtmmGYHqrG56FGwX9SUEQmzNLAeS7g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"JSONStream": "1.3.1",
|
||||
"assert": "1.4.1",
|
||||
"browser-pack": "6.0.2",
|
||||
"browser-resolve": "1.11.2",
|
||||
"browserify-zlib": "0.1.4",
|
||||
"browserify-zlib": "0.2.0",
|
||||
"buffer": "5.0.8",
|
||||
"cached-path-relative": "1.0.1",
|
||||
"concat-stream": "1.5.2",
|
||||
@@ -558,9 +547,10 @@
|
||||
"https-browserify": "1.0.0",
|
||||
"inherits": "2.0.3",
|
||||
"insert-module-globals": "7.0.1",
|
||||
"JSONStream": "1.3.1",
|
||||
"labeled-stream-splicer": "2.0.0",
|
||||
"module-deps": "4.1.1",
|
||||
"os-browserify": "0.1.2",
|
||||
"os-browserify": "0.3.0",
|
||||
"parents": "1.0.1",
|
||||
"path-browserify": "0.0.0",
|
||||
"process": "0.11.10",
|
||||
@@ -583,6 +573,29 @@
|
||||
"util": "0.10.3",
|
||||
"vm-browserify": "0.0.4",
|
||||
"xtend": "4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"browserify-zlib": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
|
||||
"integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pako": "1.0.6"
|
||||
}
|
||||
},
|
||||
"os-browserify": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
|
||||
"integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
|
||||
"dev": true
|
||||
},
|
||||
"pako": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
|
||||
"integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"browserify-aes": {
|
||||
@@ -646,15 +659,6 @@
|
||||
"parse-asn1": "5.1.0"
|
||||
}
|
||||
},
|
||||
"browserify-zlib": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
|
||||
"integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pako": "0.2.9"
|
||||
}
|
||||
},
|
||||
"buffer": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.0.8.tgz",
|
||||
@@ -2658,10 +2662,10 @@
|
||||
"integrity": "sha1-wDv04BywhtW15azorQr+eInWOMM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"JSONStream": "1.3.1",
|
||||
"combine-source-map": "0.7.2",
|
||||
"concat-stream": "1.5.2",
|
||||
"is-buffer": "1.1.5",
|
||||
"JSONStream": "1.3.1",
|
||||
"lexical-scope": "1.2.0",
|
||||
"process": "0.11.10",
|
||||
"through2": "2.0.3",
|
||||
@@ -3016,6 +3020,16 @@
|
||||
"integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
|
||||
"dev": true
|
||||
},
|
||||
"JSONStream": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.1.tgz",
|
||||
"integrity": "sha1-cH92HgHa6eFvG8+TcDt4xwlmV5o=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsonparse": "1.3.1",
|
||||
"through": "2.3.8"
|
||||
}
|
||||
},
|
||||
"kew": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
|
||||
@@ -3654,7 +3668,6 @@
|
||||
"integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"JSONStream": "1.3.1",
|
||||
"browser-resolve": "1.11.2",
|
||||
"cached-path-relative": "1.0.1",
|
||||
"concat-stream": "1.5.2",
|
||||
@@ -3662,6 +3675,7 @@
|
||||
"detective": "4.5.0",
|
||||
"duplexer2": "0.1.4",
|
||||
"inherits": "2.0.3",
|
||||
"JSONStream": "1.3.1",
|
||||
"parents": "1.0.1",
|
||||
"readable-stream": "2.3.3",
|
||||
"resolve": "1.1.7",
|
||||
@@ -3901,12 +3915,6 @@
|
||||
"integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=",
|
||||
"dev": true
|
||||
},
|
||||
"os-browserify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.1.2.tgz",
|
||||
"integrity": "sha1-ScoCk+CxlZCl9d4Qx/JlphfY/lQ=",
|
||||
"dev": true
|
||||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
|
||||
@@ -3919,12 +3927,6 @@
|
||||
"integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
|
||||
"dev": true
|
||||
},
|
||||
"pako": {
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
|
||||
"integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
|
||||
"dev": true
|
||||
},
|
||||
"parents": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz",
|
||||
@@ -4160,9 +4162,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"q": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz",
|
||||
"integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE=",
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
|
||||
"integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
|
||||
"dev": true
|
||||
},
|
||||
"querystring": {
|
||||
@@ -4847,7 +4849,7 @@
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arrify": "1.0.1",
|
||||
"chalk": "2.1.0",
|
||||
"chalk": "2.2.0",
|
||||
"diff": "3.3.1",
|
||||
"make-error": "1.3.0",
|
||||
"minimist": "1.2.0",
|
||||
@@ -4868,14 +4870,14 @@
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
|
||||
"integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.0.tgz",
|
||||
"integrity": "sha512-0BMM/2hG3ZaoPfR6F+h/oWpZtsh3b/s62TjSM6MGCJWEbJDN1acqCXvyhhZsDSVFklpebUoQ5O1kKC7lOzrn9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "3.2.0",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"supports-color": "4.4.0"
|
||||
"supports-color": "4.5.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
@@ -4885,9 +4887,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
|
||||
"integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
|
||||
"integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "2.0.0"
|
||||
@@ -4929,13 +4931,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"tslint": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.7.0.tgz",
|
||||
"integrity": "sha1-wl4NDJL6EgHCvDDoROCOaCtPNVI=",
|
||||
"version": "5.8.0",
|
||||
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz",
|
||||
"integrity": "sha1-H0mtWy53x2w69N3K5VKuTjYS6xM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-code-frame": "6.26.0",
|
||||
"colors": "1.1.2",
|
||||
"builtin-modules": "1.1.1",
|
||||
"chalk": "2.2.0",
|
||||
"commander": "2.11.0",
|
||||
"diff": "3.3.1",
|
||||
"glob": "7.1.2",
|
||||
@@ -4946,6 +4949,32 @@
|
||||
"tsutils": "2.12.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
|
||||
"integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "1.9.0"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.0.tgz",
|
||||
"integrity": "sha512-0BMM/2hG3ZaoPfR6F+h/oWpZtsh3b/s62TjSM6MGCJWEbJDN1acqCXvyhhZsDSVFklpebUoQ5O1kKC7lOzrn9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "3.2.0",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"supports-color": "4.5.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
|
||||
"integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz",
|
||||
@@ -4960,6 +4989,15 @@
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
|
||||
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
|
||||
"integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5000,9 +5038,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"typescript": {
|
||||
"version": "2.6.0-dev.20171011",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.0-dev.20171011.tgz",
|
||||
"integrity": "sha512-il66U8zNRbF875Gq6cP3K/CthG7Dp9PRpu5w5mVHaPcolzJhrdLa3K2WavqqJg/7h7sPOZvsU8nYdXO61sHagg==",
|
||||
"version": "2.7.0-dev.20171020",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.0-dev.20171020.tgz",
|
||||
"integrity": "sha512-Sy1F2YVw7nj2pcMP2bE6YK5dviaY2WRJb12t27EUiW4wkD8GiaZ0sgNBdTKRcvTNFJ8KXjwnl+Ysi5+J5BlcHw==",
|
||||
"dev": true
|
||||
},
|
||||
"uglify-js": {
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
"name": "typescript",
|
||||
"author": "Microsoft Corp.",
|
||||
"homepage": "http://typescriptlang.org/",
|
||||
"version": "2.6.0",
|
||||
"version": "2.7.0",
|
||||
"license": "Apache-2.0",
|
||||
"description": "TypeScript is a language for application scale JavaScript development",
|
||||
"keywords": [
|
||||
@@ -83,7 +83,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"pretest": "jake tests",
|
||||
"test": "jake runtests-parallel",
|
||||
"test": "jake runtests-parallel light=false",
|
||||
"build": "npm run build:compiler && npm run build:tests",
|
||||
"build:compiler": "jake local",
|
||||
"build:tests": "jake tests",
|
||||
|
||||
+18
-15
@@ -51,22 +51,25 @@ class DeclarationsWalker {
|
||||
return this.processType((<any>type).typeArguments[0]);
|
||||
}
|
||||
else {
|
||||
for (const decl of s.getDeclarations()) {
|
||||
const sourceFile = decl.getSourceFile();
|
||||
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
|
||||
return;
|
||||
}
|
||||
if (decl.kind === ts.SyntaxKind.EnumDeclaration && !isStringEnum(decl as ts.EnumDeclaration)) {
|
||||
this.removedTypes.push(type);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// splice declaration in final d.ts file
|
||||
let text = decl.getFullText();
|
||||
this.text += `${text}\n`;
|
||||
// recursively pull all dependencies into result dts file
|
||||
const declarations = s.getDeclarations();
|
||||
if (declarations) {
|
||||
for (const decl of declarations) {
|
||||
const sourceFile = decl.getSourceFile();
|
||||
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
|
||||
return;
|
||||
}
|
||||
if (decl.kind === ts.SyntaxKind.EnumDeclaration && !isStringEnum(decl as ts.EnumDeclaration)) {
|
||||
this.removedTypes.push(type);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// splice declaration in final d.ts file
|
||||
let text = decl.getFullText();
|
||||
this.text += `${text}\n`;
|
||||
// recursively pull all dependencies into result dts file
|
||||
|
||||
this.visitTypeNodes(decl);
|
||||
this.visitTypeNodes(decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,16 +27,55 @@ function main(): void {
|
||||
|
||||
function visitDirectory(name: string) {
|
||||
const inputFilePath = path.join(inputPath, name, "diagnosticMessages", "diagnosticMessages.generated.json.lcl");
|
||||
const outputFilePath = path.join(outputPath, name, "diagnosticMessages.generated.json");
|
||||
|
||||
fs.readFile(inputFilePath, (err, data) => {
|
||||
handleError(err);
|
||||
xml2js.parseString(data.toString(), (err, result) => {
|
||||
handleError(err);
|
||||
writeFile(outputFilePath, xmlObjectToString(result));
|
||||
if (!result || !result.LCX || !result.LCX.$ || !result.LCX.$.TgtCul) {
|
||||
console.error("Unexpected XML file structure. Expected to find result.LCX.$.TgtCul.");
|
||||
process.exit(1);
|
||||
}
|
||||
const outputDirectoryName = getPreferedLocaleName(result.LCX.$.TgtCul);
|
||||
if (!outputDirectoryName) {
|
||||
console.error(`Invalid output locale name for '${result.LCX.$.TgtCul}'.`);
|
||||
process.exit(1);
|
||||
}
|
||||
writeFile(path.join(outputPath, outputDirectoryName, "diagnosticMessages.generated.json"), xmlObjectToString(result));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* A locale name is based on the language tagging conventions of RFC 4646 (Windows Vista
|
||||
* and later), and is represented by LOCALE_SNAME.
|
||||
* Generally, the pattern <language>-<REGION> is used. Here, language is a lowercase ISO 639
|
||||
* language code. The codes from ISO 639-1 are used when available. Otherwise, codes from
|
||||
* ISO 639-2/T are used. REGION specifies an uppercase ISO 3166-1 country/region identifier.
|
||||
* For example, the locale name for English (United States) is "en-US" and the locale name
|
||||
* for Divehi (Maldives) is "dv-MV".
|
||||
*
|
||||
* If the locale is a neutral locale (no region), the LOCALE_SNAME value follows the
|
||||
* pattern <language>. If it is a neutral locale for which the script is significant, the
|
||||
* pattern is <language>-<Script>.
|
||||
*
|
||||
* More at https://msdn.microsoft.com/en-us/library/windows/desktop/dd373814(v=vs.85).aspx
|
||||
*
|
||||
* Most of the languages we support are neutral locales, so we want to use the language name.
|
||||
* There are three exceptions, zh-CN, zh-TW and pt-BR.
|
||||
*/
|
||||
function getPreferedLocaleName(localeName: string) {
|
||||
localeName = localeName.toLowerCase();
|
||||
switch (localeName) {
|
||||
case "zh-cn":
|
||||
case "zh-tw":
|
||||
case "pt-br":
|
||||
return localeName;
|
||||
default:
|
||||
return localeName.split("-")[0];
|
||||
}
|
||||
}
|
||||
|
||||
function handleError(err: null | object) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
@@ -46,9 +85,9 @@ function main(): void {
|
||||
|
||||
function xmlObjectToString(o: any) {
|
||||
const out: any = {};
|
||||
for (const item of o["LCX"]["Item"][0]["Item"][0]["Item"]) {
|
||||
let ItemId = item["$"]["ItemId"];
|
||||
let Val = item["Str"][0]["Tgt"] ? item["Str"][0]["Tgt"][0]["Val"][0] : item["Str"][0]["Val"][0];
|
||||
for (const item of o.LCX.Item[0].Item[0].Item) {
|
||||
let ItemId = item.$.ItemId;
|
||||
let Val = item.Str[0].Tgt ? item.Str[0].Tgt[0].Val[0] : item.Str[0].Val[0];
|
||||
|
||||
if (typeof ItemId !== "string" || typeof Val !== "string") {
|
||||
console.error("Unexpected XML file structure");
|
||||
|
||||
@@ -192,7 +192,7 @@ namespace ts {
|
||||
return bindSourceFile;
|
||||
|
||||
function bindInStrictMode(file: SourceFile, opts: CompilerOptions): boolean {
|
||||
if ((opts.alwaysStrict === undefined ? opts.strict : opts.alwaysStrict) && !file.isDeclarationFile) {
|
||||
if (getStrictOptionValue(opts, "alwaysStrict") && !file.isDeclarationFile) {
|
||||
// bind in strict mode source files with alwaysStrict option
|
||||
return true;
|
||||
}
|
||||
|
||||
+134
-160
@@ -6,58 +6,38 @@ namespace ts {
|
||||
emitSkipped: boolean;
|
||||
}
|
||||
|
||||
export interface EmitOutputDetailed extends EmitOutput {
|
||||
diagnostics: Diagnostic[];
|
||||
sourceMaps: SourceMapData[];
|
||||
emittedSourceFiles: SourceFile[];
|
||||
}
|
||||
|
||||
export interface OutputFile {
|
||||
name: string;
|
||||
writeByteOrderMark: boolean;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export function getFileEmitOutput(program: Program, sourceFile: SourceFile, emitOnlyDtsFiles: boolean, isDetailed: boolean,
|
||||
cancellationToken?: CancellationToken, customTransformers?: CustomTransformers): EmitOutput | EmitOutputDetailed {
|
||||
const outputFiles: OutputFile[] = [];
|
||||
let emittedSourceFiles: SourceFile[];
|
||||
const emitResult = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
|
||||
if (!isDetailed) {
|
||||
return { outputFiles, emitSkipped: emitResult.emitSkipped };
|
||||
}
|
||||
|
||||
return {
|
||||
outputFiles,
|
||||
emitSkipped: emitResult.emitSkipped,
|
||||
diagnostics: emitResult.diagnostics,
|
||||
sourceMaps: emitResult.sourceMaps,
|
||||
emittedSourceFiles
|
||||
};
|
||||
|
||||
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, _onError: (message: string) => void, sourceFiles: SourceFile[]) {
|
||||
outputFiles.push({ name: fileName, writeByteOrderMark, text });
|
||||
if (isDetailed) {
|
||||
emittedSourceFiles = addRange(emittedSourceFiles, sourceFiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export function getFileEmitOutput(program: Program, sourceFile: SourceFile, emitOnlyDtsFiles: boolean,
|
||||
cancellationToken?: CancellationToken, customTransformers?: CustomTransformers): EmitOutput {
|
||||
const outputFiles: OutputFile[] = [];
|
||||
const emitResult = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers);
|
||||
return { outputFiles, emitSkipped: emitResult.emitSkipped };
|
||||
|
||||
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean) {
|
||||
outputFiles.push({ name: fileName, writeByteOrderMark, text });
|
||||
}
|
||||
}
|
||||
|
||||
export interface Builder {
|
||||
/**
|
||||
* Call this to feed new program
|
||||
*/
|
||||
/** Called to inform builder about new program */
|
||||
updateProgram(newProgram: Program): void;
|
||||
getFilesAffectedBy(program: Program, path: Path): string[];
|
||||
emitFile(program: Program, path: Path): EmitOutput;
|
||||
|
||||
/** Gets the files affected by the file path */
|
||||
getFilesAffectedBy(program: Program, path: Path): ReadonlyArray<SourceFile>;
|
||||
|
||||
/** Emit the changed files and clear the cache of the changed files */
|
||||
emitChangedFiles(program: Program): EmitOutputDetailed[];
|
||||
emitChangedFiles(program: Program, writeFileCallback: WriteFileCallback): ReadonlyArray<EmitResult>;
|
||||
|
||||
/** When called gets the semantic diagnostics for the program. It also caches the diagnostics and manage them */
|
||||
getSemanticDiagnostics(program: Program, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
getSemanticDiagnostics(program: Program, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic>;
|
||||
|
||||
/** Called to reset the status of the builder */
|
||||
clear(): void;
|
||||
@@ -88,20 +68,17 @@ namespace ts {
|
||||
/**
|
||||
* Gets the files affected by the script info which has updated shape from the known one
|
||||
*/
|
||||
getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile, singleFileResult: string[]): string[];
|
||||
getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile): ReadonlyArray<SourceFile>;
|
||||
}
|
||||
|
||||
interface FileInfo {
|
||||
fileName: string;
|
||||
version: string;
|
||||
signature: string;
|
||||
}
|
||||
|
||||
export interface BuilderOptions {
|
||||
getCanonicalFileName: (fileName: string) => string;
|
||||
getEmitOutput: (program: Program, sourceFile: SourceFile, emitOnlyDtsFiles: boolean, isDetailed: boolean) => EmitOutput | EmitOutputDetailed;
|
||||
computeHash: (data: string) => string;
|
||||
shouldEmitFile: (sourceFile: SourceFile) => boolean;
|
||||
}
|
||||
|
||||
export function createBuilder(options: BuilderOptions): Builder {
|
||||
@@ -109,12 +86,13 @@ namespace ts {
|
||||
const fileInfos = createMap<FileInfo>();
|
||||
const semanticDiagnosticsPerFile = createMap<ReadonlyArray<Diagnostic>>();
|
||||
/** The map has key by source file's path that has been changed */
|
||||
const changedFileNames = createMap<string>();
|
||||
const changedFilesSet = createMap<true>();
|
||||
const hasShapeChanged = createMap<true>();
|
||||
let allFilesExcludingDefaultLibraryFile: ReadonlyArray<SourceFile> | undefined;
|
||||
let emitHandler: EmitHandler;
|
||||
return {
|
||||
updateProgram,
|
||||
getFilesAffectedBy,
|
||||
emitFile,
|
||||
emitChangedFiles,
|
||||
getSemanticDiagnostics,
|
||||
clear
|
||||
@@ -128,6 +106,8 @@ namespace ts {
|
||||
fileInfos.clear();
|
||||
semanticDiagnosticsPerFile.clear();
|
||||
}
|
||||
hasShapeChanged.clear();
|
||||
allFilesExcludingDefaultLibraryFile = undefined;
|
||||
mutateMap(
|
||||
fileInfos,
|
||||
arrayToMap(program.getSourceFiles(), sourceFile => sourceFile.path),
|
||||
@@ -142,31 +122,34 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function registerChangedFile(path: Path, fileName: string) {
|
||||
changedFileNames.set(path, fileName);
|
||||
function registerChangedFile(path: Path) {
|
||||
changedFilesSet.set(path, true);
|
||||
// All changed files need to re-evaluate its semantic diagnostics
|
||||
semanticDiagnosticsPerFile.delete(path);
|
||||
}
|
||||
|
||||
function addNewFileInfo(program: Program, sourceFile: SourceFile): FileInfo {
|
||||
registerChangedFile(sourceFile.path, sourceFile.fileName);
|
||||
registerChangedFile(sourceFile.path);
|
||||
emitHandler.onAddSourceFile(program, sourceFile);
|
||||
return { fileName: sourceFile.fileName, version: sourceFile.version, signature: undefined };
|
||||
return { version: sourceFile.version, signature: undefined };
|
||||
}
|
||||
|
||||
function removeExistingFileInfo(existingFileInfo: FileInfo, path: Path) {
|
||||
registerChangedFile(path, existingFileInfo.fileName);
|
||||
function removeExistingFileInfo(_existingFileInfo: FileInfo, path: Path) {
|
||||
// Since we dont need to track removed file as changed file
|
||||
// We can just remove its diagnostics
|
||||
changedFilesSet.delete(path);
|
||||
semanticDiagnosticsPerFile.delete(path);
|
||||
emitHandler.onRemoveSourceFile(path);
|
||||
}
|
||||
|
||||
function updateExistingFileInfo(program: Program, existingInfo: FileInfo, sourceFile: SourceFile) {
|
||||
if (existingInfo.version !== sourceFile.version) {
|
||||
registerChangedFile(sourceFile.path, sourceFile.fileName);
|
||||
registerChangedFile(sourceFile.path);
|
||||
existingInfo.version = sourceFile.version;
|
||||
emitHandler.onUpdateSourceFile(program, sourceFile);
|
||||
}
|
||||
else if (emitHandler.onUpdateSourceFileWithSameVersion(program, sourceFile)) {
|
||||
registerChangedFile(sourceFile.path, sourceFile.fileName);
|
||||
registerChangedFile(sourceFile.path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,114 +165,95 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getFilesAffectedBy(program: Program, path: Path): string[] {
|
||||
function getFilesAffectedBy(program: Program, path: Path): ReadonlyArray<SourceFile> {
|
||||
ensureProgramGraph(program);
|
||||
|
||||
const sourceFile = program.getSourceFile(path);
|
||||
const singleFileResult = sourceFile && options.shouldEmitFile(sourceFile) ? [sourceFile.fileName] : [];
|
||||
const info = fileInfos.get(path);
|
||||
if (!info || !updateShapeSignature(program, sourceFile, info)) {
|
||||
return singleFileResult;
|
||||
const sourceFile = program.getSourceFileByPath(path);
|
||||
if (!sourceFile) {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
Debug.assert(!!sourceFile);
|
||||
return emitHandler.getFilesAffectedByUpdatedShape(program, sourceFile, singleFileResult);
|
||||
if (!updateShapeSignature(program, sourceFile)) {
|
||||
return [sourceFile];
|
||||
}
|
||||
return emitHandler.getFilesAffectedByUpdatedShape(program, sourceFile);
|
||||
}
|
||||
|
||||
function emitFile(program: Program, path: Path) {
|
||||
function emitChangedFiles(program: Program, writeFileCallback: WriteFileCallback): ReadonlyArray<EmitResult> {
|
||||
ensureProgramGraph(program);
|
||||
if (!fileInfos.has(path)) {
|
||||
return { outputFiles: [], emitSkipped: true };
|
||||
const compilerOptions = program.getCompilerOptions();
|
||||
|
||||
if (!changedFilesSet.size) {
|
||||
return emptyArray;
|
||||
}
|
||||
|
||||
return options.getEmitOutput(program, program.getSourceFileByPath(path), /*emitOnlyDtsFiles*/ false, /*isDetailed*/ false);
|
||||
}
|
||||
// With --out or --outFile all outputs go into single file, do it only once
|
||||
if (compilerOptions.outFile || compilerOptions.out) {
|
||||
Debug.assert(semanticDiagnosticsPerFile.size === 0);
|
||||
changedFilesSet.clear();
|
||||
return [program.emit(/*targetSourceFile*/ undefined, writeFileCallback)];
|
||||
}
|
||||
|
||||
function enumerateChangedFilesSet(
|
||||
program: Program,
|
||||
onChangedFile: (fileName: string, path: Path) => void,
|
||||
onAffectedFile: (fileName: string, sourceFile: SourceFile) => void
|
||||
) {
|
||||
changedFileNames.forEach((fileName, path) => {
|
||||
onChangedFile(fileName, path as Path);
|
||||
const affectedFiles = getFilesAffectedBy(program, path as Path);
|
||||
for (const file of affectedFiles) {
|
||||
onAffectedFile(file, program.getSourceFile(file));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function enumerateChangedFilesEmitOutput(
|
||||
program: Program,
|
||||
emitOnlyDtsFiles: boolean,
|
||||
onChangedFile: (fileName: string, path: Path) => void,
|
||||
onEmitOutput: (emitOutput: EmitOutputDetailed, sourceFile: SourceFile) => void
|
||||
) {
|
||||
const seenFiles = createMap<true>();
|
||||
enumerateChangedFilesSet(program, onChangedFile, (fileName, sourceFile) => {
|
||||
if (!seenFiles.has(fileName)) {
|
||||
seenFiles.set(fileName, true);
|
||||
if (sourceFile) {
|
||||
// Any affected file shouldnt have the cached diagnostics
|
||||
semanticDiagnosticsPerFile.delete(sourceFile.path);
|
||||
let result: EmitResult[] | undefined;
|
||||
changedFilesSet.forEach((_true, path) => {
|
||||
// Get the affected Files by this program
|
||||
const affectedFiles = getFilesAffectedBy(program, path as Path);
|
||||
affectedFiles.forEach(affectedFile => {
|
||||
// Affected files shouldnt have cached diagnostics
|
||||
semanticDiagnosticsPerFile.delete(affectedFile.path);
|
||||
|
||||
const emitOutput = options.getEmitOutput(program, sourceFile, emitOnlyDtsFiles, /*isDetailed*/ true) as EmitOutputDetailed;
|
||||
onEmitOutput(emitOutput, sourceFile);
|
||||
if (!seenFiles.has(affectedFile.path)) {
|
||||
seenFiles.set(affectedFile.path, true);
|
||||
|
||||
// mark all the emitted source files as seen
|
||||
if (emitOutput.emittedSourceFiles) {
|
||||
for (const file of emitOutput.emittedSourceFiles) {
|
||||
seenFiles.set(file.fileName, true);
|
||||
}
|
||||
}
|
||||
// Emit the affected file
|
||||
(result || (result = [])).push(program.emit(affectedFile, writeFileCallback));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
changedFilesSet.clear();
|
||||
return result || emptyArray;
|
||||
}
|
||||
|
||||
function emitChangedFiles(program: Program): EmitOutputDetailed[] {
|
||||
function getSemanticDiagnostics(program: Program, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
ensureProgramGraph(program);
|
||||
const result: EmitOutputDetailed[] = [];
|
||||
enumerateChangedFilesEmitOutput(program, /*emitOnlyDtsFiles*/ false,
|
||||
/*onChangedFile*/ noop, emitOutput => result.push(emitOutput));
|
||||
changedFileNames.clear();
|
||||
return result;
|
||||
}
|
||||
Debug.assert(changedFilesSet.size === 0);
|
||||
|
||||
function getSemanticDiagnostics(program: Program, cancellationToken?: CancellationToken): Diagnostic[] {
|
||||
ensureProgramGraph(program);
|
||||
|
||||
// Ensure that changed files have cleared their respective
|
||||
enumerateChangedFilesSet(program, /*onChangedFile*/ noop, (_affectedFileName, sourceFile) => {
|
||||
if (sourceFile) {
|
||||
semanticDiagnosticsPerFile.delete(sourceFile.path);
|
||||
}
|
||||
});
|
||||
const compilerOptions = program.getCompilerOptions();
|
||||
if (compilerOptions.outFile || compilerOptions.out) {
|
||||
Debug.assert(semanticDiagnosticsPerFile.size === 0);
|
||||
// We dont need to cache the diagnostics just return them from program
|
||||
return program.getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken);
|
||||
}
|
||||
|
||||
let diagnostics: Diagnostic[];
|
||||
for (const sourceFile of program.getSourceFiles()) {
|
||||
const path = sourceFile.path;
|
||||
const cachedDiagnostics = semanticDiagnosticsPerFile.get(path);
|
||||
// Report the semantic diagnostics from the cache if we already have those diagnostics present
|
||||
if (cachedDiagnostics) {
|
||||
diagnostics = addRange(diagnostics, cachedDiagnostics);
|
||||
}
|
||||
else {
|
||||
// Diagnostics werent cached, get them from program, and cache the result
|
||||
const cachedDiagnostics = program.getSemanticDiagnostics(sourceFile, cancellationToken);
|
||||
semanticDiagnosticsPerFile.set(path, cachedDiagnostics);
|
||||
diagnostics = addRange(diagnostics, cachedDiagnostics);
|
||||
}
|
||||
diagnostics = addRange(diagnostics, getSemanticDiagnosticsOfFile(program, sourceFile, cancellationToken));
|
||||
}
|
||||
return diagnostics || emptyArray;
|
||||
}
|
||||
|
||||
function getSemanticDiagnosticsOfFile(program: Program, sourceFile: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
const path = sourceFile.path;
|
||||
const cachedDiagnostics = semanticDiagnosticsPerFile.get(path);
|
||||
// Report the semantic diagnostics from the cache if we already have those diagnostics present
|
||||
if (cachedDiagnostics) {
|
||||
return cachedDiagnostics;
|
||||
}
|
||||
|
||||
// Diagnostics werent cached, get them from program, and cache the result
|
||||
const diagnostics = program.getSemanticDiagnostics(sourceFile, cancellationToken);
|
||||
semanticDiagnosticsPerFile.set(path, diagnostics);
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
function clear() {
|
||||
isModuleEmit = undefined;
|
||||
emitHandler = undefined;
|
||||
fileInfos.clear();
|
||||
semanticDiagnosticsPerFile.clear();
|
||||
changedFileNames.clear();
|
||||
changedFilesSet.clear();
|
||||
hasShapeChanged.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -310,15 +274,26 @@ namespace ts {
|
||||
/**
|
||||
* @return {boolean} indicates if the shape signature has changed since last update.
|
||||
*/
|
||||
function updateShapeSignature(program: Program, sourceFile: SourceFile, info: FileInfo) {
|
||||
function updateShapeSignature(program: Program, sourceFile: SourceFile) {
|
||||
Debug.assert(!!sourceFile);
|
||||
|
||||
// If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
|
||||
if (hasShapeChanged.has(sourceFile.path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hasShapeChanged.set(sourceFile.path, true);
|
||||
const info = fileInfos.get(sourceFile.path);
|
||||
Debug.assert(!!info);
|
||||
|
||||
const prevSignature = info.signature;
|
||||
let latestSignature: string;
|
||||
if (sourceFile.isDeclarationFile) {
|
||||
latestSignature = options.computeHash(sourceFile.text);
|
||||
latestSignature = sourceFile.version;
|
||||
info.signature = latestSignature;
|
||||
}
|
||||
else {
|
||||
const emitOutput = options.getEmitOutput(program, sourceFile, /*emitOnlyDtsFiles*/ true, /*isDetailed*/ false);
|
||||
const emitOutput = getFileEmitOutput(program, sourceFile, /*emitOnlyDtsFiles*/ true);
|
||||
if (emitOutput.outputFiles && emitOutput.outputFiles.length > 0) {
|
||||
latestSignature = options.computeHash(emitOutput.outputFiles[0].text);
|
||||
info.signature = latestSignature;
|
||||
@@ -386,24 +361,27 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the emittable files from the program.
|
||||
* @param firstSourceFile This one will be emitted first. See https://github.com/Microsoft/TypeScript/issues/16888
|
||||
* Gets all files of the program excluding the default library file
|
||||
*/
|
||||
function getAllEmittableFiles(program: Program, firstSourceFile: SourceFile): string[] {
|
||||
const defaultLibraryFileName = getDefaultLibFileName(program.getCompilerOptions());
|
||||
const sourceFiles = program.getSourceFiles();
|
||||
const result: string[] = [];
|
||||
add(firstSourceFile);
|
||||
for (const sourceFile of sourceFiles) {
|
||||
function getAllFilesExcludingDefaultLibraryFile(program: Program, firstSourceFile: SourceFile): ReadonlyArray<SourceFile> {
|
||||
// Use cached result
|
||||
if (allFilesExcludingDefaultLibraryFile) {
|
||||
return allFilesExcludingDefaultLibraryFile;
|
||||
}
|
||||
|
||||
let result: SourceFile[];
|
||||
addSourceFile(firstSourceFile);
|
||||
for (const sourceFile of program.getSourceFiles()) {
|
||||
if (sourceFile !== firstSourceFile) {
|
||||
add(sourceFile);
|
||||
addSourceFile(sourceFile);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
allFilesExcludingDefaultLibraryFile = result || emptyArray;
|
||||
return allFilesExcludingDefaultLibraryFile;
|
||||
|
||||
function add(sourceFile: SourceFile): void {
|
||||
if (getBaseFileName(sourceFile.fileName) !== defaultLibraryFileName && options.shouldEmitFile(sourceFile)) {
|
||||
result.push(sourceFile.fileName);
|
||||
function addSourceFile(sourceFile: SourceFile) {
|
||||
if (!program.isSourceFileDefaultLibrary(sourceFile)) {
|
||||
(result || (result = [])).push(sourceFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -417,14 +395,14 @@ namespace ts {
|
||||
getFilesAffectedByUpdatedShape
|
||||
};
|
||||
|
||||
function getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile, singleFileResult: string[]): string[] {
|
||||
function getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile): ReadonlyArray<SourceFile> {
|
||||
const options = program.getCompilerOptions();
|
||||
// If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project,
|
||||
// so returning the file itself is good enough.
|
||||
if (options && (options.out || options.outFile)) {
|
||||
return singleFileResult;
|
||||
return [sourceFile];
|
||||
}
|
||||
return getAllEmittableFiles(program, sourceFile);
|
||||
return getAllFilesExcludingDefaultLibraryFile(program, sourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,7 +459,7 @@ namespace ts {
|
||||
// add files referencing the removedFilePath, as changed files too
|
||||
const referencedByInfo = fileInfos.get(filePath);
|
||||
if (referencedByInfo) {
|
||||
registerChangedFile(filePath as Path, referencedByInfo.fileName);
|
||||
registerChangedFile(filePath as Path);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -495,37 +473,33 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile, singleFileResult: string[]): string[] {
|
||||
function getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile): ReadonlyArray<SourceFile> {
|
||||
if (!isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile)) {
|
||||
return getAllEmittableFiles(program, sourceFile);
|
||||
return getAllFilesExcludingDefaultLibraryFile(program, sourceFile);
|
||||
}
|
||||
|
||||
const compilerOptions = program.getCompilerOptions();
|
||||
if (compilerOptions && (compilerOptions.isolatedModules || compilerOptions.out || compilerOptions.outFile)) {
|
||||
return singleFileResult;
|
||||
return [sourceFile];
|
||||
}
|
||||
|
||||
// Now we need to if each file in the referencedBy list has a shape change as well.
|
||||
// Because if so, its own referencedBy files need to be saved as well to make the
|
||||
// emitting result consistent with files on disk.
|
||||
|
||||
const seenFileNamesMap = createMap<string>();
|
||||
const setSeenFileName = (path: Path, sourceFile: SourceFile) => {
|
||||
seenFileNamesMap.set(path, sourceFile && options.shouldEmitFile(sourceFile) ? sourceFile.fileName : undefined);
|
||||
};
|
||||
const seenFileNamesMap = createMap<SourceFile>();
|
||||
|
||||
// Start with the paths this file was referenced by
|
||||
const path = sourceFile.path;
|
||||
setSeenFileName(path, sourceFile);
|
||||
seenFileNamesMap.set(path, sourceFile);
|
||||
const queue = getReferencedByPaths(path);
|
||||
while (queue.length > 0) {
|
||||
const currentPath = queue.pop();
|
||||
if (!seenFileNamesMap.has(currentPath)) {
|
||||
const currentSourceFile = program.getSourceFileByPath(currentPath);
|
||||
if (currentSourceFile && updateShapeSignature(program, currentSourceFile, fileInfos.get(currentPath))) {
|
||||
seenFileNamesMap.set(currentPath, currentSourceFile);
|
||||
if (currentSourceFile && updateShapeSignature(program, currentSourceFile)) {
|
||||
queue.push(...getReferencedByPaths(currentPath));
|
||||
}
|
||||
setSeenFileName(currentPath, currentSourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+280
-135
@@ -65,10 +65,10 @@ namespace ts {
|
||||
const modulekind = getEmitModuleKind(compilerOptions);
|
||||
const noUnusedIdentifiers = !!compilerOptions.noUnusedLocals || !!compilerOptions.noUnusedParameters;
|
||||
const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System;
|
||||
const strictNullChecks = compilerOptions.strictNullChecks === undefined ? compilerOptions.strict : compilerOptions.strictNullChecks;
|
||||
const strictFunctionTypes = compilerOptions.strictFunctionTypes === undefined ? compilerOptions.strict : compilerOptions.strictFunctionTypes;
|
||||
const noImplicitAny = compilerOptions.noImplicitAny === undefined ? compilerOptions.strict : compilerOptions.noImplicitAny;
|
||||
const noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis;
|
||||
const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
|
||||
const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes");
|
||||
const noImplicitAny = getStrictOptionValue(compilerOptions, "noImplicitAny");
|
||||
const noImplicitThis = getStrictOptionValue(compilerOptions, "noImplicitThis");
|
||||
|
||||
const emitResolver = createResolver();
|
||||
const nodeBuilder = createNodeBuilder();
|
||||
@@ -260,6 +260,7 @@ namespace ts {
|
||||
const literalTypes = createMap<LiteralType>();
|
||||
const indexedAccessTypes = createMap<IndexedAccessType>();
|
||||
const evolvingArrayTypes: EvolvingArrayType[] = [];
|
||||
const undefinedProperties = createMap<Symbol>() as UnderscoreEscapedMap<Symbol>;
|
||||
|
||||
const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String);
|
||||
const resolvingSymbol = createSymbol(0, InternalSymbolName.Resolving);
|
||||
@@ -314,6 +315,7 @@ namespace ts {
|
||||
const jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
|
||||
|
||||
const globals = createSymbolTable();
|
||||
let ambientModulesCache: Symbol[] | undefined;
|
||||
/**
|
||||
* List of every ambient module with a "*" wildcard.
|
||||
* Unlike other ambient modules, these can't be stored in `globals` because symbol tables only deal with exact matches.
|
||||
@@ -559,10 +561,10 @@ namespace ts {
|
||||
return emitResolver;
|
||||
}
|
||||
|
||||
function error(location: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): void {
|
||||
function error(location: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void {
|
||||
const diagnostic = location
|
||||
? createDiagnosticForNode(location, message, arg0, arg1, arg2)
|
||||
: createCompilerDiagnostic(message, arg0, arg1, arg2);
|
||||
? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3)
|
||||
: createCompilerDiagnostic(message, arg0, arg1, arg2, arg3);
|
||||
diagnostics.add(diagnostic);
|
||||
}
|
||||
|
||||
@@ -1366,7 +1368,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (meaning & (SymbolFlags.Type & ~SymbolFlags.NamespaceModule & ~SymbolFlags.Value)) {
|
||||
const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.NamespaceModule & ~SymbolFlags.Type, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
|
||||
const symbol = resolveSymbol(resolveName(errorLocation, name, (SymbolFlags.ValueModule | SymbolFlags.NamespaceModule) & ~SymbolFlags.Type, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined, /*isUse*/ false));
|
||||
if (symbol) {
|
||||
error(errorLocation, Diagnostics.Cannot_use_namespace_0_as_a_type, unescapeLeadingUnderscores(name));
|
||||
return true;
|
||||
@@ -2442,18 +2444,21 @@ namespace ts {
|
||||
function createNodeBuilder() {
|
||||
return {
|
||||
typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => {
|
||||
Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0);
|
||||
const context = createNodeBuilderContext(enclosingDeclaration, flags);
|
||||
const resultingNode = typeToTypeNodeHelper(type, context);
|
||||
const result = context.encounteredError ? undefined : resultingNode;
|
||||
return result;
|
||||
},
|
||||
indexInfoToIndexSignatureDeclaration: (indexInfo: IndexInfo, kind: IndexKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => {
|
||||
Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0);
|
||||
const context = createNodeBuilderContext(enclosingDeclaration, flags);
|
||||
const resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context);
|
||||
const result = context.encounteredError ? undefined : resultingNode;
|
||||
return result;
|
||||
},
|
||||
signatureToSignatureDeclaration: (signature: Signature, kind: SyntaxKind, enclosingDeclaration?: Node, flags?: NodeBuilderFlags) => {
|
||||
Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0);
|
||||
const context = createNodeBuilderContext(enclosingDeclaration, flags);
|
||||
const resultingNode = signatureToSignatureDeclarationHelper(signature, kind, context);
|
||||
const result = context.encounteredError ? undefined : resultingNode;
|
||||
@@ -2494,7 +2499,7 @@ namespace ts {
|
||||
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, getNameOfSymbol(type.symbol, context));
|
||||
const enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type ? parentName : createQualifiedName(parentName, symbolName(type.symbol));
|
||||
return createTypeReferenceNode(enumLiteralName, /*typeArguments*/ undefined);
|
||||
}
|
||||
if (type.flags & TypeFlags.EnumLike) {
|
||||
@@ -3014,8 +3019,7 @@ namespace ts {
|
||||
typeParameterNodes = mapToTypeNodes(typeParameters, context);
|
||||
}
|
||||
|
||||
const symbolName = getNameOfSymbol(symbol, context);
|
||||
const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
|
||||
const identifier = setEmitFlags(createIdentifier(getNameOfSymbolAsWritten(symbol, context), typeParameterNodes), EmitFlags.NoAsciiEscaping);
|
||||
|
||||
return index > 0 ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier;
|
||||
}
|
||||
@@ -3127,7 +3131,14 @@ namespace ts {
|
||||
symbolStack: Symbol[] | undefined;
|
||||
}
|
||||
|
||||
function getNameOfSymbol(symbol: Symbol, context?: NodeBuilderContext): string {
|
||||
/**
|
||||
* Gets a human-readable name for a symbol.
|
||||
* Should *not* be used for the right-hand side of a `.` -- use `symbolName(symbol)` for that instead.
|
||||
*
|
||||
* Unlike `symbolName(symbol)`, this will include quotes if the name is from a string literal.
|
||||
* It will also use a representation of a number as written instead of a decimal form, e.g. `0o11` instead of `9`.
|
||||
*/
|
||||
function getNameOfSymbolAsWritten(symbol: Symbol, context?: NodeBuilderContext): string {
|
||||
if (symbol.declarations && symbol.declarations.length) {
|
||||
const declaration = symbol.declarations[0];
|
||||
const name = getNameOfDeclaration(declaration);
|
||||
@@ -3164,7 +3175,7 @@ namespace ts {
|
||||
* for the name of the symbol if it is available to match how the user wrote the name.
|
||||
*/
|
||||
function appendSymbolNameOnly(symbol: Symbol, writer: SymbolWriter): void {
|
||||
writer.writeSymbol(getNameOfSymbol(symbol), symbol);
|
||||
writer.writeSymbol(getNameOfSymbolAsWritten(symbol), symbol);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3173,7 +3184,7 @@ namespace ts {
|
||||
* ensuring that any names written with literals use element accesses.
|
||||
*/
|
||||
function appendPropertyOrElementAccessForSymbol(symbol: Symbol, writer: SymbolWriter): void {
|
||||
const symbolName = getNameOfSymbol(symbol);
|
||||
const symbolName = symbol.escapedName === "default" ? "default" : getNameOfSymbolAsWritten(symbol);
|
||||
const firstChar = symbolName.charCodeAt(0);
|
||||
const needsElementAccess = !isIdentifierStart(firstChar, languageVersion);
|
||||
|
||||
@@ -4416,8 +4427,7 @@ namespace ts {
|
||||
jsDocType = declarationType;
|
||||
}
|
||||
else if (jsDocType !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(jsDocType, declarationType)) {
|
||||
const name = getNameOfDeclaration(declaration);
|
||||
error(name, Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, declarationNameToString(name), typeToString(jsDocType), typeToString(declarationType));
|
||||
errorNextVariableDeclarationMustHaveSameType(symbol.valueDeclaration, jsDocType, declaration, declarationType);
|
||||
}
|
||||
}
|
||||
else if (!jsDocType) {
|
||||
@@ -6420,11 +6430,11 @@ namespace ts {
|
||||
* @param typeParameters The requested type parameters.
|
||||
* @param minTypeArgumentCount The minimum number of required type arguments.
|
||||
*/
|
||||
function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScript: boolean) {
|
||||
function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean) {
|
||||
const numTypeParameters = length(typeParameters);
|
||||
if (numTypeParameters) {
|
||||
const numTypeArguments = length(typeArguments);
|
||||
if ((isJavaScript || numTypeArguments >= minTypeArgumentCount) && numTypeArguments <= numTypeParameters) {
|
||||
if ((isJavaScriptImplicitAny || numTypeArguments >= minTypeArgumentCount) && numTypeArguments <= numTypeParameters) {
|
||||
if (!typeArguments) {
|
||||
typeArguments = [];
|
||||
}
|
||||
@@ -6433,12 +6443,12 @@ namespace ts {
|
||||
// If a type parameter does not have a default type, or if the default type
|
||||
// is a forward reference, the empty object type is used.
|
||||
for (let i = numTypeArguments; i < numTypeParameters; i++) {
|
||||
typeArguments[i] = getDefaultTypeArgumentType(isJavaScript);
|
||||
typeArguments[i] = getDefaultTypeArgumentType(isJavaScriptImplicitAny);
|
||||
}
|
||||
for (let i = numTypeArguments; i < numTypeParameters; i++) {
|
||||
const mapper = createTypeMapper(typeParameters, typeArguments);
|
||||
const defaultType = getDefaultFromTypeParameter(typeParameters[i]);
|
||||
typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScript);
|
||||
typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScriptImplicitAny);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6566,7 +6576,7 @@ namespace ts {
|
||||
if (!node) return false;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return (<Identifier>node).escapedText === "arguments" && isPartOfExpression(node);
|
||||
return (<Identifier>node).escapedText === "arguments" && isExpressionNode(node);
|
||||
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
@@ -6726,6 +6736,16 @@ namespace ts {
|
||||
isInJavaScriptFile(signature.declaration));
|
||||
}
|
||||
|
||||
function getBaseSignature(signature: Signature) {
|
||||
const typeParameters = signature.typeParameters;
|
||||
if (typeParameters) {
|
||||
const typeEraser = createTypeEraser(typeParameters);
|
||||
const baseConstraints = map(typeParameters, tp => instantiateType(getBaseConstraintOfType(tp), typeEraser) || emptyObjectType);
|
||||
return instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ true);
|
||||
}
|
||||
return signature;
|
||||
}
|
||||
|
||||
function getOrCreateTypeFromSignature(signature: Signature): ObjectType {
|
||||
// There are two ways to declare a construct signature, one is by declaring a class constructor
|
||||
// using the constructor keyword, and the other is declaring a bare construct signature in an
|
||||
@@ -6874,21 +6894,25 @@ namespace ts {
|
||||
if (typeParameters) {
|
||||
const numTypeArguments = length(node.typeArguments);
|
||||
const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
|
||||
const isJavascript = isInJavaScriptFile(node);
|
||||
if (!isJavascript && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) {
|
||||
error(node,
|
||||
minTypeArgumentCount === typeParameters.length
|
||||
? Diagnostics.Generic_type_0_requires_1_type_argument_s
|
||||
: Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments,
|
||||
typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType),
|
||||
minTypeArgumentCount,
|
||||
typeParameters.length);
|
||||
const isJs = isInJavaScriptFile(node);
|
||||
const isJsImplicitAny = !noImplicitAny && isJs;
|
||||
if (!isJsImplicitAny && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) {
|
||||
const missingAugmentsTag = isJs && node.parent.kind !== SyntaxKind.JSDocAugmentsTag;
|
||||
const diag = minTypeArgumentCount === typeParameters.length
|
||||
? missingAugmentsTag
|
||||
? Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag
|
||||
: Diagnostics.Generic_type_0_requires_1_type_argument_s
|
||||
: missingAugmentsTag
|
||||
? Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag
|
||||
: Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments;
|
||||
const typeStr = typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType);
|
||||
error(node, diag, typeStr, minTypeArgumentCount, typeParameters.length);
|
||||
return unknownType;
|
||||
}
|
||||
// In a type reference, the outer type parameters of the referenced class or interface are automatically
|
||||
// supplied as type arguments and the type reference only specifies arguments for the local type parameters
|
||||
// of the class or interface.
|
||||
const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs, typeParameters, minTypeArgumentCount, isJavascript));
|
||||
const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs, typeParameters, minTypeArgumentCount, isJsImplicitAny));
|
||||
return createTypeReference(<GenericType>type, typeArguments);
|
||||
}
|
||||
if (node.typeArguments) {
|
||||
@@ -7029,13 +7053,11 @@ namespace ts {
|
||||
function getIntendedTypeFromJSDocTypeReference(node: TypeReferenceNode): Type {
|
||||
if (isIdentifier(node.typeName)) {
|
||||
if (node.typeName.escapedText === "Object") {
|
||||
if (node.typeArguments && node.typeArguments.length === 2) {
|
||||
if (isJSDocIndexSignature(node)) {
|
||||
const indexed = getTypeFromTypeNode(node.typeArguments[0]);
|
||||
const target = getTypeFromTypeNode(node.typeArguments[1]);
|
||||
const index = createIndexInfo(target, /*isReadonly*/ false);
|
||||
if (indexed === stringType || indexed === numberType) {
|
||||
return createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, indexed === stringType && index, indexed === numberType && index);
|
||||
}
|
||||
return createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, indexed === stringType && index, indexed === numberType && index);
|
||||
}
|
||||
return anyType;
|
||||
}
|
||||
@@ -7971,8 +7993,8 @@ namespace ts {
|
||||
|
||||
const spread = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
|
||||
spread.flags |= propagatedFlags;
|
||||
spread.flags |= TypeFlags.FreshLiteral;
|
||||
(spread as ObjectType).objectFlags |= ObjectFlags.ObjectLiteral;
|
||||
spread.flags |= TypeFlags.FreshLiteral | TypeFlags.ContainsObjectLiteral;
|
||||
(spread as ObjectType).objectFlags |= (ObjectFlags.ObjectLiteral | ObjectFlags.ContainsSpread);
|
||||
spread.symbol = symbol;
|
||||
return spread;
|
||||
}
|
||||
@@ -9014,7 +9036,7 @@ namespace ts {
|
||||
|
||||
if (isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;
|
||||
|
||||
if (getObjectFlags(source) & ObjectFlags.ObjectLiteral && source.flags & TypeFlags.FreshLiteral) {
|
||||
if (isObjectLiteralType(source) && source.flags & TypeFlags.FreshLiteral) {
|
||||
if (hasExcessProperties(<FreshObjectLiteralType>source, target, reportErrors)) {
|
||||
if (reportErrors) {
|
||||
reportRelationError(headMessage, source, target);
|
||||
@@ -9441,32 +9463,30 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isGenericMappedType(target) && !isGenericMappedType(source) && getConstraintTypeFromMappedType(<MappedType>target) === getIndexType(source)) {
|
||||
// A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X.
|
||||
const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(<MappedType>target));
|
||||
const templateType = getTemplateTypeFromMappedType(<MappedType>target);
|
||||
if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (source.flags & TypeFlags.TypeParameter) {
|
||||
// A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X.
|
||||
if (getObjectFlags(target) & ObjectFlags.Mapped && getConstraintTypeFromMappedType(<MappedType>target) === getIndexType(source)) {
|
||||
const indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(<MappedType>target));
|
||||
const templateType = getTemplateTypeFromMappedType(<MappedType>target);
|
||||
if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) {
|
||||
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
|
||||
// A type parameter with no constraint is not related to the non-primitive object type.
|
||||
if (constraint || !(target.flags & TypeFlags.NonPrimitive)) {
|
||||
if (!constraint || constraint.flags & TypeFlags.Any) {
|
||||
constraint = emptyObjectType;
|
||||
}
|
||||
// Report constraint errors only if the constraint is not the empty object type
|
||||
const reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
|
||||
if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
let constraint = getConstraintOfTypeParameter(<TypeParameter>source);
|
||||
// A type parameter with no constraint is not related to the non-primitive object type.
|
||||
if (constraint || !(target.flags & TypeFlags.NonPrimitive)) {
|
||||
if (!constraint || constraint.flags & TypeFlags.Any) {
|
||||
constraint = emptyObjectType;
|
||||
}
|
||||
// Report constraint errors only if the constraint is not the empty object type
|
||||
const reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
|
||||
if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (source.flags & TypeFlags.IndexedAccess) {
|
||||
// A type S[K] is related to a type T if A[K] is related to T, where K is string-like and
|
||||
@@ -9584,7 +9604,7 @@ namespace ts {
|
||||
if (relation === identityRelation) {
|
||||
return propertiesIdenticalTo(source, target);
|
||||
}
|
||||
const requireOptionalProperties = relation === subtypeRelation && !(getObjectFlags(source) & ObjectFlags.ObjectLiteral);
|
||||
const requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source);
|
||||
const unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties);
|
||||
if (unmatchedProperty) {
|
||||
if (reportErrors) {
|
||||
@@ -9592,6 +9612,19 @@ namespace ts {
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
if (isObjectLiteralType(target)) {
|
||||
for (const sourceProp of getPropertiesOfType(source)) {
|
||||
if (!getPropertyOfObjectType(target, sourceProp.escapedName)) {
|
||||
const sourceType = getTypeOfSymbol(sourceProp);
|
||||
if (!(sourceType === undefinedType || sourceType === undefinedWideningType)) {
|
||||
if (reportErrors) {
|
||||
reportError(Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(sourceProp), typeToString(target));
|
||||
}
|
||||
return Ternary.False;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let result = Ternary.True;
|
||||
const properties = getPropertiesOfObjectType(target);
|
||||
for (const targetProp of properties) {
|
||||
@@ -10413,7 +10446,7 @@ namespace ts {
|
||||
* Leave signatures alone since they are not subject to the check.
|
||||
*/
|
||||
function getRegularTypeOfObjectLiteral(type: Type): Type {
|
||||
if (!(getObjectFlags(type) & ObjectFlags.ObjectLiteral && type.flags & TypeFlags.FreshLiteral)) {
|
||||
if (!(isObjectLiteralType(type) && type.flags & TypeFlags.FreshLiteral)) {
|
||||
return type;
|
||||
}
|
||||
const regularType = (<FreshObjectLiteralType>type).regularType;
|
||||
@@ -10435,18 +10468,74 @@ namespace ts {
|
||||
return regularNew;
|
||||
}
|
||||
|
||||
function getWidenedProperty(prop: Symbol): Symbol {
|
||||
function createWideningContext(parent: WideningContext, propertyName: __String, siblings: Type[]): WideningContext {
|
||||
return { parent, propertyName, siblings, resolvedPropertyNames: undefined };
|
||||
}
|
||||
|
||||
function getSiblingsOfContext(context: WideningContext): Type[] {
|
||||
if (!context.siblings) {
|
||||
const siblings: Type[] = [];
|
||||
for (const type of getSiblingsOfContext(context.parent)) {
|
||||
if (isObjectLiteralType(type)) {
|
||||
const prop = getPropertyOfObjectType(type, context.propertyName);
|
||||
if (prop) {
|
||||
forEachType(getTypeOfSymbol(prop), t => {
|
||||
siblings.push(t);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
context.siblings = siblings;
|
||||
}
|
||||
return context.siblings;
|
||||
}
|
||||
|
||||
function getPropertyNamesOfContext(context: WideningContext): __String[] {
|
||||
if (!context.resolvedPropertyNames) {
|
||||
const names = createMap<boolean>() as UnderscoreEscapedMap<boolean>;
|
||||
for (const t of getSiblingsOfContext(context)) {
|
||||
if (isObjectLiteralType(t) && !(getObjectFlags(t) & ObjectFlags.ContainsSpread)) {
|
||||
for (const prop of getPropertiesOfType(t)) {
|
||||
names.set(prop.escapedName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.resolvedPropertyNames = arrayFrom(names.keys());
|
||||
}
|
||||
return context.resolvedPropertyNames;
|
||||
}
|
||||
|
||||
function getWidenedProperty(prop: Symbol, context: WideningContext): Symbol {
|
||||
const original = getTypeOfSymbol(prop);
|
||||
const widened = getWidenedType(original);
|
||||
const propContext = context && createWideningContext(context, prop.escapedName, /*siblings*/ undefined);
|
||||
const widened = getWidenedTypeWithContext(original, propContext);
|
||||
return widened === original ? prop : createSymbolWithType(prop, widened);
|
||||
}
|
||||
|
||||
function getWidenedTypeOfObjectLiteral(type: Type): Type {
|
||||
function getUndefinedProperty(name: __String) {
|
||||
const cached = undefinedProperties.get(name);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const result = createSymbol(SymbolFlags.Property | SymbolFlags.Optional, name);
|
||||
result.type = undefinedType;
|
||||
undefinedProperties.set(name, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function getWidenedTypeOfObjectLiteral(type: Type, context: WideningContext): Type {
|
||||
const members = createSymbolTable();
|
||||
for (const prop of getPropertiesOfObjectType(type)) {
|
||||
// Since get accessors already widen their return value there is no need to
|
||||
// widen accessor based properties here.
|
||||
members.set(prop.escapedName, prop.flags & SymbolFlags.Property ? getWidenedProperty(prop) : prop);
|
||||
members.set(prop.escapedName, prop.flags & SymbolFlags.Property ? getWidenedProperty(prop, context) : prop);
|
||||
}
|
||||
if (context) {
|
||||
for (const name of getPropertyNamesOfContext(context)) {
|
||||
if (!members.has(name)) {
|
||||
members.set(name, getUndefinedProperty(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
const stringIndexInfo = getIndexInfoOfType(type, IndexKind.String);
|
||||
const numberIndexInfo = getIndexInfoOfType(type, IndexKind.Number);
|
||||
@@ -10455,20 +10544,25 @@ namespace ts {
|
||||
numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly));
|
||||
}
|
||||
|
||||
function getWidenedConstituentType(type: Type): Type {
|
||||
return type.flags & TypeFlags.Nullable ? type : getWidenedType(type);
|
||||
function getWidenedType(type: Type) {
|
||||
return getWidenedTypeWithContext(type, /*context*/ undefined);
|
||||
}
|
||||
|
||||
function getWidenedType(type: Type): Type {
|
||||
function getWidenedTypeWithContext(type: Type, context: WideningContext): Type {
|
||||
if (type.flags & TypeFlags.RequiresWidening) {
|
||||
if (type.flags & TypeFlags.Nullable) {
|
||||
return anyType;
|
||||
}
|
||||
if (getObjectFlags(type) & ObjectFlags.ObjectLiteral) {
|
||||
return getWidenedTypeOfObjectLiteral(type);
|
||||
if (isObjectLiteralType(type)) {
|
||||
return getWidenedTypeOfObjectLiteral(type, context);
|
||||
}
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
return getUnionType(sameMap((<UnionType>type).types, getWidenedConstituentType));
|
||||
const unionContext = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, (<UnionType>type).types);
|
||||
const widenedTypes = sameMap((<UnionType>type).types, t => t.flags & TypeFlags.Nullable ? t : getWidenedTypeWithContext(t, unionContext));
|
||||
// Widening an empty object literal transitions from a highly restrictive type to
|
||||
// a highly inclusive one. For that reason we perform subtype reduction here if the
|
||||
// union includes empty object types (e.g. reducing {} | string to just {}).
|
||||
return getUnionType(widenedTypes, some(widenedTypes, isEmptyObjectType));
|
||||
}
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
return createTypeReference((<TypeReference>type).target, sameMap((<TypeReference>type).typeArguments, getWidenedType));
|
||||
@@ -10490,28 +10584,35 @@ namespace ts {
|
||||
*/
|
||||
function reportWideningErrorsInType(type: Type): boolean {
|
||||
let errorReported = false;
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
for (const t of (<UnionType>type).types) {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
if (type.flags & TypeFlags.ContainsWideningType) {
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
if (some((<UnionType>type).types, isEmptyObjectType)) {
|
||||
errorReported = true;
|
||||
}
|
||||
else {
|
||||
for (const t of (<UnionType>type).types) {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
errorReported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
for (const t of (<TypeReference>type).typeArguments) {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
errorReported = true;
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
for (const t of (<TypeReference>type).typeArguments) {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
errorReported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getObjectFlags(type) & ObjectFlags.ObjectLiteral) {
|
||||
for (const p of getPropertiesOfObjectType(type)) {
|
||||
const t = getTypeOfSymbol(p);
|
||||
if (t.flags & TypeFlags.ContainsWideningType) {
|
||||
if (!reportWideningErrorsInType(t)) {
|
||||
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolName(p), typeToString(getWidenedType(t)));
|
||||
if (isObjectLiteralType(type)) {
|
||||
for (const p of getPropertiesOfObjectType(type)) {
|
||||
const t = getTypeOfSymbol(p);
|
||||
if (t.flags & TypeFlags.ContainsWideningType) {
|
||||
if (!reportWideningErrorsInType(t)) {
|
||||
error(p.valueDeclaration, Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, symbolName(p), typeToString(getWidenedType(t)));
|
||||
}
|
||||
errorReported = true;
|
||||
}
|
||||
errorReported = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10666,29 +10767,27 @@ namespace ts {
|
||||
const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional;
|
||||
const members = createSymbolTable();
|
||||
for (const prop of properties) {
|
||||
const inferredPropType = inferTargetType(getTypeOfSymbol(prop));
|
||||
if (!inferredPropType) {
|
||||
const propType = getTypeOfSymbol(prop);
|
||||
// If any property contains context sensitive functions that have been skipped, the source type
|
||||
// is incomplete and we can't infer a meaningful input type.
|
||||
if (propType.flags & TypeFlags.ContainsAnyFunctionType) {
|
||||
return undefined;
|
||||
}
|
||||
const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName);
|
||||
inferredProp.checkFlags = readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0;
|
||||
inferredProp.declarations = prop.declarations;
|
||||
inferredProp.type = inferredPropType;
|
||||
inferredProp.type = inferTargetType(propType);
|
||||
members.set(prop.escapedName, inferredProp);
|
||||
}
|
||||
if (indexInfo) {
|
||||
const inferredIndexType = inferTargetType(indexInfo.type);
|
||||
if (!inferredIndexType) {
|
||||
return undefined;
|
||||
}
|
||||
indexInfo = createIndexInfo(inferredIndexType, readonlyMask && indexInfo.isReadonly);
|
||||
indexInfo = createIndexInfo(inferTargetType(indexInfo.type), readonlyMask && indexInfo.isReadonly);
|
||||
}
|
||||
return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined);
|
||||
|
||||
function inferTargetType(sourceType: Type): Type {
|
||||
inference.candidates = undefined;
|
||||
inferTypes(inferences, sourceType, templateType);
|
||||
return inference.candidates && getUnionType(inference.candidates, /*subtypeReduction*/ true);
|
||||
return inference.candidates ? getUnionType(inference.candidates, /*subtypeReduction*/ true) : emptyObjectType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10955,7 +11054,7 @@ namespace ts {
|
||||
const targetLen = targetSignatures.length;
|
||||
const len = sourceLen < targetLen ? sourceLen : targetLen;
|
||||
for (let i = 0; i < len; i++) {
|
||||
inferFromSignature(getErasedSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i]));
|
||||
inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11019,11 +11118,28 @@ namespace ts {
|
||||
return constraint && maybeTypeOfKind(constraint, TypeFlags.Primitive | TypeFlags.Index);
|
||||
}
|
||||
|
||||
function isObjectLiteralType(type: Type) {
|
||||
return !!(getObjectFlags(type) & ObjectFlags.ObjectLiteral);
|
||||
}
|
||||
|
||||
function widenObjectLiteralCandidates(candidates: Type[]): Type[] {
|
||||
if (candidates.length > 1) {
|
||||
const objectLiterals = filter(candidates, isObjectLiteralType);
|
||||
if (objectLiterals.length) {
|
||||
const objectLiteralsType = getWidenedType(getUnionType(objectLiterals, /*subtypeReduction*/ true));
|
||||
return concatenate(filter(candidates, t => !isObjectLiteralType(t)), [objectLiteralsType]);
|
||||
}
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
||||
function getInferredType(context: InferenceContext, index: number): Type {
|
||||
const inference = context.inferences[index];
|
||||
let inferredType = inference.inferredType;
|
||||
if (!inferredType) {
|
||||
if (inference.candidates) {
|
||||
// Extract all object literal types and replace them with a single widened and normalized type.
|
||||
const candidates = widenObjectLiteralCandidates(inference.candidates);
|
||||
// We widen inferred literal types if
|
||||
// all inferences were made to top-level ocurrences of the type parameter, and
|
||||
// the type parameter has no constraint or its constraint includes no primitive or literal types, and
|
||||
@@ -11032,7 +11148,7 @@ namespace ts {
|
||||
const widenLiteralTypes = inference.topLevel &&
|
||||
!hasPrimitiveConstraint(inference.typeParameter) &&
|
||||
(inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
|
||||
const baseCandidates = widenLiteralTypes ? sameMap(inference.candidates, getWidenedLiteralType) : inference.candidates;
|
||||
const baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates;
|
||||
// If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if
|
||||
// union types were requested or if all inferences were made from the return type position, infer a
|
||||
// union type. Otherwise, infer a common supertype.
|
||||
@@ -11377,6 +11493,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getTypeWithFacts(type: Type, include: TypeFacts) {
|
||||
if (type.flags & TypeFlags.IndexedAccess) {
|
||||
// TODO (weswig): This is a substitute for a lazy negated type to remove the types indicated by the TypeFacts from the (potential) union the IndexedAccess refers to
|
||||
// - See discussion in https://github.com/Microsoft/TypeScript/pull/19275 for details, and test `strictNullNotNullIndexTypeShouldWork` for current behavior
|
||||
const baseConstraint = getBaseConstraintOfType(type) || emptyObjectType;
|
||||
const result = filterType(baseConstraint, t => (getTypeFacts(t) & include) !== 0);
|
||||
if (result !== baseConstraint) {
|
||||
return result;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
return filterType(type, t => (getTypeFacts(t) & include) !== 0);
|
||||
}
|
||||
|
||||
@@ -12396,7 +12522,7 @@ namespace ts {
|
||||
if (isRightSideOfQualifiedNameOrPropertyAccess(location)) {
|
||||
location = location.parent;
|
||||
}
|
||||
if (isPartOfExpression(location) && !isAssignmentTarget(location)) {
|
||||
if (isExpressionNode(location) && !isAssignmentTarget(location)) {
|
||||
const type = getTypeOfExpression(<Expression>location);
|
||||
if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
|
||||
return type;
|
||||
@@ -13043,12 +13169,14 @@ namespace ts {
|
||||
|
||||
// at this point the only legal case for parent is ClassLikeDeclaration
|
||||
const classLikeDeclaration = <ClassLikeDeclaration>container.parent;
|
||||
if (!getClassExtendsHeritageClauseElement(classLikeDeclaration)) {
|
||||
error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class);
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
const classType = <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration));
|
||||
const baseClassType = classType && getBaseTypes(classType)[0];
|
||||
if (!baseClassType) {
|
||||
if (!getClassExtendsHeritageClauseElement(classLikeDeclaration)) {
|
||||
error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class);
|
||||
}
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
@@ -13418,7 +13546,7 @@ namespace ts {
|
||||
// exists. Otherwise, it is the type of the string index signature in T, if one exists.
|
||||
function getContextualTypeForObjectLiteralMethod(node: MethodDeclaration): Type {
|
||||
Debug.assert(isObjectLiteralMethod(node));
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
if (node.flags & NodeFlags.InWithStatement) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return undefined;
|
||||
}
|
||||
@@ -13543,7 +13671,7 @@ namespace ts {
|
||||
* @returns the contextual type of an expression.
|
||||
*/
|
||||
function getContextualType(node: Expression): Type | undefined {
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
if (node.flags & NodeFlags.InWithStatement) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return undefined;
|
||||
}
|
||||
@@ -15050,7 +15178,7 @@ namespace ts {
|
||||
|
||||
checkPropertyNotUsedBeforeDeclaration(prop, node, right);
|
||||
|
||||
markPropertyAsReferenced(prop, node);
|
||||
markPropertyAsReferenced(prop, node, left.kind === SyntaxKind.ThisKeyword);
|
||||
|
||||
getNodeLinks(node).resolvedSymbol = prop;
|
||||
|
||||
@@ -15106,7 +15234,7 @@ namespace ts {
|
||||
// We might be in `a = { b: this.b }`, so keep looking. See `tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts`.
|
||||
return false;
|
||||
default:
|
||||
return isPartOfExpression(node) ? false : "quit";
|
||||
return isExpressionNode(node) ? false : "quit";
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -15240,12 +15368,21 @@ namespace ts {
|
||||
return bestCandidate;
|
||||
}
|
||||
|
||||
function markPropertyAsReferenced(prop: Symbol, nodeForCheckWriteOnly: Node | undefined) {
|
||||
function markPropertyAsReferenced(prop: Symbol, nodeForCheckWriteOnly: Node | undefined, isThisAccess: boolean) {
|
||||
if (prop &&
|
||||
noUnusedIdentifiers &&
|
||||
(prop.flags & SymbolFlags.ClassMember) &&
|
||||
prop.valueDeclaration && hasModifier(prop.valueDeclaration, ModifierFlags.Private)
|
||||
&& !(nodeForCheckWriteOnly && isWriteOnlyAccess(nodeForCheckWriteOnly))) {
|
||||
|
||||
if (isThisAccess) {
|
||||
// Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters).
|
||||
const containingMethod = findAncestor(nodeForCheckWriteOnly, isFunctionLikeDeclaration);
|
||||
if (containingMethod && containingMethod.symbol === prop) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (getCheckFlags(prop) & CheckFlags.Instantiated) {
|
||||
getSymbolLinks(prop).target.isReferenced = true;
|
||||
}
|
||||
@@ -18894,7 +19031,7 @@ namespace ts {
|
||||
case "arguments":
|
||||
case "prototype":
|
||||
const message = Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1;
|
||||
const className = getNameOfSymbol(getSymbolOfNode(node));
|
||||
const className = getNameOfSymbolAsWritten(getSymbolOfNode(node));
|
||||
error(memberNameNode, message, memberName, className);
|
||||
break;
|
||||
}
|
||||
@@ -19194,7 +19331,10 @@ namespace ts {
|
||||
// There is no resolved symbol cached if the type resolved to a builtin
|
||||
// via JSDoc type reference resolution (eg, Boolean became boolean), none
|
||||
// of which are generic when they have no associated symbol
|
||||
error(node, Diagnostics.Type_0_is_not_generic, typeToString(type));
|
||||
// (additionally, JSDoc's index signature syntax, Object<string, T> actually uses generic syntax without being generic)
|
||||
if (!isJSDocIndexSignature(node)) {
|
||||
error(node, Diagnostics.Type_0_is_not_generic, typeToString(type));
|
||||
}
|
||||
return;
|
||||
}
|
||||
let typeParameters = symbol.flags & SymbolFlags.TypeAlias && getSymbolLinks(symbol).typeParameters;
|
||||
@@ -20740,7 +20880,7 @@ namespace ts {
|
||||
const parentType = getTypeForBindingElementParent(parent);
|
||||
const name = node.propertyName || <Identifier>node.name;
|
||||
const property = getPropertyOfType(parentType, getTextOfPropertyName(name));
|
||||
markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined); // A destructuring is never a write-only reference.
|
||||
markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
|
||||
if (parent.initializer && property) {
|
||||
checkPropertyAccessibility(parent, parent.initializer, parentType, property);
|
||||
}
|
||||
@@ -20783,7 +20923,7 @@ namespace ts {
|
||||
// initializer is consistent with type associated with the node
|
||||
const declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node));
|
||||
if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType)) {
|
||||
error(node.name, Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2, declarationNameToString(node.name), typeToString(type), typeToString(declarationType));
|
||||
errorNextVariableDeclarationMustHaveSameType(symbol.valueDeclaration, type, node, declarationType);
|
||||
}
|
||||
if (node.initializer) {
|
||||
checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, /*headMessage*/ undefined);
|
||||
@@ -20807,6 +20947,21 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function errorNextVariableDeclarationMustHaveSameType(firstDeclaration: Declaration, firstType: Type, nextDeclaration: Declaration, nextType: Type): void {
|
||||
const firstSourceFile = getSourceFileOfNode(firstDeclaration);
|
||||
const firstSpan = getErrorSpanForNode(firstSourceFile, getNameOfDeclaration(firstDeclaration) || firstDeclaration);
|
||||
const firstLocation = getLineAndCharacterOfPosition(firstSourceFile, firstSpan.start);
|
||||
const firstLocationDescription = firstSourceFile.fileName + " " + firstLocation.line + ":" + firstLocation.character;
|
||||
const nextDeclarationName = getNameOfDeclaration(nextDeclaration);
|
||||
error(
|
||||
nextDeclarationName,
|
||||
Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_type_3,
|
||||
declarationNameToString(nextDeclarationName),
|
||||
typeToString(firstType),
|
||||
firstLocationDescription,
|
||||
typeToString(nextType));
|
||||
}
|
||||
|
||||
function areDeclarationFlagsIdentical(left: Declaration, right: Declaration) {
|
||||
if ((left.kind === SyntaxKind.Parameter && right.kind === SyntaxKind.VariableDeclaration) ||
|
||||
(left.kind === SyntaxKind.VariableDeclaration && right.kind === SyntaxKind.Parameter)) {
|
||||
@@ -23100,21 +23255,8 @@ namespace ts {
|
||||
|
||||
// Language service support
|
||||
|
||||
function isInsideWithStatementBody(node: Node): boolean {
|
||||
if (node) {
|
||||
while (node.parent) {
|
||||
if (node.parent.kind === SyntaxKind.WithStatement && (<WithStatement>node.parent).statement === node) {
|
||||
return true;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] {
|
||||
if (isInsideWithStatementBody(location)) {
|
||||
if (location.flags & NodeFlags.InWithStatement) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return [];
|
||||
}
|
||||
@@ -23365,7 +23507,7 @@ namespace ts {
|
||||
return typeParameter && typeParameter.symbol;
|
||||
}
|
||||
|
||||
if (isPartOfExpression(entityName)) {
|
||||
if (isExpressionNode(entityName)) {
|
||||
if (nodeIsMissing(entityName)) {
|
||||
// Missing entity name.
|
||||
return undefined;
|
||||
@@ -23414,7 +23556,7 @@ namespace ts {
|
||||
return isExternalModule(<SourceFile>node) ? getMergedSymbol(node.symbol) : undefined;
|
||||
}
|
||||
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
if (node.flags & NodeFlags.InWithStatement) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return undefined;
|
||||
}
|
||||
@@ -23522,7 +23664,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getTypeOfNode(node: Node): Type {
|
||||
if (isInsideWithStatementBody(node)) {
|
||||
if (node.flags & NodeFlags.InWithStatement) {
|
||||
// We cannot answer semantic questions within a with block, do not proceed any further
|
||||
return unknownType;
|
||||
}
|
||||
@@ -23539,7 +23681,7 @@ namespace ts {
|
||||
return typeFromTypeNode;
|
||||
}
|
||||
|
||||
if (isPartOfExpression(node)) {
|
||||
if (isExpressionNode(node)) {
|
||||
return getRegularTypeOfExpression(<Expression>node);
|
||||
}
|
||||
|
||||
@@ -25611,13 +25753,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getAmbientModules(): Symbol[] {
|
||||
const result: Symbol[] = [];
|
||||
globals.forEach((global, sym) => {
|
||||
if (ambientModuleSymbolRegex.test(unescapeLeadingUnderscores(sym))) {
|
||||
result.push(global);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
if (!ambientModulesCache) {
|
||||
ambientModulesCache = [];
|
||||
globals.forEach((global, sym) => {
|
||||
// No need to `unescapeLeadingUnderscores`, an escaped symbol is never an ambient module.
|
||||
if (ambientModuleSymbolRegex.test(sym as string)) {
|
||||
ambientModulesCache.push(global);
|
||||
}
|
||||
});
|
||||
}
|
||||
return ambientModulesCache;
|
||||
}
|
||||
|
||||
function checkGrammarImportCallExpression(node: ImportCall): boolean {
|
||||
|
||||
@@ -1138,6 +1138,13 @@ namespace ts {
|
||||
reportInvalidOptionValue(option && option.type !== "number");
|
||||
return Number((<NumericLiteral>valueExpression).text);
|
||||
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
if ((<PrefixUnaryExpression>valueExpression).operator !== SyntaxKind.MinusToken || (<PrefixUnaryExpression>valueExpression).operand.kind !== SyntaxKind.NumericLiteral) {
|
||||
break; // not valid JSON syntax
|
||||
}
|
||||
reportInvalidOptionValue(option && option.type !== "number");
|
||||
return -Number((<NumericLiteral>(<PrefixUnaryExpression>valueExpression).operand).text);
|
||||
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
reportInvalidOptionValue(option && option.type !== "object");
|
||||
const objectLiteralExpression = <ObjectLiteralExpression>valueExpression;
|
||||
@@ -1183,8 +1190,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function isDoubleQuotedString(node: Node) {
|
||||
return node.kind === SyntaxKind.StringLiteral && getSourceTextOfNodeFromSourceFile(sourceFile, node).charCodeAt(0) === CharacterCodes.doubleQuote;
|
||||
function isDoubleQuotedString(node: Node): boolean {
|
||||
return isStringLiteral(node) && isStringDoubleQuoted(node, sourceFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1440,9 +1447,9 @@ namespace ts {
|
||||
|
||||
function getFileNames(): ExpandResult {
|
||||
let filesSpecs: ReadonlyArray<string>;
|
||||
if (hasProperty(raw, "files") && !isNullOrUndefined(raw["files"])) {
|
||||
if (isArray(raw["files"])) {
|
||||
filesSpecs = <ReadonlyArray<string>>raw["files"];
|
||||
if (hasProperty(raw, "files") && !isNullOrUndefined(raw.files)) {
|
||||
if (isArray(raw.files)) {
|
||||
filesSpecs = <ReadonlyArray<string>>raw.files;
|
||||
if (filesSpecs.length === 0) {
|
||||
createCompilerDiagnosticOnlyIfJson(Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json");
|
||||
}
|
||||
@@ -1453,9 +1460,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
let includeSpecs: ReadonlyArray<string>;
|
||||
if (hasProperty(raw, "include") && !isNullOrUndefined(raw["include"])) {
|
||||
if (isArray(raw["include"])) {
|
||||
includeSpecs = <ReadonlyArray<string>>raw["include"];
|
||||
if (hasProperty(raw, "include") && !isNullOrUndefined(raw.include)) {
|
||||
if (isArray(raw.include)) {
|
||||
includeSpecs = <ReadonlyArray<string>>raw.include;
|
||||
}
|
||||
else {
|
||||
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "include", "Array");
|
||||
@@ -1463,16 +1470,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
let excludeSpecs: ReadonlyArray<string>;
|
||||
if (hasProperty(raw, "exclude") && !isNullOrUndefined(raw["exclude"])) {
|
||||
if (isArray(raw["exclude"])) {
|
||||
excludeSpecs = <ReadonlyArray<string>>raw["exclude"];
|
||||
if (hasProperty(raw, "exclude") && !isNullOrUndefined(raw.exclude)) {
|
||||
if (isArray(raw.exclude)) {
|
||||
excludeSpecs = <ReadonlyArray<string>>raw.exclude;
|
||||
}
|
||||
else {
|
||||
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array");
|
||||
}
|
||||
}
|
||||
else {
|
||||
const outDir = raw["compilerOptions"] && raw["compilerOptions"]["outDir"];
|
||||
const outDir = raw.compilerOptions && raw.compilerOptions.outDir;
|
||||
if (outDir) {
|
||||
excludeSpecs = [outDir];
|
||||
}
|
||||
@@ -1591,7 +1598,7 @@ namespace ts {
|
||||
const options = convertCompilerOptionsFromJsonWorker(json.compilerOptions, basePath, errors, configFileName);
|
||||
// typingOptions has been deprecated and is only supported for backward compatibility purposes.
|
||||
// It should be removed in future releases - use typeAcquisition instead.
|
||||
const typeAcquisition = convertTypeAcquisitionFromJsonWorker(json["typeAcquisition"] || json["typingOptions"], basePath, errors, configFileName);
|
||||
const typeAcquisition = convertTypeAcquisitionFromJsonWorker(json.typeAcquisition || json.typingOptions, basePath, errors, configFileName);
|
||||
json.compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors);
|
||||
let extendedConfigPath: Path;
|
||||
|
||||
@@ -1748,7 +1755,7 @@ namespace ts {
|
||||
if (!hasProperty(jsonOption, compileOnSaveCommandLineOption.name)) {
|
||||
return undefined;
|
||||
}
|
||||
const result = convertJsonOption(compileOnSaveCommandLineOption, jsonOption["compileOnSave"], basePath, errors);
|
||||
const result = convertJsonOption(compileOnSaveCommandLineOption, jsonOption.compileOnSave, basePath, errors);
|
||||
if (typeof result === "boolean" && result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
+64
-7
@@ -4,7 +4,7 @@
|
||||
namespace ts {
|
||||
// WARNING: The script `configureNightly.ts` uses a regexp to parse out these values.
|
||||
// If changing the text in this section, be sure to test `configureNightly` too.
|
||||
export const versionMajorMinor = "2.6";
|
||||
export const versionMajorMinor = "2.7";
|
||||
/** The version of the TypeScript compiler release */
|
||||
export const version = `${versionMajorMinor}.0`;
|
||||
}
|
||||
@@ -33,8 +33,8 @@ namespace ts {
|
||||
// Using 'delete' on an object causes V8 to put the object in dictionary mode.
|
||||
// This disables creation of hidden classes, which are expensive when an object is
|
||||
// constantly changing shape.
|
||||
map["__"] = undefined;
|
||||
delete map["__"];
|
||||
map.__ = undefined;
|
||||
delete map.__;
|
||||
|
||||
return map;
|
||||
}
|
||||
@@ -191,6 +191,18 @@ namespace ts {
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */
|
||||
export function firstDefined<T, U>(array: ReadonlyArray<T> | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const result = callback(array[i], i);
|
||||
if (result !== undefined) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the parent chain of a node and performs the callback on each parent until the callback
|
||||
* returns a truthy value, then returns that value.
|
||||
@@ -261,6 +273,16 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function findLast<T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => boolean): T | undefined {
|
||||
for (let i = array.length - 1; i >= 0; i--) {
|
||||
const value = array[i];
|
||||
if (predicate(value, i)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** Works like Array.prototype.findIndex, returning `-1` if no element satisfying the predicate is found. */
|
||||
export function findIndex<T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => boolean): number {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
@@ -1147,6 +1169,14 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function arrayToNumericMap<T>(array: ReadonlyArray<T>, makeKey: (value: T) => number): T[] {
|
||||
const result: T[] = [];
|
||||
for (const value of array) {
|
||||
result[makeKey(value)] = value;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a set from the elements of an array.
|
||||
*
|
||||
@@ -1680,6 +1710,12 @@ namespace ts {
|
||||
return moduleResolution;
|
||||
}
|
||||
|
||||
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "alwaysStrict";
|
||||
|
||||
export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
|
||||
return compilerOptions[flag] === undefined ? compilerOptions.strict : compilerOptions[flag];
|
||||
}
|
||||
|
||||
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
|
||||
let seenAsterisk = false;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
@@ -1831,7 +1867,7 @@ namespace ts {
|
||||
return i < 0 ? path : path.substring(i + 1);
|
||||
}
|
||||
|
||||
export function combinePaths(path1: string, path2: string) {
|
||||
export function combinePaths(path1: string, path2: string): string {
|
||||
if (!(path1 && path1.length)) return path2;
|
||||
if (!(path2 && path2.length)) return path1;
|
||||
if (getRootLength(path2) !== 0) return path2;
|
||||
@@ -2661,6 +2697,16 @@ namespace ts {
|
||||
return find<Extension>(supportedTypescriptExtensionsForExtractExtension, e => fileExtensionIs(path, e)) || find(supportedJavascriptExtensions, e => fileExtensionIs(path, e));
|
||||
}
|
||||
|
||||
// Retrieves any string from the final "." onwards from a base file name.
|
||||
// Unlike extensionFromPath, which throws an exception on unrecognized extensions.
|
||||
export function getAnyExtensionFromPath(path: string): string | undefined {
|
||||
const baseFileName = getBaseFileName(path);
|
||||
const extensionIndex = baseFileName.lastIndexOf(".");
|
||||
if (extensionIndex >= 0) {
|
||||
return baseFileName.substring(extensionIndex);
|
||||
}
|
||||
}
|
||||
|
||||
export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) {
|
||||
return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs;
|
||||
}
|
||||
@@ -2671,8 +2717,14 @@ namespace ts {
|
||||
|
||||
export function assertTypeIsNever(_: never): void { }
|
||||
|
||||
export interface FileAndDirectoryExistence {
|
||||
fileExists: boolean;
|
||||
directoryExists: boolean;
|
||||
}
|
||||
|
||||
export interface CachedDirectoryStructureHost extends DirectoryStructureHost {
|
||||
addOrDeleteFileOrDirectory(fileOrDirectory: string, fileOrDirectoryPath: Path): void;
|
||||
/** Returns the queried result for the file exists and directory exists if at all it was done */
|
||||
addOrDeleteFileOrDirectory(fileOrDirectory: string, fileOrDirectoryPath: Path): FileAndDirectoryExistence | undefined;
|
||||
addOrDeleteFile(fileName: string, filePath: Path, eventKind: FileWatcherEventKind): void;
|
||||
clearCache(): void;
|
||||
}
|
||||
@@ -2842,8 +2894,13 @@ namespace ts {
|
||||
if (parentResult) {
|
||||
const baseName = getBaseNameOfFileName(fileOrDirectory);
|
||||
if (parentResult) {
|
||||
updateFilesOfFileSystemEntry(parentResult, baseName, host.fileExists(fileOrDirectoryPath));
|
||||
updateFileSystemEntry(parentResult.directories, baseName, host.directoryExists(fileOrDirectoryPath));
|
||||
const fsQueryResult: FileAndDirectoryExistence = {
|
||||
fileExists: host.fileExists(fileOrDirectoryPath),
|
||||
directoryExists: host.directoryExists(fileOrDirectoryPath)
|
||||
};
|
||||
updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists);
|
||||
updateFileSystemEntry(parentResult.directories, baseName, fsQueryResult.directoryExists);
|
||||
return fsQueryResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1316,7 +1316,7 @@
|
||||
"category": "Error",
|
||||
"code": 2402
|
||||
},
|
||||
"Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.": {
|
||||
"Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.": {
|
||||
"category": "Error",
|
||||
"code": 2403
|
||||
},
|
||||
@@ -3539,6 +3539,14 @@
|
||||
"category": "Error",
|
||||
"code": 8025
|
||||
},
|
||||
"Expected {0} type arguments; provide these with an '@extends' tag.": {
|
||||
"category": "Error",
|
||||
"code": 8026
|
||||
},
|
||||
"Expected {0}-{1} type arguments; provide these with an '@extends' tag.": {
|
||||
"category": "Error",
|
||||
"code": 8027
|
||||
},
|
||||
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause.": {
|
||||
"category": "Error",
|
||||
"code": 9002
|
||||
@@ -3673,7 +3681,7 @@
|
||||
"category": "Error",
|
||||
"code": 90010
|
||||
},
|
||||
"Import {0} from {1}.": {
|
||||
"Import '{0}' from \"{1}\".": {
|
||||
"category": "Message",
|
||||
"code": 90013
|
||||
},
|
||||
@@ -3681,7 +3689,7 @@
|
||||
"category": "Message",
|
||||
"code": 90014
|
||||
},
|
||||
"Add {0} to existing import declaration from {1}.": {
|
||||
"Add '{0}' to existing import declaration from \"{1}\".": {
|
||||
"category": "Message",
|
||||
"code": 90015
|
||||
},
|
||||
|
||||
+22
-1
@@ -1982,7 +1982,7 @@ namespace ts {
|
||||
node.decorators = asNodeArray(decorators);
|
||||
node.modifiers = asNodeArray(modifiers);
|
||||
node.isExportEquals = isExportEquals;
|
||||
node.expression = expression;
|
||||
node.expression = isExportEquals ? parenthesizeBinaryOperand(SyntaxKind.EqualsToken, expression, /*isLeftSideOfBinary*/ false, /*leftOperand*/ undefined) : parenthesizeDefaultExpression(expression);
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -3932,6 +3932,27 @@ namespace ts {
|
||||
: e;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Per the spec](https://tc39.github.io/ecma262/#prod-ExportDeclaration), `export default` accepts _AssigmentExpression_ but
|
||||
* has a lookahead restriction for `function`, `async function`, and `class`.
|
||||
*
|
||||
* Basically, that means we need to parenthesize in the following cases:
|
||||
*
|
||||
* - BinaryExpression of CommaToken
|
||||
* - CommaList (synthetic list of multiple comma expressions)
|
||||
* - FunctionExpression
|
||||
* - ClassExpression
|
||||
*/
|
||||
export function parenthesizeDefaultExpression(e: Expression) {
|
||||
const check = skipPartiallyEmittedExpressions(e);
|
||||
return (check.kind === SyntaxKind.ClassExpression ||
|
||||
check.kind === SyntaxKind.FunctionExpression ||
|
||||
check.kind === SyntaxKind.CommaListExpression ||
|
||||
isBinaryExpression(check) && check.operatorToken.kind === SyntaxKind.CommaToken)
|
||||
? createParen(e)
|
||||
: e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an expression in parentheses if it is needed in order to use the expression
|
||||
* as the expression of a NewExpression node.
|
||||
|
||||
@@ -128,7 +128,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function getEffectiveTypeRoots(options: CompilerOptions, host: { directoryExists?: (directoryName: string) => boolean, getCurrentDirectory?: () => string }): string[] | undefined {
|
||||
export interface GetEffectiveTypeRootsHost {
|
||||
directoryExists?(directoryName: string): boolean;
|
||||
getCurrentDirectory?(): string;
|
||||
}
|
||||
export function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffectiveTypeRootsHost): string[] | undefined {
|
||||
if (options.typeRoots) {
|
||||
return options.typeRoots;
|
||||
}
|
||||
@@ -1001,7 +1005,8 @@ namespace ts {
|
||||
return withPackageId(packageId, pathAndExtension);
|
||||
}
|
||||
|
||||
function getPackageName(moduleName: string): { packageName: string, rest: string } {
|
||||
/* @internal */
|
||||
export function getPackageName(moduleName: string): { packageName: string, rest: string } {
|
||||
let idx = moduleName.indexOf(directorySeparator);
|
||||
if (moduleName[0] === "@") {
|
||||
idx = moduleName.indexOf(directorySeparator, idx + 1);
|
||||
@@ -1059,18 +1064,27 @@ namespace ts {
|
||||
const mangledScopedPackageSeparator = "__";
|
||||
|
||||
/** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */
|
||||
function mangleScopedPackage(moduleName: string, state: ModuleResolutionState): string {
|
||||
if (startsWith(moduleName, "@")) {
|
||||
const replaceSlash = moduleName.replace(ts.directorySeparator, mangledScopedPackageSeparator);
|
||||
if (replaceSlash !== moduleName) {
|
||||
const mangled = replaceSlash.slice(1); // Take off the "@"
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Scoped_package_detected_looking_in_0, mangled);
|
||||
}
|
||||
return mangled;
|
||||
function mangleScopedPackage(packageName: string, state: ModuleResolutionState): string {
|
||||
const mangled = getMangledNameForScopedPackage(packageName);
|
||||
if (state.traceEnabled && mangled !== packageName) {
|
||||
trace(state.host, Diagnostics.Scoped_package_detected_looking_in_0, mangled);
|
||||
}
|
||||
return mangled;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getTypesPackageName(packageName: string): string {
|
||||
return `@types/${getMangledNameForScopedPackage(packageName)}`;
|
||||
}
|
||||
|
||||
function getMangledNameForScopedPackage(packageName: string): string {
|
||||
if (startsWith(packageName, "@")) {
|
||||
const replaceSlash = packageName.replace(ts.directorySeparator, mangledScopedPackageSeparator);
|
||||
if (replaceSlash !== packageName) {
|
||||
return replaceSlash.slice(1); // Take off the "@"
|
||||
}
|
||||
}
|
||||
return moduleName;
|
||||
return packageName;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
@@ -4770,7 +4770,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.OpenParenToken);
|
||||
node.expression = allowInAnd(parseExpression);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
node.statement = parseStatement();
|
||||
node.statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement);
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
|
||||
+10
-4
@@ -1049,6 +1049,10 @@ namespace ts {
|
||||
// update fileName -> file mapping
|
||||
for (let i = 0; i < newSourceFiles.length; i++) {
|
||||
filesByName.set(filePaths[i], newSourceFiles[i]);
|
||||
// Set the file as found during node modules search if it was found that way in old progra,
|
||||
if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePaths[i]))) {
|
||||
sourceFilesFoundSearchingNodeModules.set(filePaths[i], true);
|
||||
}
|
||||
}
|
||||
|
||||
files = newSourceFiles;
|
||||
@@ -1278,8 +1282,10 @@ namespace ts {
|
||||
const typeChecker = getDiagnosticsProducingTypeChecker();
|
||||
|
||||
Debug.assert(!!sourceFile.bindDiagnostics);
|
||||
// For JavaScript files, we don't want to report semantic errors unless explicitly requested.
|
||||
const includeBindAndCheckDiagnostics = !isSourceFileJavaScript(sourceFile) || isCheckJsEnabledForFile(sourceFile, options);
|
||||
|
||||
// By default, only type-check .ts, .tsx, and 'External' files (external files are added by plugins)
|
||||
const includeBindAndCheckDiagnostics = sourceFile.scriptKind === ScriptKind.TS || sourceFile.scriptKind === ScriptKind.TSX ||
|
||||
sourceFile.scriptKind === ScriptKind.External || isCheckJsEnabledForFile(sourceFile, options);
|
||||
const bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : emptyArray;
|
||||
const checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : emptyArray;
|
||||
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
@@ -2125,7 +2131,7 @@ namespace ts {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib");
|
||||
}
|
||||
|
||||
if (options.noImplicitUseStrict && (options.alwaysStrict === undefined ? options.strict : options.alwaysStrict)) {
|
||||
if (options.noImplicitUseStrict && getStrictOptionValue(options, "alwaysStrict")) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict");
|
||||
}
|
||||
|
||||
@@ -2354,7 +2360,7 @@ namespace ts {
|
||||
return options.jsx ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
|
||||
}
|
||||
function needAllowJs() {
|
||||
return options.allowJs || !options.noImplicitAny ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
|
||||
return options.allowJs || !getStrictOptionValue(options, "noImplicitAny") ? undefined : Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@ namespace ts {
|
||||
interface DirectoryOfFailedLookupWatch {
|
||||
dir: string;
|
||||
dirPath: Path;
|
||||
ignore?: true;
|
||||
}
|
||||
|
||||
export const maxNumberOfFilesToIterateForInvalidation = 256;
|
||||
@@ -319,6 +320,33 @@ namespace ts {
|
||||
return endsWith(dirPath, "/node_modules");
|
||||
}
|
||||
|
||||
function isDirectoryAtleastAtLevelFromFSRoot(dirPath: Path, minLevels: number) {
|
||||
for (let searchIndex = getRootLength(dirPath); minLevels > 0; minLevels--) {
|
||||
searchIndex = dirPath.indexOf(directorySeparator, searchIndex) + 1;
|
||||
if (searchIndex === 0) {
|
||||
// Folder isnt at expected minimun levels
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function canWatchDirectory(dirPath: Path) {
|
||||
return isDirectoryAtleastAtLevelFromFSRoot(dirPath,
|
||||
// When root is "/" do not watch directories like:
|
||||
// "/", "/user", "/user/username", "/user/username/folderAtRoot"
|
||||
// When root is "c:/" do not watch directories like:
|
||||
// "c:/", "c:/folderAtRoot"
|
||||
dirPath.charCodeAt(0) === CharacterCodes.slash ? 3 : 1);
|
||||
}
|
||||
|
||||
function filterFSRootDirectoriesToWatch(watchPath: DirectoryOfFailedLookupWatch, dirPath: Path): DirectoryOfFailedLookupWatch {
|
||||
if (!canWatchDirectory(dirPath)) {
|
||||
watchPath.ignore = true;
|
||||
}
|
||||
return watchPath;
|
||||
}
|
||||
|
||||
function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: Path): DirectoryOfFailedLookupWatch {
|
||||
if (isInDirectoryPath(rootPath, failedLookupLocationPath)) {
|
||||
return { dir: rootDir, dirPath: rootPath };
|
||||
@@ -335,7 +363,7 @@ namespace ts {
|
||||
|
||||
// If the directory is node_modules use it to watch
|
||||
if (isNodeModulesDirectory(dirPath)) {
|
||||
return { dir, dirPath };
|
||||
return filterFSRootDirectoriesToWatch({ dir, dirPath }, getDirectoryPath(dirPath));
|
||||
}
|
||||
|
||||
// Use some ancestor of the root directory
|
||||
@@ -350,7 +378,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return { dir, dirPath };
|
||||
return filterFSRootDirectoriesToWatch({ dir, dirPath }, dirPath);
|
||||
}
|
||||
|
||||
function isPathWithDefaultFailedLookupExtension(path: Path) {
|
||||
@@ -391,13 +419,15 @@ namespace ts {
|
||||
const refCount = customFailedLookupPaths.get(failedLookupLocationPath) || 0;
|
||||
customFailedLookupPaths.set(failedLookupLocationPath, refCount + 1);
|
||||
}
|
||||
const { dir, dirPath } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
if (dirWatcher) {
|
||||
dirWatcher.refCount++;
|
||||
}
|
||||
else {
|
||||
directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 });
|
||||
const { dir, dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (!ignore) {
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
if (dirWatcher) {
|
||||
dirWatcher.refCount++;
|
||||
}
|
||||
else {
|
||||
directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -422,10 +452,12 @@ namespace ts {
|
||||
customFailedLookupPaths.set(failedLookupLocationPath, refCount - 1);
|
||||
}
|
||||
}
|
||||
const { dirPath } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
// Do not close the watcher yet since it might be needed by other failed lookup locations.
|
||||
dirWatcher.refCount--;
|
||||
const { dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (!ignore) {
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
// Do not close the watcher yet since it might be needed by other failed lookup locations.
|
||||
dirWatcher.refCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -577,7 +609,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
// we need to assume the directories exist to ensure that we can get all the type root directories that get included
|
||||
const typeRoots = getEffectiveTypeRoots(options, { directoryExists: returnTrue, getCurrentDirectory });
|
||||
// But filter directories that are at root level to say directory doesnt exist, so that we arent watching them
|
||||
const typeRoots = getEffectiveTypeRoots(options, { directoryExists: directoryExistsForTypeRootWatch, getCurrentDirectory });
|
||||
if (typeRoots) {
|
||||
mutateMap(
|
||||
typeRootsWatches,
|
||||
@@ -592,5 +625,16 @@ namespace ts {
|
||||
closeTypeRootsWatch();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this function to return if directory exists to get type roots to watch
|
||||
* If we return directory exists then only the paths will be added to type roots
|
||||
* Hence return true for all directories except root directories which are filtered from watching
|
||||
*/
|
||||
function directoryExistsForTypeRootWatch(nodeTypesDirectory: string) {
|
||||
const dir = getDirectoryPath(getDirectoryPath(nodeTypesDirectory));
|
||||
const dirPath = resolutionHost.toPath(dir);
|
||||
return dirPath === rootPath || canWatchDirectory(dirPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ namespace ts {
|
||||
/**
|
||||
* We assume the first line starts at position 0 and 'position' is non-negative.
|
||||
*/
|
||||
export function computeLineAndCharacterOfPosition(lineStarts: ReadonlyArray<number>, position: number) {
|
||||
export function computeLineAndCharacterOfPosition(lineStarts: ReadonlyArray<number>, position: number): LineAndCharacter {
|
||||
let lineNumber = binarySearch(lineStarts, position);
|
||||
if (lineNumber < 0) {
|
||||
// If the actual position was not found,
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace ts {
|
||||
}
|
||||
forEach(signature.typeParameters, visitType);
|
||||
|
||||
for (const parameter of signature.parameters){
|
||||
for (const parameter of signature.parameters) {
|
||||
visitSymbol(parameter);
|
||||
}
|
||||
visitType(getRestTypeOfSignature(signature));
|
||||
|
||||
+2
-2
@@ -131,7 +131,7 @@ namespace ts {
|
||||
const _os = require("os");
|
||||
const _crypto = require("crypto");
|
||||
|
||||
const useNonPollingWatchers = process.env["TSC_NONPOLLING_WATCHER"];
|
||||
const useNonPollingWatchers = process.env.TSC_NONPOLLING_WATCHER;
|
||||
|
||||
function createWatchedFileSet() {
|
||||
const dirWatchers = createMap<DirectoryWatcher>();
|
||||
@@ -573,7 +573,7 @@ namespace ts {
|
||||
|
||||
function recursiveCreateDirectory(directoryPath: string, sys: System) {
|
||||
const basePath = getDirectoryPath(directoryPath);
|
||||
const shouldCreateParent = directoryPath !== basePath && !sys.directoryExists(basePath);
|
||||
const shouldCreateParent = basePath !== "" && directoryPath !== basePath && !sys.directoryExists(basePath);
|
||||
if (shouldCreateParent) {
|
||||
recursiveCreateDirectory(basePath, sys);
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace ts {
|
||||
startLexicalEnvironment();
|
||||
|
||||
const statements: Statement[] = [];
|
||||
const ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
|
||||
const ensureUseStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
|
||||
const statementOffset = addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
|
||||
|
||||
if (shouldEmitUnderscoreUnderscoreESModule()) {
|
||||
|
||||
@@ -225,7 +225,7 @@ namespace ts {
|
||||
startLexicalEnvironment();
|
||||
|
||||
// Add any prologue directives.
|
||||
const ensureUseStrict = compilerOptions.alwaysStrict || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
|
||||
const ensureUseStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && isExternalModule(currentSourceFile));
|
||||
const statementOffset = addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor);
|
||||
|
||||
// var __moduleName = context_1 && context_1.id;
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace ts {
|
||||
|
||||
const resolver = context.getEmitResolver();
|
||||
const compilerOptions = context.getCompilerOptions();
|
||||
const strictNullChecks = typeof compilerOptions.strictNullChecks === "undefined" ? compilerOptions.strict : compilerOptions.strictNullChecks;
|
||||
const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
|
||||
const languageVersion = getEmitScriptTarget(compilerOptions);
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
|
||||
@@ -521,7 +521,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitSourceFile(node: SourceFile) {
|
||||
const alwaysStrict = (compilerOptions.alwaysStrict === undefined ? compilerOptions.strict : compilerOptions.alwaysStrict) &&
|
||||
const alwaysStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") &&
|
||||
!(isExternalModule(node) && moduleKind >= ModuleKind.ES2015);
|
||||
return updateSourceFileNode(
|
||||
node,
|
||||
|
||||
+1
-13
@@ -43,20 +43,12 @@ namespace ts {
|
||||
return s;
|
||||
}
|
||||
|
||||
function isJSONSupported() {
|
||||
return typeof JSON === "object" && typeof JSON.parse === "function";
|
||||
}
|
||||
|
||||
export function executeCommandLine(args: string[]): void {
|
||||
const commandLine = parseCommandLine(args);
|
||||
|
||||
// Configuration file name (if any)
|
||||
let configFileName: string;
|
||||
if (commandLine.options.locale) {
|
||||
if (!isJSONSupported()) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--locale"));
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
validateLocaleAndSetLanguage(commandLine.options.locale, sys, commandLine.errors);
|
||||
}
|
||||
|
||||
@@ -84,10 +76,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (commandLine.options.project) {
|
||||
if (!isJSONSupported()) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--project"));
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
if (commandLine.fileNames.length !== 0) {
|
||||
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Option_project_cannot_be_mixed_with_source_files_on_a_command_line));
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
@@ -109,7 +97,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (commandLine.fileNames.length === 0 && isJSONSupported()) {
|
||||
else if (commandLine.fileNames.length === 0) {
|
||||
const searchPath = normalizePath(sys.getCurrentDirectory());
|
||||
configFileName = findConfigFile(searchPath, sys.fileExists);
|
||||
}
|
||||
|
||||
+18
-5
@@ -365,6 +365,7 @@ namespace ts {
|
||||
JSDocFunctionType,
|
||||
JSDocVariadicType,
|
||||
JSDocComment,
|
||||
JSDocTypeLiteral,
|
||||
JSDocTag,
|
||||
JSDocAugmentsTag,
|
||||
JSDocClassTag,
|
||||
@@ -374,7 +375,6 @@ namespace ts {
|
||||
JSDocTemplateTag,
|
||||
JSDocTypedefTag,
|
||||
JSDocPropertyTag,
|
||||
JSDocTypeLiteral,
|
||||
|
||||
// Synthesized list
|
||||
SyntaxList,
|
||||
@@ -416,9 +416,9 @@ namespace ts {
|
||||
LastBinaryOperator = CaretEqualsToken,
|
||||
FirstNode = QualifiedName,
|
||||
FirstJSDocNode = JSDocTypeExpression,
|
||||
LastJSDocNode = JSDocTypeLiteral,
|
||||
LastJSDocNode = JSDocPropertyTag,
|
||||
FirstJSDocTagNode = JSDocTag,
|
||||
LastJSDocTagNode = JSDocTypeLiteral
|
||||
LastJSDocTagNode = JSDocPropertyTag
|
||||
}
|
||||
|
||||
export const enum NodeFlags {
|
||||
@@ -454,6 +454,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
PossiblyContainsDynamicImport = 1 << 19,
|
||||
JSDoc = 1 << 20, // If node was parsed inside jsdoc
|
||||
/* @internal */ InWithStatement = 1 << 21, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
|
||||
|
||||
BlockScoped = Let | Const,
|
||||
|
||||
@@ -461,7 +462,7 @@ namespace ts {
|
||||
ReachabilityAndEmitFlags = ReachabilityCheckFlags | HasAsyncFunctions,
|
||||
|
||||
// Parsing context flags
|
||||
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile,
|
||||
ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement,
|
||||
|
||||
// Exclude these flags when parsing a Type
|
||||
TypeExcludesFlags = YieldContext | AwaitContext,
|
||||
@@ -1058,6 +1059,7 @@ namespace ts {
|
||||
export interface StringLiteral extends LiteralExpression {
|
||||
kind: SyntaxKind.StringLiteral;
|
||||
/* @internal */ textSourceNode?: Identifier | StringLiteral | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
|
||||
/** Note: this is only set when synthesizing a node, not during parsing. */
|
||||
/* @internal */ singleQuote?: boolean;
|
||||
}
|
||||
|
||||
@@ -3348,6 +3350,7 @@ namespace ts {
|
||||
ObjectLiteral = 1 << 7, // Originates in an object literal
|
||||
EvolvingArray = 1 << 8, // Evolving array type
|
||||
ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties
|
||||
ContainsSpread = 1 << 10, // Object literal contains spread operation
|
||||
ClassOrInterface = Class | Interface
|
||||
}
|
||||
|
||||
@@ -3630,6 +3633,14 @@ namespace ts {
|
||||
compareTypes: TypeComparer; // Type comparer function
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface WideningContext {
|
||||
parent?: WideningContext; // Parent context
|
||||
propertyName?: __String; // Name of property in parent
|
||||
siblings?: Type[]; // Types of siblings
|
||||
resolvedPropertyNames?: __String[]; // Property names occurring in sibling object literals
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum SpecialPropertyAssignmentKind {
|
||||
None,
|
||||
@@ -3648,6 +3659,7 @@ namespace ts {
|
||||
export interface JsFileExtensionInfo {
|
||||
extension: string;
|
||||
isMixedContent: boolean;
|
||||
scriptKind?: ScriptKind;
|
||||
}
|
||||
|
||||
export interface DiagnosticMessage {
|
||||
@@ -3832,9 +3844,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface LineAndCharacter {
|
||||
/** 0-based. */
|
||||
line: number;
|
||||
/*
|
||||
* This value denotes the character position in line and is different from the 'column' because of tab characters.
|
||||
* 0-based. This value denotes the character position in line and is different from the 'column' because of tab characters.
|
||||
*/
|
||||
character: number;
|
||||
}
|
||||
|
||||
+74
-40
@@ -520,6 +520,17 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isAnyImportSyntax(node: Node): node is AnyImportSyntax {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Gets the nearest enclosing block scope container that has the provided node
|
||||
// as a descendant, that is not the provided node.
|
||||
export function getEnclosingBlockScopeContainer(node: Node): Node {
|
||||
@@ -571,14 +582,14 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
|
||||
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic {
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2);
|
||||
return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
|
||||
export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic {
|
||||
const span = getErrorSpanForNode(sourceFile, node);
|
||||
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
|
||||
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
export function createDiagnosticForNodeFromMessageChain(node: Node, messageChain: DiagnosticMessageChain): Diagnostic {
|
||||
@@ -1217,7 +1228,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isPartOfExpression(node: Node): boolean {
|
||||
export function isExpressionNode(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SuperKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
@@ -1321,7 +1332,7 @@ namespace ts {
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return (<ExpressionWithTypeArguments>parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent);
|
||||
default:
|
||||
return isPartOfExpression(parent);
|
||||
return isExpressionNode(parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1350,6 +1361,14 @@ namespace ts {
|
||||
return node && !!(node.flags & NodeFlags.JSDoc);
|
||||
}
|
||||
|
||||
export function isJSDocIndexSignature(node: TypeReferenceNode | ExpressionWithTypeArguments) {
|
||||
return isTypeReferenceNode(node) &&
|
||||
isIdentifier(node.typeName) &&
|
||||
node.typeName.escapedText === "Object" &&
|
||||
node.typeArguments && node.typeArguments.length === 2 &&
|
||||
(node.typeArguments[0].kind === SyntaxKind.StringKeyword || node.typeArguments[0].kind === SyntaxKind.NumberKeyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node is a CallExpression to the identifier 'require' with
|
||||
* exactly one argument (of the form 'require("name")').
|
||||
@@ -1376,6 +1395,10 @@ namespace ts {
|
||||
return charCode === CharacterCodes.singleQuote || charCode === CharacterCodes.doubleQuote;
|
||||
}
|
||||
|
||||
export function isStringDoubleQuoted(string: StringLiteral, sourceFile: SourceFile): boolean {
|
||||
return getSourceTextOfNodeFromSourceFile(sourceFile, string).charCodeAt(0) === CharacterCodes.doubleQuote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the node is a variable declaration whose initializer is a function expression.
|
||||
* This function does not test if the node is in a JavaScript file or not.
|
||||
@@ -1516,6 +1539,34 @@ namespace ts {
|
||||
return getJSDocCommentsAndTags(node);
|
||||
}
|
||||
|
||||
export function getSourceOfAssignment(node: Node): Node {
|
||||
return isExpressionStatement(node) &&
|
||||
node.expression && isBinaryExpression(node.expression) &&
|
||||
node.expression.operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
node.expression.right;
|
||||
}
|
||||
|
||||
export function getSingleInitializerOfVariableStatement(node: Node, child?: Node): Node {
|
||||
return isVariableStatement(node) &&
|
||||
node.declarationList.declarations.length > 0 &&
|
||||
(!child || node.declarationList.declarations[0].initializer === child) &&
|
||||
node.declarationList.declarations[0].initializer;
|
||||
}
|
||||
|
||||
export function getSingleVariableOfVariableStatement(node: Node, child?: Node): Node {
|
||||
return isVariableStatement(node) &&
|
||||
node.declarationList.declarations.length > 0 &&
|
||||
(!child || node.declarationList.declarations[0] === child) &&
|
||||
node.declarationList.declarations[0];
|
||||
}
|
||||
|
||||
export function getNestedModuleDeclaration(node: Node): Node {
|
||||
return node.kind === SyntaxKind.ModuleDeclaration &&
|
||||
(node as ModuleDeclaration).body &&
|
||||
(node as ModuleDeclaration).body.kind === SyntaxKind.ModuleDeclaration &&
|
||||
(node as ModuleDeclaration).body;
|
||||
}
|
||||
|
||||
export function getJSDocCommentsAndTags(node: Node): (JSDoc | JSDocTag)[] {
|
||||
let result: (JSDoc | JSDocTag)[] | undefined;
|
||||
getJSDocCommentsAndTagsWorker(node);
|
||||
@@ -1529,35 +1580,15 @@ namespace ts {
|
||||
// * @returns {number}
|
||||
// */
|
||||
// var x = function(name) { return name.length; }
|
||||
const isInitializerOfVariableDeclarationInStatement =
|
||||
isVariableLike(parent) &&
|
||||
parent.initializer === node &&
|
||||
parent.parent.parent.kind === SyntaxKind.VariableStatement;
|
||||
const isVariableOfVariableDeclarationStatement = isVariableLike(node) &&
|
||||
parent.parent.kind === SyntaxKind.VariableStatement;
|
||||
const variableStatementNode =
|
||||
isInitializerOfVariableDeclarationInStatement ? parent.parent.parent :
|
||||
isVariableOfVariableDeclarationStatement ? parent.parent :
|
||||
undefined;
|
||||
if (variableStatementNode) {
|
||||
getJSDocCommentsAndTagsWorker(variableStatementNode);
|
||||
if (parent && (parent.kind === SyntaxKind.PropertyAssignment || getNestedModuleDeclaration(parent))) {
|
||||
getJSDocCommentsAndTagsWorker(parent);
|
||||
}
|
||||
|
||||
// Also recognize when the node is the RHS of an assignment expression
|
||||
const isSourceOfAssignmentExpressionStatement =
|
||||
parent && parent.parent &&
|
||||
parent.kind === SyntaxKind.BinaryExpression &&
|
||||
(parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken &&
|
||||
parent.parent.kind === SyntaxKind.ExpressionStatement;
|
||||
if (isSourceOfAssignmentExpressionStatement) {
|
||||
if (parent && parent.parent &&
|
||||
(getSingleVariableOfVariableStatement(parent.parent, node) || getSourceOfAssignment(parent.parent))) {
|
||||
getJSDocCommentsAndTagsWorker(parent.parent);
|
||||
}
|
||||
|
||||
const isModuleDeclaration = node.kind === SyntaxKind.ModuleDeclaration &&
|
||||
parent && parent.kind === SyntaxKind.ModuleDeclaration;
|
||||
const isPropertyAssignmentExpression = parent && parent.kind === SyntaxKind.PropertyAssignment;
|
||||
if (isModuleDeclaration || isPropertyAssignmentExpression) {
|
||||
getJSDocCommentsAndTagsWorker(parent);
|
||||
if (parent && parent.parent && parent.parent.parent && getSingleInitializerOfVariableStatement(parent.parent.parent, node)) {
|
||||
getJSDocCommentsAndTagsWorker(parent.parent.parent);
|
||||
}
|
||||
|
||||
// Pull parameter comments from declaring function as well
|
||||
@@ -1584,13 +1615,16 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
const name = node.name.escapedText;
|
||||
const func = getJSDocHost(node);
|
||||
if (!isFunctionLike(func)) {
|
||||
return undefined;
|
||||
const host = getJSDocHost(node);
|
||||
const decl = getSourceOfAssignment(host) ||
|
||||
getSingleInitializerOfVariableStatement(host) ||
|
||||
getSingleVariableOfVariableStatement(host) ||
|
||||
getNestedModuleDeclaration(host) ||
|
||||
host;
|
||||
if (decl && isFunctionLike(decl)) {
|
||||
const parameter = find(decl.parameters, p => p.name.kind === SyntaxKind.Identifier && p.name.escapedText === name);
|
||||
return parameter && parameter.symbol;
|
||||
}
|
||||
const parameter = find(func.parameters, p =>
|
||||
p.name.kind === SyntaxKind.Identifier && p.name.escapedText === name);
|
||||
return parameter && parameter.symbol;
|
||||
}
|
||||
|
||||
export function getJSDocHost(node: JSDocTag): HasJSDoc {
|
||||
@@ -3186,7 +3220,7 @@ namespace ts {
|
||||
|
||||
const carriageReturnLineFeed = "\r\n";
|
||||
const lineFeed = "\n";
|
||||
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, system?: System): string {
|
||||
export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, system?: { newLine: string }): string {
|
||||
switch (options.newLine) {
|
||||
case NewLineKind.CarriageReturnLineFeed:
|
||||
return carriageReturnLineFeed;
|
||||
@@ -5362,7 +5396,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
/**
|
||||
* Determines whether a node is an expression based only on its kind.
|
||||
* Use `isPartOfExpression` if not in transforms.
|
||||
* Use `isExpressionNode` if not in transforms.
|
||||
*/
|
||||
export function isExpression(node: Node): node is Expression {
|
||||
return isExpressionKind(skipPartiallyEmittedExpressions(node).kind);
|
||||
|
||||
+26
-25
@@ -144,13 +144,14 @@ namespace ts {
|
||||
|
||||
function compileWatchedProgram(host: DirectoryStructureHost, program: Program, builder: Builder) {
|
||||
// First get and report any syntactic errors.
|
||||
let diagnostics = program.getSyntacticDiagnostics().slice();
|
||||
const diagnostics = program.getSyntacticDiagnostics().slice();
|
||||
let reportSemanticDiagnostics = false;
|
||||
|
||||
// If we didn't have any syntactic errors, then also try getting the global and
|
||||
// semantic errors.
|
||||
if (diagnostics.length === 0) {
|
||||
diagnostics = program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics());
|
||||
addRange(diagnostics, program.getOptionsDiagnostics());
|
||||
addRange(diagnostics, program.getGlobalDiagnostics());
|
||||
|
||||
if (diagnostics.length === 0) {
|
||||
reportSemanticDiagnostics = true;
|
||||
@@ -162,7 +163,7 @@ namespace ts {
|
||||
let sourceMaps: SourceMapData[];
|
||||
let emitSkipped: boolean;
|
||||
|
||||
const result = builder.emitChangedFiles(program);
|
||||
const result = builder.emitChangedFiles(program, writeFile);
|
||||
if (result.length === 0) {
|
||||
emitSkipped = true;
|
||||
}
|
||||
@@ -171,14 +172,13 @@ namespace ts {
|
||||
if (emitOutput.emitSkipped) {
|
||||
emitSkipped = true;
|
||||
}
|
||||
diagnostics = concatenate(diagnostics, emitOutput.diagnostics);
|
||||
addRange(diagnostics, emitOutput.diagnostics);
|
||||
sourceMaps = concatenate(sourceMaps, emitOutput.sourceMaps);
|
||||
writeOutputFiles(emitOutput.outputFiles);
|
||||
}
|
||||
}
|
||||
|
||||
if (reportSemanticDiagnostics) {
|
||||
diagnostics = diagnostics.concat(builder.getSemanticDiagnostics(program));
|
||||
addRange(diagnostics, builder.getSemanticDiagnostics(program));
|
||||
}
|
||||
return handleEmitOutputAndReportErrors(host, program, emittedFiles, emitSkipped,
|
||||
diagnostics, reportDiagnostic);
|
||||
@@ -191,31 +191,23 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, onError: (message: string) => void) {
|
||||
try {
|
||||
performance.mark("beforeIOWrite");
|
||||
ensureDirectoriesExist(getDirectoryPath(normalizePath(fileName)));
|
||||
|
||||
host.writeFile(fileName, data, writeByteOrderMark);
|
||||
host.writeFile(fileName, text, writeByteOrderMark);
|
||||
|
||||
performance.mark("afterIOWrite");
|
||||
performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite");
|
||||
|
||||
if (emittedFiles) {
|
||||
emittedFiles.push(fileName);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
return createCompilerDiagnostic(Diagnostics.Could_not_write_file_0_Colon_1, fileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
function writeOutputFiles(outputFiles: OutputFile[]) {
|
||||
if (outputFiles) {
|
||||
for (const outputFile of outputFiles) {
|
||||
const error = writeFile(outputFile.name, outputFile.text, outputFile.writeByteOrderMark);
|
||||
if (error) {
|
||||
diagnostics.push(error);
|
||||
}
|
||||
if (emittedFiles) {
|
||||
emittedFiles.push(outputFile.name);
|
||||
}
|
||||
if (onError) {
|
||||
onError(e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -308,7 +300,7 @@ namespace ts {
|
||||
getCurrentDirectory()
|
||||
);
|
||||
// There is no extra check needed since we can just rely on the program to decide emit
|
||||
const builder = createBuilder({ getCanonicalFileName, getEmitOutput: getFileEmitOutput, computeHash, shouldEmitFile: () => true });
|
||||
const builder = createBuilder({ getCanonicalFileName, computeHash });
|
||||
|
||||
synchronizeProgram();
|
||||
|
||||
@@ -605,8 +597,17 @@ namespace ts {
|
||||
const fileOrDirectoryPath = toPath(fileOrDirectory);
|
||||
|
||||
// Since the file existance changed, update the sourceFiles cache
|
||||
(directoryStructureHost as CachedDirectoryStructureHost).addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
removeSourceFile(fileOrDirectoryPath);
|
||||
const result = (directoryStructureHost as CachedDirectoryStructureHost).addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
|
||||
|
||||
// Instead of deleting the file, mark it as changed instead
|
||||
// Many times node calls add/remove/file when watching directories recursively
|
||||
const hostSourceFile = sourceFilesCache.get(fileOrDirectoryPath);
|
||||
if (hostSourceFile && !isString(hostSourceFile) && (result ? result.fileExists : directoryStructureHost.fileExists(fileOrDirectory))) {
|
||||
hostSourceFile.version++;
|
||||
}
|
||||
else {
|
||||
removeSourceFile(fileOrDirectoryPath);
|
||||
}
|
||||
|
||||
// If the the added or created file or directory is not supported file name, ignore the file
|
||||
// But when watched directory is added/removed, we need to reload the file list
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/// <reference path="core.ts" />
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
/**
|
||||
* Updates the existing missing file watches with the new set of missing files after new program is created
|
||||
@@ -72,10 +73,7 @@ namespace ts {
|
||||
existingWatchedForWildcards.set(directory, createWildcardDirectoryWatcher(directory, flags));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
export function addFileWatcher(host: System, file: string, cb: FileWatcherCallback): FileWatcher {
|
||||
return host.watchFile(file, cb);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
public checkTestCodeOutput(fileName: string) {
|
||||
describe("compiler tests for " + fileName, () => {
|
||||
describe(`${this.testSuiteName} tests for ${fileName}`, () => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Everything declared here should be cleared out in the "after" callback.
|
||||
let justName: string;
|
||||
@@ -80,9 +80,9 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
tsConfigFiles.push(this.createHarnessTestFile(testCaseContent.tsConfigFileUnitData, rootDir, ts.combinePaths(rootDir, tsConfigOptions.configFilePath)));
|
||||
}
|
||||
else {
|
||||
const baseUrl = harnessSettings["baseUrl"];
|
||||
const baseUrl = harnessSettings.baseUrl;
|
||||
if (baseUrl !== undefined && !ts.isRootedDiskPath(baseUrl)) {
|
||||
harnessSettings["baseUrl"] = ts.getNormalizedAbsolutePath(baseUrl, rootDir);
|
||||
harnessSettings.baseUrl = ts.getNormalizedAbsolutePath(baseUrl, rootDir);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
toBeCompiled = [];
|
||||
otherFiles = [];
|
||||
|
||||
if (testCaseContent.settings["noImplicitReferences"] || /require\(/.test(lastUnit.content) || /reference\spath/.test(lastUnit.content)) {
|
||||
if (testCaseContent.settings.noImplicitReferences || /require\(/.test(lastUnit.content) || /reference\spath/.test(lastUnit.content)) {
|
||||
toBeCompiled.push(this.createHarnessTestFile(lastUnit, rootDir));
|
||||
units.forEach(unit => {
|
||||
if (unit.name !== lastUnit.name) {
|
||||
@@ -114,7 +114,7 @@ class CompilerBaselineRunner extends RunnerBase {
|
||||
}
|
||||
|
||||
const output = Harness.Compiler.compileFiles(
|
||||
toBeCompiled, otherFiles, harnessSettings, /*options*/ tsConfigOptions, /*currentDirectory*/ harnessSettings["currentDirectory"]);
|
||||
toBeCompiled, otherFiles, harnessSettings, /*options*/ tsConfigOptions, /*currentDirectory*/ harnessSettings.currentDirectory);
|
||||
|
||||
options = output.options;
|
||||
result = output.result;
|
||||
|
||||
+132
-36
@@ -783,13 +783,13 @@ namespace FourSlash {
|
||||
});
|
||||
}
|
||||
|
||||
public verifyCompletionListContains(symbol: string, text?: string, documentation?: string, kind?: string, spanIndex?: number) {
|
||||
public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean) {
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
if (completions) {
|
||||
this.assertItemInCompletionList(completions.entries, symbol, text, documentation, kind, spanIndex);
|
||||
this.assertItemInCompletionList(completions.entries, entryId, text, documentation, kind, spanIndex, hasAction);
|
||||
}
|
||||
else {
|
||||
this.raiseError(`No completions at position '${this.currentCaretPosition}' when looking for '${symbol}'.`);
|
||||
this.raiseError(`No completions at position '${this.currentCaretPosition}' when looking for '${JSON.stringify(entryId)}'.`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -804,7 +804,7 @@ namespace FourSlash {
|
||||
* @param expectedKind the kind of symbol (see ScriptElementKind)
|
||||
* @param spanIndex the index of the range that the completion item's replacement text span should match
|
||||
*/
|
||||
public verifyCompletionListDoesNotContain(symbol: string, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number) {
|
||||
public verifyCompletionListDoesNotContain(entryId: ts.Completions.CompletionEntryIdentifier, expectedText?: string, expectedDocumentation?: string, expectedKind?: string, spanIndex?: number) {
|
||||
const that = this;
|
||||
let replacementSpan: ts.TextSpan;
|
||||
if (spanIndex !== undefined) {
|
||||
@@ -833,14 +833,14 @@ namespace FourSlash {
|
||||
|
||||
const completions = this.getCompletionListAtCaret();
|
||||
if (completions) {
|
||||
let filterCompletions = completions.entries.filter(e => e.name === symbol);
|
||||
let filterCompletions = completions.entries.filter(e => e.name === entryId.name && e.source === entryId.source);
|
||||
filterCompletions = expectedKind ? filterCompletions.filter(e => e.kind === expectedKind) : filterCompletions;
|
||||
filterCompletions = filterCompletions.filter(filterByTextOrDocumentation);
|
||||
if (filterCompletions.length !== 0) {
|
||||
// After filtered using all present criterion, if there are still symbol left in the list
|
||||
// then these symbols must meet the criterion for Not supposed to be in the list. So we
|
||||
// raise an error
|
||||
let error = "Completion list did contain \'" + symbol + "\'.";
|
||||
let error = `Completion list did contain '${JSON.stringify(entryId)}\'.`;
|
||||
const details = this.getCompletionEntryDetails(filterCompletions[0].name);
|
||||
if (expectedText) {
|
||||
error += "Expected text: " + expectedText + " to equal: " + ts.displayPartsToString(details.displayParts) + ".";
|
||||
@@ -953,6 +953,10 @@ namespace FourSlash {
|
||||
return this.getChecker().getSymbolsInScope(node, ts.SymbolFlags.Value | ts.SymbolFlags.Type | ts.SymbolFlags.Namespace);
|
||||
}
|
||||
|
||||
public setTypesRegistry(map: ts.MapLike<void>): void {
|
||||
this.languageServiceAdapterHost.typesRegistry = ts.createMapFromTemplate(map);
|
||||
}
|
||||
|
||||
public verifyTypeOfSymbolAtLocation(range: Range, symbol: ts.Symbol, expected: string): void {
|
||||
const node = this.goToAndGetNode(range);
|
||||
const checker = this.getChecker();
|
||||
@@ -1126,8 +1130,8 @@ Actual: ${stringify(fullActual)}`);
|
||||
return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition);
|
||||
}
|
||||
|
||||
private getCompletionEntryDetails(entryName: string) {
|
||||
return this.languageService.getCompletionEntryDetails(this.activeFile.fileName, this.currentCaretPosition, entryName);
|
||||
private getCompletionEntryDetails(entryName: string, source?: string) {
|
||||
return this.languageService.getCompletionEntryDetails(this.activeFile.fileName, this.currentCaretPosition, entryName, this.formatCodeSettings, source);
|
||||
}
|
||||
|
||||
private getReferencesAtCaret() {
|
||||
@@ -1636,7 +1640,7 @@ Actual: ${stringify(fullActual)}`);
|
||||
const longestNameLength = max(entries, m => m.name.length);
|
||||
const longestKindLength = max(entries, m => m.kind.length);
|
||||
entries.sort((m, n) => m.sortText > n.sortText ? 1 : m.sortText < n.sortText ? -1 : m.name > n.name ? 1 : m.name < n.name ? -1 : 0);
|
||||
const membersString = entries.map(m => `${pad(m.name, longestNameLength)} ${pad(m.kind, longestKindLength)} ${m.kindModifiers}`).join("\n");
|
||||
const membersString = entries.map(m => `${pad(m.name, longestNameLength)} ${pad(m.kind, longestKindLength)} ${m.kindModifiers} ${m.source === undefined ? "" : m.source}`).join("\n");
|
||||
Harness.IO.log(membersString);
|
||||
}
|
||||
|
||||
@@ -2289,6 +2293,29 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.applyCodeActions(this.getCodeFixActions(fileName, errorCode), index);
|
||||
}
|
||||
|
||||
public applyCodeActionFromCompletion(markerName: string, options: FourSlashInterface.VerifyCompletionActionOptions) {
|
||||
this.goToMarker(markerName);
|
||||
|
||||
const actualCompletion = this.getCompletionListAtCaret().entries.find(e => e.name === options.name && e.source === options.source);
|
||||
|
||||
if (!actualCompletion.hasAction) {
|
||||
this.raiseError(`Completion for ${options.name} does not have an associated action.`);
|
||||
}
|
||||
|
||||
const details = this.getCompletionEntryDetails(options.name, actualCompletion.source);
|
||||
if (details.codeActions.length !== 1) {
|
||||
this.raiseError(`Expected one code action, got ${details.codeActions.length}`);
|
||||
}
|
||||
|
||||
if (details.codeActions[0].description !== options.description) {
|
||||
this.raiseError(`Expected description to be:\n${options.description}\ngot:\n${details.codeActions[0].description}`);
|
||||
}
|
||||
|
||||
this.applyCodeActions(details.codeActions);
|
||||
|
||||
this.verifyNewContent(options);
|
||||
}
|
||||
|
||||
public verifyRangeIs(expectedText: string, includeWhiteSpace?: boolean) {
|
||||
const ranges = this.getRanges();
|
||||
if (ranges.length !== 1) {
|
||||
@@ -2360,6 +2387,10 @@ Actual: ${stringify(fullActual)}`);
|
||||
this.applyEdits(change.fileName, change.textChanges, /*isFormattingEdit*/ false);
|
||||
}
|
||||
|
||||
this.verifyNewContent(options);
|
||||
}
|
||||
|
||||
private verifyNewContent(options: FourSlashInterface.NewContentOptions) {
|
||||
if (options.newFileContent) {
|
||||
assert(!options.newRangeContent);
|
||||
this.verifyCurrentFileContent(options.newFileContent);
|
||||
@@ -2750,16 +2781,26 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
}
|
||||
|
||||
public verifyCodeFixAvailable(negative: boolean) {
|
||||
const codeFix = this.getCodeFixActions(this.activeFile.fileName);
|
||||
public verifyCodeFixAvailable(negative: boolean, info: FourSlashInterface.VerifyCodeFixAvailableOptions[] | undefined) {
|
||||
const codeFixes = this.getCodeFixActions(this.activeFile.fileName);
|
||||
|
||||
if (negative && codeFix.length) {
|
||||
this.raiseError(`verifyCodeFixAvailable failed - expected no fixes but found one.`);
|
||||
if (negative) {
|
||||
if (codeFixes.length) {
|
||||
this.raiseError(`verifyCodeFixAvailable failed - expected no fixes but found one.`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(negative || codeFix.length)) {
|
||||
if (!codeFixes.length) {
|
||||
this.raiseError(`verifyCodeFixAvailable failed - expected code fixes but none found.`);
|
||||
}
|
||||
if (info) {
|
||||
assert.equal(info.length, codeFixes.length);
|
||||
ts.zipWith(codeFixes, info, (fix, info) => {
|
||||
assert.equal(fix.description, info.description);
|
||||
this.assertObjectsEqual(fix.commands, info.commands);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public verifyApplicableRefactorAvailableAtMarker(negative: boolean, markerName: string) {
|
||||
@@ -2803,6 +2844,14 @@ Actual: ${stringify(fullActual)}`);
|
||||
}
|
||||
}
|
||||
|
||||
public verifyRefactor({ name, actionName, refactors }: FourSlashInterface.VerifyRefactorOptions) {
|
||||
const selection = this.getSelection();
|
||||
|
||||
const actualRefactors = (this.languageService.getApplicableRefactors(this.activeFile.fileName, selection) || ts.emptyArray)
|
||||
.filter(r => r.name === name && r.actions.some(a => a.name === actionName));
|
||||
this.assertObjectsEqual(actualRefactors, refactors);
|
||||
}
|
||||
|
||||
public verifyApplicableRefactorAvailableForRange(negative: boolean) {
|
||||
const ranges = this.getRanges();
|
||||
if (!(ranges && ranges.length === 1)) {
|
||||
@@ -2822,14 +2871,14 @@ Actual: ${stringify(fullActual)}`);
|
||||
public applyRefactor({ refactorName, actionName, actionDescription, newContent: newContentWithRenameMarker }: FourSlashInterface.ApplyRefactorOptions) {
|
||||
const range = this.getSelection();
|
||||
const refactors = this.languageService.getApplicableRefactors(this.activeFile.fileName, range);
|
||||
const refactor = refactors.find(r => r.name === refactorName);
|
||||
if (!refactor) {
|
||||
const refactorsWithName = refactors.filter(r => r.name === refactorName);
|
||||
if (refactorsWithName.length === 0) {
|
||||
this.raiseError(`The expected refactor: ${refactorName} is not available at the marker location.\nAvailable refactors: ${refactors.map(r => r.name)}`);
|
||||
}
|
||||
|
||||
const action = refactor.actions.find(a => a.name === actionName);
|
||||
const action = ts.firstDefined(refactorsWithName, refactor => refactor.actions.find(a => a.name === actionName));
|
||||
if (!action) {
|
||||
this.raiseError(`The expected action: ${action} is not included in: ${refactor.actions.map(a => a.name)}`);
|
||||
this.raiseError(`The expected action: ${actionName} is not included in: ${ts.flatMap(refactorsWithName, r => r.actions.map(a => a.name))}`);
|
||||
}
|
||||
if (action.description !== actionDescription) {
|
||||
this.raiseError(`Expected action description to be ${JSON.stringify(actionDescription)}, got: ${JSON.stringify(action.description)}`);
|
||||
@@ -2933,36 +2982,48 @@ Actual: ${stringify(fullActual)}`);
|
||||
return text.substring(startPos, endPos);
|
||||
}
|
||||
|
||||
private assertItemInCompletionList(items: ts.CompletionEntry[], name: string, text?: string, documentation?: string, kind?: string, spanIndex?: number) {
|
||||
private assertItemInCompletionList(
|
||||
items: ts.CompletionEntry[],
|
||||
entryId: ts.Completions.CompletionEntryIdentifier,
|
||||
text: string | undefined,
|
||||
documentation: string | undefined,
|
||||
kind: string | undefined,
|
||||
spanIndex: number | undefined,
|
||||
hasAction: boolean | undefined,
|
||||
) {
|
||||
for (const item of items) {
|
||||
if (item.name === name) {
|
||||
if (documentation !== undefined || text !== undefined) {
|
||||
const details = this.getCompletionEntryDetails(item.name);
|
||||
if (item.name === entryId.name && item.source === entryId.source) {
|
||||
if (documentation !== undefined || text !== undefined || entryId.source !== undefined) {
|
||||
const details = this.getCompletionEntryDetails(item.name, item.source);
|
||||
|
||||
if (documentation !== undefined) {
|
||||
assert.equal(ts.displayPartsToString(details.documentation), documentation, this.assertionMessageAtLastKnownMarker("completion item documentation for " + name));
|
||||
assert.equal(ts.displayPartsToString(details.documentation), documentation, this.assertionMessageAtLastKnownMarker("completion item documentation for " + entryId));
|
||||
}
|
||||
if (text !== undefined) {
|
||||
assert.equal(ts.displayPartsToString(details.displayParts), text, this.assertionMessageAtLastKnownMarker("completion item detail text for " + name));
|
||||
assert.equal(ts.displayPartsToString(details.displayParts), text, this.assertionMessageAtLastKnownMarker("completion item detail text for " + entryId));
|
||||
}
|
||||
|
||||
assert.deepEqual(details.source, entryId.source === undefined ? undefined : [ts.textPart(entryId.source)]);
|
||||
}
|
||||
|
||||
if (kind !== undefined) {
|
||||
assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + name));
|
||||
assert.equal(item.kind, kind, this.assertionMessageAtLastKnownMarker("completion item kind for " + entryId));
|
||||
}
|
||||
|
||||
if (spanIndex !== undefined) {
|
||||
const span = this.getTextSpanForRangeAtIndex(spanIndex);
|
||||
assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + name));
|
||||
assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + entryId));
|
||||
}
|
||||
|
||||
assert.equal(item.hasAction, hasAction);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const itemsString = items.map(item => stringify({ name: item.name, kind: item.kind })).join(",\n");
|
||||
|
||||
this.raiseError(`Expected "${stringify({ name, text, documentation, kind })}" to be in list [${itemsString}]`);
|
||||
this.raiseError(`Expected "${stringify({ entryId, text, documentation, kind })}" to be in list [${itemsString}]`);
|
||||
}
|
||||
|
||||
private findFile(indexOrName: any) {
|
||||
@@ -3222,7 +3283,7 @@ ${code}
|
||||
}
|
||||
|
||||
function containTSConfigJson(files: FourSlashFile[]): boolean {
|
||||
return ts.forEach(files, f => f.fileOptions["Filename"] === "tsconfig.json");
|
||||
return ts.forEach(files, f => f.fileOptions.Filename === "tsconfig.json");
|
||||
}
|
||||
|
||||
function getNonFileNameOptionInFileList(files: FourSlashFile[]): string {
|
||||
@@ -3577,6 +3638,10 @@ namespace FourSlashInterface {
|
||||
public symbolsInScope(range: FourSlash.Range): ts.Symbol[] {
|
||||
return this.state.symbolsInScope(range);
|
||||
}
|
||||
|
||||
public setTypesRegistry(map: ts.MapLike<void>): void {
|
||||
this.state.setTypesRegistry(map);
|
||||
}
|
||||
}
|
||||
|
||||
export class GoTo {
|
||||
@@ -3669,12 +3734,15 @@ namespace FourSlashInterface {
|
||||
|
||||
// Verifies the completion list contains the specified symbol. The
|
||||
// completion list is brought up if necessary
|
||||
public completionListContains(symbol: string, text?: string, documentation?: string, kind?: string, spanIndex?: number) {
|
||||
public completionListContains(entryId: string | ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string, spanIndex?: number, hasAction?: boolean) {
|
||||
if (typeof entryId === "string") {
|
||||
entryId = { name: entryId, source: undefined };
|
||||
}
|
||||
if (this.negative) {
|
||||
this.state.verifyCompletionListDoesNotContain(symbol, text, documentation, kind, spanIndex);
|
||||
this.state.verifyCompletionListDoesNotContain(entryId, text, documentation, kind, spanIndex);
|
||||
}
|
||||
else {
|
||||
this.state.verifyCompletionListContains(symbol, text, documentation, kind, spanIndex);
|
||||
this.state.verifyCompletionListContains(entryId, text, documentation, kind, spanIndex, hasAction);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3752,8 +3820,8 @@ namespace FourSlashInterface {
|
||||
this.state.verifyCodeFix(options);
|
||||
}
|
||||
|
||||
public codeFixAvailable() {
|
||||
this.state.verifyCodeFixAvailable(this.negative);
|
||||
public codeFixAvailable(options?: VerifyCodeFixAvailableOptions[]) {
|
||||
this.state.verifyCodeFixAvailable(this.negative, options);
|
||||
}
|
||||
|
||||
public applicableRefactorAvailableAtMarker(markerName: string) {
|
||||
@@ -3764,6 +3832,10 @@ namespace FourSlashInterface {
|
||||
this.state.verifyApplicableRefactorAvailableForRange(this.negative);
|
||||
}
|
||||
|
||||
public refactor(options: VerifyRefactorOptions) {
|
||||
this.state.verifyRefactor(options);
|
||||
}
|
||||
|
||||
public refactorAvailable(name: string, actionName?: string) {
|
||||
this.state.verifyRefactorAvailable(this.negative, name, actionName);
|
||||
}
|
||||
@@ -3999,6 +4071,10 @@ namespace FourSlashInterface {
|
||||
this.state.getAndApplyCodeActions(errorCode, index);
|
||||
}
|
||||
|
||||
public applyCodeActionFromCompletion(markerName: string, options: VerifyCompletionActionOptions): void {
|
||||
this.state.applyCodeActionFromCompletion(markerName, options);
|
||||
}
|
||||
|
||||
public importFixAtPosition(expectedTextArray: string[], errorCode?: number): void {
|
||||
this.state.verifyImportFixAtPosition(expectedTextArray, errorCode);
|
||||
}
|
||||
@@ -4396,12 +4472,32 @@ namespace FourSlashInterface {
|
||||
isNewIdentifierLocation?: boolean;
|
||||
}
|
||||
|
||||
export interface VerifyCodeFixOptions {
|
||||
description: string;
|
||||
// One of these should be defined.
|
||||
export interface NewContentOptions {
|
||||
// Exactly one of these should be defined.
|
||||
newFileContent?: string;
|
||||
newRangeContent?: string;
|
||||
}
|
||||
|
||||
export interface VerifyCodeFixOptions extends NewContentOptions {
|
||||
description: string;
|
||||
errorCode?: number;
|
||||
index?: number;
|
||||
}
|
||||
|
||||
export interface VerifyCodeFixAvailableOptions {
|
||||
description: string;
|
||||
commands?: ts.CodeActionCommand[];
|
||||
}
|
||||
|
||||
export interface VerifyRefactorOptions {
|
||||
name: string;
|
||||
actionName: string;
|
||||
refactors: ts.ApplicableRefactorInfo[];
|
||||
}
|
||||
|
||||
export interface VerifyCompletionActionOptions extends NewContentOptions {
|
||||
name: string;
|
||||
source?: string;
|
||||
description: string;
|
||||
}
|
||||
}
|
||||
|
||||
+17
-11
@@ -32,6 +32,9 @@
|
||||
// this will work in the browser via browserify
|
||||
var _chai: typeof chai = require("chai");
|
||||
var assert: typeof _chai.assert = _chai.assert;
|
||||
// chai's builtin `assert.isFalse` is featureful but slow - we don't use those features,
|
||||
// so we'll just overwrite it as an alterative to migrating a bunch of code off of chai
|
||||
assert.isFalse = (expr, msg) => { if (expr as any as boolean !== false) throw new Error(msg); };
|
||||
declare var __dirname: string; // Node-specific
|
||||
var global: NodeJS.Global = <any>Function("return this").call(undefined);
|
||||
|
||||
@@ -916,8 +919,8 @@ namespace Harness {
|
||||
if (file.content !== undefined) {
|
||||
const fileName = ts.normalizePath(file.unitName);
|
||||
const path = ts.toPath(file.unitName, currentDirectory, getCanonicalFileName);
|
||||
if (file.fileOptions && file.fileOptions["symlink"]) {
|
||||
const links = file.fileOptions["symlink"].split(",");
|
||||
if (file.fileOptions && file.fileOptions.symlink) {
|
||||
const links = file.fileOptions.symlink.split(",");
|
||||
for (const link of links) {
|
||||
const linkPath = ts.toPath(link, currentDirectory, getCanonicalFileName);
|
||||
realPathMap.set(linkPath, fileName);
|
||||
@@ -1196,6 +1199,9 @@ namespace Harness {
|
||||
traceResults = [];
|
||||
compilerHost.trace = text => traceResults.push(text);
|
||||
}
|
||||
else {
|
||||
compilerHost.directoryExists = () => true; // This only visibly affects resolution traces, so to save time we always return true where possible
|
||||
}
|
||||
const program = ts.createProgram(programFileNames, options, compilerHost);
|
||||
|
||||
const emitResult = program.emit();
|
||||
@@ -1232,7 +1238,7 @@ namespace Harness {
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
|
||||
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
|
||||
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
|
||||
return { declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory: currentDirectory || harnessSettings["currentDirectory"] };
|
||||
return { declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory: currentDirectory || harnessSettings.currentDirectory };
|
||||
}
|
||||
|
||||
function addDtsFile(file: TestFile, dtsFiles: TestFile[]) {
|
||||
@@ -1456,7 +1462,7 @@ namespace Harness {
|
||||
});
|
||||
}
|
||||
|
||||
export function doTypeAndSymbolBaseline(baselinePath: string, program: ts.Program, allFiles: {unitName: string, content: string}[], opts?: Harness.Baseline.BaselineOptions, multifile?: boolean, skipTypeAndSymbolbaselines?: boolean) {
|
||||
export function doTypeAndSymbolBaseline(baselinePath: string, program: ts.Program, allFiles: {unitName: string, content: string}[], opts?: Harness.Baseline.BaselineOptions, multifile?: boolean, skipTypeBaselines?: boolean, skipSymbolBaselines?: boolean) {
|
||||
// The full walker simulates the types that you would get from doing a full
|
||||
// compile. The pull walker simulates the types you get when you just do
|
||||
// a type query for a random node (like how the LS would do it). Most of the
|
||||
@@ -1514,19 +1520,19 @@ namespace Harness {
|
||||
baselinePath.replace(/\.tsx?/, "") : baselinePath;
|
||||
|
||||
if (!multifile) {
|
||||
const fullBaseLine = generateBaseLine(isSymbolBaseLine, skipTypeAndSymbolbaselines);
|
||||
const fullBaseLine = generateBaseLine(isSymbolBaseLine, isSymbolBaseLine ? skipSymbolBaselines : skipTypeBaselines);
|
||||
Harness.Baseline.runBaseline(outputFileName + fullExtension, () => fullBaseLine, opts);
|
||||
}
|
||||
else {
|
||||
Harness.Baseline.runMultifileBaseline(outputFileName, fullExtension, () => {
|
||||
return iterateBaseLine(isSymbolBaseLine, skipTypeAndSymbolbaselines);
|
||||
return iterateBaseLine(isSymbolBaseLine, isSymbolBaseLine ? skipSymbolBaselines : skipTypeBaselines);
|
||||
}, opts);
|
||||
}
|
||||
}
|
||||
|
||||
function generateBaseLine(isSymbolBaseline: boolean, skipTypeAndSymbolbaselines?: boolean): string {
|
||||
function generateBaseLine(isSymbolBaseline: boolean, skipBaseline?: boolean): string {
|
||||
let result = "";
|
||||
const gen = iterateBaseLine(isSymbolBaseline, skipTypeAndSymbolbaselines);
|
||||
const gen = iterateBaseLine(isSymbolBaseline, skipBaseline);
|
||||
for (let {done, value} = gen.next(); !done; { done, value } = gen.next()) {
|
||||
const [, content] = value;
|
||||
result += content;
|
||||
@@ -1536,8 +1542,8 @@ namespace Harness {
|
||||
/* tslint:enable:no-null-keyword */
|
||||
}
|
||||
|
||||
function *iterateBaseLine(isSymbolBaseline: boolean, skipTypeAndSymbolbaselines?: boolean): IterableIterator<[string, string]> {
|
||||
if (skipTypeAndSymbolbaselines) {
|
||||
function *iterateBaseLine(isSymbolBaseline: boolean, skipBaseline?: boolean): IterableIterator<[string, string]> {
|
||||
if (skipBaseline) {
|
||||
return;
|
||||
}
|
||||
const dupeCase = ts.createMap<number>();
|
||||
@@ -1676,7 +1682,7 @@ namespace Harness {
|
||||
}
|
||||
|
||||
function fileOutput(file: GeneratedFile, harnessSettings: Harness.TestCaseParser.CompilerSettings): string {
|
||||
const fileName = harnessSettings["fullEmitPaths"] ? file.fileName : ts.getBaseFileName(file.fileName);
|
||||
const fileName = harnessSettings.fullEmitPaths ? file.fileName : ts.getBaseFileName(file.fileName);
|
||||
return "//// [" + fileName + "]\r\n" + getByteOrderMarkText(file) + file.code;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
export class LanguageServiceAdapterHost {
|
||||
public typesRegistry: ts.Map<void> | undefined;
|
||||
protected virtualFileSystem: Utils.VirtualFileSystem = new Utils.VirtualFileSystem(virtualFileSystemRoot, /*useCaseSensitiveFilenames*/false);
|
||||
|
||||
constructor(protected cancellationToken = DefaultHostCancellationToken.Instance,
|
||||
@@ -182,6 +183,11 @@ namespace Harness.LanguageService {
|
||||
|
||||
/// Native adapter
|
||||
class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts.LanguageServiceHost {
|
||||
isKnownTypesPackageName(name: string): boolean {
|
||||
return this.typesRegistry && this.typesRegistry.has(name);
|
||||
}
|
||||
installPackage = ts.notImplemented;
|
||||
|
||||
getCompilationSettings() { return this.settings; }
|
||||
getCancellationToken() { return this.cancellationToken; }
|
||||
getDirectories(path: string): string[] {
|
||||
@@ -206,6 +212,11 @@ namespace Harness.LanguageService {
|
||||
return script ? script.version.toString() : undefined;
|
||||
}
|
||||
|
||||
directoryExists(dirName: string): boolean {
|
||||
const fileEntry = this.virtualFileSystem.traversePath(dirName);
|
||||
return fileEntry && fileEntry.isDirectory();
|
||||
}
|
||||
|
||||
fileExists(fileName: string): boolean {
|
||||
const script = this.getScriptSnapshot(fileName);
|
||||
return script !== undefined;
|
||||
@@ -405,8 +416,8 @@ namespace Harness.LanguageService {
|
||||
getCompletionsAtPosition(fileName: string, position: number): ts.CompletionInfo {
|
||||
return unwrapJSONCallResult(this.shim.getCompletionsAtPosition(fileName, position));
|
||||
}
|
||||
getCompletionEntryDetails(fileName: string, position: number, entryName: string): ts.CompletionEntryDetails {
|
||||
return unwrapJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName));
|
||||
getCompletionEntryDetails(fileName: string, position: number, entryName: string, options: ts.FormatCodeOptions | undefined, source: string | undefined): ts.CompletionEntryDetails {
|
||||
return unwrapJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName, JSON.stringify(options), source));
|
||||
}
|
||||
getCompletionEntrySymbol(): ts.Symbol {
|
||||
throw new Error("getCompletionEntrySymbol not implemented across the shim layer.");
|
||||
@@ -493,6 +504,7 @@ namespace Harness.LanguageService {
|
||||
getCodeFixesAtPosition(): ts.CodeAction[] {
|
||||
throw new Error("Not supported on the shim.");
|
||||
}
|
||||
applyCodeActionCommand = ts.notImplemented;
|
||||
getCodeFixDiagnostics(): ts.Diagnostic[] {
|
||||
throw new Error("Not supported on the shim.");
|
||||
}
|
||||
|
||||
+48
-15
@@ -89,6 +89,7 @@ interface PlaybackControl {
|
||||
namespace Playback {
|
||||
let recordLog: IOLog = undefined;
|
||||
let replayLog: IOLog = undefined;
|
||||
let replayFilesRead: ts.Map<IOLogFile> | undefined = undefined;
|
||||
let recordLogFileNameBase = "";
|
||||
|
||||
interface Memoized<T> {
|
||||
@@ -157,11 +158,20 @@ namespace Playback {
|
||||
return log;
|
||||
}
|
||||
|
||||
const canonicalizeForHarness = ts.createGetCanonicalFileName(/*caseSensitive*/ false); // This is done so tests work on windows _and_ linux
|
||||
function sanitizeTestFilePath(name: string) {
|
||||
const path = ts.toPath(ts.normalizeSlashes(name.replace(/[\^<>:"|?*%]/g, "_")).replace(/\.\.\//g, "__dotdot/"), "", canonicalizeForHarness);
|
||||
if (ts.startsWith(path, "/")) {
|
||||
return path.substring(1);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
export function oldStyleLogIntoNewStyleLog(log: IOLog, writeFile: typeof Harness.IO.writeFile, baseTestName: string) {
|
||||
if (log.filesAppended) {
|
||||
for (const file of log.filesAppended) {
|
||||
if (file.contents !== undefined) {
|
||||
file.contentsPath = ts.combinePaths("appended", Harness.Compiler.sanitizeTestFilePath(file.path));
|
||||
file.contentsPath = ts.combinePaths("appended", sanitizeTestFilePath(file.path));
|
||||
writeFile(ts.combinePaths(baseTestName, file.contentsPath), file.contents);
|
||||
delete file.contents;
|
||||
}
|
||||
@@ -170,7 +180,7 @@ namespace Playback {
|
||||
if (log.filesWritten) {
|
||||
for (const file of log.filesWritten) {
|
||||
if (file.contents !== undefined) {
|
||||
file.contentsPath = ts.combinePaths("written", Harness.Compiler.sanitizeTestFilePath(file.path));
|
||||
file.contentsPath = ts.combinePaths("written", sanitizeTestFilePath(file.path));
|
||||
writeFile(ts.combinePaths(baseTestName, file.contentsPath), file.contents);
|
||||
delete file.contents;
|
||||
}
|
||||
@@ -180,7 +190,7 @@ namespace Playback {
|
||||
for (const file of log.filesRead) {
|
||||
const { contents } = file.result;
|
||||
if (contents !== undefined) {
|
||||
file.result.contentsPath = ts.combinePaths("read", Harness.Compiler.sanitizeTestFilePath(file.path));
|
||||
file.result.contentsPath = ts.combinePaths("read", sanitizeTestFilePath(file.path));
|
||||
writeFile(ts.combinePaths(baseTestName, file.result.contentsPath), contents);
|
||||
const len = contents.length;
|
||||
if (len >= 2 && contents.charCodeAt(0) === 0xfeff) {
|
||||
@@ -213,10 +223,15 @@ namespace Playback {
|
||||
replayLog = log;
|
||||
// Remove non-found files from the log (shouldn't really need them, but we still record them for diagnostic purposes)
|
||||
replayLog.filesRead = replayLog.filesRead.filter(f => f.result.contents !== undefined);
|
||||
replayFilesRead = ts.createMap();
|
||||
for (const file of replayLog.filesRead) {
|
||||
replayFilesRead.set(ts.normalizeSlashes(file.path).toLowerCase(), file);
|
||||
}
|
||||
};
|
||||
|
||||
wrapper.endReplay = () => {
|
||||
replayLog = undefined;
|
||||
replayFilesRead = undefined;
|
||||
};
|
||||
|
||||
wrapper.startRecord = (fileNameBase) => {
|
||||
@@ -234,18 +249,38 @@ namespace Playback {
|
||||
wrapper.endRecord = () => {
|
||||
if (recordLog !== undefined) {
|
||||
let i = 0;
|
||||
const fn = () => recordLogFileNameBase + i;
|
||||
while (underlying.fileExists(fn() + ".json")) i++;
|
||||
underlying.writeFile(ts.combinePaths(fn(), "test.json"), JSON.stringify(oldStyleLogIntoNewStyleLog(recordLog, (path, string) => underlying.writeFile(ts.combinePaths(fn(), path), string), fn()), null, 4)); // tslint:disable-line:no-null-keyword
|
||||
const getBase = () => recordLogFileNameBase + i;
|
||||
while (underlying.fileExists(ts.combinePaths(getBase(), "test.json"))) i++;
|
||||
const newLog = oldStyleLogIntoNewStyleLog(recordLog, (path, string) => underlying.writeFile(path, string), getBase());
|
||||
underlying.writeFile(ts.combinePaths(getBase(), "test.json"), JSON.stringify(newLog, null, 4)); // tslint:disable-line:no-null-keyword
|
||||
const syntheticTsconfig = generateTsconfig(newLog);
|
||||
if (syntheticTsconfig) {
|
||||
underlying.writeFile(ts.combinePaths(getBase(), "tsconfig.json"), JSON.stringify(syntheticTsconfig, null, 4)); // tslint:disable-line:no-null-keyword
|
||||
}
|
||||
recordLog = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
function generateTsconfig(newLog: IOLog): undefined | { compilerOptions: ts.CompilerOptions, files: string[] } {
|
||||
if (newLog.filesRead.some(file => /tsconfig.+json$/.test(file.path))) {
|
||||
return;
|
||||
}
|
||||
const files = [];
|
||||
for (const file of newLog.filesRead) {
|
||||
if (file.result.contentsPath &&
|
||||
Harness.isDefaultLibraryFile(file.result.contentsPath) &&
|
||||
/\.[tj]s$/.test(file.result.contentsPath)) {
|
||||
files.push(file.result.contentsPath);
|
||||
}
|
||||
}
|
||||
return { compilerOptions: ts.parseCommandLine(newLog.arguments).options, files };
|
||||
}
|
||||
|
||||
wrapper.fileExists = recordReplay(wrapper.fileExists, underlying)(
|
||||
path => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path }),
|
||||
memoize(path => {
|
||||
// If we read from the file, it must exist
|
||||
if (findFileByPath(replayLog.filesRead, path, /*throwFileNotFoundError*/ false)) {
|
||||
if (findFileByPath(path, /*throwFileNotFoundError*/ false)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -289,7 +324,7 @@ namespace Playback {
|
||||
recordLog.filesRead.push(logEntry);
|
||||
return result;
|
||||
},
|
||||
memoize(path => findFileByPath(replayLog.filesRead, path, /*throwFileNotFoundError*/ true).contents));
|
||||
memoize(path => findFileByPath(path, /*throwFileNotFoundError*/ true).contents));
|
||||
|
||||
wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)(
|
||||
(path, extensions, exclude, include, depth) => {
|
||||
@@ -370,14 +405,12 @@ namespace Playback {
|
||||
return results[0].result;
|
||||
}
|
||||
|
||||
function findFileByPath(logArray: IOLogFile[],
|
||||
expectedPath: string, throwFileNotFoundError: boolean): FileInformation {
|
||||
function findFileByPath(expectedPath: string, throwFileNotFoundError: boolean): FileInformation {
|
||||
const normalizedName = ts.normalizePath(expectedPath).toLowerCase();
|
||||
// Try to find the result through normal fileName
|
||||
for (const log of logArray) {
|
||||
if (ts.normalizeSlashes(log.path).toLowerCase() === normalizedName) {
|
||||
return log.result;
|
||||
}
|
||||
const result = replayFilesRead.get(normalizedName);
|
||||
if (result) {
|
||||
return result.result;
|
||||
}
|
||||
|
||||
// If we got here, we didn't find a match
|
||||
@@ -415,4 +448,4 @@ namespace Playback {
|
||||
initWrapper(wrapper, underlying);
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace Harness.Parallel.Host {
|
||||
let closedWorkers = 0;
|
||||
for (let i = 0; i < workerCount; i++) {
|
||||
// TODO: Just send the config over the IPC channel or in the command line arguments
|
||||
const config: TestConfig = { light: Harness.lightMode, listenForWork: true, runUnitTests: runners.length !== 1 };
|
||||
const config: TestConfig = { light: Harness.lightMode, listenForWork: true, runUnitTests };
|
||||
const configPath = ts.combinePaths(taskConfigsFolder, `task-config${i}.json`);
|
||||
Harness.IO.writeFile(configPath, JSON.stringify(config));
|
||||
const child = fork(__filename, [`--config="${configPath}"`]);
|
||||
|
||||
@@ -443,7 +443,7 @@ class ProjectRunner extends RunnerBase {
|
||||
|
||||
const name = "Compiling project for " + testCase.scenario + ": testcase " + testCaseFileName;
|
||||
|
||||
describe("Projects tests", () => {
|
||||
describe("projects tests", () => {
|
||||
describe(name, () => {
|
||||
function verifyCompilerResults(moduleKind: ts.ModuleKind) {
|
||||
let compilerResult: BatchCompileProjectTestCaseResult;
|
||||
|
||||
@@ -82,7 +82,7 @@ let testConfigContent =
|
||||
|
||||
let taskConfigsFolder: string;
|
||||
let workerCount: number;
|
||||
let runUnitTests = true;
|
||||
let runUnitTests: boolean | undefined;
|
||||
let noColors = false;
|
||||
|
||||
interface TestConfig {
|
||||
@@ -108,9 +108,7 @@ function handleTestConfig() {
|
||||
if (testConfig.light) {
|
||||
Harness.lightMode = true;
|
||||
}
|
||||
if (testConfig.runUnitTests !== undefined) {
|
||||
runUnitTests = testConfig.runUnitTests;
|
||||
}
|
||||
runUnitTests = testConfig.runUnitTests;
|
||||
if (testConfig.workerCount) {
|
||||
workerCount = +testConfig.workerCount;
|
||||
}
|
||||
@@ -199,6 +197,9 @@ function handleTestConfig() {
|
||||
runners.push(new FourSlashRunner(FourSlashTestType.Server));
|
||||
// runners.push(new GeneratedFourslashRunner());
|
||||
}
|
||||
if (runUnitTests === undefined) {
|
||||
runUnitTests = runners.length !== 1; // Don't run unit tests when running only one runner if unit tests were not explicitly asked for
|
||||
}
|
||||
}
|
||||
|
||||
function beginTests() {
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace RWC {
|
||||
}
|
||||
|
||||
export function runRWCTest(jsonPath: string) {
|
||||
describe("Testing a RWC project: " + jsonPath, () => {
|
||||
describe("Testing a rwc project: " + jsonPath, () => {
|
||||
let inputFiles: Harness.Compiler.TestFile[] = [];
|
||||
let otherFiles: Harness.Compiler.TestFile[] = [];
|
||||
let tsconfigFiles: Harness.Compiler.TestFile[] = [];
|
||||
@@ -39,8 +39,6 @@ namespace RWC {
|
||||
const baseName = ts.getBaseFileName(jsonPath);
|
||||
let currentDirectory: string;
|
||||
let useCustomLibraryFile: boolean;
|
||||
let skipTypeAndSymbolbaselines = false;
|
||||
const typeAndSymbolSizeLimit = 10000000;
|
||||
after(() => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Therefore we have to clean out large objects after the test is done.
|
||||
@@ -54,7 +52,6 @@ namespace RWC {
|
||||
// or to use lib.d.ts inside the json object. If the flag is true, use the lib.d.ts inside json file
|
||||
// otherwise use the lib.d.ts from built/local
|
||||
useCustomLibraryFile = undefined;
|
||||
skipTypeAndSymbolbaselines = false;
|
||||
});
|
||||
|
||||
it("can compile", function(this: Mocha.ITestCallbackContext) {
|
||||
@@ -64,7 +61,6 @@ namespace RWC {
|
||||
const ioLog: IOLog = Playback.newStyleLogIntoOldStyleLog(JSON.parse(Harness.IO.readFile(`internal/cases/rwc/${jsonPath}/test.json`)), Harness.IO, `internal/cases/rwc/${baseName}`);
|
||||
currentDirectory = ioLog.currentDirectory;
|
||||
useCustomLibraryFile = ioLog.useCustomLibraryFile;
|
||||
skipTypeAndSymbolbaselines = ioLog.filesRead.reduce((acc, elem) => (elem && elem.result && elem.result.contents) ? acc + elem.result.contents.length : acc, 0) > typeAndSymbolSizeLimit;
|
||||
runWithIOLog(ioLog, () => {
|
||||
opts = ts.parseCommandLine(ioLog.arguments, fileName => Harness.IO.readFile(fileName));
|
||||
assert.equal(opts.errors.length, 0);
|
||||
@@ -199,14 +195,6 @@ namespace RWC {
|
||||
}, baselineOpts, [".map"]);
|
||||
});
|
||||
|
||||
/*it("has correct source map record", () => {
|
||||
if (compilerOptions.sourceMap) {
|
||||
Harness.Baseline.runBaseline(baseName + ".sourcemap.txt", () => {
|
||||
return compilerResult.getSourceMapRecord();
|
||||
}, baselineOpts);
|
||||
}
|
||||
});*/
|
||||
|
||||
it("has the expected errors", () => {
|
||||
Harness.Baseline.runMultifileBaseline(baseName, ".errors.txt", () => {
|
||||
if (compilerResult.errors.length === 0) {
|
||||
@@ -219,14 +207,6 @@ namespace RWC {
|
||||
}, baselineOpts);
|
||||
});
|
||||
|
||||
it("has the expected types", () => {
|
||||
// We don't need to pass the extension here because "doTypeAndSymbolBaseline" will append appropriate extension of ".types" or ".symbols"
|
||||
Harness.Compiler.doTypeAndSymbolBaseline(baseName, compilerResult.program, inputFiles
|
||||
.concat(otherFiles)
|
||||
.filter(file => !!compilerResult.program.getSourceFile(file.unitName))
|
||||
.filter(e => !Harness.isDefaultLibraryFile(e.unitName)), baselineOpts, /*multifile*/ true, skipTypeAndSymbolbaselines);
|
||||
});
|
||||
|
||||
// Ideally, a generated declaration file will have no errors. But we allow generated
|
||||
// declaration file errors as part of the baseline.
|
||||
it("has the expected errors in generated declaration files", () => {
|
||||
@@ -266,6 +246,7 @@ class RWCRunner extends RunnerBase {
|
||||
public initializeTests(): void {
|
||||
// Read in and evaluate the test list
|
||||
const testList = this.tests && this.tests.length ? this.tests : this.enumerateTestFiles();
|
||||
|
||||
for (let i = 0; i < testList.length; i++) {
|
||||
this.runTest(testList[i]);
|
||||
}
|
||||
|
||||
@@ -139,6 +139,7 @@
|
||||
"./unittests/telemetry.ts",
|
||||
"./unittests/languageService.ts",
|
||||
"./unittests/programMissingFiles.ts",
|
||||
"./unittests/publicApi.ts"
|
||||
"./unittests/publicApi.ts",
|
||||
"./unittests/hostNewLineSupport.ts"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class TypeWriterWalker {
|
||||
}
|
||||
|
||||
private *visitNode(node: ts.Node, isSymbolWalk: boolean): IterableIterator<TypeWriterResult> {
|
||||
if (ts.isPartOfExpression(node) || node.kind === ts.SyntaxKind.Identifier) {
|
||||
if (ts.isExpressionNode(node) || node.kind === ts.SyntaxKind.Identifier) {
|
||||
const result = this.writeTypeOrSymbol(node, isSymbolWalk);
|
||||
if (result) {
|
||||
yield result;
|
||||
@@ -101,8 +101,8 @@ class TypeWriterWalker {
|
||||
}
|
||||
count++;
|
||||
symbolString += ", ";
|
||||
if ((declaration as any)["__symbolTestOutputCache"]) {
|
||||
symbolString += (declaration as any)["__symbolTestOutputCache"];
|
||||
if ((declaration as any).__symbolTestOutputCache) {
|
||||
symbolString += (declaration as any).__symbolTestOutputCache;
|
||||
continue;
|
||||
}
|
||||
const declSourceFile = declaration.getSourceFile();
|
||||
@@ -111,7 +111,7 @@ class TypeWriterWalker {
|
||||
const isLibFile = /lib(.*)\.d\.ts/i.test(fileName);
|
||||
const declText = `Decl(${ fileName }, ${ isLibFile ? "--" : declLineAndCharacter.line }, ${ isLibFile ? "--" : declLineAndCharacter.character })`;
|
||||
symbolString += declText;
|
||||
(declaration as any)["__symbolTestOutputCache"] = declText;
|
||||
(declaration as any).__symbolTestOutputCache = declText;
|
||||
}
|
||||
}
|
||||
symbolString += ")";
|
||||
|
||||
@@ -46,15 +46,14 @@ namespace ts {
|
||||
function makeAssertChanges(getProgram: () => Program): (fileNames: ReadonlyArray<string>) => void {
|
||||
const builder = createBuilder({
|
||||
getCanonicalFileName: identity,
|
||||
getEmitOutput: getFileEmitOutput,
|
||||
computeHash: identity,
|
||||
shouldEmitFile: returnTrue,
|
||||
computeHash: identity
|
||||
});
|
||||
return fileNames => {
|
||||
const program = getProgram();
|
||||
builder.updateProgram(program);
|
||||
const changedFiles = builder.emitChangedFiles(program);
|
||||
assert.deepEqual(changedFileNames(changedFiles), fileNames);
|
||||
const outputFileNames: string[] = [];
|
||||
builder.emitChangedFiles(program, fileName => outputFileNames.push(fileName));
|
||||
assert.deepEqual(outputFileNames, fileNames);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -63,11 +62,4 @@ namespace ts {
|
||||
updateProgramText(files, fileName, fileContent);
|
||||
});
|
||||
}
|
||||
|
||||
function changedFileNames(changedFiles: ReadonlyArray<EmitOutputDetailed>): string[] {
|
||||
return changedFiles.map(f => {
|
||||
assert.lengthOf(f.outputFiles, 1);
|
||||
return f.outputFiles[0].name;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace ts.projectSystem {
|
||||
|
||||
describe("CompileOnSave affected list", () => {
|
||||
function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: FileOrFolder[] }[]) {
|
||||
const response: server.protocol.CompileOnSaveAffectedFileListSingleProject[] = session.executeCommand(request).response;
|
||||
const response = session.executeCommand(request).response as server.protocol.CompileOnSaveAffectedFileListSingleProject[];
|
||||
const actualResult = response.sort((list1, list2) => compareStrings(list1.projectFileName, list2.projectFileName));
|
||||
expectedFileList = expectedFileList.sort((list1, list2) => compareStrings(list1.projectFileName, list2.projectFileName));
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function assertCompilerOptionsWithJson(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const { options: actualCompilerOptions, errors: actualErrors} = convertCompilerOptionsFromJson(json["compilerOptions"], "/apath/", configFileName);
|
||||
const { options: actualCompilerOptions, errors: actualErrors} = convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName);
|
||||
|
||||
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
|
||||
const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions);
|
||||
@@ -33,7 +33,7 @@ namespace ts {
|
||||
assert(!!result.endOfFileToken);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost("/apath/", true, []);
|
||||
const { options: actualCompilerOptions, errors: actualParseErrors } = parseJsonSourceFileConfigFileContent(result, host, "/apath/", /*existingOptions*/ undefined, configFileName);
|
||||
expectedResult.compilerOptions["configFilePath"] = configFileName;
|
||||
expectedResult.compilerOptions.configFilePath = configFileName;
|
||||
|
||||
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
|
||||
const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions);
|
||||
@@ -421,6 +421,24 @@ namespace ts {
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert negative numbers in tsconfig.json ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"maxNodeModuleJsDepth": -1
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: {
|
||||
allowJs: true,
|
||||
maxNodeModuleJsDepth: -1
|
||||
},
|
||||
errors: []
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// jsconfig.json
|
||||
it("Convert correctly format jsconfig.json to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function assertTypeAcquisitionWithJson(json: any, configFileName: string, expectedResult: ExpectedResult) {
|
||||
const jsonOptions = json["typeAcquisition"] || json["typingOptions"];
|
||||
const jsonOptions = json.typeAcquisition || json.typingOptions;
|
||||
const { options: actualTypeAcquisition, errors: actualErrors } = convertTypeAcquisitionFromJson(jsonOptions, "/apath/", configFileName);
|
||||
verifyAcquisition(actualTypeAcquisition, expectedResult);
|
||||
verifyErrors(actualErrors, expectedResult);
|
||||
|
||||
@@ -195,12 +195,12 @@ namespace ts {
|
||||
function G<U extends T[]>(t2: U) {
|
||||
[#|t2.toString();|]
|
||||
}
|
||||
}`);
|
||||
}`, /*includeLib*/ true);
|
||||
// Confirm that the contextual type of an extracted expression counts as a use.
|
||||
testExtractFunction("extractFunction16",
|
||||
`function F<T>() {
|
||||
const array: T[] = [#|[]|];
|
||||
}`);
|
||||
}`, /*includeLib*/ true);
|
||||
// Class type parameter
|
||||
testExtractFunction("extractFunction17",
|
||||
`class C<T1, T2> {
|
||||
@@ -219,7 +219,7 @@ namespace ts {
|
||||
testExtractFunction("extractFunction19",
|
||||
`function F<T, U extends T[], V extends U[]>(v: V) {
|
||||
[#|v.toString()|];
|
||||
}`);
|
||||
}`, /*includeLib*/ true);
|
||||
|
||||
testExtractFunction("extractFunction20",
|
||||
`const _ = class {
|
||||
@@ -362,27 +362,32 @@ function parsePrimaryExpression(): any {
|
||||
}`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_Var", `
|
||||
[#|var x = 1;|]
|
||||
[#|var x = 1;
|
||||
"hello"|]
|
||||
x;
|
||||
`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_Let_Type", `
|
||||
[#|let x: number = 1;|]
|
||||
[#|let x: number = 1;
|
||||
"hello";|]
|
||||
x;
|
||||
`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_Let_NoType", `
|
||||
[#|let x = 1;|]
|
||||
[#|let x = 1;
|
||||
"hello";|]
|
||||
x;
|
||||
`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_Const_Type", `
|
||||
[#|const x: number = 1;|]
|
||||
[#|const x: number = 1;
|
||||
"hello";|]
|
||||
x;
|
||||
`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_Const_NoType", `
|
||||
[#|const x = 1;|]
|
||||
[#|const x = 1;
|
||||
"hello";|]
|
||||
x;
|
||||
`);
|
||||
|
||||
@@ -404,7 +409,8 @@ x; y; z;
|
||||
`);
|
||||
|
||||
testExtractFunction("extractFunction_VariableDeclaration_ConsumedTwice", `
|
||||
[#|const x: number = 1;|]
|
||||
[#|const x: number = 1;
|
||||
"hello";|]
|
||||
x; x;
|
||||
`);
|
||||
|
||||
@@ -542,7 +548,7 @@ var q = /*b*/ //c
|
||||
/*m*/; /*n*/ //o`);
|
||||
});
|
||||
|
||||
function testExtractFunction(caption: string, text: string) {
|
||||
testExtractSymbol(caption, text, "extractFunction", Diagnostics.Extract_function);
|
||||
function testExtractFunction(caption: string, text: string, includeLib?: boolean) {
|
||||
testExtractSymbol(caption, text, "extractFunction", Diagnostics.Extract_function, includeLib);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,6 +162,19 @@ namespace ts {
|
||||
}|]|]
|
||||
}
|
||||
`);
|
||||
|
||||
// Variable statements
|
||||
testExtractRange(`[#|let x = [$|1|];|]`);
|
||||
testExtractRange(`[#|let x = [$|1|], y;|]`);
|
||||
testExtractRange(`[#|[$|let x = 1, y = 1;|]|]`);
|
||||
|
||||
// Variable declarations
|
||||
testExtractRange(`let [#|x = [$|1|]|];`);
|
||||
testExtractRange(`let [#|x = [$|1|]|], y = 2;`);
|
||||
testExtractRange(`let x = 1, [#|y = [$|2|]|];`);
|
||||
|
||||
// Return statements
|
||||
testExtractRange(`[#|return [$|1|];|]`);
|
||||
});
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed1",
|
||||
@@ -340,6 +353,18 @@ switch (x) {
|
||||
refactor.extractSymbol.Messages.CannotExtractRangeContainingConditionalBreakOrContinueStatements.message
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed12",
|
||||
`let [#|x|];`,
|
||||
[
|
||||
refactor.extractSymbol.Messages.StatementOrExpressionExpected.message
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extractRangeFailed13",
|
||||
`[#|return;|]`,
|
||||
[
|
||||
refactor.extractSymbol.Messages.CannotExtractRange.message
|
||||
]);
|
||||
|
||||
testExtractRangeFailed("extract-method-not-for-token-expression-statement", `[#|a|]`, [refactor.extractSymbol.Messages.CannotExtractIdentifier.message]);
|
||||
});
|
||||
}
|
||||
@@ -67,7 +67,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export const newLineCharacter = "\n";
|
||||
export function getRuleProvider(action?: (opts: FormatCodeSettings) => void) {
|
||||
export const getRuleProvider = memoize(getRuleProviderInternal);
|
||||
function getRuleProviderInternal() {
|
||||
const options = {
|
||||
indentSize: 4,
|
||||
tabSize: 4,
|
||||
@@ -89,15 +90,21 @@ namespace ts {
|
||||
placeOpenBraceOnNewLineForFunctions: false,
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
if (action) {
|
||||
action(options);
|
||||
}
|
||||
const rulesProvider = new formatting.RulesProvider();
|
||||
rulesProvider.ensureUpToDate(options);
|
||||
return rulesProvider;
|
||||
}
|
||||
|
||||
export function testExtractSymbol(caption: string, text: string, baselineFolder: string, description: DiagnosticMessage) {
|
||||
const notImplementedHost: LanguageServiceHost = {
|
||||
getCompilationSettings: notImplemented,
|
||||
getScriptFileNames: notImplemented,
|
||||
getScriptVersion: notImplemented,
|
||||
getScriptSnapshot: notImplemented,
|
||||
getDefaultLibFileName: notImplemented,
|
||||
getCurrentDirectory: notImplemented,
|
||||
};
|
||||
|
||||
export function testExtractSymbol(caption: string, text: string, baselineFolder: string, description: DiagnosticMessage, includeLib?: boolean) {
|
||||
const t = extractTest(text);
|
||||
const selectionRange = t.ranges.get("selection");
|
||||
if (!selectionRange) {
|
||||
@@ -109,7 +116,7 @@ namespace ts {
|
||||
|
||||
function runBaseline(extension: Extension) {
|
||||
const path = "/a" + extension;
|
||||
const program = makeProgram({ path, content: t.source });
|
||||
const program = makeProgram({ path, content: t.source }, includeLib);
|
||||
|
||||
if (hasSyntacticDiagnostics(program)) {
|
||||
// Don't bother generating JS baselines for inputs that aren't valid JS.
|
||||
@@ -125,6 +132,7 @@ namespace ts {
|
||||
file: sourceFile,
|
||||
startPosition: selectionRange.start,
|
||||
endPosition: selectionRange.end,
|
||||
host: notImplementedHost,
|
||||
rulesProvider: getRuleProvider()
|
||||
};
|
||||
const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromBounds(selectionRange.start, selectionRange.end));
|
||||
@@ -144,15 +152,15 @@ namespace ts {
|
||||
const newTextWithRename = newText.slice(0, renameLocation) + "/*RENAME*/" + newText.slice(renameLocation);
|
||||
data.push(newTextWithRename);
|
||||
|
||||
const diagProgram = makeProgram({ path, content: newText });
|
||||
const diagProgram = makeProgram({ path, content: newText }, includeLib);
|
||||
assert.isFalse(hasSyntacticDiagnostics(diagProgram));
|
||||
}
|
||||
return data.join(newLineCharacter);
|
||||
});
|
||||
}
|
||||
|
||||
function makeProgram(f: {path: string, content: string }) {
|
||||
const host = projectSystem.createServerHost([f, projectSystem.libFile]);
|
||||
function makeProgram(f: {path: string, content: string }, includeLib?: boolean) {
|
||||
const host = projectSystem.createServerHost(includeLib ? [f, projectSystem.libFile] : [f]); // libFile is expensive to parse repeatedly - only test when required
|
||||
const projectService = projectSystem.createProjectService(host);
|
||||
projectService.openClientFile(f.path);
|
||||
const program = projectService.inferredProjects[0].getLanguageService().getProgram();
|
||||
@@ -188,6 +196,7 @@ namespace ts {
|
||||
file: sourceFile,
|
||||
startPosition: selectionRange.start,
|
||||
endPosition: selectionRange.end,
|
||||
host: notImplementedHost,
|
||||
rulesProvider: getRuleProvider()
|
||||
};
|
||||
const rangeToExtract = refactor.extractSymbol.getRangeToExtract(sourceFile, createTextSpanFromBounds(selectionRange.start, selectionRange.end));
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
namespace ts {
|
||||
describe("hostNewLineSupport", () => {
|
||||
function testLSWithFiles(settings: CompilerOptions, files: Harness.Compiler.TestFile[]) {
|
||||
function snapFor(path: string): IScriptSnapshot {
|
||||
if (path === "lib.d.ts") {
|
||||
return {
|
||||
dispose() {},
|
||||
getChangeRange() { return undefined; },
|
||||
getLength() { return 0; },
|
||||
getText(_start, _end) {
|
||||
return "";
|
||||
}
|
||||
};
|
||||
}
|
||||
const result = forEach(files, f => f.unitName === path ? f : undefined);
|
||||
if (result) {
|
||||
return {
|
||||
dispose() {},
|
||||
getChangeRange() { return undefined; },
|
||||
getLength() { return result.content.length; },
|
||||
getText(start, end) {
|
||||
return result.content.substring(start, end);
|
||||
}
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
const lshost: LanguageServiceHost = {
|
||||
getCompilationSettings: () => settings,
|
||||
getScriptFileNames: () => map(files, f => f.unitName),
|
||||
getScriptVersion: () => "1",
|
||||
getScriptSnapshot: name => snapFor(name),
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
getCurrentDirectory: () => "",
|
||||
};
|
||||
return ts.createLanguageService(lshost);
|
||||
}
|
||||
|
||||
function verifyNewLines(content: string, options: CompilerOptions) {
|
||||
const ls = testLSWithFiles(options, [{
|
||||
content,
|
||||
fileOptions: {},
|
||||
unitName: "input.ts"
|
||||
}]);
|
||||
const result = ls.getEmitOutput("input.ts");
|
||||
assert(!result.emitSkipped, "emit was skipped");
|
||||
assert(result.outputFiles.length === 1, "a number of files other than 1 was output");
|
||||
assert(result.outputFiles[0].name === "input.js", `Expected output file name input.js, but got ${result.outputFiles[0].name}`);
|
||||
assert(result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /\r\n/ : /[^\r]\n/), "expected to find appropriate newlines");
|
||||
assert(!result.outputFiles[0].text.match(options.newLine === NewLineKind.CarriageReturnLineFeed ? /[^\r]\n/ : /\r\n/), "expected not to find inappropriate newlines");
|
||||
}
|
||||
|
||||
function verifyBothNewLines(content: string) {
|
||||
verifyNewLines(content, { newLine: NewLineKind.CarriageReturnLineFeed });
|
||||
verifyNewLines(content, { newLine: NewLineKind.LineFeed });
|
||||
}
|
||||
|
||||
it("should exist and respect provided compiler options", () => {
|
||||
verifyBothNewLines(`
|
||||
function foo() {
|
||||
return 2 + 2;
|
||||
}
|
||||
`);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -57,7 +57,7 @@ namespace ts.projectSystem {
|
||||
});
|
||||
|
||||
checkNumberOfProjects(projectService, { externalProjects: 1 });
|
||||
const diags = session.executeCommand(compilerOptionsRequest).response;
|
||||
const diags = session.executeCommand(compilerOptionsRequest).response as server.protocol.DiagnosticWithLinePosition[];
|
||||
// only file1 exists - expect error
|
||||
checkDiagnosticsWithLinePos(diags, ["File '/a/b/applib.ts' not found."]);
|
||||
}
|
||||
@@ -65,7 +65,7 @@ namespace ts.projectSystem {
|
||||
{
|
||||
// only file2 exists - expect error
|
||||
checkNumberOfProjects(projectService, { externalProjects: 1 });
|
||||
const diags = session.executeCommand(compilerOptionsRequest).response;
|
||||
const diags = session.executeCommand(compilerOptionsRequest).response as server.protocol.DiagnosticWithLinePosition[];
|
||||
checkDiagnosticsWithLinePos(diags, ["File '/a/b/app.ts' not found."]);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace ts.projectSystem {
|
||||
{
|
||||
// both files exist - expect no errors
|
||||
checkNumberOfProjects(projectService, { externalProjects: 1 });
|
||||
const diags = session.executeCommand(compilerOptionsRequest).response;
|
||||
const diags = session.executeCommand(compilerOptionsRequest).response as server.protocol.DiagnosticWithLinePosition[];
|
||||
checkDiagnosticsWithLinePos(diags, []);
|
||||
}
|
||||
});
|
||||
@@ -103,13 +103,13 @@ namespace ts.projectSystem {
|
||||
seq: 2,
|
||||
arguments: { projectFileName: project.getProjectName() }
|
||||
};
|
||||
let diags = session.executeCommand(compilerOptionsRequest).response;
|
||||
let diags = session.executeCommand(compilerOptionsRequest).response as server.protocol.DiagnosticWithLinePosition[];
|
||||
checkDiagnosticsWithLinePos(diags, ["File '/a/b/applib.ts' not found."]);
|
||||
|
||||
host.reloadFS([file1, file2, config, libFile]);
|
||||
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
diags = session.executeCommand(compilerOptionsRequest).response;
|
||||
diags = session.executeCommand(compilerOptionsRequest).response as server.protocol.DiagnosticWithLinePosition[];
|
||||
checkDiagnosticsWithLinePos(diags, []);
|
||||
});
|
||||
|
||||
|
||||
@@ -53,6 +53,17 @@ namespace ts.server {
|
||||
return new TestSession(opts);
|
||||
}
|
||||
|
||||
// Disable sourcemap support for the duration of the test, as sourcemapping the errors generated during this test is slow and not something we care to test
|
||||
let oldPrepare: Function;
|
||||
before(() => {
|
||||
oldPrepare = (Error as any).prepareStackTrace;
|
||||
delete (Error as any).prepareStackTrace;
|
||||
});
|
||||
|
||||
after(() => {
|
||||
(Error as any).prepareStackTrace = oldPrepare;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
session = createSession();
|
||||
session.send = (msg: protocol.Message) => {
|
||||
@@ -315,7 +326,7 @@ namespace ts.server {
|
||||
item: false
|
||||
};
|
||||
const command = "newhandle";
|
||||
const result = {
|
||||
const result: ts.server.HandlerResponse = {
|
||||
response: respBody,
|
||||
responseRequired: true
|
||||
};
|
||||
@@ -332,7 +343,7 @@ namespace ts.server {
|
||||
const respBody = {
|
||||
item: false
|
||||
};
|
||||
const resp = {
|
||||
const resp: ts.server.HandlerResponse = {
|
||||
response: respBody,
|
||||
responseRequired: true
|
||||
};
|
||||
@@ -372,7 +383,7 @@ namespace ts.server {
|
||||
};
|
||||
const command = "test";
|
||||
|
||||
session.output(body, command);
|
||||
session.output(body, command, /*reqSeq*/ 0);
|
||||
|
||||
expect(lastSent).to.deep.equal({
|
||||
seq: 0,
|
||||
@@ -387,6 +398,18 @@ namespace ts.server {
|
||||
});
|
||||
|
||||
describe("exceptions", () => {
|
||||
|
||||
// Disable sourcemap support for the duration of the test, as sourcemapping the errors generated during this test is slow and not something we care to test
|
||||
let oldPrepare: Function;
|
||||
before(() => {
|
||||
oldPrepare = (Error as any).prepareStackTrace;
|
||||
delete (Error as any).prepareStackTrace;
|
||||
});
|
||||
|
||||
after(() => {
|
||||
(Error as any).prepareStackTrace = oldPrepare;
|
||||
});
|
||||
|
||||
const command = "testhandler";
|
||||
class TestSession extends Session {
|
||||
lastSent: protocol.Message;
|
||||
@@ -475,7 +498,7 @@ namespace ts.server {
|
||||
};
|
||||
const command = "test";
|
||||
|
||||
session.output(body, command);
|
||||
session.output(body, command, /*reqSeq*/ 0);
|
||||
|
||||
expect(session.lastSent).to.deep.equal({
|
||||
seq: 0,
|
||||
@@ -542,7 +565,7 @@ namespace ts.server {
|
||||
handleRequest(msg: protocol.Request) {
|
||||
let response: protocol.Response;
|
||||
try {
|
||||
({ response } = this.executeCommand(msg));
|
||||
response = this.executeCommand(msg).response as protocol.Response;
|
||||
}
|
||||
catch (e) {
|
||||
this.output(undefined, msg.command, msg.seq, e.toString());
|
||||
@@ -661,4 +684,28 @@ namespace ts.server {
|
||||
session.consumeQueue();
|
||||
});
|
||||
});
|
||||
|
||||
describe("helpers", () => {
|
||||
it(getLocationInNewDocument.name, () => {
|
||||
const text = `// blank line\nconst x = 0;`;
|
||||
const renameLocationInOldText = text.indexOf("0");
|
||||
const fileName = "/a.ts";
|
||||
const edits: ts.FileTextChanges = {
|
||||
fileName,
|
||||
textChanges: [
|
||||
{
|
||||
span: { start: 0, length: 0 },
|
||||
newText: "const newLocal = 0;\n\n",
|
||||
},
|
||||
{
|
||||
span: { start: renameLocationInOldText, length: 1 },
|
||||
newText: "newLocal",
|
||||
},
|
||||
],
|
||||
};
|
||||
const renameLocationInNewText = renameLocationInOldText + edits.textChanges[0].newText.length;
|
||||
const res = getLocationInNewDocument(text, fileName, renameLocationInNewText, [edits]);
|
||||
assert.deepEqual(res, { line: 4, offset: 11 });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace ts {
|
||||
const printerOptions = { newLine: NewLineKind.LineFeed };
|
||||
const newLineCharacter = getNewLineCharacter(printerOptions);
|
||||
|
||||
function getRuleProvider(action?: (opts: FormatCodeSettings) => void) {
|
||||
const getRuleProviderDefault = memoize(() => {
|
||||
const options = {
|
||||
indentSize: 4,
|
||||
tabSize: 4,
|
||||
@@ -45,12 +45,38 @@ namespace ts {
|
||||
placeOpenBraceOnNewLineForFunctions: false,
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
if (action) {
|
||||
action(options);
|
||||
}
|
||||
const rulesProvider = new formatting.RulesProvider();
|
||||
rulesProvider.ensureUpToDate(options);
|
||||
return rulesProvider;
|
||||
});
|
||||
const getRuleProviderNewlineBrace = memoize(() => {
|
||||
const options = {
|
||||
indentSize: 4,
|
||||
tabSize: 4,
|
||||
newLineCharacter,
|
||||
convertTabsToSpaces: true,
|
||||
indentStyle: ts.IndentStyle.Smart,
|
||||
insertSpaceAfterConstructor: false,
|
||||
insertSpaceAfterCommaDelimiter: true,
|
||||
insertSpaceAfterSemicolonInForStatements: true,
|
||||
insertSpaceBeforeAndAfterBinaryOperators: true,
|
||||
insertSpaceAfterKeywordsInControlFlowStatements: true,
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true,
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false,
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false,
|
||||
insertSpaceBeforeFunctionParenthesis: false,
|
||||
placeOpenBraceOnNewLineForFunctions: true,
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
};
|
||||
const rulesProvider = new formatting.RulesProvider();
|
||||
rulesProvider.ensureUpToDate(options);
|
||||
return rulesProvider;
|
||||
});
|
||||
function getRuleProvider(placeOpenBraceOnNewLineForFunctions: boolean) {
|
||||
return placeOpenBraceOnNewLineForFunctions ? getRuleProviderNewlineBrace() : getRuleProviderDefault();
|
||||
}
|
||||
|
||||
// validate that positions that were recovered from the printed text actually match positions that will be created if the same text is parsed.
|
||||
@@ -78,11 +104,11 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function runSingleFileTest(caption: string, setupFormatOptions: (opts: FormatCodeSettings) => void, text: string, validateNodes: boolean, testBlock: (sourceFile: SourceFile, changeTracker: textChanges.ChangeTracker) => void) {
|
||||
function runSingleFileTest(caption: string, placeOpenBraceOnNewLineForFunctions: boolean, text: string, validateNodes: boolean, testBlock: (sourceFile: SourceFile, changeTracker: textChanges.ChangeTracker) => void) {
|
||||
it(caption, () => {
|
||||
Harness.Baseline.runBaseline(`textChanges/${caption}.js`, () => {
|
||||
const sourceFile = createSourceFile("source.ts", text, ScriptTarget.ES2015, /*setParentNodes*/ true);
|
||||
const rulesProvider = getRuleProvider(setupFormatOptions);
|
||||
const rulesProvider = getRuleProvider(placeOpenBraceOnNewLineForFunctions);
|
||||
const changeTracker = new textChanges.ChangeTracker(printerOptions.newLine, rulesProvider, validateNodes ? verifyPositions : undefined);
|
||||
testBlock(sourceFile, changeTracker);
|
||||
const changes = changeTracker.getChanges();
|
||||
@@ -94,10 +120,6 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function setNewLineForOpenBraceInFunctions(opts: FormatCodeSettings) {
|
||||
opts.placeOpenBraceOnNewLineForFunctions = true;
|
||||
}
|
||||
|
||||
{
|
||||
const text = `
|
||||
namespace M
|
||||
@@ -120,7 +142,7 @@ namespace M
|
||||
}
|
||||
}
|
||||
}`;
|
||||
runSingleFileTest("extractMethodLike", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("extractMethodLike", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
const statements = (<Block>(<FunctionDeclaration>findChild("foo", sourceFile)).body).statements.slice(1);
|
||||
const newFunction = createFunctionDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
@@ -155,7 +177,7 @@ function bar() {
|
||||
return 2;
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("deleteRange1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteRange1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteRange(sourceFile, { pos: text.indexOf("function foo"), end: text.indexOf("function bar") });
|
||||
});
|
||||
}
|
||||
@@ -175,19 +197,19 @@ var x = 1; // some comment - 1
|
||||
var y = 2; // comment 3
|
||||
var z = 3; // comment 4
|
||||
`;
|
||||
runSingleFileTest("deleteNode1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNode1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNode2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNode2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedStartPosition: true });
|
||||
});
|
||||
runSingleFileTest("deleteNode3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNode3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedEndPosition: true });
|
||||
});
|
||||
runSingleFileTest("deleteNode4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNode4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findVariableStatementContaining("y", sourceFile), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
});
|
||||
runSingleFileTest("deleteNode5", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNode5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findVariableStatementContaining("x", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -201,18 +223,18 @@ var z = 3; // comment 5
|
||||
// comment 6
|
||||
var a = 4; // comment 7
|
||||
`;
|
||||
runSingleFileTest("deleteNodeRange1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeRange1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeRange2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeRange2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile),
|
||||
{ useNonAdjustedStartPosition: true });
|
||||
});
|
||||
runSingleFileTest("deleteNodeRange3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeRange3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile),
|
||||
{ useNonAdjustedEndPosition: true });
|
||||
});
|
||||
runSingleFileTest("deleteNodeRange4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeRange4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile),
|
||||
{ useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
});
|
||||
@@ -257,14 +279,14 @@ var y = 2; // comment 4
|
||||
var z = 3; // comment 5
|
||||
// comment 6
|
||||
var a = 4; // comment 7`;
|
||||
runSingleFileTest("replaceRange", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceRange", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceRange(sourceFile, { pos: text.indexOf("var y"), end: text.indexOf("var a") }, createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceRangeWithForcedIndentation", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceRangeWithForcedIndentation", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceRange(sourceFile, { pos: text.indexOf("var y"), end: text.indexOf("var a") }, createTestClass(), { suffix: newLineCharacter, indentation: 8, delta: 0 });
|
||||
});
|
||||
|
||||
runSingleFileTest("replaceRangeNoLineBreakBefore", setNewLineForOpenBraceInFunctions, `const x = 1, y = "2";`, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceRangeNoLineBreakBefore", /*placeOpenBraceOnNewLineForFunctions*/ true, `const x = 1, y = "2";`, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createTestVariableDeclaration("z1");
|
||||
changeTracker.replaceRange(sourceFile, { pos: sourceFile.text.indexOf("y"), end: sourceFile.text.indexOf(";") }, newNode);
|
||||
});
|
||||
@@ -275,7 +297,7 @@ namespace A {
|
||||
const x = 1, y = "2";
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("replaceNode1NoLineBreakBefore", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode1NoLineBreakBefore", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createTestVariableDeclaration("z1");
|
||||
changeTracker.replaceNode(sourceFile, findChild("y", sourceFile), newNode);
|
||||
});
|
||||
@@ -289,19 +311,19 @@ var y = 2; // comment 4
|
||||
var z = 3; // comment 5
|
||||
// comment 6
|
||||
var a = 4; // comment 7`;
|
||||
runSingleFileTest("replaceNode1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode1", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNode2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, suffix: newLineCharacter, prefix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNode3", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode3", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNode4", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode4", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
});
|
||||
runSingleFileTest("replaceNode5", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNode5", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNode(sourceFile, findVariableStatementContaining("x", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
});
|
||||
}
|
||||
@@ -314,16 +336,16 @@ var y = 2; // comment 4
|
||||
var z = 3; // comment 5
|
||||
// comment 6
|
||||
var a = 4; // comment 7`;
|
||||
runSingleFileTest("replaceNodeRange1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNodeRange1", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNodeRange2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNodeRange2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, suffix: newLineCharacter, prefix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNodeRange3", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNodeRange3", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedEndPosition: true, suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("replaceNodeRange4", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("replaceNodeRange4", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.replaceNodeRange(sourceFile, findVariableStatementContaining("y", sourceFile), findVariableStatementContaining("z", sourceFile), createTestClass(), { useNonAdjustedStartPosition: true, useNonAdjustedEndPosition: true });
|
||||
});
|
||||
}
|
||||
@@ -336,10 +358,10 @@ var y; // comment 4
|
||||
var z = 3; // comment 5
|
||||
// comment 6
|
||||
var a = 4; // comment 7`;
|
||||
runSingleFileTest("insertNodeAt1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAt1", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAt(sourceFile, text.indexOf("var y"), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("insertNodeAt2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAt2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAt(sourceFile, text.indexOf("; // comment 4"), createTestVariableDeclaration("z1"));
|
||||
});
|
||||
}
|
||||
@@ -354,16 +376,16 @@ namespace M {
|
||||
// comment 6
|
||||
var a = 4; // comment 7
|
||||
}`;
|
||||
runSingleFileTest("insertNodeBefore1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeBefore1", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeBefore(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("insertNodeBefore2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeBefore2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeBefore(sourceFile, findChild("M", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("insertNodeAfter1", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfter1", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("y", sourceFile), createTestClass(), { suffix: newLineCharacter });
|
||||
});
|
||||
runSingleFileTest("insertNodeAfter2", setNewLineForOpenBraceInFunctions, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfter2", /*placeOpenBraceOnNewLineForFunctions*/ true, text, /*validateNodes*/ true, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findChild("M", sourceFile), createTestClass(), { prefix: newLineCharacter });
|
||||
});
|
||||
}
|
||||
@@ -389,7 +411,7 @@ class A {
|
||||
}
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeAfter3", noop, text1, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfter3", /*placeOpenBraceOnNewLineForFunctions*/ false, text1, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findOpenBraceForConstructor(sourceFile), createTestSuperCall(), { suffix: newLineCharacter });
|
||||
});
|
||||
const text2 = `
|
||||
@@ -399,7 +421,7 @@ class A {
|
||||
}
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeAfter4", noop, text2, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfter4", /*placeOpenBraceOnNewLineForFunctions*/ false, text2, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("x", sourceFile), createTestSuperCall(), { suffix: newLineCharacter });
|
||||
});
|
||||
const text3 = `
|
||||
@@ -409,31 +431,31 @@ class A {
|
||||
}
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeAfter3-block with newline", noop, text3, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfter3-block with newline", /*placeOpenBraceOnNewLineForFunctions*/ false, text3, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findOpenBraceForConstructor(sourceFile), createTestSuperCall(), { suffix: newLineCharacter });
|
||||
});
|
||||
}
|
||||
{
|
||||
const text = `var a = 1, b = 2, c = 3;`;
|
||||
runSingleFileTest("deleteNodeInList1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
{
|
||||
const text = `var a = 1,b = 2,c = 3;`;
|
||||
runSingleFileTest("deleteNodeInList1_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList1_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList2_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList2_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList3_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList3_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -444,13 +466,13 @@ namespace M {
|
||||
b = 2,
|
||||
c = 3;
|
||||
}`;
|
||||
runSingleFileTest("deleteNodeInList4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList5", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList6", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList6", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -463,13 +485,13 @@ namespace M {
|
||||
// comment 4
|
||||
c = 3; // comment 5
|
||||
}`;
|
||||
runSingleFileTest("deleteNodeInList4_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList4_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList5_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList5_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList6_1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList6_1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -478,13 +500,13 @@ namespace M {
|
||||
function foo(a: number, b: string, c = true) {
|
||||
return 1;
|
||||
}`;
|
||||
runSingleFileTest("deleteNodeInList7", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList7", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList8", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList8", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList9", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList9", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -493,13 +515,13 @@ function foo(a: number, b: string, c = true) {
|
||||
function foo(a: number,b: string,c = true) {
|
||||
return 1;
|
||||
}`;
|
||||
runSingleFileTest("deleteNodeInList10", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList10", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList11", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList11", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList12", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList12", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -511,40 +533,40 @@ function foo(
|
||||
c = true) {
|
||||
return 1;
|
||||
}`;
|
||||
runSingleFileTest("deleteNodeInList13", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList13", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("a", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList14", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList14", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("b", sourceFile));
|
||||
});
|
||||
runSingleFileTest("deleteNodeInList15", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeInList15", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNodeInList(sourceFile, findChild("c", sourceFile));
|
||||
});
|
||||
}
|
||||
{
|
||||
const text = `
|
||||
const x = 1, y = 2;`;
|
||||
runSingleFileTest("insertNodeInListAfter1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
runSingleFileTest("insertNodeInListAfter2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
}
|
||||
{
|
||||
const text = `
|
||||
const /*x*/ x = 1, /*y*/ y = 2;`;
|
||||
runSingleFileTest("insertNodeInListAfter3", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter3", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
runSingleFileTest("insertNodeInListAfter4", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter4", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
}
|
||||
{
|
||||
const text = `
|
||||
const x = 1;`;
|
||||
runSingleFileTest("insertNodeInListAfter5", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter5", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
}
|
||||
@@ -552,10 +574,10 @@ const x = 1;`;
|
||||
const text = `
|
||||
const x = 1,
|
||||
y = 2;`;
|
||||
runSingleFileTest("insertNodeInListAfter6", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter6", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
runSingleFileTest("insertNodeInListAfter7", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter7", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
}
|
||||
@@ -563,10 +585,10 @@ const x = 1,
|
||||
const text = `
|
||||
const /*x*/ x = 1,
|
||||
/*y*/ y = 2;`;
|
||||
runSingleFileTest("insertNodeInListAfter8", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter8", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
runSingleFileTest("insertNodeInListAfter9", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter9", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("y", sourceFile), createVariableDeclaration("z", /*type*/ undefined, createLiteral(1)));
|
||||
});
|
||||
}
|
||||
@@ -575,7 +597,7 @@ const /*x*/ x = 1,
|
||||
import {
|
||||
x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter10", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter10", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -584,7 +606,7 @@ import {
|
||||
import {
|
||||
x // this is x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter11", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter11", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -593,7 +615,7 @@ import {
|
||||
import {
|
||||
x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter12", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter12", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -602,7 +624,7 @@ import {
|
||||
import {
|
||||
x // this is x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter13", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter13", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -612,7 +634,7 @@ import {
|
||||
x0,
|
||||
x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter14", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter14", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -622,7 +644,7 @@ import {
|
||||
x0,
|
||||
x // this is x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter15", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter15", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(createIdentifier("b"), createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -632,7 +654,7 @@ import {
|
||||
x0,
|
||||
x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter16", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter16", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -642,7 +664,7 @@ import {
|
||||
x0,
|
||||
x // this is x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter17", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter17", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -651,7 +673,7 @@ import {
|
||||
import {
|
||||
x0, x
|
||||
} from "bar"`;
|
||||
runSingleFileTest("insertNodeInListAfter18", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInListAfter18", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeInListAfter(sourceFile, findChild("x", sourceFile), createImportSpecifier(undefined, createIdentifier("a")));
|
||||
});
|
||||
}
|
||||
@@ -660,7 +682,7 @@ import {
|
||||
class A {
|
||||
x;
|
||||
}`;
|
||||
runSingleFileTest("insertNodeAfterMultipleNodes", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfterMultipleNodes", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNodes = [];
|
||||
for (let i = 0; i < 11 /*error doesn't occur with fewer nodes*/; ++i) {
|
||||
newNodes.push(
|
||||
@@ -678,7 +700,7 @@ class A {
|
||||
x
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeAfterInClass1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfterInClass1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), createProperty(undefined, undefined, "a", undefined, createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined), { suffix: newLineCharacter });
|
||||
});
|
||||
}
|
||||
@@ -688,7 +710,7 @@ class A {
|
||||
x;
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeAfterInClass2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeAfterInClass2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.insertNodeAfter(sourceFile, findChild("x", sourceFile), createProperty(undefined, undefined, "a", undefined, createKeywordTypeNode(SyntaxKind.BooleanKeyword), undefined), { suffix: newLineCharacter });
|
||||
});
|
||||
}
|
||||
@@ -699,7 +721,7 @@ class A {
|
||||
y = 1;
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("deleteNodeAfterInClass1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeAfterInClass1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findChild("x", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -710,7 +732,7 @@ class A {
|
||||
y = 1;
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("deleteNodeAfterInClass2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("deleteNodeAfterInClass2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
changeTracker.deleteNode(sourceFile, findChild("x", sourceFile));
|
||||
});
|
||||
}
|
||||
@@ -720,7 +742,7 @@ class A {
|
||||
x = foo
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
@@ -738,7 +760,7 @@ class A {
|
||||
}
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInClassAfterNodeWithoutSeparator2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
@@ -755,7 +777,7 @@ interface A {
|
||||
x
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
@@ -772,7 +794,7 @@ interface A {
|
||||
x()
|
||||
}
|
||||
`;
|
||||
runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator2", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInInterfaceAfterNodeWithoutSeparator2", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createProperty(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
@@ -787,7 +809,7 @@ interface A {
|
||||
const text = `
|
||||
let x = foo
|
||||
`;
|
||||
runSingleFileTest("insertNodeInStatementListAfterNodeWithoutSeparator1", noop, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
runSingleFileTest("insertNodeInStatementListAfterNodeWithoutSeparator1", /*placeOpenBraceOnNewLineForFunctions*/ false, text, /*validateNodes*/ false, (sourceFile, changeTracker) => {
|
||||
const newNode = createStatement(createParen(createLiteral(1)));
|
||||
changeTracker.insertNodeAfter(sourceFile, findVariableStatementContaining("x", sourceFile), newNode, { suffix: newLineCharacter });
|
||||
});
|
||||
|
||||
@@ -80,9 +80,9 @@ namespace ts.tscWatch {
|
||||
checkOutputDoesNotContain(host, expectedNonAffectedFiles);
|
||||
}
|
||||
|
||||
function checkOutputErrors(host: WatchedSystem, errors?: ReadonlyArray<Diagnostic>, isInitial?: true, skipWaiting?: true) {
|
||||
function checkOutputErrors(host: WatchedSystem, errors: ReadonlyArray<Diagnostic>, isInitial?: true, skipWaiting?: true) {
|
||||
const outputs = host.getOutput();
|
||||
const expectedOutputCount = (isInitial ? 0 : 1) + (errors ? errors.length : 0) + (skipWaiting ? 0 : 1);
|
||||
const expectedOutputCount = (isInitial ? 0 : 1) + errors.length + (skipWaiting ? 0 : 1);
|
||||
assert.equal(outputs.length, expectedOutputCount, "Outputs = " + outputs.toString());
|
||||
let index = 0;
|
||||
if (!isInitial) {
|
||||
@@ -254,7 +254,7 @@ namespace ts.tscWatch {
|
||||
checkProgramRootFiles(watch(), [file1.path, file2.path]);
|
||||
checkWatchedFiles(host, [configFile.path, file1.path, file2.path, libFile.path]);
|
||||
const configDir = getDirectoryPath(configFile.path);
|
||||
checkWatchedDirectories(host, projectSystem.getTypeRootsFromLocation(configDir).concat(configDir), /*recursive*/ true);
|
||||
checkWatchedDirectories(host, [configDir, combinePaths(configDir, projectSystem.nodeModulesAtTypes)], /*recursive*/ true);
|
||||
});
|
||||
|
||||
// TODO: if watching for config file creation
|
||||
@@ -269,7 +269,7 @@ namespace ts.tscWatch {
|
||||
const host = createWatchedSystem([commonFile1, libFile, configFile]);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
const configDir = getDirectoryPath(configFile.path);
|
||||
checkWatchedDirectories(host, projectSystem.getTypeRootsFromLocation(configDir).concat(configDir), /*recursive*/ true);
|
||||
checkWatchedDirectories(host, [configDir, combinePaths(configDir, projectSystem.nodeModulesAtTypes)], /*recursive*/ true);
|
||||
|
||||
checkProgramRootFiles(watch(), [commonFile1.path]);
|
||||
|
||||
@@ -339,7 +339,7 @@ namespace ts.tscWatch {
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkProgramRootFiles(watch(), [file1.path]);
|
||||
checkProgramActualFiles(watch(), [file1.path, libFile.path, commonFile2.path]);
|
||||
checkOutputErrors(host);
|
||||
checkOutputErrors(host, emptyArray);
|
||||
});
|
||||
|
||||
it("should reflect change in config file", () => {
|
||||
@@ -792,7 +792,7 @@ namespace ts.tscWatch {
|
||||
moduleFile.path = moduleFileOldPath;
|
||||
host.reloadFS([moduleFile, file1, libFile]);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkOutputErrors(host);
|
||||
checkOutputErrors(host, emptyArray);
|
||||
});
|
||||
|
||||
it("rename a module file and rename back should restore the states for configured projects", () => {
|
||||
@@ -824,7 +824,7 @@ namespace ts.tscWatch {
|
||||
moduleFile.path = moduleFileOldPath;
|
||||
host.reloadFS([moduleFile, file1, configFile, libFile]);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkOutputErrors(host);
|
||||
checkOutputErrors(host, emptyArray);
|
||||
});
|
||||
|
||||
it("types should load from config file path if config exists", () => {
|
||||
@@ -867,7 +867,7 @@ namespace ts.tscWatch {
|
||||
|
||||
host.reloadFS([file1, moduleFile, libFile]);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkOutputErrors(host);
|
||||
checkOutputErrors(host, emptyArray);
|
||||
});
|
||||
|
||||
it("Configure file diagnostics events are generated when the config file has errors", () => {
|
||||
@@ -942,7 +942,7 @@ namespace ts.tscWatch {
|
||||
}`;
|
||||
host.reloadFS([file, configFile, libFile]);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkOutputErrors(host);
|
||||
checkOutputErrors(host, emptyArray);
|
||||
});
|
||||
|
||||
it("non-existing directories listed in config file input array should be tolerated without crashing the server", () => {
|
||||
@@ -1105,6 +1105,64 @@ namespace ts.tscWatch {
|
||||
const outJs = "/a/out.js";
|
||||
createWatchForOut(/*out*/ undefined, outJs);
|
||||
});
|
||||
|
||||
function verifyFilesEmittedOnce(useOutFile: boolean) {
|
||||
const file1: FileOrFolder = {
|
||||
path: "/a/b/output/AnotherDependency/file1.d.ts",
|
||||
content: "declare namespace Common.SomeComponent.DynamicMenu { enum Z { Full = 0, Min = 1, Average = 2, } }"
|
||||
};
|
||||
const file2: FileOrFolder = {
|
||||
path: "/a/b/dependencies/file2.d.ts",
|
||||
content: "declare namespace Dependencies.SomeComponent { export class SomeClass { version: string; } }"
|
||||
};
|
||||
const file3: FileOrFolder = {
|
||||
path: "/a/b/project/src/main.ts",
|
||||
content: "namespace Main { export function fooBar() {} }"
|
||||
};
|
||||
const file4: FileOrFolder = {
|
||||
path: "/a/b/project/src/main2.ts",
|
||||
content: "namespace main.file4 { import DynamicMenu = Common.SomeComponent.DynamicMenu; export function foo(a: DynamicMenu.z) { } }"
|
||||
};
|
||||
const configFile: FileOrFolder = {
|
||||
path: "/a/b/project/tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: useOutFile ?
|
||||
{ outFile: "../output/common.js", target: "es5" } :
|
||||
{ outDir: "../output", target: "es5" },
|
||||
files: [file1.path, file2.path, file3.path, file4.path]
|
||||
})
|
||||
};
|
||||
const files = [file1, file2, file3, file4];
|
||||
const allfiles = files.concat(configFile);
|
||||
const host = createWatchedSystem(allfiles);
|
||||
const originalWriteFile = host.writeFile.bind(host);
|
||||
const mapOfFilesWritten = createMap<number>();
|
||||
host.writeFile = (p: string, content: string) => {
|
||||
const count = mapOfFilesWritten.get(p);
|
||||
mapOfFilesWritten.set(p, count ? count + 1 : 1);
|
||||
return originalWriteFile(p, content);
|
||||
};
|
||||
createWatchModeWithConfigFile(configFile.path, host);
|
||||
if (useOutFile) {
|
||||
// Only out file
|
||||
assert.equal(mapOfFilesWritten.size, 1);
|
||||
}
|
||||
else {
|
||||
// main.js and main2.js
|
||||
assert.equal(mapOfFilesWritten.size, 2);
|
||||
}
|
||||
mapOfFilesWritten.forEach((value, key) => {
|
||||
assert.equal(value, 1, "Key: " + key);
|
||||
});
|
||||
}
|
||||
|
||||
it("with --outFile and multiple declaration files in the program", () => {
|
||||
verifyFilesEmittedOnce(/*useOutFile*/ true);
|
||||
});
|
||||
|
||||
it("without --outFile and multiple declaration files in the program", () => {
|
||||
verifyFilesEmittedOnce(/*useOutFile*/ false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsc-watch emit for configured projects", () => {
|
||||
@@ -1687,7 +1745,7 @@ namespace ts.tscWatch {
|
||||
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called.");
|
||||
checkOutputErrors(host);
|
||||
checkOutputErrors(host, emptyArray);
|
||||
});
|
||||
|
||||
it("should compile correctly when resolved module goes missing and then comes back (module is not part of the root)", () => {
|
||||
@@ -1733,7 +1791,7 @@ namespace ts.tscWatch {
|
||||
host.reloadFS(filesWithImported);
|
||||
host.checkTimeoutQueueLengthAndRun(1);
|
||||
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called.");
|
||||
checkOutputErrors(host);
|
||||
checkOutputErrors(host, emptyArray);
|
||||
});
|
||||
|
||||
it("works when module resolution changes to ambient module", () => {
|
||||
@@ -1773,7 +1831,7 @@ declare module "fs" {
|
||||
|
||||
host.reloadFS(filesWithNodeType);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkOutputErrors(host);
|
||||
checkOutputErrors(host, emptyArray);
|
||||
});
|
||||
|
||||
it("works when included file with ambient module changes", () => {
|
||||
@@ -1816,7 +1874,127 @@ declare module "fs" {
|
||||
file.content += fileContentWithFS;
|
||||
host.reloadFS(files);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkOutputErrors(host);
|
||||
checkOutputErrors(host, emptyArray);
|
||||
});
|
||||
|
||||
it("works when reusing program with files from external library", () => {
|
||||
interface ExpectedFile { path: string; isExpectedToEmit?: boolean; content?: string; }
|
||||
const configDir = "/a/b/projects/myProject/src/";
|
||||
const file1: FileOrFolder = {
|
||||
path: configDir + "file1.ts",
|
||||
content: 'import module1 = require("module1");\nmodule1("hello");'
|
||||
};
|
||||
const file2: FileOrFolder = {
|
||||
path: configDir + "file2.ts",
|
||||
content: 'import module11 = require("module1");\nmodule11("hello");'
|
||||
};
|
||||
const module1: FileOrFolder = {
|
||||
path: "/a/b/projects/myProject/node_modules/module1/index.js",
|
||||
content: "module.exports = options => { return options.toString(); }"
|
||||
};
|
||||
const configFile: FileOrFolder = {
|
||||
path: configDir + "tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {
|
||||
allowJs: true,
|
||||
rootDir: ".",
|
||||
outDir: "../dist",
|
||||
moduleResolution: "node",
|
||||
maxNodeModuleJsDepth: 1
|
||||
}
|
||||
})
|
||||
};
|
||||
const outDirFolder = "/a/b/projects/myProject/dist/";
|
||||
const programFiles = [file1, file2, module1, libFile];
|
||||
const host = createWatchedSystem(programFiles.concat(configFile), { currentDirectory: "/a/b/projects/myProject/" });
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
checkProgramActualFiles(watch(), programFiles.map(f => f.path));
|
||||
checkOutputErrors(host, emptyArray, /*isInitial*/ true);
|
||||
const expectedFiles: ExpectedFile[] = [
|
||||
createExpectedEmittedFile(file1),
|
||||
createExpectedEmittedFile(file2),
|
||||
createExpectedToNotEmitFile("index.js"),
|
||||
createExpectedToNotEmitFile("src/index.js"),
|
||||
createExpectedToNotEmitFile("src/file1.js"),
|
||||
createExpectedToNotEmitFile("src/file2.js"),
|
||||
createExpectedToNotEmitFile("lib.js"),
|
||||
createExpectedToNotEmitFile("lib.d.ts")
|
||||
];
|
||||
verifyExpectedFiles(expectedFiles);
|
||||
|
||||
file1.content += "\n;";
|
||||
expectedFiles[0].content += ";\n"; // Only emit file1 with this change
|
||||
expectedFiles[1].isExpectedToEmit = false;
|
||||
host.reloadFS(programFiles.concat(configFile));
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkProgramActualFiles(watch(), programFiles.map(f => f.path));
|
||||
checkOutputErrors(host, emptyArray);
|
||||
verifyExpectedFiles(expectedFiles);
|
||||
|
||||
|
||||
function verifyExpectedFiles(expectedFiles: ExpectedFile[]) {
|
||||
forEach(expectedFiles, f => {
|
||||
assert.equal(!!host.fileExists(f.path), f.isExpectedToEmit, "File " + f.path + " is expected to " + (f.isExpectedToEmit ? "emit" : "not emit"));
|
||||
if (f.isExpectedToEmit) {
|
||||
assert.equal(host.readFile(f.path), f.content, "Expected contents of " + f.path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createExpectedToNotEmitFile(fileName: string): ExpectedFile {
|
||||
return {
|
||||
path: outDirFolder + fileName,
|
||||
isExpectedToEmit: false
|
||||
};
|
||||
}
|
||||
|
||||
function createExpectedEmittedFile(file: FileOrFolder): ExpectedFile {
|
||||
return {
|
||||
path: removeFileExtension(file.path.replace(configDir, outDirFolder)) + Extension.Js,
|
||||
isExpectedToEmit: true,
|
||||
content: '"use strict";\nexports.__esModule = true;\n' + file.content.replace("import", "var") + "\n"
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsc-watch with when module emit is specified as node", () => {
|
||||
it("when instead of filechanged recursive directory watcher is invoked", () => {
|
||||
const configFile: FileOrFolder = {
|
||||
path: "/a/rootFolder/project/tsconfig.json",
|
||||
content: JSON.stringify({
|
||||
"compilerOptions": {
|
||||
"module": "none",
|
||||
"allowJs": true,
|
||||
"outDir": "Static/scripts/"
|
||||
},
|
||||
"include": [
|
||||
"Scripts/**/*"
|
||||
],
|
||||
})
|
||||
};
|
||||
const outputFolder = "/a/rootFolder/project/Static/scripts/";
|
||||
const file1: FileOrFolder = {
|
||||
path: "/a/rootFolder/project/Scripts/TypeScript.ts",
|
||||
content: "var z = 10;"
|
||||
};
|
||||
const file2: FileOrFolder = {
|
||||
path: "/a/rootFolder/project/Scripts/Javascript.js",
|
||||
content: "var zz = 10;"
|
||||
};
|
||||
const files = [configFile, file1, file2, libFile];
|
||||
const host = createWatchedSystem(files);
|
||||
const watch = createWatchModeWithConfigFile(configFile.path, host);
|
||||
|
||||
checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path));
|
||||
file1.content = "var zz30 = 100;";
|
||||
host.reloadFS(files, /*invokeDirectoryWatcherInsteadOfFileChanged*/ true);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
checkProgramActualFiles(watch(), mapDefined(files, f => f === configFile ? undefined : f.path));
|
||||
const outputFile1 = changeExtension((outputFolder + getBaseFileName(file1.path)), ".js");
|
||||
assert.isTrue(host.fileExists(outputFile1));
|
||||
assert.equal(host.readFile(outputFile1), file1.content + host.newLine);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -4,6 +4,8 @@
|
||||
|
||||
namespace ts.projectSystem {
|
||||
import TI = server.typingsInstaller;
|
||||
import validatePackageName = JsTyping.validatePackageName;
|
||||
import PackageNameValidationResult = JsTyping.PackageNameValidationResult;
|
||||
|
||||
interface InstallerParams {
|
||||
globalTypingsCacheLocation?: string;
|
||||
@@ -266,7 +268,7 @@ namespace ts.projectSystem {
|
||||
};
|
||||
const host = createServerHost([file1]);
|
||||
let enqueueIsCalled = false;
|
||||
const installer = new (class extends Installer {
|
||||
const installer: Installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { typesRegistry: createTypesRegistry("jquery") });
|
||||
}
|
||||
@@ -983,21 +985,21 @@ namespace ts.projectSystem {
|
||||
for (let i = 0; i < 8; i++) {
|
||||
packageName += packageName;
|
||||
}
|
||||
assert.equal(TI.validatePackageName(packageName), TI.PackageNameValidationResult.NameTooLong);
|
||||
assert.equal(validatePackageName(packageName), PackageNameValidationResult.NameTooLong);
|
||||
});
|
||||
it("name cannot start with dot", () => {
|
||||
assert.equal(TI.validatePackageName(".foo"), TI.PackageNameValidationResult.NameStartsWithDot);
|
||||
assert.equal(validatePackageName(".foo"), PackageNameValidationResult.NameStartsWithDot);
|
||||
});
|
||||
it("name cannot start with underscore", () => {
|
||||
assert.equal(TI.validatePackageName("_foo"), TI.PackageNameValidationResult.NameStartsWithUnderscore);
|
||||
assert.equal(validatePackageName("_foo"), PackageNameValidationResult.NameStartsWithUnderscore);
|
||||
});
|
||||
it("scoped packages not supported", () => {
|
||||
assert.equal(TI.validatePackageName("@scope/bar"), TI.PackageNameValidationResult.ScopedPackagesNotSupported);
|
||||
assert.equal(validatePackageName("@scope/bar"), PackageNameValidationResult.ScopedPackagesNotSupported);
|
||||
});
|
||||
it("non URI safe characters are not supported", () => {
|
||||
assert.equal(TI.validatePackageName(" scope "), TI.PackageNameValidationResult.NameContainsNonURISafeCharacters);
|
||||
assert.equal(TI.validatePackageName("; say ‘Hello from TypeScript!’ #"), TI.PackageNameValidationResult.NameContainsNonURISafeCharacters);
|
||||
assert.equal(TI.validatePackageName("a/b/c"), TI.PackageNameValidationResult.NameContainsNonURISafeCharacters);
|
||||
assert.equal(validatePackageName(" scope "), PackageNameValidationResult.NameContainsNonURISafeCharacters);
|
||||
assert.equal(validatePackageName("; say ‘Hello from TypeScript!’ #"), PackageNameValidationResult.NameContainsNonURISafeCharacters);
|
||||
assert.equal(validatePackageName("a/b/c"), PackageNameValidationResult.NameContainsNonURISafeCharacters);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1250,7 +1252,7 @@ namespace ts.projectSystem {
|
||||
const host = createServerHost([f1, packageFile]);
|
||||
let beginEvent: server.BeginInstallTypes;
|
||||
let endEvent: server.EndInstallTypes;
|
||||
const installer = new (class extends Installer {
|
||||
const installer: Installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: cachePath, typesRegistry: createTypesRegistry("commander") });
|
||||
}
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
/// <reference path="harness.ts" />
|
||||
|
||||
namespace ts.TestFSWithWatch {
|
||||
const { content: libFileContent } = Harness.getDefaultLibraryFile(Harness.IO);
|
||||
export const libFile: FileOrFolder = {
|
||||
path: "/a/lib/lib.d.ts",
|
||||
content: libFileContent
|
||||
content: `/// <reference no-default-lib="true"/>
|
||||
interface Boolean {}
|
||||
interface Function {}
|
||||
interface IArguments {}
|
||||
interface Number { toExponential: any; }
|
||||
interface Object {}
|
||||
interface RegExp {}
|
||||
interface String { charAt: any; }
|
||||
interface Array<T> {}`
|
||||
};
|
||||
|
||||
export const safeList = {
|
||||
@@ -28,6 +35,7 @@ namespace ts.TestFSWithWatch {
|
||||
executingFilePath?: string;
|
||||
currentDirectory?: string;
|
||||
newLine?: string;
|
||||
useWindowsStylePaths?: boolean;
|
||||
}
|
||||
|
||||
export function createWatchedSystem(fileOrFolderList: ReadonlyArray<FileOrFolder>, params?: TestServerHostCreationParameters): TestServerHost {
|
||||
@@ -39,7 +47,8 @@ namespace ts.TestFSWithWatch {
|
||||
params.executingFilePath || getExecutingFilePathFromLibFile(),
|
||||
params.currentDirectory || "/",
|
||||
fileOrFolderList,
|
||||
params.newLine);
|
||||
params.newLine,
|
||||
params.useWindowsStylePaths);
|
||||
return host;
|
||||
}
|
||||
|
||||
@@ -52,7 +61,8 @@ namespace ts.TestFSWithWatch {
|
||||
params.executingFilePath || getExecutingFilePathFromLibFile(),
|
||||
params.currentDirectory || "/",
|
||||
fileOrFolderList,
|
||||
params.newLine);
|
||||
params.newLine,
|
||||
params.useWindowsStylePaths);
|
||||
return host;
|
||||
}
|
||||
|
||||
@@ -230,11 +240,14 @@ namespace ts.TestFSWithWatch {
|
||||
readonly watchedDirectories = createMultiMap<TestDirectoryWatcher>();
|
||||
readonly watchedDirectoriesRecursive = createMultiMap<TestDirectoryWatcher>();
|
||||
readonly watchedFiles = createMultiMap<TestFileWatcher>();
|
||||
private readonly executingFilePath: string;
|
||||
private readonly currentDirectory: string;
|
||||
|
||||
constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, private executingFilePath: string, private currentDirectory: string, fileOrFolderList: ReadonlyArray<FileOrFolder>, public readonly newLine = "\n") {
|
||||
constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, executingFilePath: string, currentDirectory: string, fileOrFolderList: ReadonlyArray<FileOrFolder>, public readonly newLine = "\n", public readonly useWindowsStylePath?: boolean) {
|
||||
this.getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
this.toPath = s => toPath(s, currentDirectory, this.getCanonicalFileName);
|
||||
|
||||
this.executingFilePath = this.getHostSpecificPath(executingFilePath);
|
||||
this.currentDirectory = this.getHostSpecificPath(currentDirectory);
|
||||
this.reloadFS(fileOrFolderList);
|
||||
}
|
||||
|
||||
@@ -250,11 +263,24 @@ namespace ts.TestFSWithWatch {
|
||||
return this.toPath(this.toNormalizedAbsolutePath(s));
|
||||
}
|
||||
|
||||
reloadFS(fileOrFolderList: ReadonlyArray<FileOrFolder>) {
|
||||
getHostSpecificPath(s: string) {
|
||||
if (this.useWindowsStylePath && s.startsWith(directorySeparator)) {
|
||||
return "c:/" + s.substring(1);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
reloadFS(fileOrFolderList: ReadonlyArray<FileOrFolder>, invokeDirectoryWatcherInsteadOfFileChanged?: boolean) {
|
||||
const mapNewLeaves = createMap<true>();
|
||||
const isNewFs = this.fs.size === 0;
|
||||
// always inject safelist file in the list of files
|
||||
for (const fileOrDirectory of fileOrFolderList.concat(this.withSafeList ? safeList : [])) {
|
||||
fileOrFolderList = fileOrFolderList.concat(this.withSafeList ? safeList : []);
|
||||
const filesOrFoldersToLoad: ReadonlyArray<FileOrFolder> = !this.useWindowsStylePath ? fileOrFolderList :
|
||||
fileOrFolderList.map<FileOrFolder>(f => {
|
||||
const result = clone(f);
|
||||
result.path = this.getHostSpecificPath(f.path);
|
||||
return result;
|
||||
});
|
||||
for (const fileOrDirectory of filesOrFoldersToLoad) {
|
||||
const path = this.toFullPath(fileOrDirectory.path);
|
||||
mapNewLeaves.set(path, true);
|
||||
// If its a change
|
||||
@@ -265,7 +291,12 @@ namespace ts.TestFSWithWatch {
|
||||
// Update file
|
||||
if (currentEntry.content !== fileOrDirectory.content) {
|
||||
currentEntry.content = fileOrDirectory.content;
|
||||
this.invokeFileWatcher(currentEntry.fullPath, FileWatcherEventKind.Changed);
|
||||
if (invokeDirectoryWatcherInsteadOfFileChanged) {
|
||||
this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath);
|
||||
}
|
||||
else {
|
||||
this.invokeFileWatcher(currentEntry.fullPath, FileWatcherEventKind.Changed);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
Vendored
+384
-1
File diff suppressed because it is too large
Load Diff
Vendored
+40
-2
@@ -443,6 +443,8 @@ interface FileReader extends EventTarget, MSBaseReader {
|
||||
readAsText(blob: Blob, encoding?: string): void;
|
||||
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var FileReader: {
|
||||
@@ -525,6 +527,8 @@ interface IDBDatabase extends EventTarget {
|
||||
addEventListener(type: "versionchange", listener: (ev: IDBVersionChangeEvent) => any, useCapture?: boolean): void;
|
||||
addEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof IDBDatabaseEventMap>(type: K, listener: (this: IDBDatabase, ev: IDBDatabaseEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var IDBDatabase: {
|
||||
@@ -610,6 +614,8 @@ interface IDBOpenDBRequest extends IDBRequest {
|
||||
onupgradeneeded: (this: IDBOpenDBRequest, ev: IDBVersionChangeEvent) => any;
|
||||
addEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof IDBOpenDBRequestEventMap>(type: K, listener: (this: IDBOpenDBRequest, ev: IDBOpenDBRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var IDBOpenDBRequest: {
|
||||
@@ -632,6 +638,8 @@ interface IDBRequest extends EventTarget {
|
||||
readonly transaction: IDBTransaction;
|
||||
addEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof IDBRequestEventMap>(type: K, listener: (this: IDBRequest, ev: IDBRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var IDBRequest: {
|
||||
@@ -659,6 +667,8 @@ interface IDBTransaction extends EventTarget {
|
||||
readonly VERSION_CHANGE: string;
|
||||
addEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof IDBTransactionEventMap>(type: K, listener: (this: IDBTransaction, ev: IDBTransactionEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var IDBTransaction: {
|
||||
@@ -725,6 +735,8 @@ interface MessagePort extends EventTarget {
|
||||
start(): void;
|
||||
addEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof MessagePortEventMap>(type: K, listener: (this: MessagePort, ev: MessagePortEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var MessagePort: {
|
||||
@@ -754,6 +766,8 @@ interface Notification extends EventTarget {
|
||||
close(): void;
|
||||
addEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof NotificationEventMap>(type: K, listener: (this: Notification, ev: NotificationEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var Notification: {
|
||||
@@ -982,6 +996,8 @@ interface ServiceWorker extends EventTarget, AbstractWorker {
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
addEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerEventMap>(type: K, listener: (this: ServiceWorker, ev: ServiceWorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var ServiceWorker: {
|
||||
@@ -1007,6 +1023,8 @@ interface ServiceWorkerRegistration extends EventTarget {
|
||||
update(): Promise<void>;
|
||||
addEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerRegistrationEventMap>(type: K, listener: (this: ServiceWorkerRegistration, ev: ServiceWorkerRegistrationEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var ServiceWorkerRegistration: {
|
||||
@@ -1073,6 +1091,8 @@ interface WebSocket extends EventTarget {
|
||||
readonly OPEN: number;
|
||||
addEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof WebSocketEventMap>(type: K, listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var WebSocket: {
|
||||
@@ -1094,6 +1114,8 @@ interface Worker extends EventTarget, AbstractWorker {
|
||||
terminate(): void;
|
||||
addEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof WorkerEventMap>(type: K, listener: (this: Worker, ev: WorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var Worker: {
|
||||
@@ -1135,6 +1157,8 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
|
||||
readonly UNSENT: number;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventMap>(type: K, listener: (this: XMLHttpRequest, ev: XMLHttpRequestEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var XMLHttpRequest: {
|
||||
@@ -1150,6 +1174,8 @@ declare var XMLHttpRequest: {
|
||||
interface XMLHttpRequestUpload extends EventTarget, XMLHttpRequestEventTarget {
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestUpload, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var XMLHttpRequestUpload: {
|
||||
@@ -1165,6 +1191,8 @@ interface AbstractWorker {
|
||||
onerror: (this: AbstractWorker, ev: ErrorEvent) => any;
|
||||
addEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof AbstractWorkerEventMap>(type: K, listener: (this: AbstractWorker, ev: AbstractWorkerEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
interface Body {
|
||||
@@ -1203,6 +1231,8 @@ interface MSBaseReader {
|
||||
readonly LOADING: number;
|
||||
addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
interface NavigatorBeacon {
|
||||
@@ -1258,6 +1288,8 @@ interface XMLHttpRequestEventTarget {
|
||||
ontimeout: (this: XMLHttpRequest, ev: ProgressEvent) => any;
|
||||
addEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof XMLHttpRequestEventTargetEventMap>(type: K, listener: (this: XMLHttpRequestEventTarget, ev: XMLHttpRequestEventTargetEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
interface Client {
|
||||
@@ -1294,6 +1326,8 @@ interface DedicatedWorkerGlobalScope extends WorkerGlobalScope {
|
||||
postMessage(message: any, transfer?: any[]): void;
|
||||
addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var DedicatedWorkerGlobalScope: {
|
||||
@@ -1405,6 +1439,8 @@ interface ServiceWorkerGlobalScope extends WorkerGlobalScope {
|
||||
skipWaiting(): Promise<void>;
|
||||
addEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof ServiceWorkerGlobalScopeEventMap>(type: K, listener: (this: ServiceWorkerGlobalScope, ev: ServiceWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var ServiceWorkerGlobalScope: {
|
||||
@@ -1450,6 +1486,8 @@ interface WorkerGlobalScope extends EventTarget, WorkerUtils, WindowConsole, Glo
|
||||
createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
addEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
removeEventListener<K extends keyof WorkerGlobalScopeEventMap>(type: K, listener: (this: WorkerGlobalScope, ev: WorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
declare var WorkerGlobalScope: {
|
||||
@@ -1819,7 +1857,6 @@ declare function msWriteProfilerMark(profilerMarkName: string): void;
|
||||
declare function createImageBitmap(image: ImageBitmap | ImageData | Blob, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
declare function createImageBitmap(image: ImageBitmap | ImageData | Blob, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
declare function dispatchEvent(evt: Event): boolean;
|
||||
declare function removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
declare var indexedDB: IDBFactory;
|
||||
declare var msIndexedDB: IDBFactory;
|
||||
declare var navigator: WorkerNavigator;
|
||||
@@ -1838,9 +1875,10 @@ declare function btoa(rawString: string): string;
|
||||
declare var console: Console;
|
||||
declare function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
||||
declare function dispatchEvent(evt: Event): boolean;
|
||||
declare function removeEventListener(type: string, listener?: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
|
||||
declare function addEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
declare function addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
declare function removeEventListener<K extends keyof DedicatedWorkerGlobalScopeEventMap>(type: K, listener: (this: DedicatedWorkerGlobalScope, ev: DedicatedWorkerGlobalScopeEventMap[K]) => any, useCapture?: boolean): void;
|
||||
declare function removeEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
type AlgorithmIdentifier = string | Algorithm;
|
||||
type BodyInit = any;
|
||||
type IDBKeyPath = string;
|
||||
|
||||
@@ -792,6 +792,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[不能在构造函数中访问类“{1}”中的抽象属性“{0}”。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -821,12 +830,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[将 {0} 从 {1} 添加到现有导入声明。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1329,6 +1338,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[使用 JSDoc 中的类型批注]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[使用 JSDoc 中的类型批注]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1476,6 +1503,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[调用修饰器表达式。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1883,12 +1919,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[将 {0} 更改为 {1}。]]></Val>
|
||||
<Val><![CDATA[将“{0}”更改为“{1}”。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}]]></Val>
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2004,6 +2040,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[类声明不能有多个 "@augments" 或 "@extends" 标记。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2853,6 +2898,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[应为 {0}-{1} 类型参数;请为这些参数添加 "@extends" 标记。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2880,6 +2934,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[应为 {0} 类型参数;请为这些参数添加 "@extends" 标记。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3635,12 +3698,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[从 {1} 导入 {0}。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3786,6 +3849,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[从用法中推断出参数类型。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[从用法中推断出“{0}”的类型。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3978,20 +4059,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc "@augments {0}" 与“扩展 {1}”子句不匹配。]]></Val>
|
||||
<Val><![CDATA[JSDoc "@{0} {1}" 不匹配 "extends {2}" 子句。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc "@augments" 未附加到类声明。]]></Val>
|
||||
<Val><![CDATA[JSDoc "@{0}" 未附加到类。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6303,11 +6384,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[后续变量声明必须属于同一类型。变量“{0}”必须属于类型“{1}”,但此处却为类型“{2}”。]]></Val>
|
||||
<Val><![CDATA[后续变量声明必须属于同一类型。变量 "{0}" 在“{2}”中必须为类型“{1}”,但此处却为类型“{3}”。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7254,6 +7335,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[类型参数“{0}”具有循环默认值。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7734,6 +7824,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[“{0}”收到的参数过少,无法在此处充当修饰器。你是要先调用它,然后再写入 "@{0}()" 吗?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -792,6 +792,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[無法從建構函式存取類別 '{1}' 中的抽象屬性 '{0}'。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -821,12 +830,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[從 {1} 將 {0} 新增至現有的匯入宣告。]]></Val>
|
||||
<Val><![CDATA[從 "{1}" 將 '{0}' 新增至現有的匯入宣告。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1329,6 +1338,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[為來自 JSDoc 的類型標註]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[為來自 JSDoc 的類型標註]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1476,6 +1503,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[呼叫裝飾項目運算式。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1883,12 +1919,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[將 {0} 變更為 {1}。]]></Val>
|
||||
<Val><![CDATA[將 '{0}' 變更為 '{1}'。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}]]></Val>
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2004,6 +2040,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[類別宣告只可有一個 '@augments' 或 '@extends' 標記。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2853,6 +2898,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[必須是 {0}-{1} 型別引數; 請提供有 '@ extends' 標記的這類型引數。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2880,6 +2934,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[必須是 {0} 型別引數; 請提供有 '@ extends' 標記的這類引數。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3635,12 +3698,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[將 {0} 從 {1} 匯入。]]></Val>
|
||||
<Val><![CDATA[從 "{1}" 匯入 '{0}'。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3786,6 +3849,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[從用法推斷參數類型。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[從用法推斷 '{0}' 的類型。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3978,20 +4059,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' 不符合 'extends {1}' 子句。]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' 不符合 'extends {2}' 子句。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc '@augments' 未連結至類別宣告。]]></Val>
|
||||
<Val><![CDATA[JSDoc ''@{0}' 未連結到類別。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6303,11 +6384,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[後續的變數宣告必須具有相同的類型。變數 '{0}' 的類型必須是 '{1}' 但卻是 '{2}'。]]></Val>
|
||||
<Val><![CDATA[後續的變數宣告必須具有相同的類型。變數 '{0}' 必須在 {2} 有類型 '{1}' 但卻是 '{3}'。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7254,6 +7335,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[型別參數 '{0}' 包含循環的預設值。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7734,6 +7824,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' 在此只接受極少數的引數用為裝飾項目。要先呼叫此項目,然後再寫入 '@{0}()' 嗎?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -801,6 +801,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[K abstraktní vlastnosti {0} ve třídě {1} nelze získat přístup v konstruktoru.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -830,12 +839,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Přidat {0} k existující deklaraci importu z {1}]]></Val>
|
||||
<Val><![CDATA[Přidá {0} k existující deklaraci importu z {1}.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1338,6 +1347,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Přidat poznámku s typem z JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Přidat poznámky s typy z JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1485,6 +1512,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Výraz pro volání dekoratéru]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1892,12 +1928,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Změnit {0} na {1}]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}]]></Val>
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2013,6 +2049,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Deklarace tříd nemůžou obsahovat více než jednu značku @augments nebo @extends.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2862,6 +2907,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Očekávané argumenty typu {0}–{1}; zadejte je se značkou @extends.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2889,6 +2943,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Očekávané argumenty typu {0}; zadejte je se značkou @extends.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3644,12 +3707,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importovat {0} z {1}]]></Val>
|
||||
<Val><![CDATA[Importujte {0} z: {1}.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3795,6 +3858,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Odvodit typy parametrů z používání]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Odvodit typ {0} z používání]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3987,20 +4068,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Značka JSDoc @augments {0} neodpovídá klauzuli extends {1}.]]></Val>
|
||||
<Val><![CDATA[Značka JSDoc @{0} {1} neodpovídá klauzuli extends {2}.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Značka JSDoc @augments není připojená k deklaraci třídy.]]></Val>
|
||||
<Val><![CDATA[Značka JSDoc @{0} není připojená k třídě.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6312,11 +6393,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Deklarace následných proměnných musí obsahovat stejný typ. Proměnná {0} musí být typu {1}, ale tady je typu {2}.]]></Val>
|
||||
<Val><![CDATA[Deklarace následných proměnných musí obsahovat stejný typ. Proměnná {0} musí být typu {1} v {2}, ale tady je typu {3}.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7263,6 +7344,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Parametr typu {0} má cyklickou výchozí hodnotu.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7743,6 +7833,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Objekt {0} přijímá málo argumentů k tomu, aby se dal použít jako dekoratér. Nechtěli jste ho nejprve volat a napsat @{0}()?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -789,6 +789,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Auf die abstrakte Eigenschaft "{0}" in der Klasse "{1}" kann im Konstruktor nicht zugegriffen werden.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -818,10 +827,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["{0}" zur vorhandenen Importdeklaration aus "{1}" hinzufügen.]]></Val>
|
||||
<Val><![CDATA[Fügen Sie "{0}" zur vorhandenen Importdeklaration aus "{1}" hinzu.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1320,6 +1332,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Mit Typ aus JSDoc kommentieren]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Mit Typen aus JSDoc kommentieren]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1467,6 +1497,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Rufen Sie den Decoratorausdruck auf.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1874,10 +1913,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["{0}" in "{1}" ändern]]></Val>
|
||||
<Val><![CDATA[Ändern Sie "{0}" in "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1989,6 +2031,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Klassendeklarationen dürfen maximal ein "@augments"- oder "@extends"-Tag aufweisen.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2838,6 +2889,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0}-{1} Typargumente erwartet; geben Sie diese mit einem @extends-Tag an.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2865,6 +2925,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} Typargumente erwartet; geben Sie diese mit einem @extends-Tag an.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3617,10 +3686,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["{0}" aus "{1}" importieren.]]></Val>
|
||||
<Val><![CDATA[Importieren Sie "{0}" aus "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3765,6 +3837,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Leiten Sie Parametertypen aus der Nutzung ab.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Leiten Sie den Typ von "{0}" aus der Nutzung ab.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3957,20 +4047,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["@augments {0}" in JSDoc entspricht nicht der Klausel "extends {1}".]]></Val>
|
||||
<Val><![CDATA[JSDoc "@{0} {1}" entspricht nicht der Klausel "extends {2}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["@augments" in JSDoc ist keiner Klassendeklaration zugeordnet.]]></Val>
|
||||
<Val><![CDATA[JSDoc "@{0}" ist keiner Klassendeklaration zugeordnet.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6273,11 +6363,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Nachfolgende Variablendeklarationen müssen den gleichen Typ aufweisen. Die Variable "{0}" muss den Typ "{1}" aufweisen, ist hier aber vom Typ "{2}".]]></Val>
|
||||
<Val><![CDATA[Nachfolgende Variablendeklarationen müssen den gleichen Typ aufweisen. Die Variable "{0}" muss bei "{2}" den Typ "{1}" aufweisen, ist hier aber vom Typ "{3}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7224,6 +7314,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Der Typparameter "{0}" weist einen zirkulären Standard auf.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7704,6 +7803,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["{0}" akzeptiert zu wenige Argumente, um hier als Decorator verwendet zu werden. Wollten Sie es zuerst aufrufen und "@{0}()" schreiben?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -801,6 +801,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[No se puede acceder a la propiedad abstracta "{0}" de la clase "{1}" en el constructor.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -830,12 +839,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Agrega {0} a una declaración de importación existente desde {1}.]]></Val>
|
||||
<Val><![CDATA[Agregue "{0}" a una declaración de importación existente desde "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1338,6 +1347,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Anotar con tipo de JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Anotar con tipos de JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1485,6 +1512,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Llame a la expresión decorador.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1892,12 +1928,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Cambia {0} a {1}.]]></Val>
|
||||
<Val><![CDATA[Cambie "{0}" a "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}]]></Val>
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2013,6 +2049,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Las declaraciones de clase no pueden tener más de una etiqueta "@augments" o "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2862,6 +2907,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Se esperaban argumentos de tipo {0}-{1}; proporciónelos con una etiqueta "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2889,6 +2943,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Se esperaban argumentos de tipo {0}; proporciónelos con una etiqueta "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3644,12 +3707,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importa {0} desde {1}.]]></Val>
|
||||
<Val><![CDATA[Importe "{0}" desde "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3795,6 +3858,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Infiera los tipos de parámetro del uso.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Infiera el tipo de "{0}" del uso.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3987,20 +4068,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[La etiqueta "@augments {0}" de JSDoc no coincide con la cláusula "extends {1}".]]></Val>
|
||||
<Val><![CDATA[La etiqueta "@{0} {1}" de JSDoc no coincide con la cláusula "extends {2}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[La etiqueta "@augments" de JSDoc no está asociada a una declaración de clase.]]></Val>
|
||||
<Val><![CDATA[La etiqueta "@{0}" de JSDoc no está asociada a una clase.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6312,11 +6393,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Las declaraciones de variable subsiguientes deben tener el mismo tipo. La variable '{0}' debe ser de tipo '{1}', pero aquí tiene el tipo '{2}'.]]></Val>
|
||||
<Val><![CDATA[Las declaraciones de variable subsiguientes deben tener el mismo tipo. La variable "{0}" tiene el tipo "{1}" en {2}, pero aquí tiene el tipo "{3}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7263,6 +7344,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[El parámetro de tipo "{0}" tiene un valor circular predeterminado.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7743,6 +7833,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["{0}" no acepta suficientes argumentos para utilizarse como decorador aquí. ¿Pretendía llamar primero y escribir "@{0}()"?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -801,6 +801,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[La propriété abstraite '{0}' de la classe '{1}' n'est pas accessible dans le constructeur.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -830,12 +839,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ajoutez {0} à une déclaration d'importation existante à partir de {1}.]]></Val>
|
||||
<Val><![CDATA[Ajoutez '{0}' à une déclaration d'importation existante à partir de "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1338,6 +1347,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Annoter avec le type de JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Annoter avec les types de JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1485,6 +1512,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Appelez l'expression de l'élément décoratif.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1892,12 +1928,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Changez {0} en {1}.]]></Val>
|
||||
<Val><![CDATA[Changez '{0}' en '{1}'.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}]]></Val>
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2013,6 +2049,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Les déclarations de classes ne peuvent pas avoir plusieurs balises '@augments' ou '@extends'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2862,6 +2907,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Arguments de type {0}-{1} attendus ; indiquez-les avec la balise '@extends'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2889,6 +2943,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Arguments de type {0} attendus ; indiquez-les avec la balise '@extends'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3644,12 +3707,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importez {0} à partir de {1}.]]></Val>
|
||||
<Val><![CDATA[Importez '{0}' à partir de "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3795,6 +3858,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Déduisez les types des paramètres à partir de l'utilisation.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Déduisez le type de '{0}' à partir de l'utilisation.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3987,20 +4068,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[La balise JSDoc '@augments {0}' ne correspond pas à la clause 'extends {1}'.]]></Val>
|
||||
<Val><![CDATA[La balise JSDoc '@{0} {1}' ne correspond pas à la clause 'extends {2}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[La balise JSDoc '@augments' n'est pas attaché à une déclaration de classe.]]></Val>
|
||||
<Val><![CDATA[La balise JSDoc '@{0}' n'est pas attachée à une classe.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6312,11 +6393,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Les déclarations de variable ultérieures doivent avoir le même type. La variable '{0}' doit être de type '{1}', mais elle a ici le type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Les déclarations de variables ultérieures doivent avoir le même type. La variable '{0}' a le type '{1}' au niveau de {2}, mais ici elle a le type '{3}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7263,6 +7344,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Le paramètre de type '{0}' a une valeur par défaut circulaire.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7743,6 +7833,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' accepte trop peu d'arguments pour pouvoir être utilisé ici en tant qu'élément décoratif. Voulez-vous vraiment l'appeler d'abord et écrire '@{0}()' ?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -792,6 +792,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Non è possibile accedere alla proprietà astratta '{0}' nella classe '{1}' nel costruttore.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -821,12 +830,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Aggiungi {0} alla dichiarazione di importazione esistente da {1}.]]></Val>
|
||||
<Val><![CDATA[Aggiungere '{0}' alla dichiarazione di importazione esistente da "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1329,6 +1338,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Annota con tipo di JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Annota con tipi di JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1476,6 +1503,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Chiama l'espressione Decorator.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1883,12 +1919,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Cambia {0} in {1}.]]></Val>
|
||||
<Val><![CDATA[Cambia '{0}' in '{1}'.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}]]></Val>
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2004,6 +2040,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Le dichiarazioni di classe non possono contenere più di un tag `@augments` o `@extends`.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2853,6 +2898,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Sono previsti argomento tipo {0}-{1}. Per specificarli, usare un tag '@extends'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2880,6 +2934,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Sono previsti argomento tipo {0}. Per specificarli, usare un tag '@extends'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3635,12 +3698,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importa {0} da {1}.]]></Val>
|
||||
<Val><![CDATA[Importare '{0}' da "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3786,6 +3849,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Deriva i tipi di parametro dall'utilizzo.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Deriva il tipo di '{0}' dall'utilizzo.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3978,20 +4059,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Il tag '@augments {0}' di JSDoc non corrisponde alla clausola 'extends {1}'.]]></Val>
|
||||
<Val><![CDATA[Il tag '@{0} {1}' di JSDoc non corrisponde alla clausola 'extends {2}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Il tag '@augments' di JSDoc non è collegato a una dichiarazione di classe.]]></Val>
|
||||
<Val><![CDATA[Il tag '@{0}' di JSDoc non è collegato a una classe.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6303,11 +6384,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Le dichiarazioni di variabili successive devono essere dello stesso tipo. La variabile '{0}' deve essere di tipo '{1}', mentre è di tipo '{2}'.]]></Val>
|
||||
<Val><![CDATA[Le dichiarazioni di variabili successive devono essere dello stesso tipo. La variabile '{0}' è di tipo '{1}' alla posizione {2}, ma qui è di tipo '{3}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7254,6 +7335,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Il parametro di tipo '{0}' contiene un'impostazione predefinita circolare.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7734,6 +7824,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' accetta un numero troppo ridotto di argomenti da usare come espressione Decorator in questo punto. Si intendeva chiamarlo prima e scrivere '@{0}()'?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -792,6 +792,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[コンストラクター内でクラス '{1}' の抽象プロパティ '{0}' にアクセスできません。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -821,12 +830,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{1} から既存のインポート宣言に {0} を追加します。]]></Val>
|
||||
<Val><![CDATA["{1}" から既存のインポート宣言に '{0}' を追加します。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1329,6 +1338,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc の型で注釈を付けます]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc の型で注釈を付けます]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1476,6 +1503,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[デコレーター式を呼び出します。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1883,12 +1919,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} を {1} に変更します。]]></Val>
|
||||
<Val><![CDATA['{0}' を '{1}' に変更します。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}]]></Val>
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2004,6 +2040,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[クラス宣言で複数の '@augments' または `@extends` タグを使用することはできません。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2853,6 +2898,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0}-{1} 型の引数が必要です。'@extends' タグで指定してください。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2880,6 +2934,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} 型の引数が必要です。'@extends' タグで指定してください。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3635,12 +3698,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{1} から {0} をインポートします。]]></Val>
|
||||
<Val><![CDATA["{1}" から '{0}' をインポートします。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3786,6 +3849,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[使用状況からパラメーターの型を推論します。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[使用状況から型 '{0}' を推論します。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3978,20 +4059,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' は 'extends {1}' 句と一致しません。]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' が 'extends {2}' 句と一致しません。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc '@augments' はクラス宣言にアタッチされていません。]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' はクラスにアタッチされていません。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6303,11 +6384,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[後続の変数宣言は同じ型でなければなりません。変数 '{0}' の型は '{1}' である必要がありますが、'{2}' になっています。]]></Val>
|
||||
<Val><![CDATA[後続の変数宣言は同じ型でなければなりません。変数 '{0}' の型は {2} では '{1}' ですが、ここでは型が '{3}' になっています。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7254,6 +7335,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[型パラメーター '{0}' に循環既定値があります。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7734,6 +7824,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' は受け入れる引数が少なすぎるので、ここでデコレーターとして使用することができません。最初にこれを呼び出してから、'@{0}()' を書き込むつもりでしたか?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -792,6 +792,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[생성자에서 '{1}' 클래스의 추상 속성 '{0}'에 액세스할 수 없습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -821,12 +830,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{1}에서 기존 가져오기 선언에 {0}을(를) 추가합니다.]]></Val>
|
||||
<Val><![CDATA["{1}"에서 기존 가져오기 선언에 '{0}'을(를) 추가합니다.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1329,6 +1338,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc의 형식을 사용하여 주석 추가]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc의 형식을 사용하여 주석 추가]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1476,6 +1503,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[decorator 식을 호출합니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1883,12 +1919,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0}을(를) {1}(으)로 변경합니다.]]></Val>
|
||||
<Val><![CDATA['{0}'을(를) '{1}'(으)로 변경합니다.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}]]></Val>
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2004,6 +2040,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[클래스 선언은 '@augments' 또는 `@extends` 태그를 둘 이상 가질 수 없습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2853,6 +2898,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['@extends' 태그로 제공하는 예상되는 {0}-{1} 형식 인수입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2880,6 +2934,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['@extends' 태그로 제공하는 예상되는 {0} 형식 인수입니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3635,12 +3698,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{1}에서 {0}을(를) 가져옵니다.]]></Val>
|
||||
<Val><![CDATA["{1}"에서 '{0}'을(를) 가져옵니다.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3786,6 +3849,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[사용량에서 매개 변수 형식을 유추합니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[사용량에서 '{0}'의 형식을 유추합니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3978,20 +4059,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc '@augments {0}'이(가) 'extends {1}' 절과 일치하지 않습니다.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}'이(가) 'extends {2}' 절과 일치하지 않습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc '@augments'가 클래스 선언에 연결되어 있지 않습니다.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}'이(가) 클래스에 연결되어 있지 않습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6303,11 +6384,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[후속 변수 선언에 같은 형식이 있어야 합니다. '{0}' 변수가 '{1}' 형식이어야 하는데 여기에는 '{2}' 형식이 있습니다.]]></Val>
|
||||
<Val><![CDATA[후속 변수 선언에 같은 형식이 있어야 합니다. '{0}' 변수가 {2}에서 '{1}' 형식이어야 하는데 여기에는 '{3}' 형식이 있습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7254,6 +7335,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[형식 매개 변수 '{0}'에 순환 기본값이 있습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7734,6 +7824,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}'이(가) 여기에서 decorator로 사용할 인수를 너무 적게 허용합니다. 먼저 이를 호출하고 '@{0}()'을(를) 작성하시겠습니까?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -782,6 +782,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Właściwość abstrakcyjna „{0}” w klasie „{1}” jest niedostępna w konstruktorze.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -811,10 +820,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dodaj element {0} do istniejącej deklaracji importu z {1}.]]></Val>
|
||||
<Val><![CDATA[Dodaj element „{0}” do istniejącej deklaracji importu z elementu „{1}”.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1313,6 +1325,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dodaj adnotację przy użyciu typu z JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dodaj adnotację przy użyciu typów z JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1460,6 +1490,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Wywołaj wyrażenie dekoratora.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1867,10 +1906,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Zmień {0} na {1}.]]></Val>
|
||||
<Val><![CDATA[Zmień element „{0}” na „{1}”.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1982,6 +2024,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Deklaracje klas nie mogą mieć więcej niż jeden tag „@augments” lub „@extends”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2831,6 +2882,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Oczekiwano argumentów typu {0}-{1}; podaj je z tagiem „@extends”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2858,6 +2918,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Oczekiwano argumentów typu {0}; podaj je z tagiem „@extends”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3610,10 +3679,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importuj {0} z {1}.]]></Val>
|
||||
<Val><![CDATA[Importuj element „{0}” z elementu „{1}”.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3758,6 +3830,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Wywnioskuj typy parametrów na podstawie użycia.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Wywnioskuj typ elementu „{0}” na podstawie użycia.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3950,20 +4040,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Element JSDoc „@augments {0}” jest niezgodny z klauzulą „extends {1}”.]]></Val>
|
||||
<Val><![CDATA[Element JSDoc „@{0} {1}” nie pasuje do klauzuli „extends {2}”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Element JSDoc „@augments” nie został dołączony do deklaracji klasy.]]></Val>
|
||||
<Val><![CDATA[Element JSDoc „@{0}” nie został dołączony do klasy.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6266,11 +6356,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Kolejne deklaracje zmiennej muszą być tego samego typu. Zmienna „{0}” musi być typu „{1}”, ale w tym miejscu jest typu „{2}”.]]></Val>
|
||||
<Val><![CDATA[Kolejne deklaracje zmiennej muszą być tego samego typu. Zmienna „{0}” musi być typu „{1}” w {2} , ale w tym miejscu jest typu „{3}”.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7217,6 +7307,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Parametr typu „{0}” ma cykliczną wartość domyślną.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7697,6 +7796,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Element „{0}” akceptuje za mało argumentów, aby można go było użyć w tym miejscu jako dekorator. Czy chcesz najpierw go wywołać i zapisać tag „@{0}()”?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -782,6 +782,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[A propriedade abstrata '{0}' na classe '{1}' não pode ser acessada no construtor.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -811,10 +820,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Adicionar {0} à declaração de importação existente de {1}.]]></Val>
|
||||
<Val><![CDATA[Adicione "{0}" à declaração de importação existente de "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1313,6 +1325,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Anotar com o tipo do JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Anotar com os tipos do JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1460,6 +1490,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Chamar expressão decoradora.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1867,10 +1906,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Alterar {0} para {1}.]]></Val>
|
||||
<Val><![CDATA[Alterar '{0}' para '{1}'.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -1982,6 +2024,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Declarações de classe não podem ter mais de uma marca `@augments` ou `@extends`.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2831,6 +2882,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Espera-se {0}-{1} argumentos de tipo; forneça esses recursos com uma marca "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2858,6 +2918,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Espera-se {0} argumentos de tipo; forneça esses recursos com uma marca "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3610,10 +3679,13 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Importar {0} de {1}.]]></Val>
|
||||
<Val><![CDATA[Importar "{0}" de "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
@@ -3758,6 +3830,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Inferir os tipos de parâmetro do uso.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Inferir o tipo de '{0}' do uso.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3950,20 +4040,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc "@augments {0}" não corresponde à cláusula "extends {1}".]]></Val>
|
||||
<Val><![CDATA[O '@{0} {1}' do JSDoc não corresponde à cláusula 'extends {2}'.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc "@augments" não está anexado à declaração de classe.]]></Val>
|
||||
<Val><![CDATA[O '@{0}' do JSDoc não está anexado a uma classe.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6266,11 +6356,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Declarações de variável subsequentes devem ter o mesmo tipo. A variável '{0}' deve ser do tipo '{1}', mas aqui tem o tipo '{2}'.]]></Val>
|
||||
<Val><![CDATA[Declarações de variável subsequentes devem ter o mesmo tipo. A variável "{0}" deve ser do tipo "{1}" em {2}, mas aqui tem o tipo "{3}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7217,6 +7307,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[O parâmetro de tipo '{0}' tem um padrão circular.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7697,6 +7796,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' aceita muito poucos argumentos para serem usados como um decorador aqui. Você quis dizer para chamá-lo primeiro e gravar '@{0}()'?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -791,6 +791,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Абстрактное свойство "{0}" в классе "{1}" недоступно в конструкторе.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -820,12 +829,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Добавьте {0} в существующее объявление импорта из {1}.]]></Val>
|
||||
<Val><![CDATA[Добавьте "{0}" в существующее объявление импорта из "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1328,6 +1337,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Заметка с типом из JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Заметки с типами из JSDoc]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1475,6 +1502,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Вызов выражения-декоратора.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1882,12 +1918,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Измените {0} на {1}.]]></Val>
|
||||
<Val><![CDATA[Замена "{0}" на "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}]]></Val>
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -2003,6 +2039,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[В объявлении класса не может использоваться более одного тега "@augments" или "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2852,6 +2897,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ожидается аргументов типа: {0}–{1}. Укажите их с тегом "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2879,6 +2933,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ожидается аргументов типа: {0}. Укажите их с тегом "@extends".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3634,12 +3697,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Импортируйте {0} из {1}.]]></Val>
|
||||
<Val><![CDATA[Импортируйте "{0}" из "{1}".]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3785,6 +3848,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Вывод типов параметров на основе использования.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Вывод типа "{0}" на основе использования.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3977,20 +4058,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Параметр "@augments {0}" JSDoc не соответствует предложению "extends {1}".]]></Val>
|
||||
<Val><![CDATA[Параметр "@{0} {1}" JSDoc не соответствует предложению "extends {2}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Параметр "@augments" JSDoc не связан с объявлением класса.]]></Val>
|
||||
<Val><![CDATA[Параметр "@{0}" JSDoc не связан с классом.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6302,11 +6383,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Последующие объявления переменных должны иметь тот же тип. Переменная "{0}" должна иметь тип "{1}", однако имеет тип "{2}".]]></Val>
|
||||
<Val><![CDATA[Последующие объявления переменных должны иметь тот же тип. Переменная "{0}" должна иметь тип "{1}" в {2}, но имеет тип "{3}".]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7253,6 +7334,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Параметр типа "{0}" по умолчанию является циклическим.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7733,6 +7823,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["{0}" принимает слишком мало аргументов для использования в качестве декоратора. Вы хотели сначала вызвать его и записать "@{0}()"?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -785,6 +785,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Abstract property '{0}' in class '{1}' cannot be accessed in the constructor.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{1}' sınıfındaki '{0}' soyut özelliğine oluşturucuda erişilemiyor.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Accessibility_modifier_already_seen_1028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Accessibility modifier already seen.]]></Val>
|
||||
@@ -814,12 +823,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Add_0_to_existing_import_declaration_from_1_90015" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
<Val><![CDATA[Add '{0}' to existing import declaration from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} öğesini {1} konumundaki mevcut içeri aktarma bildirimine ekleyin.]]></Val>
|
||||
<Val><![CDATA['{0}' öğesini "{1}" konumundaki mevcut içeri aktarma bildirimine ekleyin.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}]]></Val>
|
||||
<Val><![CDATA[Add {0} to existing import declaration from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1322,6 +1331,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_type_from_JSDoc_95009" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with type from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc türü ile not ekle]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Annotate_with_types_from_JSDoc_95010" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Annotate with types from JSDoc]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc türleri ile not ekle]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Argument_expression_expected_1135" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Argument expression expected.]]></Val>
|
||||
@@ -1469,6 +1496,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_decorator_expression_90028" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call decorator expression.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dekoratör ifadesini çağırın.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Call signature, which lacks return-type annotation, implicitly has an 'any' return type.]]></Val>
|
||||
@@ -1876,12 +1912,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Change_0_to_1_90014" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
<Val><![CDATA[Change '{0}' to '{1}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} öğesini {1} olarak değiştirin.]]></Val>
|
||||
<Val><![CDATA['{0}' değerini '{1}' olarak değiştirin.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Change {0} to {1}]]></Val>
|
||||
<Val><![CDATA[Change {0} to {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -1997,6 +2033,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class declarations cannot have more than one `@augments` or `@extends` tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Sınıf bildirimlerinde birden fazla `@augments` veya `@extends` etiketi olamaz.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Class_name_cannot_be_0_2414" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Class name cannot be '{0}'.]]></Val>
|
||||
@@ -2846,6 +2891,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0}-{1} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0}-{1} türünde bağımsız değişkenler bekleniyordu; bunları bir '@extends' etiketiyle sağlayın.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_arguments_but_got_1_2554" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} arguments, but got {1}.]]></Val>
|
||||
@@ -2873,6 +2927,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_0_type_arguments_provide_these_with_an_extends_tag_8026" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected {0} type arguments; provide these with an '@extends' tag.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} türünde bağımsız değişkenler bekleniyordu; bunları bir '@extends' etiketiyle sağlayın.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -3628,12 +3691,12 @@
|
||||
</Item>
|
||||
<Item ItemId=";Import_0_from_1_90013" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
<Val><![CDATA[Import '{0}' from "{1}".]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[{0} öğesini {1} kaynağından içeri aktarın.]]></Val>
|
||||
<Val><![CDATA['{0}' öğesini "{1}" kaynağından içeri aktarın.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Import {0} from {1}]]></Val>
|
||||
<Val><![CDATA[Import {0} from {1}.]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -3779,6 +3842,24 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_parameter_types_from_usage_95012" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer parameter types from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Parametre türlerini kullanımdan çıkarsayın.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Infer_type_of_0_from_usage_95011" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Infer type of '{0}' from usage.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' türünü kullanımdan çıkarsayın.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Initialize_property_0_in_the_constructor_90020" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Initialize property '{0}' in the constructor.]]></Val>
|
||||
@@ -3971,20 +4052,20 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_0_does_not_match_the_extends_1_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_1_does_not_match_the_extends_2_clause_8023" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments {0}' does not match the 'extends {1}' clause.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}' does not match the 'extends {2}' clause.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc '@augments {0}', 'extends {1}' yan tümcesiyle eşleşmiyor.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0} {1}', 'extends {2}' yan tümcesiyle eşleşmiyor.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";JSDoc_augments_is_not_attached_to_a_class_declaration_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";JSDoc_0_is_not_attached_to_a_class_8022" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[JSDoc '@augments' is not attached to a class declaration.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' is not attached to a class.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[JSDoc '@augments', bir sınıf bildirimine eklenmemiş.]]></Val>
|
||||
<Val><![CDATA[JSDoc '@{0}' bir sınıfa eklenmemiş.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -6296,11 +6377,11 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Item ItemId=";Subsequent_variable_declarations_must_have_the_same_type_Variable_0_has_type_1_at_2_but_here_has_typ_2403" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'.]]></Val>
|
||||
<Val><![CDATA[Subsequent variable declarations must have the same type. Variable '{0}' has type '{1}' at {2}, but here has type '{3}'.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ardışık değişken bildirimleri aynı türe sahip olmalıdır. '{0}' değişkeni '{1}' türünde olmalıdır, ancak burada '{2}' türüne sahip.]]></Val>
|
||||
<Val><![CDATA[Ardışık değişken bildirimleri aynı türe sahip olmalıdır. '{0}' değişkeni {2} konumunda '{1}' türüne sahip olmasına rağmen burada '{3}' türüne sahip.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
@@ -7247,6 +7328,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_has_a_circular_default_2716" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' has a circular default.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' tür parametresi döngüsel bir varsayılana sahip.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'.]]></Val>
|
||||
@@ -7727,6 +7817,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' burada dekoratör olarak kullanılmak için çok az bağımsız değişken kabul ediyor. Önce çağırıp '@{0}()' yazmak mı istediniz?]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA['{0}' are specified twice. The attribute named '{0}' will be overwritten.]]></Val>
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function extractMessage(message: string) {
|
||||
export function extractMessage(message: string): string {
|
||||
// Read the content length
|
||||
const contentLengthPrefix = "Content-Length: ";
|
||||
const lines = message.split(/\r?\n/);
|
||||
@@ -198,7 +198,9 @@ namespace ts.server {
|
||||
const request = this.processRequest<protocol.CompletionDetailsRequest>(CommandNames.CompletionDetails, args);
|
||||
const response = this.processResponse<protocol.CompletionDetailsResponse>(request);
|
||||
Debug.assert(response.body.length === 1, "Unexpected length of completion details response body.");
|
||||
return response.body[0];
|
||||
|
||||
const convertedCodeActions = map(response.body[0].codeActions, codeAction => this.convertCodeActions(codeAction, fileName));
|
||||
return { ...response.body[0], codeActions: convertedCodeActions };
|
||||
}
|
||||
|
||||
getCompletionEntrySymbol(_fileName: string, _position: number, _entryName: string): Symbol {
|
||||
@@ -540,6 +542,8 @@ namespace ts.server {
|
||||
return response.body.map(entry => this.convertCodeActions(entry, file));
|
||||
}
|
||||
|
||||
applyCodeActionCommand = notImplemented;
|
||||
|
||||
private createFileLocationOrRangeRequestArgs(positionOrRange: number | TextRange, fileName: string): protocol.FileLocationOrRangeRequestArgs {
|
||||
return typeof positionOrRange === "number"
|
||||
? this.createFileLocationRequestArgs(fileName, positionOrRange)
|
||||
|
||||
@@ -220,13 +220,28 @@ namespace ts.server {
|
||||
|
||||
interface FilePropertyReader<T> {
|
||||
getFileName(f: T): string;
|
||||
getScriptKind(f: T): ScriptKind;
|
||||
getScriptKind(f: T, extraFileExtensions?: JsFileExtensionInfo[]): ScriptKind;
|
||||
hasMixedContent(f: T, extraFileExtensions: JsFileExtensionInfo[]): boolean;
|
||||
}
|
||||
|
||||
const fileNamePropertyReader: FilePropertyReader<string> = {
|
||||
getFileName: x => x,
|
||||
getScriptKind: _ => undefined,
|
||||
getScriptKind: (fileName, extraFileExtensions) => {
|
||||
let result: ScriptKind;
|
||||
if (extraFileExtensions) {
|
||||
const fileExtension = getAnyExtensionFromPath(fileName);
|
||||
if (fileExtension) {
|
||||
some(extraFileExtensions, info => {
|
||||
if (info.extension === fileExtension) {
|
||||
result = info.scriptKind;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
hasMixedContent: (fileName, extraFileExtensions) => some(extraFileExtensions, ext => ext.isMixedContent && fileExtensionIs(fileName, ext.extension)),
|
||||
};
|
||||
|
||||
@@ -337,9 +352,9 @@ namespace ts.server {
|
||||
*/
|
||||
readonly configuredProjects = createMap<ConfiguredProject>();
|
||||
/**
|
||||
* list of open files
|
||||
* Open files: with value being project root path, and key being Path of the file that is open
|
||||
*/
|
||||
readonly openFiles: ScriptInfo[] = [];
|
||||
readonly openFiles = createMap<NormalizedPath>();
|
||||
|
||||
private compilerOptionsForInferredProjects: CompilerOptions;
|
||||
private compilerOptionsForInferredProjectsPerProjectRoot = createMap<CompilerOptions>();
|
||||
@@ -554,6 +569,11 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
hasPendingProjectUpdate(project: Project) {
|
||||
return this.pendingProjectUpdates.has(project.getProjectName());
|
||||
}
|
||||
|
||||
private sendProjectsUpdatedInBackgroundEvent() {
|
||||
if (!this.eventHandler) {
|
||||
return;
|
||||
@@ -562,7 +582,7 @@ namespace ts.server {
|
||||
const event: ProjectsUpdatedInBackgroundEvent = {
|
||||
eventName: ProjectsUpdatedInBackgroundEvent,
|
||||
data: {
|
||||
openFiles: this.openFiles.map(f => f.fileName)
|
||||
openFiles: arrayFrom(this.openFiles.keys(), path => this.getScriptInfoForPath(path as Path).fileName)
|
||||
}
|
||||
};
|
||||
this.eventHandler(event);
|
||||
@@ -795,8 +815,14 @@ namespace ts.server {
|
||||
);
|
||||
}
|
||||
|
||||
/** Gets the config file existence info for the configured project */
|
||||
/*@internal*/
|
||||
getConfigFileExistenceInfo(project: ConfiguredProject) {
|
||||
return this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath);
|
||||
}
|
||||
|
||||
private onConfigChangedForConfiguredProject(project: ConfiguredProject, eventKind: FileWatcherEventKind) {
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath);
|
||||
const configFileExistenceInfo = this.getConfigFileExistenceInfo(project);
|
||||
if (eventKind === FileWatcherEventKind.Deleted) {
|
||||
// Update the cached status
|
||||
// We arent updating or removing the cached config file presence info as that will be taken care of by
|
||||
@@ -865,7 +891,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
assignOrphanScriptInfoToInferredProject(info: ScriptInfo, projectRootPath?: string) {
|
||||
assignOrphanScriptInfoToInferredProject(info: ScriptInfo, projectRootPath: NormalizedPath | undefined) {
|
||||
Debug.assert(info.isOrphan());
|
||||
|
||||
const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) ||
|
||||
@@ -898,18 +924,6 @@ namespace ts.server {
|
||||
return project;
|
||||
}
|
||||
|
||||
private addToListOfOpenFiles(info: ScriptInfo) {
|
||||
Debug.assert(!info.isOrphan());
|
||||
for (const p of info.containingProjects) {
|
||||
// file is the part of configured project, addref the project
|
||||
if (p.projectKind === ProjectKind.Configured) {
|
||||
((<ConfiguredProject>p)).addOpenRef();
|
||||
}
|
||||
}
|
||||
|
||||
this.openFiles.push(info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove this file from the set of open, non-configured files.
|
||||
* @param info The file that has been closed or newly configured
|
||||
@@ -921,7 +935,7 @@ namespace ts.server {
|
||||
info.close();
|
||||
this.stopWatchingConfigFilesForClosedScriptInfo(info);
|
||||
|
||||
unorderedRemoveItem(this.openFiles, info);
|
||||
this.openFiles.delete(info.path);
|
||||
|
||||
const fileExists = this.host.fileExists(info.fileName);
|
||||
|
||||
@@ -932,10 +946,8 @@ namespace ts.server {
|
||||
if (info.hasMixedContent) {
|
||||
info.registerFileUpdate();
|
||||
}
|
||||
// Delete the reference to the open configured projects but
|
||||
// do not remove the project so that we can reuse this project
|
||||
// Do not remove the project so that we can reuse this project
|
||||
// if it would need to be re-created with next file open
|
||||
(<ConfiguredProject>p).deleteOpenRef();
|
||||
}
|
||||
else if (p.projectKind === ProjectKind.Inferred && p.isRoot(info)) {
|
||||
// If this was the open root file of inferred project
|
||||
@@ -962,11 +974,12 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
// collect orphaned files and assign them to inferred project just like we treat open of a file
|
||||
for (const f of this.openFiles) {
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
const f = this.getScriptInfoForPath(path as Path);
|
||||
if (f.isOrphan()) {
|
||||
this.assignOrphanScriptInfoToInferredProject(f);
|
||||
this.assignOrphanScriptInfoToInferredProject(f, projectRootPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Cleanup script infos that arent part of any project (eg. those could be closed script infos not referenced by any project)
|
||||
// is postponed to next file open so that if file from same project is opened,
|
||||
@@ -1025,7 +1038,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private setConfigFileExistenceByNewConfiguredProject(project: ConfiguredProject) {
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath);
|
||||
const configFileExistenceInfo = this.getConfigFileExistenceInfo(project);
|
||||
if (configFileExistenceInfo) {
|
||||
Debug.assert(configFileExistenceInfo.exists);
|
||||
// close existing watcher
|
||||
@@ -1054,7 +1067,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private setConfigFileExistenceInfoByClosedConfiguredProject(closedProject: ConfiguredProject) {
|
||||
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(closedProject.canonicalConfigFilePath);
|
||||
const configFileExistenceInfo = this.getConfigFileExistenceInfo(closedProject);
|
||||
Debug.assert(!!configFileExistenceInfo);
|
||||
if (configFileExistenceInfo.openFilesImpactedByConfigFile.size) {
|
||||
const configFileName = closedProject.getConfigFilePath();
|
||||
@@ -1160,7 +1173,7 @@ namespace ts.server {
|
||||
* This is called by inferred project whenever script info is added as a root
|
||||
*/
|
||||
/* @internal */
|
||||
startWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo) {
|
||||
startWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo, projectRootPath: NormalizedPath | undefined) {
|
||||
Debug.assert(info.isScriptOpen());
|
||||
this.forEachConfigFileLocation(info, (configFileName, canonicalConfigFilePath) => {
|
||||
let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
|
||||
@@ -1182,7 +1195,7 @@ namespace ts.server {
|
||||
!this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath)) {
|
||||
this.createConfigFileWatcherOfConfigFileExistence(configFileName, canonicalConfigFilePath, configFileExistenceInfo);
|
||||
}
|
||||
});
|
||||
}, projectRootPath);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1250,7 +1263,7 @@ namespace ts.server {
|
||||
* The server must start searching from the directory containing
|
||||
* the newly opened file.
|
||||
*/
|
||||
private getConfigFileNameForFile(info: ScriptInfo, projectRootPath?: NormalizedPath) {
|
||||
private getConfigFileNameForFile(info: ScriptInfo, projectRootPath: NormalizedPath | undefined) {
|
||||
Debug.assert(info.isScriptOpen());
|
||||
this.logger.info(`Search path: ${getDirectoryPath(info.fileName)}`);
|
||||
const configFileName = this.forEachConfigFileLocation(info,
|
||||
@@ -1289,9 +1302,9 @@ namespace ts.server {
|
||||
printProjects(this.inferredProjects, counter);
|
||||
|
||||
this.logger.info("Open files: ");
|
||||
for (const rootFile of this.openFiles) {
|
||||
this.logger.info(`\t${rootFile.fileName}`);
|
||||
}
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
this.logger.info(`\tFileName: ${this.getScriptInfoForPath(path as Path).fileName} ProjectRootPath: ${projectRootPath}`);
|
||||
});
|
||||
|
||||
this.logger.endGroup();
|
||||
}
|
||||
@@ -1338,10 +1351,10 @@ namespace ts.server {
|
||||
const projectOptions: ProjectOptions = {
|
||||
files: parsedCommandLine.fileNames,
|
||||
compilerOptions: parsedCommandLine.options,
|
||||
configHasExtendsProperty: parsedCommandLine.raw["extends"] !== undefined,
|
||||
configHasFilesProperty: parsedCommandLine.raw["files"] !== undefined,
|
||||
configHasIncludeProperty: parsedCommandLine.raw["include"] !== undefined,
|
||||
configHasExcludeProperty: parsedCommandLine.raw["exclude"] !== undefined,
|
||||
configHasExtendsProperty: parsedCommandLine.raw.extends !== undefined,
|
||||
configHasFilesProperty: parsedCommandLine.raw.files !== undefined,
|
||||
configHasIncludeProperty: parsedCommandLine.raw.include !== undefined,
|
||||
configHasExcludeProperty: parsedCommandLine.raw.exclude !== undefined,
|
||||
wildcardDirectories: createMapFromTemplate(parsedCommandLine.wildcardDirectories),
|
||||
typeAcquisition: parsedCommandLine.typeAcquisition,
|
||||
compileOnSave: parsedCommandLine.compileOnSave
|
||||
@@ -1504,7 +1517,7 @@ namespace ts.server {
|
||||
scriptInfo = normalizedPath;
|
||||
}
|
||||
else {
|
||||
const scriptKind = propertyReader.getScriptKind(f);
|
||||
const scriptKind = propertyReader.getScriptKind(f, this.hostConfiguration.extraFileExtensions);
|
||||
const hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions);
|
||||
scriptInfo = this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(normalizedPath, scriptKind, hasMixedContent, project.directoryStructureHost);
|
||||
path = scriptInfo.path;
|
||||
@@ -1593,7 +1606,7 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
private getOrCreateInferredProjectForProjectRootPathIfEnabled(info: ScriptInfo, projectRootPath: string | undefined): InferredProject | undefined {
|
||||
private getOrCreateInferredProjectForProjectRootPathIfEnabled(info: ScriptInfo, projectRootPath: NormalizedPath | undefined): InferredProject | undefined {
|
||||
if (!this.useInferredProjectPerProjectRoot) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1647,7 +1660,7 @@ namespace ts.server {
|
||||
return this.createInferredProject(/*currentDirectory*/ undefined, /*isSingleInferredProject*/ true);
|
||||
}
|
||||
|
||||
private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: string): InferredProject {
|
||||
private createInferredProject(currentDirectory: string | undefined, isSingleInferredProject?: boolean, projectRootPath?: NormalizedPath): InferredProject {
|
||||
const compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects;
|
||||
const project = new InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, currentDirectory);
|
||||
if (isSingleInferredProject) {
|
||||
@@ -1784,23 +1797,19 @@ namespace ts.server {
|
||||
// as there is no need to load contents of the files from the disk
|
||||
|
||||
// Reload Projects
|
||||
this.reloadConfiguredProjectForFiles(this.openFiles, /*delayReload*/ false);
|
||||
this.reloadConfiguredProjectForFiles(this.openFiles, /*delayReload*/ false, returnTrue);
|
||||
this.refreshInferredProjects();
|
||||
}
|
||||
|
||||
private delayReloadConfiguredProjectForFiles(configFileExistenceInfo: ConfigFileExistenceInfo, ignoreIfNotRootOfInferredProject: boolean) {
|
||||
// Get open files to reload projects for
|
||||
const openFiles = mapDefinedIter(
|
||||
configFileExistenceInfo.openFilesImpactedByConfigFile.entries(),
|
||||
([path, isRootOfInferredProject]) => {
|
||||
if (!ignoreIfNotRootOfInferredProject || isRootOfInferredProject) {
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
Debug.assert(!!info);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
this.reloadConfiguredProjectForFiles(
|
||||
configFileExistenceInfo.openFilesImpactedByConfigFile,
|
||||
/*delayReload*/ true,
|
||||
ignoreIfNotRootOfInferredProject ?
|
||||
isRootOfInferredProject => isRootOfInferredProject : // Reload open files if they are root of inferred project
|
||||
returnTrue // Reload all the open files impacted by config file
|
||||
);
|
||||
this.reloadConfiguredProjectForFiles(openFiles, /*delayReload*/ true);
|
||||
this.delayInferredProjectsRefresh();
|
||||
}
|
||||
|
||||
@@ -1809,16 +1818,24 @@ namespace ts.server {
|
||||
* If the config file is found and it refers to existing project, it reloads it either immediately
|
||||
* or schedules it for reload depending on delayReload option
|
||||
* If the there is no existing project it just opens the configured project for the config file
|
||||
* reloadForInfo provides a way to filter out files to reload configured project for
|
||||
*/
|
||||
private reloadConfiguredProjectForFiles(openFiles: ReadonlyArray<ScriptInfo>, delayReload: boolean) {
|
||||
private reloadConfiguredProjectForFiles<T>(openFiles: Map<T>, delayReload: boolean, shouldReloadProjectFor: (openFileValue: T) => boolean) {
|
||||
const updatedProjects = createMap<true>();
|
||||
// try to reload config file for all open files
|
||||
for (const info of openFiles) {
|
||||
openFiles.forEach((openFileValue, path) => {
|
||||
// Filter out the files that need to be ignored
|
||||
if (!shouldReloadProjectFor(openFileValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
Debug.assert(info.isScriptOpen());
|
||||
// This tries to search for a tsconfig.json for the given file. If we found it,
|
||||
// we first detect if there is already a configured project created for it: if so,
|
||||
// we re- read the tsconfig file content and update the project only if we havent already done so
|
||||
// otherwise we create a new one.
|
||||
const configFileName = this.getConfigFileNameForFile(info);
|
||||
const configFileName = this.getConfigFileNameForFile(info, this.openFiles.get(path));
|
||||
if (configFileName) {
|
||||
const project = this.findConfiguredProjectByProjectName(configFileName);
|
||||
if (!project) {
|
||||
@@ -1836,7 +1853,7 @@ namespace ts.server {
|
||||
updatedProjects.set(configFileName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1881,16 +1898,17 @@ namespace ts.server {
|
||||
this.logger.info("refreshInferredProjects: updating project structure from ...");
|
||||
this.printProjects();
|
||||
|
||||
for (const info of this.openFiles) {
|
||||
this.openFiles.forEach((projectRootPath, path) => {
|
||||
const info = this.getScriptInfoForPath(path as Path);
|
||||
// collect all orphaned script infos from open files
|
||||
if (info.isOrphan()) {
|
||||
this.assignOrphanScriptInfoToInferredProject(info);
|
||||
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
|
||||
}
|
||||
else {
|
||||
// Or remove the root of inferred project if is referenced in more than one projects
|
||||
this.removeRootOfInferredProjectIfNowPartOfOtherProject(info);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (const p of this.inferredProjects) {
|
||||
p.updateGraph();
|
||||
@@ -1943,7 +1961,8 @@ namespace ts.server {
|
||||
|
||||
this.assignOrphanScriptInfoToInferredProject(info, projectRootPath);
|
||||
}
|
||||
this.addToListOfOpenFiles(info);
|
||||
Debug.assert(!info.isOrphan());
|
||||
this.openFiles.set(info.path, projectRootPath);
|
||||
|
||||
if (sendConfigFileDiagEvent) {
|
||||
configFileErrors = project.getAllProjectErrors();
|
||||
@@ -2043,11 +2062,14 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private closeConfiguredProject(configFile: NormalizedPath): boolean {
|
||||
private closeConfiguredProjectReferencedFromExternalProject(configFile: NormalizedPath): boolean {
|
||||
const configuredProject = this.findConfiguredProjectByProjectName(configFile);
|
||||
if (configuredProject && configuredProject.deleteOpenRef() === 0) {
|
||||
this.removeProject(configuredProject);
|
||||
return true;
|
||||
if (configuredProject) {
|
||||
configuredProject.deleteExternalProjectReference();
|
||||
if (!configuredProject.hasOpenRef()) {
|
||||
this.removeProject(configuredProject);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2058,7 +2080,7 @@ namespace ts.server {
|
||||
if (configFiles) {
|
||||
let shouldRefreshInferredProjects = false;
|
||||
for (const configFile of configFiles) {
|
||||
if (this.closeConfiguredProject(configFile)) {
|
||||
if (this.closeConfiguredProjectReferencedFromExternalProject(configFile)) {
|
||||
shouldRefreshInferredProjects = true;
|
||||
}
|
||||
}
|
||||
@@ -2253,7 +2275,7 @@ namespace ts.server {
|
||||
const newConfig = tsConfigFiles[iNew];
|
||||
const oldConfig = oldConfigFiles[iOld];
|
||||
if (oldConfig < newConfig) {
|
||||
this.closeConfiguredProject(oldConfig);
|
||||
this.closeConfiguredProjectReferencedFromExternalProject(oldConfig);
|
||||
iOld++;
|
||||
}
|
||||
else if (oldConfig > newConfig) {
|
||||
@@ -2268,7 +2290,7 @@ namespace ts.server {
|
||||
}
|
||||
for (let i = iOld; i < oldConfigFiles.length; i++) {
|
||||
// projects for all remaining old config files should be closed
|
||||
this.closeConfiguredProject(oldConfigFiles[i]);
|
||||
this.closeConfiguredProjectReferencedFromExternalProject(oldConfigFiles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2283,7 +2305,7 @@ namespace ts.server {
|
||||
}
|
||||
if (project && !contains(exisingConfigFiles, tsconfigFile)) {
|
||||
// keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project
|
||||
project.addOpenRef();
|
||||
project.addExternalProjectReference();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+60
-40
@@ -242,6 +242,16 @@ namespace ts.server {
|
||||
this.markAsDirty();
|
||||
}
|
||||
|
||||
isKnownTypesPackageName(name: string): boolean {
|
||||
return this.typingsCache.isKnownTypesPackageName(name);
|
||||
}
|
||||
installPackage(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult> {
|
||||
return this.typingsCache.installPackage({ ...options, projectRootPath: this.toPath(this.currentDirectory) });
|
||||
}
|
||||
private get typingsCache(): TypingsCache {
|
||||
return this.projectService.typingsCache;
|
||||
}
|
||||
|
||||
// Method of LanguageServiceHost
|
||||
getCompilationSettings() {
|
||||
return this.compilerOptions;
|
||||
@@ -433,31 +443,33 @@ namespace ts.server {
|
||||
if (!this.builder) {
|
||||
this.builder = createBuilder({
|
||||
getCanonicalFileName: this.projectService.toCanonicalFileName,
|
||||
getEmitOutput: (_program, sourceFile, emitOnlyDts, isDetailed) =>
|
||||
this.getFileEmitOutput(sourceFile, emitOnlyDts, isDetailed),
|
||||
computeHash: data =>
|
||||
this.projectService.host.createHash(data),
|
||||
shouldEmitFile: sourceFile =>
|
||||
!this.projectService.getScriptInfoForPath(sourceFile.path).isDynamicOrHasMixedContent()
|
||||
computeHash: data => this.projectService.host.createHash(data)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private shouldEmitFile(scriptInfo: ScriptInfo) {
|
||||
return scriptInfo && !scriptInfo.isDynamicOrHasMixedContent();
|
||||
}
|
||||
|
||||
getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[] {
|
||||
if (!this.languageServiceEnabled) {
|
||||
return [];
|
||||
}
|
||||
this.updateGraph();
|
||||
this.ensureBuilder();
|
||||
return this.builder.getFilesAffectedBy(this.program, scriptInfo.path);
|
||||
return mapDefined(this.builder.getFilesAffectedBy(this.program, scriptInfo.path),
|
||||
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if emit was conducted
|
||||
*/
|
||||
emitFile(scriptInfo: ScriptInfo, writeFile: (path: string, data: string, writeByteOrderMark?: boolean) => void): boolean {
|
||||
this.ensureBuilder();
|
||||
const { emitSkipped, outputFiles } = this.builder.emitFile(this.program, scriptInfo.path);
|
||||
if (!this.languageServiceEnabled || !this.shouldEmitFile(scriptInfo)) {
|
||||
return false;
|
||||
}
|
||||
const { emitSkipped, outputFiles } = this.getLanguageService(/*ensureSynchronized*/ false).getEmitOutput(scriptInfo.fileName);
|
||||
if (!emitSkipped) {
|
||||
for (const outputFile of outputFiles) {
|
||||
const outputFileAbsoluteFileName = getNormalizedAbsolutePath(outputFile.name, this.currentDirectory);
|
||||
@@ -583,13 +595,6 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
private getFileEmitOutput(sourceFile: SourceFile, emitOnlyDtsFiles: boolean, isDetailed: boolean) {
|
||||
if (!this.languageServiceEnabled) {
|
||||
return undefined;
|
||||
}
|
||||
return this.getLanguageService(/*ensureSynchronized*/ false).getEmitOutput(sourceFile.fileName, emitOnlyDtsFiles, isDetailed);
|
||||
}
|
||||
|
||||
getExcludedFiles(): ReadonlyArray<NormalizedPath> {
|
||||
return emptyArray;
|
||||
}
|
||||
@@ -898,9 +903,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getScriptInfoForNormalizedPath(fileName: NormalizedPath) {
|
||||
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(
|
||||
fileName, /*scriptKind*/ undefined, /*hasMixedContent*/ undefined, this.directoryStructureHost
|
||||
);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(fileName);
|
||||
if (scriptInfo && !scriptInfo.isAttached(this)) {
|
||||
return Errors.ThrowProjectDoesNotContainDocument(fileName, this);
|
||||
}
|
||||
@@ -908,7 +911,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
getScriptInfo(uncheckedFileName: string) {
|
||||
return this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName));
|
||||
return this.projectService.getScriptInfo(uncheckedFileName);
|
||||
}
|
||||
|
||||
filesToString(writeProjectFileNames: boolean) {
|
||||
@@ -943,16 +946,6 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
reloadScript(filename: NormalizedPath, tempFileName?: NormalizedPath): boolean {
|
||||
const script = this.projectService.getScriptInfoForNormalizedPath(filename);
|
||||
if (script) {
|
||||
Debug.assert(script.isAttached(this));
|
||||
script.reloadFromFile(tempFileName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
getChangesSinceVersion(lastKnownVersion?: number): ProjectFilesWithTSDiagnostics {
|
||||
this.updateGraph();
|
||||
@@ -1061,7 +1054,7 @@ namespace ts.server {
|
||||
projectService: ProjectService,
|
||||
documentRegistry: DocumentRegistry,
|
||||
compilerOptions: CompilerOptions,
|
||||
projectRootPath: string | undefined,
|
||||
projectRootPath: NormalizedPath | undefined,
|
||||
currentDirectory: string | undefined) {
|
||||
super(InferredProject.newName(),
|
||||
ProjectKind.Inferred,
|
||||
@@ -1077,7 +1070,8 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
addRoot(info: ScriptInfo) {
|
||||
this.projectService.startWatchingConfigFilesForInferredProjectRoot(info);
|
||||
Debug.assert(info.isScriptOpen());
|
||||
this.projectService.startWatchingConfigFilesForInferredProjectRoot(info, this.projectService.openFiles.get(info.path));
|
||||
if (!this._isJsInferredProject && info.isJavaScript()) {
|
||||
this.toggleJsInferredProject(/*isJsInferredProject*/ true);
|
||||
}
|
||||
@@ -1136,8 +1130,8 @@ namespace ts.server {
|
||||
|
||||
private plugins: PluginModule[] = [];
|
||||
|
||||
/** Used for configured projects which may have multiple open roots */
|
||||
openRefCount = 0;
|
||||
/** Ref count to the project when opened from external project */
|
||||
private externalProjectRefCount = 0;
|
||||
|
||||
private projectErrors: Diagnostic[];
|
||||
|
||||
@@ -1348,17 +1342,43 @@ namespace ts.server {
|
||||
super.close();
|
||||
}
|
||||
|
||||
addOpenRef() {
|
||||
this.openRefCount++;
|
||||
/* @internal */
|
||||
addExternalProjectReference() {
|
||||
this.externalProjectRefCount++;
|
||||
}
|
||||
|
||||
deleteOpenRef() {
|
||||
this.openRefCount--;
|
||||
return this.openRefCount;
|
||||
/* @internal */
|
||||
deleteExternalProjectReference() {
|
||||
this.externalProjectRefCount--;
|
||||
}
|
||||
|
||||
/** Returns true if the project is needed by any of the open script info/external project */
|
||||
/* @internal */
|
||||
hasOpenRef() {
|
||||
return !!this.openRefCount;
|
||||
if (!!this.externalProjectRefCount) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Closed project doesnt have any reference
|
||||
if (this.isClosed()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const configFileExistenceInfo = this.projectService.getConfigFileExistenceInfo(this);
|
||||
if (this.projectService.hasPendingProjectUpdate(this)) {
|
||||
// If there is pending update for this project,
|
||||
// we dont know if this project would be needed by any of the open files impacted by this config file
|
||||
// In that case keep the project alive if there are open files impacted by this project
|
||||
return !!configFileExistenceInfo.openFilesImpactedByConfigFile.size;
|
||||
}
|
||||
|
||||
// If there is no pending update for this project,
|
||||
// We know exact set of open files that get impacted by this configured project as the files in the project
|
||||
// The project is referenced only if open files impacted by this project are present in this project
|
||||
return forEachEntry(
|
||||
configFileExistenceInfo.openFilesImpactedByConfigFile,
|
||||
(_value, infoPath) => this.containsScriptInfo(this.projectService.getScriptInfoForPath(infoPath as Path))
|
||||
) || false;
|
||||
}
|
||||
|
||||
getEffectiveTypeRoots() {
|
||||
|
||||
+48
-2
@@ -94,6 +94,7 @@ namespace ts.server.protocol {
|
||||
BreakpointStatement = "breakpointStatement",
|
||||
CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects",
|
||||
GetCodeFixes = "getCodeFixes",
|
||||
ApplyCodeActionCommand = "applyCodeActionCommand",
|
||||
/* @internal */
|
||||
GetCodeFixesFull = "getCodeFixes-full",
|
||||
GetSupportedCodeFixes = "getSupportedCodeFixes",
|
||||
@@ -125,6 +126,8 @@ namespace ts.server.protocol {
|
||||
* Client-initiated request message
|
||||
*/
|
||||
export interface Request extends Message {
|
||||
type: "request";
|
||||
|
||||
/**
|
||||
* The command to execute
|
||||
*/
|
||||
@@ -147,6 +150,8 @@ namespace ts.server.protocol {
|
||||
* Server-initiated event message
|
||||
*/
|
||||
export interface Event extends Message {
|
||||
type: "event";
|
||||
|
||||
/**
|
||||
* Name of event
|
||||
*/
|
||||
@@ -162,6 +167,8 @@ namespace ts.server.protocol {
|
||||
* Response by server to client request message.
|
||||
*/
|
||||
export interface Response extends Message {
|
||||
type: "response";
|
||||
|
||||
/**
|
||||
* Sequence number of the request message.
|
||||
*/
|
||||
@@ -178,7 +185,8 @@ namespace ts.server.protocol {
|
||||
command: string;
|
||||
|
||||
/**
|
||||
* Contains error message if success === false.
|
||||
* If success === false, this should always be provided.
|
||||
* Otherwise, may (or may not) contain a success message.
|
||||
*/
|
||||
message?: string;
|
||||
|
||||
@@ -520,6 +528,14 @@ namespace ts.server.protocol {
|
||||
arguments: CodeFixRequestArgs;
|
||||
}
|
||||
|
||||
export interface ApplyCodeActionCommandRequest extends Request {
|
||||
command: CommandTypes.ApplyCodeActionCommand;
|
||||
arguments: ApplyCodeActionCommandRequestArgs;
|
||||
}
|
||||
|
||||
// All we need is the `success` and `message` fields of Response.
|
||||
export interface ApplyCodeActionCommandResponse extends Response {}
|
||||
|
||||
export interface FileRangeRequestArgs extends FileRequestArgs {
|
||||
/**
|
||||
* The line number for the request (1-based).
|
||||
@@ -564,6 +580,10 @@ namespace ts.server.protocol {
|
||||
errorCodes?: number[];
|
||||
}
|
||||
|
||||
export interface ApplyCodeActionCommandRequestArgs extends FileRequestArgs {
|
||||
command: {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Response for GetCodeFixes request.
|
||||
*/
|
||||
@@ -1541,6 +1561,8 @@ namespace ts.server.protocol {
|
||||
description: string;
|
||||
/** Text changes to apply to each file as part of the code action */
|
||||
changes: FileCodeEdits[];
|
||||
/** A command is an opaque object that should be passed to `ApplyCodeActionCommandRequestArgs` without modification. */
|
||||
commands?: {}[];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1603,7 +1625,12 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Names of one or more entries for which to obtain details.
|
||||
*/
|
||||
entryNames: string[];
|
||||
entryNames: (string | CompletionEntryIdentifier)[];
|
||||
}
|
||||
|
||||
export interface CompletionEntryIdentifier {
|
||||
name: string;
|
||||
source: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1658,6 +1685,15 @@ namespace ts.server.protocol {
|
||||
* this span should be used instead of the default one.
|
||||
*/
|
||||
replacementSpan?: TextSpan;
|
||||
/**
|
||||
* Indicates whether commiting this completion entry will require additional code actions to be
|
||||
* made to avoid errors. The CompletionEntryDetails will have these actions.
|
||||
*/
|
||||
hasAction?: true;
|
||||
/**
|
||||
* Identifier (not necessarily human-readable) identifying where this completion came from.
|
||||
*/
|
||||
source?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1690,6 +1726,16 @@ namespace ts.server.protocol {
|
||||
* JSDoc tags for the symbol.
|
||||
*/
|
||||
tags: JSDocTagInfo[];
|
||||
|
||||
/**
|
||||
* The associated code actions for this entry
|
||||
*/
|
||||
codeActions?: CodeAction[];
|
||||
|
||||
/**
|
||||
* Human-readable description of the `source` from the CompletionEntry.
|
||||
*/
|
||||
source?: SymbolDisplayPart[];
|
||||
}
|
||||
|
||||
export interface CompletionsResponse extends Response {
|
||||
|
||||
+24
-22
@@ -67,7 +67,10 @@ namespace ts.server {
|
||||
this.lineMap = undefined;
|
||||
}
|
||||
|
||||
/** returns true if text changed */
|
||||
/**
|
||||
* Set the contents as newText
|
||||
* returns true if text changed
|
||||
*/
|
||||
public reload(newText: string) {
|
||||
Debug.assert(newText !== undefined);
|
||||
|
||||
@@ -87,31 +90,31 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
/** returns true if text changed */
|
||||
public reloadFromDisk() {
|
||||
let reloaded = false;
|
||||
if (!this.pendingReloadFromDisk && !this.ownFileText) {
|
||||
reloaded = this.reload(this.getFileText());
|
||||
this.ownFileText = true;
|
||||
}
|
||||
/**
|
||||
* Reads the contents from tempFile(if supplied) or own file and sets it as contents
|
||||
* returns true if text changed
|
||||
*/
|
||||
public reloadWithFileText(tempFileName?: string) {
|
||||
const reloaded = this.reload(this.getFileText(tempFileName));
|
||||
this.ownFileText = !tempFileName || tempFileName === this.fileName;
|
||||
return reloaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reloads the contents from the file if there is no pending reload from disk or the contents of file are same as file text
|
||||
* returns true if text changed
|
||||
*/
|
||||
public reloadFromDisk() {
|
||||
if (!this.pendingReloadFromDisk && !this.ownFileText) {
|
||||
return this.reloadWithFileText();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public delayReloadFromFileIntoText() {
|
||||
this.pendingReloadFromDisk = true;
|
||||
}
|
||||
|
||||
/** returns true if text changed */
|
||||
public reloadFromFile(tempFileName: string) {
|
||||
let reloaded = false;
|
||||
// Reload if different file or we dont know if we are working with own file text
|
||||
if (tempFileName !== this.fileName || !this.ownFileText) {
|
||||
reloaded = this.reload(this.getFileText(tempFileName));
|
||||
this.ownFileText = !tempFileName || tempFileName === this.fileName;
|
||||
}
|
||||
return reloaded;
|
||||
}
|
||||
|
||||
public getSnapshot(): IScriptSnapshot {
|
||||
return this.useScriptVersionCacheIfValidOrOpen()
|
||||
? this.svc.getSnapshot()
|
||||
@@ -180,8 +183,7 @@ namespace ts.server {
|
||||
private getOrLoadText() {
|
||||
if (this.text === undefined || this.pendingReloadFromDisk) {
|
||||
Debug.assert(!this.svc || this.pendingReloadFromDisk, "ScriptVersionCache should not be set when reloading from disk");
|
||||
this.reload(this.getFileText());
|
||||
this.ownFileText = true;
|
||||
this.reloadWithFileText();
|
||||
}
|
||||
return this.text;
|
||||
}
|
||||
@@ -385,7 +387,7 @@ namespace ts.server {
|
||||
this.markContainingProjectsAsDirty();
|
||||
}
|
||||
else {
|
||||
if (this.textStorage.reloadFromFile(tempFileName)) {
|
||||
if (this.textStorage.reloadWithFileText(tempFileName)) {
|
||||
this.markContainingProjectsAsDirty();
|
||||
}
|
||||
}
|
||||
|
||||
+59
-13
@@ -250,6 +250,9 @@ namespace ts.server {
|
||||
private activeRequestCount = 0;
|
||||
private requestQueue: QueuedOperation[] = [];
|
||||
private requestMap = createMap<QueuedOperation>(); // Maps operation ID to newest requestQueue entry with that ID
|
||||
/** We will lazily request the types registry on the first call to `isKnownTypesPackageName` and store it in `typesRegistryCache`. */
|
||||
private requestedRegistry: boolean;
|
||||
private typesRegistryCache: Map<void> | undefined;
|
||||
|
||||
// This number is essentially arbitrary. Processing more than one typings request
|
||||
// at a time makes sense, but having too many in the pipe results in a hang
|
||||
@@ -258,7 +261,7 @@ namespace ts.server {
|
||||
// buffer, but we have yet to find a way to retrieve that value.
|
||||
private static readonly maxActiveRequestCount = 10;
|
||||
private static readonly requestDelayMillis = 100;
|
||||
|
||||
private packageInstalledPromise: { resolve(value: ApplyCodeActionCommandResult): void, reject(reason: any): void };
|
||||
|
||||
constructor(
|
||||
private readonly telemetryEnabled: boolean,
|
||||
@@ -278,6 +281,31 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
isKnownTypesPackageName(name: string): boolean {
|
||||
// We want to avoid looking this up in the registry as that is expensive. So first check that it's actually an NPM package.
|
||||
const validationResult = JsTyping.validatePackageName(name);
|
||||
if (validationResult !== JsTyping.PackageNameValidationResult.Ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.requestedRegistry) {
|
||||
return !!this.typesRegistryCache && this.typesRegistryCache.has(name);
|
||||
}
|
||||
|
||||
this.requestedRegistry = true;
|
||||
this.send({ kind: "typesRegistry" });
|
||||
return false;
|
||||
}
|
||||
|
||||
installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise<ApplyCodeActionCommandResult> {
|
||||
const rq: InstallPackageRequest = { kind: "installPackage", ...options };
|
||||
this.send(rq);
|
||||
Debug.assert(this.packageInstalledPromise === undefined);
|
||||
return new Promise((resolve, reject) => {
|
||||
this.packageInstalledPromise = { resolve, reject };
|
||||
});
|
||||
}
|
||||
|
||||
private reportInstallerProcessId() {
|
||||
if (this.installerPidReported) {
|
||||
return;
|
||||
@@ -321,13 +349,13 @@ namespace ts.server {
|
||||
|
||||
const execArgv: string[] = [];
|
||||
for (const arg of process.execArgv) {
|
||||
const match = /^--(debug|inspect)(=(\d+))?$/.exec(arg);
|
||||
const match = /^--((?:debug|inspect)(?:-brk)?)(?:=(\d+))?$/.exec(arg);
|
||||
if (match) {
|
||||
// if port is specified - use port + 1
|
||||
// otherwise pick a default port depending on if 'debug' or 'inspect' and use its value + 1
|
||||
const currentPort = match[3] !== undefined
|
||||
? +match[3]
|
||||
: match[1] === "debug" ? 5858 : 9229;
|
||||
const currentPort = match[2] !== undefined
|
||||
? +match[2]
|
||||
: match[1].charAt(0) === "d" ? 5858 : 9229;
|
||||
execArgv.push(`--${match[1]}=${currentPort + 1}`);
|
||||
break;
|
||||
}
|
||||
@@ -343,23 +371,27 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
onProjectClosed(p: Project): void {
|
||||
this.installer.send({ projectName: p.getProjectName(), kind: "closeProject" });
|
||||
this.send({ projectName: p.getProjectName(), kind: "closeProject" });
|
||||
}
|
||||
|
||||
private send(rq: TypingInstallerRequestUnion): void {
|
||||
this.installer.send(rq);
|
||||
}
|
||||
|
||||
enqueueInstallTypingsRequest(project: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>): void {
|
||||
const request = createInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Scheduling throttled operation: ${JSON.stringify(request)}`);
|
||||
this.logger.info(`Scheduling throttled operation:${stringifyIndented(request)}`);
|
||||
}
|
||||
}
|
||||
|
||||
const operationId = project.getProjectName();
|
||||
const operation = () => {
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Sending request: ${JSON.stringify(request)}`);
|
||||
this.logger.info(`Sending request:${stringifyIndented(request)}`);
|
||||
}
|
||||
this.installer.send(request);
|
||||
this.send(request);
|
||||
};
|
||||
const queuedRequest: QueuedOperation = { operationId, operation };
|
||||
|
||||
@@ -375,12 +407,26 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private handleMessage(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse) {
|
||||
private handleMessage(response: TypesRegistryResponse | PackageInstalledResponse | SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse) {
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`Received response: ${JSON.stringify(response)}`);
|
||||
this.logger.info(`Received response:${stringifyIndented(response)}`);
|
||||
}
|
||||
|
||||
switch (response.kind) {
|
||||
case EventTypesRegistry:
|
||||
this.typesRegistryCache = ts.createMapFromTemplate(response.typesRegistry);
|
||||
break;
|
||||
case EventPackageInstalled: {
|
||||
const { success, message } = response;
|
||||
if (success) {
|
||||
this.packageInstalledPromise.resolve({ successMessage: message });
|
||||
}
|
||||
else {
|
||||
this.packageInstalledPromise.reject(message);
|
||||
}
|
||||
this.packageInstalledPromise = undefined;
|
||||
break;
|
||||
}
|
||||
case EventInitializationFailed:
|
||||
{
|
||||
if (!this.eventSender) {
|
||||
@@ -580,7 +626,7 @@ namespace ts.server {
|
||||
function createLogger() {
|
||||
const cmdLineLogFileName = findArgument("--logFile");
|
||||
const cmdLineVerbosity = getLogLevel(findArgument("--logVerbosity"));
|
||||
const envLogOptions = parseLoggingEnvironmentString(process.env["TSS_LOG"]);
|
||||
const envLogOptions = parseLoggingEnvironmentString(process.env.TSS_LOG);
|
||||
|
||||
const logFileName = cmdLineLogFileName
|
||||
? stripQuotes(cmdLineLogFileName)
|
||||
@@ -780,7 +826,7 @@ namespace ts.server {
|
||||
try {
|
||||
const args = [combinePaths(__dirname, "watchGuard.js"), path];
|
||||
if (logger.hasLevel(LogLevel.verbose)) {
|
||||
logger.info(`Starting ${process.execPath} with args ${JSON.stringify(args)}`);
|
||||
logger.info(`Starting ${process.execPath} with args:${stringifyIndented(args)}`);
|
||||
}
|
||||
childProcess.execFileSync(process.execPath, args, { stdio: "ignore", env: { "ELECTRON_RUN_AS_NODE": "1" } });
|
||||
status = true;
|
||||
|
||||
+111
-48
@@ -131,7 +131,7 @@ namespace ts.server {
|
||||
|
||||
const json = JSON.stringify(msg);
|
||||
if (verboseLogging) {
|
||||
logger.info(msg.type + ": " + json);
|
||||
logger.info(`${msg.type}:${indent(json)}`);
|
||||
}
|
||||
|
||||
const len = byteLength(json, "utf8");
|
||||
@@ -383,9 +383,9 @@ namespace ts.server {
|
||||
public logError(err: Error, cmd: string) {
|
||||
let msg = "Exception on executing command " + cmd;
|
||||
if (err.message) {
|
||||
msg += ":\n" + err.message;
|
||||
msg += ":\n" + indent(err.message);
|
||||
if ((<StackTraceError>err).stack) {
|
||||
msg += "\n" + (<StackTraceError>err).stack;
|
||||
msg += "\n" + indent((<StackTraceError>err).stack);
|
||||
}
|
||||
}
|
||||
this.logger.msg(msg, Msg.Err);
|
||||
@@ -411,19 +411,27 @@ namespace ts.server {
|
||||
this.send(ev);
|
||||
}
|
||||
|
||||
public output(info: any, cmdName: string, reqSeq = 0, errorMsg?: string) {
|
||||
// For backwards-compatibility only.
|
||||
public output(info: any, cmdName: string, reqSeq?: number, errorMsg?: string): void {
|
||||
this.doOutput(info, cmdName, reqSeq, /*success*/ !errorMsg, errorMsg);
|
||||
}
|
||||
|
||||
private doOutput(info: {} | undefined, cmdName: string, reqSeq: number, success: boolean, message?: string): void {
|
||||
const res: protocol.Response = {
|
||||
seq: 0,
|
||||
type: "response",
|
||||
command: cmdName,
|
||||
request_seq: reqSeq,
|
||||
success: !errorMsg,
|
||||
success,
|
||||
};
|
||||
if (!errorMsg) {
|
||||
if (success) {
|
||||
res.body = info;
|
||||
}
|
||||
else {
|
||||
res.message = errorMsg;
|
||||
Debug.assert(info === undefined);
|
||||
}
|
||||
if (message) {
|
||||
res.message = message;
|
||||
}
|
||||
this.send(res);
|
||||
}
|
||||
@@ -1178,11 +1186,12 @@ namespace ts.server {
|
||||
|
||||
const completions = project.getLanguageService().getCompletionsAtPosition(file, position);
|
||||
if (simplifiedResult) {
|
||||
return mapDefined(completions && completions.entries, entry => {
|
||||
return mapDefined<CompletionEntry, protocol.CompletionEntry>(completions && completions.entries, entry => {
|
||||
if (completions.isMemberCompletion || (entry.name.toLowerCase().indexOf(prefix.toLowerCase()) === 0)) {
|
||||
const { name, kind, kindModifiers, sortText, replacementSpan } = entry;
|
||||
const { name, kind, kindModifiers, sortText, replacementSpan, hasAction, source } = entry;
|
||||
const convertedSpan = replacementSpan ? this.decorateSpan(replacementSpan, scriptInfo) : undefined;
|
||||
return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan };
|
||||
// Use `hasAction || undefined` to avoid serializing `false`.
|
||||
return { name, kind, kindModifiers, sortText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source };
|
||||
}
|
||||
}).sort((a, b) => compareStrings(a.name, b.name));
|
||||
}
|
||||
@@ -1193,10 +1202,21 @@ namespace ts.server {
|
||||
|
||||
private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs): ReadonlyArray<protocol.CompletionEntryDetails> {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const position = this.getPositionInFile(args, file);
|
||||
const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
const position = this.getPosition(args, scriptInfo);
|
||||
const formattingOptions = project.projectService.getFormatCodeOptions(file);
|
||||
|
||||
return mapDefined(args.entryNames, entryName =>
|
||||
project.getLanguageService().getCompletionEntryDetails(file, position, entryName));
|
||||
return mapDefined<string | protocol.CompletionEntryIdentifier, protocol.CompletionEntryDetails>(args.entryNames, entryName => {
|
||||
const { name, source } = typeof entryName === "string" ? { name: entryName, source: undefined } : entryName;
|
||||
const details = project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source);
|
||||
if (details) {
|
||||
const mappedCodeActions = map(details.codeActions, action => this.mapCodeAction(action, scriptInfo));
|
||||
return { ...details, codeActions: mappedCodeActions };
|
||||
}
|
||||
else {
|
||||
return undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getCompileOnSaveAffectedFileList(args: protocol.FileRequestArgs): ReadonlyArray<protocol.CompileOnSaveAffectedFileListSingleProject> {
|
||||
@@ -1292,11 +1312,13 @@ namespace ts.server {
|
||||
private reload(args: protocol.ReloadRequestArgs, reqSeq: number) {
|
||||
const file = toNormalizedPath(args.file);
|
||||
const tempFileName = args.tmpfile && toNormalizedPath(args.tmpfile);
|
||||
const project = this.projectService.getDefaultProjectForFile(file, /*ensureProject*/ true);
|
||||
this.changeSeq++;
|
||||
// make sure no changes happen before this one is finished
|
||||
if (project.reloadScript(file, tempFileName)) {
|
||||
this.output(undefined, CommandNames.Reload, reqSeq);
|
||||
const info = this.projectService.getScriptInfoForNormalizedPath(file);
|
||||
if (info) {
|
||||
this.changeSeq++;
|
||||
// make sure no changes happen before this one is finished
|
||||
if (info.reloadFromFile(tempFileName)) {
|
||||
this.doOutput(/*info*/ undefined, CommandNames.Reload, reqSeq, /*success*/ true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1495,16 +1517,18 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
if (simplifiedResult) {
|
||||
const file = result.renameFilename;
|
||||
let location: protocol.Location | undefined;
|
||||
if (file !== undefined && result.renameLocation !== undefined) {
|
||||
const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(file));
|
||||
location = renameScriptInfo.positionToLineOffset(result.renameLocation);
|
||||
const { renameFilename, renameLocation, edits } = result;
|
||||
let mappedRenameLocation: protocol.Location | undefined;
|
||||
if (renameFilename !== undefined && renameLocation !== undefined) {
|
||||
const renameScriptInfo = project.getScriptInfoForNormalizedPath(toNormalizedPath(renameFilename));
|
||||
const snapshot = renameScriptInfo.getSnapshot();
|
||||
const oldText = snapshot.getText(0, snapshot.getLength());
|
||||
mappedRenameLocation = getLocationInNewDocument(oldText, renameFilename, renameLocation, edits);
|
||||
}
|
||||
return {
|
||||
renameLocation: location,
|
||||
renameFilename: file,
|
||||
edits: result.edits.map(change => this.mapTextChangesToCodeEdits(project, change))
|
||||
renameLocation: mappedRenameLocation,
|
||||
renameFilename,
|
||||
edits: edits.map(change => this.mapTextChangesToCodeEdits(project, change))
|
||||
};
|
||||
}
|
||||
else {
|
||||
@@ -1534,6 +1558,15 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
private applyCodeActionCommand(commandName: string, requestSeq: number, args: protocol.ApplyCodeActionCommandRequestArgs): void {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
const output = (success: boolean, message: string) => this.doOutput({}, commandName, requestSeq, success, message);
|
||||
const command = args.command as CodeActionCommand; // They should be sending back the command we sent them.
|
||||
project.getLanguageService().applyCodeActionCommand(file, command).then(
|
||||
({ successMessage }) => { output(/*success*/ true, successMessage); },
|
||||
error => { output(/*success*/ false, error); });
|
||||
}
|
||||
|
||||
private getStartAndEndPosition(args: protocol.FileRangeRequestArgs, scriptInfo: ScriptInfo) {
|
||||
let startPosition: number = undefined, endPosition: number = undefined;
|
||||
if (args.startPosition !== undefined) {
|
||||
@@ -1556,14 +1589,12 @@ namespace ts.server {
|
||||
return { startPosition, endPosition };
|
||||
}
|
||||
|
||||
private mapCodeAction(codeAction: CodeAction, scriptInfo: ScriptInfo): protocol.CodeAction {
|
||||
return {
|
||||
description: codeAction.description,
|
||||
changes: codeAction.changes.map(change => ({
|
||||
fileName: change.fileName,
|
||||
textChanges: change.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo))
|
||||
}))
|
||||
};
|
||||
private mapCodeAction({ description, changes: unmappedChanges, commands }: CodeAction, scriptInfo: ScriptInfo): protocol.CodeAction {
|
||||
const changes = unmappedChanges.map(change => ({
|
||||
fileName: change.fileName,
|
||||
textChanges: change.textChanges.map(textChange => this.convertTextChangeToCodeEdit(textChange, scriptInfo))
|
||||
}));
|
||||
return { description, changes, commands };
|
||||
}
|
||||
|
||||
private mapTextChangesToCodeEdits(project: Project, textChanges: FileTextChanges): protocol.FileCodeEdits {
|
||||
@@ -1649,15 +1680,15 @@ namespace ts.server {
|
||||
exit() {
|
||||
}
|
||||
|
||||
private notRequired() {
|
||||
private notRequired(): HandlerResponse {
|
||||
return { responseRequired: false };
|
||||
}
|
||||
|
||||
private requiredResponse(response: any) {
|
||||
private requiredResponse(response: {}): HandlerResponse {
|
||||
return { response, responseRequired: true };
|
||||
}
|
||||
|
||||
private handlers = createMapFromTemplate<(request: protocol.Request) => { response?: any, responseRequired?: boolean }>({
|
||||
private handlers = createMapFromTemplate<(request: protocol.Request) => HandlerResponse>({
|
||||
[CommandNames.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => {
|
||||
this.projectService.openExternalProject(request.arguments, /*suppressRefreshOfInferredProjects*/ false);
|
||||
// TODO: report errors
|
||||
@@ -1835,7 +1866,7 @@ namespace ts.server {
|
||||
},
|
||||
[CommandNames.Configure]: (request: protocol.ConfigureRequest) => {
|
||||
this.projectService.setHostConfiguration(request.arguments);
|
||||
this.output(undefined, CommandNames.Configure, request.seq);
|
||||
this.doOutput(/*info*/ undefined, CommandNames.Configure, request.seq, /*success*/ true);
|
||||
return this.notRequired();
|
||||
},
|
||||
[CommandNames.Reload]: (request: protocol.ReloadRequest) => {
|
||||
@@ -1902,6 +1933,10 @@ namespace ts.server {
|
||||
[CommandNames.GetCodeFixesFull]: (request: protocol.CodeFixRequest) => {
|
||||
return this.requiredResponse(this.getCodeFixes(request.arguments, /*simplifiedResult*/ false));
|
||||
},
|
||||
[CommandNames.ApplyCodeActionCommand]: (request: protocol.ApplyCodeActionCommandRequest) => {
|
||||
this.applyCodeActionCommand(request.command, request.seq, request.arguments);
|
||||
return this.notRequired(); // Response will come asynchronously.
|
||||
},
|
||||
[CommandNames.GetSupportedCodeFixes]: () => {
|
||||
return this.requiredResponse(this.getSupportedCodeFixes());
|
||||
},
|
||||
@@ -1916,7 +1951,7 @@ namespace ts.server {
|
||||
}
|
||||
});
|
||||
|
||||
public addProtocolHandler(command: string, handler: (request: protocol.Request) => { response?: any, responseRequired: boolean }) {
|
||||
public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse) {
|
||||
if (this.handlers.has(command)) {
|
||||
throw new Error(`Protocol handler already exists for command "${command}"`);
|
||||
}
|
||||
@@ -1945,14 +1980,14 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
public executeCommand(request: protocol.Request): { response?: any, responseRequired?: boolean } {
|
||||
public executeCommand(request: protocol.Request): HandlerResponse {
|
||||
const handler = this.handlers.get(request.command);
|
||||
if (handler) {
|
||||
return this.executeWithRequestId(request.seq, () => handler(request));
|
||||
}
|
||||
else {
|
||||
this.logger.msg(`Unrecognized JSON command: ${JSON.stringify(request)}`, Msg.Err);
|
||||
this.output(undefined, CommandNames.Unknown, request.seq, `Unrecognized JSON command: ${request.command}`);
|
||||
this.logger.msg(`Unrecognized JSON command:${stringifyIndented(request)}`, Msg.Err);
|
||||
this.doOutput(/*info*/ undefined, CommandNames.Unknown, request.seq, /*success*/ false, `Unrecognized JSON command: ${request.command}`);
|
||||
return { responseRequired: false };
|
||||
}
|
||||
}
|
||||
@@ -1963,7 +1998,7 @@ namespace ts.server {
|
||||
if (this.logger.hasLevel(LogLevel.requestTime)) {
|
||||
start = this.hrtime();
|
||||
if (this.logger.hasLevel(LogLevel.verbose)) {
|
||||
this.logger.info(`request: ${message}`);
|
||||
this.logger.info(`request:${indent(message)}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1983,25 +2018,53 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
if (response) {
|
||||
this.output(response, request.command, request.seq);
|
||||
this.doOutput(response, request.command, request.seq, /*success*/ true);
|
||||
}
|
||||
else if (responseRequired) {
|
||||
this.output(undefined, request.command, request.seq, "No content available.");
|
||||
this.doOutput(/*info*/ undefined, request.command, request.seq, /*success*/ false, "No content available.");
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
if (err instanceof OperationCanceledException) {
|
||||
// Handle cancellation exceptions
|
||||
this.output({ canceled: true }, request.command, request.seq);
|
||||
this.doOutput({ canceled: true }, request.command, request.seq, /*success*/ true);
|
||||
return;
|
||||
}
|
||||
this.logError(err, message);
|
||||
this.output(
|
||||
undefined,
|
||||
this.doOutput(
|
||||
/*info*/ undefined,
|
||||
request ? request.command : CommandNames.Unknown,
|
||||
request ? request.seq : 0,
|
||||
/*success*/ false,
|
||||
"Error processing request. " + (<StackTraceError>err).message + "\n" + (<StackTraceError>err).stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface HandlerResponse {
|
||||
response?: {};
|
||||
responseRequired?: boolean;
|
||||
}
|
||||
|
||||
/* @internal */ // Exported only for tests
|
||||
export function getLocationInNewDocument(oldText: string, renameFilename: string, renameLocation: number, edits: ReadonlyArray<FileTextChanges>): protocol.Location {
|
||||
const newText = applyEdits(oldText, renameFilename, edits);
|
||||
const { line, character } = computeLineAndCharacterOfPosition(computeLineStarts(newText), renameLocation);
|
||||
return { line: line + 1, offset: character + 1 };
|
||||
}
|
||||
|
||||
function applyEdits(text: string, textFilename: string, edits: ReadonlyArray<FileTextChanges>): string {
|
||||
for (const { fileName, textChanges } of edits) {
|
||||
if (fileName !== textFilename) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let i = textChanges.length - 1; i >= 0; i--) {
|
||||
const { newText, span: { start, length } } = textChanges[i];
|
||||
text = text.slice(0, start) + newText + text.slice(start + length);
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
namespace ts.server {
|
||||
export const ActionSet: ActionSet = "action::set";
|
||||
export const ActionInvalidate: ActionInvalidate = "action::invalidate";
|
||||
export const EventTypesRegistry: EventTypesRegistry = "event::typesRegistry";
|
||||
export const EventPackageInstalled: EventPackageInstalled = "event::packageInstalled";
|
||||
export const EventBeginInstallTypes: EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
export const EventEndInstallTypes: EventEndInstallTypes = "event::endInstallTypes";
|
||||
export const EventInitializationFailed: EventInitializationFailed = "event::initializationFailed";
|
||||
|
||||
+35
-5
@@ -28,12 +28,14 @@ declare namespace ts.server {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
|
||||
export interface TypingInstallerRequest {
|
||||
export interface TypingInstallerRequestWithProjectName {
|
||||
readonly projectName: string;
|
||||
readonly kind: "discover" | "closeProject";
|
||||
}
|
||||
|
||||
export interface DiscoverTypings extends TypingInstallerRequest {
|
||||
/* @internal */
|
||||
export type TypingInstallerRequestUnion = DiscoverTypings | CloseProject | TypesRegistryRequest | InstallPackageRequest;
|
||||
|
||||
export interface DiscoverTypings extends TypingInstallerRequestWithProjectName {
|
||||
readonly fileNames: string[];
|
||||
readonly projectRootPath: Path;
|
||||
readonly compilerOptions: CompilerOptions;
|
||||
@@ -43,18 +45,46 @@ declare namespace ts.server {
|
||||
readonly kind: "discover";
|
||||
}
|
||||
|
||||
export interface CloseProject extends TypingInstallerRequest {
|
||||
export interface CloseProject extends TypingInstallerRequestWithProjectName {
|
||||
readonly kind: "closeProject";
|
||||
}
|
||||
|
||||
export interface TypesRegistryRequest {
|
||||
readonly kind: "typesRegistry";
|
||||
}
|
||||
|
||||
export interface InstallPackageRequest {
|
||||
readonly kind: "installPackage";
|
||||
readonly fileName: Path;
|
||||
readonly packageName: string;
|
||||
readonly projectRootPath: Path;
|
||||
}
|
||||
|
||||
export type ActionSet = "action::set";
|
||||
export type ActionInvalidate = "action::invalidate";
|
||||
export type EventTypesRegistry = "event::typesRegistry";
|
||||
export type EventPackageInstalled = "event::packageInstalled";
|
||||
export type EventBeginInstallTypes = "event::beginInstallTypes";
|
||||
export type EventEndInstallTypes = "event::endInstallTypes";
|
||||
export type EventInitializationFailed = "event::initializationFailed";
|
||||
|
||||
export interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | EventPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
}
|
||||
/* @internal */
|
||||
export type TypingInstallerResponseUnion = SetTypings | InvalidateCachedTypings | TypesRegistryResponse | PackageInstalledResponse | InstallTypes | InitializationFailedResponse;
|
||||
|
||||
/* @internal */
|
||||
export interface TypesRegistryResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventTypesRegistry;
|
||||
readonly typesRegistry: MapLike<void>;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface PackageInstalledResponse extends TypingInstallerResponse {
|
||||
readonly kind: EventPackageInstalled;
|
||||
readonly success: boolean;
|
||||
readonly message: string;
|
||||
}
|
||||
|
||||
export interface InitializationFailedResponse extends TypingInstallerResponse {
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
/// <reference path="project.ts"/>
|
||||
|
||||
namespace ts.server {
|
||||
export interface InstallPackageOptionsWithProjectRootPath extends InstallPackageOptions {
|
||||
projectRootPath: Path;
|
||||
}
|
||||
|
||||
export interface ITypingsInstaller {
|
||||
isKnownTypesPackageName(name: string): boolean;
|
||||
installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise<ApplyCodeActionCommandResult>;
|
||||
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>): void;
|
||||
attach(projectService: ProjectService): void;
|
||||
onProjectClosed(p: Project): void;
|
||||
@@ -9,6 +15,9 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export const nullTypingsInstaller: ITypingsInstaller = {
|
||||
isKnownTypesPackageName: returnFalse,
|
||||
// Should never be called because we never provide a types registry.
|
||||
installPackage: notImplemented,
|
||||
enqueueInstallTypingsRequest: noop,
|
||||
attach: noop,
|
||||
onProjectClosed: noop,
|
||||
@@ -77,6 +86,14 @@ namespace ts.server {
|
||||
constructor(private readonly installer: ITypingsInstaller) {
|
||||
}
|
||||
|
||||
isKnownTypesPackageName(name: string): boolean {
|
||||
return this.installer.isKnownTypesPackageName(name);
|
||||
}
|
||||
|
||||
installPackage(options: InstallPackageOptionsWithProjectRootPath): Promise<ApplyCodeActionCommandResult> {
|
||||
return this.installer.installPackage(options);
|
||||
}
|
||||
|
||||
getTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string>, forceRefresh: boolean): SortedReadonlyArray<string> {
|
||||
const typeAcquisition = project.getTypeAcquisition();
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
try {
|
||||
const content = <TypesRegistryFile>JSON.parse(host.readFile(typesRegistryFilePath));
|
||||
return createMapFromTemplate<void>(content.entries);
|
||||
return createMapFromTemplate(content.entries);
|
||||
}
|
||||
catch (e) {
|
||||
if (log.isEnabled()) {
|
||||
@@ -79,7 +79,7 @@ namespace ts.server.typingsInstaller {
|
||||
private readonly npmPath: string;
|
||||
readonly typesRegistry: Map<void>;
|
||||
|
||||
private delayedInitializationError: InitializationFailedResponse;
|
||||
private delayedInitializationError: InitializationFailedResponse | undefined;
|
||||
|
||||
constructor(globalTypingsCacheLocation: string, typingSafeListLocation: string, typesMapLocation: string, npmLocation: string | undefined, throttleLimit: number, log: Log) {
|
||||
super(
|
||||
@@ -127,7 +127,7 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
|
||||
listen() {
|
||||
process.on("message", (req: DiscoverTypings | CloseProject) => {
|
||||
process.on("message", (req: TypingInstallerRequestUnion) => {
|
||||
if (this.delayedInitializationError) {
|
||||
// report initializationFailed error
|
||||
this.sendResponse(this.delayedInitializationError);
|
||||
@@ -139,13 +139,41 @@ namespace ts.server.typingsInstaller {
|
||||
break;
|
||||
case "closeProject":
|
||||
this.closeProject(req);
|
||||
break;
|
||||
case "typesRegistry": {
|
||||
const typesRegistry: { [key: string]: void } = {};
|
||||
this.typesRegistry.forEach((value, key) => {
|
||||
typesRegistry[key] = value;
|
||||
});
|
||||
const response: TypesRegistryResponse = { kind: EventTypesRegistry, typesRegistry };
|
||||
this.sendResponse(response);
|
||||
break;
|
||||
}
|
||||
case "installPackage": {
|
||||
const { fileName, packageName, projectRootPath } = req;
|
||||
const cwd = getDirectoryOfPackageJson(fileName, this.installTypingHost) || projectRootPath;
|
||||
if (cwd) {
|
||||
this.installWorker(-1, [packageName], cwd, success => {
|
||||
const message = success ? `Package ${packageName} installed.` : `There was an error installing ${packageName}.`;
|
||||
const response: PackageInstalledResponse = { kind: EventPackageInstalled, success, message };
|
||||
this.sendResponse(response);
|
||||
});
|
||||
}
|
||||
else {
|
||||
const response: PackageInstalledResponse = { kind: EventPackageInstalled, success: false, message: "Could not determine a project root path." };
|
||||
this.sendResponse(response);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
Debug.assertNever(req);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse) {
|
||||
protected sendResponse(response: TypingInstallerResponseUnion) {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`Sending response: ${JSON.stringify(response)}`);
|
||||
this.log.writeLine(`Sending response:\n ${JSON.stringify(response)}`);
|
||||
}
|
||||
process.send(response);
|
||||
if (this.log.isEnabled()) {
|
||||
@@ -153,11 +181,11 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
protected installWorker(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void {
|
||||
protected installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void {
|
||||
if (this.log.isEnabled()) {
|
||||
this.log.writeLine(`#${requestId} with arguments'${JSON.stringify(args)}'.`);
|
||||
this.log.writeLine(`#${requestId} with arguments'${JSON.stringify(packageNames)}'.`);
|
||||
}
|
||||
const command = `${this.npmPath} install --ignore-scripts ${args.join(" ")} --save-dev --user-agent="typesInstaller/${version}"`;
|
||||
const command = `${this.npmPath} install --ignore-scripts ${packageNames.join(" ")} --save-dev --user-agent="typesInstaller/${version}"`;
|
||||
const start = Date.now();
|
||||
const hasError = this.execSyncAndLog(command, { cwd });
|
||||
if (this.log.isEnabled()) {
|
||||
@@ -186,6 +214,14 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
function getDirectoryOfPackageJson(fileName: string, host: InstallTypingHost): string | undefined {
|
||||
return forEachAncestorDirectory(getDirectoryPath(fileName), directory => {
|
||||
if (host.fileExists(combinePaths(directory, "package.json"))) {
|
||||
return directory;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const logFilePath = findArgument(server.Arguments.LogFile);
|
||||
const globalTypingsCacheLocation = findArgument(server.Arguments.GlobalCacheLocation);
|
||||
const typingSafeListLocation = findArgument(server.Arguments.TypingSafeListLocation);
|
||||
|
||||
@@ -32,50 +32,11 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
export enum PackageNameValidationResult {
|
||||
Ok,
|
||||
ScopedPackagesNotSupported,
|
||||
EmptyName,
|
||||
NameTooLong,
|
||||
NameStartsWithDot,
|
||||
NameStartsWithUnderscore,
|
||||
NameContainsNonURISafeCharacters
|
||||
}
|
||||
|
||||
|
||||
export const MaxPackageNameLength = 214;
|
||||
/**
|
||||
* Validates package name using rules defined at https://docs.npmjs.com/files/package.json
|
||||
*/
|
||||
export function validatePackageName(packageName: string): PackageNameValidationResult {
|
||||
if (!packageName) {
|
||||
return PackageNameValidationResult.EmptyName;
|
||||
}
|
||||
if (packageName.length > MaxPackageNameLength) {
|
||||
return PackageNameValidationResult.NameTooLong;
|
||||
}
|
||||
if (packageName.charCodeAt(0) === CharacterCodes.dot) {
|
||||
return PackageNameValidationResult.NameStartsWithDot;
|
||||
}
|
||||
if (packageName.charCodeAt(0) === CharacterCodes._) {
|
||||
return PackageNameValidationResult.NameStartsWithUnderscore;
|
||||
}
|
||||
// check if name is scope package like: starts with @ and has one '/' in the middle
|
||||
// scoped packages are not currently supported
|
||||
// TODO: when support will be added we'll need to split and check both scope and package name
|
||||
if (/^@[^/]+\/[^/]+$/.test(packageName)) {
|
||||
return PackageNameValidationResult.ScopedPackagesNotSupported;
|
||||
}
|
||||
if (encodeURIComponent(packageName) !== packageName) {
|
||||
return PackageNameValidationResult.NameContainsNonURISafeCharacters;
|
||||
}
|
||||
return PackageNameValidationResult.Ok;
|
||||
}
|
||||
|
||||
export type RequestCompletedAction = (success: boolean) => void;
|
||||
interface PendingRequest {
|
||||
requestId: number;
|
||||
args: string[];
|
||||
packageNames: string[];
|
||||
cwd: string;
|
||||
onRequestCompleted: RequestCompletedAction;
|
||||
}
|
||||
@@ -255,8 +216,8 @@ namespace ts.server.typingsInstaller {
|
||||
if (this.missingTypingsSet.get(typing) || this.packageNameToTypingLocation.get(typing)) {
|
||||
continue;
|
||||
}
|
||||
const validationResult = validatePackageName(typing);
|
||||
if (validationResult === PackageNameValidationResult.Ok) {
|
||||
const validationResult = JsTyping.validatePackageName(typing);
|
||||
if (validationResult === JsTyping.PackageNameValidationResult.Ok) {
|
||||
if (this.typesRegistry.has(typing)) {
|
||||
result.push(typing);
|
||||
}
|
||||
@@ -270,26 +231,7 @@ namespace ts.server.typingsInstaller {
|
||||
// add typing name to missing set so we won't process it again
|
||||
this.missingTypingsSet.set(typing, true);
|
||||
if (this.log.isEnabled()) {
|
||||
switch (validationResult) {
|
||||
case PackageNameValidationResult.EmptyName:
|
||||
this.log.writeLine(`Package name '${typing}' cannot be empty`);
|
||||
break;
|
||||
case PackageNameValidationResult.NameTooLong:
|
||||
this.log.writeLine(`Package name '${typing}' should be less than ${MaxPackageNameLength} characters`);
|
||||
break;
|
||||
case PackageNameValidationResult.NameStartsWithDot:
|
||||
this.log.writeLine(`Package name '${typing}' cannot start with '.'`);
|
||||
break;
|
||||
case PackageNameValidationResult.NameStartsWithUnderscore:
|
||||
this.log.writeLine(`Package name '${typing}' cannot start with '_'`);
|
||||
break;
|
||||
case PackageNameValidationResult.ScopedPackagesNotSupported:
|
||||
this.log.writeLine(`Package '${typing}' is scoped and currently is not supported`);
|
||||
break;
|
||||
case PackageNameValidationResult.NameContainsNonURISafeCharacters:
|
||||
this.log.writeLine(`Package name '${typing}' contains non URI safe characters`);
|
||||
break;
|
||||
}
|
||||
this.log.writeLine(JsTyping.renderPackageNameValidationFailure(validationResult, typing));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -430,8 +372,8 @@ namespace ts.server.typingsInstaller {
|
||||
};
|
||||
}
|
||||
|
||||
private installTypingsAsync(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void {
|
||||
this.pendingRunRequests.unshift({ requestId, args, cwd, onRequestCompleted });
|
||||
private installTypingsAsync(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void {
|
||||
this.pendingRunRequests.unshift({ requestId, packageNames, cwd, onRequestCompleted });
|
||||
this.executeWithThrottling();
|
||||
}
|
||||
|
||||
@@ -439,7 +381,7 @@ namespace ts.server.typingsInstaller {
|
||||
while (this.inFlightRequestCount < this.throttleLimit && this.pendingRunRequests.length) {
|
||||
this.inFlightRequestCount++;
|
||||
const request = this.pendingRunRequests.pop();
|
||||
this.installWorker(request.requestId, request.args, request.cwd, ok => {
|
||||
this.installWorker(request.requestId, request.packageNames, request.cwd, ok => {
|
||||
this.inFlightRequestCount--;
|
||||
request.onRequestCompleted(ok);
|
||||
this.executeWithThrottling();
|
||||
@@ -447,7 +389,7 @@ namespace ts.server.typingsInstaller {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract installWorker(requestId: number, args: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void;
|
||||
protected abstract installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void;
|
||||
protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes): void;
|
||||
}
|
||||
|
||||
|
||||
@@ -318,4 +318,15 @@ namespace ts.server {
|
||||
deleted(oldItems[oldIndex++]);
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function indent(string: string): string {
|
||||
return "\n " + string;
|
||||
}
|
||||
|
||||
/** Put stringified JSON on the next line, indented. */
|
||||
/* @internal */
|
||||
export function stringifyIndented(json: {}): string {
|
||||
return "\n " + JSON.stringify(json);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ namespace ts.BreakpointResolver {
|
||||
}
|
||||
}
|
||||
|
||||
if (isPartOfExpression(node)) {
|
||||
if (isExpressionNode(node)) {
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.DoStatement:
|
||||
// Set span as if on while keyword
|
||||
|
||||
@@ -5,15 +5,13 @@ namespace ts {
|
||||
getCodeActions(context: CodeFixContext): CodeAction[] | undefined;
|
||||
}
|
||||
|
||||
export interface CodeFixContext {
|
||||
export interface CodeFixContext extends textChanges.TextChangesContext {
|
||||
errorCode: number;
|
||||
sourceFile: SourceFile;
|
||||
span: TextSpan;
|
||||
program: Program;
|
||||
newLineCharacter: string;
|
||||
host: LanguageServiceHost;
|
||||
cancellationToken: CancellationToken;
|
||||
rulesProvider: formatting.RulesProvider;
|
||||
}
|
||||
|
||||
export namespace codefix {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/* @internal */
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [
|
||||
Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code,
|
||||
],
|
||||
getCodeActions: context => {
|
||||
const { sourceFile, span: { start } } = context;
|
||||
const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
|
||||
if (!isStringLiteral(token)) {
|
||||
throw Debug.fail(); // These errors should only happen on the module name.
|
||||
}
|
||||
|
||||
const action = tryGetCodeActionForInstallPackageTypes(context.host, token.text);
|
||||
return action && [action];
|
||||
},
|
||||
});
|
||||
|
||||
export function tryGetCodeActionForInstallPackageTypes(host: LanguageServiceHost, moduleName: string): CodeAction | undefined {
|
||||
const { packageName } = getPackageName(moduleName);
|
||||
|
||||
if (!host.isKnownTypesPackageName(packageName)) {
|
||||
// If !registry, registry not available yet, can't do anything.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const typesPackageName = getTypesPackageName(packageName);
|
||||
return {
|
||||
description: `Install '${typesPackageName}'`,
|
||||
changes: [],
|
||||
commands: [{ type: "install package", packageName: typesPackageName }],
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
/// <reference path="fixClassIncorrectlyImplementsInterface.ts" />
|
||||
/// <reference path="fixAddMissingMember.ts" />
|
||||
/// <reference path="fixSpelling.ts" />
|
||||
/// <reference path="fixCannotFindModule.ts" />
|
||||
/// <reference path="fixClassDoesntImplementInheritedAbstractMember.ts" />
|
||||
/// <reference path="fixClassSuperMustPrecedeThisAccess.ts" />
|
||||
/// <reference path="fixConstructorForDerivedNeedSuperCall.ts" />
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -368,7 +368,7 @@ namespace ts.codefix {
|
||||
}
|
||||
|
||||
function inferTypeFromContextualType(node: Expression, checker: TypeChecker, usageContext: UsageContext): void {
|
||||
if (isPartOfExpression(node)) {
|
||||
if (isExpressionNode(node)) {
|
||||
addCandidateType(usageContext, checker.getContextualType(node));
|
||||
}
|
||||
}
|
||||
@@ -521,7 +521,7 @@ namespace ts.codefix {
|
||||
if (!usageContext.properties) {
|
||||
usageContext.properties = createUnderscoreEscapedMap<UsageContext>();
|
||||
}
|
||||
const propertyUsageContext = {};
|
||||
const propertyUsageContext = usageContext.properties.get(name) || { };
|
||||
inferTypeFromContext(parent, checker, propertyUsageContext);
|
||||
usageContext.properties.set(name, propertyUsageContext);
|
||||
}
|
||||
@@ -575,7 +575,7 @@ namespace ts.codefix {
|
||||
if (usageContext.properties) {
|
||||
usageContext.properties.forEach((context, name) => {
|
||||
const symbol = checker.createSymbol(SymbolFlags.Property, name);
|
||||
symbol.type = getTypeFromUsageContext(context, checker);
|
||||
symbol.type = getTypeFromUsageContext(context, checker) || checker.getAnyType();
|
||||
members.set(name, symbol);
|
||||
});
|
||||
}
|
||||
@@ -636,7 +636,7 @@ namespace ts.codefix {
|
||||
symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i]));
|
||||
parameters.push(symbol);
|
||||
}
|
||||
const returnType = getTypeFromUsageContext(callContext.returnType, checker);
|
||||
const returnType = getTypeFromUsageContext(callContext.returnType, checker) || checker.getVoidType();
|
||||
return checker.createSignature(/*declaration*/ undefined, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, callContext.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false);
|
||||
}
|
||||
|
||||
|
||||
+293
-76
@@ -4,13 +4,31 @@
|
||||
namespace ts.Completions {
|
||||
export type Log = (message: string) => void;
|
||||
|
||||
interface SymbolOriginInfo {
|
||||
moduleSymbol: Symbol;
|
||||
isDefaultExport: boolean;
|
||||
}
|
||||
/**
|
||||
* Map from symbol id -> SymbolOriginInfo.
|
||||
* Only populated for symbols that come from other modules.
|
||||
*/
|
||||
type SymbolOriginInfoMap = (SymbolOriginInfo | undefined)[];
|
||||
|
||||
const enum KeywordCompletionFilters {
|
||||
None,
|
||||
ClassElementKeywords, // Keywords at class keyword
|
||||
ConstructorParameterKeywords, // Keywords at constructor parameter
|
||||
}
|
||||
|
||||
export function getCompletionsAtPosition(host: LanguageServiceHost, typeChecker: TypeChecker, log: Log, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number): CompletionInfo | undefined {
|
||||
export function getCompletionsAtPosition(
|
||||
host: LanguageServiceHost,
|
||||
typeChecker: TypeChecker,
|
||||
log: Log,
|
||||
compilerOptions: CompilerOptions,
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
): CompletionInfo | undefined {
|
||||
if (isInReferenceComment(sourceFile, position)) {
|
||||
return PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host);
|
||||
}
|
||||
@@ -19,12 +37,12 @@ namespace ts.Completions {
|
||||
return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log);
|
||||
}
|
||||
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position);
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
|
||||
if (!completionData) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, request, keywordFilters } = completionData;
|
||||
const { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, request, keywordFilters, symbolToOriginInfoMap } = completionData;
|
||||
|
||||
if (sourceFile.languageVariant === LanguageVariant.JSX &&
|
||||
location && location.parent && location.parent.kind === SyntaxKind.JsxClosingElement) {
|
||||
@@ -56,7 +74,7 @@ namespace ts.Completions {
|
||||
const entries: CompletionEntry[] = [];
|
||||
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral);
|
||||
const uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, symbolToOriginInfoMap);
|
||||
getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target, entries);
|
||||
}
|
||||
else {
|
||||
@@ -64,7 +82,7 @@ namespace ts.Completions {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral);
|
||||
getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, symbolToOriginInfoMap);
|
||||
}
|
||||
|
||||
// TODO add filter for keyword based on type/value/namespace and also location
|
||||
@@ -82,7 +100,7 @@ namespace ts.Completions {
|
||||
function getJavaScriptCompletionEntries(
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
uniqueNames: Map<true>,
|
||||
uniqueNames: Map<{}>,
|
||||
target: ScriptTarget,
|
||||
entries: Push<CompletionEntry>): void {
|
||||
getNameTable(sourceFile).forEach((pos, name) => {
|
||||
@@ -109,7 +127,15 @@ namespace ts.Completions {
|
||||
});
|
||||
}
|
||||
|
||||
function createCompletionEntry(symbol: Symbol, location: Node, performCharacterChecks: boolean, typeChecker: TypeChecker, target: ScriptTarget, allowStringLiteral: boolean): CompletionEntry {
|
||||
function createCompletionEntry(
|
||||
symbol: Symbol,
|
||||
location: Node,
|
||||
performCharacterChecks: boolean,
|
||||
typeChecker: TypeChecker,
|
||||
target: ScriptTarget,
|
||||
allowStringLiteral: boolean,
|
||||
origin: SymbolOriginInfo,
|
||||
): CompletionEntry | undefined {
|
||||
// Try to get a valid display name for this symbol, if we could not find one, then ignore it.
|
||||
// We would like to only show things that can be added after a dot, so for instance numeric properties can
|
||||
// not be accessed with a dot (a.1 <- invalid)
|
||||
@@ -131,27 +157,56 @@ namespace ts.Completions {
|
||||
kind: SymbolDisplay.getSymbolKind(typeChecker, symbol, location),
|
||||
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
|
||||
sortText: "0",
|
||||
source: getSourceFromOrigin(origin),
|
||||
hasAction: origin === undefined ? undefined : true,
|
||||
};
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromSymbols(symbols: Symbol[], entries: Push<CompletionEntry>, location: Node, performCharacterChecks: boolean, typeChecker: TypeChecker, target: ScriptTarget, log: Log, allowStringLiteral: boolean): Map<true> {
|
||||
function getSourceFromOrigin(origin: SymbolOriginInfo | undefined): string | undefined {
|
||||
return origin && stripQuotes(origin.moduleSymbol.name);
|
||||
}
|
||||
|
||||
function getCompletionEntriesFromSymbols(
|
||||
symbols: ReadonlyArray<Symbol>,
|
||||
entries: Push<CompletionEntry>,
|
||||
location: Node,
|
||||
performCharacterChecks: boolean,
|
||||
typeChecker: TypeChecker,
|
||||
target: ScriptTarget,
|
||||
log: Log,
|
||||
allowStringLiteral: boolean,
|
||||
symbolToOriginInfoMap?: SymbolOriginInfoMap,
|
||||
): Map<true> {
|
||||
const start = timestamp();
|
||||
const uniqueNames = createMap<true>();
|
||||
// Tracks unique names.
|
||||
// We don't set this for global variables or completions from external module exports, because we can have multiple of those.
|
||||
// Based on the order we add things we will always see locals first, then globals, then module exports.
|
||||
// So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name.
|
||||
const uniques = createMap<true>();
|
||||
if (symbols) {
|
||||
for (const symbol of symbols) {
|
||||
const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral);
|
||||
if (entry) {
|
||||
const id = entry.name;
|
||||
if (!uniqueNames.has(id)) {
|
||||
entries.push(entry);
|
||||
uniqueNames.set(id, true);
|
||||
}
|
||||
const origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[getSymbolId(symbol)] : undefined;
|
||||
const entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin);
|
||||
if (!entry) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const { name } = entry;
|
||||
if (uniques.has(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Latter case tests whether this is a global variable.
|
||||
if (!origin && !(symbol.parent === undefined && !some(symbol.declarations, d => d.getSourceFile() === location.getSourceFile()))) {
|
||||
uniques.set(name, true);
|
||||
}
|
||||
|
||||
entries.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (timestamp() - start));
|
||||
return uniqueNames;
|
||||
return uniques;
|
||||
}
|
||||
|
||||
function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined {
|
||||
@@ -298,78 +353,157 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
export function getCompletionEntryDetails(typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number, entryName: string): CompletionEntryDetails {
|
||||
// Compute all the completion symbols again.
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position);
|
||||
if (completionData) {
|
||||
const { symbols, location, allowStringLiteral } = completionData;
|
||||
|
||||
// Find the symbol with the matching entry name.
|
||||
// We don't need to perform character checks here because we're only comparing the
|
||||
// name against 'entryName' (which is known to be good), not building a new
|
||||
// completion entry.
|
||||
const symbol = forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === entryName ? s : undefined);
|
||||
|
||||
if (symbol) {
|
||||
const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, SemanticMeaning.All);
|
||||
return {
|
||||
name: entryName,
|
||||
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
|
||||
kind: symbolKind,
|
||||
displayParts,
|
||||
documentation,
|
||||
tags
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't find a symbol with this name. See if we can find a keyword instead.
|
||||
const keywordCompletion = forEach(
|
||||
getKeywordCompletions(KeywordCompletionFilters.None),
|
||||
c => c.name === entryName
|
||||
);
|
||||
if (keywordCompletion) {
|
||||
return {
|
||||
name: entryName,
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
displayParts: [displayPart(entryName, SymbolDisplayPartKind.keyword)],
|
||||
documentation: undefined,
|
||||
tags: undefined
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getCompletionEntrySymbol(typeChecker: TypeChecker, log: (message: string) => void, compilerOptions: CompilerOptions, sourceFile: SourceFile, position: number, entryName: string): Symbol | undefined {
|
||||
// Compute all the completion symbols again.
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position);
|
||||
function getSymbolCompletionFromEntryId(
|
||||
typeChecker: TypeChecker,
|
||||
log: (message: string) => void,
|
||||
compilerOptions: CompilerOptions,
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
{ name, source }: CompletionEntryIdentifier,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
): { type: "symbol", symbol: Symbol, location: Node, symbolToOriginInfoMap: SymbolOriginInfoMap } | { type: "request", request: Request } | { type: "none" } {
|
||||
const completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles);
|
||||
if (!completionData) {
|
||||
return undefined;
|
||||
return { type: "none" };
|
||||
}
|
||||
const { symbols, allowStringLiteral } = completionData;
|
||||
|
||||
const { symbols, location, allowStringLiteral, symbolToOriginInfoMap, request } = completionData;
|
||||
if (request) {
|
||||
return { type: "request", request };
|
||||
}
|
||||
|
||||
// Find the symbol with the matching entry name.
|
||||
// We don't need to perform character checks here because we're only comparing the
|
||||
// name against 'entryName' (which is known to be good), not building a new
|
||||
// completion entry.
|
||||
return forEach(symbols, s => getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === entryName ? s : undefined);
|
||||
const symbol = find(symbols, s =>
|
||||
getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral) === name
|
||||
&& getSourceFromOrigin(symbolToOriginInfoMap[getSymbolId(s)]) === source);
|
||||
return symbol ? { type: "symbol", symbol, location, symbolToOriginInfoMap } : { type: "none" };
|
||||
}
|
||||
|
||||
export interface CompletionEntryIdentifier {
|
||||
name: string;
|
||||
source?: string;
|
||||
}
|
||||
|
||||
export function getCompletionEntryDetails(
|
||||
typeChecker: TypeChecker,
|
||||
log: (message: string) => void,
|
||||
compilerOptions: CompilerOptions,
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
entryId: CompletionEntryIdentifier,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
host: LanguageServiceHost,
|
||||
rulesProvider: formatting.RulesProvider,
|
||||
): CompletionEntryDetails {
|
||||
const { name, source } = entryId;
|
||||
// Compute all the completion symbols again.
|
||||
const symbolCompletion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles);
|
||||
switch (symbolCompletion.type) {
|
||||
case "request": {
|
||||
const { request } = symbolCompletion;
|
||||
switch (request.kind) {
|
||||
case "JsDocTagName":
|
||||
return JsDoc.getJSDocTagNameCompletionDetails(name);
|
||||
case "JsDocTag":
|
||||
return JsDoc.getJSDocTagCompletionDetails(name);
|
||||
case "JsDocParameterName":
|
||||
return JsDoc.getJSDocParameterNameCompletionDetails(name);
|
||||
default:
|
||||
return Debug.assertNever(request);
|
||||
}
|
||||
}
|
||||
case "symbol": {
|
||||
const { symbol, location, symbolToOriginInfoMap } = symbolCompletion;
|
||||
const codeActions = getCompletionEntryCodeActions(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, rulesProvider);
|
||||
const kindModifiers = SymbolDisplay.getSymbolModifiers(symbol);
|
||||
const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, SemanticMeaning.All);
|
||||
return { name, kindModifiers, kind: symbolKind, displayParts, documentation, tags, codeActions, source: source === undefined ? undefined : [textPart(source)] };
|
||||
}
|
||||
case "none": {
|
||||
// Didn't find a symbol with this name. See if we can find a keyword instead.
|
||||
if (some(getKeywordCompletions(KeywordCompletionFilters.None), c => c.name === name)) {
|
||||
return {
|
||||
name,
|
||||
kind: ScriptElementKind.keyword,
|
||||
kindModifiers: ScriptElementKindModifier.none,
|
||||
displayParts: [displayPart(name, SymbolDisplayPartKind.keyword)],
|
||||
documentation: undefined,
|
||||
tags: undefined,
|
||||
codeActions: undefined,
|
||||
source: undefined,
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getCompletionEntryCodeActions(
|
||||
symbolToOriginInfoMap: SymbolOriginInfoMap,
|
||||
symbol: Symbol,
|
||||
checker: TypeChecker,
|
||||
host: LanguageServiceHost,
|
||||
compilerOptions: CompilerOptions,
|
||||
sourceFile: SourceFile,
|
||||
rulesProvider: formatting.RulesProvider,
|
||||
): CodeAction[] | undefined {
|
||||
const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)];
|
||||
if (!symbolOriginInfo) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { moduleSymbol, isDefaultExport } = symbolOriginInfo;
|
||||
return codefix.getCodeActionForImport(moduleSymbol, {
|
||||
host,
|
||||
checker,
|
||||
newLineCharacter: host.getNewLine(),
|
||||
compilerOptions,
|
||||
sourceFile,
|
||||
rulesProvider,
|
||||
symbolName: symbol.name,
|
||||
getCanonicalFileName: createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false),
|
||||
symbolToken: undefined,
|
||||
kind: isDefaultExport ? codefix.ImportKind.Default : codefix.ImportKind.Named,
|
||||
});
|
||||
}
|
||||
|
||||
export function getCompletionEntrySymbol(
|
||||
typeChecker: TypeChecker,
|
||||
log: (message: string) => void,
|
||||
compilerOptions: CompilerOptions,
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
entryId: CompletionEntryIdentifier,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
): Symbol | undefined {
|
||||
const completion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles);
|
||||
return completion.type === "symbol" ? completion.symbol : undefined;
|
||||
}
|
||||
|
||||
interface CompletionData {
|
||||
symbols: Symbol[];
|
||||
symbols: ReadonlyArray<Symbol>;
|
||||
isGlobalCompletion: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
allowStringLiteral: boolean;
|
||||
isNewIdentifierLocation: boolean;
|
||||
location: Node;
|
||||
location: Node | undefined;
|
||||
isRightOfDot: boolean;
|
||||
request?: Request;
|
||||
keywordFilters: KeywordCompletionFilters;
|
||||
symbolToOriginInfoMap: SymbolOriginInfoMap;
|
||||
}
|
||||
type Request = { kind: "JsDocTagName" } | { kind: "JsDocTag" } | { kind: "JsDocParameterName", tag: JSDocParameterTag };
|
||||
|
||||
function getCompletionData(typeChecker: TypeChecker, log: (message: string) => void, sourceFile: SourceFile, position: number): CompletionData | undefined {
|
||||
function getCompletionData(
|
||||
typeChecker: TypeChecker,
|
||||
log: (message: string) => void,
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
allSourceFiles: ReadonlyArray<SourceFile>,
|
||||
): CompletionData | undefined {
|
||||
const isJavaScriptFile = isSourceFileJavaScript(sourceFile);
|
||||
|
||||
let request: Request | undefined;
|
||||
@@ -441,7 +575,18 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
if (request) {
|
||||
return { symbols: undefined, isGlobalCompletion: false, isMemberCompletion: false, allowStringLiteral: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, request, keywordFilters: KeywordCompletionFilters.None };
|
||||
return {
|
||||
symbols: emptyArray,
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: false,
|
||||
allowStringLiteral: false,
|
||||
isNewIdentifierLocation: false,
|
||||
location: undefined,
|
||||
isRightOfDot: false,
|
||||
request,
|
||||
keywordFilters: KeywordCompletionFilters.None,
|
||||
symbolToOriginInfoMap: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
if (!insideJsDocTagTypeExpression) {
|
||||
@@ -543,6 +688,7 @@ namespace ts.Completions {
|
||||
let isNewIdentifierLocation: boolean;
|
||||
let keywordFilters = KeywordCompletionFilters.None;
|
||||
let symbols: Symbol[] = [];
|
||||
const symbolToOriginInfoMap: SymbolOriginInfoMap = [];
|
||||
|
||||
if (isRightOfDot) {
|
||||
getTypeScriptMemberSymbols();
|
||||
@@ -579,7 +725,7 @@ namespace ts.Completions {
|
||||
|
||||
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
|
||||
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request, keywordFilters };
|
||||
return { symbols, isGlobalCompletion, isMemberCompletion, allowStringLiteral, isNewIdentifierLocation, location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request, keywordFilters, symbolToOriginInfoMap };
|
||||
|
||||
type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag;
|
||||
|
||||
@@ -752,13 +898,16 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias;
|
||||
symbols = filterGlobalCompletion(typeChecker.getSymbolsInScope(scopeNode, symbolMeanings));
|
||||
|
||||
symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings);
|
||||
getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "");
|
||||
filterGlobalCompletion(symbols);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function filterGlobalCompletion(symbols: Symbol[]) {
|
||||
return filter(symbols, symbol => {
|
||||
function filterGlobalCompletion(symbols: Symbol[]): void {
|
||||
filterMutate(symbols, symbol => {
|
||||
if (!isSourceFile(location)) {
|
||||
// export = /**/ here we want to get all meanings, so any symbol is ok
|
||||
if (isExportAssignment(location.parent)) {
|
||||
@@ -832,6 +981,62 @@ namespace ts.Completions {
|
||||
}
|
||||
}
|
||||
|
||||
function getSymbolsFromOtherSourceFileExports(symbols: Symbol[], tokenText: string): void {
|
||||
const tokenTextLowerCase = tokenText.toLowerCase();
|
||||
|
||||
codefix.forEachExternalModule(typeChecker, allSourceFiles, moduleSymbol => {
|
||||
if (moduleSymbol === sourceFile.symbol) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let symbol of typeChecker.getExportsOfModule(moduleSymbol)) {
|
||||
let { name } = symbol;
|
||||
const isDefaultExport = name === "default";
|
||||
if (isDefaultExport) {
|
||||
const localSymbol = getLocalSymbolForExportDefault(symbol);
|
||||
if (localSymbol) {
|
||||
symbol = localSymbol;
|
||||
name = localSymbol.name;
|
||||
}
|
||||
}
|
||||
|
||||
if (symbol.declarations && symbol.declarations.some(d => isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier)) {
|
||||
// Don't add a completion for a re-export, only for the original.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (stringContainsCharactersInOrder(name.toLowerCase(), tokenTextLowerCase)) {
|
||||
symbols.push(symbol);
|
||||
symbolToOriginInfoMap[getSymbolId(symbol)] = { moduleSymbol, isDefaultExport };
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* True if you could remove some characters in `a` to get `b`.
|
||||
* E.g., true for "abcdef" and "bdf".
|
||||
* But not true for "abcdef" and "dbf".
|
||||
*/
|
||||
function stringContainsCharactersInOrder(str: string, characters: string): boolean {
|
||||
if (characters.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
let characterIndex = 0;
|
||||
for (let strIndex = 0; strIndex < str.length; strIndex++) {
|
||||
if (str.charCodeAt(strIndex) === characters.charCodeAt(characterIndex)) {
|
||||
characterIndex++;
|
||||
if (characterIndex === characters.length) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Did not find all characters
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the first node that "embraces" the position, so that one may
|
||||
* accurately aggregate locals from the closest containing scope.
|
||||
@@ -1627,13 +1832,25 @@ namespace ts.Completions {
|
||||
// First check of the displayName is not external module; if it is an external module, it is not valid entry
|
||||
if (symbol.flags & SymbolFlags.Namespace) {
|
||||
const firstCharCode = name.charCodeAt(0);
|
||||
if (firstCharCode === CharacterCodes.singleQuote || firstCharCode === CharacterCodes.doubleQuote) {
|
||||
if (isSingleOrDoubleQuote(firstCharCode)) {
|
||||
// If the symbol is external module, don't show it in the completion list
|
||||
// (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there)
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// If the symbol is for a member of an object type and is the internal name of an ES
|
||||
// symbol, it is not a valid entry. Internal names for ES symbols start with "__@"
|
||||
if (symbol.flags & SymbolFlags.ClassMember) {
|
||||
const escapedName = symbol.escapedName as string;
|
||||
if (escapedName.length >= 3 &&
|
||||
escapedName.charCodeAt(0) === CharacterCodes._ &&
|
||||
escapedName.charCodeAt(1) === CharacterCodes._ &&
|
||||
escapedName.charCodeAt(2) === CharacterCodes.at) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral);
|
||||
}
|
||||
|
||||
|
||||
@@ -377,19 +377,26 @@ namespace ts.FindAllReferences.Core {
|
||||
|
||||
const result: SymbolAndEntries[] = [];
|
||||
const state = new State(sourceFiles, /*isForConstructor*/ node.kind === SyntaxKind.ConstructorKeyword, checker, cancellationToken, searchMeaning, options, result);
|
||||
const search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: populateSearchSymbolSet(symbol, node, checker, options.implementations) });
|
||||
|
||||
// Try to get the smallest valid scope that we can limit our search to;
|
||||
// otherwise we'll need to search globally (i.e. include each file).
|
||||
const scope = getSymbolScope(symbol);
|
||||
if (scope) {
|
||||
getReferencesInContainer(scope, scope.getSourceFile(), search, state);
|
||||
if (node.kind === SyntaxKind.DefaultKeyword) {
|
||||
addReference(node, symbol, node, state);
|
||||
searchForImportsOfExport(node, symbol, { exportingModuleSymbol: symbol.parent, exportKind: ExportKind.Default }, state);
|
||||
}
|
||||
else {
|
||||
// Global search
|
||||
for (const sourceFile of state.sourceFiles) {
|
||||
state.cancellationToken.throwIfCancellationRequested();
|
||||
searchForName(sourceFile, search, state);
|
||||
const search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: populateSearchSymbolSet(symbol, node, checker, options.implementations) });
|
||||
|
||||
// Try to get the smallest valid scope that we can limit our search to;
|
||||
// otherwise we'll need to search globally (i.e. include each file).
|
||||
const scope = getSymbolScope(symbol);
|
||||
if (scope) {
|
||||
getReferencesInContainer(scope, scope.getSourceFile(), search, state);
|
||||
}
|
||||
else {
|
||||
// Global search
|
||||
for (const sourceFile of state.sourceFiles) {
|
||||
state.cancellationToken.throwIfCancellationRequested();
|
||||
searchForName(sourceFile, search, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -849,7 +849,7 @@ namespace ts.formatting {
|
||||
}
|
||||
|
||||
static NodeIsInDecoratorContext(node: Node): boolean {
|
||||
while (isPartOfExpression(node)) {
|
||||
while (isExpressionNode(node)) {
|
||||
node = node.parent;
|
||||
}
|
||||
return node.kind === SyntaxKind.Decorator;
|
||||
|
||||
+55
-4
@@ -65,19 +65,44 @@ namespace ts.JsDoc {
|
||||
return documentationComment;
|
||||
}
|
||||
|
||||
export function getJsDocTagsFromDeclarations(declarations?: Declaration[]) {
|
||||
export function getJsDocTagsFromDeclarations(declarations?: Declaration[]): JSDocTagInfo[] {
|
||||
// Only collect doc comments from duplicate declarations once.
|
||||
const tags: JSDocTagInfo[] = [];
|
||||
forEachUnique(declarations, declaration => {
|
||||
for (const tag of getJSDocTags(declaration)) {
|
||||
if (tag.kind === SyntaxKind.JSDocTag) {
|
||||
tags.push({ name: tag.tagName.text, text: tag.comment });
|
||||
}
|
||||
tags.push({ name: tag.tagName.text, text: getCommentText(tag) });
|
||||
}
|
||||
});
|
||||
return tags;
|
||||
}
|
||||
|
||||
function getCommentText(tag: JSDocTag): string {
|
||||
const { comment } = tag;
|
||||
switch (tag.kind) {
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return withNode((tag as JSDocAugmentsTag).class);
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
return withList((tag as JSDocTemplateTag).typeParameters);
|
||||
case SyntaxKind.JSDocTypeTag:
|
||||
return withNode((tag as JSDocTypeTag).typeExpression);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
case SyntaxKind.JSDocPropertyTag:
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
const { name } = tag as JSDocTypedefTag | JSDocPropertyTag | JSDocParameterTag;
|
||||
return name ? withNode(name) : comment;
|
||||
default:
|
||||
return comment;
|
||||
}
|
||||
|
||||
function withNode(node: Node) {
|
||||
return `${node.getText()} ${comment}`;
|
||||
}
|
||||
|
||||
function withList(list: NodeArray<Node>): string {
|
||||
return `${list.map(x => x.getText())} ${comment}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through 'array' by index and performs the callback on each element of array until the callback
|
||||
* returns a truthy value, then returns that value.
|
||||
@@ -108,6 +133,8 @@ namespace ts.JsDoc {
|
||||
}));
|
||||
}
|
||||
|
||||
export const getJSDocTagNameCompletionDetails = getJSDocTagCompletionDetails;
|
||||
|
||||
export function getJSDocTagCompletions(): CompletionEntry[] {
|
||||
return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, tagName => {
|
||||
return {
|
||||
@@ -119,6 +146,18 @@ namespace ts.JsDoc {
|
||||
}));
|
||||
}
|
||||
|
||||
export function getJSDocTagCompletionDetails(name: string): CompletionEntryDetails {
|
||||
return {
|
||||
name,
|
||||
kind: ScriptElementKind.unknown, // TODO: should have its own kind?
|
||||
kindModifiers: "",
|
||||
displayParts: [textPart(name)],
|
||||
documentation: emptyArray,
|
||||
tags: emptyArray,
|
||||
codeActions: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export function getJSDocParameterNameCompletions(tag: JSDocParameterTag): CompletionEntry[] {
|
||||
if (!isIdentifier(tag.name)) {
|
||||
return emptyArray;
|
||||
@@ -141,6 +180,18 @@ namespace ts.JsDoc {
|
||||
});
|
||||
}
|
||||
|
||||
export function getJSDocParameterNameCompletionDetails(name: string): CompletionEntryDetails {
|
||||
return {
|
||||
name,
|
||||
kind: ScriptElementKind.parameterElement,
|
||||
kindModifiers: "",
|
||||
displayParts: [textPart(name)],
|
||||
documentation: emptyArray,
|
||||
tags: emptyArray,
|
||||
codeActions: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if position points to a valid position to add JSDoc comments, and if so,
|
||||
* returns the appropriate template. Otherwise returns an empty string.
|
||||
|
||||
@@ -246,4 +246,65 @@ namespace ts.JsTyping {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const enum PackageNameValidationResult {
|
||||
Ok,
|
||||
ScopedPackagesNotSupported,
|
||||
EmptyName,
|
||||
NameTooLong,
|
||||
NameStartsWithDot,
|
||||
NameStartsWithUnderscore,
|
||||
NameContainsNonURISafeCharacters
|
||||
}
|
||||
|
||||
const MaxPackageNameLength = 214;
|
||||
|
||||
/**
|
||||
* Validates package name using rules defined at https://docs.npmjs.com/files/package.json
|
||||
*/
|
||||
export function validatePackageName(packageName: string): PackageNameValidationResult {
|
||||
if (!packageName) {
|
||||
return PackageNameValidationResult.EmptyName;
|
||||
}
|
||||
if (packageName.length > MaxPackageNameLength) {
|
||||
return PackageNameValidationResult.NameTooLong;
|
||||
}
|
||||
if (packageName.charCodeAt(0) === CharacterCodes.dot) {
|
||||
return PackageNameValidationResult.NameStartsWithDot;
|
||||
}
|
||||
if (packageName.charCodeAt(0) === CharacterCodes._) {
|
||||
return PackageNameValidationResult.NameStartsWithUnderscore;
|
||||
}
|
||||
// check if name is scope package like: starts with @ and has one '/' in the middle
|
||||
// scoped packages are not currently supported
|
||||
// TODO: when support will be added we'll need to split and check both scope and package name
|
||||
if (/^@[^/]+\/[^/]+$/.test(packageName)) {
|
||||
return PackageNameValidationResult.ScopedPackagesNotSupported;
|
||||
}
|
||||
if (encodeURIComponent(packageName) !== packageName) {
|
||||
return PackageNameValidationResult.NameContainsNonURISafeCharacters;
|
||||
}
|
||||
return PackageNameValidationResult.Ok;
|
||||
}
|
||||
|
||||
export function renderPackageNameValidationFailure(result: PackageNameValidationResult, typing: string): string {
|
||||
switch (result) {
|
||||
case PackageNameValidationResult.EmptyName:
|
||||
return `Package name '${typing}' cannot be empty`;
|
||||
case PackageNameValidationResult.NameTooLong:
|
||||
return `Package name '${typing}' should be less than ${MaxPackageNameLength} characters`;
|
||||
case PackageNameValidationResult.NameStartsWithDot:
|
||||
return `Package name '${typing}' cannot start with '.'`;
|
||||
case PackageNameValidationResult.NameStartsWithUnderscore:
|
||||
return `Package name '${typing}' cannot start with '_'`;
|
||||
case PackageNameValidationResult.ScopedPackagesNotSupported:
|
||||
return `Package '${typing}' is scoped and currently is not supported`;
|
||||
case PackageNameValidationResult.NameContainsNonURISafeCharacters:
|
||||
return `Package name '${typing}' contains non URI safe characters`;
|
||||
case PackageNameValidationResult.Ok:
|
||||
throw Debug.fail(); // Shouldn't have called this.
|
||||
default:
|
||||
Debug.assertNever(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ namespace ts.Completions.PathCompletions {
|
||||
}
|
||||
}
|
||||
else if (host.getDirectories) {
|
||||
let typeRoots: string[];
|
||||
let typeRoots: ReadonlyArray<string>;
|
||||
try {
|
||||
// Wrap in try catch because getEffectiveTypeRoots touches the filesystem
|
||||
typeRoots = getEffectiveTypeRoots(options, host);
|
||||
|
||||
@@ -14,13 +14,12 @@ namespace ts {
|
||||
getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined;
|
||||
}
|
||||
|
||||
export interface RefactorContext {
|
||||
export interface RefactorContext extends textChanges.TextChangesContext {
|
||||
file: SourceFile;
|
||||
startPosition: number;
|
||||
endPosition?: number;
|
||||
program: Program;
|
||||
newLineCharacter: string;
|
||||
rulesProvider?: formatting.RulesProvider;
|
||||
host: LanguageServiceHost;
|
||||
cancellationToken?: CancellationToken;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,16 +5,9 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
const annotateTypeFromJSDoc: Refactor = {
|
||||
name: "Annotate with type from JSDoc",
|
||||
description: Diagnostics.Annotate_with_type_from_JSDoc.message,
|
||||
getEditsForAction: getEditsForAnnotation,
|
||||
getEditsForAction,
|
||||
getAvailableActions
|
||||
};
|
||||
const annotateFunctionFromJSDoc: Refactor = {
|
||||
name: "Annotate with types from JSDoc",
|
||||
description: Diagnostics.Annotate_with_types_from_JSDoc.message,
|
||||
getEditsForAction: getEditsForFunctionAnnotation,
|
||||
getAvailableActions
|
||||
};
|
||||
|
||||
type DeclarationWithType =
|
||||
| FunctionLikeDeclaration
|
||||
| VariableDeclaration
|
||||
@@ -23,13 +16,41 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
| PropertyDeclaration;
|
||||
|
||||
registerRefactor(annotateTypeFromJSDoc);
|
||||
registerRefactor(annotateFunctionFromJSDoc);
|
||||
|
||||
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
|
||||
if (isInJavaScriptFile(context.file)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false);
|
||||
if (hasUsableJSDoc(findAncestor(node, isDeclarationWithType))) {
|
||||
return [{
|
||||
name: annotateTypeFromJSDoc.name,
|
||||
description: annotateTypeFromJSDoc.description,
|
||||
actions: [
|
||||
{
|
||||
description: annotateTypeFromJSDoc.description,
|
||||
name: actionName
|
||||
}
|
||||
]
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
function hasUsableJSDoc(decl: DeclarationWithType): boolean {
|
||||
if (!decl) {
|
||||
return false;
|
||||
}
|
||||
if (isFunctionLikeDeclaration(decl)) {
|
||||
return decl.parameters.some(hasUsableJSDoc) || (!decl.type && !!getJSDocReturnType(decl));
|
||||
}
|
||||
return !decl.type && !!getJSDocType(decl);
|
||||
}
|
||||
|
||||
function getEditsForAction(context: RefactorContext, action: string): RefactorEditInfo | undefined {
|
||||
if (actionName !== action) {
|
||||
return Debug.fail(`actionName !== action: ${actionName} !== ${action}`);
|
||||
}
|
||||
const node = getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false);
|
||||
const decl = findAncestor(node, isDeclarationWithType);
|
||||
if (!decl || decl.type) {
|
||||
@@ -37,28 +58,18 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
}
|
||||
const jsdocType = getJSDocType(decl);
|
||||
const isFunctionWithJSDoc = isFunctionLikeDeclaration(decl) && (getJSDocReturnType(decl) || decl.parameters.some(p => !!getJSDocType(p)));
|
||||
const refactor = (isFunctionWithJSDoc || jsdocType && decl.kind === SyntaxKind.Parameter) ? annotateFunctionFromJSDoc :
|
||||
jsdocType ? annotateTypeFromJSDoc :
|
||||
undefined;
|
||||
if (refactor) {
|
||||
return [{
|
||||
name: refactor.name,
|
||||
description: refactor.description,
|
||||
actions: [
|
||||
{
|
||||
description: refactor.description,
|
||||
name: actionName
|
||||
}
|
||||
]
|
||||
}];
|
||||
if (isFunctionWithJSDoc || jsdocType && decl.kind === SyntaxKind.Parameter) {
|
||||
return getEditsForFunctionAnnotation(context);
|
||||
}
|
||||
else if (jsdocType) {
|
||||
return getEditsForAnnotation(context);
|
||||
}
|
||||
else {
|
||||
Debug.assert(!!refactor, "No applicable refactor found.");
|
||||
}
|
||||
}
|
||||
|
||||
function getEditsForAnnotation(context: RefactorContext, action: string): RefactorEditInfo | undefined {
|
||||
if (actionName !== action) {
|
||||
return Debug.fail(`actionName !== action: ${actionName} !== ${action}`);
|
||||
}
|
||||
|
||||
function getEditsForAnnotation(context: RefactorContext): RefactorEditInfo | undefined {
|
||||
const sourceFile = context.file;
|
||||
const token = getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false);
|
||||
const decl = findAncestor(token, isDeclarationWithType);
|
||||
@@ -78,11 +89,7 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
};
|
||||
}
|
||||
|
||||
function getEditsForFunctionAnnotation(context: RefactorContext, action: string): RefactorEditInfo | undefined {
|
||||
if (actionName !== action) {
|
||||
return Debug.fail(`actionName !== action: ${actionName} !== ${action}`);
|
||||
}
|
||||
|
||||
function getEditsForFunctionAnnotation(context: RefactorContext): RefactorEditInfo | undefined {
|
||||
const sourceFile = context.file;
|
||||
const token = getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false);
|
||||
const decl = findAncestor(token, isFunctionLikeDeclaration);
|
||||
@@ -166,7 +173,9 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
case SyntaxKind.TypeReference:
|
||||
return transformJSDocTypeReference(node as TypeReferenceNode);
|
||||
default:
|
||||
return visitEachChild(node, transformJSDocType, /*context*/ undefined) as TypeNode;
|
||||
const visited = visitEachChild(node, transformJSDocType, /*context*/ undefined) as TypeNode;
|
||||
setEmitFlags(visited, EmitFlags.SingleLine);
|
||||
return visited;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +208,9 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
let name = node.typeName;
|
||||
let args = node.typeArguments;
|
||||
if (isIdentifier(node.typeName)) {
|
||||
if (isJSDocIndexSignature(node)) {
|
||||
return transformJSDocIndexSignature(node);
|
||||
}
|
||||
let text = node.typeName.text;
|
||||
switch (node.typeName.text) {
|
||||
case "String":
|
||||
@@ -223,4 +235,18 @@ namespace ts.refactor.annotateWithTypeFromJSDoc {
|
||||
}
|
||||
return createTypeReferenceNode(name, args);
|
||||
}
|
||||
|
||||
function transformJSDocIndexSignature(node: TypeReferenceNode) {
|
||||
const index = createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
node.typeArguments[0].kind === SyntaxKind.NumberKeyword ? "n" : "s",
|
||||
/*questionToken*/ undefined,
|
||||
createTypeReferenceNode(node.typeArguments[0].kind === SyntaxKind.NumberKeyword ? "number" : "string", []),
|
||||
/*initializer*/ undefined);
|
||||
const indexSignature = createTypeLiteralNode([createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments[1])]);
|
||||
setEmitFlags(indexSignature, EmitFlags.SingleLine);
|
||||
return indexSignature;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,12 +244,52 @@ namespace ts.refactor.extractSymbol {
|
||||
return { targetRange: { range: statements, facts: rangeFacts, declarations } };
|
||||
}
|
||||
|
||||
if (isReturnStatement(start) && !start.expression) {
|
||||
// Makes no sense to extract an expression-less return statement.
|
||||
return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.CannotExtractRange)] };
|
||||
}
|
||||
|
||||
// We have a single node (start)
|
||||
const errors = checkRootNode(start) || checkNode(start);
|
||||
const node = refineNode(start);
|
||||
|
||||
const errors = checkRootNode(node) || checkNode(node);
|
||||
if (errors) {
|
||||
return { errors };
|
||||
}
|
||||
return { targetRange: { range: getStatementOrExpressionRange(start), facts: rangeFacts, declarations } };
|
||||
return { targetRange: { range: getStatementOrExpressionRange(node), facts: rangeFacts, declarations } };
|
||||
|
||||
/**
|
||||
* Attempt to refine the extraction node (generally, by shrinking it) to produce better results.
|
||||
* @param node The unrefined extraction node.
|
||||
*/
|
||||
function refineNode(node: Node) {
|
||||
if (isReturnStatement(node)) {
|
||||
if (node.expression) {
|
||||
return node.expression;
|
||||
}
|
||||
}
|
||||
else if (isVariableStatement(node)) {
|
||||
let numInitializers = 0;
|
||||
let lastInitializer: Expression | undefined = undefined;
|
||||
for (const declaration of node.declarationList.declarations) {
|
||||
if (declaration.initializer) {
|
||||
numInitializers++;
|
||||
lastInitializer = declaration.initializer;
|
||||
}
|
||||
}
|
||||
if (numInitializers === 1) {
|
||||
return lastInitializer;
|
||||
}
|
||||
// No special handling if there are multiple initializers.
|
||||
}
|
||||
else if (isVariableDeclaration(node)) {
|
||||
if (node.initializer) {
|
||||
return node.initializer;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
function checkRootNode(node: Node): Diagnostic[] | undefined {
|
||||
if (isIdentifier(isExpressionStatement(node) ? node.expression : node)) {
|
||||
@@ -291,7 +331,7 @@ namespace ts.refactor.extractSymbol {
|
||||
Continue = 1 << 1,
|
||||
Return = 1 << 2
|
||||
}
|
||||
if (!isStatement(nodeToCheck) && !(isPartOfExpression(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
|
||||
if (!isStatement(nodeToCheck) && !(isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
|
||||
return [createDiagnosticForNode(nodeToCheck, Messages.StatementOrExpressionExpected)];
|
||||
}
|
||||
|
||||
@@ -451,7 +491,7 @@ namespace ts.refactor.extractSymbol {
|
||||
if (isStatement(node)) {
|
||||
return [node];
|
||||
}
|
||||
else if (isPartOfExpression(node)) {
|
||||
else if (isExpressionNode(node)) {
|
||||
// If our selection is the expression in an ExpressionStatement, expand
|
||||
// the selection to include the enclosing Statement (this stops us
|
||||
// from trying to care about the return value of the extracted function
|
||||
@@ -470,7 +510,7 @@ namespace ts.refactor.extractSymbol {
|
||||
* you may be able to extract into a class method *or* local closure *or* namespace function,
|
||||
* depending on what's in the extracted body.
|
||||
*/
|
||||
function collectEnclosingScopes(range: TargetRange): Scope[] | undefined {
|
||||
function collectEnclosingScopes(range: TargetRange): Scope[] {
|
||||
let current: Node = isReadonlyArray(range.range) ? first(range.range) : range.range;
|
||||
if (range.facts & RangeFacts.UsesThis) {
|
||||
// if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class
|
||||
@@ -483,30 +523,27 @@ namespace ts.refactor.extractSymbol {
|
||||
}
|
||||
}
|
||||
|
||||
const start = current;
|
||||
const scopes: Scope[] = [];
|
||||
while (true) {
|
||||
current = current.parent;
|
||||
// A function parameter's initializer is actually in the outer scope, not the function declaration
|
||||
if (current.kind === SyntaxKind.Parameter) {
|
||||
// Skip all the way to the outer scope of the function that declared this parameter
|
||||
current = findAncestor(current, parent => isFunctionLikeDeclaration(parent)).parent;
|
||||
}
|
||||
|
||||
let scopes: Scope[] | undefined = undefined;
|
||||
while (current) {
|
||||
// We want to find the nearest parent where we can place an "equivalent" sibling to the node we're extracting out of.
|
||||
// Walk up to the closest parent of a place where we can logically put a sibling:
|
||||
// * Function declaration
|
||||
// * Class declaration or expression
|
||||
// * Module/namespace or source file
|
||||
if (current !== start && isScope(current)) {
|
||||
(scopes = scopes || []).push(current);
|
||||
if (isScope(current)) {
|
||||
scopes.push(current);
|
||||
if (current.kind === SyntaxKind.SourceFile) {
|
||||
return scopes;
|
||||
}
|
||||
}
|
||||
|
||||
// A function parameter's initializer is actually in the outer scope, not the function declaration
|
||||
if (current && current.parent && current.parent.kind === SyntaxKind.Parameter) {
|
||||
// Skip all the way to the outer scope of the function that declared this parameter
|
||||
current = findAncestor(current, parent => isFunctionLikeDeclaration(parent)).parent;
|
||||
}
|
||||
else {
|
||||
current = current.parent;
|
||||
}
|
||||
|
||||
}
|
||||
return scopes;
|
||||
}
|
||||
|
||||
function getFunctionExtractionAtIndex(targetRange: TargetRange, context: RefactorContext, requestedChangesIndex: number): RefactorEditInfo {
|
||||
@@ -592,15 +629,7 @@ namespace ts.refactor.extractSymbol {
|
||||
function getPossibleExtractionsWorker(targetRange: TargetRange, context: RefactorContext): { readonly scopes: Scope[], readonly readsAndWrites: ReadsAndWrites } {
|
||||
const { file: sourceFile } = context;
|
||||
|
||||
if (targetRange === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const scopes = collectEnclosingScopes(targetRange);
|
||||
if (scopes === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile);
|
||||
const readsAndWrites = collectReadsAndWrites(
|
||||
targetRange,
|
||||
@@ -701,7 +730,7 @@ namespace ts.refactor.extractSymbol {
|
||||
let type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node);
|
||||
// Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {"
|
||||
type = checker.getBaseTypeOfLiteralType(type);
|
||||
typeNode = checker.typeToTypeNode(type, node, NodeBuilderFlags.NoTruncation);
|
||||
typeNode = checker.typeToTypeNode(type, scope, NodeBuilderFlags.NoTruncation);
|
||||
}
|
||||
|
||||
const paramDecl = createParameter(
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/* @internal */
|
||||
namespace ts.refactor.installTypesForPackage {
|
||||
const actionName = "install";
|
||||
|
||||
const installTypesForPackage: Refactor = {
|
||||
name: "Install missing types package",
|
||||
description: "Install missing types package",
|
||||
getEditsForAction,
|
||||
getAvailableActions,
|
||||
};
|
||||
|
||||
registerRefactor(installTypesForPackage);
|
||||
|
||||
function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined {
|
||||
if (getStrictOptionValue(context.program.getCompilerOptions(), "noImplicitAny")) {
|
||||
// Then it will be available via `fixCannotFindModule`.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const action = getAction(context);
|
||||
return action && [
|
||||
{
|
||||
name: installTypesForPackage.name,
|
||||
description: installTypesForPackage.description,
|
||||
actions: [
|
||||
{
|
||||
description: action.description,
|
||||
name: actionName,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined {
|
||||
Debug.assertEqual(actionName, _actionName);
|
||||
const action = getAction(context)!; // Should be defined if we said there was an action available.
|
||||
return {
|
||||
edits: [],
|
||||
renameFilename: undefined,
|
||||
renameLocation: undefined,
|
||||
commands: action.commands,
|
||||
};
|
||||
}
|
||||
|
||||
function getAction(context: RefactorContext): CodeAction | undefined {
|
||||
const { file, startPosition } = context;
|
||||
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
|
||||
if (isStringLiteral(node) && isModuleIdentifier(node) && getResolvedModule(file, node.text) === undefined) {
|
||||
return codefix.tryGetCodeActionForInstallPackageTypes(context.host, node.text);
|
||||
}
|
||||
}
|
||||
|
||||
function isModuleIdentifier(node: StringLiteral): boolean {
|
||||
switch (node.parent.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
case SyntaxKind.ExternalModuleReference:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
/// <reference path="annotateWithTypeFromJSDoc.ts" />
|
||||
/// <reference path="convertFunctionToEs6Class.ts" />
|
||||
/// <reference path="extractSymbol.ts" />
|
||||
/// <reference path="installTypesForPackage.ts" />
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user