Merge branch 'master' into requireJson
This commit is contained in:
commit
579748bc2b
16
.gitmodules
vendored
16
.gitmodules
vendored
|
@ -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
|
||||
|
|
|
@ -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"]) {
|
|
@ -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;
|
||||
|
|
|
@ -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
1558
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -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",
|
||||
|
|
|
@ -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}`);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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] };
|
||||
}
|
||||
|
||||
|
|
1
scripts/types/ambient.d.ts
vendored
1
scripts/types/ambient.d.ts
vendored
|
@ -14,4 +14,3 @@ declare module "gulp-insert" {
|
|||
}
|
||||
|
||||
declare module "sorcery";
|
||||
declare module "travis-fold";
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
},
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace ts {
|
|||
value = node.right;
|
||||
}
|
||||
else {
|
||||
return value;
|
||||
return visitNode(value, visitor, isExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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[]) {
|
||||
|
|
|
@ -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")];
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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", () => {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
35
src/lib/es2015.core.d.ts
vendored
35
src/lib/es2015.core.d.ts
vendored
|
@ -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> {
|
||||
|
|
9
src/lib/es2015.promise.d.ts
vendored
9
src/lib/es2015.promise.d.ts
vendored
|
@ -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
21
src/lib/es5.d.ts
vendored
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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() };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
];
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
// Please delete me later.
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
68
src/services/getEditsForFileRename.ts
Normal file
68
src/services/getEditsForFileRename.ts
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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++;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
// Please delete me later.
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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+/, "");
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'.
|
23
tests/baselines/reference/aliasDoesNotDuplicateSignatures.js
Normal file
23
tests/baselines/reference/aliasDoesNotDuplicateSignatures.js
Normal 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;
|
|
@ -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))
|
||||
|
|
@ -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
Loading…
Reference in a new issue