Merge branch 'master' into jsxFragment

This commit is contained in:
uniqueiniquity
2017-10-31 10:53:57 -07:00
354 changed files with 10466 additions and 2916 deletions
+42 -27
View File
@@ -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
View File
@@ -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
View File
@@ -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**
+115 -77
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}
}
}
+44 -5
View File
@@ -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");
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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 {
+21 -14
View File
@@ -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
View File
@@ -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;
}
}
}
+11 -3
View File
@@ -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
View File
@@ -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.
+26 -12
View File
@@ -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 */
+1 -1
View File
@@ -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
View File
@@ -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;
}
}
+58 -14
View File
@@ -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);
}
}
}
+1 -1
View File
@@ -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,
+1 -1
View File
@@ -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
View File
@@ -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);
}
+1 -1
View File
@@ -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()) {
+1 -1
View File
@@ -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;
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 -3
View File
@@ -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);
}
+5 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+14 -2
View File
@@ -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
View File
@@ -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;
}
}
}
+1 -1
View File
@@ -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}"`]);
+1 -1
View File
@@ -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;
+5 -4
View File
@@ -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() {
+2 -21
View File
@@ -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]);
}
+2 -1
View File
@@ -139,6 +139,7 @@
"./unittests/telemetry.ts",
"./unittests/languageService.ts",
"./unittests/programMissingFiles.ts",
"./unittests/publicApi.ts"
"./unittests/publicApi.ts",
"./unittests/hostNewLineSupport.ts"
]
}
+4 -4
View File
@@ -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 += ")";
+4 -12
View File
@@ -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;
});
}
}
+1 -1
View File
@@ -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);
+17 -11
View File
@@ -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);
}
}
+25
View File
@@ -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]);
});
}
+18 -9
View File
@@ -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;
}
`);
});
});
}
+5 -5
View File
@@ -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, []);
});
+52 -5
View File
@@ -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 });
});
});
}
+114 -92
View File
@@ -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 });
});
+191 -13
View File
@@ -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
+11 -9
View File
@@ -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") });
}
+41 -10
View File
@@ -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 {
+384 -1
View File
File diff suppressed because it is too large Load Diff
+40 -2
View File
@@ -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>
+6 -2
View File
@@ -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)
+90 -68
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
}
+2
View File
@@ -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
View File
@@ -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 {
+17
View File
@@ -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;
}
+11
View File
@@ -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);
}
}
+1 -1
View File
@@ -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
+1 -3
View File
@@ -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 }],
};
}
}
+1
View File
@@ -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
+4 -4
View File
@@ -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
View File
@@ -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);
}
+17 -10
View File
@@ -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);
}
}
}
+1 -1
View File
@@ -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
View File
@@ -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.
+61
View File
@@ -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);
}
}
}
+1 -1
View File
@@ -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);
+2 -3
View File
@@ -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;
}
}
+59 -30
View File
@@ -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
View File
@@ -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