Merge branch 'master' into requireJson

This commit is contained in:
Sheetal Nandi 2018-04-30 11:44:09 -07:00
commit 579748bc2b
485 changed files with 13236 additions and 4381 deletions

16
.gitmodules vendored
View file

@ -18,7 +18,23 @@
path = tests/cases/user/TypeScript-WeChat-Starter/TypeScript-WeChat-Starter
url = https://github.com/Microsoft/TypeScript-WeChat-Starter.git
ignore = all
[submodule "tests/cases/user/create-react-app/create-react-app"]
path = tests/cases/user/create-react-app/create-react-app
url = https://github.com/facebook/create-react-app.git
ignore = all
[submodule "tests/cases/user/webpack/webpack"]
path = tests/cases/user/webpack/webpack
url = https://github.com/webpack/webpack.git
ignore = all
[submodule "tests/cases/user/puppeteer/puppeteer"]
path = tests/cases/user/puppeteer/puppeteer
url = https://github.com/GoogleChrome/puppeteer.git
ignore = all
[submodule "tests/cases/user/axios-src/axios-src"]
path = tests/cases/user/axios-src/axios-src
url = https://github.com/axios/axios.git
ignore = all
[submodule "tests/cases/user/prettier/prettier"]
path = tests/cases/user/prettier/prettier
url = https://github.com/prettier/prettier.git
ignore = all

View file

@ -1,35 +1,27 @@
/// <reference path="scripts/types/ambient.d.ts" />
import * as cp from "child_process";
import * as path from "path";
import * as fs from "fs";
import child_process = require("child_process");
import originalGulp = require("gulp");
import helpMaker = require("gulp-help");
import runSequence = require("run-sequence");
import concat = require("gulp-concat");
import clone = require("gulp-clone");
import newer = require("gulp-newer");
import tsc = require("gulp-typescript");
declare module "gulp-typescript" {
interface Settings {
pretty?: boolean;
newLine?: string;
noImplicitThis?: boolean;
stripInternal?: boolean;
types?: string[];
}
}
import * as insert from "gulp-insert";
import * as sourcemaps from "gulp-sourcemaps";
import Q = require("q");
import del = require("del");
import mkdirP = require("mkdirp");
import minimist = require("minimist");
import browserify = require("browserify");
import through2 = require("through2");
import merge2 = require("merge2");
import * as os from "os";
import fold = require("travis-fold");
// @ts-check
const cp = require("child_process");
const path = require("path");
const fs = require("fs");
const child_process = require("child_process");
const originalGulp = require("gulp");
const helpMaker = require("gulp-help");
const runSequence = require("run-sequence");
const concat = require("gulp-concat");
const clone = require("gulp-clone");
const newer = require("gulp-newer");
const tsc = require("gulp-typescript");
const insert = require("gulp-insert");
const sourcemaps = require("gulp-sourcemaps");
const Q = require("q");
const del = require("del");
const mkdirP = require("mkdirp");
const minimist = require("minimist");
const browserify = require("browserify");
const through2 = require("through2");
const merge2 = require("merge2");
const os = require("os");
const fold = require("travis-fold");
const gulp = helpMaker(originalGulp);
Error.stackTraceLimit = 1000;
@ -73,17 +65,26 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
});
const noop = () => {}; // tslint:disable-line no-empty
function exec(cmd: string, args: string[], complete: () => void = noop, error: (e: any, status: number) => void = noop) {
/**
* @param {string} cmd
* @param {string[]} args
* @param {() => void} complete
* @param {(e: *, status: number) => void} error
*/
function exec(cmd, args, complete = noop, error = noop) {
console.log(`${cmd} ${args.join(" ")}`);
// TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition
const subshellFlag = isWin ? "/c" : "-c";
const command = isWin ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`];
const ex = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true } as any);
const ex = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true });
ex.on("exit", (code) => code === 0 ? complete() : error(/*e*/ undefined, code));
ex.on("error", error);
}
function possiblyQuote(cmd: string) {
/**
* @param {string} cmd
*/
function possiblyQuote(cmd) {
return cmd.indexOf(" ") >= 0 ? `"${cmd}"` : cmd;
}
@ -215,12 +216,17 @@ for (const i in libraryTargets) {
.pipe(gulp.dest(".")));
}
const configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js");
const configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts");
const configurePreleleaseJs = path.join(scriptsDirectory, "configurePrerelease.js");
const configurePreleleaseTs = path.join(scriptsDirectory, "configurePrerelease.ts");
const packageJson = "package.json";
const versionFile = path.join(compilerDirectory, "core.ts");
function needsUpdate(source: string | string[], dest: string | string[]): boolean {
/**
* @param {string | string[]} source
* @param {string | string[]} dest
* @returns {boolean}
*/
function needsUpdate(source, dest) {
if (typeof source === "string" && typeof dest === "string") {
if (fs.existsSync(dest)) {
const {mtime: outTime} = fs.statSync(dest);
@ -283,8 +289,13 @@ function needsUpdate(source: string | string[], dest: string | string[]): boolea
return true;
}
function getCompilerSettings(base: tsc.Settings, useBuiltCompiler?: boolean): tsc.Settings {
const copy: tsc.Settings = {};
/**
* @param {tsc.Settings} base
* @param {boolean=} useBuiltCompiler
* @returns {tsc.Settings}
*/
function getCompilerSettings(base, useBuiltCompiler) {
const copy = /** @type {tsc.Settings} */ ({});
for (const key in base) {
copy[key] = base[key];
}
@ -293,32 +304,34 @@ function getCompilerSettings(base: tsc.Settings, useBuiltCompiler?: boolean): ts
}
copy.newLine = "lf";
if (useBuiltCompiler === true) {
copy.typescript = require("./built/local/typescript.js");
copy.typescript = /** @type {*} */ (require("./built/local/typescript.js"));
}
else if (useBuiltCompiler === false) {
copy.typescript = require("./lib/typescript.js");
copy.typescript = /** @type {*} */ (require("./lib/typescript.js"));
}
return copy;
}
gulp.task(configureNightlyJs, /*help*/ false, [], () => {
const settings: tsc.Settings = {
gulp.task(configurePreleleaseJs, /*help*/ false, [], () => {
/** @type {tsc.Settings} */
const settings = {
declaration: false,
removeComments: true,
noResolve: false,
stripInternal: false,
module: "commonjs"
};
return gulp.src(configureNightlyTs)
return gulp.src(configurePreleleaseTs)
.pipe(sourcemaps.init())
.pipe(tsc(settings))
.pipe(sourcemaps.write(path.dirname(configureNightlyJs)))
.pipe(gulp.dest(path.dirname(configureNightlyJs)));
.pipe(sourcemaps.write("."))
.pipe(gulp.dest("./scripts"));
});
// Nightly management tasks
gulp.task("configure-nightly", "Runs scripts/configureNightly.ts to prepare a build for nightly publishing", [configureNightlyJs], (done) => {
exec(host, [configureNightlyJs, packageJson, versionFile], done, done);
gulp.task("configure-nightly", "Runs scripts/configurePrerelease.ts to prepare a build for nightly publishing", [configurePreleleaseJs], (done) => {
exec(host, [configurePreleleaseJs, "dev", packageJson, versionFile], done, done);
});
gulp.task("publish-nightly", "Runs `npm publish --tag next` to create a new nightly build on npm", ["LKG"], () => {
return runSequence("clean", "useDebugMode", "runtests-parallel", (done) => {
@ -331,7 +344,8 @@ const importDefinitelyTypedTestsJs = path.join(importDefinitelyTypedTestsDirecto
const importDefinitelyTypedTestsTs = path.join(importDefinitelyTypedTestsDirectory, "importDefinitelyTypedTests.ts");
gulp.task(importDefinitelyTypedTestsJs, /*help*/ false, [], () => {
const settings: tsc.Settings = getCompilerSettings({
/** @type {tsc.Settings} */
const settings = getCompilerSettings({
declaration: false,
removeComments: true,
noResolve: false,
@ -362,20 +376,11 @@ const builtGeneratedDiagnosticMessagesJSON = path.join(builtLocalDirectory, "dia
// processDiagnosticMessages script
gulp.task(processDiagnosticMessagesJs, /*help*/ false, [], () => {
const settings: tsc.Settings = getCompilerSettings({
target: "es5",
declaration: false,
removeComments: true,
noResolve: false,
stripInternal: false,
outFile: processDiagnosticMessagesJs
}, /*useBuiltCompiler*/ false);
return gulp.src(processDiagnosticMessagesTs)
const diagsProject = tsc.createProject('./scripts/processDiagnosticMessages.tsconfig.json');
return diagsProject.src()
.pipe(newer(processDiagnosticMessagesJs))
.pipe(sourcemaps.init())
.pipe(tsc(settings))
.pipe(sourcemaps.write("."))
.pipe(gulp.dest("."));
.pipe(diagsProject())
.pipe(gulp.dest(scriptsDirectory));
});
// The generated diagnostics map; built for the compiler and for the "generate-diagnostics" task
@ -402,7 +407,8 @@ const generateLocalizedDiagnosticMessagesJs = path.join(scriptsDirectory, "gener
const generateLocalizedDiagnosticMessagesTs = path.join(scriptsDirectory, "generateLocalizedDiagnosticMessages.ts");
gulp.task(generateLocalizedDiagnosticMessagesJs, /*help*/ false, [], () => {
const settings: tsc.Settings = getCompilerSettings({
/** @type {tsc.Settings} */
const settings = getCompilerSettings({
target: "es5",
declaration: false,
removeComments: true,
@ -433,8 +439,12 @@ const nodePackageFile = path.join(builtLocalDirectory, "typescript.js");
const nodeDefinitionsFile = path.join(builtLocalDirectory, "typescript.d.ts");
const nodeStandaloneDefinitionsFile = path.join(builtLocalDirectory, "typescript_standalone.d.ts");
let copyrightContent: string;
function prependCopyright(outputCopyright: boolean = !useDebugMode) {
/** @type {string} */
let copyrightContent;
/**
* @param {boolean} outputCopyright
*/
function prependCopyright(outputCopyright = !useDebugMode) {
return insert.prepend(outputCopyright ? (copyrightContent || (copyrightContent = fs.readFileSync(copyright).toString())) : "");
}
@ -526,9 +536,10 @@ const tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverli
gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile, typesMapJson], (done) => {
const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/ true));
const {js, dts}: { js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream } = serverLibraryProject.src()
/** @type {{ js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream }} */
const {js, dts} = serverLibraryProject.src()
.pipe(sourcemaps.init())
.pipe(newer(<any>{ dest: tsserverLibraryFile, extra: ["src/compiler/**/*.ts", "src/services/**/*.ts"] }))
.pipe(newer(/** @type {*} */({ dest: tsserverLibraryFile, extra: ["src/compiler/**/*.ts", "src/services/**/*.ts"] })))
.pipe(serverLibraryProject());
return merge2([
@ -563,7 +574,8 @@ const specWord = path.join(docDirectory, "TypeScript Language Specification.docx
const specMd = path.join(docDirectory, "spec.md");
gulp.task(word2mdJs, /*help*/ false, [], () => {
const settings: tsc.Settings = getCompilerSettings({
/** @type {tsc.Settings} */
const settings = getCompilerSettings({
outFile: word2mdJs
}, /*useBuiltCompiler*/ false);
return gulp.src(word2mdTs)
@ -642,7 +654,8 @@ function deleteTemporaryProjectOutput() {
return del(path.join(localBaseline, "projectOutput/"));
}
let savedNodeEnv: string;
/** @type {string} */
let savedNodeEnv;
function setNodeEnvToDevelopment() {
savedNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "development";
@ -652,7 +665,12 @@ function restoreSavedNodeEnv() {
process.env.NODE_ENV = savedNodeEnv;
}
function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: (e?: any) => void) {
/**
* @param {string} defaultReporter
* @param {boolean} runInParallel
* @param {(e?: any) => void} done
*/
function runConsoleTests(defaultReporter, runInParallel, done) {
const lintFlag = cmdLineOptions.lint;
cleanTestDirs((err) => {
if (err) { console.error(err); failWithStatus(err, 1); }
@ -727,7 +745,11 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
}
});
function failWithStatus(err?: any, status?: number) {
/**
* @param {any=} err
* @param {number=} status
*/
function failWithStatus(err, status) {
if (err || status) {
process.exit(typeof status === "number" ? status : 2);
}
@ -743,7 +765,11 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
}
}
function finish(error?: any, errorStatus?: number) {
/**
* @param {any=} error
* @param {number=} errorStatus
*/
function finish(error, errorStatus) {
restoreSavedNodeEnv();
deleteTestConfig().then(deleteTemporaryProjectOutput).then(() => {
if (error !== undefined || errorStatus !== undefined) {
@ -773,7 +799,8 @@ gulp.task("runtests",
const nodeServerOutFile = "tests/webTestServer.js";
const nodeServerInFile = "tests/webTestServer.ts";
gulp.task(nodeServerOutFile, /*help*/ false, [servicesFile], () => {
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ true);
/** @type {tsc.Settings} */
const settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ true);
return gulp.src(nodeServerInFile)
.pipe(newer(nodeServerOutFile))
.pipe(sourcemaps.init())
@ -782,16 +809,18 @@ gulp.task(nodeServerOutFile, /*help*/ false, [servicesFile], () => {
.pipe(gulp.dest(path.dirname(nodeServerOutFile)));
});
import convertMap = require("convert-source-map");
import sorcery = require("sorcery");
import Vinyl = require("vinyl");
const convertMap = require("convert-source-map");
const sorcery = require("sorcery");
const Vinyl = require("vinyl");
const bundlePath = path.resolve("built/local/bundle.js");
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => {
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: bundlePath, inlineSourceMap: true }, /*useBuiltCompiler*/ true));
let originalMap: any;
let prebundledContent: string;
/** @type {*} */
let originalMap;
/** @type {string} */
let prebundledContent;
browserify(testProject.src()
.pipe(newer(bundlePath))
.pipe(sourcemaps.init())
@ -855,8 +884,10 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo
});
});
function cleanTestDirs(done: (e?: any) => void) {
/**
* @param {(e?: any) => void} done
*/
function cleanTestDirs(done) {
// Clean the local baselines & Rwc baselines directories
del([
localBaseline,
@ -872,8 +903,17 @@ function cleanTestDirs(done: (e?: any) => void) {
});
}
// used to pass data from jake command line directly to run.js
function writeTestConfigFile(tests: string, runners: string, light: boolean, taskConfigsFolder?: string, workerCount?: number, stackTraceLimit?: string, timeout?: number) {
/**
* used to pass data from jake command line directly to run.js
* @param {string} tests
* @param {string} runners
* @param {boolean} light
* @param {string=} taskConfigsFolder
* @param {number=} workerCount
* @param {string=} stackTraceLimit
* @param {number=} timeout
*/
function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, timeout) {
const testConfigContents = JSON.stringify({
test: tests ? [tests] : undefined,
runner: runners ? runners.split(",") : undefined,
@ -974,7 +1014,7 @@ gulp.task("baseline-accept-test262", "Makes the most recent test262 test results
const webhostPath = "tests/webhost/webtsc.ts";
const webhostJsPath = "tests/webhost/webtsc.js";
gulp.task(webhostJsPath, /*help*/ false, [servicesFile], () => {
const settings: tsc.Settings = getCompilerSettings({
const settings = getCompilerSettings({
outFile: webhostJsPath
}, /*useBuiltCompiler*/ true);
return gulp.src(webhostPath)
@ -994,7 +1034,7 @@ gulp.task("webhost", "Builds the tsc web host", [webhostJsPath], () => {
const perftscPath = "tests/perftsc.ts";
const perftscJsPath = "built/local/perftsc.js";
gulp.task(perftscJsPath, /*help*/ false, [servicesFile], () => {
const settings: tsc.Settings = getCompilerSettings({
const settings = getCompilerSettings({
outFile: perftscJsPath
}, /*useBuiltCompiler*/ true);
return gulp.src(perftscPath)
@ -1025,7 +1065,7 @@ gulp.task(loggedIOJsPath, /*help*/ false, [], (done) => {
const instrumenterPath = path.join(harnessDirectory, "instrumenter.ts");
const instrumenterJsPath = path.join(builtLocalDirectory, "instrumenter.js");
gulp.task(instrumenterJsPath, /*help*/ false, [servicesFile], () => {
const settings: tsc.Settings = getCompilerSettings({
const settings = getCompilerSettings({
module: "commonjs",
target: "es5",
lib: [
@ -1052,7 +1092,7 @@ gulp.task("update-sublime", "Updates the sublime plugin's tsserver", ["local", s
});
gulp.task("build-rules", "Compiles tslint rules to js", () => {
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs", lib: ["es6"] }, /*useBuiltCompiler*/ false);
const settings = getCompilerSettings({ module: "commonjs", lib: ["es6"] }, /*useBuiltCompiler*/ false);
const dest = path.join(builtLocalDirectory, "tslint");
return gulp.src("scripts/tslint/**/*.ts")
.pipe(newer({
@ -1065,51 +1105,6 @@ gulp.task("build-rules", "Compiles tslint rules to js", () => {
.pipe(gulp.dest(dest));
});
const lintTargets = [
"Gulpfile.ts",
"src/compiler/**/*.ts",
"src/harness/**/*.ts",
"!src/harness/unittests/services/formatting/**/*.ts",
"src/server/**/*.ts",
"scripts/tslint/**/*.ts",
"src/services/**/*.ts",
"tests/*.ts", "tests/webhost/*.ts" // Note: does *not* descend recursively
];
function sendNextFile(files: {path: string}[], child: cp.ChildProcess, callback: (failures: number) => void, failures: number) {
const file = files.pop();
if (file) {
console.log(`Linting '${file.path}'.`);
child.send({ kind: "file", name: file.path });
}
else {
child.send({ kind: "close" });
callback(failures);
}
}
function spawnLintWorker(files: {path: string}[], callback: (failures: number) => void) {
const child = cp.fork("./scripts/parallel-lint");
let failures = 0;
child.on("message", data => {
switch (data.kind) {
case "result":
if (data.failures > 0) {
failures += data.failures;
console.log(data.output);
}
sendNextFile(files, child, callback, failures);
break;
case "error":
console.error(data.error);
failures++;
sendNextFile(files, child, callback, failures);
break;
}
});
sendNextFile(files, child, callback, failures);
}
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"));
for (const project of ["scripts/tslint/tsconfig.json", "src/tsconfig-base.json"]) {

View file

@ -491,7 +491,7 @@ compileFile(/*outfile*/configurePrereleaseJs,
/*prereqs*/[configurePrereleaseTs],
/*prefixes*/[],
/*useBuiltCompiler*/ false,
{ noOutFile: false, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false });
{ noOutFile: true, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false });
task("setDebugMode", function () {
useDebugMode = true;

View file

@ -24,7 +24,7 @@ Please help us by doing the following steps before logging an issue:
-->
<!-- Please try to reproduce the issue with `typescript@next`. It may have already been fixed. -->
**TypeScript Version:** 2.7.0-dev.201xxxxx
**TypeScript Version:** 2.9.0-dev.201xxxxx
<!-- Search terms you tried before logging this (so others can find this issue more easily) -->
**Search Terms:**

1558
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -48,11 +48,12 @@
"@types/q": "latest",
"@types/run-sequence": "latest",
"@types/through2": "latest",
"@types/travis-fold": "latest",
"@types/xml2js": "^0.4.0",
"xml2js": "^0.4.19",
"browser-resolve": "^1.11.2",
"browserify": "latest",
"chai": "latest",
"chalk": "latest",
"convert-source-map": "latest",
"del": "latest",
"gulp": "3.X",
@ -76,11 +77,10 @@
"source-map-support": "latest",
"through2": "latest",
"travis-fold": "latest",
"ts-node": "latest",
"tslint": "latest",
"typescript": "next",
"vinyl": "latest",
"chalk": "latest",
"typescript": "next"
"xml2js": "^0.4.19"
},
"scripts": {
"pretest": "jake tests",

View file

@ -178,7 +178,7 @@ function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptSer
ts.sys.writeFile(outputFile, protocolDts);
if (diagnostics.length) {
const flattenedDiagnostics = diagnostics.map(d => `${ts.flattenDiagnosticMessageText(d.messageText, "\n")} at ${d.file.fileName} line ${d.start}`).join("\n");
const flattenedDiagnostics = diagnostics.map(d => `${ts.flattenDiagnosticMessageText(d.messageText, "\n")} at ${d.file ? d.file.fileName : "<unknown>"} line ${d.start}`).join("\n");
throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
}
}

View file

@ -1,4 +1,9 @@
/// <reference path="../src/compiler/sys.ts" />
/// <reference types="node"/>
import { normalize } from "path";
import assert = require("assert");
import { readFileSync, writeFileSync } from "fs";
const args = process.argv.slice(2);
/**
* A minimal description for a parsed package.json object.
@ -10,28 +15,27 @@ interface PackageJson {
}
function main(): void {
const sys = ts.sys;
if (sys.args.length < 3) {
sys.write("Usage:" + sys.newLine)
sys.write("\tnode configureNightly.js <dev|insiders> <package.json location> <file containing version>" + sys.newLine);
if (args.length < 3) {
console.log("Usage:");
console.log("\tnode configureNightly.js <dev|insiders> <package.json location> <file containing version>");
return;
}
const tag = sys.args[0];
const tag = args[0];
if (tag !== "dev" && tag !== "insiders") {
throw new Error(`Unexpected tag name '${tag}'.`);
}
// Acquire the version from the package.json file and modify it appropriately.
const packageJsonFilePath = ts.normalizePath(sys.args[1]);
const packageJsonValue: PackageJson = JSON.parse(sys.readFile(packageJsonFilePath));
const packageJsonFilePath = normalize(args[1]);
const packageJsonValue: PackageJson = JSON.parse(readFileSync(packageJsonFilePath).toString());
const { majorMinor, patch } = parsePackageJsonVersion(packageJsonValue.version);
const prereleasePatch = getPrereleasePatch(tag, patch);
// Acquire and modify the source file that exposes the version string.
const tsFilePath = ts.normalizePath(sys.args[2]);
const tsFileContents = ts.sys.readFile(tsFilePath);
const tsFilePath = normalize(args[2]);
const tsFileContents = readFileSync(tsFilePath).toString();
const modifiedTsFileContents = updateTsFile(tsFilePath, tsFileContents, majorMinor, patch, prereleasePatch);
// Ensure we are actually changing something - the user probably wants to know that the update failed.
@ -44,20 +48,20 @@ function main(): void {
// Finally write the changes to disk.
// Modify the package.json structure
packageJsonValue.version = `${majorMinor}.${prereleasePatch}`;
sys.writeFile(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4))
sys.writeFile(tsFilePath, modifiedTsFileContents);
writeFileSync(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4))
writeFileSync(tsFilePath, modifiedTsFileContents);
}
function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: string, patch: string, nightlyPatch: string): string {
const majorMinorRgx = /export const versionMajorMinor = "(\d+\.\d+)"/;
const majorMinorMatch = majorMinorRgx.exec(tsFileContents);
ts.Debug.assert(majorMinorMatch !== null, "", () => `The file seems to no longer have a string matching '${majorMinorRgx}'.`);
assert(majorMinorMatch !== null, `The file seems to no longer have a string matching '${majorMinorRgx}'.`);
const parsedMajorMinor = majorMinorMatch[1];
ts.Debug.assert(parsedMajorMinor === majorMinor, "versionMajorMinor does not match.", () => `${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`);
assert(parsedMajorMinor === majorMinor, `versionMajorMinor does not match. ${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`);
const versionRgx = /export const version = `\$\{versionMajorMinor\}\.(\d)(-dev)?`;/;
const patchMatch = versionRgx.exec(tsFileContents);
ts.Debug.assert(patchMatch !== null, "The file seems to no longer have a string matching", () => versionRgx.toString());
assert(patchMatch !== null, "The file seems to no longer have a string matching " + versionRgx.toString());
const parsedPatch = patchMatch[1];
if (parsedPatch !== patch) {
throw new Error(`patch does not match. ${tsFilePath}: '${parsedPatch}; package.json: '${patch}'`);
@ -69,7 +73,7 @@ function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: st
function parsePackageJsonVersion(versionString: string): { majorMinor: string, patch: string } {
const versionRgx = /(\d+\.\d+)\.(\d+)($|\-)/;
const match = versionString.match(versionRgx);
ts.Debug.assert(match !== null, "package.json 'version' should match", () => versionRgx.toString());
assert(match !== null, "package.json 'version' should match " + versionRgx.toString());
return { majorMinor: match[1], patch: match[2] };
}

View file

@ -14,4 +14,3 @@ declare module "gulp-insert" {
}
declare module "sorcery";
declare module "travis-fold";

View file

@ -520,8 +520,9 @@ namespace ts {
const saveReturnTarget = currentReturnTarget;
const saveActiveLabels = activeLabels;
const saveHasExplicitReturn = hasExplicitReturn;
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node);
// A non-async IIFE is considered part of the containing control flow. Return statements behave
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) &&
!(<FunctionLikeDeclaration>node).asteriskToken && !!getImmediatelyInvokedFunctionExpression(node);
// A non-async, non-generator IIFE is considered part of the containing control flow. Return statements behave
// similarly to break statements that exit to a label just past the statement body.
if (!isIIFE) {
currentFlow = { flags: FlowFlags.Start };
@ -2230,14 +2231,14 @@ namespace ts {
bindAnonymousDeclaration(file, SymbolFlags.ValueModule, `"${removeFileExtension(file.fileName)}"` as __String);
}
function bindExportAssignment(node: ExportAssignment | BinaryExpression) {
function bindExportAssignment(node: ExportAssignment) {
if (!container.symbol || !container.symbol.exports) {
// Export assignment in some sort of block construct
bindAnonymousDeclaration(node, SymbolFlags.Alias, getDeclarationName(node));
}
else {
const flags = node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node)
// An export default clause with an EntityNameExpression exports all meanings of that identifier
// An export default clause with an EntityNameExpression or a class expression exports all meanings of that identifier or expression;
? SymbolFlags.Alias
// An export default clause with any other expression exports a value
: SymbolFlags.Property;
@ -2332,7 +2333,10 @@ namespace ts {
// 'module.exports = expr' assignment
setCommonJsModuleIndicator(node);
declareSymbol(file.symbol.exports, file.symbol, node, SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule, SymbolFlags.None);
const flags = exportAssignmentIsAlias(node)
? SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class
: SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule;
declareSymbol(file.symbol.exports, file.symbol, node, flags, SymbolFlags.None);
}
function bindThisPropertyAssignment(node: BinaryExpression | PropertyAccessExpression) {

View file

@ -249,7 +249,7 @@ namespace ts {
export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, host, oldProgram, configFileParsingDiagnostics }: BuilderCreationParameters) {
// Return same program if underlying program doesnt change
let oldState = oldProgram && oldProgram.getState();
if (oldState && newProgram === oldState.program && configFileParsingDiagnostics !== newProgram.getConfigFileParsingDiagnostics()) {
if (oldState && newProgram === oldState.program && configFileParsingDiagnostics === newProgram.getConfigFileParsingDiagnostics()) {
newProgram = undefined;
oldState = undefined;
return oldProgram;

File diff suppressed because it is too large Load diff

View file

@ -678,6 +678,12 @@ namespace ts {
category: Diagnostics.Advanced_Options,
description: Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types,
},
{
name: "keyofStringsOnly",
type: "boolean",
category: Diagnostics.Advanced_Options,
description: Diagnostics.Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols,
},
{
// A list of plugins to load in the language service
name: "plugins",
@ -2127,19 +2133,10 @@ namespace ts {
});
function createDiagnostic(message: DiagnosticMessage, spec: string): Diagnostic {
const jsonObjectLiteral = getTsConfigObjectLiteralExpression(jsonSourceFile);
if (jsonObjectLiteral) {
for (const property of getPropertyAssignment(jsonObjectLiteral, specKey)) {
if (isArrayLiteralExpression(property.initializer)) {
for (const element of property.initializer.elements) {
if (isStringLiteral(element) && element.text === spec) {
return createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec);
}
}
}
}
}
return createCompilerDiagnostic(message, spec);
const element = getTsConfigPropArrayElementValue(jsonSourceFile, specKey, spec);
return element ?
createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec) :
createCompilerDiagnostic(message, spec);
}
}

View file

@ -2212,6 +2212,15 @@ namespace ts {
return absolutePath;
}
export function getRelativePath(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName) {
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
return ensurePathIsRelative(relativePath);
}
export function ensurePathIsRelative(path: string): string {
return !pathIsRelative(path) ? "./" + path : path;
}
export function getBaseFileName(path: string) {
if (path === undefined) {
return undefined;
@ -2987,18 +2996,19 @@ namespace ts {
}
/** Remove the *first* occurrence of `item` from the array. */
export function unorderedRemoveItem<T>(array: T[], item: T): void {
unorderedRemoveFirstItemWhere(array, element => element === item);
export function unorderedRemoveItem<T>(array: T[], item: T) {
return unorderedRemoveFirstItemWhere(array, element => element === item);
}
/** Remove the *first* element satisfying `predicate`. */
function unorderedRemoveFirstItemWhere<T>(array: T[], predicate: (element: T) => boolean): void {
function unorderedRemoveFirstItemWhere<T>(array: T[], predicate: (element: T) => boolean) {
for (let i = 0; i < array.length; i++) {
if (predicate(array[i])) {
unorderedRemoveItemAt(array, i);
break;
return true;
}
}
return false;
}
export type GetCanonicalFileName = (fileName: string) => string;

View file

@ -23,6 +23,10 @@
"category": "Error",
"code": 1010
},
"An element access expression should take an argument.": {
"category": "Error",
"code": 1011
},
"Unexpected token.": {
"category": "Error",
"code": 1012
@ -967,6 +971,10 @@
"category": "Error",
"code": 1342
},
"The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.": {
"category": "Error",
"code": 1343
},
"Duplicate identifier '{0}'.": {
"category": "Error",
@ -2947,10 +2955,6 @@
"category": "Message",
"code": 6040
},
"Compilation complete. Watching for file changes.": {
"category": "Message",
"code": 6042
},
"Generates corresponding '.map' file.": {
"category": "Message",
"code": 6043
@ -3526,18 +3530,27 @@
"code": 6192,
"reportsUnnecessary": true
},
"Found 1 error.": {
"Found 1 error. Watching for file changes.": {
"category": "Message",
"code": 6193
},
"Found {0} errors.": {
"Found {0} errors. Watching for file changes.": {
"category": "Message",
"code": 6194
},
"Resolve module name imported with '.json' extension to the json source file.": {
"Resolve 'keyof' to string valued property names only (no numbers or symbols).": {
"category": "Message",
"code": 6195
},
"'{0}' is declared but never used.": {
"category": "Error",
"code": 6196,
"reportsUnnecessary": true
},
"Resolve module name imported with '.json' extension to the json source file.": {
"category": "Message",
"code": 6197
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
@ -3927,7 +3940,7 @@
"category": "Message",
"code": 90007
},
"Add 'this.' to unresolved variable": {
"Add '{0}.' to unresolved variable": {
"category": "Message",
"code": 90008
},
@ -4135,7 +4148,7 @@
"category": "Message",
"code": 95036
},
"Add 'this.' to all unresolved variables matching a member name": {
"Add qualifier to all unresolved variables matching a member name": {
"category": "Message",
"code": 95037
},

View file

@ -1445,9 +1445,9 @@ namespace ts {
function emitElementAccessExpression(node: ElementAccessExpression) {
emitExpression(node.expression);
const openPos = emitTokenWithComment(SyntaxKind.OpenBracketToken, node.expression.end, writePunctuation, node);
emitTokenWithComment(SyntaxKind.OpenBracketToken, node.expression.end, writePunctuation, node);
emitExpression(node.argumentExpression);
emitTokenWithComment(SyntaxKind.CloseBracketToken, node.argumentExpression ? node.argumentExpression.end : openPos, writePunctuation, node);
emitTokenWithComment(SyntaxKind.CloseBracketToken, node.argumentExpression.end, writePunctuation, node);
}
function emitCallExpression(node: CallExpression) {
@ -1466,6 +1466,7 @@ namespace ts {
function emitTaggedTemplateExpression(node: TaggedTemplateExpression) {
emitExpression(node.tag);
emitTypeArguments(node, node.typeArguments);
writeSpace();
emitExpression(node.template);
}

View file

@ -1030,17 +1030,32 @@ namespace ts {
: node;
}
export function createTaggedTemplate(tag: Expression, template: TemplateLiteral) {
export function createTaggedTemplate(tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
export function createTaggedTemplate(tag: Expression, typeArguments: ReadonlyArray<TypeNode>, template: TemplateLiteral): TaggedTemplateExpression;
/** @internal */
export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray<TypeNode> | TemplateLiteral, template?: TemplateLiteral): TaggedTemplateExpression;
export function createTaggedTemplate(tag: Expression, typeArgumentsOrTemplate: ReadonlyArray<TypeNode> | TemplateLiteral, template?: TemplateLiteral) {
const node = <TaggedTemplateExpression>createSynthesizedNode(SyntaxKind.TaggedTemplateExpression);
node.tag = parenthesizeForAccess(tag);
node.template = template;
if (template) {
node.typeArguments = asNodeArray(typeArgumentsOrTemplate as ReadonlyArray<TypeNode>);
node.template = template!;
}
else {
node.typeArguments = undefined;
node.template = typeArgumentsOrTemplate as TemplateLiteral;
}
return node;
}
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral) {
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, template: TemplateLiteral): TaggedTemplateExpression;
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArguments: ReadonlyArray<TypeNode>, template: TemplateLiteral): TaggedTemplateExpression;
export function updateTaggedTemplate(node: TaggedTemplateExpression, tag: Expression, typeArgumentsOrTemplate: ReadonlyArray<TypeNode> | TemplateLiteral, template?: TemplateLiteral) {
return node.tag !== tag
|| node.template !== template
? updateNode(createTaggedTemplate(tag, template), node)
|| (template
? node.typeArguments !== typeArgumentsOrTemplate || node.template !== template
: node.typeArguments !== undefined || node.template !== typeArgumentsOrTemplate)
? updateNode(createTaggedTemplate(tag, typeArgumentsOrTemplate, template), node)
: node;
}

View file

@ -445,6 +445,12 @@ namespace ts {
}
}
export function resolveModuleNameFromCache(moduleName: string, containingFile: string, cache: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations | undefined {
const containingDirectory = getDirectoryPath(containingFile);
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
return perFolderCache && perFolderCache.get(moduleName);
}
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
const traceEnabled = isTraceEnabled(compilerOptions, host);
if (traceEnabled) {

View file

@ -223,6 +223,7 @@ namespace ts {
visitNodes(cbNode, cbNodes, (<CallExpression>node).arguments);
case SyntaxKind.TaggedTemplateExpression:
return visitNode(cbNode, (<TaggedTemplateExpression>node).tag) ||
visitNodes(cbNode, cbNodes, (<TaggedTemplateExpression>node).typeArguments) ||
visitNode(cbNode, (<TaggedTemplateExpression>node).template);
case SyntaxKind.TypeAssertionExpression:
return visitNode(cbNode, (<TypeAssertion>node).type) ||
@ -539,7 +540,7 @@ namespace ts {
const newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks);
// Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import.
// We will manually port the flag to the new source file.
newSourceFile.flags |= (sourceFile.flags & NodeFlags.PossiblyContainsDynamicImport);
newSourceFile.flags |= (sourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags);
return newSourceFile;
}
@ -1280,7 +1281,7 @@ namespace ts {
if (reportAtCurrentPosition) {
parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0);
}
else {
else if (diagnosticMessage) {
parseErrorAtCurrentToken(diagnosticMessage, arg0);
}
@ -2665,6 +2666,20 @@ namespace ts {
return token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken;
}
function nextTokenIsDot() {
return nextToken() === SyntaxKind.DotToken;
}
function nextTokenIsOpenParenOrLessThanOrDot() {
switch (nextToken()) {
case SyntaxKind.OpenParenToken:
case SyntaxKind.LessThanToken:
case SyntaxKind.DotToken:
return true;
}
return false;
}
function parseTypeLiteral(): TypeLiteralNode {
const node = <TypeLiteralNode>createNode(SyntaxKind.TypeLiteral);
node.members = parseObjectTypeMembers();
@ -3133,7 +3148,7 @@ namespace ts {
case SyntaxKind.Identifier:
return true;
case SyntaxKind.ImportKeyword:
return lookAhead(nextTokenIsOpenParenOrLessThan);
return lookAhead(nextTokenIsOpenParenOrLessThanOrDot);
default:
return isIdentifier();
}
@ -3995,14 +4010,31 @@ namespace ts {
// 3)we have a MemberExpression which either completes the LeftHandSideExpression,
// or starts the beginning of the first four CallExpression productions.
let expression: MemberExpression;
if (token() === SyntaxKind.ImportKeyword && lookAhead(nextTokenIsOpenParenOrLessThan)) {
// We don't want to eagerly consume all import keyword as import call expression so we look a head to find "("
// For example:
// var foo3 = require("subfolder
// import * as foo1 from "module-from-node
// We want this import to be a statement rather than import call expression
sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport;
expression = parseTokenNode<PrimaryExpression>();
if (token() === SyntaxKind.ImportKeyword) {
if (lookAhead(nextTokenIsOpenParenOrLessThan)) {
// We don't want to eagerly consume all import keyword as import call expression so we look ahead to find "("
// For example:
// var foo3 = require("subfolder
// import * as foo1 from "module-from-node
// We want this import to be a statement rather than import call expression
sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport;
expression = parseTokenNode<PrimaryExpression>();
}
else if (lookAhead(nextTokenIsDot)) {
// This is an 'import.*' metaproperty (i.e. 'import.meta')
const fullStart = scanner.getStartPos();
nextToken(); // advance past the 'import'
nextToken(); // advance past the dot
const node = createNode(SyntaxKind.MetaProperty, fullStart) as MetaProperty;
node.keywordToken = SyntaxKind.ImportKeyword;
node.name = parseIdentifierName();
expression = finishNode(node);
sourceFile.flags |= NodeFlags.PossiblyContainsImportMeta;
}
else {
expression = parseMemberExpressionOrHigher();
}
}
else {
expression = token() === SyntaxKind.SuperKeyword ? parseSuperExpression() : parseMemberExpressionOrHigher();
@ -4388,14 +4420,15 @@ namespace ts {
const indexedAccess = <ElementAccessExpression>createNode(SyntaxKind.ElementAccessExpression, expression.pos);
indexedAccess.expression = expression;
// It's not uncommon for a user to write: "new Type[]".
// Check for that common pattern and report a better error message.
if (token() !== SyntaxKind.CloseBracketToken) {
indexedAccess.argumentExpression = allowInAnd(parseExpression);
if (indexedAccess.argumentExpression.kind === SyntaxKind.StringLiteral || indexedAccess.argumentExpression.kind === SyntaxKind.NumericLiteral) {
const literal = <LiteralExpression>indexedAccess.argumentExpression;
literal.text = internIdentifier(literal.text);
if (token() === SyntaxKind.CloseBracketToken) {
indexedAccess.argumentExpression = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ true, Diagnostics.An_element_access_expression_should_take_an_argument);
}
else {
const argument = allowInAnd(parseExpression);
if (isStringOrNumericLiteral(argument)) {
argument.text = internIdentifier(argument.text);
}
indexedAccess.argumentExpression = argument;
}
parseExpected(SyntaxKind.CloseBracketToken);
@ -4403,13 +4436,8 @@ namespace ts {
continue;
}
if (token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead) {
const tagExpression = <TaggedTemplateExpression>createNode(SyntaxKind.TaggedTemplateExpression, expression.pos);
tagExpression.tag = expression;
tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral
? <NoSubstitutionTemplateLiteral>parseLiteralNode()
: parseTemplateExpression();
expression = finishNode(tagExpression);
if (isTemplateStartOfTaggedTemplate()) {
expression = parseTaggedTemplateRest(expression, /*typeArguments*/ undefined);
continue;
}
@ -4417,6 +4445,20 @@ namespace ts {
}
}
function isTemplateStartOfTaggedTemplate() {
return token() === SyntaxKind.NoSubstitutionTemplateLiteral || token() === SyntaxKind.TemplateHead;
}
function parseTaggedTemplateRest(tag: LeftHandSideExpression, typeArguments: NodeArray<TypeNode> | undefined) {
const tagExpression = <TaggedTemplateExpression>createNode(SyntaxKind.TaggedTemplateExpression, tag.pos);
tagExpression.tag = tag;
tagExpression.typeArguments = typeArguments;
tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral
? <NoSubstitutionTemplateLiteral>parseLiteralNode()
: parseTemplateExpression();
return finishNode(tagExpression);
}
function parseCallExpressionRest(expression: LeftHandSideExpression): LeftHandSideExpression {
while (true) {
expression = parseMemberExpressionRest(expression);
@ -4430,6 +4472,11 @@ namespace ts {
return expression;
}
if (isTemplateStartOfTaggedTemplate()) {
expression = parseTaggedTemplateRest(expression, typeArguments);
continue;
}
const callExpr = <CallExpression>createNode(SyntaxKind.CallExpression, expression.pos);
callExpr.expression = expression;
callExpr.typeArguments = typeArguments;
@ -4477,8 +4524,10 @@ namespace ts {
function canFollowTypeArgumentsInExpression(): boolean {
switch (token()) {
case SyntaxKind.OpenParenToken: // foo<x>(
// this case are the only case where this token can legally follow a type argument
// list. So we definitely want to treat this as a type arg list.
case SyntaxKind.NoSubstitutionTemplateLiteral: // foo<T> `...`
case SyntaxKind.TemplateHead: // foo<T> `...${100}...`
// these are the only tokens can legally follow a type argument
// list. So we definitely want to treat them as type arg lists.
case SyntaxKind.DotToken: // foo<x>.
case SyntaxKind.CloseParenToken: // foo<x>)
@ -4546,7 +4595,7 @@ namespace ts {
case SyntaxKind.FunctionKeyword:
return parseFunctionExpression();
case SyntaxKind.NewKeyword:
return parseNewExpression();
return parseNewExpressionOrNewDotTarget();
case SyntaxKind.SlashToken:
case SyntaxKind.SlashEqualsToken:
if (reScanSlashToken() === SyntaxKind.RegularExpressionLiteral) {
@ -4697,7 +4746,7 @@ namespace ts {
return isIdentifier() ? parseIdentifier() : undefined;
}
function parseNewExpression(): NewExpression | MetaProperty {
function parseNewExpressionOrNewDotTarget(): NewExpression | MetaProperty {
const fullStart = scanner.getStartPos();
parseExpected(SyntaxKind.NewKeyword);
if (parseOptional(SyntaxKind.DotToken)) {
@ -4707,9 +4756,23 @@ namespace ts {
return finishNode(node);
}
let expression: MemberExpression = parsePrimaryExpression();
let typeArguments;
while (true) {
expression = parseMemberExpressionRest(expression);
typeArguments = tryParse(parseTypeArgumentsInExpression);
if (isTemplateStartOfTaggedTemplate()) {
Debug.assert(!!typeArguments,
"Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'");
expression = parseTaggedTemplateRest(expression, typeArguments);
typeArguments = undefined;
}
break;
}
const node = <NewExpression>createNode(SyntaxKind.NewExpression, fullStart);
node.expression = parseMemberExpressionOrHigher();
node.typeArguments = tryParse(parseTypeArgumentsInExpression);
node.expression = expression;
node.typeArguments = typeArguments;
if (node.typeArguments || token() === SyntaxKind.OpenParenToken) {
node.arguments = parseArgumentList();
}
@ -5131,7 +5194,7 @@ namespace ts {
return true;
case SyntaxKind.ImportKeyword:
return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThan);
return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThanOrDot);
case SyntaxKind.ConstKeyword:
case SyntaxKind.ExportKeyword:
@ -6117,14 +6180,35 @@ namespace ts {
}
function setExternalModuleIndicator(sourceFile: SourceFile) {
sourceFile.externalModuleIndicator = forEach(sourceFile.statements, node =>
hasModifier(node, ModifierFlags.Export)
|| node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference
|| node.kind === SyntaxKind.ImportDeclaration
|| node.kind === SyntaxKind.ExportAssignment
|| node.kind === SyntaxKind.ExportDeclaration
// Try to use the first top-level import/export when available, then
// fall back to looking for an 'import.meta' somewhere in the tree if necessary.
sourceFile.externalModuleIndicator =
forEach(sourceFile.statements, isAnExternalModuleIndicatorNode) ||
getImportMetaIfNecessary(sourceFile);
}
function isAnExternalModuleIndicatorNode(node: Node) {
return hasModifier(node, ModifierFlags.Export)
|| node.kind === SyntaxKind.ImportEqualsDeclaration && (<ImportEqualsDeclaration>node).moduleReference.kind === SyntaxKind.ExternalModuleReference
|| node.kind === SyntaxKind.ImportDeclaration
|| node.kind === SyntaxKind.ExportAssignment
|| node.kind === SyntaxKind.ExportDeclaration
? node
: undefined);
: undefined;
}
function getImportMetaIfNecessary(sourceFile: SourceFile) {
return sourceFile.flags & NodeFlags.PossiblyContainsImportMeta ?
walkTreeForExternalModuleIndicators(sourceFile) :
undefined;
}
function walkTreeForExternalModuleIndicators(node: Node): Node {
return isImportMeta(node) ? node : forEachChild(node, walkTreeForExternalModuleIndicators);
}
function isImportMeta(node: Node): boolean {
return isMetaProperty(node) && node.keywordToken === SyntaxKind.ImportKeyword && node.name.escapedText === "meta";
}
const enum ParsingContext {

View file

@ -622,9 +622,6 @@ namespace ts {
Debug.assert(!!missingFilePaths);
// unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks
moduleResolutionCache = undefined;
// Release any files we have acquired in the old program but are
// not part of the new program.
if (oldProgram && host.onReleaseOldSourceFile) {
@ -670,7 +667,8 @@ namespace ts {
sourceFileToPackageName,
redirectTargetsSet,
isEmittedFile,
getConfigFileParsingDiagnostics
getConfigFileParsingDiagnostics,
getResolvedModuleWithFailedLookupLocationsFromCache,
};
verifyCompilerOptions();
@ -679,6 +677,10 @@ namespace ts {
return program;
function getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations {
return moduleResolutionCache && resolveModuleNameFromCache(moduleName, containingFile, moduleResolutionCache);
}
function toPath(fileName: string): Path {
return ts.toPath(fileName, currentDirectory, getCanonicalFileName);
}
@ -984,7 +986,7 @@ namespace ts {
// moduleAugmentations has changed
oldProgram.structureIsReused = StructureIsReused.SafeModules;
}
if ((oldSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport) !== (newSourceFile.flags & NodeFlags.PossiblyContainsDynamicImport)) {
if ((oldSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags) !== (newSourceFile.flags & NodeFlags.PermanentlySetIncrementalFlags)) {
// dynamicImport has changed
oldProgram.structureIsReused = StructureIsReused.SafeModules;
}
@ -1624,6 +1626,9 @@ namespace ts {
collectDynamicImportOrRequireCalls(node);
}
}
if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) {
collectDynamicImportOrRequireCalls(file.endOfFileToken);
}
file.imports = imports || emptyArray;
file.moduleAugmentations = moduleAugmentations || emptyArray;
@ -2004,7 +2009,8 @@ namespace ts {
&& !options.noResolve
&& i < file.imports.length
&& !elideImport
&& !(isJsFile && !options.allowJs);
&& !(isJsFile && !options.allowJs)
&& (isInJavaScriptFile(file.imports[i]) || !(file.imports[i].flags & NodeFlags.JSDoc));
if (elideImport) {
modulesWithElidedImports.set(file.path, true);

View file

@ -10,6 +10,7 @@ namespace ts {
invalidateResolutionOfFile(filePath: Path): void;
removeResolutionsOfFile(filePath: Path): void;
setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map<ReadonlyArray<string>>): void;
createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution;
startCachingPerDirectoryResolution(): void;
@ -74,6 +75,7 @@ namespace ts {
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string, logChangesWhenResolvingModule: boolean): ResolutionCache {
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
let filesWithInvalidatedResolutions: Map<true> | undefined;
let filesWithInvalidatedNonRelativeUnresolvedImports: Map<ReadonlyArray<string>> | undefined;
let allFilesHaveInvalidatedResolution = false;
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory());
@ -122,6 +124,7 @@ namespace ts {
resolveTypeReferenceDirectives,
removeResolutionsOfFile,
invalidateResolutionOfFile,
setFilesWithInvalidatedNonRelativeUnresolvedImports,
createHasInvalidatedResolution,
updateTypeRootsWatch,
closeTypeRootsWatch,
@ -165,6 +168,16 @@ namespace ts {
return collected;
}
function isFileWithInvalidatedNonRelativeUnresolvedImports(path: Path) {
if (!filesWithInvalidatedNonRelativeUnresolvedImports) {
return false;
}
// Invalidated if file has unresolved imports
const value = filesWithInvalidatedNonRelativeUnresolvedImports.get(path);
return value && !!value.length;
}
function createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution {
if (allFilesHaveInvalidatedResolution || forceAllFilesAsInvalidated) {
// Any file asked would have invalidated resolution
@ -173,7 +186,8 @@ namespace ts {
}
const collected = filesWithInvalidatedResolutions;
filesWithInvalidatedResolutions = undefined;
return path => collected && collected.has(path);
return path => (collected && collected.has(path)) ||
isFileWithInvalidatedNonRelativeUnresolvedImports(path);
}
function clearPerDirectoryResolutions() {
@ -184,6 +198,7 @@ namespace ts {
function finishCachingPerDirectoryResolution() {
allFilesHaveInvalidatedResolution = false;
filesWithInvalidatedNonRelativeUnresolvedImports = undefined;
directoryWatchesOfFailedLookups.forEach((watcher, path) => {
if (watcher.refCount === 0) {
directoryWatchesOfFailedLookups.delete(path);
@ -237,13 +252,15 @@ namespace ts {
const resolvedModules: R[] = [];
const compilerOptions = resolutionHost.getCompilationSettings();
const hasInvalidatedNonRelativeUnresolvedImport = logChanges && isFileWithInvalidatedNonRelativeUnresolvedImports(path);
const seenNamesInFile = createMap<true>();
for (const name of names) {
let resolution = resolutionsInFile.get(name);
// Resolution is valid if it is present and not invalidated
if (!seenNamesInFile.has(name) &&
allFilesHaveInvalidatedResolution || !resolution || resolution.isInvalidated) {
allFilesHaveInvalidatedResolution || !resolution || resolution.isInvalidated ||
// If the name is unresolved import that was invalidated, recalculate
(hasInvalidatedNonRelativeUnresolvedImport && !isExternalModuleNameRelative(name) && !getResolutionWithResolvedFileName(resolution))) {
const existingResolution = resolution;
const resolutionInDirectory = perDirectoryResolution.get(name);
if (resolutionInDirectory) {
@ -284,7 +301,7 @@ namespace ts {
if (oldResolution === newResolution) {
return true;
}
if (!oldResolution || !newResolution || oldResolution.isInvalidated) {
if (!oldResolution || !newResolution) {
return false;
}
const oldResult = getResolutionWithResolvedFileName(oldResolution);
@ -577,6 +594,11 @@ namespace ts {
);
}
function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: Map<ReadonlyArray<string>>) {
Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined);
filesWithInvalidatedNonRelativeUnresolvedImports = filesMap;
}
function invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath: Path, isCreatingWatchedDirectory: boolean) {
let isChangedFailedLookupLocation: (location: string) => boolean;
if (isCreatingWatchedDirectory) {

View file

@ -428,6 +428,7 @@ namespace ts {
newLine: string;
useCaseSensitiveFileNames: boolean;
write(s: string): void;
writeOutputIsTTY?(): boolean;
readFile(path: string, encoding?: string): string | undefined;
getFileSize?(path: string): number;
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void;
@ -561,6 +562,9 @@ namespace ts {
write(s: string): void {
process.stdout.write(s);
},
writeOutputIsTTY() {
return process.stdout.isTTY;
},
readFile,
writeFile,
watchFile: getWatchFile(),

View file

@ -46,7 +46,7 @@ namespace ts {
value = node.right;
}
else {
return value;
return visitNode(value, visitor, isExpression);
}
}
}

View file

@ -502,6 +502,9 @@ namespace ts {
case SyntaxKind.NewExpression:
return visitNewExpression(<NewExpression>node);
case SyntaxKind.TaggedTemplateExpression:
return visitTaggedTemplateExpression(<TaggedTemplateExpression>node);
case SyntaxKind.NonNullExpression:
// TypeScript non-null expressions are removed, but their subtrees are preserved.
return visitNonNullExpression(<NonNullExpression>node);
@ -2547,6 +2550,14 @@ namespace ts {
visitNodes(node.arguments, visitor, isExpression));
}
function visitTaggedTemplateExpression(node: TaggedTemplateExpression) {
return updateTaggedTemplate(
node,
visitNode(node.tag, visitor, isExpression),
/*typeArguments*/ undefined,
visitNode(node.template, visitor, isExpression));
}
/**
* Determines whether to emit an enum declaration.
*

View file

@ -19,11 +19,18 @@ namespace ts {
let reportDiagnostic = createDiagnosticReporter(sys);
function updateReportDiagnostic(options: CompilerOptions) {
if (options.pretty) {
if (shouldBePretty(options)) {
reportDiagnostic = createDiagnosticReporter(sys, /*pretty*/ true);
}
}
function shouldBePretty(options: CompilerOptions) {
if (typeof options.pretty === "undefined") {
return !!sys.writeOutputIsTTY && sys.writeOutputIsTTY();
}
return options.pretty;
}
function padLeft(s: string, length: number) {
while (s.length < length) {
s = " " + s;
@ -147,9 +154,12 @@ namespace ts {
function updateWatchCompilationHost(watchCompilerHost: WatchCompilerHost<EmitAndSemanticDiagnosticsBuilderProgram>) {
const compileUsingBuilder = watchCompilerHost.createProgram;
watchCompilerHost.createProgram = (rootNames, options, host, oldProgram) => {
enableStatistics(options);
return compileUsingBuilder(rootNames, options, host, oldProgram);
watchCompilerHost.createProgram = (rootNames, options, host, oldProgram, configFileParsingDiagnostics) => {
Debug.assert(rootNames !== undefined || (options === undefined && !!oldProgram));
if (options !== undefined) {
enableStatistics(options);
}
return compileUsingBuilder(rootNames, options, host, oldProgram, configFileParsingDiagnostics);
};
const emitFilesUsingBuilder = watchCompilerHost.afterProgramCreate;
watchCompilerHost.afterProgramCreate = builderProgram => {
@ -159,7 +169,7 @@ namespace ts {
}
function createWatchStatusReporter(options: CompilerOptions) {
return ts.createWatchStatusReporter(sys, !!options.pretty);
return ts.createWatchStatusReporter(sys, shouldBePretty(options));
}
function createWatchOfConfigFile(configParseResult: ParsedCommandLine, optionsToExtend: CompilerOptions) {

View file

@ -490,20 +490,22 @@ namespace ts {
ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error
HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node
// This flag will be set when the parser encounters a dynamic import expression so that module resolution
// will not have to walk the tree if the flag is not set. However, this flag is just a approximation because
// once it is set, the flag never gets cleared (hence why it's named "PossiblyContainsDynamicImport").
// During editing, if dynamic import is removed, incremental parsing will *NOT* update this flag. This means that the tree will always be traversed
// during module resolution. However, the removal operation should not occur often and in the case of the
// These flags will be set when the parser encounters a dynamic import expression or 'import.meta' to avoid
// walking the tree if the flags are not set. However, these flags are just a approximation
// (hence why it's named "PossiblyContainsDynamicImport") because once set, the flags never get cleared.
// During editing, if a dynamic import is removed, incremental parsing will *NOT* clear this flag.
// This means that the tree will always be traversed during module resolution, or when looking for external module indicators.
// However, the removal operation should not occur often and in the case of the
// removal, it is likely that users will add the import anyway.
// The advantage of this approach is its simplicity. For the case of batch compilation,
// we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used.
/* @internal */
PossiblyContainsDynamicImport = 1 << 19,
JSDoc = 1 << 20, // If node was parsed inside jsdoc
/* @internal */ Ambient = 1 << 21, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
/* @internal */ InWithStatement = 1 << 22, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
JsonFile = 1 << 23, // If node was parsed in a Json
/* @internal */ PossiblyContainsDynamicImport = 1 << 19,
/* @internal */ PossiblyContainsImportMeta = 1 << 20,
JSDoc = 1 << 21, // If node was parsed inside jsdoc
/* @internal */ Ambient = 1 << 22, // If node was inside an ambient context -- a declaration file, or inside something with the `declare` modifier.
/* @internal */ InWithStatement = 1 << 23, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`)
JsonFile = 1 << 24, // If node was parsed in a Json
BlockScoped = Let | Const,
@ -515,6 +517,11 @@ namespace ts {
// Exclude these flags when parsing a Type
TypeExcludesFlags = YieldContext | AwaitContext,
// Represents all flags that are potentially set once and
// never cleared on SourceFiles which get re-used in between incremental parses.
// See the comment above on `PossiblyContainsDynamicImport` and `PossiblyContainsImportMeta`.
/* @internal */ PermanentlySetIncrementalFlags = PossiblyContainsDynamicImport | PossiblyContainsImportMeta,
}
export const enum ModifierFlags {
@ -880,6 +887,7 @@ namespace ts {
export interface PropertyDeclaration extends ClassElement, JSDocContainer {
kind: SyntaxKind.PropertyDeclaration;
parent: ClassLikeDeclaration;
name: PropertyName;
questionToken?: QuestionToken; // Present for use with reporting a grammar error
exclamationToken?: ExclamationToken;
@ -1685,7 +1693,7 @@ namespace ts {
export interface ElementAccessExpression extends MemberExpression {
kind: SyntaxKind.ElementAccessExpression;
expression: LeftHandSideExpression;
argumentExpression?: Expression;
argumentExpression: Expression;
}
export interface SuperElementAccessExpression extends ElementAccessExpression {
@ -1727,6 +1735,7 @@ namespace ts {
export interface TaggedTemplateExpression extends MemberExpression {
kind: SyntaxKind.TaggedTemplateExpression;
tag: LeftHandSideExpression;
typeArguments?: NodeArray<TypeNode>;
template: TemplateLiteral;
}
@ -1755,7 +1764,7 @@ namespace ts {
// for the same reasons we treat NewExpression as a PrimaryExpression.
export interface MetaProperty extends PrimaryExpression {
kind: SyntaxKind.MetaProperty;
keywordToken: SyntaxKind.NewKeyword;
keywordToken: SyntaxKind.NewKeyword | SyntaxKind.ImportKeyword;
name: Identifier;
}
@ -1892,7 +1901,7 @@ namespace ts {
kind: SyntaxKind.DebuggerStatement;
}
export interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement {
export interface MissingDeclaration extends DeclarationStatement {
kind: SyntaxKind.MissingDeclaration;
name?: Identifier;
}
@ -2331,7 +2340,7 @@ namespace ts {
}
export interface JSDocTag extends Node {
parent: JSDoc;
parent: JSDoc | JSDocTypeLiteral;
atToken: AtToken;
tagName: Identifier;
comment: string | undefined;
@ -2556,7 +2565,11 @@ namespace ts {
languageVersion: ScriptTarget;
/* @internal */ scriptKind: ScriptKind;
// The first node that causes this file to be an external module
/**
* The first "most obvious" node that makes a file an external module.
* This is intended to be the first top-level import/export,
* but could be arbitrarily nested (e.g. `import.meta`).
*/
/* @internal */ externalModuleIndicator: Node;
// The first node that causes this file to be a CommonJS module
/* @internal */ commonJsModuleIndicator: Node;
@ -2737,6 +2750,8 @@ namespace ts {
/* @internal */ redirectTargetsSet: Map<true>;
/** Is the file emitted file */
/* @internal */ isEmittedFile(file: string): boolean;
/* @internal */ getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
}
/* @internal */
@ -3010,6 +3025,13 @@ namespace ts {
* Others are added in computeSuggestionDiagnostics.
*/
/* @internal */ getSuggestionDiagnostics(file: SourceFile): ReadonlyArray<Diagnostic>;
/**
* Depending on the operation performed, it may be appropriate to throw away the checker
* if the cancellation token is triggered. Typically, if it is used for error checking
* and the operation is cancelled, then it should be discarded, otherwise it is safe to keep.
*/
runWithCancellationToken<T>(token: CancellationToken, cb: (checker: TypeChecker) => T): T;
}
/* @internal */
@ -3206,7 +3228,8 @@ namespace ts {
export type AnyValidImportOrReExport =
| (ImportDeclaration | ExportDeclaration) & { moduleSpecifier: StringLiteral }
| ImportEqualsDeclaration & { moduleReference: ExternalModuleReference & { expression: StringLiteral } }
| RequireOrImportCall;
| RequireOrImportCall
| ImportTypeNode & { argument: LiteralType };
/* @internal */
export type RequireOrImportCall = CallExpression & { arguments: [StringLiteralLike] };
@ -3386,6 +3409,7 @@ namespace ts {
/* @internal */ mergeId?: number; // Merge id (used to look up merged symbol)
/* @internal */ parent?: Symbol; // Parent symbol
/* @internal */ exportSymbol?: Symbol; // Exported symbol associated with this symbol
/* @internal */ nameType?: Type; // Type associated with a late-bound symbol
/* @internal */ constEnumOnlyModule?: boolean; // True if module contains only const enums or other modules with only const enums
/* @internal */ isReferenced?: SymbolFlags; // True if the symbol is referenced elsewhere. Keeps track of the meaning of a reference in case a symbol is both a type parameter and parameter.
/* @internal */ isReplaceableByMethod?: boolean; // Can this Javascript class property be replaced by a method symbol?
@ -3420,7 +3444,6 @@ namespace ts {
enumKind?: EnumKind; // Enum declaration classification
originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol`
lateSymbol?: Symbol; // Late-bound symbol for a computed property
nameType?: Type; // Type associate with a late-bound or mapped type property symbol's name
}
/* @internal */
@ -3617,11 +3640,14 @@ namespace ts {
Intrinsic = Any | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
/* @internal */
Primitive = String | Number | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol,
StringLike = String | StringLiteral | Index,
StringLike = String | StringLiteral,
NumberLike = Number | NumberLiteral | Enum,
BooleanLike = Boolean | BooleanLiteral,
EnumLike = Enum | EnumLiteral,
ESSymbolLike = ESSymbol | UniqueESSymbol,
VoidLike = Void | Undefined,
/* @internal */
DisjointDomains = NonPrimitive | StringLike | NumberLike | BooleanLike | ESSymbolLike | VoidLike | Null,
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection,
TypeVariable = TypeParameter | IndexedAccess,
@ -3638,7 +3664,15 @@ namespace ts {
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
/* @internal */
PropagatingFlags = ContainsWideningType | ContainsObjectLiteral | ContainsAnyFunctionType,
// The following flags are used for different purposes during union and intersection type construction
/* @internal */
NonWideningType = ContainsWideningType,
/* @internal */
Wildcard = ContainsObjectLiteral,
/* @internal */
EmptyObject = ContainsAnyFunctionType,
/* @internal */
ConstructionFlags = NonWideningType | Wildcard | EmptyObject
}
export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression;
@ -3774,7 +3808,7 @@ namespace ts {
/* @internal */
resolvedIndexType: IndexType;
/* @internal */
resolvedDeclaredIndexType: IndexType;
resolvedStringIndexType: IndexType;
/* @internal */
resolvedBaseConstraint: Type;
/* @internal */
@ -3863,7 +3897,7 @@ namespace ts {
/* @internal */
resolvedIndexType?: IndexType;
/* @internal */
resolvedDeclaredIndexType?: IndexType;
resolvedStringIndexType?: IndexType;
}
// Type parameters (TypeFlags.TypeParameter)
@ -3895,9 +3929,9 @@ namespace ts {
// keyof T types (TypeFlags.Index)
export interface IndexType extends InstantiableType {
/* @internal */
isDeclaredType?: boolean;
type: InstantiableType | UnionOrIntersectionType;
/* @internal */
stringsOnly: boolean;
}
export interface ConditionalRoot {
@ -4056,10 +4090,10 @@ namespace ts {
/* @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
parent?: WideningContext; // Parent context
propertyName?: __String; // Name of property in parent
siblings?: Type[]; // Types of siblings
resolvedProperties?: Symbol[]; // Properties occurring in sibling object literals
}
/* @internal */
@ -4174,6 +4208,7 @@ namespace ts {
inlineSources?: boolean;
isolatedModules?: boolean;
jsx?: JsxEmit;
keyofStringsOnly?: boolean;
lib?: string[];
/*@internal*/listEmittedFiles?: boolean;
/*@internal*/listFiles?: boolean;
@ -4207,7 +4242,7 @@ namespace ts {
preserveSymlinks?: boolean;
/* @internal */ preserveWatchOutput?: boolean;
project?: string;
/* @internal */ pretty?: DiagnosticStyle;
/* @internal */ pretty?: boolean;
reactNamespace?: string;
jsxFactory?: string;
removeComments?: boolean;
@ -4306,12 +4341,6 @@ namespace ts {
JSX,
}
/* @internal */
export const enum DiagnosticStyle {
Simple,
Pretty,
}
/** Either a parsed command line or a parsed tsconfig.json */
export interface ParsedCommandLine {
options: CompilerOptions;

View file

@ -1081,6 +1081,21 @@ namespace ts {
}
}
export function getTsConfigPropArrayElementValue(tsConfigSourceFile: TsConfigSourceFile, propKey: string, elementValue: string): StringLiteral {
const jsonObjectLiteral = getTsConfigObjectLiteralExpression(tsConfigSourceFile);
if (jsonObjectLiteral) {
for (const property of getPropertyAssignment(jsonObjectLiteral, propKey)) {
if (isArrayLiteralExpression(property.initializer)) {
for (const element of property.initializer.elements) {
if (isStringLiteral(element) && element.text === elementValue) {
return element;
}
}
}
}
}
}
export function getContainingFunction(node: Node): SignatureDeclaration {
return findAncestor(node.parent, isFunctionLike);
}
@ -1726,8 +1741,10 @@ namespace ts {
return (node.parent as ExternalModuleReference).parent as AnyValidImportOrReExport;
case SyntaxKind.CallExpression:
return node.parent as AnyValidImportOrReExport;
case SyntaxKind.LiteralType:
return cast(node.parent.parent, isImportTypeNode) as ImportTypeNode & { argument: LiteralType };
default:
return Debug.fail(Debug.showSyntaxKind(node));
return Debug.fail(Debug.showSyntaxKind(node.parent));
}
}
@ -1832,10 +1849,8 @@ namespace ts {
function getJSDocCommentsAndTagsWorker(node: Node): void {
const parent = node.parent;
if (parent &&
(parent.kind === SyntaxKind.PropertyAssignment ||
parent.kind === SyntaxKind.PropertyDeclaration ||
getNestedModuleDeclaration(parent))) {
if (!parent) return;
if (parent.kind === SyntaxKind.PropertyAssignment || parent.kind === SyntaxKind.PropertyDeclaration || getNestedModuleDeclaration(parent)) {
getJSDocCommentsAndTagsWorker(parent);
}
// Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement.
@ -1844,16 +1859,18 @@ namespace ts {
// * @returns {number}
// */
// var x = function(name) { return name.length; }
if (parent && parent.parent &&
if (parent.parent &&
(getSingleVariableOfVariableStatement(parent.parent) === node || getSourceOfAssignment(parent.parent))) {
getJSDocCommentsAndTagsWorker(parent.parent);
}
if (parent && parent.parent && parent.parent.parent &&
(getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node || getSourceOfDefaultedAssignment(parent.parent.parent))) {
if (parent.parent && parent.parent.parent &&
(getSingleVariableOfVariableStatement(parent.parent.parent) ||
getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node ||
getSourceOfDefaultedAssignment(parent.parent.parent))) {
getJSDocCommentsAndTagsWorker(parent.parent.parent);
}
if (isBinaryExpression(node) && getSpecialPropertyAssignmentKind(node) !== SpecialPropertyAssignmentKind.None ||
parent && isBinaryExpression(parent) && getSpecialPropertyAssignmentKind(parent) !== SpecialPropertyAssignmentKind.None ||
isBinaryExpression(parent) && getSpecialPropertyAssignmentKind(parent) !== SpecialPropertyAssignmentKind.None ||
node.kind === SyntaxKind.PropertyAccessExpression && node.parent && node.parent.kind === SyntaxKind.ExpressionStatement) {
getJSDocCommentsAndTagsWorker(parent);
}
@ -1902,6 +1919,15 @@ namespace ts {
}
export function getJSDocHost(node: JSDocTag): HasJSDoc {
while (node.parent.kind === SyntaxKind.JSDocTypeLiteral) {
if (node.parent.parent.kind === SyntaxKind.JSDocTypedefTag) {
node = node.parent.parent as JSDocTypedefTag;
}
else {
// node.parent.parent is a type expression, child of a parameter type
node = node.parent.parent.parent as JSDocParameterTag;
}
}
Debug.assert(node.parent!.kind === SyntaxKind.JSDocComment);
return node.parent!.parent!;
}
@ -2151,11 +2177,13 @@ namespace ts {
node.kind === SyntaxKind.NamespaceImport ||
node.kind === SyntaxKind.ImportSpecifier ||
node.kind === SyntaxKind.ExportSpecifier ||
node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node);
node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node) ||
isBinaryExpression(node) && getSpecialPropertyAssignmentKind(node) === SpecialPropertyAssignmentKind.ModuleExports;
}
export function exportAssignmentIsAlias(node: ExportAssignment): boolean {
return isEntityNameExpression(node.expression);
export function exportAssignmentIsAlias(node: ExportAssignment | BinaryExpression): boolean {
const e = isExportAssignment(node) ? node.expression : node.right;
return isEntityNameExpression(e) || isClassExpression(e);
}
export function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration | InterfaceDeclaration) {
@ -2947,11 +2975,7 @@ namespace ts {
}
export function getFirstConstructorWithBody(node: ClassLikeDeclaration): ConstructorDeclaration {
return forEach(node.members, member => {
if (member.kind === SyntaxKind.Constructor && nodeIsPresent((<ConstructorDeclaration>member).body)) {
return <ConstructorDeclaration>member;
}
});
return find(node.members, (member): member is ConstructorDeclaration => isConstructorDeclaration(member) && nodeIsPresent(member.body));
}
function getSetAccessorValueParameter(accessor: SetAccessorDeclaration): ParameterDeclaration | undefined {
@ -3053,6 +3077,10 @@ namespace ts {
return (node as HasType).type || (isInJavaScriptFile(node) ? getJSDocType(node) : undefined);
}
export function getTypeAnnotationNode(node: Node): TypeNode | undefined {
return (node as HasType).type;
}
/**
* Gets the effective return type annotation of a signature. If the node was parsed in a
* JavaScript file, gets the return type annotation from JSDoc.
@ -3065,11 +3093,11 @@ namespace ts {
* Gets the effective type parameters. If the node was parsed in a
* JavaScript file, gets the type parameters from the `@template` tag from JSDoc.
*/
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration> | undefined {
export function getEffectiveTypeParameterDeclarations(node: DeclarationWithTypeParameters) {
return node.typeParameters || (isInJavaScriptFile(node) ? getJSDocTypeParameterDeclarations(node) : undefined);
}
export function getJSDocTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray<TypeParameterDeclaration> {
export function getJSDocTypeParameterDeclarations(node: DeclarationWithTypeParameters) {
const templateTag = getJSDocTemplateTag(node);
return templateTag && templateTag.typeParameters;
}
@ -4034,12 +4062,14 @@ namespace ts {
}
/** Add a value to a set, and return true if it wasn't already present. */
export function addToSeen(seen: Map<true>, key: string | number): boolean {
export function addToSeen(seen: Map<true>, key: string | number): boolean;
export function addToSeen<T>(seen: Map<T>, key: string | number, value: T): boolean;
export function addToSeen<T>(seen: Map<T>, key: string | number, value: T = true as any): boolean {
key = String(key);
if (seen.has(key)) {
return false;
}
seen.set(key, true);
seen.set(key, value);
return true;
}
@ -4287,8 +4317,9 @@ namespace ts {
}
}
export function isParameterPropertyDeclaration(node: Node): node is ParameterDeclaration {
return hasModifier(node, ModifierFlags.ParameterPropertyModifier) && node.parent.kind === SyntaxKind.Constructor && isClassLike(node.parent.parent);
export type ParameterPropertyDeclaration = ParameterDeclaration & { parent: ConstructorDeclaration, name: Identifier };
export function isParameterPropertyDeclaration(node: Node): node is ParameterPropertyDeclaration {
return hasModifier(node, ModifierFlags.ParameterPropertyModifier) && node.parent.kind === SyntaxKind.Constructor;
}
export function isEmptyBindingPattern(node: BindingName): node is BindingPattern {
@ -4937,6 +4968,10 @@ namespace ts {
return node.kind === SyntaxKind.LiteralType;
}
export function isImportTypeNode(node: Node): node is ImportTypeNode {
return node.kind === SyntaxKind.ImportType;
}
// Binding patterns
export function isObjectBindingPattern(node: Node): node is ObjectBindingPattern {
@ -5617,8 +5652,7 @@ namespace ts {
|| kind === SyntaxKind.GetAccessor
|| kind === SyntaxKind.SetAccessor
|| kind === SyntaxKind.IndexSignature
|| kind === SyntaxKind.SemicolonClassElement
|| kind === SyntaxKind.MissingDeclaration;
|| kind === SyntaxKind.SemicolonClassElement;
}
export function isClassLike(node: Node): node is ClassLikeDeclaration {
@ -5649,8 +5683,7 @@ namespace ts {
|| kind === SyntaxKind.CallSignature
|| kind === SyntaxKind.PropertySignature
|| kind === SyntaxKind.MethodSignature
|| kind === SyntaxKind.IndexSignature
|| kind === SyntaxKind.MissingDeclaration;
|| kind === SyntaxKind.IndexSignature;
}
export function isClassOrTypeElement(node: Node): node is ClassElement | TypeElement {
@ -5664,8 +5697,7 @@ namespace ts {
|| kind === SyntaxKind.SpreadAssignment
|| kind === SyntaxKind.MethodDeclaration
|| kind === SyntaxKind.GetAccessor
|| kind === SyntaxKind.SetAccessor
|| kind === SyntaxKind.MissingDeclaration;
|| kind === SyntaxKind.SetAccessor;
}
// Type

View file

@ -478,6 +478,7 @@ namespace ts {
case SyntaxKind.TaggedTemplateExpression:
return updateTaggedTemplate(<TaggedTemplateExpression>node,
visitNode((<TaggedTemplateExpression>node).tag, visitor, isExpression),
visitNodes((<TaggedTemplateExpression>node).typeArguments, visitor, isExpression),
visitNode((<TaggedTemplateExpression>node).template, visitor, isTemplateLiteral));
case SyntaxKind.TypeAssertionExpression:

View file

@ -29,19 +29,36 @@ namespace ts {
/** @internal */
export const nonClearingMessageCodes: number[] = [
Diagnostics.Compilation_complete_Watching_for_file_changes.code,
Diagnostics.Found_1_error.code,
Diagnostics.Found_0_errors.code
Diagnostics.Found_1_error_Watching_for_file_changes.code,
Diagnostics.Found_0_errors_Watching_for_file_changes.code
];
function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic, options: CompilerOptions) {
/**
* @returns Whether the screen was cleared.
*/
function clearScreenIfNotWatchingForFileChanges(system: System, diagnostic: Diagnostic, options: CompilerOptions): boolean {
if (system.clearScreen &&
!options.preserveWatchOutput &&
!options.extendedDiagnostics &&
!options.diagnostics &&
!contains(nonClearingMessageCodes, diagnostic.code)) {
system.clearScreen();
return true;
}
return false;
}
/** @internal */
export const screenStartingMessageCodes: number[] = [
Diagnostics.Starting_compilation_in_watch_mode.code,
Diagnostics.File_change_detected_Starting_incremental_compilation.code,
];
function getPlainDiagnosticFollowingNewLines(diagnostic: Diagnostic, newLine: string): string {
return contains(screenStartingMessageCodes, diagnostic.code)
? newLine + newLine
: newLine;
}
/**
@ -52,13 +69,19 @@ namespace ts {
(diagnostic, newLine, options) => {
clearScreenIfNotWatchingForFileChanges(system, diagnostic, options);
let output = `[${formatColorAndReset(new Date().toLocaleTimeString(), ForegroundColorEscapeSequences.Grey)}] `;
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`;
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine}`;
system.write(output);
} :
(diagnostic, newLine, options) => {
clearScreenIfNotWatchingForFileChanges(system, diagnostic, options);
let output = new Date().toLocaleTimeString() + " - ";
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${newLine + newLine + newLine}`;
let output = "";
if (!clearScreenIfNotWatchingForFileChanges(system, diagnostic, options)) {
output += newLine;
}
output += `${new Date().toLocaleTimeString()} - `;
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${getPlainDiagnosticFollowingNewLines(diagnostic, newLine)}`;
system.write(output);
};
}
@ -231,10 +254,10 @@ namespace ts {
const reportSummary = (errorCount: number) => {
if (errorCount === 1) {
onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_1_error, errorCount), newLine, compilerOptions);
onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_1_error_Watching_for_file_changes, errorCount), newLine, compilerOptions);
}
else {
onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_0_errors, errorCount, errorCount), newLine, compilerOptions);
onWatchStatusChange(createCompilerDiagnostic(Diagnostics.Found_0_errors_Watching_for_file_changes, errorCount, errorCount), newLine, compilerOptions);
}
};
@ -602,9 +625,19 @@ namespace ts {
builderProgram = createProgram(/*rootNames*/ undefined, /*options*/ undefined, compilerHost, builderProgram, configFileParsingDiagnostics);
hasChangedConfigFileParsingErrors = false;
}
return builderProgram;
}
else {
createNewProgram(program, hasInvalidatedResolution);
}
if (host.afterProgramCreate) {
host.afterProgramCreate(builderProgram);
}
return builderProgram;
}
function createNewProgram(program: Program, hasInvalidatedResolution: HasInvalidatedResolution) {
// Compile the program
if (watchLogLevel !== WatchLogLevel.None) {
writeLog("CreatingProgramWith::");
@ -640,12 +673,6 @@ namespace ts {
}
missingFilePathsRequestedForRelease = undefined;
}
if (host.afterProgramCreate) {
host.afterProgramCreate(builderProgram);
}
reportWatchDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes);
return builderProgram;
}
function updateRootFileNames(files: string[]) {

View file

@ -66,7 +66,7 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
if (fs.existsSync(path.join(cwd, "node_modules"))) {
require("del").sync(path.join(cwd, "node_modules"), { force: true });
}
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
const install = cp.spawnSync(`npm`, ["i", "--ignore-scripts"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed: ${install.stderr.toString()}`);
}
const args = [path.join(__dirname, "tsc.js")];

View file

@ -276,14 +276,10 @@ namespace FourSlash {
if (configFileName) {
const baseDir = ts.normalizePath(ts.getDirectoryPath(configFileName));
const host = new Utils.MockParseConfigHost(baseDir, /*ignoreCase*/ false, this.inputFiles);
const configJsonObj = ts.parseConfigFileTextToJson(configFileName, this.inputFiles.get(configFileName));
assert.isTrue(configJsonObj.config !== undefined);
compilationOptions = ts.parseJsonConfigFileContent(configJsonObj.config, host, baseDir, compilationOptions, configFileName).options;
const jsonSourceFile = ts.parseJsonText(configFileName, this.inputFiles.get(configFileName));
compilationOptions = ts.parseJsonSourceFileConfigFileContent(jsonSourceFile, host, baseDir, compilationOptions, configFileName).options;
}
if (compilationOptions.typeRoots) {
compilationOptions.typeRoots = compilationOptions.typeRoots.map(p => ts.getNormalizedAbsolutePath(p, this.basePath));
}
@ -842,6 +838,7 @@ namespace FourSlash {
const actualCompletions = this.getCompletionListAtCaret(options);
if (!actualCompletions) {
if (expected === undefined) return;
this.raiseError(`No completions at position '${this.currentCaretPosition}'.`);
}
@ -2103,14 +2100,11 @@ Actual: ${stringify(fullActual)}`);
this.raiseError("verifyRangesInImplementationList failed - expected to find at least one implementation location but got 0");
}
for (let i = 0; i < implementations.length; i++) {
for (let j = 0; j < implementations.length; j++) {
if (i !== j && implementationsAreEqual(implementations[i], implementations[j])) {
const { textSpan, fileName } = implementations[i];
const end = textSpan.start + textSpan.length;
this.raiseError(`Duplicate implementations returned for range (${textSpan.start}, ${end}) in ${fileName}`);
}
}
const duplicate = findDuplicatedElement(implementations, implementationsAreEqual);
if (duplicate) {
const { textSpan, fileName } = duplicate;
const end = textSpan.start + textSpan.length;
this.raiseError(`Duplicate implementations returned for range (${textSpan.start}, ${end}) in ${fileName}`);
}
const ranges = this.getRanges();
@ -2425,14 +2419,7 @@ Actual: ${stringify(fullActual)}`);
public applyCodeActionFromCompletion(markerName: string, options: FourSlashInterface.VerifyCompletionActionOptions) {
this.goToMarker(markerName);
const actualCompletion = this.getCompletionListAtCaret({ ...ts.defaultPreferences, includeCompletionsForModuleExports: true }).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, options.preferences);
const details = this.getCompletionEntryDetails(options.name, options.source, options.preferences);
if (details.codeActions.length !== 1) {
this.raiseError(`Expected one code action, got ${details.codeActions.length}`);
}
@ -2910,6 +2897,7 @@ Actual: ${stringify(fullActual)}`);
}
private verifyDocumentHighlights(expectedRanges: Range[], fileNames: ReadonlyArray<string> = [this.activeFile.fileName]) {
fileNames = ts.map(fileNames, ts.normalizePath);
const documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNames) || [];
for (const dh of documentHighlights) {
@ -2919,7 +2907,7 @@ Actual: ${stringify(fullActual)}`);
}
for (const fileName of fileNames) {
const expectedRangesInFile = expectedRanges.filter(r => r.fileName === fileName);
const expectedRangesInFile = expectedRanges.filter(r => ts.normalizePath(r.fileName) === fileName);
const highlights = ts.find(documentHighlights, dh => dh.fileName === fileName);
const spansInFile = highlights ? highlights.highlightSpans.sort((s1, s2) => s1.textSpan.start - s2.textSpan.start) : [];
@ -3219,14 +3207,14 @@ Actual: ${stringify(fullActual)}`);
}
}
else if (ts.isString(indexOrName)) {
let name = indexOrName;
let name = ts.normalizePath(indexOrName);
// names are stored in the compiler with this relative path, this allows people to use goTo.file on just the fileName
name = name.indexOf("/") === -1 ? (this.basePath + "/" + name) : name;
const availableNames: string[] = [];
const result = ts.forEach(this.testData.files, file => {
const fn = file.fileName;
const fn = ts.normalizePath(file.fileName);
if (fn) {
if (fn === name) {
return file;
@ -3281,6 +3269,15 @@ Actual: ${stringify(fullActual)}`);
private static textSpansEqual(a: ts.TextSpan, b: ts.TextSpan) {
return a && b && a.start === b.start && a.length === b.length;
}
public getEditsForFileRename(options: FourSlashInterface.GetEditsForFileRenameOptions): void {
const changes = this.languageService.getEditsForFileRename(options.oldPath, options.newPath, this.formatCodeSettings);
this.applyChanges(changes);
for (const fileName in options.newFileContents) {
this.openFile(fileName);
this.verifyCurrentFileContent(options.newFileContents[fileName]);
}
}
}
export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string) {
@ -3755,6 +3752,16 @@ ${code}
function stripWhitespace(s: string): string {
return s.replace(/\s/g, "");
}
function findDuplicatedElement<T>(a: ReadonlyArray<T>, equal: (a: T, b: T) => boolean): T {
for (let i = 0; i < a.length; i++) {
for (let j = i + 1; j < a.length; j++) {
if (equal(a[i], a[j])) {
return a[i];
}
}
}
}
}
namespace FourSlashInterface {
@ -4362,6 +4369,10 @@ namespace FourSlashInterface {
public allRangesAppearInImplementationList(markerName: string) {
this.state.verifyRangesInImplementationList(markerName);
}
public getEditsForFileRename(options: GetEditsForFileRenameOptions) {
this.state.getEditsForFileRename(options);
}
}
export class Edit {
@ -4645,10 +4656,12 @@ namespace FourSlashInterface {
export type ExpectedCompletionEntry = string | { name: string, insertText?: string, replacementSpan?: FourSlash.Range };
export interface CompletionsAtOptions extends Partial<ts.UserPreferences> {
triggerCharacter?: string;
isNewIdentifierLocation?: boolean;
}
export interface VerifyCompletionListContainsOptions extends ts.UserPreferences {
triggerCharacter?: string;
sourceDisplay: string;
isRecommended?: true;
insertText?: string;
@ -4702,4 +4715,10 @@ namespace FourSlashInterface {
range?: FourSlash.Range;
code: number;
}
export interface GetEditsForFileRenameOptions {
readonly oldPath: string;
readonly newPath: string;
readonly newFileContents: { readonly [fileName: string]: string };
}
}

View file

@ -304,14 +304,13 @@ namespace Utils {
o.containsParseError = true;
}
ts.forEach(Object.getOwnPropertyNames(n), propertyName => {
for (const propertyName of Object.getOwnPropertyNames(n) as ReadonlyArray<keyof ts.SourceFile | keyof ts.Identifier>) {
switch (propertyName) {
case "parent":
case "symbol":
case "locals":
case "localSymbol":
case "kind":
case "semanticDiagnostics":
case "id":
case "nodeCount":
case "symbolCount":
@ -334,7 +333,6 @@ namespace Utils {
}
break;
case "referenceDiagnostics":
case "parseDiagnostics":
o[propertyName] = convertDiagnostics((<any>n)[propertyName]);
break;
@ -355,9 +353,7 @@ namespace Utils {
default:
o[propertyName] = (<any>n)[propertyName];
}
return undefined;
});
}
return o;
}

View file

@ -528,6 +528,9 @@ namespace Harness.LanguageService {
organizeImports(_scope: ts.OrganizeImportsScope, _formatOptions: ts.FormatCodeSettings): ReadonlyArray<ts.FileTextChanges> {
throw new Error("Not supported on the shim.");
}
getEditsForFileRename(): ReadonlyArray<ts.FileTextChanges> {
throw new Error("Not supported on the shim.");
}
getEmitOutput(fileName: string): ts.EmitOutput {
return unwrapJSONCallResult(this.shim.getEmitOutput(fileName));
}

View file

@ -70,6 +70,7 @@
"../services/navigateTo.ts",
"../services/navigationBar.ts",
"../services/organizeImports.ts",
"../services/getEditsForFileRename.ts",
"../services/outliningElementsCollector.ts",
"../services/patternMatcher.ts",
"../services/preProcess.ts",
@ -112,10 +113,8 @@
"../services/codefixes/fixInvalidImportSyntax.ts",
"../services/codefixes/fixStrictClassInitialization.ts",
"../services/codefixes/useDefaultImport.ts",
"../services/codefixes/fixes.ts",
"../services/refactors/extractSymbol.ts",
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
"../services/refactors/refactors.ts",
"../services/sourcemaps.ts",
"../services/services.ts",
"../services/breakpoints.ts",

View file

@ -0,0 +1,95 @@
/// <reference path="..\harness.ts" />
namespace ts {
describe("cancellableLanguageServiceOperations", () => {
const file = `
function foo(): void;
function foo<T>(x: T): T;
function foo<T>(x?: T): T | void {}
foo(f);
`;
it("can cancel signature help mid-request", () => {
verifyOperationCancelledAfter(file, 4, service => // Two calls are top-level in services, one is the root type, and the second should be for the parameter type
service.getSignatureHelpItems("file.ts", file.lastIndexOf("f")),
r => assert.exists(r.items[0])
);
});
it("can cancel find all references mid-request", () => {
verifyOperationCancelledAfter(file, 3, service => // Two calls are top-level in services, one is the root type
service.findReferences("file.ts", file.lastIndexOf("o")),
r => assert.exists(r[0].definition)
);
});
it("can cancel quick info mid-request", () => {
verifyOperationCancelledAfter(file, 1, service => // The LS doesn't do any top-level checks on the token for quickinfo, so the first check is within the checker
service.getQuickInfoAtPosition("file.ts", file.lastIndexOf("o")),
r => assert.exists(r.displayParts)
);
});
it("can cancel completion entry details mid-request", () => {
const options: FormatCodeSettings = {
indentSize: 4,
tabSize: 4,
newLineCharacter: "\n",
convertTabsToSpaces: true,
indentStyle: 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: false,
placeOpenBraceOnNewLineForControlBlocks: false,
};
verifyOperationCancelledAfter(file, 1, service => // The LS doesn't do any top-level checks on the token for completion entry details, so the first check is within the checker
service.getCompletionEntryDetails("file.ts", file.lastIndexOf("f"), "foo", options, /*content*/ undefined, {}),
r => assert.exists(r.displayParts)
);
});
});
function verifyOperationCancelledAfter<T>(content: string, cancelAfter: number, operation: (service: LanguageService) => T, validator: (arg: T) => void) {
let checks = 0;
const token: HostCancellationToken = {
isCancellationRequested() {
checks++;
const result = checks >= cancelAfter;
if (result) {
checks = -Infinity; // Cancel just once, then disable cancellation, effectively
}
return result;
}
};
const adapter = new Harness.LanguageService.NativeLanguageServiceAdapter(token);
const host = adapter.getHost();
host.addScript("file.ts", content, /*isRootFile*/ true);
const service = adapter.getLanguageService();
assertCancelled(() => operation(service));
validator(operation(service));
}
/**
* We don't just use `assert.throws` because it doesn't validate instances for thrown objects which do not inherit from `Error`
*/
function assertCancelled(cb: () => void) {
let caught: any;
try {
cb();
}
catch (e) {
caught = e;
}
assert.exists(caught, "Expected operation to be cancelled, but was not");
assert.instanceOf(caught, OperationCanceledException);
}
}

View file

@ -59,6 +59,32 @@ describe("PreProcessFile:", () => {
});
}),
it("Do not return reference path of non-imports", () => {
test("Quill.import('delta');",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
importedFiles: <ts.FileReference[]>[],
typeReferenceDirectives: [],
ambientExternalModules: undefined,
isLibFile: false
});
}),
it("Do not return reference path of nested non-imports", () => {
test("a.b.import('c');",
/*readImportFile*/ true,
/*detectJavaScriptImports*/ false,
{
referencedFiles: <ts.FileReference[]>[],
importedFiles: <ts.FileReference[]>[],
typeReferenceDirectives: [],
ambientExternalModules: undefined,
isLibFile: false
});
}),
it("Correctly return imported files", () => {
test("import i1 = require(\"r1.ts\"); import i2 =require(\"r2.ts\"); import i3= require(\"r3.ts\"); import i4=require(\"r4.ts\"); import i5 = require (\"r5.ts\");",
/*readImportFile*/ true,

View file

@ -263,6 +263,8 @@ namespace ts.server {
CommandNames.GetEditsForRefactorFull,
CommandNames.OrganizeImports,
CommandNames.OrganizeImportsFull,
CommandNames.GetEditsForFileRename,
CommandNames.GetEditsForFileRenameFull,
];
it("should not throw when commands are executed with invalid arguments", () => {

View file

@ -124,14 +124,17 @@ namespace ts.tscWatch {
}
function getWatchDiagnosticWithoutDate(diagnostic: Diagnostic) {
return ` - ${flattenDiagnosticMessageText(diagnostic.messageText, host.newLine)}${host.newLine + host.newLine + host.newLine}`;
const newLines = contains(screenStartingMessageCodes, diagnostic.code)
? `${host.newLine}${host.newLine}`
: host.newLine;
return ` - ${flattenDiagnosticMessageText(diagnostic.messageText, host.newLine)}${newLines}`;
}
}
function createErrorsFoundCompilerDiagnostic(errors: ReadonlyArray<Diagnostic>) {
return errors.length === 1
? createCompilerDiagnostic(Diagnostics.Found_1_error)
: createCompilerDiagnostic(Diagnostics.Found_0_errors, errors.length);
? createCompilerDiagnostic(Diagnostics.Found_1_error_Watching_for_file_changes)
: createCompilerDiagnostic(Diagnostics.Found_0_errors_Watching_for_file_changes, errors.length);
}
function checkOutputErrorsInitial(host: WatchedSystem, errors: ReadonlyArray<Diagnostic>, disableConsoleClears?: boolean, logsBeforeErrors?: string[]) {
@ -142,8 +145,7 @@ namespace ts.tscWatch {
logsBeforeErrors,
errors,
disableConsoleClears,
createErrorsFoundCompilerDiagnostic(errors),
createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes));
createErrorsFoundCompilerDiagnostic(errors));
}
function checkOutputErrorsIncremental(host: WatchedSystem, errors: ReadonlyArray<Diagnostic>, disableConsoleClears?: boolean, logsBeforeWatchDiagnostic?: string[], logsBeforeErrors?: string[]) {
@ -154,8 +156,7 @@ namespace ts.tscWatch {
logsBeforeErrors,
errors,
disableConsoleClears,
createErrorsFoundCompilerDiagnostic(errors),
createCompilerDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes));
createErrorsFoundCompilerDiagnostic(errors));
}
function checkOutputErrorsIncrementalWithExit(host: WatchedSystem, errors: ReadonlyArray<Diagnostic>, expectedExitCode: ExitStatus, disableConsoleClears?: boolean, logsBeforeWatchDiagnostic?: string[], logsBeforeErrors?: string[]) {
@ -417,6 +418,28 @@ namespace ts.tscWatch {
checkProgramRootFiles(watch(), [commonFile1.path]);
});
it("works correctly when config file is changed but its content havent", () => {
const configFile: FileOrFolder = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {},
"files": ["${commonFile1.path}", "${commonFile2.path}"]
}`
};
const files = [libFile, commonFile1, commonFile2, configFile];
const host = createWatchedSystem(files);
const watch = createWatchOfConfigFile(configFile.path, host);
checkProgramActualFiles(watch(), [libFile.path, commonFile1.path, commonFile2.path]);
checkOutputErrorsInitial(host, emptyArray);
host.modifyFile(configFile.path, configFile.content);
host.checkTimeoutQueueLengthAndRun(1); // reload the configured project
checkProgramActualFiles(watch(), [libFile.path, commonFile1.path, commonFile2.path]);
checkOutputErrorsIncremental(host, emptyArray);
});
it("files explicitly excluded in config file", () => {
const configFile: FileOrFolder = {
path: "/a/b/tsconfig.json",

View file

@ -13,7 +13,9 @@ namespace ts.projectSystem {
export import checkArray = TestFSWithWatch.checkArray;
export import libFile = TestFSWithWatch.libFile;
export import checkWatchedFiles = TestFSWithWatch.checkWatchedFiles;
import checkWatchedDirectories = TestFSWithWatch.checkWatchedDirectories;
export import checkWatchedFilesDetailed = TestFSWithWatch.checkWatchedFilesDetailed;
export import checkWatchedDirectories = TestFSWithWatch.checkWatchedDirectories;
export import checkWatchedDirectoriesDetailed = TestFSWithWatch.checkWatchedDirectoriesDetailed;
import safeList = TestFSWithWatch.safeList;
export const customTypesMap = {
@ -478,6 +480,10 @@ namespace ts.projectSystem {
checkNthEvent(session, server.toEvent(eventName, diagnostics), 0, isMostRecent);
}
function createDiagnostic(start: protocol.Location, end: protocol.Location, message: DiagnosticMessage, args: ReadonlyArray<string> = [], category = diagnosticCategoryName(message), reportsUnnecessary?: {}): protocol.Diagnostic {
return { start, end, text: formatStringFromArgs(message.message, args), code: message.code, category, reportsUnnecessary, source: undefined };
}
function checkCompleteEvent(session: TestSession, numberOfCurrentEvents: number, expectedSequenceId: number, isMostRecent = true): void {
checkNthEvent(session, server.toEvent("requestCompleted", { request_seq: expectedSequenceId }), numberOfCurrentEvents - 1, isMostRecent);
}
@ -494,7 +500,7 @@ namespace ts.projectSystem {
function checkNthEvent(session: TestSession, expectedEvent: protocol.Event, index: number, isMostRecent: boolean) {
const events = session.events;
assert.deepEqual(events[index], expectedEvent);
assert.deepEqual(events[index], expectedEvent, `Expected ${JSON.stringify(expectedEvent)} at ${index} in ${JSON.stringify(events)}`);
const outputs = session.host.getOutput();
assert.equal(outputs[index], server.formatMessage(expectedEvent, nullLogger, Utils.byteLength, session.host.newLine));
@ -3331,6 +3337,89 @@ namespace ts.projectSystem {
checkCompleteEvent(session, 1, expectedSequenceId);
session.clearMessages();
});
it("Reports errors correctly when file referenced by inferred project root, is opened right after closing the root file", () => {
const projectRoot = "/user/username/projects/myproject";
const app: FileOrFolder = {
path: `${projectRoot}/src/client/app.js`,
content: ""
};
const serverUtilities: FileOrFolder = {
path: `${projectRoot}/src/server/utilities.js`,
content: `function getHostName() { return "hello"; } export { getHostName };`
};
const backendTest: FileOrFolder = {
path: `${projectRoot}/test/backend/index.js`,
content: `import { getHostName } from '../../src/server/utilities';export default getHostName;`
};
const files = [libFile, app, serverUtilities, backendTest];
const host = createServerHost(files);
const session = createSession(host, { useInferredProjectPerProjectRoot: true, canUseEvents: true });
session.executeCommandSeq<protocol.OpenRequest>({
command: protocol.CommandTypes.Open,
arguments: {
file: app.path,
projectRootPath: projectRoot
}
});
const service = session.getProjectService();
checkNumberOfProjects(service, { inferredProjects: 1 });
const project = service.inferredProjects[0];
checkProjectActualFiles(project, [libFile.path, app.path]);
session.executeCommandSeq<protocol.OpenRequest>({
command: protocol.CommandTypes.Open,
arguments: {
file: backendTest.path,
projectRootPath: projectRoot
}
});
checkNumberOfProjects(service, { inferredProjects: 1 });
checkProjectActualFiles(project, files.map(f => f.path));
checkErrors([backendTest.path, app.path]);
session.executeCommandSeq<protocol.CloseRequest>({
command: protocol.CommandTypes.Close,
arguments: {
file: backendTest.path
}
});
session.executeCommandSeq<protocol.OpenRequest>({
command: protocol.CommandTypes.Open,
arguments: {
file: serverUtilities.path,
projectRootPath: projectRoot
}
});
checkErrors([serverUtilities.path, app.path]);
function checkErrors(openFiles: [string, string]) {
const expectedSequenceId = session.getNextSeq();
session.executeCommandSeq<protocol.GeterrRequest>({
command: protocol.CommandTypes.Geterr,
arguments: {
delay: 0,
files: openFiles
}
});
for (const openFile of openFiles) {
session.clearMessages();
host.checkTimeoutQueueLength(3);
host.runQueuedTimeoutCallbacks(host.getNextTimeoutId() - 1);
checkErrorMessage(session, "syntaxDiag", { file: openFile, diagnostics: [] });
session.clearMessages();
host.runQueuedImmediateCallbacks();
checkErrorMessage(session, "semanticDiag", { file: openFile, diagnostics: [] });
session.clearMessages();
host.runQueuedImmediateCallbacks(1);
checkErrorMessage(session, "suggestionDiag", { file: openFile, diagnostics: [] });
}
checkCompleteEvent(session, 2, expectedSequenceId);
session.clearMessages();
}
});
});
describe("tsserverProjectSystem autoDiscovery", () => {
@ -4291,10 +4380,6 @@ namespace ts.projectSystem {
session.clearMessages();
});
function createDiagnostic(start: protocol.Location, end: protocol.Location, message: DiagnosticMessage, args: ReadonlyArray<string> = [], category = diagnosticCategoryName(message), reportsUnnecessary?: {}): protocol.Diagnostic {
return { start, end, text: formatStringFromArgs(message.message, args), code: message.code, category, reportsUnnecessary, source: undefined };
}
});
describe("tsserverProjectSystem Configure file diagnostics events", () => {
@ -7294,7 +7379,6 @@ namespace ts.projectSystem {
const host = createServerHost(files);
const session = createSession(host);
const projectService = session.getProjectService();
debugger;
session.executeCommandSeq<protocol.OpenRequest>({
command: protocol.CommandTypes.Open,
arguments: {
@ -7822,8 +7906,8 @@ namespace ts.projectSystem {
checkWatchedDirectories(host, emptyArray, /*recursive*/ true);
TestFSWithWatch.checkMultiMapKeyCount("watchedFiles", host.watchedFiles, expectedWatchedFiles);
TestFSWithWatch.checkMultiMapKeyCount("watchedDirectories", host.watchedDirectories, expectedWatchedDirectories);
checkWatchedFilesDetailed(host, expectedWatchedFiles);
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectories, /*recursive*/ false);
checkProjectActualFiles(project, fileNames);
}
}

View file

@ -141,7 +141,19 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { configuredProjects: 1 });
const p = configuredProjectAt(projectService, 0);
checkProjectActualFiles(p, [file1.path, tsconfig.path]);
checkWatchedFiles(host, [tsconfig.path, libFile.path, packageJson.path, "/a/b/bower_components", "/a/b/node_modules"]);
const expectedWatchedFiles = createMap<number>();
expectedWatchedFiles.set(tsconfig.path, 1); // tsserver
expectedWatchedFiles.set(libFile.path, 1); // tsserver
expectedWatchedFiles.set(packageJson.path, 1); // typing installer
checkWatchedFilesDetailed(host, expectedWatchedFiles);
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
const expectedWatchedDirectoriesRecursive = createMap<number>();
expectedWatchedDirectoriesRecursive.set("/a/b", 2); // TypingInstaller and wild card
expectedWatchedDirectoriesRecursive.set("/a/b/node_modules/@types", 1); // type root watch
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectoriesRecursive, /*recursive*/ true);
installer.installAll(/*expectedCount*/ 1);
@ -149,7 +161,9 @@ namespace ts.projectSystem {
host.checkTimeoutQueueLengthAndRun(2);
checkProjectActualFiles(p, [file1.path, jquery.path, tsconfig.path]);
// should not watch jquery
checkWatchedFiles(host, [tsconfig.path, libFile.path, packageJson.path, "/a/b/bower_components", "/a/b/node_modules"]);
checkWatchedFilesDetailed(host, expectedWatchedFiles);
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
checkWatchedDirectoriesDetailed(host, expectedWatchedDirectoriesRecursive, /*recursive*/ true);
});
it("inferred project (typings installed)", () => {
@ -827,7 +841,17 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { configuredProjects: 1 });
const p = configuredProjectAt(projectService, 0);
checkProjectActualFiles(p, [app.path, jsconfig.path]);
checkWatchedFiles(host, [jsconfig.path, "/bower_components", "/node_modules", libFile.path]);
const watchedFilesExpected = createMap<number>();
watchedFilesExpected.set(jsconfig.path, 1); // project files
watchedFilesExpected.set(libFile.path, 1); // project files
checkWatchedFilesDetailed(host, watchedFilesExpected);
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
const watchedRecursiveDirectoriesExpected = createMap<number>();
watchedRecursiveDirectoriesExpected.set("/", 2); // wild card + type installer
checkWatchedDirectoriesDetailed(host, watchedRecursiveDirectoriesExpected, /*recursive*/ true);
installer.installAll(/*expectedCount*/ 1);
@ -999,14 +1023,14 @@ namespace ts.projectSystem {
proj.updateGraph();
assert.deepEqual(
proj.getCachedUnresolvedImportsPerFile_TestOnly().get(<Path>f1.path),
proj.cachedUnresolvedImportsPerFile.get(<Path>f1.path),
["foo", "foo", "foo", "@bar/router", "@bar/common", "@bar/common"]
);
installer.installAll(/*expectedCount*/ 1);
});
it("should recompute resolutions after typings are installed", () => {
it("cached unresolved typings are not recomputed if program structure did not change", () => {
const host = createServerHost([]);
const session = createSession(host);
const f = {
@ -1029,7 +1053,7 @@ namespace ts.projectSystem {
const projectService = session.getProjectService();
checkNumberOfProjects(projectService, { inferredProjects: 1 });
const proj = projectService.inferredProjects[0];
const version1 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion();
const version1 = proj.lastCachedUnresolvedImportsList;
// make a change that should not affect the structure of the program
const changeRequest: server.protocol.ChangeRequest = {
@ -1047,8 +1071,8 @@ namespace ts.projectSystem {
};
session.executeCommand(changeRequest);
host.checkTimeoutQueueLengthAndRun(2); // This enqueues the updategraph and refresh inferred projects
const version2 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion();
assert.notEqual(version1, version2, "set of unresolved imports should change");
const version2 = proj.lastCachedUnresolvedImportsList;
assert.strictEqual(version1, version2, "set of unresolved imports should change");
});
it("expired cache entry (inferred project, should install typings)", () => {
@ -1621,4 +1645,75 @@ namespace ts.projectSystem {
assert.deepEqual(commands, expectedCommands, "commands");
});
});
describe("recomputing resolutions of unresolved imports", () => {
const globalTypingsCacheLocation = "/tmp";
const appPath = "/a/b/app.js" as Path;
const foooPath = "/a/b/node_modules/fooo/index.d.ts";
function verifyResolvedModuleOfFooo(project: server.Project) {
const foooResolution = project.getLanguageService().getProgram().getSourceFileByPath(appPath).resolvedModules.get("fooo");
assert.equal(foooResolution.resolvedFileName, foooPath);
return foooResolution;
}
function verifyUnresolvedImportResolutions(appContents: string, typingNames: string[], typingFiles: FileOrFolder[]) {
const app: FileOrFolder = {
path: appPath,
content: `${appContents}import * as x from "fooo";`
};
const fooo: FileOrFolder = {
path: foooPath,
content: `export var x: string;`
};
const host = createServerHost([app, fooo]);
const installer = new (class extends Installer {
constructor() {
super(host, { globalTypingsCacheLocation, typesRegistry: createTypesRegistry("foo") });
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
executeCommand(this, host, typingNames, typingFiles, cb);
}
})();
const projectService = createProjectService(host, { typingsInstaller: installer });
projectService.openClientFile(app.path);
projectService.checkNumberOfProjects({ inferredProjects: 1 });
const proj = projectService.inferredProjects[0];
checkProjectActualFiles(proj, [app.path, fooo.path]);
const foooResolution1 = verifyResolvedModuleOfFooo(proj);
installer.installAll(/*expectedCount*/ 1);
host.checkTimeoutQueueLengthAndRun(2);
checkProjectActualFiles(proj, typingFiles.map(f => f.path).concat(app.path, fooo.path));
const foooResolution2 = verifyResolvedModuleOfFooo(proj);
assert.strictEqual(foooResolution1, foooResolution2);
}
it("correctly invalidate the resolutions with typing names", () => {
verifyUnresolvedImportResolutions('import * as a from "foo";', ["foo"], [{
path: `${globalTypingsCacheLocation}/node_modules/foo/index.d.ts`,
content: "export function a(): void;"
}]);
});
it("correctly invalidate the resolutions with typing names that are trimmed", () => {
const fooAA: FileOrFolder = {
path: `${globalTypingsCacheLocation}/node_modules/foo/a/a.d.ts`,
content: "export function a (): void;"
};
const fooAB: FileOrFolder = {
path: `${globalTypingsCacheLocation}/node_modules/foo/a/b.d.ts`,
content: "export function b (): void;"
};
const fooAC: FileOrFolder = {
path: `${globalTypingsCacheLocation}/node_modules/foo/a/c.d.ts`,
content: "export function c (): void;"
};
verifyUnresolvedImportResolutions(`
import * as a from "foo/a/a";
import * as b from "foo/a/b";
import * as c from "foo/a/c";
`, ["foo"], [fooAA, fooAB, fooAC]);
});
});
}

View file

@ -125,7 +125,7 @@ namespace Utils {
addFile(path: string, content?: Harness.LanguageService.ScriptInfo) {
const absolutePath = ts.normalizePath(ts.getNormalizedAbsolutePath(path, this.currentDirectory));
const fileName = ts.getBaseFileName(path);
const fileName = ts.getBaseFileName(absolutePath);
const directoryPath = ts.getDirectoryPath(absolutePath);
const directory = this.addDirectory(directoryPath);
return directory ? directory.addFile(fileName, content) : undefined;

View file

@ -179,10 +179,18 @@ interface Array<T> {}`
checkMapKeys("watchedFiles", host.watchedFiles, expectedFiles);
}
export function checkWatchedDirectories(host: TestServerHost, expectedDirectories: string[], recursive = false) {
export function checkWatchedFilesDetailed(host: TestServerHost, expectedFiles: Map<number>) {
checkMultiMapKeyCount("watchedFiles", host.watchedFiles, expectedFiles);
}
export function checkWatchedDirectories(host: TestServerHost, expectedDirectories: string[], recursive: boolean) {
checkMapKeys(`watchedDirectories${recursive ? " recursive" : ""}`, recursive ? host.watchedDirectoriesRecursive : host.watchedDirectories, expectedDirectories);
}
export function checkWatchedDirectoriesDetailed(host: TestServerHost, expectedDirectories: Map<number>, recursive: boolean) {
checkMultiMapKeyCount(`watchedDirectories${recursive ? " recursive" : ""}`, recursive ? host.watchedDirectoriesRecursive : host.watchedDirectories, expectedDirectories);
}
export function checkOutputContains(host: TestServerHost, expected: ReadonlyArray<string>) {
const mapExpected = arrayToSet(expected);
const mapSeen = createMap<true>();
@ -385,21 +393,7 @@ interface Array<T> {}`
if (isString(fileOrDirectory.content)) {
// Update file
if (currentEntry.content !== fileOrDirectory.content) {
if (options && options.invokeFileDeleteCreateAsPartInsteadOfChange) {
this.removeFileOrFolder(currentEntry, returnFalse);
this.ensureFileOrFolder(fileOrDirectory);
}
else {
currentEntry.content = fileOrDirectory.content;
currentEntry.modifiedTime = this.now();
this.fs.get(getDirectoryPath(currentEntry.path)).modifiedTime = this.now();
if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) {
this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath);
}
else {
this.invokeFileWatcher(currentEntry.fullPath, FileWatcherEventKind.Changed);
}
}
this.modifyFile(fileOrDirectory.path, fileOrDirectory.content, options);
}
}
else {
@ -438,6 +432,30 @@ interface Array<T> {}`
}
}
modifyFile(filePath: string, content: string, options?: Partial<ReloadWatchInvokeOptions>) {
const path = this.toFullPath(filePath);
const currentEntry = this.fs.get(path);
if (!currentEntry || !isFile(currentEntry)) {
throw new Error(`file not present: ${filePath}`);
}
if (options && options.invokeFileDeleteCreateAsPartInsteadOfChange) {
this.removeFileOrFolder(currentEntry, returnFalse);
this.ensureFileOrFolder({ path: filePath, content });
}
else {
currentEntry.content = content;
currentEntry.modifiedTime = this.now();
this.fs.get(getDirectoryPath(currentEntry.path)).modifiedTime = this.now();
if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) {
this.invokeDirectoryWatcher(getDirectoryPath(currentEntry.fullPath), currentEntry.fullPath);
}
else {
this.invokeFileWatcher(currentEntry.fullPath, FileWatcherEventKind.Changed);
}
}
}
renameFolder(folderName: string, newFolderName: string) {
const fullPath = getNormalizedAbsolutePath(folderName, this.currentDirectory);
const path = this.toPath(fullPath);

View file

@ -1,5 +1,3 @@
declare type PropertyKey = string | number | symbol;
interface Array<T> {
/**
* Returns the value of the first element in the array where predicate is true, and undefined
@ -258,20 +256,6 @@ interface NumberConstructor {
parseInt(string: string, radix?: number): number;
}
interface Object {
/**
* Determines whether an object has a property with the specified name.
* @param v A property name.
*/
hasOwnProperty(v: PropertyKey): boolean;
/**
* Determines whether a specified property is enumerable.
* @param v A property name.
*/
propertyIsEnumerable(v: PropertyKey): boolean;
}
interface ObjectConstructor {
/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
@ -327,25 +311,6 @@ interface ObjectConstructor {
* @param proto The value of the new prototype or null.
*/
setPrototypeOf(o: any, proto: object | null): any;
/**
* Gets the own property descriptor of the specified object.
* An own property descriptor is one that is defined directly on the object and is not
* inherited from the object's prototype.
* @param o Object that contains the property.
* @param p Name of the property.
*/
getOwnPropertyDescriptor(o: any, propertyKey: PropertyKey): PropertyDescriptor | undefined;
/**
* Adds a property to an object, or modifies attributes of an existing property.
* @param o Object on which to add or modify the property. This can be a native JavaScript
* object (that is, a user-defined object or a built in object) or a DOM object.
* @param p The property name.
* @param attributes Descriptor for the property. It can be for a data property or an accessor
* property.
*/
defineProperty(o: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): any;
}
interface ReadonlyArray<T> {

View file

@ -177,14 +177,7 @@ interface PromiseConstructor {
* @param reason The reason the promise was rejected.
* @returns A new rejected Promise.
*/
reject(reason: any): Promise<never>;
/**
* Creates a new rejected promise for the provided reason.
* @param reason The reason the promise was rejected.
* @returns A new rejected Promise.
*/
reject<T>(reason: any): Promise<T>;
reject<T = never>(reason?: any): Promise<T>;
/**
* Creates a new resolved promise for the provided value.

21
src/lib/es5.d.ts vendored
View file

@ -74,6 +74,8 @@ declare function escape(string: string): string;
*/
declare function unescape(string: string): string;
declare type PropertyKey = string | number | symbol;
interface PropertyDescriptor {
configurable?: boolean;
enumerable?: boolean;
@ -104,7 +106,7 @@ interface Object {
* Determines whether an object has a property with the specified name.
* @param v A property name.
*/
hasOwnProperty(v: string): boolean;
hasOwnProperty(v: PropertyKey): boolean;
/**
* Determines whether an object exists in another object's prototype chain.
@ -116,7 +118,7 @@ interface Object {
* Determines whether a specified property is enumerable.
* @param v A property name.
*/
propertyIsEnumerable(v: string): boolean;
propertyIsEnumerable(v: PropertyKey): boolean;
}
interface ObjectConstructor {
@ -139,7 +141,7 @@ interface ObjectConstructor {
* @param o Object that contains the property.
* @param p Name of the property.
*/
getOwnPropertyDescriptor(o: any, p: string): PropertyDescriptor | undefined;
getOwnPropertyDescriptor(o: any, p: PropertyKey): PropertyDescriptor | undefined;
/**
* Returns the names of the own properties of an object. The own properties of an object are those that are defined directly
@ -167,7 +169,7 @@ interface ObjectConstructor {
* @param p The property name.
* @param attributes Descriptor for the property. It can be for a data property or an accessor property.
*/
defineProperty(o: any, p: string, attributes: PropertyDescriptor & ThisType<any>): any;
defineProperty(o: any, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>): any;
/**
* Adds one or more properties to an object, and/or modifies attributes of existing properties.
@ -505,6 +507,15 @@ interface TemplateStringsArray extends ReadonlyArray<string> {
readonly raw: ReadonlyArray<string>;
}
/**
* The type of `import.meta`.
*
* If you need to declare that a given property exists on `import.meta`,
* this type may be augmented via interface merging.
*/
interface ImportMeta {
}
interface Math {
/** The mathematical constant e. This is Euler's number, the base of natural logarithms. */
readonly E: number;
@ -1340,7 +1351,7 @@ type Pick<T, K extends keyof T> = {
/**
* Construct a type with a set of properties K of type T
*/
type Record<K extends string, T> = {
type Record<K extends keyof any, T> = {
[P in K]: T;
};

View file

@ -903,6 +903,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[将“{0}.”添加到未解析的变量]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -999,27 +1008,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[将 "this." 添加到匹配成员名称的所有未解析变量]]></Val>
<Val><![CDATA[将限定符添加到匹配成员名称的所有未解析变量]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[向未解析的变量添加 "this."]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -1254,6 +1251,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[元素访问表达式应采用参数。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@ -2388,15 +2394,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[编译完成。查看文件更改。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3771,20 +3768,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[找到 {0} 个错误。]]></Val>
<Val><![CDATA[找到 {0} 个错误。注意文件更改。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[找到 1 个错误。]]></Val>
<Val><![CDATA[找到 1 个错误。注意文件更改。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -6516,6 +6513,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[只将 "keyof" 解析为字符串值的属性名称(不含数字或符号)。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>
@ -8766,6 +8772,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[“{0}”已声明,但从未使用过。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>

View file

@ -903,6 +903,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[對未解析的變數新增 '{0}.']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -999,27 +1008,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[為所有用以比對成員名稱未解析的變數新增 'this.']]></Val>
<Val><![CDATA[對所有比對成員名稱的未解析變數新增限定詞]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[將 'this' 新增至未解析的變數]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -2388,15 +2385,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[編譯完成。正在等候檔案變更。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3771,20 +3759,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[找到 {0} 個錯誤。]]></Val>
<Val><![CDATA[找到 {0} 個錯誤。正在監看檔案變更。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[找到 1 個錯誤。]]></Val>
<Val><![CDATA[找到 1 個錯誤。正在監看檔案變更。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -3900,6 +3888,9 @@
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[產生 'get' 與 'set' 存取子]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6015,6 +6006,9 @@
<Item ItemId=";Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[類型 '{1}' 不存在屬性 '{0}'。是否忘記要使用 'await'?]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6510,6 +6504,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>

View file

@ -912,6 +912,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Přidat {0}. k nerozpoznané proměnné]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -1008,27 +1017,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Přidat this. do všech nerozpoznaných proměnných odpovídajících názvu členu]]></Val>
<Val><![CDATA[Přidat kvalifikátor do všech nerozpoznaných proměnných odpovídajících názvu členu]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Přidat k nerozpoznané proměnné this.]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -1263,6 +1260,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Výraz přístupu k elementu by měl přijímat argument.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@ -2397,15 +2403,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Kompilace je hotová. Sledují se změny souborů.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3780,20 +3777,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Našel se tento počet chyb: {0}.]]></Val>
<Val><![CDATA[Byl nalezen tento počet chyb: {0}. Sledují se změny souborů.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Našla se 1 chyba.]]></Val>
<Val><![CDATA[Byla nalezena 1 chyba. Sledují se změny souborů.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -3906,6 +3903,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Generovat přístupové objekty get a set]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generates a sourcemap for each corresponding '.d.ts' file.]]></Val>
@ -6018,6 +6024,9 @@
<Item ItemId=";Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Vlastnost {0} v typu {1} neexistuje. Nezapomněli jste použít await?]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6513,6 +6522,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[keyof překládejte jen na názvy vlastností s hodnotami typu string (ne čísla ani symboly).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>
@ -8763,6 +8781,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} se nadeklarovalo, ale nepoužilo.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>

View file

@ -900,6 +900,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Der nicht aufgelösten Variablen "{0}." hinzufügen]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -996,27 +1005,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Allen nicht aufgelösten Variablen, die einem Membernamen entsprechen, "this." hinzufügen]]></Val>
<Val><![CDATA[Allen nicht aufgelösten Variablen, die einem Membernamen entsprechen, Qualifizierer hinzufügen]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Der nicht aufgelösten Variablen "this." hinzufügen]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -2385,15 +2382,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Die Kompilierung wurde abgeschlossen. Dateiänderungen werden überprüft.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3768,20 +3756,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} Fehler gefunden.]]></Val>
<Val><![CDATA[{0} Fehler gefunden. Es wird auf Dateiänderungen überwacht.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[1 Fehler gefunden.]]></Val>
<Val><![CDATA[1 Fehler gefunden. Es wird auf Dateiänderungen überwacht.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -3894,6 +3882,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[GET- und SET-Accessoren generieren]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generates a sourcemap for each corresponding '.d.ts' file.]]></Val>
@ -6003,6 +6000,9 @@
<Item ItemId=";Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Die Eigenschaft "{0}" ist im Typ "{1}" nicht vorhanden. Haben Sie "await" nicht verwendet?]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6498,6 +6498,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>

View file

@ -912,6 +912,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Agregar "{0}." a una variable no resuelta]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -1008,27 +1017,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Agregar "this." a todas las variables no resueltas que coincidan con un nombre de miembro]]></Val>
<Val><![CDATA[Agregar un calificador a todas las variables no resueltas que coincidan con un nombre de miembro]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Agregar "this." a una variable no resuelta]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -2397,15 +2394,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Compilación completada. Supervisando los cambios del archivo.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3780,20 +3768,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Se encontró {0} errores.]]></Val>
<Val><![CDATA[Se encontraron {0} errores. Supervisando los cambios del archivo.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Se encontró 1 error.]]></Val>
<Val><![CDATA[Se encontró un error. Supervisando los cambios del archivo.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -3906,6 +3894,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Generar los descriptores de acceso "get" y "set"]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generates a sourcemap for each corresponding '.d.ts' file.]]></Val>
@ -6018,6 +6015,9 @@
<Item ItemId=";Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La propiedad "{0}" no existe en el tipo "{1}". ¿Olvidó usar "await"?]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6513,6 +6513,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>

View file

@ -912,6 +912,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Ajouter '{0}.' à la variable non résolue]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -1008,27 +1017,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Ajouter 'this.' à toutes les variables non résolues correspondant à un nom de membre]]></Val>
<Val><![CDATA[Ajouter un qualificateur à toutes les variables non résolues correspondant à un nom de membre]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Ajouter 'this.' à la variable non résolue]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -2397,15 +2394,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Fin de la compilation. Détection des changements apportés au fichier.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3780,20 +3768,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} erreurs trouvées.]]></Val>
<Val><![CDATA[{0} erreurs trouvées. Changements de fichier sous surveillance.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[1 erreur trouvée.]]></Val>
<Val><![CDATA[1 erreur trouvée. Changements de fichier sous surveillance.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -3906,6 +3894,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Générer les accesseurs 'get' et 'set']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generates a sourcemap for each corresponding '.d.ts' file.]]></Val>
@ -6018,6 +6015,9 @@
<Item ItemId=";Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La propriété '{0}' n'existe pas sur le type '{1}'. Avez-vous oublié d'utiliser 'await' ?]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6513,6 +6513,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>

View file

@ -903,6 +903,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Aggiungere '{0}.' alla variabile non risolta]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -999,27 +1008,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Aggiungere 'this.' a tutte le variabili non risolte corrispondenti a un nome di membro]]></Val>
<Val><![CDATA[Aggiungere il qualificatore a tutte le variabili non risolte corrispondenti a un nome di membro]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Aggiungere 'this.' alla variabile non risolta]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -1254,6 +1251,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Un'espressione di accesso a elementi deve accettare un argomento.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@ -2388,15 +2394,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Compilazione completata. Verranno individuate le modifiche ai file.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3771,20 +3768,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Sono stati trovati {0} errori.]]></Val>
<Val><![CDATA[Sono stati trovati {0} errori. Verranno individuate le modifiche ai file.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[È stato trovato 1 errore.]]></Val>
<Val><![CDATA[È stato trovato 1 errore. Verranno individuate le modifiche ai file.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -6516,6 +6513,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Risolvere 'keyof' solo in nomi di proprietà con valori stringa (senza numeri o simboli).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>
@ -8766,6 +8772,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La variabile '{0}' è dichiarata, ma non viene mai usata.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>

View file

@ -903,6 +903,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['{0}' を未解決の変数に追加します]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -999,27 +1008,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[メンバー名と一致するすべての未解決の変数に 'this.' を追加します]]></Val>
<Val><![CDATA[メンバー名と一致するすべての未解決の変数に修飾子を追加します]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['this.' を未解決の変数に追加する]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -2388,15 +2385,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[コンパイルが完了しました。ファイルの変更を監視しています。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3771,20 +3759,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} 件のエラーが見つかりました。]]></Val>
<Val><![CDATA[{0} 件のエラーが見つかりました。ファイルの変更をモニタリングしています。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[1 件のエラーが見つかりました。]]></Val>
<Val><![CDATA[1 件のエラーが見つかりました。ファイルの変更をモニタリングしています。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -3897,6 +3885,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['get' および 'set' アクセサーの生成]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generates a sourcemap for each corresponding '.d.ts' file.]]></Val>
@ -6009,6 +6006,9 @@
<Item ItemId=";Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[型 '{1}' にプロパティ '{0}' は存在しません。'await' を使用していない可能性があります。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6504,6 +6504,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>

View file

@ -903,6 +903,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[확인되지 않은 변수에 '{0}.' 추가]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -999,27 +1008,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[멤버 이름과 일치하는 모든 확인되지 않은 변수에 'this.' 추가]]></Val>
<Val><![CDATA[멤버 이름과 일치하는 모든 확인되지 않은 변수에 한정자 추가]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[확인되지 않은 변수에 'this.' 추가]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -2388,15 +2385,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[컴파일이 완료되었습니다. 파일이 변경되었는지 확인하는 중입니다.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3771,20 +3759,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0}개 오류가 발견되었습니다.]]></Val>
<Val><![CDATA[{0}개 오류가 발견되었습니다. 파일이 변경되었는지 확인하는 중입니다.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[1개 오류가 발견되었습니다.]]></Val>
<Val><![CDATA[1개 오류가 발견되었습니다. 파일이 변경되었는지 확인하는 중입니다.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -3897,6 +3885,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['get' 및 'set' 접근자 생성]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generates a sourcemap for each corresponding '.d.ts' file.]]></Val>
@ -6009,6 +6006,9 @@
<Item ItemId=";Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[속성 '{0}'이(가) '{1}' 형식에 없습니다. 'await' 사용을 잊으셨나요?]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6504,6 +6504,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>

View file

@ -893,6 +893,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Dodaj „{0}.” do nierozpoznanej zmiennej]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -989,27 +998,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Dodaj element „this.” do wszystkich nierozpoznanych zmiennych pasujących do nazwy elementu członkowskiego]]></Val>
<Val><![CDATA[Dodaj kwalifikator do wszystkich nierozpoznanych zmiennych pasujących do nazwy składowej]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Dodaj „this.” do nierozpoznanej zmiennej]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -1244,6 +1241,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Wyrażenie dostępu do elementu powinno przyjmować argument.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@ -2378,15 +2384,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Ukończono kompilację. Wyszukiwanie zmian plików.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3761,20 +3758,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Znaleziono błędy: {0}.]]></Val>
<Val><![CDATA[Znalezione błędy: {0}. Obserwowanie zmian plików.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Znaleziono 1 błąd.]]></Val>
<Val><![CDATA[Znaleziono 1 błąd. Obserwowanie zmian plików.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -6503,6 +6500,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Rozwiązuj elementy „keyof” tylko do nazw właściwości mających jako wartość ciągi (nie liczby czy symbole).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>
@ -8753,6 +8759,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Element „{0}” jest zadeklarowany, ale nie jest nigdy używany.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>

View file

@ -893,6 +893,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Adicionar '{0}.' à variável não resolvida]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -989,27 +998,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Adicionar 'this.' a todas as variáveis não resolvidas correspondentes a um nome de membro]]></Val>
<Val><![CDATA[Adicionar um qualificador a todas as variáveis não resolvidas correspondentes a um nome de membro]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Adicionar 'this.' a uma variável não resolvida]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -2378,15 +2375,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Compilação concluída. Monitorando alterações de arquivo.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3761,20 +3749,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Encontrados {0} erros.]]></Val>
<Val><![CDATA[{0} erros encontrados. Monitorando alterações de arquivo.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Encontrado 1 erro.]]></Val>
<Val><![CDATA[Um erro encontrado. Monitorando alterações de arquivo.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -3887,6 +3875,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Gerar acessadores 'get' e 'set']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generates a sourcemap for each corresponding '.d.ts' file.]]></Val>
@ -5996,6 +5993,9 @@
<Item ItemId=";Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[A propriedade '{0}' não existe no tipo '{1}'. Você esqueceu de usar 'await'?]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6491,6 +6491,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>

View file

@ -902,6 +902,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Добавить "{0}." к неразрешенной переменной]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -998,27 +1007,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Добавить "this." ко всем неразрешенным переменным, соответствующим имени элемента]]></Val>
<Val><![CDATA[Добавить квалификатор ко всем неразрешенным переменным, соответствующим имени члена]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Добавьте "this." к неразрешенной переменной]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -1253,6 +1250,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_element_access_expression_should_take_an_argument_1011" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An element access expression should take an argument.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Выражение доступа к элементу должно принимать аргумент.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";An_enum_member_cannot_have_a_numeric_name_2452" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[An enum member cannot have a numeric name.]]></Val>
@ -2387,15 +2393,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Компиляция завершена. Отслеживание изменений в файлах.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3770,20 +3767,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Найдено ошибок: {0}.]]></Val>
<Val><![CDATA[Найдено ошибок: {0}. Отслеживаются изменения в файлах.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Найдено ошибок: 1.]]></Val>
<Val><![CDATA[Найдена одна ошибка. Отслеживаются изменения в файлах.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -3896,6 +3893,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Создать методы доступа get и set]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generates a sourcemap for each corresponding '.d.ts' file.]]></Val>
@ -6008,6 +6014,9 @@
<Item ItemId=";Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Свойство "{0}" не существует в типе "{1}". Возможно, пропущено "await"?]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6503,6 +6512,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Разрешать "keyof" только в имена свойств со строковым значением (не числа и не символы).]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>
@ -8753,6 +8771,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["{0}" объявлен, но никогда не использовался.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>

View file

@ -896,6 +896,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_0_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '{0}.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Çözümlenmemiş değişkene '{0}.' ekle]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_all_missing_async_modifiers_95041" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add all missing 'async' modifiers]]></Val>
@ -992,27 +1001,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Add_qualifier_to_all_unresolved_variables_matching_a_member_name_95037" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to all unresolved variables matching a member name]]></Val>
<Val><![CDATA[Add qualifier to all unresolved variables matching a member name]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Bir üye adıyla eşleşen tüm çözülmemiş değişkenlere 'this.' ekle]]></Val>
<Val><![CDATA[Bir üye adıyla eşleşen tüm çözülmemiş değişkenlere niteleyici ekle]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_this_to_unresolved_variable_90008" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Çözümlenmemiş değişkene 'this.' ekle]]></Val>
</Tgt>
<Prev Cat="Text">
<Val><![CDATA[Add 'this.' to unresolved variable.]]></Val>
</Prev>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Add_to_all_uncalled_decorators_95044" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Add '()' to all uncalled decorators]]></Val>
@ -2381,15 +2378,6 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compilation_complete_Watching_for_file_changes_6042" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compilation complete. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Derleme tamamlandı. Dosya değişiklikleri izleniyor.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'.]]></Val>
@ -3764,20 +3752,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_0_errors_6194" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_0_errors_Watching_for_file_changes_6194" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found {0} errors.]]></Val>
<Val><![CDATA[Found {0} errors. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[{0} hata bulundu.]]></Val>
<Val><![CDATA[{0} hata bulundu. Dosya değişiklikleri izleniyor.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Found_1_error_6193" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Found_1_error_Watching_for_file_changes_6193" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Found 1 error.]]></Val>
<Val><![CDATA[Found 1 error. Watching for file changes.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[1 hata bulundu.]]></Val>
<Val><![CDATA[1 hata bulundu. Dosya değişiklikleri izleniyor.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
@ -3890,6 +3878,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generate_get_and_set_accessors_95046" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generate 'get' and 'set' accessors]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['get' ve 'set' erişimcilerini oluşturun]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Generates_a_sourcemap_for_each_corresponding_d_ts_file_6000" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Generates a sourcemap for each corresponding '.d.ts' file.]]></Val>
@ -6002,6 +5999,9 @@
<Item ItemId=";Property_0_does_not_exist_on_type_1_Did_you_forget_to_use_await_2570" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on type '{1}'. Did you forget to use 'await'?]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['{0}' özelliği '{1}' türü üzerinde yok. 'await' kullanmayı mı unuttunuz?]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@ -6497,6 +6497,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolve_keyof_to_string_valued_property_names_only_no_numbers_or_symbols_6195" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolve 'keyof' to string valued property names only (no numbers or symbols).]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Resolving_from_node_modules_folder_6118" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Resolving from node_modules folder...]]></Val>
@ -8747,6 +8753,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_declared_but_never_used_6196" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is declared but never used.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?]]></Val>

View file

@ -632,6 +632,10 @@ namespace ts.server {
return notImplemented();
}
getEditsForFileRename() {
return notImplemented();
}
private convertCodeEditsToTextChanges(edits: protocol.FileCodeEdits[]): FileTextChanges[] {
return edits.map(edit => {
const fileName = edit.fileName;

View file

@ -310,9 +310,14 @@ namespace ts.server {
return `Project: ${project ? project.getProjectName() : ""} WatchType: ${watchType}`;
}
function updateProjectIfDirty(project: Project) {
return project.dirty && project.updateGraph();
}
export class ProjectService {
public readonly typingsCache: TypingsCache;
/*@internal*/
readonly typingsCache: TypingsCache;
private readonly documentRegistry: DocumentRegistry;
@ -523,13 +528,13 @@ namespace ts.server {
}
switch (response.kind) {
case ActionSet:
project.resolutionCache.clear();
this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typeAcquisition, response.unresolvedImports, response.typings);
// Update the typing files and update the project
project.updateTypingFiles(this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typeAcquisition, response.unresolvedImports, response.typings));
break;
case ActionInvalidate:
project.resolutionCache.clear();
this.typingsCache.deleteTypingsForProject(response.projectName);
break;
// Do not clear resolution cache, there was changes detected in typings, so enque typing request and let it get us correct results
this.typingsCache.enqueueInstallTypingsForProject(project, project.lastCachedUnresolvedImportsList, /*forceRefresh*/ true);
return;
}
this.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project);
}
@ -672,7 +677,7 @@ namespace ts.server {
let hasChanges = this.pendingEnsureProjectForOpenFiles;
this.pendingProjectUpdates.clear();
const updateGraph = (project: Project) => {
hasChanges = this.updateProjectIfDirty(project) || hasChanges;
hasChanges = updateProjectIfDirty(project) || hasChanges;
};
this.externalProjects.forEach(updateGraph);
@ -683,10 +688,6 @@ namespace ts.server {
}
}
private updateProjectIfDirty(project: Project) {
return project.dirty && project.updateGraph();
}
getFormatCodeOptions(file: NormalizedPath) {
const info = this.getScriptInfoForNormalizedPath(file);
return info && info.getFormatCodeSettings() || this.hostConfiguration.formatCodeOptions;
@ -1979,7 +1980,7 @@ namespace ts.server {
}
});
this.pendingEnsureProjectForOpenFiles = false;
this.inferredProjects.forEach(p => this.updateProjectIfDirty(p));
this.inferredProjects.forEach(updateProjectIfDirty);
this.logger.info("Structure after ensureProjectForOpenFiles:");
this.printProjects();
@ -2026,7 +2027,7 @@ namespace ts.server {
}
else {
// Ensure project is ready to check if it contains opened script info
project.updateGraph();
updateProjectIfDirty(project);
}
}
}
@ -2035,6 +2036,11 @@ namespace ts.server {
// - external project search, which updates the project before checking if info is present in it
// - configured project - either created or updated to ensure we know correct status of info
// At this point we need to ensure that containing projects of the info are uptodate
// This will ensure that later question of info.isOrphan() will return correct answer
// and we correctly create inferred project for the info
info.containingProjects.forEach(updateProjectIfDirty);
// At this point if file is part of any any configured or external project, then it would be present in the containing projects
// So if it still doesnt have any containing projects, it needs to be part of inferred project
if (info.isOrphan()) {

View file

@ -55,34 +55,6 @@ namespace ts.server {
projectErrors: ReadonlyArray<Diagnostic>;
}
export class UnresolvedImportsMap {
readonly perFileMap = createMap<ReadonlyArray<string>>();
private version = 0;
public clear() {
this.perFileMap.clear();
this.version = 0;
}
public getVersion() {
return this.version;
}
public remove(path: Path) {
this.perFileMap.delete(path);
this.version++;
}
public get(path: Path) {
return this.perFileMap.get(path);
}
public set(path: Path, value: ReadonlyArray<string>) {
this.perFileMap.set(path, value);
this.version++;
}
}
export interface PluginCreateInfo {
project: Project;
languageService: LanguageService;
@ -116,8 +88,18 @@ namespace ts.server {
private missingFilesMap: Map<FileWatcher>;
private plugins: PluginModule[] = [];
private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap();
private lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
/*@internal*/
/**
* This is map from files to unresolved imports in it
* Maop does not contain entries for files that do not have unresolved imports
* This helps in containing the set of files to invalidate
*/
cachedUnresolvedImportsPerFile = createMap<ReadonlyArray<string>>();
/*@internal*/
lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
/*@internal*/
private hasAddedorRemovedFiles = false;
private lastFileExceededProgramSize: string | undefined;
@ -149,10 +131,10 @@ namespace ts.server {
*/
private lastReportedVersion = 0;
/**
* Current project structure version.
* Current project's program version. (incremented everytime new program is created that is not complete reuse from the old one)
* This property is changed in 'updateGraph' based on the set of files in program
*/
private projectStructureVersion = 0;
private projectProgramVersion = 0;
/**
* Current version of the project state. It is changed when:
* - new root file was added/removed
@ -167,7 +149,8 @@ namespace ts.server {
/*@internal*/
hasChangedAutomaticTypeDirectiveNames = false;
private typingFiles: SortedReadonlyArray<string>;
/*@internal*/
typingFiles: SortedReadonlyArray<string> = emptyArray;
private readonly cancellationToken: ThrottledCancellationToken;
@ -181,10 +164,6 @@ namespace ts.server {
return hasOneOrMoreJsAndNoTsFiles(this);
}
public getCachedUnresolvedImportsPerFile_TestOnly() {
return this.cachedUnresolvedImportsPerFile;
}
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} {
const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules")));
log(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`);
@ -742,7 +721,7 @@ namespace ts.server {
else {
this.resolutionCache.invalidateResolutionOfFile(info.path);
}
this.cachedUnresolvedImportsPerFile.remove(info.path);
this.cachedUnresolvedImportsPerFile.delete(info.path);
if (detachFromProject) {
info.detachFromProject(this);
@ -763,16 +742,13 @@ namespace ts.server {
}
/* @internal */
private extractUnresolvedImportsFromSourceFile(file: SourceFile, result: Push<string>, ambientModules: string[]) {
private extractUnresolvedImportsFromSourceFile(file: SourceFile, ambientModules: string[]): ReadonlyArray<string> {
const cached = this.cachedUnresolvedImportsPerFile.get(file.path);
if (cached) {
// found cached result - use it and return
for (const f of cached) {
result.push(f);
}
return;
// found cached result, return
return cached;
}
let unresolvedImports: string[];
let unresolvedImports: string[] | undefined;
if (file.resolvedModules) {
file.resolvedModules.forEach((resolvedModule, name) => {
// pick unresolved non-relative names
@ -788,17 +764,23 @@ namespace ts.server {
trimmed = trimmed.substr(0, i);
}
(unresolvedImports || (unresolvedImports = [])).push(trimmed);
result.push(trimmed);
}
});
}
this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports || emptyArray);
return unresolvedImports || emptyArray;
function isAmbientlyDeclaredModule(name: string) {
return ambientModules.some(m => m === name);
}
}
/* @internal */
onFileAddedOrRemoved() {
this.hasAddedorRemovedFiles = true;
}
/**
* Updates set of files that contribute to this project
* @returns: true if set of files in the project stays the same and false - otherwise.
@ -806,13 +788,15 @@ namespace ts.server {
updateGraph(): boolean {
this.resolutionCache.startRecordingFilesWithChangedResolutions();
let hasChanges = this.updateGraphWorker();
const hasNewProgram = this.updateGraphWorker();
const hasAddedorRemovedFiles = this.hasAddedorRemovedFiles;
this.hasAddedorRemovedFiles = false;
const changedFiles: ReadonlyArray<Path> = this.resolutionCache.finishRecordingFilesWithChangedResolutions() || emptyArray;
for (const file of changedFiles) {
// delete cached information for changed files
this.cachedUnresolvedImportsPerFile.remove(file);
this.cachedUnresolvedImportsPerFile.delete(file);
}
// update builder only if language service is enabled
@ -824,30 +808,35 @@ namespace ts.server {
// 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files
// (can reuse cached imports for files that were not changed)
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
if (hasChanges || changedFiles.length) {
const result: string[] = [];
if (hasNewProgram || changedFiles.length) {
let result: string[] | undefined;
const ambientModules = this.program.getTypeChecker().getAmbientModules().map(mod => stripQuotes(mod.getName()));
for (const sourceFile of this.program.getSourceFiles()) {
this.extractUnresolvedImportsFromSourceFile(sourceFile, result, ambientModules);
const unResolved = this.extractUnresolvedImportsFromSourceFile(sourceFile, ambientModules);
if (unResolved !== emptyArray) {
(result || (result = [])).push(...unResolved);
}
}
this.lastCachedUnresolvedImportsList = toDeduplicatedSortedArray(result);
this.lastCachedUnresolvedImportsList = result ? toDeduplicatedSortedArray(result) : emptyArray;
}
const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasChanges);
if (!arrayIsEqualTo(this.typingFiles, cachedTypings)) {
this.typingFiles = cachedTypings;
this.markAsDirty();
hasChanges = this.updateGraphWorker() || hasChanges;
}
this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasAddedorRemovedFiles);
}
else {
this.lastCachedUnresolvedImportsList = undefined;
}
if (hasChanges) {
this.projectStructureVersion++;
if (hasNewProgram) {
this.projectProgramVersion++;
}
return !hasChanges;
return !hasNewProgram;
}
/*@internal*/
updateTypingFiles(typingFiles: SortedReadonlyArray<string>) {
this.typingFiles = typingFiles;
// Invalidate files with unresolved imports
this.resolutionCache.setFilesWithInvalidatedNonRelativeUnresolvedImports(this.cachedUnresolvedImportsPerFile);
}
/* @internal */
@ -876,9 +865,9 @@ namespace ts.server {
// bump up the version if
// - oldProgram is not set - this is a first time updateGraph is called
// - newProgram is different from the old program and structure of the old program was not reused.
const hasChanges = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & StructureIsReused.Completely)));
const hasNewProgram = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & StructureIsReused.Completely)));
this.hasChangedAutomaticTypeDirectiveNames = false;
if (hasChanges) {
if (hasNewProgram) {
if (oldProgram) {
for (const f of oldProgram.getSourceFiles()) {
if (this.program.getSourceFileByPath(f.path)) {
@ -916,8 +905,8 @@ namespace ts.server {
removed => this.detachScriptInfoFromProject(removed)
);
const elapsed = timestamp() - start;
this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} Version: ${this.getProjectVersion()} structureChanged: ${hasChanges} Elapsed: ${elapsed}ms`);
return hasChanges;
this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} Version: ${this.getProjectVersion()} structureChanged: ${hasNewProgram} Elapsed: ${elapsed}ms`);
return hasNewProgram;
}
private detachScriptInfoFromProject(uncheckedFileName: string) {
@ -985,15 +974,13 @@ namespace ts.server {
setCompilerOptions(compilerOptions: CompilerOptions) {
if (compilerOptions) {
compilerOptions.allowNonTsExtensions = true;
if (changesAffectModuleResolution(this.compilerOptions, compilerOptions)) {
// reset cached unresolved imports if changes in compiler options affected module resolution
this.cachedUnresolvedImportsPerFile.clear();
this.lastCachedUnresolvedImportsList = undefined;
}
const oldOptions = this.compilerOptions;
this.compilerOptions = compilerOptions;
this.setInternalCompilerOptionsForEmittingJsFiles();
if (changesAffectModuleResolution(oldOptions, compilerOptions)) {
// reset cached unresolved imports if changes in compiler options affected module resolution
this.cachedUnresolvedImportsPerFile.clear();
this.lastCachedUnresolvedImportsList = undefined;
this.resolutionCache.clear();
}
this.markAsDirty();
@ -1006,7 +993,7 @@ namespace ts.server {
const info: protocol.ProjectVersionInfo = {
projectName: this.getProjectName(),
version: this.projectStructureVersion,
version: this.projectProgramVersion,
isInferred: this.projectKind === ProjectKind.Inferred,
options: this.getCompilationSettings(),
languageServiceDisabled: !this.languageServiceEnabled,
@ -1017,7 +1004,7 @@ namespace ts.server {
// check if requested version is the same that we have reported last time
if (this.lastReportedFileNames && lastKnownVersion === this.lastReportedVersion) {
// if current structure version is the same - return info without any changes
if (this.projectStructureVersion === this.lastReportedVersion && !updatedFileNames) {
if (this.projectProgramVersion === this.lastReportedVersion && !updatedFileNames) {
return { info, projectErrors: this.getGlobalProjectErrors() };
}
// compute and return the difference
@ -1040,7 +1027,7 @@ namespace ts.server {
}
});
this.lastReportedFileNames = currentFiles;
this.lastReportedVersion = this.projectStructureVersion;
this.lastReportedVersion = this.projectProgramVersion;
return { info, changes: { added, removed, updated }, projectErrors: this.getGlobalProjectErrors() };
}
else {
@ -1049,7 +1036,7 @@ namespace ts.server {
const externalFiles = this.getExternalFiles().map(f => toNormalizedPath(f));
const allFiles = projectFileNames.concat(externalFiles);
this.lastReportedFileNames = arrayToSet(allFiles);
this.lastReportedVersion = this.projectStructureVersion;
this.lastReportedVersion = this.projectProgramVersion;
return { info, files: allFiles, projectErrors: this.getGlobalProjectErrors() };
}
}

View file

@ -121,6 +121,9 @@ namespace ts.server.protocol {
OrganizeImports = "organizeImports",
/* @internal */
OrganizeImportsFull = "organizeImports-full",
GetEditsForFileRename = "getEditsForFileRename",
/* @internal */
GetEditsForFileRenameFull = "getEditsForFileRename-full",
// NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`.
}
@ -610,6 +613,22 @@ namespace ts.server.protocol {
edits: ReadonlyArray<FileCodeEdits>;
}
export interface GetEditsForFileRenameRequest extends Request {
command: CommandTypes.GetEditsForFileRename;
arguments: GetEditsForFileRenameRequestArgs;
}
// Note: The file from FileRequestArgs is just any file in the project.
// We will generate code changes for every file in that project, so the choice is arbitrary.
export interface GetEditsForFileRenameRequestArgs extends FileRequestArgs {
readonly oldFilePath: string;
readonly newFilePath: string;
}
export interface GetEditsForFileRenameResponse extends Response {
edits: ReadonlyArray<FileCodeEdits>;
}
/**
* Request for the available codefixes at a specific position.
*/
@ -1749,6 +1768,7 @@ namespace ts.server.protocol {
* Optional prefix to apply to possible completions.
*/
prefix?: string;
triggerCharacter?: string;
/**
* @deprecated Use UserPreferences.includeCompletionsForModuleExports
*/

View file

@ -304,6 +304,7 @@ namespace ts.server {
const isNew = !this.isAttached(project);
if (isNew) {
this.containingProjects.push(project);
project.onFileAddedOrRemoved();
if (!project.getCompilerOptions().preserveSymlinks) {
this.ensureRealPath();
}
@ -328,19 +329,24 @@ namespace ts.server {
return;
case 1:
if (this.containingProjects[0] === project) {
project.onFileAddedOrRemoved();
this.containingProjects.pop();
}
break;
case 2:
if (this.containingProjects[0] === project) {
project.onFileAddedOrRemoved();
this.containingProjects[0] = this.containingProjects.pop();
}
else if (this.containingProjects[1] === project) {
project.onFileAddedOrRemoved();
this.containingProjects.pop();
}
break;
default:
unorderedRemoveItem(this.containingProjects, project);
if (unorderedRemoveItem(this.containingProjects, project)) {
project.onFileAddedOrRemoved();
}
break;
}
}

View file

@ -634,7 +634,8 @@ namespace ts.server {
code: d.code,
source: d.source,
startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start),
endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length)
endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length),
reportsUnnecessary: d.reportsUnnecessary
});
}
@ -1286,6 +1287,7 @@ namespace ts.server {
const completions = project.getLanguageService().getCompletionsAtPosition(file, position, {
...this.getPreferences(file),
triggerCharacter: args.triggerCharacter,
includeExternalModuleExports: args.includeExternalModuleExports,
includeInsertTextCompletions: args.includeInsertTextCompletions
});
@ -1663,6 +1665,12 @@ namespace ts.server {
}
}
private getEditsForFileRename(args: protocol.GetEditsForFileRenameRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.FileCodeEdits> | ReadonlyArray<FileTextChanges> {
const { file, project } = this.getFileAndProject(args);
const changes = project.getLanguageService().getEditsForFileRename(args.oldFilePath, args.newFilePath, this.getFormatOptions(file));
return simplifiedResult ? this.mapTextChangesToCodeEdits(project, changes) : changes;
}
private getCodeFixes(args: protocol.CodeFixRequestArgs, simplifiedResult: boolean): ReadonlyArray<protocol.CodeFixAction> | ReadonlyArray<CodeFixAction> {
if (args.errorCodes.length === 0) {
return undefined;
@ -2116,7 +2124,13 @@ namespace ts.server {
},
[CommandNames.OrganizeImportsFull]: (request: protocol.OrganizeImportsRequest) => {
return this.requiredResponse(this.organizeImports(request.arguments, /*simplifiedResult*/ false));
}
},
[CommandNames.GetEditsForFileRename]: (request: protocol.GetEditsForFileRenameRequest) => {
return this.requiredResponse(this.getEditsForFileRename(request.arguments, /*simplifiedResult*/ true));
},
[CommandNames.GetEditsForFileRenameFull]: (request: protocol.GetEditsForFileRenameRequest) => {
return this.requiredResponse(this.getEditsForFileRename(request.arguments, /*simplifiedResult*/ false));
},
});
public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse) {

View file

@ -66,6 +66,7 @@
"../services/navigateTo.ts",
"../services/navigationBar.ts",
"../services/organizeImports.ts",
"../services/getEditsForFileRename.ts",
"../services/outliningElementsCollector.ts",
"../services/patternMatcher.ts",
"../services/preProcess.ts",
@ -108,10 +109,8 @@
"../services/codefixes/fixInvalidImportSyntax.ts",
"../services/codefixes/fixStrictClassInitialization.ts",
"../services/codefixes/useDefaultImport.ts",
"../services/codefixes/fixes.ts",
"../services/refactors/extractSymbol.ts",
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
"../services/refactors/refactors.ts",
"../services/sourcemaps.ts",
"../services/services.ts",
"../services/breakpoints.ts",

View file

@ -72,6 +72,7 @@
"../services/navigateTo.ts",
"../services/navigationBar.ts",
"../services/organizeImports.ts",
"../services/getEditsForFileRename.ts",
"../services/outliningElementsCollector.ts",
"../services/patternMatcher.ts",
"../services/preProcess.ts",
@ -114,10 +115,8 @@
"../services/codefixes/fixInvalidImportSyntax.ts",
"../services/codefixes/fixStrictClassInitialization.ts",
"../services/codefixes/useDefaultImport.ts",
"../services/codefixes/fixes.ts",
"../services/refactors/extractSymbol.ts",
"../services/refactors/generateGetAccessorAndSetAccessor.ts",
"../services/refactors/refactors.ts",
"../services/sourcemaps.ts",
"../services/services.ts",
"../services/breakpoints.ts",

View file

@ -119,8 +119,10 @@ declare namespace ts.server {
/* @internal */
export interface InstallTypingHost extends JsTyping.TypingResolutionHost {
useCaseSensitiveFileNames: boolean;
writeFile(path: string, content: string): void;
createDirectory(path: string): void;
watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number): FileWatcher;
watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean): FileWatcher;
}
}

View file

@ -24,7 +24,7 @@ namespace ts.server {
globalTypingsCacheLocation: undefined
};
class TypingsCacheEntry {
interface TypingsCacheEntry {
readonly typeAcquisition: TypeAcquisition;
readonly compilerOptions: CompilerOptions;
readonly typings: SortedReadonlyArray<string>;
@ -80,6 +80,7 @@ namespace ts.server {
return !arrayIsEqualTo(imports1, imports2);
}
/*@internal*/
export class TypingsCache {
private readonly perProjectCache: Map<TypingsCacheEntry> = createMap<TypingsCacheEntry>();
@ -94,15 +95,14 @@ namespace ts.server {
return this.installer.installPackage(options);
}
getTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string>, forceRefresh: boolean): SortedReadonlyArray<string> {
enqueueInstallTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string>, forceRefresh: boolean) {
const typeAcquisition = project.getTypeAcquisition();
if (!typeAcquisition || !typeAcquisition.enable) {
return <any>emptyArray;
return;
}
const entry = this.perProjectCache.get(project.getProjectName());
const result: SortedReadonlyArray<string> = entry ? entry.typings : <any>emptyArray;
if (forceRefresh ||
!entry ||
typeAcquisitionChanged(typeAcquisition, entry.typeAcquisition) ||
@ -113,28 +113,25 @@ namespace ts.server {
this.perProjectCache.set(project.getProjectName(), {
compilerOptions: project.getCompilationSettings(),
typeAcquisition,
typings: result,
typings: entry ? entry.typings : emptyArray,
unresolvedImports,
poisoned: true
});
// something has been changed, issue a request to update typings
this.installer.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
}
return result;
}
updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>, newTypings: string[]) {
const typings = toSortedArray(newTypings);
this.perProjectCache.set(projectName, {
compilerOptions,
typeAcquisition,
typings: toSortedArray(newTypings),
typings,
unresolvedImports,
poisoned: false
});
}
deleteTypingsForProject(projectName: string) {
this.perProjectCache.delete(projectName);
return !typeAcquisition || !typeAcquisition.enable ? emptyArray : typings;
}
onProjectClosed(project: Project) {

View file

@ -64,13 +64,31 @@ namespace ts.server.typingsInstaller {
onRequestCompleted: RequestCompletedAction;
}
function isPackageOrBowerJson(fileName: string) {
const base = getBaseFileName(fileName);
return base === "package.json" || base === "bower.json";
}
function getDirectoryExcludingNodeModulesOrBowerComponents(f: string) {
const indexOfNodeModules = f.indexOf("/node_modules/");
const indexOfBowerComponents = f.indexOf("/bower_components/");
const subStrLength = indexOfNodeModules === -1 || indexOfBowerComponents === -1 ?
Math.max(indexOfNodeModules, indexOfBowerComponents) :
Math.min(indexOfNodeModules, indexOfBowerComponents);
return subStrLength === -1 ? f : f.substr(0, subStrLength);
}
type ProjectWatchers = Map<FileWatcher> & { isInvoked?: boolean; };
export abstract class TypingsInstaller {
private readonly packageNameToTypingLocation: Map<JsTyping.CachedTyping> = createMap<JsTyping.CachedTyping>();
private readonly missingTypingsSet: Map<true> = createMap<true>();
private readonly knownCachesSet: Map<true> = createMap<true>();
private readonly projectWatchers = createMap<Map<FileWatcher>>();
private readonly projectWatchers = createMap<ProjectWatchers>();
private safeList: JsTyping.SafeList | undefined;
readonly pendingRunRequests: PendingRequest[] = [];
private readonly toCanonicalFileName: GetCanonicalFileName;
private readonly globalCacheCanonicalPackageJsonPath: string;
private installRunCount = 1;
private inFlightRequestCount = 0;
@ -84,6 +102,8 @@ namespace ts.server.typingsInstaller {
private readonly typesMapLocation: Path,
private readonly throttleLimit: number,
protected readonly log = nullLog) {
this.toCanonicalFileName = createGetCanonicalFileName(installTypingHost.useCaseSensitiveFileNames);
this.globalCacheCanonicalPackageJsonPath = combinePaths(this.toCanonicalFileName(globalCachePath), "package.json");
if (this.log.isEnabled()) {
this.log.writeLine(`Global cache location '${globalCachePath}', safe file path '${safeListPath}', types map path ${typesMapLocation}`);
}
@ -145,7 +165,7 @@ namespace ts.server.typingsInstaller {
}
// start watching files
this.watchFiles(req.projectName, discoverTypingsResult.filesToWatch);
this.watchFiles(req.projectName, discoverTypingsResult.filesToWatch, req.projectRootPath);
// install typings
if (discoverTypingsResult.newTypingNames.length) {
@ -365,7 +385,7 @@ namespace ts.server.typingsInstaller {
}
}
private watchFiles(projectName: string, files: string[]) {
private watchFiles(projectName: string, files: string[], projectRootPath: Path) {
if (!files.length) {
// shut down existing watchers
this.closeWatchers(projectName);
@ -373,43 +393,104 @@ namespace ts.server.typingsInstaller {
}
let watchers = this.projectWatchers.get(projectName);
const toRemove = createMap<FileWatcher>();
if (!watchers) {
watchers = createMap();
this.projectWatchers.set(projectName, watchers);
}
else {
copyEntries(watchers, toRemove);
}
// handler should be invoked once for the entire set of files since it will trigger full rediscovery of typings
let isInvoked = false;
watchers.isInvoked = false;
const isLoggingEnabled = this.log.isEnabled();
mutateMap(
watchers,
arrayToSet(files),
{
// Watch the missing files
createNewValue: file => {
if (isLoggingEnabled) {
this.log.writeLine(`FileWatcher:: Added:: WatchInfo: ${file}`);
}
const watcher = this.installTypingHost.watchFile(file, (f, eventKind) => {
if (isLoggingEnabled) {
this.log.writeLine(`FileWatcher:: Triggered with ${f} eventKind: ${FileWatcherEventKind[eventKind]}:: WatchInfo: ${file}:: handler is already invoked '${isInvoked}'`);
}
if (!isInvoked) {
this.sendResponse({ projectName, kind: ActionInvalidate });
isInvoked = true;
}
}, /*pollingInterval*/ 2000);
return isLoggingEnabled ? {
close: () => {
this.log.writeLine(`FileWatcher:: Closed:: WatchInfo: ${file}`);
}
} : watcher;
},
// Files that are no longer missing (e.g. because they are no longer required)
// should no longer be watched.
onDeleteValue: closeFileWatcher
const createProjectWatcher = (path: string, createWatch: (path: string) => FileWatcher) => {
toRemove.delete(path);
if (watchers.has(path)) {
return;
}
);
watchers.set(path, createWatch(path));
};
const createProjectFileWatcher = (file: string): FileWatcher => {
if (isLoggingEnabled) {
this.log.writeLine(`FileWatcher:: Added:: WatchInfo: ${file}`);
}
const watcher = this.installTypingHost.watchFile(file, (f, eventKind) => {
if (isLoggingEnabled) {
this.log.writeLine(`FileWatcher:: Triggered with ${f} eventKind: ${FileWatcherEventKind[eventKind]}:: WatchInfo: ${file}:: handler is already invoked '${watchers.isInvoked}'`);
}
if (!watchers.isInvoked) {
watchers.isInvoked = true;
this.sendResponse({ projectName, kind: ActionInvalidate });
}
}, /*pollingInterval*/ 2000);
return isLoggingEnabled ? {
close: () => {
this.log.writeLine(`FileWatcher:: Closed:: WatchInfo: ${file}`);
watcher.close();
}
} : watcher;
};
const createProjectDirectoryWatcher = (dir: string): FileWatcher => {
if (isLoggingEnabled) {
this.log.writeLine(`DirectoryWatcher:: Added:: WatchInfo: ${dir} recursive`);
}
const watcher = this.installTypingHost.watchDirectory(dir, f => {
if (isLoggingEnabled) {
this.log.writeLine(`DirectoryWatcher:: Triggered with ${f} :: WatchInfo: ${dir} recursive :: handler is already invoked '${watchers.isInvoked}'`);
}
if (watchers.isInvoked) {
return;
}
f = this.toCanonicalFileName(f);
if (f !== this.globalCacheCanonicalPackageJsonPath && isPackageOrBowerJson(f)) {
watchers.isInvoked = true;
this.sendResponse({ projectName, kind: ActionInvalidate });
}
}, /*recursive*/ true);
return isLoggingEnabled ? {
close: () => {
this.log.writeLine(`DirectoryWatcher:: Closed:: WatchInfo: ${dir} recursive`);
watcher.close();
}
} : watcher;
};
// Create watches from list of files
for (const file of files) {
const filePath = this.toCanonicalFileName(file);
if (isPackageOrBowerJson(filePath)) {
// package.json or bower.json exists, watch the file to detect changes and update typings
createProjectWatcher(filePath, createProjectFileWatcher);
continue;
}
// path in projectRoot, watch project root
if (containsPath(projectRootPath, filePath, projectRootPath, !this.installTypingHost.useCaseSensitiveFileNames)) {
createProjectWatcher(projectRootPath, createProjectDirectoryWatcher);
continue;
}
// path in global cache, watch global cache
if (containsPath(this.globalCachePath, filePath, projectRootPath, !this.installTypingHost.useCaseSensitiveFileNames)) {
createProjectWatcher(this.globalCachePath, createProjectDirectoryWatcher);
continue;
}
// Get path without node_modules and bower_components
createProjectWatcher(getDirectoryExcludingNodeModulesOrBowerComponents(getDirectoryPath(filePath)), createProjectDirectoryWatcher);
}
// Remove unused watches
toRemove.forEach((watch, path) => {
watch.close();
watchers.delete(path);
});
}
private createSetTypings(request: DiscoverTypings, typings: string[]): SetTypings {

View file

@ -34,13 +34,14 @@ namespace ts.codefix {
case SyntaxKind.VariableDeclaration:
precedingNode = ctorDeclaration.parent.parent;
newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration as VariableDeclaration);
if ((<VariableDeclarationList>ctorDeclaration.parent).declarations.length === 1) {
copyComments(precedingNode, newClassDeclaration, sourceFile);
deleteNode(precedingNode);
}
else {
deleteNode(ctorDeclaration, /*inList*/ true);
}
newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration as VariableDeclaration);
break;
}

View file

@ -114,8 +114,8 @@ namespace ts.codefix {
return false;
}
case SyntaxKind.BinaryExpression: {
const { left, operatorToken, right } = expression as BinaryExpression;
return operatorToken.kind === SyntaxKind.EqualsToken && convertAssignment(sourceFile, checker, statement as ExpressionStatement, left, right, changes, exports);
const { operatorToken } = expression as BinaryExpression;
return operatorToken.kind === SyntaxKind.EqualsToken && convertAssignment(sourceFile, checker, expression as BinaryExpression, changes, exports);
}
}
}
@ -130,23 +130,23 @@ namespace ts.codefix {
let foundImport = false;
const newNodes = flatMap(declarationList.declarations, decl => {
const { name, initializer } = decl;
if (isExportsOrModuleExportsOrAlias(sourceFile, initializer)) {
// `const alias = module.exports;` can be removed.
foundImport = true;
return [];
}
if (isRequireCall(initializer, /*checkArgumentIsStringLiteralLike*/ true)) {
foundImport = true;
return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target);
}
else if (isPropertyAccessExpression(initializer) && isRequireCall(initializer.expression, /*checkArgumentIsStringLiteralLike*/ true)) {
foundImport = true;
return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers);
}
else {
// Move it out to its own variable statement.
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([decl], declarationList.flags));
if (initializer) {
if (isExportsOrModuleExportsOrAlias(sourceFile, initializer)) {
// `const alias = module.exports;` can be removed.
foundImport = true;
return [];
}
else if (isRequireCall(initializer, /*checkArgumentIsStringLiteralLike*/ true)) {
foundImport = true;
return convertSingleImport(sourceFile, name, initializer.arguments[0], changes, checker, identifiers, target);
}
else if (isPropertyAccessExpression(initializer) && isRequireCall(initializer.expression, /*checkArgumentIsStringLiteralLike*/ true)) {
foundImport = true;
return convertPropertyAccessImport(name, initializer.name.text, initializer.expression.arguments[0], identifiers);
}
}
// Move it out to its own variable statement. (This will not be used if `!foundImport`)
return createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([decl], declarationList.flags));
});
if (foundImport) {
// useNonAdjustedEndPosition to ensure we don't eat the newline after the statement.
@ -177,12 +177,11 @@ namespace ts.codefix {
function convertAssignment(
sourceFile: SourceFile,
checker: TypeChecker,
statement: ExpressionStatement,
left: Expression,
right: Expression,
assignment: BinaryExpression,
changes: textChanges.ChangeTracker,
exports: ExportRenames,
): ModuleExportsChanged {
const { left, right } = assignment;
if (!isPropertyAccessExpression(left)) {
return false;
}
@ -190,7 +189,7 @@ namespace ts.codefix {
if (isExportsOrModuleExportsOrAlias(sourceFile, left)) {
if (isExportsOrModuleExportsOrAlias(sourceFile, right)) {
// `const alias = module.exports;` or `module.exports = alias;` can be removed.
changes.deleteNode(sourceFile, statement);
changes.deleteNode(sourceFile, assignment.parent);
}
else {
let newNodes = isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right) : undefined;
@ -198,12 +197,12 @@ namespace ts.codefix {
if (!newNodes) {
([newNodes, changedToDefaultExport] = convertModuleExportsToExportDefault(right, checker));
}
changes.replaceNodeWithNodes(sourceFile, statement, newNodes);
changes.replaceNodeWithNodes(sourceFile, assignment.parent, newNodes);
return changedToDefaultExport;
}
}
else if (isExportsOrModuleExportsOrAlias(sourceFile, left.expression)) {
convertNamedExport(sourceFile, statement, left.name, right, changes, exports);
convertNamedExport(sourceFile, assignment as BinaryExpression & { left: PropertyAccessExpression }, changes, exports);
}
return false;
@ -223,7 +222,7 @@ namespace ts.codefix {
case SyntaxKind.SpreadAssignment:
return undefined;
case SyntaxKind.PropertyAssignment:
return !isIdentifier(prop.name) ? undefined : convertExportsDotXEquals(prop.name.text, prop.initializer);
return !isIdentifier(prop.name) ? undefined : convertExportsDotXEquals_replaceNode(prop.name.text, prop.initializer);
case SyntaxKind.MethodDeclaration:
return !isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [createToken(SyntaxKind.ExportKeyword)], prop);
default:
@ -234,14 +233,12 @@ namespace ts.codefix {
function convertNamedExport(
sourceFile: SourceFile,
statement: Statement,
propertyName: Identifier,
right: Expression,
assignment: BinaryExpression & { left: PropertyAccessExpression },
changes: textChanges.ChangeTracker,
exports: ExportRenames,
): void {
// If "originalKeywordKind" was set, this is e.g. `exports.
const { text } = propertyName;
const { text } = assignment.left.name;
const rename = exports.get(text);
if (rename !== undefined) {
/*
@ -249,13 +246,13 @@ namespace ts.codefix {
export { _class as class };
*/
const newNodes = [
makeConst(/*modifiers*/ undefined, rename, right),
makeConst(/*modifiers*/ undefined, rename, assignment.right),
makeExportDeclaration([createExportSpecifier(rename, text)]),
];
changes.replaceNodeWithNodes(sourceFile, statement, newNodes);
changes.replaceNodeWithNodes(sourceFile, assignment.parent, newNodes);
}
else {
changes.replaceNode(sourceFile, statement, convertExportsDotXEquals(text, right));
convertExportsPropertyAssignment(assignment, sourceFile, changes);
}
}
@ -303,7 +300,27 @@ namespace ts.codefix {
return makeExportDeclaration([createExportSpecifier(/*propertyName*/ undefined, "default")], moduleSpecifier);
}
function convertExportsDotXEquals(name: string | undefined, exported: Expression): Statement {
function convertExportsPropertyAssignment({ left, right, parent }: BinaryExpression & { left: PropertyAccessExpression }, sourceFile: SourceFile, changes: textChanges.ChangeTracker): void {
const name = left.name.text;
if ((isFunctionExpression(right) || isArrowFunction(right) || isClassExpression(right)) && (!right.name || right.name.text === name)) {
// `exports.f = function() {}` -> `export function f() {}` -- Replace `exports.f = ` with `export `, and insert the name after `function`.
changes.replaceRange(sourceFile, { pos: left.getStart(sourceFile), end: right.getStart(sourceFile) }, createToken(SyntaxKind.ExportKeyword), { suffix: " " });
if (!right.name) changes.insertName(sourceFile, right, name);
const semi = findChildOfKind(parent, SyntaxKind.SemicolonToken, sourceFile);
if (semi) changes.deleteNode(sourceFile, semi, { useNonAdjustedEndPosition: true });
}
else {
// `exports.f = function g() {}` -> `export const f = function g() {}` -- just replace `exports.` with `export const `
changes.replaceNodeRangeWithNodes(sourceFile, left.expression, findChildOfKind(left, SyntaxKind.DotToken, sourceFile)!,
[createToken(SyntaxKind.ExportKeyword), createToken(SyntaxKind.ConstKeyword)],
{ joiner: " ", suffix: " " });
}
}
// TODO: GH#22492 this will cause an error if a change has been made inside the body of the node.
function convertExportsDotXEquals_replaceNode(name: string | undefined, exported: Expression): Statement {
const modifiers = [createToken(SyntaxKind.ExportKeyword)];
switch (exported.kind) {
case SyntaxKind.FunctionExpression: {

View file

@ -1,35 +1,38 @@
/* @internal */
namespace ts.codefix {
const fixId = "forgottenThisPropertyAccess";
const errorCodes = [Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code];
const didYouMeanStaticMemberCode = Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code;
const errorCodes = [
Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code,
didYouMeanStaticMemberCode,
];
registerCodeFix({
errorCodes,
getCodeActions(context) {
const { sourceFile } = context;
const token = getNode(sourceFile, context.span.start);
if (!token) {
const info = getInfo(sourceFile, context.span.start, context.errorCode);
if (!info) {
return undefined;
}
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, token));
return [createCodeFixAction(fixId, changes, Diagnostics.Add_this_to_unresolved_variable, fixId, Diagnostics.Add_this_to_all_unresolved_variables_matching_a_member_name)];
const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, info));
return [createCodeFixAction(fixId, changes, [Diagnostics.Add_0_to_unresolved_variable, info.className || "this"], fixId, Diagnostics.Add_qualifier_to_all_unresolved_variables_matching_a_member_name)];
},
fixIds: [fixId],
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
doChange(changes, context.sourceFile, getNode(diag.file, diag.start!));
doChange(changes, context.sourceFile, getInfo(diag.file, diag.start!, diag.code));
}),
});
function getNode(sourceFile: SourceFile, pos: number): Identifier | undefined {
interface Info { readonly node: Identifier; readonly className: string | undefined; }
function getInfo(sourceFile: SourceFile, pos: number, diagCode: number): Info | undefined {
const node = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
return isIdentifier(node) ? node : undefined;
if (!isIdentifier(node)) return undefined;
return { node, className: diagCode === didYouMeanStaticMemberCode ? getContainingClass(node).name.text : undefined };
}
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Identifier | undefined): void {
if (!token) {
return;
}
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, { node, className }: Info): void {
// TODO (https://github.com/Microsoft/TypeScript/issues/21246): use shared helper
suppressLeadingAndTrailingTrivia(token);
changes.replaceNode(sourceFile, token, createPropertyAccess(createThis(), token));
suppressLeadingAndTrailingTrivia(node);
changes.replaceNode(sourceFile, node, createPropertyAccess(className ? createIdentifier(className) : createThis(), node));
}
}

View file

@ -127,7 +127,7 @@ namespace ts.codefix {
const classDeclaration = getClassLikeDeclarationOfSymbol(type.symbol);
if (!classDeclaration || hasModifier(classDeclaration, ModifierFlags.Abstract)) return undefined;
const constructorDeclaration = find<ClassElement, ConstructorDeclaration>(classDeclaration.members, (m): m is ConstructorDeclaration => isConstructorDeclaration(m) && !!m.body)!;
const constructorDeclaration = getFirstConstructorWithBody(classDeclaration);
if (constructorDeclaration && constructorDeclaration.parameters.length) return undefined;
return createNew(createIdentifier(type.symbol.name), /*typeArguments*/ undefined, /*argumentsArray*/ undefined);

View file

@ -5,6 +5,7 @@ namespace ts.codefix {
const fixIdDelete = "unusedIdentifier_delete";
const errorCodes = [
Diagnostics._0_is_declared_but_its_value_is_never_read.code,
Diagnostics._0_is_declared_but_never_used.code,
Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code,
Diagnostics.All_imports_in_import_declaration_are_unused.code,
];

View file

@ -1 +0,0 @@
// Please delete me later.

View file

@ -7,7 +7,8 @@ namespace ts.codefix {
Diagnostics.Cannot_find_name_0.code,
Diagnostics.Cannot_find_name_0_Did_you_mean_1.code,
Diagnostics.Cannot_find_namespace_0.code,
Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code
Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code,
Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here.code,
],
getCodeActions: getImportCodeActions,
// TODO: GH#20315
@ -39,7 +40,6 @@ namespace ts.codefix {
}
function convertToImportCodeFixContext(context: CodeFixContext, symbolToken: Node, symbolName: string): ImportCodeFixContext {
const useCaseSensitiveFileNames = context.host.useCaseSensitiveFileNames ? context.host.useCaseSensitiveFileNames() : false;
const { program } = context;
const checker = program.getTypeChecker();
@ -51,7 +51,7 @@ namespace ts.codefix {
checker,
compilerOptions: program.getCompilerOptions(),
cachedImportDeclarations: [],
getCanonicalFileName: createGetCanonicalFileName(useCaseSensitiveFileNames),
getCanonicalFileName: createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(context.host)),
symbolName,
symbolToken,
preferences: context.preferences,
@ -98,16 +98,21 @@ namespace ts.codefix {
symbolToken: Node | undefined,
preferences: UserPreferences,
): { readonly moduleSpecifier: string, readonly codeAction: CodeAction } {
const exportInfos = getAllReExportingModules(exportedSymbol, symbolName, checker, allSourceFiles);
const exportInfos = getAllReExportingModules(exportedSymbol, moduleSymbol, symbolName, sourceFile, checker, allSourceFiles);
Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol));
// We sort the best codefixes first, so taking `first` is best for completions.
const moduleSpecifier = first(getNewImportInfos(program, sourceFile, exportInfos, compilerOptions, getCanonicalFileName, host, preferences)).moduleSpecifier;
const ctx: ImportCodeFixContext = { host, program, checker, compilerOptions, sourceFile, formatContext, symbolName, getCanonicalFileName, symbolToken, preferences };
return { moduleSpecifier, codeAction: first(getCodeActionsForImport(exportInfos, ctx)) };
}
function getAllReExportingModules(exportedSymbol: Symbol, symbolName: string, checker: TypeChecker, allSourceFiles: ReadonlyArray<SourceFile>): ReadonlyArray<SymbolExportInfo> {
function getAllReExportingModules(exportedSymbol: Symbol, exportingModuleSymbol: Symbol, symbolName: string, sourceFile: SourceFile, checker: TypeChecker, allSourceFiles: ReadonlyArray<SourceFile>): ReadonlyArray<SymbolExportInfo> {
const result: SymbolExportInfo[] = [];
forEachExternalModule(checker, allSourceFiles, moduleSymbol => {
forEachExternalModule(checker, allSourceFiles, (moduleSymbol, moduleFile) => {
// Don't import from a re-export when looking "up" like to `./index` or `../index`.
if (moduleFile && moduleSymbol !== exportingModuleSymbol && startsWith(sourceFile.fileName, getDirectoryPath(moduleFile.fileName))) {
return;
}
for (const exported of checker.getExportsOfModule(moduleSymbol)) {
if (exported.escapedName === InternalSymbolName.Default || exported.name === symbolName && skipAlias(exported, checker) === exportedSymbol) {
const isDefaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol) === exported;
@ -119,6 +124,12 @@ namespace ts.codefix {
}
function getCodeActionsForImport(exportInfos: ReadonlyArray<SymbolExportInfo>, context: ImportCodeFixContext): CodeFixAction[] {
const result: CodeFixAction[] = [];
getCodeActionsForImport_separateExistingAndNew(exportInfos, context, result, result);
return result;
}
function getCodeActionsForImport_separateExistingAndNew(exportInfos: ReadonlyArray<SymbolExportInfo>, context: ImportCodeFixContext, useExisting: Push<CodeFixAction>, addNew: Push<CodeFixAction>): void {
const existingImports = flatMap(exportInfos, info =>
getImportDeclarations(info, context.checker, context.sourceFile, context.cachedImportDeclarations));
// It is possible that multiple import statements with the same specifier exist in the file.
@ -133,16 +144,18 @@ namespace ts.codefix {
// 1. change "member3" to "ns.member3"
// 2. add "member3" to the second import statement's import list
// and it is up to the user to decide which one fits best.
const useExistingImportActions = !context.symbolToken || !isIdentifier(context.symbolToken) ? emptyArray : mapDefined(existingImports, ({ declaration }) => {
const namespace = getNamespaceImportName(declaration);
if (namespace) {
const moduleSymbol = context.checker.getAliasedSymbol(context.checker.getSymbolAtLocation(namespace));
if (moduleSymbol && moduleSymbol.exports.has(escapeLeadingUnderscores(context.symbolName))) {
return getCodeActionForUseExistingNamespaceImport(namespace.text, context, context.symbolToken as Identifier);
if (context.symbolToken && isIdentifier(context.symbolToken)) {
for (const { declaration } of existingImports) {
const namespace = getNamespaceImportName(declaration);
if (namespace) {
const moduleSymbol = context.checker.getAliasedSymbol(context.checker.getSymbolAtLocation(namespace));
if (moduleSymbol && moduleSymbol.exports.has(escapeLeadingUnderscores(context.symbolName))) {
useExisting.push(getCodeActionForUseExistingNamespaceImport(namespace.text, context, context.symbolToken));
}
}
}
});
return [...useExistingImportActions, ...getCodeActionsForAddImport(exportInfos, context, existingImports)];
}
getCodeActionsForAddImport(exportInfos, context, existingImports, useExisting, addNew);
}
function getNamespaceImportName(declaration: AnyImportSyntax): Identifier | undefined {
@ -547,16 +560,13 @@ namespace ts.codefix {
return startsWith(path, "..");
}
function getRelativePath(path: string, directoryPath: string, getCanonicalFileName: GetCanonicalFileName) {
const relativePath = getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false);
return !pathIsRelative(relativePath) ? "./" + relativePath : relativePath;
}
function getCodeActionsForAddImport(
exportInfos: ReadonlyArray<SymbolExportInfo>,
ctx: ImportCodeFixContext,
existingImports: ReadonlyArray<ExistingImportInfo>,
): CodeFixAction[] {
useExisting: Push<CodeFixAction>,
addNew: Push<CodeFixAction>,
): void {
const fromExistingImport = firstDefined(existingImports, ({ declaration, importKind }) => {
if (declaration.kind === SyntaxKind.ImportDeclaration && declaration.importClause) {
const changes = tryUpdateExistingImport(ctx, isImportClause(declaration.importClause) && declaration.importClause || undefined, importKind);
@ -567,14 +577,17 @@ namespace ts.codefix {
}
});
if (fromExistingImport) {
return [fromExistingImport];
useExisting.push(fromExistingImport);
return;
}
const existingDeclaration = firstDefined(existingImports, newImportInfoFromExistingSpecifier);
const newImportInfos = existingDeclaration
? [existingDeclaration]
: getNewImportInfos(ctx.program, ctx.sourceFile, exportInfos, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host, ctx.preferences);
return newImportInfos.map(info => getCodeActionForNewImport(ctx, info));
for (const info of newImportInfos) {
addNew.push(getCodeActionForNewImport(ctx, info));
}
}
function newImportInfoFromExistingSpecifier({ declaration, importKind }: ExistingImportInfo): NewImportInfo | undefined {
@ -765,7 +778,12 @@ namespace ts.codefix {
}
});
return arrayFrom(flatMapIterator(originalSymbolToExportInfos.values(), exportInfos => getCodeActionsForImport(exportInfos, convertToImportCodeFixContext(context, symbolToken, symbolName))));
const addToExistingDeclaration: CodeFixAction[] = [];
const addNewDeclaration: CodeFixAction[] = [];
originalSymbolToExportInfos.forEach(exportInfos => {
getCodeActionsForImport_separateExistingAndNew(exportInfos, convertToImportCodeFixContext(context, symbolToken, symbolName), addToExistingDeclaration, addNewDeclaration);
});
return [...addToExistingDeclaration, ...addNewDeclaration];
}
function checkSymbolHasMeaning({ declarations }: Symbol, meaning: SemanticMeaning): boolean {

View file

@ -25,7 +25,7 @@ namespace ts.Completions {
const enum GlobalsSearch { Continue, Success, Fail }
export function getCompletionsAtPosition(host: LanguageServiceHost, program: Program, log: Log, sourceFile: SourceFile, position: number, preferences: UserPreferences): CompletionInfo | undefined {
export function getCompletionsAtPosition(host: LanguageServiceHost, program: Program, log: Log, sourceFile: SourceFile, position: number, preferences: UserPreferences, triggerCharacter: string | undefined): CompletionInfo | undefined {
const typeChecker = program.getTypeChecker();
const compilerOptions = program.getCompilerOptions();
if (isInReferenceComment(sourceFile, position)) {
@ -34,6 +34,7 @@ namespace ts.Completions {
}
const contextToken = findPrecedingToken(position, sourceFile);
if (triggerCharacter && !isValidTrigger(sourceFile, triggerCharacter, contextToken, position)) return undefined;
if (isInString(sourceFile, position, contextToken)) {
return !contextToken || !isStringLiteralLike(contextToken)
@ -46,7 +47,7 @@ namespace ts.Completions {
return getLabelCompletionAtPosition(contextToken.parent);
}
const completionData = getCompletionData(program, log, sourceFile, position, preferences);
const completionData = getCompletionData(program, log, sourceFile, position, preferences, /*detailsEntryId*/ undefined);
if (!completionData) {
return undefined;
}
@ -485,9 +486,9 @@ namespace ts.Completions {
previousToken: Node;
readonly isJsxInitializer: IsJsxInitializer;
}
function getSymbolCompletionFromEntryId(program: Program, log: Log, sourceFile: SourceFile, position: number, { name, source }: CompletionEntryIdentifier,
function getSymbolCompletionFromEntryId(program: Program, log: Log, sourceFile: SourceFile, position: number, entryId: CompletionEntryIdentifier,
): SymbolCompletion | { type: "request", request: Request } | { type: "none" } {
const completionData = getCompletionData(program, log, sourceFile, position, { includeCompletionsForModuleExports: true, includeCompletionsWithInsertText: true });
const completionData = getCompletionData(program, log, sourceFile, position, { includeCompletionsForModuleExports: true, includeCompletionsWithInsertText: true }, entryId);
if (!completionData) {
return { type: "none" };
}
@ -504,7 +505,9 @@ namespace ts.Completions {
return firstDefined<Symbol, SymbolCompletion>(symbols, (symbol): SymbolCompletion => { // TODO: Shouldn't need return type annotation (GH#12632)
const origin = symbolToOriginInfoMap[getSymbolId(symbol)];
const info = getCompletionEntryDisplayNameForSymbol(symbol, program.getCompilerOptions().target, origin, completionKind);
return info && info.name === name && getSourceFromOrigin(origin) === source ? { type: "symbol" as "symbol", symbol, location, symbolToOriginInfoMap, previousToken, isJsxInitializer } : undefined;
return info && info.name === entryId.name && getSourceFromOrigin(origin) === entryId.source
? { type: "symbol" as "symbol", symbol, location, symbolToOriginInfoMap, previousToken, isJsxInitializer }
: undefined;
}) || { type: "none" };
}
@ -531,6 +534,7 @@ namespace ts.Completions {
formatContext: formatting.FormatContext,
getCanonicalFileName: GetCanonicalFileName,
preferences: UserPreferences,
cancellationToken: CancellationToken,
): CompletionEntryDetails {
const typeChecker = program.getTypeChecker();
const compilerOptions = program.getCompilerOptions();
@ -541,7 +545,7 @@ namespace ts.Completions {
const stringLiteralCompletions = !contextToken || !isStringLiteralLike(contextToken)
? undefined
: getStringLiteralCompletionEntries(sourceFile, contextToken, position, typeChecker, compilerOptions, host);
return stringLiteralCompletions && stringLiteralCompletionDetails(name, contextToken, stringLiteralCompletions, sourceFile, typeChecker);
return stringLiteralCompletions && stringLiteralCompletionDetails(name, contextToken, stringLiteralCompletions, sourceFile, typeChecker, cancellationToken);
}
// Compute all the completion symbols again.
@ -563,7 +567,7 @@ namespace ts.Completions {
case "symbol": {
const { symbol, location, symbolToOriginInfoMap, previousToken } = symbolCompletion;
const { codeActions, sourceDisplay } = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, program, typeChecker, host, compilerOptions, sourceFile, previousToken, formatContext, getCanonicalFileName, program.getSourceFiles(), preferences);
return createCompletionDetailsForSymbol(symbol, typeChecker, sourceFile, location, codeActions, sourceDisplay);
return createCompletionDetailsForSymbol(symbol, typeChecker, sourceFile, location, cancellationToken, codeActions, sourceDisplay);
}
case "none":
// Didn't find a symbol with this name. See if we can find a keyword instead.
@ -571,12 +575,15 @@ namespace ts.Completions {
}
}
function createCompletionDetailsForSymbol(symbol: Symbol, checker: TypeChecker, sourceFile: SourceFile, location: Node, codeActions?: CodeAction[], sourceDisplay?: SymbolDisplayPart[]): CompletionEntryDetails {
const { displayParts, documentation, symbolKind, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, sourceFile, location, location, SemanticMeaning.All);
function createCompletionDetailsForSymbol(symbol: Symbol, checker: TypeChecker, sourceFile: SourceFile, location: Node, cancellationToken: CancellationToken, codeActions?: CodeAction[], sourceDisplay?: SymbolDisplayPart[]): CompletionEntryDetails {
const { displayParts, documentation, symbolKind, tags } =
checker.runWithCancellationToken(cancellationToken, checker =>
SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, sourceFile, location, location, SemanticMeaning.All)
);
return createCompletionDetails(symbol.name, SymbolDisplay.getSymbolModifiers(symbol), symbolKind, displayParts, documentation, tags, codeActions, sourceDisplay);
}
function stringLiteralCompletionDetails(name: string, location: Node, completion: StringLiteralCompletion, sourceFile: SourceFile, checker: TypeChecker): CompletionEntryDetails | undefined {
function stringLiteralCompletionDetails(name: string, location: Node, completion: StringLiteralCompletion, sourceFile: SourceFile, checker: TypeChecker, cancellationToken: CancellationToken): CompletionEntryDetails | undefined {
switch (completion.kind) {
case StringLiteralCompletionKind.Paths: {
const match = find(completion.paths, p => p.name === name);
@ -584,7 +591,7 @@ namespace ts.Completions {
}
case StringLiteralCompletionKind.Properties: {
const match = find(completion.symbols, s => s.name === name);
return match && createCompletionDetailsForSymbol(match, checker, sourceFile, location);
return match && createCompletionDetailsForSymbol(match, checker, sourceFile, location, cancellationToken);
}
case StringLiteralCompletionKind.Types:
return find(completion.types, t => t.value === name) ? createCompletionDetails(name, ScriptElementKindModifier.none, ScriptElementKind.typeElement, [textPart(name)]) : undefined;
@ -754,6 +761,7 @@ namespace ts.Completions {
sourceFile: SourceFile,
position: number,
preferences: Pick<UserPreferences, "includeCompletionsForModuleExports" | "includeCompletionsWithInsertText">,
detailsEntryId: CompletionEntryIdentifier | undefined,
): CompletionData | Request | undefined {
const typeChecker = program.getTypeChecker();
@ -1197,14 +1205,11 @@ namespace ts.Completions {
// If already using commonjs, don't introduce ES6.
if (sourceFile.commonJsModuleIndicator) return false;
// If some file is using ES6 modules, assume that it's OK to add more.
if (program.getSourceFiles().some(s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!s.externalModuleIndicator)) {
return true;
}
if (programContainsEs6Modules(program)) return true;
// For JS, stay on the safe side.
if (isSourceFileJavaScript(sourceFile)) return false;
// If module transpilation is enabled or we're targeting es6 or above, or not emitting, OK.
const compilerOptions = program.getCompilerOptions();
return !!compilerOptions.module || compilerOptions.target >= ScriptTarget.ES2015 || !!compilerOptions.noEmit;
return compilerOptionsIndicateEs6Modules(program.getCompilerOptions());
}
function isSnippetScope(scopeNode: Node): boolean {
@ -1301,6 +1306,11 @@ namespace ts.Completions {
const tokenTextLowerCase = tokenText.toLowerCase();
codefix.forEachExternalModuleToImportFrom(typeChecker, sourceFile, program.getSourceFiles(), moduleSymbol => {
// Perf -- ignore other modules if this is a request for details
if (detailsEntryId && detailsEntryId.source && stripQuotes(moduleSymbol.name) !== detailsEntryId.source) {
return;
}
for (let symbol of typeChecker.getExportsOfModule(moduleSymbol)) {
// Don't add a completion for a re-export, only for the original.
// The actual import fix might end up coming from a re-export -- we don't compute that until getting completion details.
@ -1319,7 +1329,7 @@ namespace ts.Completions {
}
const origin: SymbolOriginInfo = { type: "export", moduleSymbol, isDefaultExport };
if (stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) {
if (detailsEntryId || stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) {
symbols.push(symbol);
symbolToOriginInfoMap[getSymbolId(symbol)] = origin;
}
@ -2197,4 +2207,31 @@ namespace ts.Completions {
function hasIndexSignature(type: Type): boolean {
return !!type.getStringIndexType() || !!type.getNumberIndexType();
}
function isValidTrigger(sourceFile: SourceFile, triggerCharacter: string, contextToken: Node, position: number): boolean {
switch (triggerCharacter) {
case '"':
case "'":
case "`":
// Only automatically bring up completions if this is an opening quote.
return isStringLiteralOrTemplate(contextToken) && position === contextToken.getStart(sourceFile) + 1;
case "<":
// Opening JSX tag
return contextToken.kind === SyntaxKind.LessThanToken && contextToken.parent.kind !== SyntaxKind.BinaryExpression;
default:
return Debug.fail(triggerCharacter);
}
}
function isStringLiteralOrTemplate(node: Node): node is StringLiteralLike | TemplateExpression | TaggedTemplateExpression {
switch (node.kind) {
case SyntaxKind.StringLiteral:
case SyntaxKind.NoSubstitutionTemplateLiteral:
case SyntaxKind.TemplateExpression:
case SyntaxKind.TaggedTemplateExpression:
return true;
default:
return false;
}
}
}

View file

@ -45,7 +45,10 @@ namespace ts.FindAllReferences {
const checker = program.getTypeChecker();
return !referencedSymbols || !referencedSymbols.length ? undefined : mapDefined<SymbolAndEntries, ReferencedSymbol>(referencedSymbols, ({ definition, references }) =>
// Only include referenced symbols that have a valid definition.
definition && { definition: definitionToReferencedSymbolDefinitionInfo(definition, checker, node), references: references.map(toReferenceEntry) });
definition && {
definition: checker.runWithCancellationToken(cancellationToken, checker => definitionToReferencedSymbolDefinitionInfo(definition, checker, node)),
references: references.map(toReferenceEntry)
});
}
export function getImplementationsAtPosition(program: Program, cancellationToken: CancellationToken, sourceFiles: ReadonlyArray<SourceFile>, sourceFile: SourceFile, position: number): ImplementationLocation[] {
@ -130,8 +133,7 @@ namespace ts.FindAllReferences {
const { node, name, kind, displayParts } = info;
const sourceFile = node.getSourceFile();
const textSpan = getTextSpan(isComputedPropertyName(node) ? node.expression : node, sourceFile);
return { containerKind: ScriptElementKind.unknown, containerName: "", fileName: sourceFile.fileName, kind, name, textSpan, displayParts };
return { containerKind: ScriptElementKind.unknown, containerName: "", fileName: sourceFile.fileName, kind, name, textSpan: getTextSpan(isComputedPropertyName(node) ? node.expression : node, sourceFile), displayParts };
}
function getDefinitionKindAndDisplayParts(symbol: Symbol, checker: TypeChecker, node: Node): { displayParts: SymbolDisplayPart[], kind: ScriptElementKind } {
@ -148,21 +150,23 @@ namespace ts.FindAllReferences {
}
const { node, isInString } = entry;
const sourceFile = node.getSourceFile();
return {
fileName: node.getSourceFile().fileName,
textSpan: getTextSpan(node),
fileName: sourceFile.fileName,
textSpan: getTextSpan(node, sourceFile),
isWriteAccess: isWriteAccessForReference(node),
isDefinition: node.kind === SyntaxKind.DefaultKeyword
|| isAnyDeclarationName(node)
|| isLiteralComputedPropertyDeclarationName(node),
isInString
isInString,
};
}
function toImplementationLocation(entry: Entry, checker: TypeChecker): ImplementationLocation {
if (entry.type === "node") {
const { node } = entry;
return { textSpan: getTextSpan(node), fileName: node.getSourceFile().fileName, ...implementationKindDisplayParts(node, checker) };
const sourceFile = node.getSourceFile();
return { textSpan: getTextSpan(node, sourceFile), fileName: sourceFile.fileName, ...implementationKindDisplayParts(node, checker) };
}
else {
const { textSpan, fileName } = entry;
@ -199,17 +203,17 @@ namespace ts.FindAllReferences {
}
const { node, isInString } = entry;
const fileName = entry.node.getSourceFile().fileName;
const sourceFile = node.getSourceFile();
const writeAccess = isWriteAccessForReference(node);
const span: HighlightSpan = {
textSpan: getTextSpan(node),
textSpan: getTextSpan(node, sourceFile),
kind: writeAccess ? HighlightSpanKind.writtenReference : HighlightSpanKind.reference,
isInString
};
return { fileName, span };
return { fileName: sourceFile.fileName, span };
}
function getTextSpan(node: Node, sourceFile?: SourceFile): TextSpan {
function getTextSpan(node: Node, sourceFile: SourceFile): TextSpan {
let start = node.getStart(sourceFile);
let end = node.getEnd();
if (node.kind === SyntaxKind.StringLiteral) {
@ -424,7 +428,8 @@ namespace ts.FindAllReferences.Core {
readonly text: string;
readonly escapedText: __String;
/** Only set if `options.implementations` is true. These are the symbols checked to get the implementations of a property access. */
readonly parents: Symbol[] | undefined;
readonly parents: ReadonlyArray<Symbol> | undefined;
readonly allSearchSymbols: ReadonlyArray<Symbol>;
/**
* Whether a symbol is in the search set.
@ -500,14 +505,11 @@ namespace ts.FindAllReferences.Core {
// here appears to be intentional).
const {
text = stripQuotes(unescapeLeadingUnderscores((getLocalSymbolForExportDefault(symbol) || symbol).escapedName)),
allSearchSymbols,
allSearchSymbols = [symbol],
} = searchOptions;
const escapedText = escapeLeadingUnderscores(text);
const parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker);
return {
symbol, comingFrom, text, escapedText, parents,
includes: referenceSymbol => allSearchSymbols ? contains(allSearchSymbols, referenceSymbol) : referenceSymbol === symbol,
};
return { symbol, comingFrom, text, escapedText, parents, allSearchSymbols, includes: sym => contains(allSearchSymbols, sym) };
}
private readonly symbolIdToReferences: Entry[][] = [];
@ -534,13 +536,17 @@ namespace ts.FindAllReferences.Core {
}
// Source file ID → symbol ID → Whether the symbol has been searched for in the source file.
private readonly sourceFileToSeenSymbols: true[][] = [];
private readonly sourceFileToSeenSymbols: Map<true>[] = [];
/** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */
markSearchedSymbol(sourceFile: SourceFile, symbol: Symbol): boolean {
markSearchedSymbols(sourceFile: SourceFile, symbols: ReadonlyArray<Symbol>): boolean {
const sourceId = getNodeId(sourceFile);
const symbolId = getSymbolId(symbol);
const seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = []);
return !seenSymbols[symbolId] && (seenSymbols[symbolId] = true);
const seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = createMap<true>());
let anyNewSymbols = false;
for (const sym of symbols) {
anyNewSymbols = addToSeen(seenSymbols, getSymbolId(sym)) || anyNewSymbols;
}
return anyNewSymbols;
}
}
@ -552,7 +558,10 @@ namespace ts.FindAllReferences.Core {
if (singleReferences.length) {
const addRef = state.referenceAdder(exportSymbol);
for (const singleRef of singleReferences) {
addRef(singleRef);
// At `default` in `import { default as x }` or `export { default as x }`, do add a reference, but do not rename.
if (!(state.options.isForRename && (isExportSpecifier(singleRef.parent) || isImportSpecifier(singleRef.parent)) && singleRef.escapedText === InternalSymbolName.Default)) {
addRef(singleRef);
}
}
}
@ -704,9 +713,8 @@ namespace ts.FindAllReferences.Core {
export function isSymbolReferencedInFile(definition: Identifier, checker: TypeChecker, sourceFile: SourceFile) {
const symbol = checker.getSymbolAtLocation(definition);
if (!symbol) return true; // Be lenient with invalid code.
return getPossibleSymbolReferencePositions(sourceFile, symbol.name).some(position => {
const token = tryCast(getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true), isIdentifier);
if (!token || token === definition || token.escapedText !== definition.escapedText) return false;
return getPossibleSymbolReferenceNodes(sourceFile, symbol.name).some(token => {
if (!isIdentifier(token) || token === definition || token.escapedText !== definition.escapedText) return false;
const referenceSymbol = checker.getSymbolAtLocation(token);
return referenceSymbol === symbol
|| checker.getShorthandAssignmentValueSymbol(token.parent) === symbol
@ -805,7 +813,7 @@ namespace ts.FindAllReferences.Core {
* searchLocation: a node where the search value
*/
function getReferencesInContainer(container: Node, sourceFile: SourceFile, search: Search, state: State, addReferencesHere: boolean): void {
if (!state.markSearchedSymbol(sourceFile, search.symbol)) {
if (!state.markSearchedSymbols(sourceFile, search.allSearchSymbols)) {
return;
}
@ -885,7 +893,10 @@ namespace ts.FindAllReferences.Core {
}
if (!propertyName) {
addRef();
// Don't rename at `export { default } from "m";`. (but do continue to search for imports of the re-export)
if (!(state.options.isForRename && name.escapedText === InternalSymbolName.Default)) {
addRef();
}
}
else if (referenceLocation === propertyName) {
// For `export { foo as bar } from "baz"`, "`foo`" will be added from the singleReferences for import searches of the original export.
@ -1006,21 +1017,17 @@ namespace ts.FindAllReferences.Core {
function addClassStaticThisReferences(referenceLocation: Node, search: Search, state: State): void {
addReference(referenceLocation, search.symbol, state);
if (!state.options.isForRename && isClassLike(referenceLocation.parent)) {
Debug.assert(referenceLocation.parent.name === referenceLocation);
// This is the class declaration.
addStaticThisReferences(referenceLocation.parent, state.referenceAdder(search.symbol));
}
}
function addStaticThisReferences(classLike: ClassLikeDeclaration, pusher: (node: Node) => void): void {
const classLike = referenceLocation.parent;
if (state.options.isForRename || !isClassLike(classLike)) return;
Debug.assert(classLike.name === referenceLocation);
const addRef = state.referenceAdder(search.symbol);
for (const member of classLike.members) {
if (!(isMethodOrAccessor(member) && hasModifier(member, ModifierFlags.Static))) {
continue;
}
member.body.forEachChild(function cb(node) {
if (node.kind === SyntaxKind.ThisKeyword) {
pusher(node);
addRef(node);
}
else if (!isFunctionLike(node)) {
node.forEachChild(cb);
@ -1029,10 +1036,6 @@ namespace ts.FindAllReferences.Core {
}
}
function getPropertyAccessExpressionFromRightHandSide(node: Node): PropertyAccessExpression {
return isRightSideOfPropertyAccess(node) && <PropertyAccessExpression>node.parent;
}
/**
* `classSymbol` is the class where the constructor was defined.
* Reference the constructor and all calls to `new this()`.
@ -1104,69 +1107,37 @@ namespace ts.FindAllReferences.Core {
}
// If we got a type reference, try and see if the reference applies to any expressions that can implement an interface
const containingTypeReference = getContainingTypeReference(refNode);
if (containingTypeReference && state.markSeenContainingTypeReference(containingTypeReference)) {
const parent = containingTypeReference.parent;
if (hasType(parent) && parent.type === containingTypeReference && hasInitializer(parent) && isImplementationExpression(parent.initializer)) {
addReference(parent.initializer);
// Find the first node whose parent isn't a type node -- i.e., the highest type node.
const typeNode = findAncestor(refNode, a => !isQualifiedName(a.parent) && !isTypeNode(a.parent) && !isTypeElement(a.parent));
const typeHavingNode = typeNode.parent;
if (hasType(typeHavingNode) && typeHavingNode.type === typeNode && state.markSeenContainingTypeReference(typeHavingNode)) {
if (hasInitializer(typeHavingNode)) {
addIfImplementation(typeHavingNode.initializer);
}
else if (isFunctionLike(parent) && parent.type === containingTypeReference && (parent as FunctionLikeDeclaration).body) {
const body = (parent as FunctionLikeDeclaration).body;
else if (isFunctionLike(typeHavingNode) && (typeHavingNode as FunctionLikeDeclaration).body) {
const body = (typeHavingNode as FunctionLikeDeclaration).body;
if (body.kind === SyntaxKind.Block) {
forEachReturnStatement(<Block>body, returnStatement => {
if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) {
addReference(returnStatement.expression);
}
if (returnStatement.expression) addIfImplementation(returnStatement.expression);
});
}
else if (isImplementationExpression(body)) {
addReference(body);
else {
addIfImplementation(body);
}
}
else if (isAssertionExpression(parent) && isImplementationExpression(parent.expression)) {
addReference(parent.expression);
else if (isAssertionExpression(typeHavingNode)) {
addIfImplementation(typeHavingNode.expression);
}
}
function addIfImplementation(e: Expression): void {
if (isImplementationExpression(e)) addReference(e);
}
}
function getSymbolsForClassAndInterfaceComponents(type: UnionOrIntersectionType, result: Symbol[] = []): Symbol[] {
for (const componentType of type.types) {
if (componentType.symbol && componentType.symbol.getFlags() & (SymbolFlags.Class | SymbolFlags.Interface)) {
result.push(componentType.symbol);
}
if (componentType.isUnionOrIntersection()) {
getSymbolsForClassAndInterfaceComponents(componentType, result);
}
}
return result;
}
function getContainingTypeReference(node: Node): Node {
let topLevelTypeReference: Node;
while (node) {
if (isTypeNode(node)) {
topLevelTypeReference = node;
}
node = node.parent;
}
return topLevelTypeReference;
}
function getContainingClassIfInHeritageClause(node: Node): ClassLikeDeclaration {
if (node && node.parent) {
if (node.kind === SyntaxKind.ExpressionWithTypeArguments
&& node.parent.kind === SyntaxKind.HeritageClause
&& isClassLike(node.parent.parent)) {
return node.parent.parent;
}
else if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression) {
return getContainingClassIfInHeritageClause(node.parent);
}
}
return undefined;
function getContainingClassIfInHeritageClause(node: Node): ClassLikeDeclaration | InterfaceDeclaration {
return isIdentifier(node) || isPropertyAccessExpression(node) ? getContainingClassIfInHeritageClause(node.parent)
: isExpressionWithTypeArguments(node) ? tryCast(node.parent.parent, isClassLike) : undefined;
}
/**
@ -1461,7 +1432,7 @@ namespace ts.FindAllReferences.Core {
? rootSymbol && !(getCheckFlags(sym) & CheckFlags.Synthetic) ? rootSymbol : sym
: undefined,
/*allowBaseTypes*/ rootSymbol =>
!(search.parents && !some(search.parents, parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker))));
!(search.parents && !search.parents.some(parent => explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, checker))));
}
/** Gets all symbols for one property. Does not get symbols for every property. */
@ -1548,13 +1519,11 @@ namespace ts.FindAllReferences.Core {
* symbol may have a different parent symbol if the local type's symbol does not declare the property
* being accessed (i.e. it is declared in some parent class or interface)
*/
function getParentSymbolsOfPropertyAccess(location: Node, symbol: Symbol, checker: TypeChecker): Symbol[] | undefined {
const propertyAccessExpression = getPropertyAccessExpressionFromRightHandSide(location);
const localParentType = propertyAccessExpression && checker.getTypeAtLocation(propertyAccessExpression.expression);
return localParentType && localParentType.symbol && localParentType.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) && localParentType.symbol !== symbol.parent
? [localParentType.symbol]
: localParentType && localParentType.isUnionOrIntersection()
? getSymbolsForClassAndInterfaceComponents(localParentType)
: undefined;
function getParentSymbolsOfPropertyAccess(location: Node, symbol: Symbol, checker: TypeChecker): ReadonlyArray<Symbol> | undefined {
const propertyAccessExpression = isRightSideOfPropertyAccess(location) ? <PropertyAccessExpression>location.parent : undefined;
const lhsType = propertyAccessExpression && checker.getTypeAtLocation(propertyAccessExpression.expression);
const res = mapDefined(lhsType && (lhsType.isUnionOrIntersection() ? lhsType.types : lhsType.symbol === symbol.parent ? undefined : [lhsType]), t =>
t.symbol && t.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface) ? t.symbol : undefined);
return res.length === 0 ? undefined : res;
}
}

View file

@ -126,8 +126,8 @@ namespace ts.formatting {
rule("SpaceBetweenAsyncAndOpenParen", SyntaxKind.AsyncKeyword, SyntaxKind.OpenParenToken, [isArrowFunctionContext, isNonJsxSameLineTokenContext], RuleAction.Space),
rule("SpaceBetweenAsyncAndFunctionKeyword", SyntaxKind.AsyncKeyword, SyntaxKind.FunctionKeyword, [isNonJsxSameLineTokenContext], RuleAction.Space),
// template string
rule("NoSpaceBetweenTagAndTemplateString", SyntaxKind.Identifier, [SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], RuleAction.Delete),
// Template string
rule("NoSpaceBetweenTagAndTemplateString", [SyntaxKind.Identifier, SyntaxKind.CloseParenToken], [SyntaxKind.NoSubstitutionTemplateLiteral, SyntaxKind.TemplateHead], [isNonJsxSameLineTokenContext], RuleAction.Delete),
// JSX opening elements
rule("SpaceBeforeJsxAttribute", anyToken, SyntaxKind.Identifier, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], RuleAction.Space),

View file

@ -0,0 +1,68 @@
/* @internal */
namespace ts {
export function getEditsForFileRename(program: Program, oldFilePath: string, newFilePath: string, host: LanguageServiceHost, formatContext: formatting.FormatContext): ReadonlyArray<FileTextChanges> {
const pathUpdater = getPathUpdater(oldFilePath, newFilePath, host);
return textChanges.ChangeTracker.with({ host, formatContext }, changeTracker => {
updateTsconfigFiles(program, changeTracker, oldFilePath, newFilePath);
for (const { sourceFile, toUpdate } of getImportsToUpdate(program, oldFilePath)) {
const newPath = pathUpdater(isRef(toUpdate) ? toUpdate.fileName : toUpdate.text);
if (newPath !== undefined) {
const range = isRef(toUpdate) ? toUpdate : createStringRange(toUpdate, sourceFile);
changeTracker.replaceRangeWithText(sourceFile, range, isRef(toUpdate) ? newPath : removeFileExtension(newPath));
}
}
});
}
function updateTsconfigFiles(program: Program, changeTracker: textChanges.ChangeTracker, oldFilePath: string, newFilePath: string): void {
const configFile = program.getCompilerOptions().configFile;
const oldFile = getTsConfigPropArrayElementValue(configFile, "files", oldFilePath);
if (oldFile) {
changeTracker.replaceRangeWithText(configFile, createStringRange(oldFile, configFile), newFilePath);
}
}
interface ToUpdate {
readonly sourceFile: SourceFile;
readonly toUpdate: StringLiteralLike | FileReference;
}
function isRef(toUpdate: StringLiteralLike | FileReference): toUpdate is FileReference {
return "fileName" in toUpdate;
}
function getImportsToUpdate(program: Program, oldFilePath: string): ReadonlyArray<ToUpdate> {
const checker = program.getTypeChecker();
const result: ToUpdate[] = [];
for (const sourceFile of program.getSourceFiles()) {
for (const ref of sourceFile.referencedFiles) {
if (!program.getSourceFileFromReference(sourceFile, ref) && resolveTripleslashReference(ref.fileName, sourceFile.fileName) === oldFilePath) {
result.push({ sourceFile, toUpdate: ref });
}
}
for (const importStringLiteral of sourceFile.imports) {
// If it resolved to something already, ignore.
if (checker.getSymbolAtLocation(importStringLiteral)) continue;
const resolved = program.getResolvedModuleWithFailedLookupLocationsFromCache(importStringLiteral.text, sourceFile.fileName);
if (contains(resolved.failedLookupLocations, oldFilePath)) {
result.push({ sourceFile, toUpdate: importStringLiteral });
}
}
}
return result;
}
function getPathUpdater(oldFilePath: string, newFilePath: string, host: LanguageServiceHost): (oldPath: string) => string | undefined {
// Get the relative path from old to new location, and append it on to the end of imports and normalize.
const rel = getRelativePath(newFilePath, getDirectoryPath(oldFilePath), createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host)));
return oldPath => {
if (!pathIsRelative(oldPath)) return;
return ensurePathIsRelative(normalizePath(combinePaths(getDirectoryPath(oldPath), rel)));
};
}
function createStringRange(node: StringLiteralLike, sourceFile: SourceFileLike): TextRange {
return createTextRange(node.getStart(sourceFile) + 1, node.end - 1);
}
}

View file

@ -18,13 +18,7 @@ namespace ts.GoToDefinition {
}
const typeChecker = program.getTypeChecker();
const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node);
if (calledDeclaration) {
return [createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration)];
}
let symbol = typeChecker.getSymbolAtLocation(node);
const symbol = getSymbol(node, typeChecker);
// Could not find a symbol e.g. node is string or number keyword,
// or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
@ -32,15 +26,14 @@ namespace ts.GoToDefinition {
return getDefinitionInfoForIndexSignatures(node, typeChecker);
}
// If this is an alias, and the request came at the declaration location
// get the aliased symbol instead. This allows for goto def on an import e.g.
// import {A, B} from "mod";
// to jump to the implementation directly.
if (symbol.flags & SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
const aliased = typeChecker.getAliasedSymbol(symbol);
if (aliased.declarations) {
symbol = aliased;
}
const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node);
if (calledDeclaration) {
const sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration);
// For a function, if this is the original function definition, return just sigInfo.
// If this is the original constructor definition, parent is the class.
return typeChecker.getRootSymbols(symbol).some(s => calledDeclaration.symbol === s || calledDeclaration.symbol.parent === s)
? [sigInfo]
: [sigInfo, ...getDefinitionFromSymbol(typeChecker, symbol, node)];
}
// Because name in short-hand property assignment has two different meanings: property name and property value,
@ -50,16 +43,7 @@ namespace ts.GoToDefinition {
// assignment. This case and others are handled by the following code.
if (node.parent.kind === SyntaxKind.ShorthandPropertyAssignment) {
const shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
if (!shorthandSymbol) {
return [];
}
const shorthandDeclarations = shorthandSymbol.getDeclarations();
const shorthandSymbolKind = SymbolDisplay.getSymbolKind(typeChecker, shorthandSymbol, node);
const shorthandSymbolName = typeChecker.symbolToString(shorthandSymbol);
const shorthandContainerName = typeChecker.symbolToString(symbol.parent, node);
return map(shorthandDeclarations,
declaration => createDefinitionInfo(declaration, shorthandSymbolKind, shorthandSymbolName, shorthandContainerName));
return shorthandSymbol ? shorthandSymbol.declarations.map(decl => createDefinitionInfo(decl, typeChecker, shorthandSymbol, node)) : [];
}
// If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the
@ -167,6 +151,21 @@ namespace ts.GoToDefinition {
});
}
function getSymbol(node: Node, checker: TypeChecker): Symbol | undefined {
const symbol = checker.getSymbolAtLocation(node);
// If this is an alias, and the request came at the declaration location
// get the aliased symbol instead. This allows for goto def on an import e.g.
// import {A, B} from "mod";
// to jump to the implementation directly.
if (symbol && symbol.flags & SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
const aliased = checker.getAliasedSymbol(symbol);
if (aliased.declarations) {
return aliased;
}
}
return symbol;
}
// Go to the original declaration for cases:
//
// (1) when the aliased symbol was declared in the location(parent).
@ -191,8 +190,7 @@ namespace ts.GoToDefinition {
}
function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo[] {
const { symbolName, symbolKind, containerName } = getSymbolInfo(typeChecker, symbol, node);
return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(symbol.declarations, declaration => createDefinitionInfo(declaration, symbolKind, symbolName, containerName));
return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(symbol.declarations, declaration => createDefinitionInfo(declaration, typeChecker, symbol, node));
function getConstructSignatureDefinition(): DefinitionInfo[] | undefined {
// Applicable only if we are in a new expression, or we are on a constructor declaration
@ -213,33 +211,24 @@ namespace ts.GoToDefinition {
if (!signatureDeclarations) {
return undefined;
}
const declarations = signatureDeclarations.filter(selectConstructors ? isConstructorDeclaration : isSignatureDeclaration);
const declarations = signatureDeclarations.filter(selectConstructors ? isConstructorDeclaration : isFunctionLike);
return declarations.length
? [createDefinitionInfo(find(declarations, d => !!(<FunctionLikeDeclaration>d).body) || last(declarations), symbolKind, symbolName, containerName)]
? [createDefinitionInfo(find(declarations, d => !!(<FunctionLikeDeclaration>d).body) || last(declarations), typeChecker, symbol, node)]
: undefined;
}
}
function isSignatureDeclaration(node: Node): boolean {
switch (node.kind) {
case SyntaxKind.Constructor:
case SyntaxKind.ConstructSignature:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
return true;
default:
return false;
}
}
/** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */
function createDefinitionInfo(node: Declaration, symbolKind: ScriptElementKind, symbolName: string, containerName: string): DefinitionInfo {
return createDefinitionInfoFromName(getNameOfDeclaration(node) || node, symbolKind, symbolName, containerName);
function createDefinitionInfo(declaration: Declaration, checker: TypeChecker, symbol: Symbol, node: Node): DefinitionInfo {
const symbolName = checker.symbolToString(symbol); // Do not get scoped name, just the name of the symbol
const symbolKind = SymbolDisplay.getSymbolKind(checker, symbol, node);
const containerName = symbol.parent ? checker.symbolToString(symbol.parent, node) : "";
return createDefinitionInfoFromName(declaration, symbolKind, symbolName, containerName);
}
/** Creates a DefinitionInfo directly from the name of a declaration. */
function createDefinitionInfoFromName(name: Node, symbolKind: ScriptElementKind, symbolName: string, containerName: string): DefinitionInfo {
function createDefinitionInfoFromName(declaration: Declaration, symbolKind: ScriptElementKind, symbolName: string, containerName: string): DefinitionInfo {
const name = getNameOfDeclaration(declaration) || declaration;
const sourceFile = name.getSourceFile();
return {
fileName: sourceFile.fileName,
@ -251,26 +240,12 @@ namespace ts.GoToDefinition {
};
}
function getSymbolInfo(typeChecker: TypeChecker, symbol: Symbol, node: Node) {
return {
symbolName: typeChecker.symbolToString(symbol), // Do not get scoped name, just the name of the symbol
symbolKind: SymbolDisplay.getSymbolKind(typeChecker, symbol, node),
containerName: symbol.parent ? typeChecker.symbolToString(symbol.parent, node) : ""
};
}
function createDefinitionFromSignatureDeclaration(typeChecker: TypeChecker, decl: SignatureDeclaration): DefinitionInfo {
const { symbolName, symbolKind, containerName } = getSymbolInfo(typeChecker, decl.symbol, decl);
return createDefinitionInfo(decl, symbolKind, symbolName, containerName);
return createDefinitionInfo(decl, typeChecker, decl.symbol, decl);
}
export function findReferenceInPosition(refs: ReadonlyArray<FileReference>, pos: number): FileReference | undefined {
for (const ref of refs) {
if (ref.pos <= pos && pos <= ref.end) {
return ref;
}
}
return undefined;
return find(refs, ref => ref.pos <= pos && pos <= ref.end);
}
function getDefinitionInfoForFileReference(name: string, targetFileName: string): DefinitionInfo {
@ -298,13 +273,7 @@ namespace ts.GoToDefinition {
function tryGetSignatureDeclaration(typeChecker: TypeChecker, node: Node): SignatureDeclaration | undefined {
const callLike = getAncestorCallLikeExpression(node);
const signature = callLike && typeChecker.getResolvedSignature(callLike);
if (signature) {
const decl = signature.declaration;
if (decl && isSignatureDeclaration(decl)) {
return decl;
}
}
// Don't go to a function type, go to the value having that type.
return undefined;
return tryCast(signature && signature.declaration, (d): d is SignatureDeclaration => isFunctionLike(d) && !isFunctionTypeNode(d));
}
}

View file

@ -33,7 +33,7 @@ namespace ts.FindAllReferences {
interface AmbientModuleDeclaration extends ModuleDeclaration { body?: ModuleBlock; }
type SourceFileLike = SourceFile | AmbientModuleDeclaration;
// Identifier for the case of `const x = require("y")`.
type Importer = AnyImportOrReExport | Identifier;
type Importer = AnyImportOrReExport | ImportTypeNode | Identifier;
type ImporterOrCallExpression = Importer | CallExpression;
/** Returns import statements that directly reference the exporting module, and a list of files that may access the module through a namespace. */
@ -215,6 +215,10 @@ namespace ts.FindAllReferences {
return;
}
if (decl.kind === SyntaxKind.ImportType) {
return;
}
// Ignore if there's a grammar error
if (decl.moduleSpecifier.kind !== SyntaxKind.StringLiteral) {
return;
@ -250,7 +254,7 @@ namespace ts.FindAllReferences {
}
// 'default' might be accessed as a named import `{ default as foo }`.
if (!isForRename && exportKind === ExportKind.Default) {
if (exportKind === ExportKind.Default) {
searchForNamedImport(namedBindings as NamedImports | undefined);
}
}
@ -282,7 +286,9 @@ namespace ts.FindAllReferences {
if (propertyName) {
// This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference.
singleReferences.push(propertyName);
if (!isForRename) { // If renaming `foo`, don't touch `bar`, just `foo`.
// If renaming `{ foo as bar }`, don't touch `bar`, just `foo`.
// But do rename `foo` in ` { default as foo }` if that's the original export name.
if (!isForRename || name.escapedText === exportSymbol.escapedName) {
// Search locally for `bar`.
addSearch(name, checker.getSymbolAtLocation(name));
}

View file

@ -365,13 +365,10 @@ namespace ts.JsDoc {
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
return (<FunctionExpression>rightHandSide).parameters;
case SyntaxKind.ClassExpression:
for (const member of (<ClassExpression>rightHandSide).members) {
if (member.kind === SyntaxKind.Constructor) {
return (<ConstructorDeclaration>member).parameters;
}
}
break;
case SyntaxKind.ClassExpression: {
const ctr = find((rightHandSide as ClassExpression).members, isConstructorDeclaration);
return ctr && ctr.parameters;
}
}
return emptyArray;

View file

@ -21,7 +21,17 @@ namespace ts.OutliningElementsCollector {
if (span) out.push(span);
depthRemaining--;
n.forEachChild(walk);
if (isIfStatement(n) && n.elseStatement && isIfStatement(n.elseStatement)) {
// Consider an 'else if' to be on the same depth as the 'if'.
walk(n.expression);
walk(n.thenStatement);
depthRemaining++;
walk(n.elseStatement);
depthRemaining--;
}
else {
n.forEachChild(walk);
}
depthRemaining++;
});
}

View file

@ -12,20 +12,23 @@ namespace ts {
};
const importedFiles: FileReference[] = [];
let ambientExternalModules: { ref: FileReference, depth: number }[];
let lastToken: SyntaxKind;
let currentToken: SyntaxKind;
let braceNesting = 0;
// assume that text represent an external module if it contains at least one top level import/export
// ambient modules that are found inside external modules are interpreted as module augmentations
let externalModule = false;
function nextToken() {
const token = scanner.scan();
if (token === SyntaxKind.OpenBraceToken) {
lastToken = currentToken;
currentToken = scanner.scan();
if (currentToken === SyntaxKind.OpenBraceToken) {
braceNesting++;
}
else if (token === SyntaxKind.CloseBraceToken) {
else if (currentToken === SyntaxKind.CloseBraceToken) {
braceNesting--;
}
return token;
return currentToken;
}
function getFileReference() {
@ -77,6 +80,9 @@ namespace ts {
* Returns true if at least one token was consumed from the stream
*/
function tryConsumeImport(): boolean {
if (lastToken === SyntaxKind.DotToken) {
return false;
}
let token = scanner.getToken();
if (token === SyntaxKind.ImportKeyword) {
token = nextToken();
@ -293,6 +299,10 @@ namespace ts {
// export import i = require("mod")
// (for JavaScript files) require("mod")
// Do not look for:
// AnySymbol.import("mod")
// AnySymbol.nested.import("mod")
while (true) {
if (scanner.getToken() === SyntaxKind.EndOfFileToken) {
break;

View file

@ -4,17 +4,14 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
const actionDescription = Diagnostics.Generate_get_and_set_accessors.message;
registerRefactor(actionName, { getEditsForAction, getAvailableActions });
type AcceptedDeclaration = ParameterDeclaration | PropertyDeclaration | PropertyAssignment;
type AcceptedDeclaration = ParameterPropertyDeclaration | PropertyDeclaration | PropertyAssignment;
type AcceptedNameType = Identifier | StringLiteral;
type ContainerDeclaration = ClassLikeDeclaration | ObjectLiteralExpression;
interface DeclarationInfo {
interface Info {
container: ContainerDeclaration;
isStatic: boolean;
type: TypeNode | undefined;
}
interface Info extends DeclarationInfo {
declaration: AcceptedDeclaration;
fieldName: AcceptedNameType;
accessorName: AcceptedNameType;
@ -92,46 +89,6 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
return modifiers && createNodeArray(modifiers);
}
function getPropertyDeclarationInfo(propertyDeclaration: PropertyDeclaration): DeclarationInfo | undefined {
if (!isClassLike(propertyDeclaration.parent) || !propertyDeclaration.parent.members) return undefined;
return {
isStatic: hasStaticModifier(propertyDeclaration),
type: propertyDeclaration.type,
container: propertyDeclaration.parent
};
}
function getParameterPropertyDeclarationInfo(parameterDeclaration: ParameterDeclaration): DeclarationInfo | undefined {
if (!isClassLike(parameterDeclaration.parent.parent) || !parameterDeclaration.parent.parent.members) return undefined;
return {
isStatic: false,
type: parameterDeclaration.type,
container: parameterDeclaration.parent.parent
};
}
function getPropertyAssignmentDeclarationInfo(propertyAssignment: PropertyAssignment): DeclarationInfo | undefined {
return {
isStatic: false,
type: undefined,
container: propertyAssignment.parent
};
}
function getDeclarationInfo(declaration: AcceptedDeclaration) {
if (isPropertyDeclaration(declaration)) {
return getPropertyDeclarationInfo(declaration);
}
else if (isPropertyAssignment(declaration)) {
return getPropertyAssignmentDeclarationInfo(declaration);
}
else {
return getParameterPropertyDeclarationInfo(declaration);
}
}
function getConvertibleFieldAtPosition(file: SourceFile, startPosition: number): Info | undefined {
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
const declaration = findAncestor(node.parent, isAcceptedDeclaration);
@ -139,15 +96,17 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static;
if (!declaration || !isConvertableName(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined;
const info = getDeclarationInfo(declaration);
const fieldName = createPropertyName(getUniqueName(`_${declaration.name.text}`, file.text), declaration.name);
const accessorName = createPropertyName(declaration.name.text, declaration.name);
suppressLeadingAndTrailingTrivia(fieldName);
suppressLeadingAndTrailingTrivia(declaration);
return {
...info,
isStatic: hasStaticModifier(declaration),
type: getTypeAnnotationNode(declaration),
container: declaration.kind === SyntaxKind.Parameter ? declaration.parent.parent : declaration.parent,
declaration,
fieldName,
accessorName: createPropertyName(declaration.name.text, declaration.name)
accessorName,
};
}

View file

@ -1 +0,0 @@
// Please delete me later.

View file

@ -546,7 +546,6 @@ namespace ts {
public typeReferenceDirectives: FileReference[];
public syntacticDiagnostics: Diagnostic[];
public referenceDiagnostics: Diagnostic[];
public parseDiagnostics: Diagnostic[];
public bindDiagnostics: Diagnostic[];
@ -1128,7 +1127,6 @@ namespace ts {
let lastProjectVersion: string;
let lastTypesRootVersion = 0;
const useCaseSensitivefileNames = host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames();
const cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken());
const currentDirectory = host.getCurrentDirectory();
@ -1145,7 +1143,8 @@ namespace ts {
}
}
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitivefileNames);
const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host);
const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
function getValidSourceFile(fileName: string): SourceFile {
const sourceFile = program.getSourceFile(fileName);
@ -1202,7 +1201,7 @@ namespace ts {
getSourceFileByPath: getOrCreateSourceFileByPath,
getCancellationToken: () => cancellationToken,
getCanonicalFileName,
useCaseSensitiveFileNames: () => useCaseSensitivefileNames,
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
getNewLine: () => getNewLineCharacter(newSettings, () => getNewLineOrDefaultFromHost(host)),
getDefaultLibFileName: (options) => host.getDefaultLibFileName(options),
writeFile: noop,
@ -1409,7 +1408,8 @@ namespace ts {
log,
getValidSourceFile(fileName),
position,
fullPreferences);
fullPreferences,
options.triggerCharacter);
}
function getCompletionEntryDetails(fileName: string, position: number, name: string, formattingOptions: FormatCodeSettings | undefined, source: string | undefined, preferences: UserPreferences = defaultPreferences): CompletionEntryDetails {
@ -1423,7 +1423,9 @@ namespace ts {
host,
formattingOptions && formatting.getFormatContext(formattingOptions),
getCanonicalFileName,
preferences);
preferences,
cancellationToken,
);
}
function getCompletionEntrySymbol(fileName: string, position: number, name: string, source?: string): Symbol {
@ -1464,7 +1466,7 @@ namespace ts {
kind: ScriptElementKind.unknown,
kindModifiers: ScriptElementKindModifier.none,
textSpan: createTextSpanFromNode(node, sourceFile),
displayParts: typeToDisplayParts(typeChecker, type, getContainerNode(node)),
displayParts: typeChecker.runWithCancellationToken(cancellationToken, typeChecker => typeToDisplayParts(typeChecker, type, getContainerNode(node))),
documentation: type.symbol ? type.symbol.getDocumentationComment(typeChecker) : undefined,
tags: type.symbol ? type.symbol.getJsDocTags() : undefined
};
@ -1473,7 +1475,9 @@ namespace ts {
return undefined;
}
const { symbolKind, displayParts, documentation, tags } = SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(node), node);
const { symbolKind, displayParts, documentation, tags } = typeChecker.runWithCancellationToken(cancellationToken, typeChecker =>
SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, getContainerNode(node), node)
);
return {
kind: symbolKind,
kindModifiers: SymbolDisplay.getSymbolModifiers(symbol),
@ -1673,7 +1677,7 @@ namespace ts {
}
function getDocumentHighlights(fileName: string, position: number, filesToSearch: ReadonlyArray<string>): DocumentHighlights[] {
Debug.assert(contains(filesToSearch, fileName));
Debug.assert(filesToSearch.some(f => normalizePath(f) === fileName));
synchronizeHostData();
const sourceFilesToSearch = map(filesToSearch, f => Debug.assertDefined(program.getSourceFile(f)));
const sourceFile = getValidSourceFile(fileName);
@ -1950,6 +1954,10 @@ namespace ts {
return OrganizeImports.organizeImports(sourceFile, formatContext, host, program, preferences);
}
function getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray<FileTextChanges> {
return ts.getEditsForFileRename(getProgram(), oldFilePath, newFilePath, host, formatting.getFormatContext(formatOptions));
}
function applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
function applyCodeActionCommand(action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
function applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
@ -2250,6 +2258,7 @@ namespace ts {
getCombinedCodeFix,
applyCodeActionCommand,
organizeImports,
getEditsForFileRename,
getEmitOutput,
getNonBoundSourceFile,
getSourceFile,

View file

@ -912,7 +912,7 @@ namespace ts {
* to provide at the given source position and providing a member completion
* list if requested.
*/
public getCompletionsAtPosition(fileName: string, position: number, preferences: UserPreferences | undefined) {
public getCompletionsAtPosition(fileName: string, position: number, preferences: GetCompletionsAtPositionOptions | undefined) {
return this.forwardJSONCall(
`getCompletionsAtPosition('${fileName}', ${position}, ${preferences})`,
() => this.languageService.getCompletionsAtPosition(fileName, position, preferences)

View file

@ -41,16 +41,16 @@ namespace ts.SignatureHelp {
// We didn't have any sig help items produced by the TS compiler. If this is a JS
// file, then see if we can figure out anything better.
if (isSourceFileJavaScript(sourceFile)) {
return createJavaScriptSignatureHelpItems(argumentInfo, program);
return createJavaScriptSignatureHelpItems(argumentInfo, program, cancellationToken);
}
return undefined;
}
return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo, typeChecker);
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(candidates, resolvedSignature, argumentInfo, typeChecker));
}
function createJavaScriptSignatureHelpItems(argumentInfo: ArgumentListInfo, program: Program): SignatureHelpItems {
function createJavaScriptSignatureHelpItems(argumentInfo: ArgumentListInfo, program: Program, cancellationToken: CancellationToken): SignatureHelpItems {
if (argumentInfo.invocation.kind !== SyntaxKind.CallExpression) {
return undefined;
}
@ -76,7 +76,7 @@ namespace ts.SignatureHelp {
if (type) {
const callSignatures = type.getCallSignatures();
if (callSignatures && callSignatures.length) {
return createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, typeChecker);
return typeChecker.runWithCancellationToken(cancellationToken, typeChecker => createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, typeChecker));
}
}
}

View file

@ -5,8 +5,8 @@ namespace ts {
const checker = program.getDiagnosticsProducingTypeChecker();
const diags: Diagnostic[] = [];
if (sourceFile.commonJsModuleIndicator) {
diags.push(createDiagnosticForNode(sourceFile.commonJsModuleIndicator, Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module));
if (sourceFile.commonJsModuleIndicator && (programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions()))) {
diags.push(createDiagnosticForNode(getErrorNodeFromCommonJsIndicator(sourceFile.commonJsModuleIndicator), Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES6_module));
}
const isJsFile = isSourceFileJavaScript(sourceFile);
@ -61,4 +61,8 @@ namespace ts {
return undefined;
}
}
function getErrorNodeFromCommonJsIndicator(commonJsModuleIndicator: Node): Node {
return isBinaryExpression(commonJsModuleIndicator) ? commonJsModuleIndicator.left : commonJsModuleIndicator;
}
}

View file

@ -26,6 +26,15 @@ namespace ts.SymbolDisplay {
}
function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker: TypeChecker, symbol: Symbol, location: Node): ScriptElementKind {
const roots = typeChecker.getRootSymbols(symbol);
// If this is a method from a mapped type, leave as a method so long as it still has a call signature.
if (roots.length === 1
&& first(roots).flags & SymbolFlags.Method
// Ensure the mapped version is still a method, as opposed to `{ [K in keyof I]: number }`.
&& typeChecker.getTypeOfSymbolAtLocation(symbol, location).getNonNullableType().getCallSignatures().length !== 0) {
return ScriptElementKind.memberFunctionElement;
}
if (typeChecker.isUndefinedSymbol(symbol)) {
return ScriptElementKind.variableElement;
}
@ -125,6 +134,7 @@ namespace ts.SymbolDisplay {
let type: Type;
let printer: Printer;
let documentationFromAlias: SymbolDisplayPart[];
let tagsFromAlias: JSDocTagInfo[];
// Class at constructor site need to be shown as constructor apart from property,method, vars
if (symbolKind !== ScriptElementKind.unknown || symbolFlags & SymbolFlags.Class || symbolFlags & SymbolFlags.Alias) {
@ -178,7 +188,7 @@ namespace ts.SymbolDisplay {
}
else if (symbolFlags & SymbolFlags.Alias) {
symbolKind = ScriptElementKind.alias;
pushTypePart(symbolKind);
pushSymbolKind(symbolKind);
displayParts.push(spacePart());
if (useConstructSignatures) {
displayParts.push(keywordPart(SyntaxKind.NewKeyword));
@ -258,7 +268,7 @@ namespace ts.SymbolDisplay {
// Special case for class expressions because we would like to indicate that
// the class name is local to the class body (similar to function expression)
// (local class) class <className>
pushTypePart(ScriptElementKind.localClassElement);
pushSymbolKind(ScriptElementKind.localClassElement);
}
else {
// Class declaration has name which is not local.
@ -387,6 +397,7 @@ namespace ts.SymbolDisplay {
displayParts.push(...resolvedInfo.displayParts);
displayParts.push(lineBreakPart());
documentationFromAlias = resolvedInfo.documentation;
tagsFromAlias = resolvedInfo.tags;
}
}
}
@ -402,6 +413,9 @@ namespace ts.SymbolDisplay {
displayParts.push(spacePart());
displayParts.push(keywordPart((symbol.declarations[0] as ExportAssignment).isExportEquals ? SyntaxKind.EqualsToken : SyntaxKind.DefaultKeyword));
break;
case SyntaxKind.ExportSpecifier:
displayParts.push(keywordPart(SyntaxKind.ExportKeyword));
break;
default:
displayParts.push(keywordPart(SyntaxKind.ImportKeyword));
}
@ -512,6 +526,9 @@ namespace ts.SymbolDisplay {
if (documentation.length === 0 && documentationFromAlias) {
documentation = documentationFromAlias;
}
if (tags.length === 0 && tagsFromAlias) {
tags = tagsFromAlias;
}
return { displayParts, documentation, symbolKind, tags };
@ -531,7 +548,7 @@ namespace ts.SymbolDisplay {
function addAliasPrefixIfNecessary() {
if (alias) {
pushTypePart(ScriptElementKind.alias);
pushSymbolKind(ScriptElementKind.alias);
displayParts.push(spacePart());
}
}
@ -549,12 +566,16 @@ namespace ts.SymbolDisplay {
const fullSymbolDisplayParts = symbolToDisplayParts(typeChecker, symbolToDisplay, enclosingDeclaration || sourceFile, /*meaning*/ undefined,
SymbolFormatFlags.WriteTypeParametersOrArguments | SymbolFormatFlags.UseOnlyExternalAliasing | SymbolFormatFlags.AllowAnyNodeKind);
addRange(displayParts, fullSymbolDisplayParts);
if (symbol.flags & SymbolFlags.Optional) {
displayParts.push(punctuationPart(SyntaxKind.QuestionToken));
}
}
function addPrefixForAnyFunctionOrVar(symbol: Symbol, symbolKind: string) {
prefixNextMeaning();
if (symbolKind) {
pushTypePart(symbolKind);
pushSymbolKind(symbolKind);
if (symbol && !some(symbol.declarations, d => isArrowFunction(d) || (isFunctionExpression(d) || isClassExpression(d)) && !d.name)) {
displayParts.push(spacePart());
addFullSymbolName(symbol);
@ -562,7 +583,7 @@ namespace ts.SymbolDisplay {
}
}
function pushTypePart(symbolKind: string) {
function pushSymbolKind(symbolKind: string) {
switch (symbolKind) {
case ScriptElementKind.variableElement:
case ScriptElementKind.functionElement:

View file

@ -100,6 +100,10 @@ namespace ts.textChanges {
preserveLeadingWhitespace?: boolean;
}
export interface ReplaceWithMultipleNodesOptions extends InsertNodeOptions {
readonly joiner?: string;
}
enum ChangeKind {
Remove,
ReplaceWithSingleNode,
@ -130,7 +134,7 @@ namespace ts.textChanges {
interface ReplaceWithMultipleNodes extends BaseChange {
readonly kind: ChangeKind.ReplaceWithMultipleNodes;
readonly nodes: ReadonlyArray<Node>;
readonly options?: InsertNodeOptions;
readonly options?: ReplaceWithMultipleNodesOptions;
}
interface ChangeText extends BaseChange {
@ -208,8 +212,7 @@ namespace ts.textChanges {
export class ChangeTracker {
private readonly changes: Change[] = [];
private readonly deletedNodesInLists: true[] = []; // Stores ids of nodes in lists that we already deleted. Used to avoid deleting `, ` twice in `a, b`.
// Map from class id to nodes to insert at the start
private readonly nodesInsertedAtClassStarts = createMap<{ sourceFile: SourceFile, cls: ClassLikeDeclaration, members: ClassElement[] }>();
private readonly classesWithNodesInsertedAtStart = createMap<ClassDeclaration>(); // Set<ClassDeclaration> implemented as Map<node id, ClassDeclaration>
public static fromContext(context: TextChangesContext): ChangeTracker {
return new ChangeTracker(getNewLineOrDefaultFromHost(context.host, context.formatContext.options), context.formatContext);
@ -303,7 +306,7 @@ namespace ts.textChanges {
this.replaceRange(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNode, options);
}
private replaceRangeWithNodes(sourceFile: SourceFile, range: TextRange, newNodes: ReadonlyArray<Node>, options: InsertNodeOptions = {}) {
private replaceRangeWithNodes(sourceFile: SourceFile, range: TextRange, newNodes: ReadonlyArray<Node>, options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = {}) {
this.changes.push({ kind: ChangeKind.ReplaceWithMultipleNodes, sourceFile, range, options, nodes: newNodes });
return this;
}
@ -312,7 +315,7 @@ namespace ts.textChanges {
return this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, oldNode, oldNode, options), newNodes, options);
}
public replaceNodeRangeWithNodes(sourceFile: SourceFile, startNode: Node, endNode: Node, newNodes: ReadonlyArray<Node>, options: ChangeNodeOptions = useNonAdjustedPositions) {
public replaceNodeRangeWithNodes(sourceFile: SourceFile, startNode: Node, endNode: Node, newNodes: ReadonlyArray<Node>, options: ReplaceWithMultipleNodesOptions & ConfigurableStartEnd = useNonAdjustedPositions) {
return this.replaceRangeWithNodes(sourceFile, getAdjustedRange(sourceFile, startNode, endNode, options), newNodes, options);
}
@ -326,7 +329,7 @@ namespace ts.textChanges {
this.replaceRange(sourceFile, createTextRange(pos), newNode, options);
}
private insertNodesAt(sourceFile: SourceFile, pos: number, newNodes: ReadonlyArray<Node>, options: InsertNodeOptions = {}): void {
private insertNodesAt(sourceFile: SourceFile, pos: number, newNodes: ReadonlyArray<Node>, options: ReplaceWithMultipleNodesOptions = {}): void {
this.changes.push({ kind: ChangeKind.ReplaceWithMultipleNodes, sourceFile, options, nodes: newNodes, range: { pos, end: pos } });
}
@ -339,8 +342,7 @@ namespace ts.textChanges {
}
public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, blankLineBetween = false) {
const pos = getAdjustedStartPosition(sourceFile, before, {}, Position.Start);
return this.replaceRange(sourceFile, { pos, end: pos }, newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween));
this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, {}, Position.Start), newNode, this.getOptionsForInsertNodeBefore(before, blankLineBetween));
}
public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void {
@ -361,8 +363,12 @@ namespace ts.textChanges {
this.insertText(sourceFile, token.getStart(sourceFile), text);
}
public replaceRangeWithText(sourceFile: SourceFile, range: TextRange, text: string) {
this.changes.push({ kind: ChangeKind.Text, sourceFile, range, text });
}
private insertText(sourceFile: SourceFile, pos: number, text: string): void {
this.changes.push({ kind: ChangeKind.Text, sourceFile, range: { pos, end: pos }, text });
this.replaceRangeWithText(sourceFile, createTextRange(pos), text);
}
/** Prefer this over replacing a node with another that has a type annotation, as it avoids reformatting the other parts of the node. */
@ -435,21 +441,20 @@ namespace ts.textChanges {
}
public insertNodeAtClassStart(sourceFile: SourceFile, cls: ClassLikeDeclaration, newElement: ClassElement): void {
const firstMember = firstOrUndefined(cls.members);
if (!firstMember) {
const id = getNodeId(cls).toString();
const newMembers = this.nodesInsertedAtClassStarts.get(id);
if (newMembers) {
Debug.assert(newMembers.sourceFile === sourceFile && newMembers.cls === cls);
newMembers.members.push(newElement);
}
else {
this.nodesInsertedAtClassStarts.set(id, { sourceFile, cls, members: [newElement] });
const clsStart = cls.getStart(sourceFile);
let prefix = "";
let suffix = this.newLineCharacter;
if (addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(cls), cls)) {
prefix = this.newLineCharacter;
// For `class C {\n}`, don't add the trailing "\n"
if (cls.members.length === 0 && !(positionsAreOnSameLine as any)(...getClassBraceEnds(cls, sourceFile), sourceFile)) { // TODO: GH#4130 remove 'as any'
suffix = "";
}
}
else {
this.insertNodeBefore(sourceFile, firstMember, newElement);
}
const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options)
+ this.formatContext.options.indentSize;
this.insertNodeAt(sourceFile, cls.members.pos, newElement, { indentation, prefix, suffix });
}
public insertNodeAfter(sourceFile: SourceFile, after: Node, newNode: Node): this {
@ -483,6 +488,35 @@ namespace ts.textChanges {
return Debug.failBadSyntaxKind(node); // We haven't handled this kind of node yet -- add it
}
public insertName(sourceFile: SourceFile, node: FunctionExpression | ClassExpression | ArrowFunction, name: string): void {
Debug.assert(!node.name);
if (node.kind === SyntaxKind.ArrowFunction) {
const arrow = findChildOfKind(node, SyntaxKind.EqualsGreaterThanToken, sourceFile)!;
const lparen = findChildOfKind(node, SyntaxKind.OpenParenToken, sourceFile);
if (lparen) {
// `() => {}` --> `function f() {}`
this.insertNodesAt(sourceFile, lparen.getStart(sourceFile), [createToken(SyntaxKind.FunctionKeyword), createIdentifier(name)], { joiner: " " });
this.deleteNode(sourceFile, arrow);
}
else {
// `x => {}` -> `function f(x) {}`
this.insertText(sourceFile, first(node.parameters).getStart(sourceFile), `function ${name}(`);
// Replacing full range of arrow to get rid of the leading space -- replace ` =>` with `)`
this.replaceRange(sourceFile, arrow, createToken(SyntaxKind.CloseParenToken));
}
if (node.body.kind !== SyntaxKind.Block) {
// `() => 0` => `function f() { return 0; }`
this.insertNodesAt(sourceFile, node.body.getStart(sourceFile), [createToken(SyntaxKind.OpenBraceToken), createToken(SyntaxKind.ReturnKeyword)], { joiner: " ", suffix: " " });
this.insertNodesAt(sourceFile, node.body.end, [createToken(SyntaxKind.SemicolonToken), createToken(SyntaxKind.CloseBraceToken)], { joiner: " " });
}
}
else {
const pos = findChildOfKind(node, node.kind === SyntaxKind.FunctionExpression ? SyntaxKind.FunctionKeyword : SyntaxKind.ClassKeyword, sourceFile)!.end;
this.insertNodeAt(sourceFile, pos, createIdentifier(name), { prefix: " " });
}
}
/**
* This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range,
* i.e. arguments in arguments lists, parameters in parameter lists etc.
@ -601,12 +635,14 @@ namespace ts.textChanges {
return this;
}
private finishInsertNodeAtClassStart(): void {
this.nodesInsertedAtClassStarts.forEach(({ sourceFile, cls, members }) => {
const newCls = cls.kind === SyntaxKind.ClassDeclaration
? updateClassDeclaration(cls, cls.decorators, cls.modifiers, cls.name, cls.typeParameters, cls.heritageClauses, members)
: updateClassExpression(cls, cls.modifiers, cls.name, cls.typeParameters, cls.heritageClauses, members);
this.replaceNode(sourceFile, cls, newCls);
private finishClassesWithNodesInsertedAtStart(): void {
this.classesWithNodesInsertedAtStart.forEach(cls => {
const sourceFile = cls.getSourceFile();
const [openBraceEnd, closeBraceEnd] = getClassBraceEnds(cls, sourceFile);
// For `class C { }` remove the whitespace inside the braces.
if (positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) {
this.deleteRange(sourceFile, createTextRange(openBraceEnd, closeBraceEnd - 1));
}
});
}
@ -617,11 +653,15 @@ namespace ts.textChanges {
* so we can only call this once and can't get the non-formatted text separately.
*/
public getChanges(validate?: ValidateNonFormattedText): FileTextChanges[] {
this.finishInsertNodeAtClassStart();
this.finishClassesWithNodesInsertedAtStart();
return changesToText.getTextChangesFromChanges(this.changes, this.newLineCharacter, this.formatContext, validate);
}
}
function getClassBraceEnds(cls: ClassLikeDeclaration, sourceFile: SourceFile): [number, number] {
return [findChildOfKind(cls, SyntaxKind.OpenBraceToken, sourceFile).end, findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile).end];
}
export type ValidateNonFormattedText = (node: Node, text: string) => void;
namespace changesToText {
@ -652,7 +692,7 @@ namespace ts.textChanges {
const { options = {}, range: { pos } } = change;
const format = (n: Node) => getFormattedTextOfNode(n, sourceFile, pos, options, newLineCharacter, formatContext, validate);
const text = change.kind === ChangeKind.ReplaceWithMultipleNodes
? change.nodes.map(n => removeSuffix(format(n), newLineCharacter)).join(newLineCharacter)
? change.nodes.map(n => removeSuffix(format(n), newLineCharacter)).join(change.options.joiner || newLineCharacter)
: format(change.node);
// strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line
const noIndent = (options.preserveLeadingWhitespace || options.indentation !== undefined || getLineStartPositionForPosition(pos, sourceFile) === pos) ? text : text.replace(/^\s+/, "");

View file

@ -63,6 +63,7 @@
"navigateTo.ts",
"navigationBar.ts",
"organizeImports.ts",
"getEditsForFileRename.ts",
"outliningElementsCollector.ts",
"patternMatcher.ts",
"preProcess.ts",
@ -105,10 +106,8 @@
"codefixes/fixInvalidImportSyntax.ts",
"codefixes/fixStrictClassInitialization.ts",
"codefixes/useDefaultImport.ts",
"codefixes/fixes.ts",
"refactors/extractSymbol.ts",
"refactors/generateGetAccessorAndSetAccessor.ts",
"refactors/refactors.ts",
"sourcemaps.ts",
"services.ts",
"breakpoints.ts",

View file

@ -331,9 +331,10 @@ namespace ts {
applyCodeActionCommand(fileName: string, action: CodeActionCommand[]): Promise<ApplyCodeActionCommandResult[]>;
/** @deprecated `fileName` will be ignored */
applyCodeActionCommand(fileName: string, action: CodeActionCommand | CodeActionCommand[]): Promise<ApplyCodeActionCommandResult | ApplyCodeActionCommandResult[]>;
getApplicableRefactors(fileName: string, positionOrRaneg: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[];
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[];
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined;
organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray<FileTextChanges>;
getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray<FileTextChanges>;
getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput;
@ -354,8 +355,9 @@ namespace ts {
export type OrganizeImportsScope = CombinedCodeFixScope;
/** @deprecated Use UserPreferences */
export interface GetCompletionsAtPositionOptions extends UserPreferences {
/** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */
triggerCharacter?: string;
/** @deprecated Use includeCompletionsForModuleExports */
includeExternalModuleExports?: boolean;
/** @deprecated Use includeCompletionsWithInsertText */

View file

@ -1213,6 +1213,21 @@ namespace ts {
? isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined
: getTextOfIdentifierOrLiteral(name);
}
export function programContainsEs6Modules(program: Program): boolean {
return program.getSourceFiles().some(s => !s.isDeclarationFile && !program.isSourceFileFromExternalLibrary(s) && !!s.externalModuleIndicator);
}
export function compilerOptionsIndicateEs6Modules(compilerOptions: CompilerOptions): boolean {
return !!compilerOptions.module || compilerOptions.target >= ScriptTarget.ES2015 || !!compilerOptions.noEmit;
}
export function hostUsesCaseSensitiveFileNames(host: LanguageServiceHost): boolean {
return host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : false;
}
export function hostGetCanonicalFileName(host: LanguageServiceHost): GetCanonicalFileName {
return createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host));
}
}
// Display-part writer helpers

View file

@ -0,0 +1,21 @@
tests/cases/compiler/user.ts(3,5): error TS2322: Type '() => void' is not assignable to type 'string'.
tests/cases/compiler/user.ts(4,5): error TS2322: Type '() => void' is not assignable to type 'string'.
==== tests/cases/compiler/demo.d.ts (0 errors) ====
declare namespace demoNS {
function f(): void;
}
declare module 'demoModule' {
import alias = demoNS;
export = alias;
}
==== tests/cases/compiler/user.ts (2 errors) ====
import { f } from 'demoModule';
// Assign an incorrect type here to see the type of 'f'.
let x1: string = demoNS.f;
~~
!!! error TS2322: Type '() => void' is not assignable to type 'string'.
let x2: string = f;
~~
!!! error TS2322: Type '() => void' is not assignable to type 'string'.

View file

@ -0,0 +1,23 @@
//// [tests/cases/compiler/aliasDoesNotDuplicateSignatures.ts] ////
//// [demo.d.ts]
declare namespace demoNS {
function f(): void;
}
declare module 'demoModule' {
import alias = demoNS;
export = alias;
}
//// [user.ts]
import { f } from 'demoModule';
// Assign an incorrect type here to see the type of 'f'.
let x1: string = demoNS.f;
let x2: string = f;
//// [user.js]
"use strict";
exports.__esModule = true;
var demoModule_1 = require("demoModule");
// Assign an incorrect type here to see the type of 'f'.
var x1 = demoNS.f;
var x2 = demoModule_1.f;

View file

@ -0,0 +1,32 @@
=== tests/cases/compiler/demo.d.ts ===
declare namespace demoNS {
>demoNS : Symbol(demoNS, Decl(demo.d.ts, 0, 0))
function f(): void;
>f : Symbol(f, Decl(demo.d.ts, 0, 26))
}
declare module 'demoModule' {
>'demoModule' : Symbol('demoModule', Decl(demo.d.ts, 2, 1))
import alias = demoNS;
>alias : Symbol(alias, Decl(demo.d.ts, 3, 29))
>demoNS : Symbol(alias, Decl(demo.d.ts, 0, 0))
export = alias;
>alias : Symbol(alias, Decl(demo.d.ts, 3, 29))
}
=== tests/cases/compiler/user.ts ===
import { f } from 'demoModule';
>f : Symbol(f, Decl(user.ts, 0, 8))
// Assign an incorrect type here to see the type of 'f'.
let x1: string = demoNS.f;
>x1 : Symbol(x1, Decl(user.ts, 2, 3))
>demoNS.f : Symbol(f, Decl(demo.d.ts, 0, 26))
>demoNS : Symbol(demoNS, Decl(demo.d.ts, 0, 0))
>f : Symbol(f, Decl(demo.d.ts, 0, 26))
let x2: string = f;
>x2 : Symbol(x2, Decl(user.ts, 3, 3))
>f : Symbol(f, Decl(user.ts, 0, 8))

View file

@ -0,0 +1,32 @@
=== tests/cases/compiler/demo.d.ts ===
declare namespace demoNS {
>demoNS : typeof demoNS
function f(): void;
>f : () => void
}
declare module 'demoModule' {
>'demoModule' : typeof 'demoModule'
import alias = demoNS;
>alias : typeof alias
>demoNS : typeof alias
export = alias;
>alias : typeof alias
}
=== tests/cases/compiler/user.ts ===
import { f } from 'demoModule';
>f : () => void
// Assign an incorrect type here to see the type of 'f'.
let x1: string = demoNS.f;
>x1 : string
>demoNS.f : () => void
>demoNS : typeof demoNS
>f : () => void
let x2: string = f;
>x2 : string
>f : () => void

Some files were not shown because too many files have changed in this diff Show more