Merge branch 'master' into AddVueSupport

This commit is contained in:
Armando Aguirre
2018-04-18 15:51:58 -07:00
81 changed files with 1099 additions and 581 deletions
+12
View File
@@ -18,7 +18,19 @@
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
+126 -131
View File
@@ -1,35 +1,27 @@
/// <reference path="scripts/types/ambient.d.ts" />
import * as cp from "child_process";
import * as path from "path";
import * as fs from "fs";
import child_process = require("child_process");
import originalGulp = require("gulp");
import helpMaker = require("gulp-help");
import runSequence = require("run-sequence");
import concat = require("gulp-concat");
import clone = require("gulp-clone");
import newer = require("gulp-newer");
import tsc = require("gulp-typescript");
declare module "gulp-typescript" {
interface Settings {
pretty?: boolean;
newLine?: string;
noImplicitThis?: boolean;
stripInternal?: boolean;
types?: string[];
}
}
import * as insert from "gulp-insert";
import * as sourcemaps from "gulp-sourcemaps";
import Q = require("q");
import del = require("del");
import mkdirP = require("mkdirp");
import minimist = require("minimist");
import browserify = require("browserify");
import through2 = require("through2");
import merge2 = require("merge2");
import * as os from "os";
import fold = require("travis-fold");
// @ts-check
const cp = require("child_process");
const path = require("path");
const fs = require("fs");
const child_process = require("child_process");
const originalGulp = require("gulp");
const helpMaker = require("gulp-help");
const runSequence = require("run-sequence");
const concat = require("gulp-concat");
const clone = require("gulp-clone");
const newer = require("gulp-newer");
const tsc = require("gulp-typescript");
const insert = require("gulp-insert");
const sourcemaps = require("gulp-sourcemaps");
const Q = require("q");
const del = require("del");
const mkdirP = require("mkdirp");
const minimist = require("minimist");
const browserify = require("browserify");
const through2 = require("through2");
const merge2 = require("merge2");
const os = require("os");
const fold = require("travis-fold");
const gulp = helpMaker(originalGulp);
Error.stackTraceLimit = 1000;
@@ -73,17 +65,26 @@ const cmdLineOptions = minimist(process.argv.slice(2), {
});
const noop = () => {}; // tslint:disable-line no-empty
function exec(cmd: string, args: string[], complete: () => void = noop, error: (e: any, status: number) => void = noop) {
/**
* @param {string} cmd
* @param {string[]} args
* @param {() => void} complete
* @param {(e: *, status: number) => void} error
*/
function exec(cmd, args, complete = noop, error = noop) {
console.log(`${cmd} ${args.join(" ")}`);
// TODO (weswig): Update child_process types to add windowsVerbatimArguments to the type definition
const subshellFlag = isWin ? "/c" : "-c";
const command = isWin ? [possiblyQuote(cmd), ...args] : [`${cmd} ${args.join(" ")}`];
const ex = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true } as any);
const ex = cp.spawn(isWin ? "cmd" : "/bin/sh", [subshellFlag, ...command], { stdio: "inherit", windowsVerbatimArguments: true });
ex.on("exit", (code) => code === 0 ? complete() : error(/*e*/ undefined, code));
ex.on("error", error);
}
function possiblyQuote(cmd: string) {
/**
* @param {string} cmd
*/
function possiblyQuote(cmd) {
return cmd.indexOf(" ") >= 0 ? `"${cmd}"` : cmd;
}
@@ -215,12 +216,17 @@ for (const i in libraryTargets) {
.pipe(gulp.dest(".")));
}
const configureNightlyJs = path.join(scriptsDirectory, "configureNightly.js");
const configureNightlyTs = path.join(scriptsDirectory, "configureNightly.ts");
const configurePreleleaseJs = path.join(scriptsDirectory, "configurePrerelease.js");
const configurePreleleaseTs = path.join(scriptsDirectory, "configurePrerelease.ts");
const packageJson = "package.json";
const versionFile = path.join(compilerDirectory, "core.ts");
function needsUpdate(source: string | string[], dest: string | string[]): boolean {
/**
* @param {string | string[]} source
* @param {string | string[]} dest
* @returns {boolean}
*/
function needsUpdate(source, dest) {
if (typeof source === "string" && typeof dest === "string") {
if (fs.existsSync(dest)) {
const {mtime: outTime} = fs.statSync(dest);
@@ -283,8 +289,13 @@ function needsUpdate(source: string | string[], dest: string | string[]): boolea
return true;
}
function getCompilerSettings(base: tsc.Settings, useBuiltCompiler?: boolean): tsc.Settings {
const copy: tsc.Settings = {};
/**
* @param {tsc.Settings} base
* @param {boolean=} useBuiltCompiler
* @returns {tsc.Settings}
*/
function getCompilerSettings(base, useBuiltCompiler) {
const copy = /** @type {tsc.Settings} */ ({});
for (const key in base) {
copy[key] = base[key];
}
@@ -293,32 +304,34 @@ function getCompilerSettings(base: tsc.Settings, useBuiltCompiler?: boolean): ts
}
copy.newLine = "lf";
if (useBuiltCompiler === true) {
copy.typescript = require("./built/local/typescript.js");
copy.typescript = /** @type {*} */ (require("./built/local/typescript.js"));
}
else if (useBuiltCompiler === false) {
copy.typescript = require("./lib/typescript.js");
copy.typescript = /** @type {*} */ (require("./lib/typescript.js"));
}
return copy;
}
gulp.task(configureNightlyJs, /*help*/ false, [], () => {
const settings: tsc.Settings = {
gulp.task(configurePreleleaseJs, /*help*/ false, [], () => {
/** @type {tsc.Settings} */
const settings = {
declaration: false,
removeComments: true,
noResolve: false,
stripInternal: false,
module: "commonjs"
};
return gulp.src(configureNightlyTs)
return gulp.src(configurePreleleaseTs)
.pipe(sourcemaps.init())
.pipe(tsc(settings))
.pipe(sourcemaps.write(path.dirname(configureNightlyJs)))
.pipe(gulp.dest(path.dirname(configureNightlyJs)));
.pipe(sourcemaps.write("."))
.pipe(gulp.dest("./scripts"));
});
// Nightly management tasks
gulp.task("configure-nightly", "Runs scripts/configureNightly.ts to prepare a build for nightly publishing", [configureNightlyJs], (done) => {
exec(host, [configureNightlyJs, packageJson, versionFile], done, done);
gulp.task("configure-nightly", "Runs scripts/configurePrerelease.ts to prepare a build for nightly publishing", [configurePreleleaseJs], (done) => {
exec(host, [configurePreleleaseJs, "dev", packageJson, versionFile], done, done);
});
gulp.task("publish-nightly", "Runs `npm publish --tag next` to create a new nightly build on npm", ["LKG"], () => {
return runSequence("clean", "useDebugMode", "runtests-parallel", (done) => {
@@ -331,7 +344,8 @@ const importDefinitelyTypedTestsJs = path.join(importDefinitelyTypedTestsDirecto
const importDefinitelyTypedTestsTs = path.join(importDefinitelyTypedTestsDirectory, "importDefinitelyTypedTests.ts");
gulp.task(importDefinitelyTypedTestsJs, /*help*/ false, [], () => {
const settings: tsc.Settings = getCompilerSettings({
/** @type {tsc.Settings} */
const settings = getCompilerSettings({
declaration: false,
removeComments: true,
noResolve: false,
@@ -362,20 +376,11 @@ const builtGeneratedDiagnosticMessagesJSON = path.join(builtLocalDirectory, "dia
// processDiagnosticMessages script
gulp.task(processDiagnosticMessagesJs, /*help*/ false, [], () => {
const settings: tsc.Settings = getCompilerSettings({
target: "es5",
declaration: false,
removeComments: true,
noResolve: false,
stripInternal: false,
outFile: processDiagnosticMessagesJs
}, /*useBuiltCompiler*/ false);
return gulp.src(processDiagnosticMessagesTs)
const diagsProject = tsc.createProject('./scripts/processDiagnosticMessages.tsconfig.json');
return diagsProject.src()
.pipe(newer(processDiagnosticMessagesJs))
.pipe(sourcemaps.init())
.pipe(tsc(settings))
.pipe(sourcemaps.write("."))
.pipe(gulp.dest("."));
.pipe(diagsProject())
.pipe(gulp.dest(scriptsDirectory));
});
// The generated diagnostics map; built for the compiler and for the "generate-diagnostics" task
@@ -402,7 +407,8 @@ const generateLocalizedDiagnosticMessagesJs = path.join(scriptsDirectory, "gener
const generateLocalizedDiagnosticMessagesTs = path.join(scriptsDirectory, "generateLocalizedDiagnosticMessages.ts");
gulp.task(generateLocalizedDiagnosticMessagesJs, /*help*/ false, [], () => {
const settings: tsc.Settings = getCompilerSettings({
/** @type {tsc.Settings} */
const settings = getCompilerSettings({
target: "es5",
declaration: false,
removeComments: true,
@@ -433,8 +439,12 @@ const nodePackageFile = path.join(builtLocalDirectory, "typescript.js");
const nodeDefinitionsFile = path.join(builtLocalDirectory, "typescript.d.ts");
const nodeStandaloneDefinitionsFile = path.join(builtLocalDirectory, "typescript_standalone.d.ts");
let copyrightContent: string;
function prependCopyright(outputCopyright: boolean = !useDebugMode) {
/** @type {string} */
let copyrightContent;
/**
* @param {boolean} outputCopyright
*/
function prependCopyright(outputCopyright = !useDebugMode) {
return insert.prepend(outputCopyright ? (copyrightContent || (copyrightContent = fs.readFileSync(copyright).toString())) : "");
}
@@ -526,9 +536,10 @@ const tsserverLibraryDefinitionFile = path.join(builtLocalDirectory, "tsserverli
gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile, typesMapJson], (done) => {
const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/ true));
const {js, dts}: { js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream } = serverLibraryProject.src()
/** @type {{ js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream }} */
const {js, dts} = serverLibraryProject.src()
.pipe(sourcemaps.init())
.pipe(newer(<any>{ dest: tsserverLibraryFile, extra: ["src/compiler/**/*.ts", "src/services/**/*.ts"] }))
.pipe(newer(/** @type {*} */({ dest: tsserverLibraryFile, extra: ["src/compiler/**/*.ts", "src/services/**/*.ts"] })))
.pipe(serverLibraryProject());
return merge2([
@@ -563,7 +574,8 @@ const specWord = path.join(docDirectory, "TypeScript Language Specification.docx
const specMd = path.join(docDirectory, "spec.md");
gulp.task(word2mdJs, /*help*/ false, [], () => {
const settings: tsc.Settings = getCompilerSettings({
/** @type {tsc.Settings} */
const settings = getCompilerSettings({
outFile: word2mdJs
}, /*useBuiltCompiler*/ false);
return gulp.src(word2mdTs)
@@ -642,7 +654,8 @@ function deleteTemporaryProjectOutput() {
return del(path.join(localBaseline, "projectOutput/"));
}
let savedNodeEnv: string;
/** @type {string} */
let savedNodeEnv;
function setNodeEnvToDevelopment() {
savedNodeEnv = process.env.NODE_ENV;
process.env.NODE_ENV = "development";
@@ -652,7 +665,12 @@ function restoreSavedNodeEnv() {
process.env.NODE_ENV = savedNodeEnv;
}
function runConsoleTests(defaultReporter: string, runInParallel: boolean, done: (e?: any) => void) {
/**
* @param {string} defaultReporter
* @param {boolean} runInParallel
* @param {(e?: any) => void} done
*/
function runConsoleTests(defaultReporter, runInParallel, done) {
const lintFlag = cmdLineOptions.lint;
cleanTestDirs((err) => {
if (err) { console.error(err); failWithStatus(err, 1); }
@@ -727,7 +745,11 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
}
});
function failWithStatus(err?: any, status?: number) {
/**
* @param {any=} err
* @param {number=} status
*/
function failWithStatus(err, status) {
if (err || status) {
process.exit(typeof status === "number" ? status : 2);
}
@@ -743,7 +765,11 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
}
}
function finish(error?: any, errorStatus?: number) {
/**
* @param {any=} error
* @param {number=} errorStatus
*/
function finish(error, errorStatus) {
restoreSavedNodeEnv();
deleteTestConfig().then(deleteTemporaryProjectOutput).then(() => {
if (error !== undefined || errorStatus !== undefined) {
@@ -773,7 +799,8 @@ gulp.task("runtests",
const nodeServerOutFile = "tests/webTestServer.js";
const nodeServerInFile = "tests/webTestServer.ts";
gulp.task(nodeServerOutFile, /*help*/ false, [servicesFile], () => {
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ true);
/** @type {tsc.Settings} */
const settings = getCompilerSettings({ module: "commonjs" }, /*useBuiltCompiler*/ true);
return gulp.src(nodeServerInFile)
.pipe(newer(nodeServerOutFile))
.pipe(sourcemaps.init())
@@ -782,16 +809,18 @@ gulp.task(nodeServerOutFile, /*help*/ false, [servicesFile], () => {
.pipe(gulp.dest(path.dirname(nodeServerOutFile)));
});
import convertMap = require("convert-source-map");
import sorcery = require("sorcery");
import Vinyl = require("vinyl");
const convertMap = require("convert-source-map");
const sorcery = require("sorcery");
const Vinyl = require("vinyl");
const bundlePath = path.resolve("built/local/bundle.js");
gulp.task("browserify", "Runs browserify on run.js to produce a file suitable for running tests in the browser", [servicesFile], (done) => {
const testProject = tsc.createProject("src/harness/tsconfig.json", getCompilerSettings({ outFile: bundlePath, inlineSourceMap: true }, /*useBuiltCompiler*/ true));
let originalMap: any;
let prebundledContent: string;
/** @type {*} */
let originalMap;
/** @type {string} */
let prebundledContent;
browserify(testProject.src()
.pipe(newer(bundlePath))
.pipe(sourcemaps.init())
@@ -855,8 +884,10 @@ gulp.task("browserify", "Runs browserify on run.js to produce a file suitable fo
});
});
function cleanTestDirs(done: (e?: any) => void) {
/**
* @param {(e?: any) => void} done
*/
function cleanTestDirs(done) {
// Clean the local baselines & Rwc baselines directories
del([
localBaseline,
@@ -872,8 +903,17 @@ function cleanTestDirs(done: (e?: any) => void) {
});
}
// used to pass data from jake command line directly to run.js
function writeTestConfigFile(tests: string, runners: string, light: boolean, taskConfigsFolder?: string, workerCount?: number, stackTraceLimit?: string, timeout?: number) {
/**
* used to pass data from jake command line directly to run.js
* @param {string} tests
* @param {string} runners
* @param {boolean} light
* @param {string=} taskConfigsFolder
* @param {number=} workerCount
* @param {string=} stackTraceLimit
* @param {number=} timeout
*/
function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, timeout) {
const testConfigContents = JSON.stringify({
test: tests ? [tests] : undefined,
runner: runners ? runners.split(",") : undefined,
@@ -974,7 +1014,7 @@ gulp.task("baseline-accept-test262", "Makes the most recent test262 test results
const webhostPath = "tests/webhost/webtsc.ts";
const webhostJsPath = "tests/webhost/webtsc.js";
gulp.task(webhostJsPath, /*help*/ false, [servicesFile], () => {
const settings: tsc.Settings = getCompilerSettings({
const settings = getCompilerSettings({
outFile: webhostJsPath
}, /*useBuiltCompiler*/ true);
return gulp.src(webhostPath)
@@ -994,7 +1034,7 @@ gulp.task("webhost", "Builds the tsc web host", [webhostJsPath], () => {
const perftscPath = "tests/perftsc.ts";
const perftscJsPath = "built/local/perftsc.js";
gulp.task(perftscJsPath, /*help*/ false, [servicesFile], () => {
const settings: tsc.Settings = getCompilerSettings({
const settings = getCompilerSettings({
outFile: perftscJsPath
}, /*useBuiltCompiler*/ true);
return gulp.src(perftscPath)
@@ -1025,7 +1065,7 @@ gulp.task(loggedIOJsPath, /*help*/ false, [], (done) => {
const instrumenterPath = path.join(harnessDirectory, "instrumenter.ts");
const instrumenterJsPath = path.join(builtLocalDirectory, "instrumenter.js");
gulp.task(instrumenterJsPath, /*help*/ false, [servicesFile], () => {
const settings: tsc.Settings = getCompilerSettings({
const settings = getCompilerSettings({
module: "commonjs",
target: "es5",
lib: [
@@ -1052,7 +1092,7 @@ gulp.task("update-sublime", "Updates the sublime plugin's tsserver", ["local", s
});
gulp.task("build-rules", "Compiles tslint rules to js", () => {
const settings: tsc.Settings = getCompilerSettings({ module: "commonjs", lib: ["es6"] }, /*useBuiltCompiler*/ false);
const settings = getCompilerSettings({ module: "commonjs", lib: ["es6"] }, /*useBuiltCompiler*/ false);
const dest = path.join(builtLocalDirectory, "tslint");
return gulp.src("scripts/tslint/**/*.ts")
.pipe(newer({
@@ -1065,51 +1105,6 @@ gulp.task("build-rules", "Compiles tslint rules to js", () => {
.pipe(gulp.dest(dest));
});
const lintTargets = [
"Gulpfile.ts",
"src/compiler/**/*.ts",
"src/harness/**/*.ts",
"!src/harness/unittests/services/formatting/**/*.ts",
"src/server/**/*.ts",
"scripts/tslint/**/*.ts",
"src/services/**/*.ts",
"tests/*.ts", "tests/webhost/*.ts" // Note: does *not* descend recursively
];
function sendNextFile(files: {path: string}[], child: cp.ChildProcess, callback: (failures: number) => void, failures: number) {
const file = files.pop();
if (file) {
console.log(`Linting '${file.path}'.`);
child.send({ kind: "file", name: file.path });
}
else {
child.send({ kind: "close" });
callback(failures);
}
}
function spawnLintWorker(files: {path: string}[], callback: (failures: number) => void) {
const child = cp.fork("./scripts/parallel-lint");
let failures = 0;
child.on("message", data => {
switch (data.kind) {
case "result":
if (data.failures > 0) {
failures += data.failures;
console.log(data.output);
}
sendNextFile(files, child, callback, failures);
break;
case "error":
console.error(data.error);
failures++;
sendNextFile(files, child, callback, failures);
break;
}
});
sendNextFile(files, child, callback, failures);
}
gulp.task("lint", "Runs tslint on the compiler sources. Optional arguments are: --f[iles]=regex", ["build-rules"], () => {
if (fold.isTravis()) console.log(fold.start("lint"));
for (const project of ["scripts/tslint/tsconfig.json", "src/tsconfig-base.json"]) {
+1 -1
View File
@@ -491,7 +491,7 @@ compileFile(/*outfile*/configurePrereleaseJs,
/*prereqs*/[configurePrereleaseTs],
/*prefixes*/[],
/*useBuiltCompiler*/ false,
{ noOutFile: false, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false });
{ noOutFile: true, generateDeclarations: false, keepComments: false, noResolve: false, stripInternal: false });
task("setDebugMode", function () {
useDebugMode = true;
-1
View File
@@ -76,7 +76,6 @@
"source-map-support": "latest",
"through2": "latest",
"travis-fold": "latest",
"ts-node": "latest",
"tslint": "latest",
"vinyl": "latest",
"chalk": "latest",
+20 -16
View File
@@ -1,4 +1,9 @@
/// <reference path="../src/compiler/sys.ts" />
/// <reference types="node"/>
import { normalize } from "path";
import assert = require("assert");
import { readFileSync, writeFileSync } from "fs";
const args = process.argv.slice(2);
/**
* A minimal description for a parsed package.json object.
@@ -10,28 +15,27 @@ interface PackageJson {
}
function main(): void {
const sys = ts.sys;
if (sys.args.length < 3) {
sys.write("Usage:" + sys.newLine)
sys.write("\tnode configureNightly.js <dev|insiders> <package.json location> <file containing version>" + sys.newLine);
if (args.length < 3) {
console.log("Usage:");
console.log("\tnode configureNightly.js <dev|insiders> <package.json location> <file containing version>");
return;
}
const tag = sys.args[0];
const tag = args[0];
if (tag !== "dev" && tag !== "insiders") {
throw new Error(`Unexpected tag name '${tag}'.`);
}
// Acquire the version from the package.json file and modify it appropriately.
const packageJsonFilePath = ts.normalizePath(sys.args[1]);
const packageJsonValue: PackageJson = JSON.parse(sys.readFile(packageJsonFilePath));
const packageJsonFilePath = normalize(args[1]);
const packageJsonValue: PackageJson = JSON.parse(readFileSync(packageJsonFilePath).toString());
const { majorMinor, patch } = parsePackageJsonVersion(packageJsonValue.version);
const prereleasePatch = getPrereleasePatch(tag, patch);
// Acquire and modify the source file that exposes the version string.
const tsFilePath = ts.normalizePath(sys.args[2]);
const tsFileContents = ts.sys.readFile(tsFilePath);
const tsFilePath = normalize(args[2]);
const tsFileContents = readFileSync(tsFilePath).toString();
const modifiedTsFileContents = updateTsFile(tsFilePath, tsFileContents, majorMinor, patch, prereleasePatch);
// Ensure we are actually changing something - the user probably wants to know that the update failed.
@@ -44,20 +48,20 @@ function main(): void {
// Finally write the changes to disk.
// Modify the package.json structure
packageJsonValue.version = `${majorMinor}.${prereleasePatch}`;
sys.writeFile(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4))
sys.writeFile(tsFilePath, modifiedTsFileContents);
writeFileSync(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4))
writeFileSync(tsFilePath, modifiedTsFileContents);
}
function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: string, patch: string, nightlyPatch: string): string {
const majorMinorRgx = /export const versionMajorMinor = "(\d+\.\d+)"/;
const majorMinorMatch = majorMinorRgx.exec(tsFileContents);
ts.Debug.assert(majorMinorMatch !== null, "", () => `The file seems to no longer have a string matching '${majorMinorRgx}'.`);
assert(majorMinorMatch !== null, `The file seems to no longer have a string matching '${majorMinorRgx}'.`);
const parsedMajorMinor = majorMinorMatch[1];
ts.Debug.assert(parsedMajorMinor === majorMinor, "versionMajorMinor does not match.", () => `${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`);
assert(parsedMajorMinor === majorMinor, `versionMajorMinor does not match. ${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`);
const versionRgx = /export const version = `\$\{versionMajorMinor\}\.(\d)(-dev)?`;/;
const patchMatch = versionRgx.exec(tsFileContents);
ts.Debug.assert(patchMatch !== null, "The file seems to no longer have a string matching", () => versionRgx.toString());
assert(patchMatch !== null, "The file seems to no longer have a string matching " + versionRgx.toString());
const parsedPatch = patchMatch[1];
if (parsedPatch !== patch) {
throw new Error(`patch does not match. ${tsFilePath}: '${parsedPatch}; package.json: '${patch}'`);
@@ -69,7 +73,7 @@ function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: st
function parsePackageJsonVersion(versionString: string): { majorMinor: string, patch: string } {
const versionRgx = /(\d+\.\d+)\.(\d+)($|\-)/;
const match = versionString.match(versionRgx);
ts.Debug.assert(match !== null, "package.json 'version' should match", () => versionRgx.toString());
assert(match !== null, "package.json 'version' should match " + versionRgx.toString());
return { majorMinor: match[1], patch: match[2] };
}
+4 -1
View File
@@ -24465,7 +24465,10 @@ namespace ts {
checkImportBinding(importClause.namedBindings);
}
else {
forEach(importClause.namedBindings.elements, checkImportBinding);
const moduleExisted = resolveExternalModuleName(node, node.moduleSpecifier);
if (moduleExisted) {
forEach(importClause.namedBindings.elements, checkImportBinding);
}
}
}
}
+5 -4
View File
@@ -2994,18 +2994,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;
+2 -6
View File
@@ -2943,10 +2943,6 @@
"category": "Message",
"code": 6040
},
"Compilation complete. Watching for file changes.": {
"category": "Message",
"code": 6042
},
"Generates corresponding '.map' file.": {
"category": "Message",
"code": 6043
@@ -3522,11 +3518,11 @@
"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
},
+26 -4
View File
@@ -10,6 +10,7 @@ namespace ts {
invalidateResolutionOfFile(filePath: Path): void;
removeResolutionsOfFile(filePath: Path): void;
setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map<ReadonlyArray<string>>): void;
createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution;
startCachingPerDirectoryResolution(): void;
@@ -74,6 +75,7 @@ namespace ts {
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string, logChangesWhenResolvingModule: boolean): ResolutionCache {
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
let filesWithInvalidatedResolutions: Map<true> | undefined;
let filesWithInvalidatedNonRelativeUnresolvedImports: Map<ReadonlyArray<string>> | undefined;
let allFilesHaveInvalidatedResolution = false;
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory());
@@ -122,6 +124,7 @@ namespace ts {
resolveTypeReferenceDirectives,
removeResolutionsOfFile,
invalidateResolutionOfFile,
setFilesWithInvalidatedNonRelativeUnresolvedImports,
createHasInvalidatedResolution,
updateTypeRootsWatch,
closeTypeRootsWatch,
@@ -165,6 +168,16 @@ namespace ts {
return collected;
}
function isFileWithInvalidatedNonRelativeUnresolvedImports(path: Path) {
if (!filesWithInvalidatedNonRelativeUnresolvedImports) {
return false;
}
// Invalidated if file has unresolved imports
const value = filesWithInvalidatedNonRelativeUnresolvedImports.get(path);
return value && !!value.length;
}
function createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution {
if (allFilesHaveInvalidatedResolution || forceAllFilesAsInvalidated) {
// Any file asked would have invalidated resolution
@@ -173,7 +186,8 @@ namespace ts {
}
const collected = filesWithInvalidatedResolutions;
filesWithInvalidatedResolutions = undefined;
return path => collected && collected.has(path);
return path => (collected && collected.has(path)) ||
isFileWithInvalidatedNonRelativeUnresolvedImports(path);
}
function clearPerDirectoryResolutions() {
@@ -184,6 +198,7 @@ namespace ts {
function finishCachingPerDirectoryResolution() {
allFilesHaveInvalidatedResolution = false;
filesWithInvalidatedNonRelativeUnresolvedImports = undefined;
directoryWatchesOfFailedLookups.forEach((watcher, path) => {
if (watcher.refCount === 0) {
directoryWatchesOfFailedLookups.delete(path);
@@ -237,13 +252,15 @@ namespace ts {
const resolvedModules: R[] = [];
const compilerOptions = resolutionHost.getCompilationSettings();
const hasInvalidatedNonRelativeUnresolvedImport = logChanges && isFileWithInvalidatedNonRelativeUnresolvedImports(path);
const seenNamesInFile = createMap<true>();
for (const name of names) {
let resolution = resolutionsInFile.get(name);
// Resolution is valid if it is present and not invalidated
if (!seenNamesInFile.has(name) &&
allFilesHaveInvalidatedResolution || !resolution || resolution.isInvalidated) {
allFilesHaveInvalidatedResolution || !resolution || resolution.isInvalidated ||
// If the name is unresolved import that was invalidated, recalculate
(hasInvalidatedNonRelativeUnresolvedImport && !isExternalModuleNameRelative(name) && !getResolutionWithResolvedFileName(resolution))) {
const existingResolution = resolution;
const resolutionInDirectory = perDirectoryResolution.get(name);
if (resolutionInDirectory) {
@@ -284,7 +301,7 @@ namespace ts {
if (oldResolution === newResolution) {
return true;
}
if (!oldResolution || !newResolution || oldResolution.isInvalidated) {
if (!oldResolution || !newResolution) {
return false;
}
const oldResult = getResolutionWithResolvedFileName(oldResolution);
@@ -577,6 +594,11 @@ namespace ts {
);
}
function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: Map<ReadonlyArray<string>>) {
Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined);
filesWithInvalidatedNonRelativeUnresolvedImports = filesMap;
}
function invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath: Path, isCreatingWatchedDirectory: boolean) {
let isChangedFailedLookupLocation: (location: string) => boolean;
if (isCreatingWatchedDirectory) {
+3 -2
View File
@@ -1892,7 +1892,7 @@ namespace ts {
kind: SyntaxKind.DebuggerStatement;
}
export interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement {
export interface MissingDeclaration extends DeclarationStatement {
kind: SyntaxKind.MissingDeclaration;
name?: Identifier;
}
@@ -3193,7 +3193,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] };
+10 -7
View File
@@ -1710,8 +1710,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));
}
}
@@ -4926,6 +4928,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 {
@@ -5606,8 +5612,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 {
@@ -5638,8 +5643,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 {
@@ -5653,8 +5657,7 @@ namespace ts {
|| kind === SyntaxKind.SpreadAssignment
|| kind === SyntaxKind.MethodDeclaration
|| kind === SyntaxKind.GetAccessor
|| kind === SyntaxKind.SetAccessor
|| kind === SyntaxKind.MissingDeclaration;
|| kind === SyntaxKind.SetAccessor;
}
// Type
+5 -6
View File
@@ -29,9 +29,8 @@ 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) {
@@ -231,10 +230,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);
}
};
@@ -644,7 +643,7 @@ namespace ts {
if (host.afterProgramCreate) {
host.afterProgramCreate(builderProgram);
}
reportWatchDiagnostic(Diagnostics.Compilation_complete_Watching_for_file_changes);
return builderProgram;
}
+1 -1
View File
@@ -66,7 +66,7 @@ abstract class ExternalCompileRunnerBase extends RunnerBase {
if (fs.existsSync(path.join(cwd, "node_modules"))) {
require("del").sync(path.join(cwd, "node_modules"), { force: true });
}
const install = cp.spawnSync(`npm`, ["i"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
const install = cp.spawnSync(`npm`, ["i", "--ignore-scripts"], { cwd, timeout: timeout / 2, shell: true, stdio }); // NPM shouldn't take the entire timeout - if it takes a long time, it should be terminated and we should log the failure
if (install.status !== 0) throw new Error(`NPM Install for ${directoryName} failed: ${install.stderr.toString()}`);
}
const args = [path.join(__dirname, "tsc.js")];
+19 -11
View File
@@ -2103,14 +2103,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();
@@ -2910,6 +2907,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 +2917,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 +3217,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;
@@ -3755,6 +3753,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 {
-2
View File
@@ -112,10 +112,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",
+4 -6
View File
@@ -130,8 +130,8 @@ namespace ts.tscWatch {
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 +142,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 +153,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[]) {
@@ -7294,7 +7294,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: {
+76 -5
View File
@@ -999,14 +999,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 +1029,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 +1047,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 +1621,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]);
});
});
}
+1 -1
View File
@@ -125,7 +125,7 @@ namespace Utils {
addFile(path: string, content?: Harness.LanguageService.ScriptInfo) {
const absolutePath = ts.normalizePath(ts.getNormalizedAbsolutePath(path, this.currentDirectory));
const fileName = ts.getBaseFileName(path);
const fileName = ts.getBaseFileName(absolutePath);
const directoryPath = ts.getDirectoryPath(absolutePath);
const directory = this.addDirectory(directoryPath);
return directory ? directory.addFile(fileName, content) : undefined;
@@ -3906,6 +3906,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 +6027,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>
@@ -3894,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[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 +6012,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>
@@ -3906,6 +3906,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 +6027,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>
@@ -3906,6 +3906,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 +6027,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>
@@ -3897,6 +3897,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 +6018,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>
@@ -3897,6 +3897,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 +6018,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>
@@ -3887,6 +3887,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 +6005,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>
@@ -3896,6 +3896,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 +6017,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>
@@ -3890,6 +3890,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 +6011,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>
+7 -6
View File
@@ -312,7 +312,8 @@ namespace ts.server {
export class ProjectService {
public readonly typingsCache: TypingsCache;
/*@internal*/
readonly typingsCache: TypingsCache;
private readonly documentRegistry: DocumentRegistry;
@@ -523,13 +524,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);
}
+61 -74
View File
@@ -55,34 +55,6 @@ namespace ts.server {
projectErrors: ReadonlyArray<Diagnostic>;
}
export class UnresolvedImportsMap {
readonly perFileMap = createMap<ReadonlyArray<string>>();
private version = 0;
public clear() {
this.perFileMap.clear();
this.version = 0;
}
public getVersion() {
return this.version;
}
public remove(path: Path) {
this.perFileMap.delete(path);
this.version++;
}
public get(path: Path) {
return this.perFileMap.get(path);
}
public set(path: Path, value: ReadonlyArray<string>) {
this.perFileMap.set(path, value);
this.version++;
}
}
export interface PluginCreateInfo {
project: Project;
languageService: LanguageService;
@@ -116,8 +88,18 @@ namespace ts.server {
private missingFilesMap: Map<FileWatcher>;
private plugins: PluginModule[] = [];
private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap();
private lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
/*@internal*/
/**
* This is map from files to unresolved imports in it
* Maop does not contain entries for files that do not have unresolved imports
* This helps in containing the set of files to invalidate
*/
cachedUnresolvedImportsPerFile = createMap<ReadonlyArray<string>>();
/*@internal*/
lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
/*@internal*/
private hasAddedorRemovedFiles = false;
private lastFileExceededProgramSize: string | undefined;
@@ -149,10 +131,10 @@ namespace ts.server {
*/
private lastReportedVersion = 0;
/**
* Current project structure version.
* Current project's program version. (incremented everytime new program is created that is not complete reuse from the old one)
* This property is changed in 'updateGraph' based on the set of files in program
*/
private projectStructureVersion = 0;
private projectProgramVersion = 0;
/**
* Current version of the project state. It is changed when:
* - new root file was added/removed
@@ -167,7 +149,8 @@ namespace ts.server {
/*@internal*/
hasChangedAutomaticTypeDirectiveNames = false;
private typingFiles: SortedReadonlyArray<string>;
/*@internal*/
typingFiles: SortedReadonlyArray<string> = emptyArray;
private readonly cancellationToken: ThrottledCancellationToken;
@@ -181,10 +164,6 @@ namespace ts.server {
return hasOneOrMoreJsAndNoTsFiles(this);
}
public getCachedUnresolvedImportsPerFile_TestOnly() {
return this.cachedUnresolvedImportsPerFile;
}
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} {
const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules")));
log(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`);
@@ -742,7 +721,7 @@ namespace ts.server {
else {
this.resolutionCache.invalidateResolutionOfFile(info.path);
}
this.cachedUnresolvedImportsPerFile.remove(info.path);
this.cachedUnresolvedImportsPerFile.delete(info.path);
if (detachFromProject) {
info.detachFromProject(this);
@@ -763,16 +742,13 @@ namespace ts.server {
}
/* @internal */
private extractUnresolvedImportsFromSourceFile(file: SourceFile, result: Push<string>, ambientModules: string[]) {
private extractUnresolvedImportsFromSourceFile(file: SourceFile, ambientModules: string[]): ReadonlyArray<string> {
const cached = this.cachedUnresolvedImportsPerFile.get(file.path);
if (cached) {
// found cached result - use it and return
for (const f of cached) {
result.push(f);
}
return;
// found cached result, return
return cached;
}
let unresolvedImports: string[];
let unresolvedImports: string[] | undefined;
if (file.resolvedModules) {
file.resolvedModules.forEach((resolvedModule, name) => {
// pick unresolved non-relative names
@@ -788,17 +764,23 @@ namespace ts.server {
trimmed = trimmed.substr(0, i);
}
(unresolvedImports || (unresolvedImports = [])).push(trimmed);
result.push(trimmed);
}
});
}
this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports || emptyArray);
return unresolvedImports || emptyArray;
function isAmbientlyDeclaredModule(name: string) {
return ambientModules.some(m => m === name);
}
}
/* @internal */
onFileAddedOrRemoved() {
this.hasAddedorRemovedFiles = true;
}
/**
* Updates set of files that contribute to this project
* @returns: true if set of files in the project stays the same and false - otherwise.
@@ -806,13 +788,15 @@ namespace ts.server {
updateGraph(): boolean {
this.resolutionCache.startRecordingFilesWithChangedResolutions();
let hasChanges = this.updateGraphWorker();
const hasNewProgram = this.updateGraphWorker();
const hasAddedorRemovedFiles = this.hasAddedorRemovedFiles;
this.hasAddedorRemovedFiles = false;
const changedFiles: ReadonlyArray<Path> = this.resolutionCache.finishRecordingFilesWithChangedResolutions() || emptyArray;
for (const file of changedFiles) {
// delete cached information for changed files
this.cachedUnresolvedImportsPerFile.remove(file);
this.cachedUnresolvedImportsPerFile.delete(file);
}
// update builder only if language service is enabled
@@ -824,30 +808,35 @@ namespace ts.server {
// 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files
// (can reuse cached imports for files that were not changed)
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
if (hasChanges || changedFiles.length) {
const result: string[] = [];
if (hasNewProgram || changedFiles.length) {
let result: string[] | undefined;
const ambientModules = this.program.getTypeChecker().getAmbientModules().map(mod => stripQuotes(mod.getName()));
for (const sourceFile of this.program.getSourceFiles()) {
this.extractUnresolvedImportsFromSourceFile(sourceFile, result, ambientModules);
const unResolved = this.extractUnresolvedImportsFromSourceFile(sourceFile, ambientModules);
if (unResolved !== emptyArray) {
(result || (result = [])).push(...unResolved);
}
}
this.lastCachedUnresolvedImportsList = toDeduplicatedSortedArray(result);
this.lastCachedUnresolvedImportsList = result ? toDeduplicatedSortedArray(result) : emptyArray;
}
const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasChanges);
if (!arrayIsEqualTo(this.typingFiles, cachedTypings)) {
this.typingFiles = cachedTypings;
this.markAsDirty();
hasChanges = this.updateGraphWorker() || hasChanges;
}
this.projectService.typingsCache.enqueueInstallTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasAddedorRemovedFiles);
}
else {
this.lastCachedUnresolvedImportsList = undefined;
}
if (hasChanges) {
this.projectStructureVersion++;
if (hasNewProgram) {
this.projectProgramVersion++;
}
return !hasChanges;
return !hasNewProgram;
}
/*@internal*/
updateTypingFiles(typingFiles: SortedReadonlyArray<string>) {
this.typingFiles = typingFiles;
// Invalidate files with unresolved imports
this.resolutionCache.setFilesWithInvalidatedNonRelativeUnresolvedImports(this.cachedUnresolvedImportsPerFile);
}
/* @internal */
@@ -876,9 +865,9 @@ namespace ts.server {
// bump up the version if
// - oldProgram is not set - this is a first time updateGraph is called
// - newProgram is different from the old program and structure of the old program was not reused.
const hasChanges = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & StructureIsReused.Completely)));
const hasNewProgram = this.program && (!oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & StructureIsReused.Completely)));
this.hasChangedAutomaticTypeDirectiveNames = false;
if (hasChanges) {
if (hasNewProgram) {
if (oldProgram) {
for (const f of oldProgram.getSourceFiles()) {
if (this.program.getSourceFileByPath(f.path)) {
@@ -916,8 +905,8 @@ namespace ts.server {
removed => this.detachScriptInfoFromProject(removed)
);
const elapsed = timestamp() - start;
this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} Version: ${this.getProjectVersion()} structureChanged: ${hasChanges} Elapsed: ${elapsed}ms`);
return hasChanges;
this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} Version: ${this.getProjectVersion()} structureChanged: ${hasNewProgram} Elapsed: ${elapsed}ms`);
return hasNewProgram;
}
private detachScriptInfoFromProject(uncheckedFileName: string) {
@@ -985,15 +974,13 @@ namespace ts.server {
setCompilerOptions(compilerOptions: CompilerOptions) {
if (compilerOptions) {
compilerOptions.allowNonTsExtensions = true;
if (changesAffectModuleResolution(this.compilerOptions, compilerOptions)) {
// reset cached unresolved imports if changes in compiler options affected module resolution
this.cachedUnresolvedImportsPerFile.clear();
this.lastCachedUnresolvedImportsList = undefined;
}
const oldOptions = this.compilerOptions;
this.compilerOptions = compilerOptions;
this.setInternalCompilerOptionsForEmittingJsFiles();
if (changesAffectModuleResolution(oldOptions, compilerOptions)) {
// reset cached unresolved imports if changes in compiler options affected module resolution
this.cachedUnresolvedImportsPerFile.clear();
this.lastCachedUnresolvedImportsList = undefined;
this.resolutionCache.clear();
}
this.markAsDirty();
@@ -1006,7 +993,7 @@ namespace ts.server {
const info: protocol.ProjectVersionInfo = {
projectName: this.getProjectName(),
version: this.projectStructureVersion,
version: this.projectProgramVersion,
isInferred: this.projectKind === ProjectKind.Inferred,
options: this.getCompilationSettings(),
languageServiceDisabled: !this.languageServiceEnabled,
@@ -1017,7 +1004,7 @@ namespace ts.server {
// check if requested version is the same that we have reported last time
if (this.lastReportedFileNames && lastKnownVersion === this.lastReportedVersion) {
// if current structure version is the same - return info without any changes
if (this.projectStructureVersion === this.lastReportedVersion && !updatedFileNames) {
if (this.projectProgramVersion === this.lastReportedVersion && !updatedFileNames) {
return { info, projectErrors: this.getGlobalProjectErrors() };
}
// compute and return the difference
@@ -1040,7 +1027,7 @@ namespace ts.server {
}
});
this.lastReportedFileNames = currentFiles;
this.lastReportedVersion = this.projectStructureVersion;
this.lastReportedVersion = this.projectProgramVersion;
return { info, changes: { added, removed, updated }, projectErrors: this.getGlobalProjectErrors() };
}
else {
@@ -1049,7 +1036,7 @@ namespace ts.server {
const externalFiles = this.getExternalFiles().map(f => toNormalizedPath(f));
const allFiles = projectFileNames.concat(externalFiles);
this.lastReportedFileNames = arrayToSet(allFiles);
this.lastReportedVersion = this.projectStructureVersion;
this.lastReportedVersion = this.projectProgramVersion;
return { info, files: allFiles, projectErrors: this.getGlobalProjectErrors() };
}
}
+7 -1
View File
@@ -304,6 +304,7 @@ namespace ts.server {
const isNew = !this.isAttached(project);
if (isNew) {
this.containingProjects.push(project);
project.onFileAddedOrRemoved();
if (!project.getCompilerOptions().preserveSymlinks) {
this.ensureRealPath();
}
@@ -328,19 +329,24 @@ namespace ts.server {
return;
case 1:
if (this.containingProjects[0] === project) {
project.onFileAddedOrRemoved();
this.containingProjects.pop();
}
break;
case 2:
if (this.containingProjects[0] === project) {
project.onFileAddedOrRemoved();
this.containingProjects[0] = this.containingProjects.pop();
}
else if (this.containingProjects[1] === project) {
project.onFileAddedOrRemoved();
this.containingProjects.pop();
}
break;
default:
unorderedRemoveItem(this.containingProjects, project);
if (unorderedRemoveItem(this.containingProjects, project)) {
project.onFileAddedOrRemoved();
}
break;
}
}
+2 -1
View File
@@ -634,7 +634,8 @@ namespace ts.server {
code: d.code,
source: d.source,
startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start),
endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length)
endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length),
reportsUnnecessary: d.reportsUnnecessary
});
}
-2
View File
@@ -108,10 +108,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",
-2
View File
@@ -114,10 +114,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",
+8 -11
View File
@@ -24,7 +24,7 @@ namespace ts.server {
globalTypingsCacheLocation: undefined
};
class TypingsCacheEntry {
interface TypingsCacheEntry {
readonly typeAcquisition: TypeAcquisition;
readonly compilerOptions: CompilerOptions;
readonly typings: SortedReadonlyArray<string>;
@@ -80,6 +80,7 @@ namespace ts.server {
return !arrayIsEqualTo(imports1, imports2);
}
/*@internal*/
export class TypingsCache {
private readonly perProjectCache: Map<TypingsCacheEntry> = createMap<TypingsCacheEntry>();
@@ -94,15 +95,14 @@ namespace ts.server {
return this.installer.installPackage(options);
}
getTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string>, forceRefresh: boolean): SortedReadonlyArray<string> {
enqueueInstallTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string>, forceRefresh: boolean) {
const typeAcquisition = project.getTypeAcquisition();
if (!typeAcquisition || !typeAcquisition.enable) {
return <any>emptyArray;
return;
}
const entry = this.perProjectCache.get(project.getProjectName());
const result: SortedReadonlyArray<string> = entry ? entry.typings : <any>emptyArray;
if (forceRefresh ||
!entry ||
typeAcquisitionChanged(typeAcquisition, entry.typeAcquisition) ||
@@ -113,28 +113,25 @@ namespace ts.server {
this.perProjectCache.set(project.getProjectName(), {
compilerOptions: project.getCompilationSettings(),
typeAcquisition,
typings: result,
typings: entry ? entry.typings : emptyArray,
unresolvedImports,
poisoned: true
});
// something has been changed, issue a request to update typings
this.installer.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
}
return result;
}
updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>, newTypings: string[]) {
const typings = toSortedArray(newTypings);
this.perProjectCache.set(projectName, {
compilerOptions,
typeAcquisition,
typings: toSortedArray(newTypings),
typings,
unresolvedImports,
poisoned: false
});
}
deleteTypingsForProject(projectName: string) {
this.perProjectCache.delete(projectName);
return !typeAcquisition || !typeAcquisition.enable ? emptyArray : typings;
}
onProjectClosed(project: Project) {
@@ -64,11 +64,13 @@ namespace ts.server.typingsInstaller {
onRequestCompleted: RequestCompletedAction;
}
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[] = [];
@@ -378,8 +380,8 @@ namespace ts.server.typingsInstaller {
this.projectWatchers.set(projectName, watchers);
}
watchers.isInvoked = false;
// handler should be invoked once for the entire set of files since it will trigger full rediscovery of typings
let isInvoked = false;
const isLoggingEnabled = this.log.isEnabled();
mutateMap(
watchers,
@@ -392,11 +394,11 @@ namespace ts.server.typingsInstaller {
}
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}'`);
this.log.writeLine(`FileWatcher:: Triggered with ${f} eventKind: ${FileWatcherEventKind[eventKind]}:: WatchInfo: ${file}:: handler is already invoked '${watchers.isInvoked}'`);
}
if (!isInvoked) {
if (!watchers.isInvoked) {
watchers.isInvoked = true;
this.sendResponse({ projectName, kind: ActionInvalidate });
isInvoked = true;
}
}, /*pollingInterval*/ 2000);
return isLoggingEnabled ? {
@@ -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;
}
+16 -16
View File
@@ -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. (This will not be used if `!foundImport`)
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.
-1
View File
@@ -1 +0,0 @@
// Please delete me later.
+52 -87
View File
@@ -130,8 +130,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 +147,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 +200,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 +425,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 +502,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 +533,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;
}
}
@@ -804,7 +807,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;
}
@@ -1028,10 +1031,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()`.
@@ -1103,69 +1102,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;
}
/**
@@ -1460,7 +1427,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. */
@@ -1547,13 +1514,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;
}
}
+14 -53
View File
@@ -50,16 +50,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
@@ -191,8 +182,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 +203,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 +232,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 +265,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));
}
}
+5 -1
View File
@@ -33,7 +33,7 @@ namespace ts.FindAllReferences {
interface AmbientModuleDeclaration extends ModuleDeclaration { body?: ModuleBlock; }
type SourceFileLike = SourceFile | AmbientModuleDeclaration;
// Identifier for the case of `const x = require("y")`.
type Importer = AnyImportOrReExport | Identifier;
type Importer = AnyImportOrReExport | ImportTypeNode | Identifier;
type ImporterOrCallExpression = Importer | CallExpression;
/** Returns import statements that directly reference the exporting module, and a list of files that may access the module through a namespace. */
@@ -215,6 +215,10 @@ namespace ts.FindAllReferences {
return;
}
if (decl.kind === SyntaxKind.ImportType) {
return;
}
// Ignore if there's a grammar error
if (decl.moduleSpecifier.kind !== SyntaxKind.StringLiteral) {
return;
+11 -1
View File
@@ -21,7 +21,17 @@ namespace ts.OutliningElementsCollector {
if (span) out.push(span);
depthRemaining--;
n.forEachChild(walk);
if (isIfStatement(n) && n.elseStatement && isIfStatement(n.elseStatement)) {
// Consider an 'else if' to be on the same depth as the 'if'.
walk(n.expression);
walk(n.thenStatement);
depthRemaining++;
walk(n.elseStatement);
depthRemaining--;
}
else {
n.forEachChild(walk);
}
depthRemaining++;
});
}
-1
View File
@@ -1 +0,0 @@
// Please delete me later.
+1 -1
View File
@@ -1673,7 +1673,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);
+5 -1
View File
@@ -6,7 +6,7 @@ namespace ts {
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));
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;
}
}
+18 -5
View File
@@ -26,6 +26,15 @@ namespace ts.SymbolDisplay {
}
function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker: TypeChecker, symbol: Symbol, location: Node): ScriptElementKind {
const roots = typeChecker.getRootSymbols(symbol);
// If this is a method from a mapped type, leave as a method so long as it still has a call signature.
if (roots.length === 1
&& first(roots).flags & SymbolFlags.Method
// Ensure the mapped version is still a method, as opposed to `{ [K in keyof I]: number }`.
&& typeChecker.getTypeOfSymbolAtLocation(symbol, location).getNonNullableType().getCallSignatures().length !== 0) {
return ScriptElementKind.memberFunctionElement;
}
if (typeChecker.isUndefinedSymbol(symbol)) {
return ScriptElementKind.variableElement;
}
@@ -178,7 +187,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 +267,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.
@@ -531,7 +540,7 @@ namespace ts.SymbolDisplay {
function addAliasPrefixIfNecessary() {
if (alias) {
pushTypePart(ScriptElementKind.alias);
pushSymbolKind(ScriptElementKind.alias);
displayParts.push(spacePart());
}
}
@@ -549,12 +558,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 +575,7 @@ namespace ts.SymbolDisplay {
}
}
function pushTypePart(symbolKind: string) {
function pushSymbolKind(symbolKind: string) {
switch (symbolKind) {
case ScriptElementKind.variableElement:
case ScriptElementKind.functionElement:
-2
View File
@@ -105,10 +105,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",
+4 -28
View File
@@ -1160,7 +1160,7 @@ declare namespace ts {
interface DebuggerStatement extends Statement {
kind: SyntaxKind.DebuggerStatement;
}
interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement {
interface MissingDeclaration extends DeclarationStatement {
kind: SyntaxKind.MissingDeclaration;
name?: Identifier;
}
@@ -3175,6 +3175,7 @@ declare namespace ts {
function isIndexedAccessTypeNode(node: Node): node is IndexedAccessTypeNode;
function isMappedTypeNode(node: Node): node is MappedTypeNode;
function isLiteralTypeNode(node: Node): node is LiteralTypeNode;
function isImportTypeNode(node: Node): node is ImportTypeNode;
function isObjectBindingPattern(node: Node): node is ObjectBindingPattern;
function isArrayBindingPattern(node: Node): node is ArrayBindingPattern;
function isBindingElement(node: Node): node is BindingElement;
@@ -7613,17 +7614,6 @@ declare namespace ts.server {
readonly globalTypingsCacheLocation: string;
}
const nullTypingsInstaller: ITypingsInstaller;
class TypingsCache {
private readonly installer;
private readonly perProjectCache;
constructor(installer: ITypingsInstaller);
isKnownTypesPackageName(name: string): boolean;
installPackage(options: InstallPackageOptionsWithProject): Promise<ApplyCodeActionCommandResult>;
getTypingsForProject(project: Project, unresolvedImports: SortedReadonlyArray<string>, forceRefresh: boolean): SortedReadonlyArray<string>;
updateTypingsForProject(projectName: string, compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>, newTypings: string[]): void;
deleteTypingsForProject(projectName: string): void;
onProjectClosed(project: Project): void;
}
}
declare namespace ts.server {
enum ProjectKind {
@@ -7633,15 +7623,6 @@ declare namespace ts.server {
}
function allRootFilesAreJsOrDts(project: Project): boolean;
function allFilesAreJsOrDts(project: Project): boolean;
class UnresolvedImportsMap {
readonly perFileMap: Map<ReadonlyArray<string>>;
private version;
clear(): void;
getVersion(): number;
remove(path: Path): void;
get(path: Path): ReadonlyArray<string>;
set(path: Path, value: ReadonlyArray<string>): void;
}
interface PluginCreateInfo {
project: Project;
languageService: LanguageService;
@@ -7674,8 +7655,6 @@ declare namespace ts.server {
private externalFiles;
private missingFilesMap;
private plugins;
private cachedUnresolvedImportsPerFile;
private lastCachedUnresolvedImportsList;
private lastFileExceededProgramSize;
protected languageService: LanguageService;
languageServiceEnabled: boolean;
@@ -7695,10 +7674,10 @@ declare namespace ts.server {
*/
private lastReportedVersion;
/**
* 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;
private projectProgramVersion;
/**
* Current version of the project state. It is changed when:
* - new root file was added/removed
@@ -7706,11 +7685,9 @@ declare namespace ts.server {
* This property is different from projectStructureVersion since in most cases edits don't affect set of files in the project
*/
private projectStateVersion;
private typingFiles;
private readonly cancellationToken;
isNonTsProject(): boolean;
isJsOnlyProject(): boolean;
getCachedUnresolvedImportsPerFile_TestOnly(): UnresolvedImportsMap;
static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {};
isKnownTypesPackageName(name: string): boolean;
installPackage(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
@@ -7971,7 +7948,6 @@ declare namespace ts.server {
syntaxOnly?: boolean;
}
class ProjectService {
readonly typingsCache: TypingsCache;
private readonly documentRegistry;
/**
* Container of all known scripts
+2 -1
View File
@@ -1160,7 +1160,7 @@ declare namespace ts {
interface DebuggerStatement extends Statement {
kind: SyntaxKind.DebuggerStatement;
}
interface MissingDeclaration extends DeclarationStatement, ClassElement, ObjectLiteralElement, TypeElement {
interface MissingDeclaration extends DeclarationStatement {
kind: SyntaxKind.MissingDeclaration;
name?: Identifier;
}
@@ -3175,6 +3175,7 @@ declare namespace ts {
function isIndexedAccessTypeNode(node: Node): node is IndexedAccessTypeNode;
function isMappedTypeNode(node: Node): node is MappedTypeNode;
function isLiteralTypeNode(node: Node): node is LiteralTypeNode;
function isImportTypeNode(node: Node): node is ImportTypeNode;
function isObjectBindingPattern(node: Node): node is ObjectBindingPattern;
function isArrayBindingPattern(node: Node): node is ArrayBindingPattern;
function isBindingElement(node: Node): node is BindingElement;
@@ -0,0 +1,8 @@
tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts(1,16): error TS2307: Cannot find module 'module-not-existed'.
==== tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts (1 errors) ====
import {} from 'module-not-existed'
~~~~~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module 'module-not-existed'.
@@ -0,0 +1,7 @@
//// [importEmptyFromModuleNotExisted.ts]
import {} from 'module-not-existed'
//// [importEmptyFromModuleNotExisted.js]
"use strict";
exports.__esModule = true;
@@ -0,0 +1,4 @@
=== tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts ===
import {} from 'module-not-existed'
No type information for this code.
No type information for this code.
@@ -0,0 +1,4 @@
=== tests/cases/conformance/es6/modules/importEmptyFromModuleNotExisted.ts ===
import {} from 'module-not-existed'
No type information for this code.
No type information for this code.
@@ -0,0 +1,44 @@
Exit Code: 1
Standard output:
lib/adapters/http.js(12,19): error TS2307: Cannot find module './../../package.json'.
lib/adapters/http.js(83,22): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
Type 'undefined' is not assignable to type 'string'.
lib/adapters/http.js(189,23): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'.
lib/adapters/http.js(195,44): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'.
lib/adapters/http.js(201,13): error TS2322: Type 'string' is not assignable to type 'Buffer'.
lib/adapters/http.js(213,40): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'.
lib/adapters/http.js(237,42): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'.
lib/adapters/xhr.js(29,16): error TS2339: Property 'XDomainRequest' does not exist on type 'Window'.
lib/adapters/xhr.js(31,28): error TS2339: Property 'XDomainRequest' does not exist on type 'Window'.
lib/adapters/xhr.js(80,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'.
lib/adapters/xhr.js(92,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'.
lib/adapters/xhr.js(99,51): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'.
lib/adapters/xhr.js(102,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'.
lib/adapters/xhr.js(111,7): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'.
lib/adapters/xhr.js(181,9): error TS2322: Type 'null' is not assignable to type 'XMLHttpRequest'.
lib/axios.js(23,3): error TS2554: Expected 3 arguments, but got 2.
lib/axios.js(25,3): error TS2322: Type '(...args: any[]) => any' is not assignable to type 'Axios'.
Property 'defaults' is missing in type '(...args: any[]) => any'.
lib/axios.js(32,7): error TS2339: Property 'Axios' does not exist on type 'Axios'.
lib/axios.js(35,7): error TS2339: Property 'create' does not exist on type 'Axios'.
lib/axios.js(40,7): error TS2339: Property 'Cancel' does not exist on type 'Axios'.
lib/axios.js(41,7): error TS2339: Property 'CancelToken' does not exist on type 'Axios'.
lib/axios.js(42,7): error TS2339: Property 'isCancel' does not exist on type 'Axios'.
lib/axios.js(45,7): error TS2339: Property 'all' does not exist on type 'Axios'.
lib/axios.js(48,7): error TS2339: Property 'spread' does not exist on type 'Axios'.
lib/cancel/CancelToken.js(37,12): error TS2339: Property 'reason' does not exist on type 'CancelToken'.
lib/cancel/CancelToken.js(38,16): error TS2339: Property 'reason' does not exist on type 'CancelToken'.
lib/core/enhanceError.js(14,9): error TS2339: Property 'config' does not exist on type 'Error'.
lib/core/enhanceError.js(16,11): error TS2339: Property 'code' does not exist on type 'Error'.
lib/core/enhanceError.js(18,9): error TS2339: Property 'request' does not exist on type 'Error'.
lib/core/enhanceError.js(19,9): error TS2339: Property 'response' does not exist on type 'Error'.
lib/core/settle.js(21,7): error TS2345: Argument of type 'null' is not assignable to parameter of type 'string | undefined'.
lib/helpers/btoa.js(11,13): error TS2339: Property 'code' does not exist on type 'Error'.
lib/helpers/btoa.js(31,13): error TS2532: Object is possibly 'undefined'.
lib/helpers/cookies.js(16,56): error TS2551: Property 'toGMTString' does not exist on type 'Date'. Did you mean 'toUTCString'?
lib/utils.js(244,20): error TS8029: JSDoc '@param' tag has name 'obj1', but there is no parameter with that name. It would match 'arguments' if it had an array type.
lib/utils.js(268,20): error TS8029: JSDoc '@param' tag has name 'obj1', but there is no parameter with that name. It would match 'arguments' if it had an array type.
Standard error:
@@ -0,0 +1,79 @@
Exit Code: 1
Standard output:
packages/babel-preset-react-app/dependencies.js(38,17): error TS2307: Cannot find module '@babel/preset-env'.
packages/babel-preset-react-app/dependencies.js(49,17): error TS2307: Cannot find module '@babel/preset-env'.
packages/babel-preset-react-app/index.js(52,17): error TS2307: Cannot find module '@babel/preset-env'.
packages/babel-preset-react-app/index.js(61,17): error TS2307: Cannot find module '@babel/preset-env'.
packages/babel-preset-react-app/index.js(74,17): error TS2307: Cannot find module '@babel/preset-react'.
packages/babel-preset-react-app/index.js(84,33): error TS2307: Cannot find module '@babel/preset-flow'.
packages/babel-preset-react-app/index.js(89,15): error TS2307: Cannot find module 'babel-plugin-macros'.
packages/babel-preset-react-app/index.js(93,15): error TS2307: Cannot find module '@babel/plugin-transform-destructuring'.
packages/babel-preset-react-app/index.js(98,17): error TS2307: Cannot find module '@babel/plugin-proposal-class-properties'.
packages/babel-preset-react-app/index.js(107,17): error TS2307: Cannot find module '@babel/plugin-proposal-object-rest-spread'.
packages/babel-preset-react-app/index.js(114,17): error TS2307: Cannot find module '@babel/plugin-transform-runtime'.
packages/babel-preset-react-app/index.js(123,17): error TS2307: Cannot find module 'babel-plugin-transform-react-remove-prop-types'.
packages/babel-preset-react-app/index.js(130,17): error TS2307: Cannot find module '@babel/plugin-transform-regenerator'.
packages/babel-preset-react-app/index.js(137,15): error TS2307: Cannot find module '@babel/plugin-syntax-dynamic-import'.
packages/babel-preset-react-app/index.js(140,17): error TS2307: Cannot find module 'babel-plugin-transform-dynamic-import'.
packages/confusing-browser-globals/test.js(14,1): error TS2304: Cannot find name 'it'.
packages/confusing-browser-globals/test.js(15,3): error TS2304: Cannot find name 'expect'.
packages/confusing-browser-globals/test.js(18,1): error TS2304: Cannot find name 'it'.
packages/confusing-browser-globals/test.js(19,3): error TS2304: Cannot find name 'expect'.
packages/create-react-app/createReactApp.js(37,37): error TS2307: Cannot find module 'validate-npm-package-name'.
packages/create-react-app/createReactApp.js(47,24): error TS2307: Cannot find module 'tar-pack'.
packages/create-react-app/createReactApp.js(49,28): error TS2307: Cannot find module 'hyperquest'.
packages/create-react-app/createReactApp.js(50,25): error TS2307: Cannot find module 'envinfo'.
packages/create-react-app/createReactApp.js(52,30): error TS2307: Cannot find module 'react-dev-utils/workspaceUtils'.
packages/create-react-app/createReactApp.js(53,29): error TS2307: Cannot find module './package.json'.
packages/create-react-app/createReactApp.js(771,20): error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
Type 'undefined' is not assignable to type 'string'.
packages/create-react-app/index.js(45,5): error TS2365: Operator '<' cannot be applied to types 'string' and 'number'.
packages/eslint-config-react-app/index.js(24,33): error TS2307: Cannot find module 'confusing-browser-globals'.
packages/react-dev-utils/FileSizeReporter.js(13,24): error TS2307: Cannot find module 'filesize'.
packages/react-dev-utils/FileSizeReporter.js(14,25): error TS2307: Cannot find module 'recursive-readdir'.
packages/react-dev-utils/FileSizeReporter.js(16,24): error TS2307: Cannot find module 'gzip-size'.
packages/react-dev-utils/WebpackDevServerUtils.js(9,25): error TS2307: Cannot find module 'address'.
packages/react-dev-utils/WebpackDevServerUtils.js(14,24): error TS2307: Cannot find module 'detect-port-alt'.
packages/react-dev-utils/WebpackDevServerUtils.js(15,24): error TS2307: Cannot find module 'is-root'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(12,1): error TS2304: Cannot find name 'describe'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(13,3): error TS2304: Cannot find name 'it'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(18,5): error TS2304: Cannot find name 'expect'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(19,5): error TS2304: Cannot find name 'expect'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(22,3): error TS2304: Cannot find name 'it'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(26,5): error TS2304: Cannot find name 'expect'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(29,3): error TS2304: Cannot find name 'it'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(36,5): error TS2304: Cannot find name 'expect'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(37,5): error TS2304: Cannot find name 'expect'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(40,3): error TS2304: Cannot find name 'it'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(46,5): error TS2304: Cannot find name 'expect'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(49,3): error TS2304: Cannot find name 'it'.
packages/react-dev-utils/__tests__/ignoredFiles.test.js(53,5): error TS2304: Cannot find name 'expect'.
packages/react-dev-utils/browsersHelper.js(9,30): error TS2307: Cannot find module 'browserslist'.
packages/react-dev-utils/browsersHelper.js(13,23): error TS2307: Cannot find module 'pkg-up'.
packages/react-dev-utils/browsersHelper.js(59,22): error TS2554: Expected 1 arguments, but got 0.
packages/react-dev-utils/browsersHelper.js(61,36): error TS2345: Argument of type 'Buffer' is not assignable to parameter of type 'string'.
packages/react-dev-utils/browsersHelper.js(97,25): error TS2538: Type 'undefined' cannot be used as an index type.
packages/react-dev-utils/checkRequiredFiles.js(19,34): error TS2339: Property 'F_OK' does not exist on type 'typeof import("fs")'.
packages/react-dev-utils/checkRequiredFiles.js(23,32): error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'string'.
packages/react-dev-utils/checkRequiredFiles.js(24,34): error TS2345: Argument of type 'undefined' is not assignable to parameter of type 'string'.
packages/react-dev-utils/getProcessForPort.js(29,6): error TS2339: Property 'split' does not exist on type 'Buffer'.
packages/react-dev-utils/getProcessForPort.js(49,21): error TS2339: Property 'replace' does not exist on type 'Buffer'.
packages/react-dev-utils/getProcessForPort.js(63,5): error TS2339: Property 'trim' does not exist on type 'Buffer'.
packages/react-dev-utils/openBrowser.js(13,19): error TS2307: Cannot find module 'opn'.
packages/react-dev-utils/webpackHotDevClient.js(19,22): error TS2307: Cannot find module 'sockjs-client'.
packages/react-dev-utils/webpackHotDevClient.js(24,28): error TS2307: Cannot find module 'react-error-overlay'.
packages/react-dev-utils/webpackHotDevClient.js(31,14): error TS2339: Property 'encodeURIComponent' does not exist on type 'Window'.
packages/react-dev-utils/webpackHotDevClient.js(33,14): error TS2339: Property 'encodeURIComponent' does not exist on type 'Window'.
packages/react-dev-utils/webpackHotDevClient.js(35,14): error TS2339: Property 'encodeURIComponent' does not exist on type 'Window'.
packages/react-dev-utils/webpackHotDevClient.js(53,12): error TS2339: Property 'hot' does not exist on type 'NodeModule'.
packages/react-dev-utils/webpackHotDevClient.js(53,33): error TS2339: Property 'hot' does not exist on type 'NodeModule'.
packages/react-dev-utils/webpackHotDevClient.js(54,10): error TS2339: Property 'hot' does not exist on type 'NodeModule'.
packages/react-dev-utils/webpackHotDevClient.js(223,40): error TS2304: Cannot find name '__webpack_hash__'.
packages/react-dev-utils/webpackHotDevClient.js(228,17): error TS2339: Property 'hot' does not exist on type 'NodeModule'.
packages/react-dev-utils/webpackHotDevClient.js(233,15): error TS2339: Property 'hot' does not exist on type 'NodeModule'.
packages/react-dev-utils/webpackHotDevClient.js(261,23): error TS2339: Property 'hot' does not exist on type 'NodeModule'.
packages/react-dev-utils/workspaceUtils.js(11,25): error TS2307: Cannot find module 'find-pkg'.
Standard error:
@@ -0,0 +1,40 @@
Exit Code: 1
Standard output:
lib/Coverage.js(109,15): error TS2503: Cannot find namespace 'Protocol'.
lib/Coverage.js(196,15): error TS2503: Cannot find namespace 'Protocol'.
lib/ElementHandle.js(24,15): error TS2503: Cannot find namespace 'Protocol'.
lib/ElementHandle.js(83,29): error TS2503: Cannot find namespace 'Protocol'.
lib/EmulationManager.js(36,16): error TS2503: Cannot find namespace 'Protocol'.
lib/ExecutionContext.js(22,15): error TS2503: Cannot find namespace 'Protocol'.
lib/ExecutionContext.js(132,15): error TS2503: Cannot find namespace 'Protocol'.
lib/FrameManager.js(28,15): error TS2503: Cannot find namespace 'Protocol'.
lib/FrameManager.js(54,15): error TS2503: Cannot find namespace 'Protocol'.
lib/FrameManager.js(76,15): error TS2503: Cannot find namespace 'Protocol'.
lib/FrameManager.js(127,15): error TS2503: Cannot find namespace 'Protocol'.
lib/FrameManager.js(773,15): error TS2503: Cannot find namespace 'Protocol'.
lib/NetworkManager.js(129,15): error TS2503: Cannot find namespace 'Protocol'.
lib/NetworkManager.js(174,15): error TS2503: Cannot find namespace 'Protocol'.
lib/NetworkManager.js(207,15): error TS2503: Cannot find namespace 'Protocol'.
lib/NetworkManager.js(224,15): error TS2503: Cannot find namespace 'Protocol'.
lib/NetworkManager.js(256,15): error TS2503: Cannot find namespace 'Protocol'.
lib/NetworkManager.js(270,15): error TS2503: Cannot find namespace 'Protocol'.
lib/NetworkManager.js(286,15): error TS2503: Cannot find namespace 'Protocol'.
lib/NetworkManager.js(313,15): error TS2503: Cannot find namespace 'Protocol'.
lib/NetworkManager.js(640,13): error TS2503: Cannot find namespace 'Protocol'.
lib/Page.js(66,15): error TS2503: Cannot find namespace 'Protocol'.
lib/Page.js(185,15): error TS2503: Cannot find namespace 'Protocol'.
lib/Page.js(394,22): error TS2503: Cannot find namespace 'Protocol'.
lib/Page.js(407,15): error TS2503: Cannot find namespace 'Protocol'.
lib/Page.js(731,19): error TS2503: Cannot find namespace 'Protocol'.
lib/externs.d.ts(16,26): error TS2503: Cannot find namespace 'Protocol'.
lib/externs.d.ts(16,69): error TS2503: Cannot find namespace 'Protocol'.
lib/externs.d.ts(17,28): error TS2503: Cannot find namespace 'Protocol'.
lib/externs.d.ts(17,81): error TS2503: Cannot find namespace 'Protocol'.
lib/externs.d.ts(17,121): error TS2503: Cannot find namespace 'Protocol'.
lib/helper.js(59,15): error TS2503: Cannot find namespace 'Protocol'.
lib/helper.js(77,15): error TS2503: Cannot find namespace 'Protocol'.
lib/helper.js(101,15): error TS2503: Cannot find namespace 'Protocol'.
Standard error:
+60 -59
View File
@@ -6,65 +6,66 @@ node_modules/uglify-js/lib/ast.js(858,5): error TS2322: Type '{ [x: string]: any
Object literal may only specify known properties, but '_visit' does not exist in type 'TreeWalker'. Did you mean to write 'visit'?
node_modules/uglify-js/lib/compress.js(165,27): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(453,26): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(722,18): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(964,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(990,51): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'true | ((node: any) => any)' has no compatible call signatures.
node_modules/uglify-js/lib/compress.js(1074,53): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(1114,112): error TS2532: Object is possibly 'undefined'.
node_modules/uglify-js/lib/compress.js(1115,29): error TS2532: Object is possibly 'undefined'.
node_modules/uglify-js/lib/compress.js(1124,87): error TS2322: Type 'false' is not assignable to type 'number'.
node_modules/uglify-js/lib/compress.js(1132,29): error TS2322: Type 'false' is not assignable to type 'never'.
node_modules/uglify-js/lib/compress.js(1185,38): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(1278,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(1374,27): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(1406,26): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(1820,44): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(1998,19): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(2258,27): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(2998,23): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3011,33): error TS2322: Type '"f"' is not assignable to type 'boolean'.
node_modules/uglify-js/lib/compress.js(3148,18): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3158,33): error TS2339: Property 'add' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3162,32): error TS2339: Property 'add' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3168,40): error TS2339: Property 'add' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3177,41): error TS2339: Property 'add' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3194,14): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3196,40): error TS2339: Property 'get' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3204,33): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(3278,63): error TS2339: Property 'get' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3467,23): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3484,36): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(3490,38): error TS2339: Property 'set' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3494,40): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(3519,22): error TS2339: Property 'each' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3524,30): error TS2339: Property 'del' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3529,30): error TS2339: Property 'set' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3540,41): error TS2339: Property 'has' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3542,48): error TS2339: Property 'get' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3554,41): error TS2339: Property 'has' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3556,48): error TS2339: Property 'get' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3640,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary', but here has type 'any'.
node_modules/uglify-js/lib/compress.js(3642,36): error TS2339: Property 'get' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3659,22): error TS2339: Property 'set' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3679,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead.
node_modules/uglify-js/lib/compress.js(3704,30): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3855,22): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(4133,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'.
node_modules/uglify-js/lib/compress.js(4217,22): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(4545,30): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(4552,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ [x: string]: any; get: () => string; toString: () => string; indent: () => void; indentation: (...'.
node_modules/uglify-js/lib/compress.js(4556,36): error TS2532: Object is possibly 'undefined'.
node_modules/uglify-js/lib/compress.js(4561,41): error TS2339: Property 'get' does not exist on type 'string'.
node_modules/uglify-js/lib/compress.js(5040,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned.
node_modules/uglify-js/lib/compress.js(5505,32): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(5565,24): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(5637,24): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(5643,26): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(5993,43): error TS2454: Variable 'property' is used before being assigned.
node_modules/uglify-js/lib/compress.js(6007,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'.
node_modules/uglify-js/lib/compress.js(6010,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'.
node_modules/uglify-js/lib/compress.js(6017,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'.
node_modules/uglify-js/lib/compress.js(6070,19): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(734,18): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(976,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(1002,51): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'true | ((node: any) => any)' has no compatible call signatures.
node_modules/uglify-js/lib/compress.js(1086,53): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(1126,112): error TS2532: Object is possibly 'undefined'.
node_modules/uglify-js/lib/compress.js(1127,29): error TS2532: Object is possibly 'undefined'.
node_modules/uglify-js/lib/compress.js(1136,87): error TS2322: Type 'false' is not assignable to type 'number'.
node_modules/uglify-js/lib/compress.js(1144,29): error TS2322: Type 'false' is not assignable to type 'never'.
node_modules/uglify-js/lib/compress.js(1197,38): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(1290,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(1386,27): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(1418,26): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(1832,44): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(2024,19): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(2284,27): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3024,23): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3037,33): error TS2322: Type '"f"' is not assignable to type 'boolean'.
node_modules/uglify-js/lib/compress.js(3174,18): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3184,33): error TS2339: Property 'add' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3188,32): error TS2339: Property 'add' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3194,40): error TS2339: Property 'add' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3203,41): error TS2339: Property 'add' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3220,14): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3222,40): error TS2339: Property 'get' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3230,33): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(3304,63): error TS2339: Property 'get' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3493,23): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3510,36): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(3516,38): error TS2339: Property 'set' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3520,40): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'.
node_modules/uglify-js/lib/compress.js(3545,22): error TS2339: Property 'each' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3550,30): error TS2339: Property 'del' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3555,30): error TS2339: Property 'set' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3566,41): error TS2339: Property 'has' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3568,48): error TS2339: Property 'get' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3580,41): error TS2339: Property 'has' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3582,48): error TS2339: Property 'get' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3688,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary', but here has type 'any'.
node_modules/uglify-js/lib/compress.js(3690,36): error TS2339: Property 'get' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3719,22): error TS2339: Property 'set' does not exist on type 'Dictionary'.
node_modules/uglify-js/lib/compress.js(3739,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead.
node_modules/uglify-js/lib/compress.js(3764,30): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(3902,18): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(4201,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'.
node_modules/uglify-js/lib/compress.js(4285,22): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(4613,30): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(4620,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ [x: string]: any; get: () => string; toString: () => string; indent: () => void; indentation: (...'.
node_modules/uglify-js/lib/compress.js(4624,36): error TS2532: Object is possibly 'undefined'.
node_modules/uglify-js/lib/compress.js(4629,41): error TS2339: Property 'get' does not exist on type 'string'.
node_modules/uglify-js/lib/compress.js(5114,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned.
node_modules/uglify-js/lib/compress.js(5553,25): error TS2365: Operator '==' cannot be applied to types 'boolean' and '"f"'.
node_modules/uglify-js/lib/compress.js(5580,32): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(5640,24): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(5712,24): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(5718,26): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/compress.js(6068,43): error TS2454: Variable 'property' is used before being assigned.
node_modules/uglify-js/lib/compress.js(6082,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'.
node_modules/uglify-js/lib/compress.js(6085,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'.
node_modules/uglify-js/lib/compress.js(6092,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'.
node_modules/uglify-js/lib/compress.js(6145,19): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/minify.js(166,75): error TS2339: Property 'compress' does not exist on type 'Compressor'.
node_modules/uglify-js/lib/mozilla-ast.js(569,18): error TS2554: Expected 0 arguments, but got 1.
node_modules/uglify-js/lib/output.js(473,22): error TS2554: Expected 0 arguments, but got 1.
@@ -0,0 +1 @@
import {} from 'module-not-existed'
@@ -0,0 +1,16 @@
/// <reference path='fourslash.ts' />
// @allowJs: true
// @Filename: /a.js
/////** Doc */
////const C = function() { this.x = 0; }
verify.codeFix({
description: "Convert function to an ES2015 class",
newFileContent:
`/** Doc */
class C {
constructor() { this.x = 0; }
}
`,
});
@@ -0,0 +1,7 @@
/// <reference path='fourslash.ts' />
//@Filename: C:\a\b\c.ts
////var /*1*/[|x|] = 1;
const range = test.ranges()[0];
verify.documentHighlightsOf(range, [range], { filesToSearch: [range.fileName] });
@@ -1,13 +1,13 @@
/// <reference path='fourslash.ts' />
// @Filename: foo.ts
//// export function [|bar|]() { return "bar"; }
//// import('./foo').then(({ [|bar|] }) => undefined);
////export function [|{| "isWriteAccess": true, "isDefinition": true |}bar|]() { return "bar"; }
////import('./foo').then(({ [|{| "isWriteAccess": true, "isDefinition": true |}bar|] }) => undefined);
const [r0, r1] = test.ranges();
// This is because bindingElement at r1 are both name and value
verify.referencesOf(r0, [r1, r0, r1, r0]);
verify.referencesOf(r1, [r0, r1, r1, r0]);
verify.renameLocations(r0, [r0, r1]);
verify.renameLocations(r1, [r1, r0, r0, r1]);
verify.referenceGroups(r0, [{ definition: "function bar(): string", ranges: [r0, r1] }]);
verify.referenceGroups(r1, [
{ definition: "function bar(): string", ranges: [r0] },
{ definition: "var bar: () => string", ranges: [r1] },
]);
verify.rangesAreRenameLocations();
@@ -12,12 +12,12 @@ const [r0, r1, r2, r3] = ranges;
// members of spread types only refer to themselves and the resulting property
verify.referenceGroups(r0, [{ definition: "(property) A1.a: string", ranges: [r0, r2, r3] }]);
verify.referenceGroups(r1, [{ definition: "(property) A2.a: number", ranges: [r1, r2] }]);
verify.referenceGroups(r1, [{ definition: "(property) A2.a?: number", ranges: [r1, r2] }]);
// but the resulting property refers to everything
verify.referenceGroups(r2, [
{ definition: "(property) A1.a: string", ranges: [r0, r2, r3] },
{ definition: "(property) A2.a: number", ranges: [r1] },
{ definition: "(property) A2.a?: number", ranges: [r1] },
]);
verify.referenceGroups(r3, [{ definition: "(property) A1.a: string", ranges: [r0, r2, r3] }]);
@@ -8,4 +8,4 @@
////function f ({ [|next|]: { [|next|]: x} }: Recursive) {
////}
verify.singleReferenceGroup("(property) Recursive.next: Recursive");
verify.singleReferenceGroup("(property) Recursive.next?: Recursive");
@@ -0,0 +1,8 @@
/// <reference path='fourslash.ts' />
// @Filename: /a.ts
////export const [|{| "isWriteAccess": true, "isDefinition": true |}x|] = 0;
////declare const a: typeof import("./a");
////a.[|x|];
verify.singleReferenceGroup("const x: 0");
@@ -0,0 +1,89 @@
/// <reference path="fourslash.ts"/>
// Tests that each 'else if' does not count towards a higher nesting depth.
////if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else if (1)[| {
//// 1;
////}|] else[| {
//// 1;
////}|]
verify.outliningSpansInCurrentFile(test.ranges());
@@ -9,5 +9,5 @@
////}
for (const marker of test.markerNames()) {
verify.quickInfoAt(marker, "(property) Recursive.next: Recursive");
verify.quickInfoAt(marker, "(property) Recursive.next?: Recursive");
}
@@ -1,4 +1,4 @@
/// <reference path="../fourslash.ts"/>
/// <reference path="./fourslash.ts"/>
////interface Foo {
//// /** Doc */
@@ -0,0 +1,11 @@
/// <reference path="./fourslash.ts"/>
////interface I { m(): void; }
////declare const o: { [K in keyof I]: number };
////o.m/*0*/;
////
////declare const p: { [K in keyof I]: I[K] };
////p.m/*1*/;
verify.quickInfoAt("0", "(property) m: number");
verify.quickInfoAt("1", "(method) m(): void");
@@ -3,7 +3,7 @@
// @allowJs: true
// @Filename: /a.js
////[|exports.f = function() {}|];
////[|exports.f|] = function() {};
////exports.C = class {};
////exports.x = 0;
////exports.a1 = () => {};
@@ -0,0 +1,14 @@
/// <reference path='fourslash.ts' />
// @allowJs: true
// @Filename: /a.js
////require("m");
////let x; x;
verify.codeFix({
description: "Convert to ES6 module",
newFileContent:
`import "m";
let x; x;`
});
+3
View File
@@ -0,0 +1,3 @@
{
"types": ["node"]
}
+14
View File
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"noImplicitAny": false,
"noImplicitThis": false,
"maxNodeModuleJsDepth": 0,
"strict": true,
"noEmit": true,
"allowJs": true,
"checkJs": true,
"types": ["node"],
"lib": ["esnext", "dom"],
},
"include": ["axios-src/lib"]
}
+1
View File
@@ -0,0 +1 @@
declare module 'chalk';
@@ -0,0 +1,3 @@
{
"types": []
}
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"noImplicitAny": false,
"noImplicitThis": false,
"maxNodeModuleJsDepth": 0,
"strict": true,
"noEmit": true,
"allowJs": true,
"checkJs": true,
"types": ["node"],
"lib": ["esnext", "dom"],
"baseUrl": "./",
"paths": {
"chalk": ["chalk-override"]
}
},
"include": ["create-react-app"],
"exclude": ["create-react-app/packages/react-error-overlay",
"create-react-app/packages/react-scripts"]
}
+3
View File
@@ -0,0 +1,3 @@
{
"types": []
}