mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'main' of https://github.com/microsoft/TypeScript into fix(50751)
This commit is contained in:
+11
-6
@@ -11,7 +11,7 @@
|
||||
"es6": true
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint", "no-null", "import", "eslint-plugin-local"
|
||||
"@typescript-eslint", "no-null", "import", "eslint-plugin-local", "simple-import-sort"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"**/node_modules/**",
|
||||
@@ -25,11 +25,8 @@
|
||||
"/coverage/**"
|
||||
],
|
||||
"rules": {
|
||||
"sort-imports": ["error", {
|
||||
"ignoreCase": true,
|
||||
"ignoreDeclarationSort": true,
|
||||
"allowSeparatedGroups": true
|
||||
}],
|
||||
"simple-import-sort/imports": "error",
|
||||
"simple-import-sort/exports": "error",
|
||||
|
||||
"@typescript-eslint/adjacent-overload-signatures": "error",
|
||||
"@typescript-eslint/array-type": "error",
|
||||
@@ -180,6 +177,14 @@
|
||||
{ "name": "exports" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
// These files contain imports in a specific order that are generally unsafe to modify.
|
||||
"files": ["**/_namespaces/**"],
|
||||
"rules": {
|
||||
"simple-import-sort/imports": "off",
|
||||
"simple-import-sort/exports": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
{
|
||||
"name": "addReply",
|
||||
"parameters": {
|
||||
"comment": "Thanks for the PR! It looks like you've changed the TSServer protocol in some way. Please ensure that any changes here don't break consumers of the current TSServer API. For some extra review, we'll ping @sheetalkamat, @mjbvz, and @minestarks for you. Feel free to loop in other consumers/maintainers if necessary"
|
||||
"comment": "Thanks for the PR! It looks like you've changed the TSServer protocol in some way. Please ensure that any changes here don't break consumers of the current TSServer API. For some extra review, we'll ping @sheetalkamat, @mjbvz, @zkat, and @joj for you. Feel free to loop in other consumers/maintainers if necessary"
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -487,7 +487,7 @@
|
||||
{
|
||||
"name": "addReply",
|
||||
"parameters": {
|
||||
"comment": "Thanks for the PR! It looks like you've changed 'preProcess.ts' in some way. Please ensure that any changes here don't break consumers with unique project systems such as Visual Studio. Pinging @sheetalkamat and @minestarks so they are aware of the changes."
|
||||
"comment": "Thanks for the PR! It looks like you've changed 'preProcess.ts' in some way. Please ensure that any changes here don't break consumers with unique project systems such as Visual Studio. Pinging @sheetalkamat, @zkat, and @joj so they are aware of the changes."
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Vendored
+6
@@ -40,6 +40,12 @@
|
||||
"env": {
|
||||
"NODE_ENV": "testing"
|
||||
},
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/built/**/*.js",
|
||||
"${workspaceFolder}/built/**/*.mjs",
|
||||
"${workspaceFolder}/built/**/*.cjs",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"sourceMaps": true,
|
||||
"smartStep": true,
|
||||
"preLaunchTask": "npm: build:tests",
|
||||
|
||||
Vendored
+8
@@ -13,6 +13,14 @@
|
||||
// ".git-blame-ignore-revs"
|
||||
// ]
|
||||
|
||||
// Match eslint-plugin-simple-import-sort in organize/auto-imports.
|
||||
"typescript.unstable": {
|
||||
"organizeImportsCollation": "unicode",
|
||||
"organizeImportsCaseFirst": "upper",
|
||||
"organizeImportsIgnoreCase": false,
|
||||
"organizeImportsNumericCollation": true
|
||||
},
|
||||
|
||||
// These options search the repo recursively and slow down
|
||||
// the build task menu. We define our own in tasks.json.
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
|
||||
+40
-39
@@ -1,21 +1,22 @@
|
||||
// @ts-check
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import del from "del";
|
||||
import { task } from "hereby";
|
||||
import _glob from "glob";
|
||||
import util from "util";
|
||||
import { CancelToken } from "@esfx/canceltoken";
|
||||
import chalk from "chalk";
|
||||
import chokidar from "chokidar";
|
||||
import del from "del";
|
||||
import esbuild from "esbuild";
|
||||
import { EventEmitter } from "events";
|
||||
import fs from "fs";
|
||||
import fsExtra from "fs-extra";
|
||||
import { Debouncer, Deferred, exec, getDiffTool, getDirSize, memoize, needsUpdate, readJson } from "./scripts/build/utils.mjs";
|
||||
import { localBaseline, localRwcBaseline, refBaseline, refRwcBaseline, runConsoleTests } from "./scripts/build/tests.mjs";
|
||||
import { buildProject, cleanProject, watchProject } from "./scripts/build/projects.mjs";
|
||||
import _glob from "glob";
|
||||
import { task } from "hereby";
|
||||
import path from "path";
|
||||
import util from "util";
|
||||
|
||||
import { localizationDirectories } from "./scripts/build/localization.mjs";
|
||||
import cmdLineOptions from "./scripts/build/options.mjs";
|
||||
import esbuild from "esbuild";
|
||||
import chokidar from "chokidar";
|
||||
import { EventEmitter } from "events";
|
||||
import { CancelToken } from "@esfx/canceltoken";
|
||||
import { buildProject, cleanProject, watchProject } from "./scripts/build/projects.mjs";
|
||||
import { localBaseline, localRwcBaseline, refBaseline, refRwcBaseline, runConsoleTests } from "./scripts/build/tests.mjs";
|
||||
import { Debouncer, Deferred, exec, getDiffTool, getDirSize, memoize, needsUpdate, readJson } from "./scripts/build/utils.mjs";
|
||||
|
||||
const glob = util.promisify(_glob);
|
||||
|
||||
@@ -59,10 +60,7 @@ export const generateLibs = task({
|
||||
|
||||
for (const source of lib.sources) {
|
||||
const contents = await fs.promises.readFile(source, "utf-8");
|
||||
// TODO(jakebailey): "\n\n" is for compatibility with our current tests; our test baselines
|
||||
// are sensitive to the positions of things in the lib files. Eventually remove this,
|
||||
// or remove lib.d.ts line numbers from our baselines.
|
||||
output += "\n\n" + contents.replace(/\r\n/g, "\n");
|
||||
output += "\n" + contents.replace(/\r\n/g, "\n");
|
||||
}
|
||||
|
||||
await fs.promises.writeFile(lib.target, output);
|
||||
@@ -182,28 +180,6 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
|
||||
packages: "external",
|
||||
logLevel: "warning",
|
||||
// legalComments: "none", // If we add copyright headers to the source files, uncomment.
|
||||
plugins: [
|
||||
{
|
||||
name: "fix-require",
|
||||
setup: (build) => {
|
||||
build.onEnd(async () => {
|
||||
// esbuild converts calls to "require" to "__require"; this function
|
||||
// calls the real require if it exists, or throws if it does not (rather than
|
||||
// throwing an error like "require not defined"). But, since we want typescript
|
||||
// to be consumable by other bundlers, we need to convert these calls back to
|
||||
// require so our imports are visible again.
|
||||
//
|
||||
// The leading spaces are to keep the offsets the same within the files to keep
|
||||
// source maps working (though this only really matters for the line the require is on).
|
||||
//
|
||||
// See: https://github.com/evanw/esbuild/issues/1905
|
||||
let contents = await fs.promises.readFile(outfile, "utf-8");
|
||||
contents = contents.replace(/__require\(/g, " require(");
|
||||
await fs.promises.writeFile(outfile, contents);
|
||||
});
|
||||
},
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
if (taskOptions.exportIsTsObject) {
|
||||
@@ -213,6 +189,30 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
|
||||
options.globalName = "ts";
|
||||
// If we are in a CJS context, export the ts namespace.
|
||||
options.footer = { js: `\nif (typeof module !== "undefined" && module.exports) { module.exports = ts; }` };
|
||||
|
||||
// esbuild converts calls to "require" to "__require"; this function
|
||||
// calls the real require if it exists, or throws if it does not (rather than
|
||||
// throwing an error like "require not defined"). But, since we want typescript
|
||||
// to be consumable by other bundlers, we need to convert these calls back to
|
||||
// require so our imports are visible again.
|
||||
//
|
||||
// The leading spaces are to keep the offsets the same within the files to keep
|
||||
// source maps working (though this only really matters for the line the require is on).
|
||||
//
|
||||
// See: https://github.com/evanw/esbuild/issues/1905
|
||||
options.define = { require: "$$require" };
|
||||
options.plugins = [
|
||||
{
|
||||
name: "fix-require",
|
||||
setup: (build) => {
|
||||
build.onEnd(async () => {
|
||||
let contents = await fs.promises.readFile(outfile, "utf-8");
|
||||
contents = contents.replace(/\$\$require/g, " require");
|
||||
await fs.promises.writeFile(outfile, contents);
|
||||
});
|
||||
},
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
return options;
|
||||
@@ -515,6 +515,7 @@ const { main: watchGuard, watch: watchWatchGuard } = entrypointBuildTask({
|
||||
export const generateTypesMap = task({
|
||||
name: "generate-types-map",
|
||||
run: async () => {
|
||||
await fs.promises.mkdir("./built/local", { recursive: true });
|
||||
const source = "src/server/typesMap.json";
|
||||
const target = "built/local/typesMap.json";
|
||||
const contents = await fs.promises.readFile(source, "utf-8");
|
||||
|
||||
Generated
+329
-310
File diff suppressed because it is too large
Load Diff
@@ -66,6 +66,7 @@
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-local": "^1.0.0",
|
||||
"eslint-plugin-no-null": "^1.0.2",
|
||||
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||
"fast-xml-parser": "^4.0.11",
|
||||
"fs-extra": "^9.1.0",
|
||||
"glob": "latest",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import chalk from "chalk";
|
||||
import { join } from "path";
|
||||
import { readFileSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
let playwright;
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { dirname, join, resolve } from "path";
|
||||
import { existsSync } from "fs";
|
||||
import { dirname, join, resolve } from "path";
|
||||
import url from "url";
|
||||
|
||||
const __filename = url.fileURLToPath(new URL(import.meta.url));
|
||||
|
||||
@@ -26,13 +26,13 @@ const parsed = minimist(process.argv.slice(2), {
|
||||
inspect: process.env.inspect || process.env["inspect-brk"] || process.env.i,
|
||||
host: process.env.TYPESCRIPT_HOST || process.env.host || "node",
|
||||
browser: process.env.browser || process.env.b || (os.platform() === "win32" ? "edge" : "chrome"),
|
||||
timeout: process.env.timeout || 40000,
|
||||
timeout: +(process.env.timeout ?? 0) || 40000,
|
||||
tests: process.env.test || process.env.tests || process.env.t,
|
||||
runners: process.env.runners || process.env.runner || process.env.ru,
|
||||
light: process.env.light === undefined || process.env.light !== "false",
|
||||
reporter: process.env.reporter || process.env.r,
|
||||
fix: process.env.fix || process.env.f,
|
||||
workers: process.env.workerCount || ((os.cpus().length - (ci ? 0 : 1)) || 1),
|
||||
workers: +(process.env.workerCount ?? 0) || ((os.cpus().length - (ci ? 0 : 1)) || 1),
|
||||
failed: false,
|
||||
keepFailed: false,
|
||||
lkg: true,
|
||||
@@ -73,11 +73,11 @@ export default options;
|
||||
* @property {string | boolean} break
|
||||
* @property {string | boolean} inspect
|
||||
* @property {string} runners
|
||||
* @property {string|number} workers
|
||||
* @property {number} workers
|
||||
* @property {string} host
|
||||
* @property {string} reporter
|
||||
* @property {string} stackTraceLimit
|
||||
* @property {string|number} timeout
|
||||
* @property {number} timeout
|
||||
* @property {boolean} failed
|
||||
* @property {boolean} keepFailed
|
||||
* @property {boolean} ci
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Debouncer, exec } from "./utils.mjs";
|
||||
import { resolve } from "path";
|
||||
|
||||
import { findUpRoot } from "./findUpDir.mjs";
|
||||
import cmdLineOptions from "./options.mjs";
|
||||
import { Debouncer, exec } from "./utils.mjs";
|
||||
|
||||
class ProjectQueue {
|
||||
/**
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { CancelError } from "@esfx/canceltoken";
|
||||
import chalk from "chalk";
|
||||
import del from "del";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
import chalk from "chalk";
|
||||
|
||||
import { findUpFile, findUpRoot } from "./findUpDir.mjs";
|
||||
import cmdLineOptions from "./options.mjs";
|
||||
import { exec } from "./utils.mjs";
|
||||
import { findUpFile, findUpRoot } from "./findUpDir.mjs";
|
||||
import { CancelError } from "@esfx/canceltoken";
|
||||
|
||||
const mochaJs = path.resolve(findUpRoot(), "node_modules", "mocha", "bin", "_mocha");
|
||||
export const localBaseline = "tests/baselines/local/";
|
||||
@@ -175,9 +176,9 @@ export async function cleanTestDirs() {
|
||||
* @param {string} runners
|
||||
* @param {boolean} light
|
||||
* @param {string} [taskConfigsFolder]
|
||||
* @param {string | number} [workerCount]
|
||||
* @param {number} [workerCount]
|
||||
* @param {string} [stackTraceLimit]
|
||||
* @param {string | number} [timeout]
|
||||
* @param {number} [timeout]
|
||||
* @param {boolean} [keepFailed]
|
||||
* @param {number | undefined} [shards]
|
||||
* @param {number | undefined} [shardId]
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
/* eslint-disable no-restricted-globals */
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import chalk from "chalk";
|
||||
import which from "which";
|
||||
import { spawn } from "child_process";
|
||||
import assert from "assert";
|
||||
import JSONC from "jsonc-parser";
|
||||
import { CancelError } from "@esfx/canceltoken";
|
||||
import assert from "assert";
|
||||
import chalk from "chalk";
|
||||
import { spawn } from "child_process";
|
||||
import fs from "fs";
|
||||
import JSONC from "jsonc-parser";
|
||||
import path from "path";
|
||||
import which from "which";
|
||||
|
||||
/**
|
||||
* Executes the provided command once with the supplied arguments.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { normalize, relative } from "path";
|
||||
import assert from "assert";
|
||||
import { readFileSync, writeFileSync } from "fs";
|
||||
import { normalize, relative } from "path";
|
||||
import url from "url";
|
||||
|
||||
const __filename = url.fileURLToPath(new URL(import.meta.url));
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
* bundle as namespaces again, even though the project is modules.
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import minimist from "minimist";
|
||||
import url from "url";
|
||||
import ts from "../lib/typescript.js";
|
||||
import assert, { fail } from "assert";
|
||||
import fs from "fs";
|
||||
import minimist from "minimist";
|
||||
import path from "path";
|
||||
import url from "url";
|
||||
|
||||
import ts from "../lib/typescript.js";
|
||||
|
||||
const __filename = url.fileURLToPath(new URL(import.meta.url));
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// This file requires a modern version of node 14+, and grep to be available.
|
||||
|
||||
// node scripts/find-unused-diagnostic-messages.mjs
|
||||
import { execSync } from "child_process";
|
||||
import { readFileSync } from "fs";
|
||||
import { EOL } from "os";
|
||||
import { execSync } from "child_process";
|
||||
|
||||
const diags = readFileSync("src/compiler/diagnosticInformationMap.generated.ts", "utf8");
|
||||
const startOfDiags = diags.split("export const Diagnostics")[1];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { XMLParser } from "fast-xml-parser";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { XMLParser } from "fast-xml-parser";
|
||||
|
||||
/** @typedef {{
|
||||
LCX: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as os from "os";
|
||||
import * as childProcess from "child_process";
|
||||
import * as fs from "fs";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
import url from "url";
|
||||
|
||||
const __filename = url.fileURLToPath(new URL(import.meta.url));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import url from "url";
|
||||
|
||||
import { findUpRoot } from "./build/findUpDir.mjs";
|
||||
|
||||
const __filename = url.fileURLToPath(new URL(import.meta.url));
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import { runSequence } from "./run-sequence.mjs";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import url from "url";
|
||||
|
||||
import { runSequence } from "./run-sequence.mjs";
|
||||
|
||||
const __filename = url.fileURLToPath(new URL(import.meta.url));
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Octokit } from "@octokit/rest";
|
||||
|
||||
import { runSequence } from "./run-sequence.mjs";
|
||||
|
||||
const userName = process.env.GH_USERNAME || "typescript-bot";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Octokit } from "@octokit/rest";
|
||||
import fs from "fs";
|
||||
import ado from "azure-devops-node-api";
|
||||
import fetch from "node-fetch";
|
||||
import assert from "assert";
|
||||
import ado from "azure-devops-node-api";
|
||||
import fs from "fs";
|
||||
import fetch from "node-fetch";
|
||||
|
||||
|
||||
async function main() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
/** @typedef {{
|
||||
category: string;
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import fs from "fs-extra";
|
||||
import path from "path";
|
||||
import glob from "glob";
|
||||
import url from "url";
|
||||
import del from "del";
|
||||
import fs from "fs-extra";
|
||||
import glob from "glob";
|
||||
import path from "path";
|
||||
import url from "url";
|
||||
|
||||
import { localizationDirectories } from "./build/localization.mjs";
|
||||
|
||||
const __filename = url.fileURLToPath(new URL(import.meta.url));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Octokit } from "@octokit/rest";
|
||||
|
||||
import { runSequence } from "./run-sequence.mjs";
|
||||
|
||||
// The first is used by bot-based kickoffs, the second by automatic triggers
|
||||
|
||||
+53
-3
@@ -37,6 +37,7 @@ import {
|
||||
emitSkippedWithNoDiagnostics,
|
||||
emptyArray,
|
||||
ensurePathIsNonModuleName,
|
||||
FileIncludeKind,
|
||||
filterSemanticDiagnostics,
|
||||
forEach,
|
||||
forEachEntry,
|
||||
@@ -911,9 +912,17 @@ export type ProgramBuildInfoEmitSignature = ProgramBuildInfoFileId | [fileId: Pr
|
||||
*/
|
||||
export type ProgramMultiFileEmitBuildInfoFileInfo = string | ProgramMultiFileEmitBuildInfoBuilderStateFileInfo;
|
||||
/** @internal */
|
||||
export type ProgramBuildInfoRootStartEnd = [start: ProgramBuildInfoFileId, end: ProgramBuildInfoFileId];
|
||||
/**
|
||||
* Either start and end of FileId for consecutive fileIds to be included as root or single fileId that is root
|
||||
* @internal
|
||||
*/
|
||||
export type ProgramBuildInfoRoot = ProgramBuildInfoRootStartEnd | ProgramBuildInfoFileId;
|
||||
/** @internal */
|
||||
export interface ProgramMultiFileEmitBuildInfo {
|
||||
fileNames: readonly string[];
|
||||
fileInfos: readonly ProgramMultiFileEmitBuildInfoFileInfo[];
|
||||
root: readonly ProgramBuildInfoRoot[];
|
||||
options: CompilerOptions | undefined;
|
||||
fileIdsList: readonly (readonly ProgramBuildInfoFileId[])[] | undefined;
|
||||
referencedMap: ProgramBuildInfoReferencedMap | undefined;
|
||||
@@ -942,6 +951,7 @@ export type ProgramBuildInfoBundlePendingEmit = BuilderFileEmit | false;
|
||||
export interface ProgramBundleEmitBuildInfo {
|
||||
fileNames: readonly string[];
|
||||
fileInfos: readonly ProgramBundleEmitBuildInfoFileInfo[];
|
||||
root: readonly ProgramBuildInfoRoot[];
|
||||
options: CompilerOptions | undefined;
|
||||
outSignature: EmitSignature | undefined;
|
||||
latestChangedDtsFile: string | undefined;
|
||||
@@ -966,12 +976,14 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
|
||||
const latestChangedDtsFile = state.latestChangedDtsFile ? relativeToBuildInfoEnsuringAbsolutePath(state.latestChangedDtsFile) : undefined;
|
||||
const fileNames: string[] = [];
|
||||
const fileNameToFileId = new Map<string, ProgramBuildInfoFileId>();
|
||||
const root: ProgramBuildInfoRoot[] = [];
|
||||
if (outFile(state.compilerOptions)) {
|
||||
// Copy all fileInfo, version and impliedFormat
|
||||
// Affects global scope and signature doesnt matter because with --out they arent calculated or needed to determine upto date ness
|
||||
const fileInfos = arrayFrom(state.fileInfos.entries(), ([key, value]): ProgramBundleEmitBuildInfoFileInfo => {
|
||||
// Ensure fileId
|
||||
toFileId(key);
|
||||
const fileId = toFileId(key);
|
||||
tryAddRoot(key, fileId);
|
||||
return value.impliedFormat ?
|
||||
{ version: value.version, impliedFormat: value.impliedFormat, signature: undefined, affectsGlobalScope: undefined } :
|
||||
value.version;
|
||||
@@ -979,6 +991,7 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
|
||||
const program: ProgramBundleEmitBuildInfo = {
|
||||
fileNames,
|
||||
fileInfos,
|
||||
root,
|
||||
options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions),
|
||||
outSignature: state.outSignature,
|
||||
latestChangedDtsFile,
|
||||
@@ -1005,6 +1018,7 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
|
||||
const fileInfos = arrayFrom(state.fileInfos.entries(), ([key, value]): ProgramMultiFileEmitBuildInfoFileInfo => {
|
||||
// Ensure fileId
|
||||
const fileId = toFileId(key);
|
||||
tryAddRoot(key, fileId);
|
||||
Debug.assert(fileNames[fileId - 1] === relativeToBuildInfo(key));
|
||||
const oldSignature = state.oldSignatures?.get(key);
|
||||
const actualSignature = oldSignature !== undefined ? oldSignature || undefined : value.signature;
|
||||
@@ -1100,6 +1114,7 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
|
||||
const program: ProgramMultiFileEmitBuildInfo = {
|
||||
fileNames,
|
||||
fileInfos,
|
||||
root,
|
||||
options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions),
|
||||
fileIdsList,
|
||||
referencedMap,
|
||||
@@ -1140,6 +1155,25 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
|
||||
return fileIdListId;
|
||||
}
|
||||
|
||||
function tryAddRoot(path: Path, fileId: ProgramBuildInfoFileId) {
|
||||
const file = state.program!.getSourceFile(path)!;
|
||||
if (!state.program!.getFileIncludeReasons().get(file.path)!.some(r => r.kind === FileIncludeKind.RootFile)) return;
|
||||
// First fileId as is
|
||||
if (!root.length) return root.push(fileId);
|
||||
const last = root[root.length - 1];
|
||||
const isLastStartEnd = isArray(last);
|
||||
// If its [..., last = [start, end = fileId - 1]], update last to [start, fileId]
|
||||
if (isLastStartEnd && last[1] === fileId - 1) return last[1] = fileId;
|
||||
// If its [..., last = [start, end !== fileId - 1]] or [last] or [..., last !== fileId - 1], push the fileId
|
||||
if (isLastStartEnd || root.length === 1 || last !== fileId - 1) return root.push(fileId);
|
||||
const lastButOne = root[root.length - 2];
|
||||
// If [..., lastButOne = [start, end], lastFileId] or [..., lastButOne !== lastFileId - 1, lastFileId], push the fileId
|
||||
if (!isNumber(lastButOne) || lastButOne !== last - 1) return root.push(fileId);
|
||||
// Convert lastButOne as [lastButOne, fileId]
|
||||
root[root.length - 2] = [lastButOne, fileId];
|
||||
return root.length = root.length - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param optionKey key of CommandLineOption to use to determine if the option should be serialized in tsbuildinfo
|
||||
*/
|
||||
@@ -1776,16 +1810,32 @@ export function getBuildInfoFileVersionMap(
|
||||
program: ProgramBuildInfo,
|
||||
buildInfoPath: string,
|
||||
host: Pick<ReadBuildProgramHost, "useCaseSensitiveFileNames" | "getCurrentDirectory">
|
||||
): Map<Path, string> {
|
||||
) {
|
||||
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory()));
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
|
||||
const fileInfos = new Map<Path, string>();
|
||||
let rootIndex = 0;
|
||||
const roots: Path[] = [];
|
||||
program.fileInfos.forEach((fileInfo, index) => {
|
||||
const path = toPath(program.fileNames[index], buildInfoDirectory, getCanonicalFileName);
|
||||
const version = isString(fileInfo) ? fileInfo : fileInfo.version;
|
||||
fileInfos.set(path, version);
|
||||
if (rootIndex < program.root.length) {
|
||||
const current = program.root[rootIndex];
|
||||
const fileId = (index + 1) as ProgramBuildInfoFileId;
|
||||
if (isArray(current)) {
|
||||
if (current[0] <= fileId && fileId <= current[1]) {
|
||||
roots.push(path);
|
||||
if (current[1] === fileId) rootIndex++;
|
||||
}
|
||||
}
|
||||
else if (current === fileId) {
|
||||
roots.push(path);
|
||||
rootIndex++;
|
||||
}
|
||||
}
|
||||
});
|
||||
return fileInfos;
|
||||
return { fileInfos, roots };
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
+162
-131
@@ -111,7 +111,10 @@ import {
|
||||
createGetCanonicalFileName,
|
||||
createGetSymbolWalker,
|
||||
createModeAwareCacheKey,
|
||||
createPrinter,
|
||||
createPrinterWithDefaults,
|
||||
createPrinterWithRemoveComments,
|
||||
createPrinterWithRemoveCommentsNeverAsciiEscape,
|
||||
createPrinterWithRemoveCommentsOmitTrailingSemicolon,
|
||||
createPropertyNameNodeForIdentifierOrLiteral,
|
||||
createSymbolTable,
|
||||
createTextWriter,
|
||||
@@ -448,6 +451,7 @@ import {
|
||||
isBlock,
|
||||
isBlockOrCatchScoped,
|
||||
isBlockScopedContainerTopLevel,
|
||||
isBooleanLiteral,
|
||||
isCallChain,
|
||||
isCallExpression,
|
||||
isCallLikeExpression,
|
||||
@@ -596,6 +600,7 @@ import {
|
||||
isLet,
|
||||
isLineBreak,
|
||||
isLiteralComputedPropertyDeclarationName,
|
||||
isLiteralExpression,
|
||||
isLiteralExpressionOfObject,
|
||||
isLiteralImportTypeNode,
|
||||
isLiteralTypeNode,
|
||||
@@ -1057,8 +1062,8 @@ import {
|
||||
WithStatement,
|
||||
YieldExpression,
|
||||
} from "./_namespaces/ts";
|
||||
import * as performance from "./_namespaces/ts.performance";
|
||||
import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers";
|
||||
import * as performance from "./_namespaces/ts.performance";
|
||||
|
||||
const ambientModuleSymbolRegex = /^".+"$/;
|
||||
const anon = "(anonymous)" as __String & string;
|
||||
@@ -1256,8 +1261,8 @@ export const enum SignatureCheckMode {
|
||||
|
||||
const enum IntersectionState {
|
||||
None = 0,
|
||||
Source = 1 << 0,
|
||||
Target = 1 << 1,
|
||||
Source = 1 << 0, // Source type is a constituent of an outer intersection
|
||||
Target = 1 << 1, // Target type is a constituent of an outer intersection
|
||||
}
|
||||
|
||||
const enum RecursionFlags {
|
||||
@@ -1722,6 +1727,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
isArrayType,
|
||||
isTupleType,
|
||||
isArrayLikeType,
|
||||
isEmptyAnonymousObjectType,
|
||||
isTypeInvalidDueToUnionDiscriminant,
|
||||
getExactOptionalProperties,
|
||||
getAllPossiblePropertiesOfTypes,
|
||||
@@ -3879,7 +3885,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
|
||||
function resolveExportByName(moduleSymbol: Symbol, name: __String, sourceNode: TypeOnlyCompatibleAliasDeclaration | undefined, dontResolveAlias: boolean) {
|
||||
const exportValue = moduleSymbol.exports!.get(InternalSymbolName.ExportEquals);
|
||||
const exportSymbol = exportValue ? getPropertyOfType(getTypeOfSymbol(exportValue), name) : moduleSymbol.exports!.get(name);
|
||||
const exportSymbol = exportValue
|
||||
? getPropertyOfType(getTypeOfSymbol(exportValue), name, /*skipObjectFunctionPropertyAugment*/ true)
|
||||
: moduleSymbol.exports!.get(name);
|
||||
const resolved = resolveSymbol(exportSymbol, dontResolveAlias);
|
||||
markSymbolOfAliasDeclarationIfTypeOnly(sourceNode, exportSymbol, resolved, /*overwriteEmpty*/ false);
|
||||
return resolved;
|
||||
@@ -4954,14 +4962,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName);
|
||||
}
|
||||
else {
|
||||
const tsExtension = tryExtractTSExtension(moduleReference);
|
||||
const isExtensionlessRelativePathImport = pathIsRelative(moduleReference) && !hasExtension(moduleReference);
|
||||
const resolutionIsNode16OrNext = moduleResolutionKind === ModuleResolutionKind.Node16 ||
|
||||
moduleResolutionKind === ModuleResolutionKind.NodeNext;
|
||||
if (tsExtension) {
|
||||
errorOnTSExtensionImport(tsExtension);
|
||||
}
|
||||
else if (!getResolveJsonModule(compilerOptions) &&
|
||||
if (!getResolveJsonModule(compilerOptions) &&
|
||||
fileExtensionIs(moduleReference, Extension.Json) &&
|
||||
moduleResolutionKind !== ModuleResolutionKind.Classic &&
|
||||
hasJsonModuleEmitEnabled(compilerOptions)) {
|
||||
@@ -4986,11 +4990,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
return undefined;
|
||||
|
||||
function errorOnTSExtensionImport(tsExtension: string) {
|
||||
const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
|
||||
error(errorNode, diag, tsExtension, getSuggestedImportSource(tsExtension));
|
||||
}
|
||||
|
||||
function getSuggestedImportSource(tsExtension: string) {
|
||||
const importSourceWithoutExtension = removeExtension(moduleReference, tsExtension);
|
||||
/**
|
||||
@@ -6123,7 +6122,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function symbolToStringWorker(writer: EmitTextWriter) {
|
||||
const entity = builder(symbol, meaning!, enclosingDeclaration, nodeFlags)!; // TODO: GH#18217
|
||||
// add neverAsciiEscape for GH#39027
|
||||
const printer = enclosingDeclaration?.kind === SyntaxKind.SourceFile ? createPrinter({ removeComments: true, neverAsciiEscape: true }) : createPrinter({ removeComments: true });
|
||||
const printer = enclosingDeclaration?.kind === SyntaxKind.SourceFile
|
||||
? createPrinterWithRemoveCommentsNeverAsciiEscape()
|
||||
: createPrinterWithRemoveComments();
|
||||
const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration);
|
||||
printer.writeNode(EmitHint.Unspecified, entity, /*sourceFile*/ sourceFile, writer);
|
||||
return writer;
|
||||
@@ -6142,7 +6143,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
sigOutput = kind === SignatureKind.Construct ? SyntaxKind.ConstructSignature : SyntaxKind.CallSignature;
|
||||
}
|
||||
const sig = nodeBuilder.signatureToSignatureDeclaration(signature, sigOutput, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName);
|
||||
const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true });
|
||||
const printer = createPrinterWithRemoveCommentsOmitTrailingSemicolon();
|
||||
const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration);
|
||||
printer.writeNode(EmitHint.Unspecified, sig!, /*sourceFile*/ sourceFile, getTrailingSemicolonDeferringWriter(writer)); // TODO: GH#18217
|
||||
return writer;
|
||||
@@ -6155,8 +6156,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (typeNode === undefined) return Debug.fail("should always get typenode");
|
||||
// The unresolved type gets a synthesized comment on `any` to hint to users that it's not a plain `any`.
|
||||
// Otherwise, we always strip comments out.
|
||||
const options = { removeComments: type !== unresolvedType };
|
||||
const printer = createPrinter(options);
|
||||
const printer = type !== unresolvedType ? createPrinterWithRemoveComments() : createPrinterWithDefaults();
|
||||
const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration);
|
||||
printer.writeNode(EmitHint.Unspecified, typeNode, /*sourceFile*/ sourceFile, writer);
|
||||
const result = writer.getText();
|
||||
@@ -7307,7 +7307,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (signature.thisParameter) {
|
||||
return symbolToParameterDeclaration(signature.thisParameter, context);
|
||||
}
|
||||
if (signature.declaration) {
|
||||
if (signature.declaration && isInJSFile(signature.declaration)) {
|
||||
const thisTag = getJSDocThisTag(signature.declaration);
|
||||
if (thisTag && thisTag.typeExpression) {
|
||||
return factory.createParameterDeclaration(
|
||||
@@ -9636,7 +9636,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
typePredicate.kind === TypePredicateKind.Identifier || typePredicate.kind === TypePredicateKind.AssertsIdentifier ? factory.createIdentifier(typePredicate.parameterName) : factory.createThisTypeNode(),
|
||||
typePredicate.type && nodeBuilder.typeToTypeNode(typePredicate.type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.WriteTypeParametersInQualifiedName)! // TODO: GH#18217
|
||||
);
|
||||
const printer = createPrinter({ removeComments: true });
|
||||
const printer = createPrinterWithRemoveComments();
|
||||
const sourceFile = enclosingDeclaration && getSourceFileOfNode(enclosingDeclaration);
|
||||
printer.writeNode(EmitHint.Unspecified, predicate, /*sourceFile*/ sourceFile, writer);
|
||||
return writer;
|
||||
@@ -10519,7 +10519,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// function/class/{} initializers are themselves containers, so they won't merge in the same way as other initializers
|
||||
const container = getAssignedExpandoInitializer(symbol.valueDeclaration);
|
||||
if (container) {
|
||||
const tag = getJSDocTypeTag(container);
|
||||
const tag = isInJSFile(container) ? getJSDocTypeTag(container) : undefined;
|
||||
if (tag && tag.typeExpression) {
|
||||
return getTypeFromTypeNode(tag.typeExpression);
|
||||
}
|
||||
@@ -14309,6 +14309,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
|
||||
if (isInJSFile(declaration)) {
|
||||
const thisTag = getJSDocThisTag(declaration);
|
||||
if (thisTag && thisTag.typeExpression) {
|
||||
thisParameter = createSymbolWithType(createSymbol(SymbolFlags.FunctionScopedVariable, InternalSymbolName.This), getTypeFromTypeNode(thisTag.typeExpression));
|
||||
}
|
||||
}
|
||||
|
||||
const classType = declaration.kind === SyntaxKind.Constructor ?
|
||||
getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent as ClassDeclaration).symbol))
|
||||
: undefined;
|
||||
@@ -14442,7 +14449,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (node.tags) {
|
||||
for (const tag of node.tags) {
|
||||
if (isJSDocOverloadTag(tag)) {
|
||||
result.push(getSignatureFromDeclaration(tag.typeExpression));
|
||||
const jsDocSignature = tag.typeExpression;
|
||||
if (jsDocSignature.type === undefined && !isConstructorDeclaration(decl)) {
|
||||
reportImplicitAny(jsDocSignature, anyType);
|
||||
}
|
||||
result.push(getSignatureFromDeclaration(jsDocSignature));
|
||||
hasJSDocOverloads = true;
|
||||
}
|
||||
}
|
||||
@@ -14565,6 +14576,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (declaration.kind === SyntaxKind.Constructor) {
|
||||
return getDeclaredTypeOfClassOrInterface(getMergedSymbol((declaration.parent as ClassDeclaration).symbol));
|
||||
}
|
||||
if (isJSDocSignature(declaration)) {
|
||||
const root = getJSDocRoot(declaration);
|
||||
if (root && isConstructorDeclaration(root.parent)) {
|
||||
return getDeclaredTypeOfClassOrInterface(getMergedSymbol((root.parent.parent as ClassDeclaration).symbol));
|
||||
}
|
||||
}
|
||||
if (isJSDocConstructSignature(declaration)) {
|
||||
return getTypeFromTypeNode((declaration.parameters[0] as ParameterDeclaration).type!); // TODO: GH#18217
|
||||
}
|
||||
@@ -15202,7 +15219,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function getSubstitutionType(baseType: Type, constraint: Type) {
|
||||
if (constraint.flags & TypeFlags.AnyOrUnknown || constraint === baseType) {
|
||||
if (constraint.flags & TypeFlags.AnyOrUnknown || constraint === baseType || baseType.flags & TypeFlags.Any) {
|
||||
return baseType;
|
||||
}
|
||||
const id = `${getTypeId(baseType)}>${getTypeId(constraint)}`;
|
||||
@@ -16255,7 +16272,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
// This function assumes the constituent type list is sorted and deduplicated.
|
||||
function getUnionTypeFromSortedList(types: Type[], objectFlags: ObjectFlags, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[], origin?: Type): Type {
|
||||
function getUnionTypeFromSortedList(types: Type[], precomputedObjectFlags: ObjectFlags, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[], origin?: Type): Type {
|
||||
if (types.length === 0) {
|
||||
return neverType;
|
||||
}
|
||||
@@ -16270,7 +16287,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
let type = unionTypes.get(id);
|
||||
if (!type) {
|
||||
type = createType(TypeFlags.Union) as UnionType;
|
||||
type.objectFlags = objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
|
||||
type.objectFlags = precomputedObjectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
|
||||
type.types = types;
|
||||
type.origin = origin;
|
||||
type.aliasSymbol = aliasSymbol;
|
||||
@@ -17043,8 +17060,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
}
|
||||
const propType = getTypeOfSymbol(prop);
|
||||
return accessExpression && getAssignmentTargetKind(accessExpression) !== AssignmentKind.Definite ?
|
||||
getFlowTypeOfReference(accessExpression, propType) :
|
||||
return accessExpression && getAssignmentTargetKind(accessExpression) !== AssignmentKind.Definite ? getFlowTypeOfReference(accessExpression, propType) :
|
||||
accessNode && isIndexedAccessTypeNode(accessNode) && containsMissingType(propType) ? getUnionType([propType, undefinedType]) :
|
||||
propType;
|
||||
}
|
||||
if (everyType(objectType, isTupleType) && isNumericLiteralName(propName)) {
|
||||
@@ -17733,11 +17750,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function getTypeFromImportTypeNode(node: ImportTypeNode): Type {
|
||||
const links = getNodeLinks(node);
|
||||
if (!links.resolvedType) {
|
||||
if (node.isTypeOf && node.typeArguments) { // Only the non-typeof form can make use of type arguments
|
||||
error(node, Diagnostics.Type_arguments_cannot_be_used_here);
|
||||
links.resolvedSymbol = unknownSymbol;
|
||||
return links.resolvedType = errorType;
|
||||
}
|
||||
if (!isLiteralImportTypeNode(node)) {
|
||||
error(node.argument, Diagnostics.String_literal_expected);
|
||||
links.resolvedSymbol = unknownSymbol;
|
||||
@@ -17800,7 +17812,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const resolvedSymbol = resolveSymbol(symbol);
|
||||
links.resolvedSymbol = resolvedSymbol;
|
||||
if (meaning === SymbolFlags.Value) {
|
||||
return getTypeOfSymbol(symbol); // intentionally doesn't use resolved symbol so type is cached as expected on the alias
|
||||
return getInstantiationExpressionType(getTypeOfSymbol(symbol), node); // intentionally doesn't use resolved symbol so type is cached as expected on the alias
|
||||
}
|
||||
else {
|
||||
const type = tryGetDeclaredTypeOfSymbol(resolvedSymbol); // call this first to ensure typeParameters is populated (if applicable)
|
||||
@@ -19978,7 +19990,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid
|
||||
let lastSkippedInfo: [Type, Type] | undefined;
|
||||
let incompatibleStack: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] | undefined;
|
||||
let inPropertyCheck = false;
|
||||
|
||||
Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
|
||||
|
||||
@@ -20194,26 +20205,31 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
generalizedSourceType = getTypeNameForErrorDisplay(generalizedSource);
|
||||
}
|
||||
|
||||
if (target.flags & TypeFlags.TypeParameter && target !== markerSuperTypeForCheck && target !== markerSubTypeForCheck) {
|
||||
const constraint = getBaseConstraintOfType(target);
|
||||
let needsOriginalSource;
|
||||
if (constraint && (isTypeAssignableTo(generalizedSource, constraint) || (needsOriginalSource = isTypeAssignableTo(source, constraint)))) {
|
||||
reportError(
|
||||
Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2,
|
||||
needsOriginalSource ? sourceType : generalizedSourceType,
|
||||
targetType,
|
||||
typeToString(constraint),
|
||||
);
|
||||
// If `target` is of indexed access type (And `source` it is not), we use the object type of `target` for better error reporting
|
||||
const targetFlags = target.flags & TypeFlags.IndexedAccess && !(source.flags & TypeFlags.IndexedAccess) ?
|
||||
(target as IndexedAccessType).objectType.flags :
|
||||
target.flags;
|
||||
|
||||
if (targetFlags & TypeFlags.TypeParameter && target !== markerSuperTypeForCheck && target !== markerSubTypeForCheck) {
|
||||
const constraint = getBaseConstraintOfType(target);
|
||||
let needsOriginalSource;
|
||||
if (constraint && (isTypeAssignableTo(generalizedSource, constraint) || (needsOriginalSource = isTypeAssignableTo(source, constraint)))) {
|
||||
reportError(
|
||||
Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2,
|
||||
needsOriginalSource ? sourceType : generalizedSourceType,
|
||||
targetType,
|
||||
typeToString(constraint),
|
||||
);
|
||||
}
|
||||
else {
|
||||
errorInfo = undefined;
|
||||
reportError(
|
||||
Diagnostics._0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1,
|
||||
targetType,
|
||||
generalizedSourceType
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
errorInfo = undefined;
|
||||
reportError(
|
||||
Diagnostics._0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1,
|
||||
targetType,
|
||||
generalizedSourceType
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!message) {
|
||||
if (relation === comparableRelation) {
|
||||
@@ -20938,30 +20954,33 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
|
||||
}
|
||||
}
|
||||
// For certain combinations involving intersections and optional, excess, or mismatched properties we need
|
||||
// an extra property check where the intersection is viewed as a single object. The following are motivating
|
||||
// examples that all should be errors, but aren't without this extra property check:
|
||||
// When the target is an intersection we need an extra property check in order to detect nested excess
|
||||
// properties and nested weak types. The following are motivating examples that all should be errors, but
|
||||
// aren't without this extra property check:
|
||||
//
|
||||
// let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 }; // Nested excess property
|
||||
//
|
||||
// declare let wrong: { a: { y: string } };
|
||||
// let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type
|
||||
//
|
||||
if (result && !(intersectionState & IntersectionState.Target) && target.flags & TypeFlags.Intersection &&
|
||||
!isGenericObjectType(target) && source.flags & (TypeFlags.Object | TypeFlags.Intersection)) {
|
||||
result &= propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined, /*optionalsOnly*/ false, IntersectionState.None);
|
||||
if (result && isObjectLiteralType(source) && getObjectFlags(source) & ObjectFlags.FreshLiteral) {
|
||||
result &= indexSignaturesRelatedTo(source, target, /*sourceIsPrimitive*/ false, reportErrors, IntersectionState.None);
|
||||
}
|
||||
}
|
||||
// When the source is an intersection we need an extra check of any optional properties in the target to
|
||||
// detect possible mismatched property types. For example:
|
||||
//
|
||||
// function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
|
||||
// x = y; // Mismatched property in source intersection
|
||||
// }
|
||||
//
|
||||
// We suppress recursive intersection property checks because they can generate lots of work when relating
|
||||
// recursive intersections that are structurally similar but not exactly identical. See #37854.
|
||||
if (result && !inPropertyCheck && (
|
||||
target.flags & TypeFlags.Intersection && !isGenericObjectType(target) && source.flags & (TypeFlags.Object | TypeFlags.Intersection) ||
|
||||
isNonGenericObjectType(target) && !isArrayOrTupleType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((source as IntersectionType).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) {
|
||||
inPropertyCheck = true;
|
||||
result &= propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined, IntersectionState.None);
|
||||
if (result && isObjectLiteralType(source) && getObjectFlags(source) & ObjectFlags.FreshLiteral) {
|
||||
result &= indexSignaturesRelatedTo(source, target, /*sourceIsPrimitive*/ false, reportErrors, IntersectionState.None);
|
||||
}
|
||||
inPropertyCheck = false;
|
||||
else if (result && isNonGenericObjectType(target) && !isArrayOrTupleType(target) &&
|
||||
source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType &&
|
||||
!some((source as IntersectionType).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType))) {
|
||||
result &= propertiesRelatedTo(source, target, reportErrors, /*excludedProperties*/ undefined, /*optionalsOnly*/ true, intersectionState);
|
||||
}
|
||||
}
|
||||
if (result) {
|
||||
@@ -21469,11 +21488,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (sourceFlags & (TypeFlags.Object | TypeFlags.Intersection) && targetFlags & TypeFlags.Object) {
|
||||
// Report structural errors only if we haven't reported any errors yet
|
||||
const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo.errorInfo && !sourceIsPrimitive;
|
||||
result = propertiesRelatedTo(source, target, reportStructuralErrors, /*excludedProperties*/ undefined, intersectionState);
|
||||
result = propertiesRelatedTo(source, target, reportStructuralErrors, /*excludedProperties*/ undefined, /*optionalsOnly*/ false, intersectionState);
|
||||
if (result) {
|
||||
result &= signaturesRelatedTo(source, target, SignatureKind.Call, reportStructuralErrors);
|
||||
result &= signaturesRelatedTo(source, target, SignatureKind.Call, reportStructuralErrors, intersectionState);
|
||||
if (result) {
|
||||
result &= signaturesRelatedTo(source, target, SignatureKind.Construct, reportStructuralErrors);
|
||||
result &= signaturesRelatedTo(source, target, SignatureKind.Construct, reportStructuralErrors, intersectionState);
|
||||
if (result) {
|
||||
result &= indexSignaturesRelatedTo(source, target, sourceIsPrimitive, reportStructuralErrors, intersectionState);
|
||||
}
|
||||
@@ -21644,11 +21663,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// Compare the remaining non-discriminant properties of each match.
|
||||
let result = Ternary.True;
|
||||
for (const type of matchingTypes) {
|
||||
result &= propertiesRelatedTo(source, type, /*reportErrors*/ false, excludedProperties, IntersectionState.None);
|
||||
result &= propertiesRelatedTo(source, type, /*reportErrors*/ false, excludedProperties, /*optionalsOnly*/ false, IntersectionState.None);
|
||||
if (result) {
|
||||
result &= signaturesRelatedTo(source, type, SignatureKind.Call, /*reportStructuralErrors*/ false);
|
||||
result &= signaturesRelatedTo(source, type, SignatureKind.Call, /*reportStructuralErrors*/ false, IntersectionState.None);
|
||||
if (result) {
|
||||
result &= signaturesRelatedTo(source, type, SignatureKind.Construct, /*reportStructuralErrors*/ false);
|
||||
result &= signaturesRelatedTo(source, type, SignatureKind.Construct, /*reportStructuralErrors*/ false, IntersectionState.None);
|
||||
if (result && !(isTupleType(source) && isTupleType(type))) {
|
||||
// Comparing numeric index types when both `source` and `type` are tuples is unnecessary as the
|
||||
// element types should be sufficiently covered by `propertiesRelatedTo`. It also causes problems
|
||||
@@ -21811,7 +21830,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// No array like or unmatched property error - just issue top level error (errorInfo = undefined)
|
||||
}
|
||||
|
||||
function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean, excludedProperties: Set<__String> | undefined, intersectionState: IntersectionState): Ternary {
|
||||
function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean, excludedProperties: Set<__String> | undefined, optionalsOnly: boolean, intersectionState: IntersectionState): Ternary {
|
||||
if (relation === identityRelation) {
|
||||
return propertiesIdenticalTo(source, target, excludedProperties);
|
||||
}
|
||||
@@ -21946,7 +21965,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const numericNamesOnly = isTupleType(source) && isTupleType(target);
|
||||
for (const targetProp of excludeProperties(properties, excludedProperties)) {
|
||||
const name = targetProp.escapedName;
|
||||
if (!(targetProp.flags & SymbolFlags.Prototype) && (!numericNamesOnly || isNumericLiteralName(name) || name === "length")) {
|
||||
if (!(targetProp.flags & SymbolFlags.Prototype) && (!numericNamesOnly || isNumericLiteralName(name) || name === "length") && (!optionalsOnly || targetProp.flags & SymbolFlags.Optional)) {
|
||||
const sourceProp = getPropertyOfType(source, name);
|
||||
if (sourceProp && sourceProp !== targetProp) {
|
||||
const related = propertyRelatedTo(source, target, sourceProp, targetProp, getNonMissingTypeOfSymbol, reportErrors, intersectionState, relation === comparableRelation);
|
||||
@@ -21984,7 +22003,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return result;
|
||||
}
|
||||
|
||||
function signaturesRelatedTo(source: Type, target: Type, kind: SignatureKind, reportErrors: boolean): Ternary {
|
||||
function signaturesRelatedTo(source: Type, target: Type, kind: SignatureKind, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
|
||||
if (relation === identityRelation) {
|
||||
return signaturesIdenticalTo(source, target, kind);
|
||||
}
|
||||
@@ -22029,7 +22048,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// of the much more expensive N * M comparison matrix we explore below. We erase type parameters
|
||||
// as they are known to always be the same.
|
||||
for (let i = 0; i < targetSignatures.length; i++) {
|
||||
const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors, incompatibleReporter(sourceSignatures[i], targetSignatures[i]));
|
||||
const related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors, intersectionState, incompatibleReporter(sourceSignatures[i], targetSignatures[i]));
|
||||
if (!related) {
|
||||
return Ternary.False;
|
||||
}
|
||||
@@ -22045,7 +22064,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const eraseGenerics = relation === comparableRelation || !!compilerOptions.noStrictGenericChecks;
|
||||
const sourceSignature = first(sourceSignatures);
|
||||
const targetSignature = first(targetSignatures);
|
||||
result = signatureRelatedTo(sourceSignature, targetSignature, eraseGenerics, reportErrors, incompatibleReporter(sourceSignature, targetSignature));
|
||||
result = signatureRelatedTo(sourceSignature, targetSignature, eraseGenerics, reportErrors, intersectionState, incompatibleReporter(sourceSignature, targetSignature));
|
||||
if (!result && reportErrors && kind === SignatureKind.Construct && (sourceObjectFlags & targetObjectFlags) &&
|
||||
(targetSignature.declaration?.kind === SyntaxKind.Constructor || sourceSignature.declaration?.kind === SyntaxKind.Constructor)) {
|
||||
const constructSignatureToString = (signature: Signature) =>
|
||||
@@ -22061,7 +22080,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// Only elaborate errors from the first failure
|
||||
let shouldElaborateErrors = reportErrors;
|
||||
for (const s of sourceSignatures) {
|
||||
const related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors, incompatibleReporter(s, t));
|
||||
const related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors, intersectionState, incompatibleReporter(s, t));
|
||||
if (related) {
|
||||
result &= related;
|
||||
resetErrorInfo(saveErrorInfo);
|
||||
@@ -22111,9 +22130,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
/**
|
||||
* See signatureAssignableTo, compareSignaturesIdentical
|
||||
*/
|
||||
function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean, incompatibleReporter: (source: Type, target: Type) => void): Ternary {
|
||||
function signatureRelatedTo(source: Signature, target: Signature, erase: boolean, reportErrors: boolean, intersectionState: IntersectionState, incompatibleReporter: (source: Type, target: Type) => void): Ternary {
|
||||
return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target,
|
||||
relation === strictSubtypeRelation ? SignatureCheckMode.StrictArity : 0, reportErrors, reportError, incompatibleReporter, isRelatedToWorker, reportUnreliableMapper);
|
||||
function isRelatedToWorker(source: Type, target: Type, reportErrors?: boolean) {
|
||||
return isRelatedTo(source, target, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState);
|
||||
}
|
||||
}
|
||||
|
||||
function signaturesIdenticalTo(source: Type, target: Type, kind: SignatureKind): Ternary {
|
||||
@@ -22159,7 +22181,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
for (const info of getIndexInfosOfType(source)) {
|
||||
if (isApplicableIndexType(info.keyType, keyType)) {
|
||||
const related = indexInfoRelatedTo(info, targetInfo, reportErrors);
|
||||
const related = indexInfoRelatedTo(info, targetInfo, reportErrors, intersectionState);
|
||||
if (!related) {
|
||||
return Ternary.False;
|
||||
}
|
||||
@@ -22169,8 +22191,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return result;
|
||||
}
|
||||
|
||||
function indexInfoRelatedTo(sourceInfo: IndexInfo, targetInfo: IndexInfo, reportErrors: boolean) {
|
||||
const related = isRelatedTo(sourceInfo.type, targetInfo.type, RecursionFlags.Both, reportErrors);
|
||||
function indexInfoRelatedTo(sourceInfo: IndexInfo, targetInfo: IndexInfo, reportErrors: boolean, intersectionState: IntersectionState) {
|
||||
const related = isRelatedTo(sourceInfo.type, targetInfo.type, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState);
|
||||
if (!related && reportErrors) {
|
||||
if (sourceInfo.keyType === targetInfo.keyType) {
|
||||
reportError(Diagnostics._0_index_signatures_are_incompatible, typeToString(sourceInfo.keyType));
|
||||
@@ -22204,7 +22226,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function typeRelatedToIndexInfo(source: Type, targetInfo: IndexInfo, reportErrors: boolean, intersectionState: IntersectionState): Ternary {
|
||||
const sourceInfo = getApplicableIndexInfo(source, targetInfo.keyType);
|
||||
if (sourceInfo) {
|
||||
return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors);
|
||||
return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors, intersectionState);
|
||||
}
|
||||
if (!(intersectionState & IntersectionState.Source) && isObjectTypeWithInferableIndex(source)) {
|
||||
// Intersection constituents are never considered to have an inferred index signature
|
||||
@@ -22580,10 +22602,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
// Return true if the given type is deeply nested. We consider this to be the case when structural type comparisons
|
||||
// for maxDepth or more occurrences or instantiations of the type have been recorded on the given stack. It is possible,
|
||||
// though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely
|
||||
// expanding. Effectively, we will generate a false positive when two types are structurally equal to at least maxDepth
|
||||
// levels, but unequal at some level beyond that.
|
||||
// for maxDepth or more occurrences or instantiations of the same type have been recorded on the given stack. The
|
||||
// "sameness" of instantiations is determined by the getRecursionIdentity function. An intersection is considered
|
||||
// deeply nested if any constituent of the intersection is deeply nested. It is possible, though highly unlikely, for
|
||||
// the deeply nested check to be true in a situation where a chain of instantiations is not infinitely expanding.
|
||||
// Effectively, we will generate a false positive when two types are structurally equal to at least maxDepth levels,
|
||||
// but unequal at some level beyond that.
|
||||
// In addition, this will also detect when an indexed access has been chained off of maxDepth more times (which is
|
||||
// essentially the dual of the structural comparison), and likewise mark the type as deeply nested, potentially adding
|
||||
// false positives for finite but deeply expanding indexed accesses (eg, for `Q[P1][P2][P3][P4][P5]`).
|
||||
@@ -22593,12 +22617,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// to terminate the expansion, and we do so here.
|
||||
function isDeeplyNestedType(type: Type, stack: Type[], depth: number, maxDepth = 3): boolean {
|
||||
if (depth >= maxDepth) {
|
||||
if (type.flags & TypeFlags.Intersection) {
|
||||
return some((type as IntersectionType).types, t => isDeeplyNestedType(t, stack, depth, maxDepth));
|
||||
}
|
||||
const identity = getRecursionIdentity(type);
|
||||
let count = 0;
|
||||
let lastTypeId = 0;
|
||||
for (let i = 0; i < depth; i++) {
|
||||
const t = stack[i];
|
||||
if (getRecursionIdentity(t) === identity) {
|
||||
if (t.flags & TypeFlags.Intersection ? some((t as IntersectionType).types, u => getRecursionIdentity(u) === identity) : getRecursionIdentity(t) === identity) {
|
||||
// We only count occurrences with a higher type id than the previous occurrence, since higher
|
||||
// type ids are an indicator of newer instantiations caused by recursion.
|
||||
if (t.id >= lastTypeId) {
|
||||
@@ -23415,6 +23442,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
error(declaration, Diagnostics.Function_type_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
|
||||
return;
|
||||
case SyntaxKind.JSDocSignature:
|
||||
if (noImplicitAny && isJSDocOverloadTag(declaration.parent)) {
|
||||
error(declaration.parent.tagName, Diagnostics.This_overload_implicitly_returns_the_type_0_because_it_lacks_a_return_type_annotation, typeAsString);
|
||||
}
|
||||
return;
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
@@ -25629,7 +25661,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
newOrigin = createOriginUnionOrIntersectionType(TypeFlags.Union, originFiltered);
|
||||
}
|
||||
}
|
||||
return getUnionTypeFromSortedList(filtered, (type as UnionType).objectFlags, /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined, newOrigin);
|
||||
// filtering could remove intersections so `ContainsIntersections` might be forwarded "incorrectly"
|
||||
// it is purely an optimization hint so there is no harm in accidentally forwarding it
|
||||
return getUnionTypeFromSortedList(filtered, (type as UnionType).objectFlags & (ObjectFlags.PrimitiveUnion | ObjectFlags.ContainsIntersections), /*aliasSymbol*/ undefined, /*aliasTypeArguments*/ undefined, newOrigin);
|
||||
}
|
||||
return type.flags & TypeFlags.Never || f(type) ? type : neverType;
|
||||
}
|
||||
@@ -26835,7 +26869,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function narrowTypeByLiteralExpression(type: Type, literal: LiteralExpression, assumeTrue: boolean) {
|
||||
return assumeTrue ?
|
||||
narrowTypeByTypeName(type, literal.text) :
|
||||
getTypeWithFacts(type, typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject);
|
||||
getAdjustedTypeWithFacts(type, typeofNEFacts.get(literal.text) || TypeFacts.TypeofNEHostObject);
|
||||
}
|
||||
|
||||
function narrowTypeBySwitchOptionalChainContainment(type: Type, switchStatement: SwitchStatement, clauseStart: number, clauseEnd: number, clauseCheck: (type: Type) => boolean) {
|
||||
@@ -26997,42 +27031,32 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
// Check that right operand is a function type with a prototype property
|
||||
const rightType = getTypeOfExpression(expr.right);
|
||||
if (!isTypeDerivedFrom(rightType, globalFunctionType)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
let targetType: Type | undefined;
|
||||
const prototypeProperty = getPropertyOfType(rightType, "prototype" as __String);
|
||||
if (prototypeProperty) {
|
||||
// Target type is type of the prototype property
|
||||
const prototypePropertyType = getTypeOfSymbol(prototypeProperty);
|
||||
if (!isTypeAny(prototypePropertyType)) {
|
||||
targetType = prototypePropertyType;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't narrow from 'any' if the target type is exactly 'Object' or 'Function'
|
||||
if (isTypeAny(type) && (targetType === globalObjectType || targetType === globalFunctionType)) {
|
||||
const instanceType = mapType(rightType, getInstanceType);
|
||||
// Don't narrow from `any` if the target type is exactly `Object` or `Function`, and narrow
|
||||
// in the false branch only if the target is a non-empty object type.
|
||||
if (isTypeAny(type) && (instanceType === globalObjectType || instanceType === globalFunctionType) ||
|
||||
!assumeTrue && !(instanceType.flags & TypeFlags.Object && !isEmptyAnonymousObjectType(instanceType))) {
|
||||
return type;
|
||||
}
|
||||
return getNarrowedType(type, instanceType, assumeTrue, /*checkDerived*/ true);
|
||||
}
|
||||
|
||||
if (!targetType) {
|
||||
const constructSignatures = getSignaturesOfType(rightType, SignatureKind.Construct);
|
||||
targetType = constructSignatures.length ?
|
||||
getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature)))) :
|
||||
emptyObjectType;
|
||||
function getInstanceType(constructorType: Type) {
|
||||
const prototypePropertyType = getTypeOfPropertyOfType(constructorType, "prototype" as __String);
|
||||
if (prototypePropertyType && !isTypeAny(prototypePropertyType)) {
|
||||
return prototypePropertyType;
|
||||
}
|
||||
|
||||
// We can't narrow a union based off instanceof without negated types see #31576 for more info
|
||||
if (!assumeTrue && rightType.flags & TypeFlags.Union) {
|
||||
const nonConstructorTypeInUnion = find((rightType as UnionType).types, (t) => !isConstructorType(t));
|
||||
if (!nonConstructorTypeInUnion) return type;
|
||||
const constructSignatures = getSignaturesOfType(constructorType, SignatureKind.Construct);
|
||||
if (constructSignatures.length) {
|
||||
return getUnionType(map(constructSignatures, signature => getReturnTypeOfSignature(getErasedSignature(signature))));
|
||||
}
|
||||
|
||||
return getNarrowedType(type, targetType, assumeTrue, /*checkDerived*/ true);
|
||||
// We use the empty object type to indicate we don't know the type of objects created by
|
||||
// this constructor function.
|
||||
return emptyObjectType;
|
||||
}
|
||||
|
||||
function getNarrowedType(type: Type, candidate: Type, assumeTrue: boolean, checkDerived: boolean) {
|
||||
@@ -27178,7 +27202,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function getTypeOfSymbolAtLocation(symbol: Symbol, location: Node) {
|
||||
symbol = symbol.exportSymbol || symbol;
|
||||
symbol = getExportSymbolOfValueSymbolIfExported(symbol);
|
||||
|
||||
// If we have an identifier or a property access at the given location, if the location is
|
||||
// an dotted name expression, and if the location is not an assignment target, obtain the type
|
||||
@@ -27211,7 +27235,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
isFunctionLike(node) && !getImmediatelyInvokedFunctionExpression(node) ||
|
||||
node.kind === SyntaxKind.ModuleBlock ||
|
||||
node.kind === SyntaxKind.SourceFile ||
|
||||
node.kind === SyntaxKind.CatchClause ||
|
||||
node.kind === SyntaxKind.PropertyDeclaration)!;
|
||||
}
|
||||
|
||||
@@ -27587,7 +27610,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const isParameter = getRootDeclaration(declaration).kind === SyntaxKind.Parameter;
|
||||
const declarationContainer = getControlFlowContainer(declaration);
|
||||
let flowContainer = getControlFlowContainer(node);
|
||||
const isCatch = flowContainer.kind === SyntaxKind.CatchClause;
|
||||
const isOuterVariable = flowContainer !== declarationContainer;
|
||||
const isSpreadDestructuringAssignmentTarget = node.parent && node.parent.parent && isSpreadAssignment(node.parent) && isDestructuringAssignmentTarget(node.parent.parent);
|
||||
const isModuleExports = symbol.flags & SymbolFlags.ModuleExports;
|
||||
@@ -27602,7 +27624,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
|
||||
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
|
||||
// declaration container are the same).
|
||||
const assumeInitialized = isParameter || isCatch || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) ||
|
||||
const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) ||
|
||||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0 ||
|
||||
isInTypeQuery(node) || isInAmbientOrTypeNode(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
|
||||
node.parent.kind === SyntaxKind.NonNullExpression ||
|
||||
@@ -33739,6 +33761,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
declaration.kind !== SyntaxKind.Constructor &&
|
||||
declaration.kind !== SyntaxKind.ConstructSignature &&
|
||||
declaration.kind !== SyntaxKind.ConstructorType &&
|
||||
!(isJSDocSignature(declaration) && getJSDocRoot(declaration)?.parent?.kind === SyntaxKind.Constructor) &&
|
||||
!isJSDocConstructSignature(declaration) &&
|
||||
!isJSConstructor(declaration)) {
|
||||
|
||||
@@ -34037,6 +34060,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const exprType = node.kind === SyntaxKind.ExpressionWithTypeArguments ? checkExpression(node.expression) :
|
||||
isThisIdentifier(node.exprName) ? checkThisExpression(node.exprName) :
|
||||
checkExpression(node.exprName);
|
||||
return getInstantiationExpressionType(exprType, node);
|
||||
}
|
||||
|
||||
function getInstantiationExpressionType(exprType: Type, node: NodeWithTypeArguments) {
|
||||
const typeArguments = node.typeArguments;
|
||||
if (exprType === silentNeverType || isErrorType(exprType) || !some(typeArguments)) {
|
||||
return exprType;
|
||||
@@ -37165,8 +37192,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
else if (isAssertionExpression(expr) && !isConstTypeReference(expr.type)) {
|
||||
return getTypeFromTypeNode((expr as TypeAssertion).type);
|
||||
}
|
||||
else if (node.kind === SyntaxKind.NumericLiteral || node.kind === SyntaxKind.StringLiteral ||
|
||||
node.kind === SyntaxKind.TrueKeyword || node.kind === SyntaxKind.FalseKeyword) {
|
||||
else if (isLiteralExpression(node) || isBooleanLiteral(node)) {
|
||||
return checkExpression(node);
|
||||
}
|
||||
return undefined;
|
||||
@@ -43300,7 +43326,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
getNodeLinks(node).flags |= NodeCheckFlags.LexicalModuleMergesWithClass;
|
||||
}
|
||||
}
|
||||
if (compilerOptions.verbatimModuleSyntax && node.parent.kind === SyntaxKind.SourceFile) {
|
||||
if (compilerOptions.verbatimModuleSyntax &&
|
||||
node.parent.kind === SyntaxKind.SourceFile &&
|
||||
(moduleKind === ModuleKind.CommonJS || node.parent.impliedNodeFormat === ModuleKind.CommonJS)
|
||||
) {
|
||||
const exportModifier = node.modifiers?.find(m => m.kind === SyntaxKind.ExportKeyword);
|
||||
if (exportModifier) {
|
||||
error(exportModifier, Diagnostics.A_top_level_export_modifier_cannot_be_used_on_value_declarations_in_a_CommonJS_module_when_verbatimModuleSyntax_is_enabled);
|
||||
@@ -43901,12 +43930,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
const isIllegalExportDefaultInCJS = !node.isExportEquals &&
|
||||
!(node.flags & NodeFlags.Ambient) &&
|
||||
compilerOptions.verbatimModuleSyntax &&
|
||||
(moduleKind === ModuleKind.CommonJS || getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS);
|
||||
|
||||
if (node.expression.kind === SyntaxKind.Identifier) {
|
||||
const id = node.expression as Identifier;
|
||||
const sym = resolveEntityName(id, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node);
|
||||
const sym = getExportSymbolOfValueSymbolIfExported(resolveEntityName(id, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node));
|
||||
if (sym) {
|
||||
markAliasReferenced(sym, id);
|
||||
// If not a value, we're interpreting the identifier as a type export, along the lines of (`export { Id as default }`)
|
||||
@@ -44696,7 +44726,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return node.parent.kind === SyntaxKind.TypeReference;
|
||||
}
|
||||
|
||||
function isHeritageClauseElementIdentifier(node: Node): boolean {
|
||||
function isInNameOfExpressionWithTypeArguments(node: Node): boolean {
|
||||
while (node.parent.kind === SyntaxKind.PropertyAccessExpression) {
|
||||
node = node.parent;
|
||||
}
|
||||
@@ -44822,11 +44852,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
name = name.parent as QualifiedName | PropertyAccessEntityNameExpression | JSDocMemberName;
|
||||
}
|
||||
|
||||
if (isHeritageClauseElementIdentifier(name)) {
|
||||
if (isInNameOfExpressionWithTypeArguments(name)) {
|
||||
let meaning = SymbolFlags.None;
|
||||
// In an interface or class, we're definitely interested in a type.
|
||||
if (name.parent.kind === SyntaxKind.ExpressionWithTypeArguments) {
|
||||
meaning = SymbolFlags.Type;
|
||||
// An 'ExpressionWithTypeArguments' may appear in type space (interface Foo extends Bar<T>),
|
||||
// value space (return foo<T>), or both(class Foo extends Bar<T>); ensure the meaning matches.
|
||||
meaning = isPartOfTypeNode(name) ? SymbolFlags.Type : SymbolFlags.Value;
|
||||
|
||||
// In a class 'extends' clause we are also looking for a value.
|
||||
if (isExpressionWithTypeArgumentsInClassExtendsClause(name.parent)) {
|
||||
|
||||
@@ -1221,7 +1221,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
|
||||
{
|
||||
name: "allowArbitraryExtensions",
|
||||
type: "boolean",
|
||||
affectsModuleResolution: true,
|
||||
affectsProgramStructure: true,
|
||||
category: Diagnostics.Modules,
|
||||
description: Diagnostics.Enable_importing_files_with_any_extension_provided_a_declaration_file_is_present,
|
||||
defaultValueDescription: false,
|
||||
|
||||
@@ -1076,10 +1076,6 @@
|
||||
"category": "Error",
|
||||
"code": 1341
|
||||
},
|
||||
"Type arguments cannot be used here.": {
|
||||
"category": "Error",
|
||||
"code": 1342
|
||||
},
|
||||
"The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', or 'nodenext'.": {
|
||||
"category": "Error",
|
||||
"code": 1343
|
||||
@@ -3030,10 +3026,6 @@
|
||||
"category": "Error",
|
||||
"code": 2690
|
||||
},
|
||||
"An import path cannot end with a '{0}' extension. Consider importing '{1}' instead.": {
|
||||
"category": "Error",
|
||||
"code": 2691
|
||||
},
|
||||
"'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible.": {
|
||||
"category": "Error",
|
||||
"code": 2692
|
||||
@@ -3499,7 +3491,7 @@
|
||||
"category": "Error",
|
||||
"code": 2808
|
||||
},
|
||||
"Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the the whole assignment in parentheses.": {
|
||||
"Declaration or statement expected. This '=' follows a block of statements, so if you intended to write a destructuring assignment, you might need to wrap the whole assignment in parentheses.": {
|
||||
"category": "Error",
|
||||
"code": 2809
|
||||
},
|
||||
@@ -4647,7 +4639,7 @@
|
||||
"category": "Message",
|
||||
"code": 6096
|
||||
},
|
||||
"File '{0}' exist - use it as a name resolution result.": {
|
||||
"File '{0}' exists - use it as a name resolution result.": {
|
||||
"category": "Message",
|
||||
"code": 6097
|
||||
},
|
||||
@@ -5562,6 +5554,26 @@
|
||||
"category": "Message",
|
||||
"code": 6411
|
||||
},
|
||||
"Project '{0}' is out of date because buildinfo file '{1}' indicates that file '{2}' was root file of compilation but not any more.": {
|
||||
"category": "Message",
|
||||
"code": 6412
|
||||
},
|
||||
"Entering conditional exports.": {
|
||||
"category": "Message",
|
||||
"code": 6413
|
||||
},
|
||||
"Resolved under condition '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6414
|
||||
},
|
||||
"Failed to resolve under condition '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6415
|
||||
},
|
||||
"Exiting conditional exports.": {
|
||||
"category": "Message",
|
||||
"code": 6416
|
||||
},
|
||||
|
||||
"The expected type comes from property '{0}' which is declared here on type '{1}'": {
|
||||
"category": "Message",
|
||||
@@ -6209,6 +6221,10 @@
|
||||
"category": "Error",
|
||||
"code": 7011
|
||||
},
|
||||
"This overload implicitly returns the type '{0}' because it lacks a return type annotation.": {
|
||||
"category": "Error",
|
||||
"code": 7012
|
||||
},
|
||||
"Construct signature, which lacks return-type annotation, implicitly has an 'any' return type.": {
|
||||
"category": "Error",
|
||||
"code": 7013
|
||||
|
||||
@@ -1343,6 +1343,18 @@ const enum PipelinePhase {
|
||||
Emit,
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const createPrinterWithDefaults = /* @__PURE__ */ memoize(() => createPrinter({}));
|
||||
|
||||
/** @internal */
|
||||
export const createPrinterWithRemoveComments = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true }));
|
||||
|
||||
/** @internal */
|
||||
export const createPrinterWithRemoveCommentsNeverAsciiEscape = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true, neverAsciiEscape: true }));
|
||||
|
||||
/** @internal */
|
||||
export const createPrinterWithRemoveCommentsOmitTrailingSemicolon = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true, omitTrailingSemicolon: true }));
|
||||
|
||||
export function createPrinter(printerOptions: PrinterOptions = {}, handlers: PrintHandlers = {}): Printer {
|
||||
const {
|
||||
hasGlobalName,
|
||||
|
||||
@@ -103,8 +103,8 @@ import {
|
||||
tryExtractTSExtension,
|
||||
tryGetExtensionFromPath,
|
||||
tryParsePatterns,
|
||||
version,
|
||||
Version,
|
||||
version,
|
||||
versionMajorMinor,
|
||||
VersionRange,
|
||||
} from "./_namespaces/ts";
|
||||
@@ -206,6 +206,38 @@ function resolvedTypeScriptOnly(resolved: Resolved | undefined): PathAndPackageI
|
||||
return { fileName: resolved.path, packageId: resolved.packageId };
|
||||
}
|
||||
|
||||
function createResolvedModuleWithFailedLookupLocationsHandlingSymlink(
|
||||
moduleName: string,
|
||||
resolved: Resolved | undefined,
|
||||
isExternalLibraryImport: boolean | undefined,
|
||||
failedLookupLocations: string[],
|
||||
affectingLocations: string[],
|
||||
diagnostics: Diagnostic[],
|
||||
state: ModuleResolutionState,
|
||||
legacyResult?: string,
|
||||
): ResolvedModuleWithFailedLookupLocations {
|
||||
// If this is from node_modules for non relative name, always respect preserveSymlinks
|
||||
if (!state.resultFromCache &&
|
||||
!state.compilerOptions.preserveSymlinks &&
|
||||
resolved &&
|
||||
isExternalLibraryImport &&
|
||||
!resolved.originalPath &&
|
||||
!isExternalModuleNameRelative(moduleName)
|
||||
) {
|
||||
const { resolvedFileName, originalPath } = getOriginalAndResolvedFileName(resolved.path, state.host, state.traceEnabled);
|
||||
if (originalPath) resolved = { ...resolved, path: resolvedFileName, originalPath };
|
||||
}
|
||||
return createResolvedModuleWithFailedLookupLocations(
|
||||
resolved,
|
||||
isExternalLibraryImport,
|
||||
failedLookupLocations,
|
||||
affectingLocations,
|
||||
diagnostics,
|
||||
state.resultFromCache,
|
||||
legacyResult,
|
||||
);
|
||||
}
|
||||
|
||||
function createResolvedModuleWithFailedLookupLocations(
|
||||
resolved: Resolved | undefined,
|
||||
isExternalLibraryImport: boolean | undefined,
|
||||
@@ -450,6 +482,16 @@ function arePathsEqual(path1: string, path2: string, host: ModuleResolutionHost)
|
||||
return comparePaths(path1, path2, !useCaseSensitiveFileNames) === Comparison.EqualTo;
|
||||
}
|
||||
|
||||
function getOriginalAndResolvedFileName(fileName: string, host: ModuleResolutionHost, traceEnabled: boolean) {
|
||||
const resolvedFileName = realPath(fileName, host, traceEnabled);
|
||||
const pathsAreEqual = arePathsEqual(fileName, resolvedFileName, host);
|
||||
return {
|
||||
// If the fileName and realpath are differing only in casing prefer fileName so that we can issue correct errors for casing under forceConsistentCasingInFileNames
|
||||
resolvedFileName: pathsAreEqual ? fileName : resolvedFileName,
|
||||
originalPath: pathsAreEqual ? undefined : fileName,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
|
||||
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
|
||||
@@ -541,13 +583,12 @@ export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string
|
||||
let resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined;
|
||||
if (resolved) {
|
||||
const { fileName, packageId } = resolved;
|
||||
const resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled);
|
||||
const pathsAreEqual = arePathsEqual(fileName, resolvedFileName, host);
|
||||
let resolvedFileName = fileName, originalPath: string | undefined;
|
||||
if (!options.preserveSymlinks) ({ resolvedFileName, originalPath } = getOriginalAndResolvedFileName(fileName, host, traceEnabled));
|
||||
resolvedTypeReferenceDirective = {
|
||||
primary,
|
||||
// If the fileName and realpath are differing only in casing prefer fileName so that we can issue correct errors for casing under forceConsistentCasingInFileNames
|
||||
resolvedFileName: pathsAreEqual ? fileName : resolvedFileName,
|
||||
originalPath: pathsAreEqual ? undefined : fileName,
|
||||
resolvedFileName,
|
||||
originalPath,
|
||||
packageId,
|
||||
isExternalLibraryImport: pathContainsNodeModules(fileName),
|
||||
};
|
||||
@@ -659,7 +700,8 @@ function getNodeResolutionFeatures(options: CompilerOptions) {
|
||||
return features;
|
||||
}
|
||||
|
||||
function getConditions(options: CompilerOptions, esmMode?: boolean) {
|
||||
/** @internal */
|
||||
export function getConditions(options: CompilerOptions, esmMode?: boolean) {
|
||||
// conditions are only used by the node16/nodenext/bundler resolvers - there's no priority order in the list,
|
||||
// it's essentially a set (priority is determined by object insertion order in the object we look at).
|
||||
const conditions = esmMode || getEmitModuleResolutionKind(options) === ModuleResolutionKind.Bundler
|
||||
@@ -1701,13 +1743,14 @@ function nodeModuleNameResolverWorker(features: NodeResolutionFeatures, moduleNa
|
||||
}
|
||||
}
|
||||
|
||||
return createResolvedModuleWithFailedLookupLocations(
|
||||
return createResolvedModuleWithFailedLookupLocationsHandlingSymlink(
|
||||
moduleName,
|
||||
result?.value?.resolved,
|
||||
result?.value?.isExternalLibraryImport,
|
||||
failedLookupLocations,
|
||||
affectingLocations,
|
||||
diagnostics,
|
||||
state.resultFromCache,
|
||||
state,
|
||||
legacyResult,
|
||||
);
|
||||
|
||||
@@ -1732,18 +1775,8 @@ function nodeModuleNameResolverWorker(features: NodeResolutionFeatures, moduleNa
|
||||
}
|
||||
resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
|
||||
}
|
||||
if (!resolved) return undefined;
|
||||
|
||||
let resolvedValue = resolved.value;
|
||||
if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
|
||||
const path = realPath(resolvedValue.path, host, traceEnabled);
|
||||
const pathsAreEqual = arePathsEqual(path, resolvedValue.path, host);
|
||||
const originalPath = pathsAreEqual ? undefined : resolvedValue.path;
|
||||
// If the path and realpath are differing only in casing prefer path so that we can issue correct errors for casing under forceConsistentCasingInFileNames
|
||||
resolvedValue = { ...resolvedValue, path: pathsAreEqual ? resolvedValue.path : path, originalPath };
|
||||
}
|
||||
// For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
|
||||
return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
|
||||
return resolved && { value: resolved.value && { resolved: resolved.value, isExternalLibraryImport: true } };
|
||||
}
|
||||
else {
|
||||
const { path: candidate, parts } = normalizePathForCJSResolution(containingDirectory, moduleName);
|
||||
@@ -1998,7 +2031,7 @@ function tryFileLookup(fileName: string, onlyRecordFailures: boolean, state: Mod
|
||||
if (!onlyRecordFailures) {
|
||||
if (state.host.fileExists(fileName)) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName);
|
||||
trace(state.host, Diagnostics.File_0_exists_use_it_as_a_name_resolution_result, fileName);
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
@@ -2551,19 +2584,26 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
|
||||
}
|
||||
else if (typeof target === "object" && target !== null) { // eslint-disable-line no-null/no-null
|
||||
if (!Array.isArray(target)) {
|
||||
traceIfEnabled(state, Diagnostics.Entering_conditional_exports);
|
||||
for (const condition of getOwnKeys(target as MapLike<unknown>)) {
|
||||
if (condition === "default" || state.conditions.indexOf(condition) >= 0 || isApplicableVersionedTypesKey(state.conditions, condition)) {
|
||||
traceIfEnabled(state, Diagnostics.Matched_0_condition_1, isImports ? "imports" : "exports", condition);
|
||||
const subTarget = (target as MapLike<unknown>)[condition];
|
||||
const result = loadModuleFromTargetImportOrExport(subTarget, subpath, pattern, key);
|
||||
if (result) {
|
||||
traceIfEnabled(state, Diagnostics.Resolved_under_condition_0, condition);
|
||||
traceIfEnabled(state, Diagnostics.Exiting_conditional_exports);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
traceIfEnabled(state, Diagnostics.Failed_to_resolve_under_condition_0, condition);
|
||||
}
|
||||
}
|
||||
else {
|
||||
traceIfEnabled(state, Diagnostics.Saw_non_matching_condition_0, condition);
|
||||
}
|
||||
}
|
||||
traceIfEnabled(state, Diagnostics.Exiting_conditional_exports);
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
@@ -2990,13 +3030,14 @@ export function classicNameResolver(moduleName: string, containingFile: string,
|
||||
tryResolve(Extensions.TypeScript | Extensions.Declaration) ||
|
||||
tryResolve(Extensions.JavaScript | (compilerOptions.resolveJsonModule ? Extensions.Json : 0));
|
||||
// No originalPath because classic resolution doesn't resolve realPath
|
||||
return createResolvedModuleWithFailedLookupLocations(
|
||||
return createResolvedModuleWithFailedLookupLocationsHandlingSymlink(
|
||||
moduleName,
|
||||
resolved && resolved.value,
|
||||
resolved?.value && pathContainsNodeModules(resolved.value.path),
|
||||
failedLookupLocations,
|
||||
affectingLocations,
|
||||
diagnostics,
|
||||
state.resultFromCache
|
||||
state,
|
||||
);
|
||||
|
||||
function tryResolve(extensions: Extensions): SearchResult<Resolved> {
|
||||
@@ -3032,6 +3073,7 @@ export function classicNameResolver(moduleName: string, containingFile: string,
|
||||
|
||||
// Program errors validate that `noEmit` or `emitDeclarationOnly` is also set,
|
||||
// so this function doesn't check them to avoid propagating errors.
|
||||
/** @internal */
|
||||
export function shouldAllowImportingTsExtension(compilerOptions: CompilerOptions, fromFileName?: string) {
|
||||
return !!compilerOptions.allowImportingTsExtensions || fromFileName && isDeclarationFileName(fromFileName);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
forEachAncestorDirectory,
|
||||
getBaseFileName,
|
||||
GetCanonicalFileName,
|
||||
getConditions,
|
||||
getDirectoryPath,
|
||||
getEmitModuleResolutionKind,
|
||||
getModeForResolutionAtIndex,
|
||||
@@ -46,6 +47,7 @@ import {
|
||||
getPathsBasePath,
|
||||
getRelativePathFromDirectory,
|
||||
getRelativePathToDirectoryOrUrl,
|
||||
getResolvePackageJsonExports,
|
||||
getSourceFileOfModule,
|
||||
getSupportedExtensions,
|
||||
getTextOfIdentifierOrLiteral,
|
||||
@@ -369,7 +371,9 @@ function computeModuleSpecifiers(
|
||||
let redirectPathsSpecifiers: string[] | undefined;
|
||||
let relativeSpecifiers: string[] | undefined;
|
||||
for (const modulePath of modulePaths) {
|
||||
const specifier = tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode);
|
||||
const specifier = modulePath.isInNodeModules
|
||||
? tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode)
|
||||
: undefined;
|
||||
nodeModulesSpecifiers = append(nodeModulesSpecifiers, specifier);
|
||||
if (specifier && modulePath.isRedirect) {
|
||||
// If we got a specifier for a redirect, it was a bare package specifier (e.g. "@foo/bar",
|
||||
@@ -945,10 +949,15 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan
|
||||
if (typeof cachedPackageJson === "object" || cachedPackageJson === undefined && host.fileExists(packageJsonPath)) {
|
||||
const packageJsonContent = cachedPackageJson?.contents.packageJsonContent || JSON.parse(host.readFile!(packageJsonPath)!);
|
||||
const importMode = overrideMode || importingSourceFile.impliedNodeFormat;
|
||||
if (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext) {
|
||||
const conditions = ["node", importMode === ModuleKind.ESNext ? "import" : "require", "types"];
|
||||
const fromExports = packageJsonContent.exports && typeof packageJsonContent.name === "string"
|
||||
? tryGetModuleNameFromExports(options, path, packageRootPath, getPackageNameFromTypesPackageName(packageJsonContent.name), packageJsonContent.exports, conditions)
|
||||
if (getResolvePackageJsonExports(options)) {
|
||||
// The package name that we found in node_modules could be different from the package
|
||||
// name in the package.json content via url/filepath dependency specifiers. We need to
|
||||
// use the actual directory name, so don't look at `packageJsonContent.name` here.
|
||||
const nodeModulesDirectoryName = packageRootPath.substring(parts.topLevelPackageNameIndex + 1);
|
||||
const packageName = getPackageNameFromTypesPackageName(nodeModulesDirectoryName);
|
||||
const conditions = getConditions(options, importMode === ModuleKind.ESNext);
|
||||
const fromExports = packageJsonContent.exports
|
||||
? tryGetModuleNameFromExports(options, path, packageRootPath, packageName, packageJsonContent.exports, conditions)
|
||||
: undefined;
|
||||
if (fromExports) {
|
||||
const withJsExtension = !hasTSFileExtension(fromExports.moduleFileToTry)
|
||||
|
||||
@@ -5201,6 +5201,7 @@ namespace Parser {
|
||||
switch (fourth) {
|
||||
case SyntaxKind.EqualsToken:
|
||||
case SyntaxKind.GreaterThanToken:
|
||||
case SyntaxKind.SlashToken:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
@@ -6620,7 +6621,7 @@ namespace Parser {
|
||||
parseExpectedMatchingBrackets(SyntaxKind.OpenBraceToken, SyntaxKind.CloseBraceToken, openBraceParsed, openBracePosition);
|
||||
const result = withJSDoc(finishNode(factory.createBlock(statements, multiLine), pos), hasJSDoc);
|
||||
if (token() === SyntaxKind.EqualsToken) {
|
||||
parseErrorAtCurrentToken(Diagnostics.Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_the_whole_assignment_in_parentheses);
|
||||
parseErrorAtCurrentToken(Diagnostics.Declaration_or_statement_expected_This_follows_a_block_of_statements_so_if_you_intended_to_write_a_destructuring_assignment_you_might_need_to_wrap_the_whole_assignment_in_parentheses);
|
||||
nextToken();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ import {
|
||||
|
||||
/** Performance measurements for the compiler. */
|
||||
|
||||
// NOTE: declared global is injected by ts-perf to monitor profiler marks to generate heap snapshots.
|
||||
declare let onProfilerEvent: ((eventName: string) => void) | undefined;
|
||||
|
||||
let perfHooks: PerformanceHooks | undefined;
|
||||
// when set, indicates the implementation of `Performance` to use for user timing.
|
||||
// when unset, indicates user timing is unavailable or disabled.
|
||||
@@ -74,6 +77,9 @@ export function mark(markName: string) {
|
||||
counts.set(markName, count + 1);
|
||||
marks.set(markName, timestamp());
|
||||
performanceImpl?.mark(markName);
|
||||
if (typeof onProfilerEvent === "function") {
|
||||
onProfilerEvent(markName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -961,14 +961,14 @@ export function createModuleResolutionLoader(
|
||||
): ResolutionLoader<StringLiteralLike, ResolvedModuleWithFailedLookupLocations, SourceFile> {
|
||||
return {
|
||||
nameAndMode: moduleResolutionNameAndModeGetter,
|
||||
resolve: (moduleName, resoluionMode) => resolveModuleName(
|
||||
resolve: (moduleName, resolutionMode) => resolveModuleName(
|
||||
moduleName,
|
||||
containingFile,
|
||||
options,
|
||||
host,
|
||||
cache,
|
||||
redirectedReference,
|
||||
resoluionMode,
|
||||
resolutionMode,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ import {
|
||||
transformECMAScriptModule,
|
||||
Transformer,
|
||||
TransformerFactory,
|
||||
transformES5,
|
||||
transformES2015,
|
||||
transformES2016,
|
||||
transformES2017,
|
||||
@@ -62,7 +63,6 @@ import {
|
||||
transformES2019,
|
||||
transformES2020,
|
||||
transformES2021,
|
||||
transformES5,
|
||||
transformESDecorators,
|
||||
transformESNext,
|
||||
transformGenerators,
|
||||
|
||||
@@ -113,6 +113,7 @@ import {
|
||||
isFunctionLike,
|
||||
isGlobalScopeAugmentation,
|
||||
isIdentifier,
|
||||
isIdentifierANonContextualKeyword,
|
||||
isImportDeclaration,
|
||||
isImportEqualsDeclaration,
|
||||
isIndexSignatureDeclaration,
|
||||
@@ -695,7 +696,7 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
if (elem.kind === SyntaxKind.OmittedExpression) {
|
||||
return elem;
|
||||
}
|
||||
if (elem.propertyName && isIdentifier(elem.propertyName) && isIdentifier(elem.name) && !elem.symbol.isReferenced) {
|
||||
if (elem.propertyName && isIdentifier(elem.propertyName) && isIdentifier(elem.name) && !elem.symbol.isReferenced && !isIdentifierANonContextualKeyword(elem.propertyName)) {
|
||||
// Unnecessary property renaming is forbidden in types, so remove renaming
|
||||
return factory.updateBindingElement(
|
||||
elem,
|
||||
|
||||
+10
-1
@@ -2,6 +2,7 @@ import {
|
||||
combinePaths,
|
||||
Extension,
|
||||
fileExtensionIs,
|
||||
Path,
|
||||
ResolvedConfigFileName,
|
||||
} from "./_namespaces/ts";
|
||||
|
||||
@@ -28,6 +29,7 @@ export enum UpToDateStatusType {
|
||||
OutOfDateWithUpstream,
|
||||
OutOfDateBuildInfo,
|
||||
OutOfDateOptions,
|
||||
OutOfDateRoots,
|
||||
UpstreamOutOfDate,
|
||||
UpstreamBlocked,
|
||||
ComputingUpstream,
|
||||
@@ -51,6 +53,7 @@ export type UpToDateStatus =
|
||||
| Status.OutOfDateWithSelf
|
||||
| Status.OutOfDateWithUpstream
|
||||
| Status.OutOfDateBuildInfo
|
||||
| Status.OutOfDateRoots
|
||||
| Status.UpstreamOutOfDate
|
||||
| Status.UpstreamBlocked
|
||||
| Status.ComputingUpstream
|
||||
@@ -127,10 +130,16 @@ export namespace Status {
|
||||
* Buildinfo indicates that build is out of date
|
||||
*/
|
||||
export interface OutOfDateBuildInfo {
|
||||
type: UpToDateStatusType.OutOfDateBuildInfo | UpToDateStatusType.OutOfDateOptions,
|
||||
type: UpToDateStatusType.OutOfDateBuildInfo | UpToDateStatusType.OutOfDateOptions;
|
||||
buildInfoFile: string;
|
||||
}
|
||||
|
||||
export interface OutOfDateRoots {
|
||||
type: UpToDateStatusType.OutOfDateRoots,
|
||||
buildInfoFile: string;
|
||||
inputFile: Path;
|
||||
}
|
||||
|
||||
/**
|
||||
* This project depends on an out-of-date project, so shouldn't be built yet
|
||||
*/
|
||||
|
||||
@@ -1729,7 +1729,7 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
|
||||
let oldestOutputFileTime = maximumDate;
|
||||
let buildInfoTime: Date | undefined;
|
||||
let buildInfoProgram: ProgramBuildInfo | undefined;
|
||||
let buildInfoVersionMap: Map<Path, string> | undefined;
|
||||
let buildInfoVersionMap: ReturnType<typeof getBuildInfoFileVersionMap> | undefined;
|
||||
if (buildInfoPath) {
|
||||
const buildInfoCacheEntry = getBuildInfoCacheEntry(state, buildInfoPath, resolvedPath);
|
||||
buildInfoTime = buildInfoCacheEntry?.modifiedTime || ts.getModifiedTime(host, buildInfoPath);
|
||||
@@ -1798,6 +1798,7 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
|
||||
let newestInputFileTime = minimumDate;
|
||||
/** True if input file has changed timestamp but text is not changed, we can then do only timestamp updates on output to make it look up-to-date later */
|
||||
let pseudoInputUpToDate = false;
|
||||
const seenRoots = new Set<Path>();
|
||||
// Get timestamps of input files
|
||||
for (const inputFile of project.fileNames) {
|
||||
const inputTime = getModifiedTime(state, inputFile);
|
||||
@@ -1815,7 +1816,7 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
|
||||
if (buildInfoProgram) {
|
||||
// Read files and see if they are same, read is anyways cached
|
||||
if (!buildInfoVersionMap) buildInfoVersionMap = getBuildInfoFileVersionMap(buildInfoProgram, buildInfoPath!, host);
|
||||
version = buildInfoVersionMap.get(toPath(state, inputFile));
|
||||
version = buildInfoVersionMap.fileInfos.get(toPath(state, inputFile));
|
||||
const text = version ? state.readFileWithCache(inputFile) : undefined;
|
||||
currentVersion = text !== undefined ? getSourceFileVersionAsHashFromText(host, text) : undefined;
|
||||
if (version && version === currentVersion) pseudoInputUpToDate = true;
|
||||
@@ -1834,6 +1835,22 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
|
||||
newestInputFileName = inputFile;
|
||||
newestInputFileTime = inputTime;
|
||||
}
|
||||
|
||||
if (buildInfoProgram) seenRoots.add(toPath(state, inputFile));
|
||||
}
|
||||
|
||||
if (buildInfoProgram) {
|
||||
if (!buildInfoVersionMap) buildInfoVersionMap = getBuildInfoFileVersionMap(buildInfoProgram, buildInfoPath!, host);
|
||||
for (const existingRoot of buildInfoVersionMap.roots) {
|
||||
if (!seenRoots.has(existingRoot)) {
|
||||
// File was root file when project was built but its not any more
|
||||
return {
|
||||
type: UpToDateStatusType.OutOfDateRoots,
|
||||
buildInfoFile: buildInfoPath!,
|
||||
inputFile: existingRoot,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now see if all outputs are newer than the newest input
|
||||
@@ -2561,6 +2578,14 @@ function reportUpToDateStatus<T extends BuilderProgram>(state: SolutionBuilderSt
|
||||
relName(state, configFileName),
|
||||
relName(state, status.buildInfoFile)
|
||||
);
|
||||
case UpToDateStatusType.OutOfDateRoots:
|
||||
return reportStatus(
|
||||
state,
|
||||
Diagnostics.Project_0_is_out_of_date_because_buildinfo_file_1_indicates_that_file_2_was_root_file_of_compilation_but_not_any_more,
|
||||
relName(state, configFileName),
|
||||
relName(state, status.buildInfoFile),
|
||||
relName(state, status.inputFile),
|
||||
);
|
||||
case UpToDateStatusType.UpToDate:
|
||||
if (status.newestInputFileTime !== undefined) {
|
||||
return reportStatus(
|
||||
|
||||
+19
-5
@@ -4927,7 +4927,7 @@ export interface TypeCheckerHost extends ModuleSpecifierResolutionHost {
|
||||
|
||||
export interface TypeChecker {
|
||||
getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type;
|
||||
/** @internal */ getTypeOfSymbol(symbol: Symbol): Type;
|
||||
getTypeOfSymbol(symbol: Symbol): Type;
|
||||
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
|
||||
getPropertiesOfType(type: Type): Symbol[];
|
||||
getPropertyOfType(type: Type, propertyName: string): Symbol | undefined;
|
||||
@@ -4946,6 +4946,8 @@ export interface TypeChecker {
|
||||
getPromisedTypeOfPromise(promise: Type, errorNode?: Node): Type | undefined;
|
||||
/** @internal */
|
||||
getAwaitedType(type: Type): Type | undefined;
|
||||
/** @internal */
|
||||
isEmptyAnonymousObjectType(type: Type): boolean;
|
||||
getReturnTypeOfSignature(signature: Signature): Type;
|
||||
/**
|
||||
* Gets the type of a parameter at a given position in a signature.
|
||||
@@ -5153,9 +5155,21 @@ export interface TypeChecker {
|
||||
/** @internal */ getRecursionIdentity(type: Type): object | undefined;
|
||||
/** @internal */ getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean): IterableIterator<Symbol>;
|
||||
|
||||
/** @internal */ isArrayType(type: Type): boolean;
|
||||
/** @internal */ isTupleType(type: Type): boolean;
|
||||
/** @internal */ isArrayLikeType(type: Type): boolean;
|
||||
/**
|
||||
* True if this type is the `Array` or `ReadonlyArray` type from lib.d.ts.
|
||||
* This function will _not_ return true if passed a type which
|
||||
* extends `Array` (for example, the TypeScript AST's `NodeArray` type).
|
||||
*/
|
||||
isArrayType(type: Type): boolean;
|
||||
/**
|
||||
* True if this type is a tuple type. This function will _not_ return true if
|
||||
* passed a type which extends from a tuple.
|
||||
*/
|
||||
isTupleType(type: Type): boolean;
|
||||
/**
|
||||
* True if this type is assignable to `ReadonlyArray<any>`.
|
||||
*/
|
||||
isArrayLikeType(type: Type): boolean;
|
||||
|
||||
/**
|
||||
* True if `contextualType` should not be considered for completions because
|
||||
@@ -6409,7 +6423,7 @@ export interface AnonymousType extends ObjectType {
|
||||
|
||||
/** @internal */
|
||||
export interface InstantiationExpressionType extends AnonymousType {
|
||||
node: ExpressionWithTypeArguments | TypeQueryNode;
|
||||
node: NodeWithTypeArguments;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
@@ -199,8 +199,8 @@ import {
|
||||
HasExpressionInitializer,
|
||||
hasExtension,
|
||||
HasFlowNode,
|
||||
hasInitializer,
|
||||
HasInitializer,
|
||||
hasInitializer,
|
||||
HasJSDoc,
|
||||
hasJSDocNodes,
|
||||
HasModifiers,
|
||||
@@ -1279,6 +1279,20 @@ export function getScriptTargetFeatures(): ScriptTargetFeatures {
|
||||
BigUint64Array: ["at"],
|
||||
ObjectConstructor: ["hasOwn"],
|
||||
Error: ["cause"]
|
||||
},
|
||||
es2023: {
|
||||
Array: ["findLastIndex", "findLast"],
|
||||
Int8Array: ["findLastIndex", "findLast"],
|
||||
Uint8Array: ["findLastIndex", "findLast"],
|
||||
Uint8ClampedArray: ["findLastIndex", "findLast"],
|
||||
Int16Array: ["findLastIndex", "findLast"],
|
||||
Uint16Array: ["findLastIndex", "findLast"],
|
||||
Int32Array: ["findLastIndex", "findLast"],
|
||||
Uint32Array: ["findLastIndex", "findLast"],
|
||||
Float32Array: ["findLastIndex", "findLast"],
|
||||
Float64Array: ["findLastIndex", "findLast"],
|
||||
BigInt64Array: ["findLastIndex", "findLast"],
|
||||
BigUint64Array: ["findLastIndex", "findLast"],
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -7975,6 +7989,7 @@ export function getEmitModuleKind(compilerOptions: {module?: CompilerOptions["mo
|
||||
getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2015 ? ModuleKind.ES2015 : ModuleKind.CommonJS;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function emitModuleKindIsNonNodeESM(moduleKind: ModuleKind) {
|
||||
return moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext;
|
||||
}
|
||||
@@ -9065,7 +9080,7 @@ export function rangeOfNode(node: Node): TextRange {
|
||||
export function rangeOfTypeParameters(sourceFile: SourceFile, typeParameters: NodeArray<TypeParameterDeclaration>): TextRange {
|
||||
// Include the `<>`
|
||||
const pos = typeParameters.pos - 1;
|
||||
const end = skipTrivia(sourceFile.text, typeParameters.end) + 1;
|
||||
const end = Math.min(sourceFile.text.length, skipTrivia(sourceFile.text, typeParameters.end) + 1);
|
||||
return { pos, end };
|
||||
}
|
||||
|
||||
|
||||
@@ -1454,7 +1454,7 @@ const visitEachChildTable: VisitEachChildTable = {
|
||||
|
||||
[SyntaxKind.JsxExpression]: function visitEachChildOfJsxExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) {
|
||||
return context.factory.updateJsxExpression(node,
|
||||
Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)));
|
||||
nodeVisitor(node.expression, visitor, isExpression));
|
||||
},
|
||||
|
||||
// Clauses
|
||||
|
||||
@@ -3,8 +3,8 @@ import {
|
||||
DeprecationOptions,
|
||||
formatStringFromArgs,
|
||||
noop,
|
||||
version,
|
||||
Version,
|
||||
version,
|
||||
} from "./_namespaces/ts";
|
||||
|
||||
export let enableDeprecationWarnings = true;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as performance from "../compiler/_namespaces/ts.performance";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import {
|
||||
arrayFrom,
|
||||
@@ -19,8 +20,8 @@ import {
|
||||
createDiagnosticReporter,
|
||||
createGetCanonicalFileName,
|
||||
createIncrementalCompilerHost,
|
||||
createProgram,
|
||||
CreateProgram,
|
||||
createProgram,
|
||||
CreateProgramOptions,
|
||||
createSolutionBuilder,
|
||||
createSolutionBuilderHost,
|
||||
@@ -87,7 +88,6 @@ import {
|
||||
WatchCompilerHost,
|
||||
WatchOptions,
|
||||
} from "./_namespaces/ts";
|
||||
import * as performance from "../compiler/_namespaces/ts.performance";
|
||||
|
||||
interface Statistic {
|
||||
name: string;
|
||||
|
||||
@@ -727,7 +727,7 @@ export class SessionClient implements LanguageService {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getDocCommentTemplateAtPosition(_fileName: string, _position: number, _options?: DocCommentTemplateOptions): TextInsertion {
|
||||
getDocCommentTemplateAtPosition(_fileName: string, _position: number, _options?: DocCommentTemplateOptions, _formatOptions?: FormatCodeSettings): TextInsertion {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as fakes from "./_namespaces/fakes";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
import * as documents from "./_namespaces/documents";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as collections from "./_namespaces/collections";
|
||||
import * as documents from "./_namespaces/documents";
|
||||
import * as fakes from "./_namespaces/fakes";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
/**
|
||||
* Test harness compiler functionality.
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as fakes from "./_namespaces/fakes";
|
||||
import * as compiler from "./_namespaces/compiler";
|
||||
import * as fakes from "./_namespaces/fakes";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
declare let Symbol: SymbolConstructor;
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
import * as documents from "./_namespaces/documents";
|
||||
import * as collections from "./_namespaces/collections";
|
||||
import * as documents from "./_namespaces/documents";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
/**
|
||||
* Fake implementations of various compiler dependencies.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as fakes from "./_namespaces/fakes";
|
||||
import * as FourSlashInterface from "./_namespaces/FourSlashInterface";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as fakes from "./_namespaces/fakes";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
import ArrayOrSingle = FourSlashInterface.ArrayOrSingle;
|
||||
|
||||
@@ -2046,6 +2046,22 @@ export class TestState {
|
||||
? entry.displayParts.map(p => p.text).join("").split("\n")
|
||||
: [`(${entry.kindModifiers}${entry.kind}) ${entry.name}`])
|
||||
);
|
||||
for (const r of result) {
|
||||
for (const entry of r.item.entries ?? ts.emptyArray) {
|
||||
for (const tag of entry.tags ?? ts.emptyArray) {
|
||||
for (const part of tag.text ?? ts.emptyArray) {
|
||||
if (part.kind === "linkName") {
|
||||
const link = part as ts.JSDocLinkDisplayPart;
|
||||
if (/lib(?:.*)\.d\.ts$/.test(link.target.fileName)) {
|
||||
// The object literal isn't a complete TextSpan, but we're only going to
|
||||
// use these results in the baseline for diffing, so just overwrite.
|
||||
(link.target.textSpan as any) = { start: "--", length: "--" };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Harness.Baseline.runBaseline(baselineFile, annotations + "\n\n" + stringify(result));
|
||||
}
|
||||
|
||||
@@ -3249,7 +3265,7 @@ export class TestState {
|
||||
|
||||
public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined, options?: ts.DocCommentTemplateOptions) {
|
||||
const name = "verifyDocCommentTemplate";
|
||||
const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition, options || { generateReturnInDocTemplate: true })!;
|
||||
const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition, options || { generateReturnInDocTemplate: true }, this.formatCodeSettings)!;
|
||||
|
||||
if (expected === undefined) {
|
||||
if (actual) {
|
||||
|
||||
@@ -452,7 +452,7 @@ export class Verify extends VerifyNegatable {
|
||||
|
||||
public docCommentTemplateAt(marker: string | FourSlash.Marker, expectedOffset: number, expectedText: string, options?: ts.DocCommentTemplateOptions) {
|
||||
this.state.goToMarker(marker);
|
||||
this.state.verifyDocCommentTemplate({ newText: expectedText.replace(/\r?\n/g, "\r\n"), caretOffset: expectedOffset }, options);
|
||||
this.state.verifyDocCommentTemplate({ newText: expectedText.replace(/\r?\n/g, ts.testFormatSettings.newLineCharacter!), caretOffset: expectedOffset }, options);
|
||||
}
|
||||
|
||||
public noDocCommentTemplateAt(marker: string | FourSlash.Marker) {
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as compiler from "./_namespaces/compiler";
|
||||
import * as documents from "./_namespaces/documents";
|
||||
import * as fakes from "./_namespaces/fakes";
|
||||
@@ -10,6 +6,10 @@ import {
|
||||
TypeWriterResult,
|
||||
TypeWriterWalker,
|
||||
} from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
export interface IO {
|
||||
newLine(): string;
|
||||
@@ -616,7 +616,11 @@ export namespace Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
yield [diagnosticSummaryMarker, Utils.removeTestPathPrefixes(minimalDiagnosticsToString(diagnostics, options && options.pretty)) + IO.newLine() + IO.newLine(), diagnostics.length];
|
||||
let topDiagnostics = minimalDiagnosticsToString(diagnostics, options && options.pretty);
|
||||
topDiagnostics = Utils.removeTestPathPrefixes(topDiagnostics);
|
||||
topDiagnostics = topDiagnostics.replace(/^(lib(?:.*)\.d\.ts)\(\d+,\d+\)/igm, "$1(--,--)");
|
||||
|
||||
yield [diagnosticSummaryMarker, topDiagnostics + IO.newLine() + IO.newLine(), diagnostics.length];
|
||||
|
||||
// Report global errors
|
||||
const globalErrors = diagnostics.filter(err => !err.file);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as fakes from "./_namespaces/fakes";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as collections from "./_namespaces/collections";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
import * as fakes from "./_namespaces/fakes";
|
||||
import {
|
||||
Compiler,
|
||||
mockHash,
|
||||
virtualFileSystemRoot,
|
||||
} from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import { getNewLineCharacter } from "./_namespaces/ts";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
export function makeDefaultProxy(info: ts.server.PluginCreateInfo): ts.LanguageService {
|
||||
const proxy = Object.create(/*prototype*/ null); // eslint-disable-line no-null/no-null
|
||||
@@ -587,8 +587,8 @@ class LanguageServiceShimProxy implements ts.LanguageService {
|
||||
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: ts.FormatCodeOptions): ts.TextChange[] {
|
||||
return unwrapJSONCallResult(this.shim.getFormattingEditsAfterKeystroke(fileName, position, key, JSON.stringify(options)));
|
||||
}
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number, options?: ts.DocCommentTemplateOptions): ts.TextInsertion {
|
||||
return unwrapJSONCallResult(this.shim.getDocCommentTemplateAtPosition(fileName, position, options));
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number, options?: ts.DocCommentTemplateOptions, formatOptions?: ts.FormatCodeSettings): ts.TextInsertion {
|
||||
return unwrapJSONCallResult(this.shim.getDocCommentTemplateAtPosition(fileName, position, options, formatOptions));
|
||||
}
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean {
|
||||
return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPosition(fileName, position, openingBrace));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
|
||||
export function encodeString(s: string): string {
|
||||
return ts.sys.bufferFrom!(s).toString("utf8");
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import {
|
||||
FileBasedTest,
|
||||
IO,
|
||||
userSpecifiedRoot,
|
||||
} from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
|
||||
export type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "rwc" | "test262" | "user" | "dt" | "docker";
|
||||
export type CompilerTestKind = "conformance" | "compiler";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as documents from "./_namespaces/documents";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
import { Compiler } from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
|
||||
interface SourceMapSpanWithDecodeErrors {
|
||||
sourceMapSpan: ts.Mapping;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as collections from "./_namespaces/collections";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
import * as documents from "./_namespaces/documents";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
/**
|
||||
* Posix-style path to the TypeScript compiler build outputs (including tsc.js, lib.d.ts, etc.)
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
import {
|
||||
ActionInvalidate,
|
||||
ActionPackageInstalled,
|
||||
ActionSet,
|
||||
EventBeginInstallTypes,
|
||||
EventEndInstallTypes,
|
||||
EventInitializationFailed,
|
||||
EventTypesRegistry,
|
||||
} from "./_namespaces/ts.server";
|
||||
import {
|
||||
CompilerOptions,
|
||||
DirectoryWatcherCallback,
|
||||
@@ -19,6 +10,15 @@ import {
|
||||
TypeAcquisition,
|
||||
WatchOptions,
|
||||
} from "./_namespaces/ts";
|
||||
import {
|
||||
ActionInvalidate,
|
||||
ActionPackageInstalled,
|
||||
ActionSet,
|
||||
EventBeginInstallTypes,
|
||||
EventEndInstallTypes,
|
||||
EventInitializationFailed,
|
||||
EventTypesRegistry,
|
||||
} from "./_namespaces/ts.server";
|
||||
|
||||
export interface TypingInstallerResponse {
|
||||
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
|
||||
interface FileInformation {
|
||||
contents?: string;
|
||||
|
||||
@@ -1,50 +1,3 @@
|
||||
import {
|
||||
ActionInvalidate,
|
||||
ActionSet,
|
||||
asNormalizedPath,
|
||||
AutoImportProviderProject,
|
||||
BeginEnablePluginResult,
|
||||
BeginInstallTypes,
|
||||
ConfiguredProject,
|
||||
countEachFileTypes,
|
||||
createPackageJsonCache,
|
||||
emptyArray,
|
||||
EndInstallTypes,
|
||||
Errors,
|
||||
ExternalProject,
|
||||
getBaseConfigFileName,
|
||||
hasNoTypeScriptSource,
|
||||
InferredProject,
|
||||
InvalidateCachedTypings,
|
||||
isConfiguredProject,
|
||||
isDynamicFileName,
|
||||
isInferredProject,
|
||||
isInferredProjectName,
|
||||
ITypingsInstaller,
|
||||
Logger,
|
||||
LogLevel,
|
||||
makeAutoImportProviderProjectName,
|
||||
makeAuxiliaryProjectName,
|
||||
makeInferredProjectName,
|
||||
Msg,
|
||||
NormalizedPath,
|
||||
normalizedPathToPath,
|
||||
nullTypingsInstaller,
|
||||
PackageInstalledResponse,
|
||||
PackageJsonCache,
|
||||
Project,
|
||||
ProjectFilesWithTSDiagnostics,
|
||||
ProjectKind,
|
||||
ProjectOptions,
|
||||
ScriptInfo,
|
||||
ScriptInfoVersion,
|
||||
ServerHost,
|
||||
Session,
|
||||
SetTypings,
|
||||
ThrottledOperations,
|
||||
toNormalizedPath,
|
||||
TypingsCache,
|
||||
} from "./_namespaces/ts.server";
|
||||
import {
|
||||
addToSeen,
|
||||
arrayFrom,
|
||||
@@ -177,6 +130,53 @@ import {
|
||||
WatchType,
|
||||
WildcardDirectoryWatcher,
|
||||
} from "./_namespaces/ts";
|
||||
import {
|
||||
ActionInvalidate,
|
||||
ActionSet,
|
||||
asNormalizedPath,
|
||||
AutoImportProviderProject,
|
||||
BeginEnablePluginResult,
|
||||
BeginInstallTypes,
|
||||
ConfiguredProject,
|
||||
countEachFileTypes,
|
||||
createPackageJsonCache,
|
||||
emptyArray,
|
||||
EndInstallTypes,
|
||||
Errors,
|
||||
ExternalProject,
|
||||
getBaseConfigFileName,
|
||||
hasNoTypeScriptSource,
|
||||
InferredProject,
|
||||
InvalidateCachedTypings,
|
||||
isConfiguredProject,
|
||||
isDynamicFileName,
|
||||
isInferredProject,
|
||||
isInferredProjectName,
|
||||
ITypingsInstaller,
|
||||
Logger,
|
||||
LogLevel,
|
||||
makeAutoImportProviderProjectName,
|
||||
makeAuxiliaryProjectName,
|
||||
makeInferredProjectName,
|
||||
Msg,
|
||||
NormalizedPath,
|
||||
normalizedPathToPath,
|
||||
nullTypingsInstaller,
|
||||
PackageInstalledResponse,
|
||||
PackageJsonCache,
|
||||
Project,
|
||||
ProjectFilesWithTSDiagnostics,
|
||||
ProjectKind,
|
||||
ProjectOptions,
|
||||
ScriptInfo,
|
||||
ScriptInfoVersion,
|
||||
ServerHost,
|
||||
Session,
|
||||
SetTypings,
|
||||
ThrottledOperations,
|
||||
toNormalizedPath,
|
||||
TypingsCache,
|
||||
} from "./_namespaces/ts.server";
|
||||
import * as protocol from "./protocol";
|
||||
|
||||
export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024;
|
||||
|
||||
+22
-22
@@ -1,26 +1,4 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import {
|
||||
asNormalizedPath,
|
||||
createModuleSpecifierCache,
|
||||
emptyArray,
|
||||
Errors,
|
||||
FileStats,
|
||||
forEachResolvedProjectReferenceProject,
|
||||
LogLevel,
|
||||
ModuleImportResult,
|
||||
Msg,
|
||||
NormalizedPath,
|
||||
projectContainsInfoDirectly,
|
||||
ProjectOptions,
|
||||
ProjectReferenceProjectLoadKind,
|
||||
ProjectService,
|
||||
ScriptInfo,
|
||||
ServerHost,
|
||||
Session,
|
||||
toNormalizedPath,
|
||||
TypingsCache,
|
||||
updateProjectIfDirty,
|
||||
} from "./_namespaces/ts.server";
|
||||
import {
|
||||
addRange,
|
||||
append,
|
||||
@@ -147,6 +125,28 @@ import {
|
||||
WatchOptions,
|
||||
WatchType,
|
||||
} from "./_namespaces/ts";
|
||||
import {
|
||||
asNormalizedPath,
|
||||
createModuleSpecifierCache,
|
||||
emptyArray,
|
||||
Errors,
|
||||
FileStats,
|
||||
forEachResolvedProjectReferenceProject,
|
||||
LogLevel,
|
||||
ModuleImportResult,
|
||||
Msg,
|
||||
NormalizedPath,
|
||||
projectContainsInfoDirectly,
|
||||
ProjectOptions,
|
||||
ProjectReferenceProjectLoadKind,
|
||||
ProjectService,
|
||||
ScriptInfo,
|
||||
ServerHost,
|
||||
Session,
|
||||
toNormalizedPath,
|
||||
TypingsCache,
|
||||
updateProjectIfDirty,
|
||||
} from "./_namespaces/ts.server";
|
||||
import * as protocol from "./protocol";
|
||||
|
||||
export enum ProjectKind {
|
||||
|
||||
+16
-16
@@ -1,19 +1,3 @@
|
||||
import {
|
||||
AbsolutePositionAndLineText,
|
||||
ConfiguredProject,
|
||||
Errors,
|
||||
ExternalProject,
|
||||
InferredProject,
|
||||
isConfiguredProject,
|
||||
isExternalProject,
|
||||
isInferredProject,
|
||||
maxFileSize,
|
||||
NormalizedPath,
|
||||
Project,
|
||||
ProjectKind,
|
||||
ScriptVersionCache,
|
||||
ServerHost,
|
||||
} from "./_namespaces/ts.server";
|
||||
import {
|
||||
assign,
|
||||
clear,
|
||||
@@ -51,6 +35,22 @@ import {
|
||||
TextSpan,
|
||||
unorderedRemoveItem,
|
||||
} from "./_namespaces/ts";
|
||||
import {
|
||||
AbsolutePositionAndLineText,
|
||||
ConfiguredProject,
|
||||
Errors,
|
||||
ExternalProject,
|
||||
InferredProject,
|
||||
isConfiguredProject,
|
||||
isExternalProject,
|
||||
isInferredProject,
|
||||
maxFileSize,
|
||||
NormalizedPath,
|
||||
Project,
|
||||
ProjectKind,
|
||||
ScriptVersionCache,
|
||||
ServerHost,
|
||||
} from "./_namespaces/ts.server";
|
||||
import * as protocol from "./protocol";
|
||||
|
||||
export interface ScriptInfoVersion {
|
||||
|
||||
@@ -730,6 +730,12 @@ function getPerProjectReferences<TResult>(
|
||||
if (resultsMap.has(project)) continue;
|
||||
if (isLocationProjectReferenceRedirect(project, location)) continue;
|
||||
|
||||
// The project could be dirty and could no longer contain the location's file after it's updated,
|
||||
// so we need to update the project and check if it still contains the file.
|
||||
updateProjectIfDirty(project);
|
||||
if (!project.containsFile(toNormalizedPath(location.fileName))) {
|
||||
continue;
|
||||
}
|
||||
const projectResults = searchPosition(project, location);
|
||||
resultsMap.set(project, projectResults ?? emptyArray);
|
||||
searchedProjectKeys.add(getProjectKey(project));
|
||||
@@ -2083,7 +2089,7 @@ export class Session<TMessage = string> implements EventSender {
|
||||
private getDocCommentTemplate(args: protocol.FileLocationRequestArgs) {
|
||||
const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
|
||||
const position = this.getPositionInFile(args, file);
|
||||
return languageService.getDocCommentTemplateAtPosition(file, position, this.getPreferences(file));
|
||||
return languageService.getDocCommentTemplateAtPosition(file, position, this.getPreferences(file), this.getFormatOptions(file));
|
||||
}
|
||||
|
||||
private getSpanOfEnclosingComment(args: protocol.SpanOfEnclosingCommentRequestArgs) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
ClassLikeDeclaration,
|
||||
ClassStaticBlockDeclaration,
|
||||
compareStringsCaseSensitive,
|
||||
createPrinter,
|
||||
createPrinterWithRemoveCommentsOmitTrailingSemicolon,
|
||||
createTextRangeFromNode,
|
||||
createTextSpanFromBounds,
|
||||
createTextSpanFromRange,
|
||||
@@ -245,7 +245,7 @@ function getCallHierarchyItemName(program: Program, node: CallHierarchyDeclarati
|
||||
}
|
||||
if (text === undefined) {
|
||||
// get the text from printing the node on a single line without comments...
|
||||
const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true });
|
||||
const printer = createPrinterWithRemoveCommentsOmitTrailingSemicolon();
|
||||
text = usingSingleLineStringWriter(writer => printer.writeNode(EmitHint.Unspecified, node, node.getSourceFile(), writer));
|
||||
}
|
||||
return { text, pos: declName.getStart(), end: declName.getEnd() };
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import {
|
||||
createCodeFixActionWithoutFixAll,
|
||||
registerCodeFix,
|
||||
} from "../_namespaces/ts.codefix";
|
||||
import {
|
||||
Diagnostics,
|
||||
factory,
|
||||
textChanges,
|
||||
} from "../_namespaces/ts";
|
||||
import {
|
||||
createCodeFixActionWithoutFixAll,
|
||||
registerCodeFix,
|
||||
} from "../_namespaces/ts.codefix";
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes: [
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
import {
|
||||
createCodeFixActionWithoutFixAll,
|
||||
moduleSpecifierToValidIdentifier,
|
||||
registerCodeFix,
|
||||
} from "../_namespaces/ts.codefix";
|
||||
import {
|
||||
__String,
|
||||
arrayFrom,
|
||||
@@ -81,6 +76,11 @@ import {
|
||||
TypeChecker,
|
||||
VariableStatement,
|
||||
} from "../_namespaces/ts";
|
||||
import {
|
||||
createCodeFixActionWithoutFixAll,
|
||||
moduleSpecifierToValidIdentifier,
|
||||
registerCodeFix,
|
||||
} from "../_namespaces/ts.codefix";
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes: [Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES_module.code],
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
import {
|
||||
createCodeFixActionWithoutFixAll,
|
||||
registerCodeFix,
|
||||
setJsonCompilerOptionValue,
|
||||
setJsonCompilerOptionValues,
|
||||
} from "../_namespaces/ts.codefix";
|
||||
import {
|
||||
CodeFixAction,
|
||||
Diagnostics,
|
||||
@@ -16,6 +10,12 @@ import {
|
||||
ScriptTarget,
|
||||
textChanges,
|
||||
} from "../_namespaces/ts";
|
||||
import {
|
||||
createCodeFixActionWithoutFixAll,
|
||||
registerCodeFix,
|
||||
setJsonCompilerOptionValue,
|
||||
setJsonCompilerOptionValues,
|
||||
} from "../_namespaces/ts.codefix";
|
||||
|
||||
registerCodeFix({
|
||||
errorCodes: [
|
||||
|
||||
@@ -83,7 +83,7 @@ function getDeleteAction(context: CodeFixContext, { name, jsDocHost, jsDocParame
|
||||
);
|
||||
}
|
||||
|
||||
function getRenameAction(context: CodeFixContext, { name, signature, jsDocParameterTag }: Info) {
|
||||
function getRenameAction(context: CodeFixContext, { name, jsDocHost, signature, jsDocParameterTag }: Info) {
|
||||
if (!length(signature.parameters)) return undefined;
|
||||
|
||||
const sourceFile = context.sourceFile;
|
||||
@@ -110,7 +110,7 @@ function getRenameAction(context: CodeFixContext, { name, signature, jsDocParame
|
||||
jsDocParameterTag.comment
|
||||
);
|
||||
const changes = textChanges.ChangeTracker.with(context, changeTracker =>
|
||||
changeTracker.replaceJSDocComment(sourceFile, signature, map(tags, t => t === jsDocParameterTag ? newJSDocParameterTag : t)));
|
||||
changeTracker.replaceJSDocComment(sourceFile, jsDocHost, map(tags, t => t === jsDocParameterTag ? newJSDocParameterTag : t)));
|
||||
return createCodeFixActionWithoutFixAll(renameUnmatchedParameter, changes, [Diagnostics.Rename_param_tag_name_0_to_1, name.getText(sourceFile), parameterName]);
|
||||
}
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ import {
|
||||
mapEntries,
|
||||
NewExpression,
|
||||
Node,
|
||||
nodeSeenTracker,
|
||||
NodeSeenTracker,
|
||||
nodeSeenTracker,
|
||||
ObjectFlags,
|
||||
ParameterDeclaration,
|
||||
PrefixUnaryExpression,
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
CancellationToken,
|
||||
canUsePropertyAccess,
|
||||
CaseBlock,
|
||||
CaseClause,
|
||||
cast,
|
||||
CharacterCodes,
|
||||
ClassElement,
|
||||
@@ -43,13 +42,11 @@ import {
|
||||
createTextSpanFromRange,
|
||||
Debug,
|
||||
Declaration,
|
||||
DefaultClause,
|
||||
Diagnostics,
|
||||
diagnosticToString,
|
||||
displayPart,
|
||||
EmitHint,
|
||||
EmitTextWriter,
|
||||
endsWith,
|
||||
EntityName,
|
||||
EnumMember,
|
||||
escapeSnippetText,
|
||||
@@ -140,7 +137,6 @@ import {
|
||||
isConstructorDeclaration,
|
||||
isContextualKeyword,
|
||||
isDeclarationName,
|
||||
isDefaultClause,
|
||||
isDeprecatedDeclaration,
|
||||
isEntityName,
|
||||
isEnumMember,
|
||||
@@ -185,7 +181,6 @@ import {
|
||||
isKeyword,
|
||||
isKnownSymbol,
|
||||
isLabeledStatement,
|
||||
isLiteralExpression,
|
||||
isLiteralImportTypeNode,
|
||||
isMemberName,
|
||||
isMethodDeclaration,
|
||||
@@ -218,6 +213,7 @@ import {
|
||||
isStatement,
|
||||
isStatic,
|
||||
isString,
|
||||
isStringAndEmptyAnonymousObjectIntersection,
|
||||
isStringANonContextualKeyword,
|
||||
isStringLiteralLike,
|
||||
isStringLiteralOrTemplate,
|
||||
@@ -275,6 +271,7 @@ import {
|
||||
ModuleReference,
|
||||
moduleResolutionSupportsPackageJsonExportsAndImports,
|
||||
NamedImportBindings,
|
||||
newCaseClauseTracker,
|
||||
Node,
|
||||
NodeArray,
|
||||
NodeBuilderFlags,
|
||||
@@ -287,7 +284,6 @@ import {
|
||||
ObjectTypeDeclaration,
|
||||
or,
|
||||
ParenthesizedTypeNode,
|
||||
parseBigInt,
|
||||
positionBelongsToNode,
|
||||
positionIsASICandidate,
|
||||
positionsAreOnSameLine,
|
||||
@@ -1104,75 +1100,6 @@ function getExhaustiveCaseSnippets(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
interface CaseClauseTracker {
|
||||
addValue(value: string | number): void;
|
||||
hasValue(value: string | number | PseudoBigInt): boolean;
|
||||
}
|
||||
|
||||
function newCaseClauseTracker(checker: TypeChecker, clauses: readonly (CaseClause | DefaultClause)[]): CaseClauseTracker {
|
||||
const existingStrings = new Set<string>();
|
||||
const existingNumbers = new Set<number>();
|
||||
const existingBigInts = new Set<string>();
|
||||
|
||||
for (const clause of clauses) {
|
||||
if (!isDefaultClause(clause)) {
|
||||
if (isLiteralExpression(clause.expression)) {
|
||||
const expression = clause.expression;
|
||||
switch (expression.kind) {
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
existingStrings.add(expression.text);
|
||||
break;
|
||||
case SyntaxKind.NumericLiteral:
|
||||
existingNumbers.add(parseInt(expression.text));
|
||||
break;
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
const parsedBigInt = parseBigInt(endsWith(expression.text, "n") ? expression.text.slice(0, -1) : expression.text);
|
||||
if (parsedBigInt) {
|
||||
existingBigInts.add(pseudoBigIntToString(parsedBigInt));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const symbol = checker.getSymbolAtLocation(clause.expression);
|
||||
if (symbol && symbol.valueDeclaration && isEnumMember(symbol.valueDeclaration)) {
|
||||
const enumValue = checker.getConstantValue(symbol.valueDeclaration);
|
||||
if (enumValue !== undefined) {
|
||||
addValue(enumValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
addValue,
|
||||
hasValue,
|
||||
};
|
||||
|
||||
function addValue(value: string | number) {
|
||||
switch (typeof value) {
|
||||
case "string":
|
||||
existingStrings.add(value);
|
||||
break;
|
||||
case "number":
|
||||
existingNumbers.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
function hasValue(value: string | number | PseudoBigInt): boolean {
|
||||
switch (typeof value) {
|
||||
case "string":
|
||||
return existingStrings.has(value);
|
||||
case "number":
|
||||
return existingNumbers.has(value);
|
||||
case "object":
|
||||
return existingBigInts.has(pseudoBigIntToString(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function typeNodeToExpression(typeNode: TypeNode, languageVersion: ScriptTarget, quotePreference: QuotePreference): Expression | undefined {
|
||||
switch (typeNode.kind) {
|
||||
case SyntaxKind.TypeReference:
|
||||
@@ -1442,7 +1369,7 @@ function createCompletionEntry(
|
||||
&& !(type.flags & TypeFlags.BooleanLike)
|
||||
&& !(type.flags & TypeFlags.Union && find((type as UnionType).types, type => !!(type.flags & TypeFlags.BooleanLike)))
|
||||
) {
|
||||
if (type.flags & TypeFlags.StringLike || (type.flags & TypeFlags.Union && every((type as UnionType).types, type => !!(type.flags & (TypeFlags.StringLike | TypeFlags.Undefined))))) {
|
||||
if (type.flags & TypeFlags.StringLike || (type.flags & TypeFlags.Union && every((type as UnionType).types, type => !!(type.flags & (TypeFlags.StringLike | TypeFlags.Undefined) || isStringAndEmptyAnonymousObjectIntersection(type))))) {
|
||||
// If is string like or undefined use quotes
|
||||
insertText = `${escapeSnippetText(name)}=${quote(sourceFile, preferences, "$1")}`;
|
||||
isSnippet = true;
|
||||
@@ -2045,7 +1972,7 @@ function completionEntryDataToSymbolOriginInfo(data: CompletionEntryData, comple
|
||||
|
||||
function getInsertTextAndReplacementSpanForImportCompletion(name: string, importStatementCompletion: ImportStatementCompletionInfo, origin: SymbolOriginInfoResolvedExport, useSemicolons: boolean, sourceFile: SourceFile, options: CompilerOptions, preferences: UserPreferences) {
|
||||
const replacementSpan = importStatementCompletion.replacementSpan;
|
||||
const quotedModuleSpecifier = quote(sourceFile, preferences, origin.moduleSpecifier);
|
||||
const quotedModuleSpecifier = quote(sourceFile, preferences, escapeSnippetText(origin.moduleSpecifier));
|
||||
const exportKind =
|
||||
origin.isDefaultExport ? ExportKind.Default :
|
||||
origin.exportName === InternalSymbolName.ExportEquals ? ExportKind.ExportEquals :
|
||||
@@ -2898,7 +2825,8 @@ function getCompletionData(
|
||||
// First case is for `<div foo={true} [||] />` or `<div foo={true} [||] ></div>`,
|
||||
// `parent` will be `{true}` and `previousToken` will be `}`
|
||||
// Second case is for `<div foo={true} t[||] ></div>`
|
||||
if (previousToken.kind === SyntaxKind.CloseBraceToken || (previousToken.kind === SyntaxKind.Identifier || previousToken.parent.kind === SyntaxKind.JsxAttribute)) {
|
||||
// Second case must not match for `<div foo={undefine[||]}></div>`
|
||||
if (previousToken.kind === SyntaxKind.CloseBraceToken || (previousToken.kind === SyntaxKind.Identifier && previousToken.parent.kind === SyntaxKind.JsxAttribute)) {
|
||||
isJsxIdentifierExpected = true;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { TextRangeWithKind } from "../_namespaces/ts.formatting";
|
||||
import {
|
||||
Debug,
|
||||
findChildOfKind,
|
||||
@@ -7,6 +6,7 @@ import {
|
||||
SourceFileLike,
|
||||
SyntaxKind,
|
||||
} from "../_namespaces/ts";
|
||||
import { TextRangeWithKind } from "../_namespaces/ts.formatting";
|
||||
|
||||
/** @internal */
|
||||
export const enum FormattingRequestKind {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { FormattingContext } from "../_namespaces/ts.formatting";
|
||||
import {
|
||||
emptyArray,
|
||||
SyntaxKind,
|
||||
} from "../_namespaces/ts";
|
||||
import { FormattingContext } from "../_namespaces/ts.formatting";
|
||||
|
||||
/** @internal */
|
||||
export interface Rule {
|
||||
|
||||
@@ -1,14 +1,3 @@
|
||||
import {
|
||||
anyContext,
|
||||
ContextPredicate,
|
||||
FormattingContext,
|
||||
FormattingRequestKind,
|
||||
Rule,
|
||||
RuleAction,
|
||||
RuleFlags,
|
||||
TextRangeWithKind,
|
||||
TokenRange,
|
||||
} from "../_namespaces/ts.formatting";
|
||||
import {
|
||||
BinaryExpression,
|
||||
contains,
|
||||
@@ -32,6 +21,17 @@ import {
|
||||
typeKeywords,
|
||||
YieldExpression,
|
||||
} from "../_namespaces/ts";
|
||||
import {
|
||||
anyContext,
|
||||
ContextPredicate,
|
||||
FormattingContext,
|
||||
FormattingRequestKind,
|
||||
Rule,
|
||||
RuleAction,
|
||||
RuleFlags,
|
||||
TextRangeWithKind,
|
||||
TokenRange,
|
||||
} from "../_namespaces/ts.formatting";
|
||||
|
||||
/** @internal */
|
||||
export interface RuleSpec {
|
||||
|
||||
@@ -2,7 +2,7 @@ import {
|
||||
__String,
|
||||
ArrowFunction,
|
||||
CallExpression,
|
||||
createPrinter,
|
||||
createPrinterWithRemoveComments,
|
||||
Debug,
|
||||
EmitHint,
|
||||
EnumMember,
|
||||
@@ -53,7 +53,6 @@ import {
|
||||
NodeBuilderFlags,
|
||||
ParameterDeclaration,
|
||||
PrefixUnaryExpression,
|
||||
PrinterOptions,
|
||||
PropertyDeclaration,
|
||||
Signature,
|
||||
skipParentheses,
|
||||
@@ -383,8 +382,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
|
||||
|
||||
function printTypeInSingleLine(type: Type) {
|
||||
const flags = NodeBuilderFlags.IgnoreErrors | TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
||||
const options: PrinterOptions = { removeComments: true };
|
||||
const printer = createPrinter(options);
|
||||
const printer = createPrinterWithRemoveComments();
|
||||
|
||||
return usingSingleLineStringWriter(writer => {
|
||||
const typeNode = checker.typeToTypeNode(type, /*enclosingDeclaration*/ undefined, flags);
|
||||
|
||||
@@ -135,6 +135,8 @@ const jsDocTagNames = [
|
||||
"lends",
|
||||
"license",
|
||||
"link",
|
||||
"linkcode",
|
||||
"linkplain",
|
||||
"listens",
|
||||
"member",
|
||||
"memberof",
|
||||
@@ -147,6 +149,7 @@ const jsDocTagNames = [
|
||||
"package",
|
||||
"param",
|
||||
"private",
|
||||
"prop",
|
||||
"property",
|
||||
"protected",
|
||||
"public",
|
||||
|
||||
@@ -41,6 +41,7 @@ import {
|
||||
RefactorContext,
|
||||
RefactorEditInfo,
|
||||
ReturnStatement,
|
||||
setTextRange,
|
||||
SourceFile,
|
||||
Statement,
|
||||
suppressLeadingAndTrailingTrivia,
|
||||
@@ -237,6 +238,7 @@ function convertToBlock(body: ConciseBody): Block {
|
||||
if (isExpression(body)) {
|
||||
const returnStatement = factory.createReturnStatement(body);
|
||||
const file = body.getSourceFile();
|
||||
setTextRange(returnStatement, body);
|
||||
suppressLeadingAndTrailingTrivia(returnStatement);
|
||||
copyTrailingAsLeadingComments(body, returnStatement, file, /* commentKind */ undefined, /* hasTrailingNewLine */ true);
|
||||
return factory.createBlock([returnStatement], /* multiLine */ true);
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as NavigateTo from "./_namespaces/ts.NavigateTo";
|
||||
import * as NavigationBar from "./_namespaces/ts.NavigationBar";
|
||||
import {
|
||||
__String,
|
||||
ApplicableRefactorInfo,
|
||||
@@ -182,8 +180,8 @@ import {
|
||||
isTextWhiteSpaceLike,
|
||||
isThisTypeParameter,
|
||||
isTransientSymbol,
|
||||
JsDoc,
|
||||
JSDoc,
|
||||
JsDoc,
|
||||
JSDocContainer,
|
||||
JSDocTagInfo,
|
||||
JsonSourceFile,
|
||||
@@ -318,6 +316,8 @@ import {
|
||||
UserPreferences,
|
||||
VariableDeclaration,
|
||||
} from "./_namespaces/ts";
|
||||
import * as NavigateTo from "./_namespaces/ts.NavigateTo";
|
||||
import * as NavigationBar from "./_namespaces/ts.NavigationBar";
|
||||
|
||||
/** The version of the language service API */
|
||||
export const servicesVersion = "0.8";
|
||||
@@ -2436,8 +2436,9 @@ export function createLanguageService(
|
||||
: Promise.reject("Host does not implement `installPackage`");
|
||||
}
|
||||
|
||||
function getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions): TextInsertion | undefined {
|
||||
return JsDoc.getDocCommentTemplateAtPosition(getNewLineOrDefaultFromHost(host, /*formatSettings*/ undefined), syntaxTreeCache.getCurrentSourceFile(fileName), position, options);
|
||||
function getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions, formatOptions?: FormatCodeSettings): TextInsertion | undefined {
|
||||
const formatSettings = formatOptions ? formatting.getFormatContext(formatOptions, host).options : undefined;
|
||||
return JsDoc.getDocCommentTemplateAtPosition(getNewLineOrDefaultFromHost(host, formatSettings), syntaxTreeCache.getCurrentSourceFile(fileName), position, options);
|
||||
}
|
||||
|
||||
function isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean {
|
||||
|
||||
@@ -349,7 +349,7 @@ export interface LanguageServiceShim extends Shim {
|
||||
/**
|
||||
* Returns JSON-encoded value of the type TextInsertion.
|
||||
*/
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions): string;
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions, formatOptions?: FormatCodeSettings): string;
|
||||
|
||||
/**
|
||||
* Returns JSON-encoded boolean to indicate whether we should support brace location
|
||||
@@ -1091,10 +1091,10 @@ class LanguageServiceShimObject extends ShimBase implements LanguageServiceShim
|
||||
});
|
||||
}
|
||||
|
||||
public getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions): string {
|
||||
public getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions, formatOptions?: FormatCodeSettings): string {
|
||||
return this.forwardJSONCall(
|
||||
`getDocCommentTemplateAtPosition('${fileName}', ${position})`,
|
||||
() => this.languageService.getDocCommentTemplateAtPosition(fileName, position, options)
|
||||
() => this.languageService.getDocCommentTemplateAtPosition(fileName, position, options, formatOptions)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
CheckFlags,
|
||||
contains,
|
||||
countWhere,
|
||||
createPrinter,
|
||||
createPrinterWithRemoveComments,
|
||||
createTextSpan,
|
||||
createTextSpanFromBounds,
|
||||
createTextSpanFromNode,
|
||||
@@ -659,7 +659,7 @@ function createTypeHelpItems(
|
||||
function getTypeHelpItem(symbol: Symbol, typeParameters: readonly TypeParameter[], checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItem {
|
||||
const typeSymbolDisplay = symbolToDisplayParts(checker, symbol);
|
||||
|
||||
const printer = createPrinter({ removeComments: true });
|
||||
const printer = createPrinterWithRemoveComments();
|
||||
const parameters = typeParameters.map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer));
|
||||
|
||||
const documentation = symbol.getDocumentationComment(checker);
|
||||
@@ -699,7 +699,7 @@ interface SignatureHelpItemInfo { readonly isVariadic: boolean; readonly paramet
|
||||
|
||||
function itemInfoForTypeParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo[] {
|
||||
const typeParameters = (candidateSignature.target || candidateSignature).typeParameters;
|
||||
const printer = createPrinter({ removeComments: true });
|
||||
const printer = createPrinterWithRemoveComments();
|
||||
const parameters = (typeParameters || emptyArray).map(t => createSignatureHelpParameterForTypeParameter(t, checker, enclosingDeclaration, sourceFile, printer));
|
||||
const thisParameter = candidateSignature.thisParameter ? [checker.symbolToParameterDeclaration(candidateSignature.thisParameter, enclosingDeclaration, signatureHelpNodeBuilderFlags)!] : [];
|
||||
|
||||
@@ -713,7 +713,7 @@ function itemInfoForTypeParameters(candidateSignature: Signature, checker: TypeC
|
||||
}
|
||||
|
||||
function itemInfoForParameters(candidateSignature: Signature, checker: TypeChecker, enclosingDeclaration: Node, sourceFile: SourceFile): SignatureHelpItemInfo[] {
|
||||
const printer = createPrinter({ removeComments: true });
|
||||
const printer = createPrinterWithRemoveComments();
|
||||
const typeParameterParts = mapToDisplayParts(writer => {
|
||||
if (candidateSignature.typeParameters && candidateSignature.typeParameters.length) {
|
||||
const args = factory.createNodeArray(candidateSignature.typeParameters.map(p => checker.typeParameterToDeclaration(p, enclosingDeclaration, signatureHelpNodeBuilderFlags)!));
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
arrayFrom,
|
||||
CallLikeExpression,
|
||||
CancellationToken,
|
||||
CaseClause,
|
||||
changeExtension,
|
||||
CharacterCodes,
|
||||
combinePaths,
|
||||
@@ -94,6 +95,7 @@ import {
|
||||
moduleResolutionUsesNodeModules,
|
||||
ModuleSpecifierEnding,
|
||||
moduleSpecifiers,
|
||||
newCaseClauseTracker,
|
||||
Node,
|
||||
normalizePath,
|
||||
normalizeSlashes,
|
||||
@@ -275,7 +277,7 @@ function stringLiteralCompletionDetails(name: string, location: Node, completion
|
||||
return match && createCompletionDetailsForSymbol(match, checker, sourceFile, location, cancellationToken);
|
||||
}
|
||||
case StringLiteralCompletionKind.Types:
|
||||
return find(completion.types, t => t.value === name) ? createCompletionDetails(name, ScriptElementKindModifier.none, ScriptElementKind.typeElement, [textPart(name)]) : undefined;
|
||||
return find(completion.types, t => t.value === name) ? createCompletionDetails(name, ScriptElementKindModifier.none, ScriptElementKind.string, [textPart(name)]) : undefined;
|
||||
default:
|
||||
return Debug.assertNever(completion);
|
||||
}
|
||||
@@ -415,12 +417,15 @@ function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringL
|
||||
// var y = require("/*completion position*/");
|
||||
// export * from "/*completion position*/";
|
||||
return { kind: StringLiteralCompletionKind.Paths, paths: getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker, preferences) };
|
||||
|
||||
case SyntaxKind.CaseClause:
|
||||
const tracker = newCaseClauseTracker(typeChecker, (node.parent as CaseClause).parent.clauses);
|
||||
const literals = fromContextualType().types.filter(literal => !tracker.hasValue(literal.value));
|
||||
return { kind: StringLiteralCompletionKind.Types, types: literals, isNewIdentifier: false };
|
||||
default:
|
||||
return fromContextualType();
|
||||
}
|
||||
|
||||
function fromContextualType(): StringLiteralCompletion {
|
||||
function fromContextualType(): StringLiteralCompletionsFromTypes {
|
||||
// Get completion for string literal from string literal type
|
||||
// i.e. var x: "hi" | "hello" = "/*completion position*/"
|
||||
return { kind: StringLiteralCompletionKind.Types, types: getStringLiteralTypes(getContextualTypeFromParent(node, typeChecker, ContextFlags.Completions)), isNewIdentifier: false };
|
||||
@@ -531,7 +536,7 @@ function getStringLiteralCompletionsFromModuleNamesWorker(sourceFile: SourceFile
|
||||
|
||||
const scriptPath = sourceFile.path;
|
||||
const scriptDirectory = getDirectoryPath(scriptPath);
|
||||
const extensionOptions = getExtensionOptions(compilerOptions, ReferenceKind.ModuleSpecifier, sourceFile, preferences, mode);
|
||||
const extensionOptions = getExtensionOptions(compilerOptions, ReferenceKind.ModuleSpecifier, sourceFile, typeChecker, preferences, mode);
|
||||
|
||||
return isPathRelativeToScript(literalValue) || !compilerOptions.baseUrl && (isRootedDiskPath(literalValue) || isUrl(literalValue))
|
||||
? getCompletionEntriesForRelativeModules(literalValue, scriptDirectory, compilerOptions, host, scriptPath, extensionOptions)
|
||||
@@ -539,16 +544,16 @@ function getStringLiteralCompletionsFromModuleNamesWorker(sourceFile: SourceFile
|
||||
}
|
||||
|
||||
interface ExtensionOptions {
|
||||
readonly extensionsToSearch: readonly Extension[];
|
||||
readonly extensionsToSearch: readonly string[];
|
||||
readonly referenceKind: ReferenceKind;
|
||||
readonly importingSourceFile: SourceFile;
|
||||
readonly endingPreference?: UserPreferences["importModuleSpecifierEnding"];
|
||||
readonly resolutionMode?: ResolutionMode;
|
||||
}
|
||||
|
||||
function getExtensionOptions(compilerOptions: CompilerOptions, referenceKind: ReferenceKind, importingSourceFile: SourceFile, preferences?: UserPreferences, resolutionMode?: ResolutionMode): ExtensionOptions {
|
||||
function getExtensionOptions(compilerOptions: CompilerOptions, referenceKind: ReferenceKind, importingSourceFile: SourceFile, typeChecker?: TypeChecker, preferences?: UserPreferences, resolutionMode?: ResolutionMode): ExtensionOptions {
|
||||
return {
|
||||
extensionsToSearch: flatten(getSupportedExtensionsForModuleResolution(compilerOptions)),
|
||||
extensionsToSearch: flatten(getSupportedExtensionsForModuleResolution(compilerOptions, typeChecker)),
|
||||
referenceKind,
|
||||
importingSourceFile,
|
||||
endingPreference: preferences?.importModuleSpecifierEnding,
|
||||
@@ -565,8 +570,17 @@ function getCompletionEntriesForRelativeModules(literalValue: string, scriptDire
|
||||
}
|
||||
}
|
||||
|
||||
function getSupportedExtensionsForModuleResolution(compilerOptions: CompilerOptions): readonly Extension[][] {
|
||||
const extensions = getSupportedExtensions(compilerOptions);
|
||||
function getSupportedExtensionsForModuleResolution(compilerOptions: CompilerOptions, typeChecker?: TypeChecker): readonly string[][] {
|
||||
/** file extensions from ambient modules declarations e.g. *.css */
|
||||
const ambientModulesExtensions = !typeChecker ? [] : mapDefined(typeChecker.getAmbientModules(),
|
||||
module => {
|
||||
const name = module.name.slice(1, -1);
|
||||
if (!name.startsWith("*.") || name.includes("/")) return;
|
||||
return name.slice(1);
|
||||
}
|
||||
);
|
||||
|
||||
const extensions = [...getSupportedExtensions(compilerOptions), ambientModulesExtensions];
|
||||
const moduleResolution = getEmitModuleResolutionKind(compilerOptions);
|
||||
return moduleResolutionUsesNodeModules(moduleResolution) ?
|
||||
getSupportedExtensionsWithJsonIfResolveJsonModule(compilerOptions, extensions) :
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
CallExpression,
|
||||
CheckFlags,
|
||||
contains,
|
||||
createPrinter,
|
||||
createPrinterWithRemoveComments,
|
||||
Debug,
|
||||
displayPart,
|
||||
EmitHint,
|
||||
@@ -75,7 +75,6 @@ import {
|
||||
NodeBuilderFlags,
|
||||
ObjectFlags,
|
||||
operatorPart,
|
||||
Printer,
|
||||
PropertyAccessExpression,
|
||||
PropertyDeclaration,
|
||||
punctuationPart,
|
||||
@@ -259,7 +258,6 @@ export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: Typ
|
||||
let hasAddedSymbolInfo = false;
|
||||
const isThisExpression = location.kind === SyntaxKind.ThisKeyword && isInExpressionContext(location) || isThisInTypeQuery(location);
|
||||
let type: Type | undefined;
|
||||
let printer: Printer;
|
||||
let documentationFromAlias: SymbolDisplayPart[] | undefined;
|
||||
let tagsFromAlias: JSDocTagInfo[] | undefined;
|
||||
let hasMultipleSignatures = false;
|
||||
@@ -730,10 +728,7 @@ export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: Typ
|
||||
return { displayParts, documentation, symbolKind, tags: tags.length === 0 ? undefined : tags };
|
||||
|
||||
function getPrinter() {
|
||||
if (!printer) {
|
||||
printer = createPrinter({ removeComments: true });
|
||||
}
|
||||
return printer;
|
||||
return createPrinterWithRemoveComments();
|
||||
}
|
||||
|
||||
function prefixNextMeaning() {
|
||||
|
||||
@@ -604,7 +604,7 @@ export interface LanguageService {
|
||||
getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[];
|
||||
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[];
|
||||
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions): TextInsertion | undefined;
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number, options?: DocCommentTemplateOptions, formatOptions?: FormatCodeSettings): TextInsertion | undefined;
|
||||
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
|
||||
/**
|
||||
|
||||
+138
-11
@@ -30,7 +30,7 @@ import {
|
||||
ConditionalExpression,
|
||||
contains,
|
||||
ContextFlags,
|
||||
createPrinter,
|
||||
createPrinterWithRemoveCommentsOmitTrailingSemicolon,
|
||||
createRange,
|
||||
createScanner,
|
||||
createTextSpan,
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
Debug,
|
||||
Declaration,
|
||||
Decorator,
|
||||
DefaultClause,
|
||||
defaultMaximumTruncationLength,
|
||||
DeleteExpression,
|
||||
Diagnostic,
|
||||
@@ -53,6 +54,7 @@ import {
|
||||
EmitHint,
|
||||
emptyArray,
|
||||
EndOfFileToken,
|
||||
endsWith,
|
||||
ensureScriptKind,
|
||||
EqualityOperator,
|
||||
escapeString,
|
||||
@@ -138,10 +140,12 @@ import {
|
||||
isDeclaration,
|
||||
isDeclarationName,
|
||||
isDecorator,
|
||||
isDefaultClause,
|
||||
isDeleteExpression,
|
||||
isElementAccessExpression,
|
||||
isEntityName,
|
||||
isEnumDeclaration,
|
||||
isEnumMember,
|
||||
isExportAssignment,
|
||||
isExportDeclaration,
|
||||
isExportSpecifier,
|
||||
@@ -188,6 +192,7 @@ import {
|
||||
isKeyword,
|
||||
isLabeledStatement,
|
||||
isLet,
|
||||
isLiteralExpression,
|
||||
isLiteralTypeNode,
|
||||
isMappedTypeNode,
|
||||
isModifier,
|
||||
@@ -281,6 +286,7 @@ import {
|
||||
or,
|
||||
OrganizeImports,
|
||||
PackageJsonDependencyGroup,
|
||||
parseBigInt,
|
||||
pathIsRelative,
|
||||
PrefixUnaryExpression,
|
||||
Program,
|
||||
@@ -288,6 +294,8 @@ import {
|
||||
PropertyAccessExpression,
|
||||
PropertyAssignment,
|
||||
PropertyName,
|
||||
PseudoBigInt,
|
||||
pseudoBigIntToString,
|
||||
QualifiedName,
|
||||
RefactorContext,
|
||||
Scanner,
|
||||
@@ -342,6 +350,7 @@ import {
|
||||
tryCast,
|
||||
Type,
|
||||
TypeChecker,
|
||||
TypeFlags,
|
||||
TypeFormatFlags,
|
||||
TypeNode,
|
||||
TypeOfExpression,
|
||||
@@ -2154,6 +2163,17 @@ export function isStringOrRegularExpressionOrTemplateLiteral(kind: SyntaxKind):
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isStringAndEmptyAnonymousObjectIntersection(type: Type) {
|
||||
if (!type.isIntersection()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { types, checker } = type;
|
||||
return types.length === 2
|
||||
&& (types[0].flags & TypeFlags.String) && checker.isEmptyAnonymousObjectType(types[1]);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isPunctuation(kind: SyntaxKind): boolean {
|
||||
return SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation;
|
||||
@@ -2413,7 +2433,9 @@ export function getModuleSpecifierResolverHost(program: Program, host: LanguageS
|
||||
|
||||
/** @internal */
|
||||
export function moduleResolutionUsesNodeModules(moduleResolution: ModuleResolutionKind): boolean {
|
||||
return moduleResolution === ModuleResolutionKind.Node10 || moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext;
|
||||
return moduleResolution === ModuleResolutionKind.Node10
|
||||
|| moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext
|
||||
|| moduleResolution === ModuleResolutionKind.Bundler;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -2984,7 +3006,7 @@ export function signatureToDisplayParts(typechecker: TypeChecker, signature: Sig
|
||||
export function nodeToDisplayParts(node: Node, enclosingDeclaration: Node): SymbolDisplayPart[] {
|
||||
const file = enclosingDeclaration.getSourceFile();
|
||||
return mapToDisplayParts(writer => {
|
||||
const printer = createPrinter({ removeComments: true, omitTrailingSemicolon: true });
|
||||
const printer = createPrinterWithRemoveCommentsOmitTrailingSemicolon();
|
||||
printer.writeNode(EmitHint.Unspecified, node, file, writer);
|
||||
});
|
||||
}
|
||||
@@ -3663,7 +3685,13 @@ export function createPackageJsonImportFilter(fromFile: SourceFile, preferences:
|
||||
).filter(p => p.parseable);
|
||||
|
||||
let usesNodeCoreModules: boolean | undefined;
|
||||
return { allowsImportingAmbientModule, allowsImportingSourceFile, allowsImportingSpecifier };
|
||||
let ambientModuleCache: Map<Symbol, boolean> | undefined;
|
||||
let sourceFileCache: Map<SourceFile, boolean> | undefined;
|
||||
return {
|
||||
allowsImportingAmbientModule,
|
||||
allowsImportingSourceFile,
|
||||
allowsImportingSpecifier,
|
||||
};
|
||||
|
||||
function moduleSpecifierIsCoveredByPackageJson(specifier: string) {
|
||||
const packageName = getNodeModuleRootSpecifier(specifier);
|
||||
@@ -3680,19 +3708,34 @@ export function createPackageJsonImportFilter(fromFile: SourceFile, preferences:
|
||||
return true;
|
||||
}
|
||||
|
||||
const declaringSourceFile = moduleSymbol.valueDeclaration.getSourceFile();
|
||||
const declaringNodeModuleName = getNodeModulesPackageNameFromFileName(declaringSourceFile.fileName, moduleSpecifierResolutionHost);
|
||||
if (typeof declaringNodeModuleName === "undefined") {
|
||||
return true;
|
||||
if (!ambientModuleCache) {
|
||||
ambientModuleCache = new Map();
|
||||
}
|
||||
else {
|
||||
const cached = ambientModuleCache.get(moduleSymbol);
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
|
||||
const declaredModuleSpecifier = stripQuotes(moduleSymbol.getName());
|
||||
if (isAllowedCoreNodeModulesImport(declaredModuleSpecifier)) {
|
||||
ambientModuleCache.set(moduleSymbol, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return moduleSpecifierIsCoveredByPackageJson(declaringNodeModuleName)
|
||||
|| moduleSpecifierIsCoveredByPackageJson(declaredModuleSpecifier);
|
||||
const declaringSourceFile = moduleSymbol.valueDeclaration.getSourceFile();
|
||||
const declaringNodeModuleName = getNodeModulesPackageNameFromFileName(declaringSourceFile.fileName, moduleSpecifierResolutionHost);
|
||||
if (typeof declaringNodeModuleName === "undefined") {
|
||||
ambientModuleCache.set(moduleSymbol, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
const result =
|
||||
moduleSpecifierIsCoveredByPackageJson(declaringNodeModuleName) ||
|
||||
moduleSpecifierIsCoveredByPackageJson(declaredModuleSpecifier);
|
||||
ambientModuleCache.set(moduleSymbol, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function allowsImportingSourceFile(sourceFile: SourceFile, moduleSpecifierResolutionHost: ModuleSpecifierResolutionHost): boolean {
|
||||
@@ -3700,12 +3743,25 @@ export function createPackageJsonImportFilter(fromFile: SourceFile, preferences:
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!sourceFileCache) {
|
||||
sourceFileCache = new Map();
|
||||
}
|
||||
else {
|
||||
const cached = sourceFileCache.get(sourceFile);
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
}
|
||||
|
||||
const moduleSpecifier = getNodeModulesPackageNameFromFileName(sourceFile.fileName, moduleSpecifierResolutionHost);
|
||||
if (!moduleSpecifier) {
|
||||
sourceFileCache.set(sourceFile, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
return moduleSpecifierIsCoveredByPackageJson(moduleSpecifier);
|
||||
const result = moduleSpecifierIsCoveredByPackageJson(moduleSpecifier);
|
||||
sourceFileCache.set(sourceFile, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function allowsImportingSpecifier(moduleSpecifier: string) {
|
||||
@@ -4023,3 +4079,74 @@ export function jsxModeNeedsExplicitImport(jsx: JsxEmit | undefined) {
|
||||
export function isSourceFileFromLibrary(program: Program, node: SourceFile) {
|
||||
return program.isSourceFileFromExternalLibrary(node) || program.isSourceFileDefaultLibrary(node);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface CaseClauseTracker {
|
||||
addValue(value: string | number): void;
|
||||
hasValue(value: string | number | PseudoBigInt): boolean;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function newCaseClauseTracker(checker: TypeChecker, clauses: readonly (CaseClause | DefaultClause)[]): CaseClauseTracker {
|
||||
const existingStrings = new Set<string>();
|
||||
const existingNumbers = new Set<number>();
|
||||
const existingBigInts = new Set<string>();
|
||||
|
||||
for (const clause of clauses) {
|
||||
if (!isDefaultClause(clause)) {
|
||||
if (isLiteralExpression(clause.expression)) {
|
||||
const expression = clause.expression;
|
||||
switch (expression.kind) {
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
existingStrings.add(expression.text);
|
||||
break;
|
||||
case SyntaxKind.NumericLiteral:
|
||||
existingNumbers.add(parseInt(expression.text));
|
||||
break;
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
const parsedBigInt = parseBigInt(endsWith(expression.text, "n") ? expression.text.slice(0, -1) : expression.text);
|
||||
if (parsedBigInt) {
|
||||
existingBigInts.add(pseudoBigIntToString(parsedBigInt));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const symbol = checker.getSymbolAtLocation(clause.expression);
|
||||
if (symbol && symbol.valueDeclaration && isEnumMember(symbol.valueDeclaration)) {
|
||||
const enumValue = checker.getConstantValue(symbol.valueDeclaration);
|
||||
if (enumValue !== undefined) {
|
||||
addValue(enumValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
addValue,
|
||||
hasValue,
|
||||
};
|
||||
|
||||
function addValue(value: string | number) {
|
||||
switch (typeof value) {
|
||||
case "string":
|
||||
existingStrings.add(value);
|
||||
break;
|
||||
case "number":
|
||||
existingNumbers.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
function hasValue(value: string | number | PseudoBigInt): boolean {
|
||||
switch (typeof value) {
|
||||
case "string":
|
||||
return existingStrings.has(value);
|
||||
case "number":
|
||||
return existingNumbers.has(value);
|
||||
case "object":
|
||||
return existingBigInts.has(pseudoBigIntToString(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as compiler from "./_namespaces/compiler";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
import {
|
||||
Baseline,
|
||||
Compiler,
|
||||
@@ -14,6 +11,9 @@ import {
|
||||
TestCaseParser,
|
||||
TestRunnerKind,
|
||||
} from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
export const enum CompilerTestType {
|
||||
Conformance,
|
||||
|
||||
@@ -2,7 +2,6 @@ import * as del from "del";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import {
|
||||
Baseline,
|
||||
IO,
|
||||
@@ -10,6 +9,7 @@ import {
|
||||
RunnerBase,
|
||||
TestRunnerKind,
|
||||
} from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
|
||||
interface ExecResult {
|
||||
stdout: Buffer;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as FourSlash from "./_namespaces/FourSlash";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import {
|
||||
IO,
|
||||
RunnerBase,
|
||||
TestRunnerKind,
|
||||
} from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
|
||||
export class FourSlashRunner extends RunnerBase {
|
||||
protected basePath: string;
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import * as Utils from "../_namespaces/Utils";
|
||||
import * as ts from "../_namespaces/ts";
|
||||
import {
|
||||
configOption,
|
||||
globalTimeout,
|
||||
@@ -24,6 +22,8 @@ import {
|
||||
TaskTimeout,
|
||||
TestInfo,
|
||||
} from "../_namespaces/Harness.Parallel";
|
||||
import * as ts from "../_namespaces/ts";
|
||||
import * as Utils from "../_namespaces/Utils";
|
||||
|
||||
export function start() {
|
||||
const Mocha = require("mocha") as typeof import("mocha");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ts from "../_namespaces/ts";
|
||||
import { TestRunnerKind } from "../_namespaces/Harness";
|
||||
import * as ts from "../_namespaces/ts";
|
||||
|
||||
export interface RunnerTask {
|
||||
runner: TestRunnerKind;
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
import {
|
||||
createRunner,
|
||||
globalTimeout,
|
||||
RunnerBase,
|
||||
runUnitTests,
|
||||
} from "../_namespaces/Harness";
|
||||
import {
|
||||
ErrorInfo,
|
||||
ParallelClientMessage,
|
||||
@@ -9,12 +15,6 @@ import {
|
||||
TestInfo,
|
||||
UnitTestTask,
|
||||
} from "../_namespaces/Harness.Parallel";
|
||||
import {
|
||||
createRunner,
|
||||
globalTimeout,
|
||||
RunnerBase,
|
||||
runUnitTests,
|
||||
} from "../_namespaces/Harness";
|
||||
|
||||
export function start() {
|
||||
function hookUncaughtExceptions() {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as documents from "./_namespaces/documents";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as fakes from "./_namespaces/fakes";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
import * as vfs from "./_namespaces/vfs";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
|
||||
// Test case is json of below type in tests/cases/project/
|
||||
interface ProjectRunnerTestCase {
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as FourSlash from "./_namespaces/FourSlash";
|
||||
import * as project from "./_namespaces/project";
|
||||
import * as RWC from "./_namespaces/RWC";
|
||||
import {
|
||||
CompilerBaselineRunner,
|
||||
CompilerTestType,
|
||||
@@ -20,6 +16,10 @@ import {
|
||||
TestRunnerKind,
|
||||
UserCodeRunner,
|
||||
} from "./_namespaces/Harness";
|
||||
import * as project from "./_namespaces/project";
|
||||
import * as RWC from "./_namespaces/RWC";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
/* eslint-disable prefer-const */
|
||||
export let runners: RunnerBase[] = [];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as Playback from "./_namespaces/Playback";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as compiler from "./_namespaces/compiler";
|
||||
import * as Harness from "./_namespaces/Harness";
|
||||
import * as Playback from "./_namespaces/Playback";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as vpath from "./_namespaces/vpath";
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as compiler from "./_namespaces/compiler";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
import {
|
||||
Baseline,
|
||||
Compiler,
|
||||
@@ -9,6 +7,8 @@ import {
|
||||
TestCaseParser,
|
||||
TestRunnerKind,
|
||||
} from "./_namespaces/Harness";
|
||||
import * as ts from "./_namespaces/ts";
|
||||
import * as Utils from "./_namespaces/Utils";
|
||||
|
||||
// In harness baselines, null is different than undefined. See `generateActual` in `harness.ts`.
|
||||
export class Test262BaselineRunner extends RunnerBase {
|
||||
|
||||
@@ -53,6 +53,7 @@ import "./unittests/services/extract/constants";
|
||||
import "./unittests/services/extract/functions";
|
||||
import "./unittests/services/extract/symbolWalker";
|
||||
import "./unittests/services/extract/ranges";
|
||||
import "./unittests/services/findAllReferences";
|
||||
import "./unittests/services/hostNewLineSupport";
|
||||
import "./unittests/services/languageService";
|
||||
import "./unittests/services/organizeImports";
|
||||
@@ -71,6 +72,7 @@ import "./unittests/tsbuild/demo";
|
||||
import "./unittests/tsbuild/emitDeclarationOnly";
|
||||
import "./unittests/tsbuild/emptyFiles";
|
||||
import "./unittests/tsbuild/exitCodeOnBogusFile";
|
||||
import "./unittests/tsbuild/fileDelete";
|
||||
import "./unittests/tsbuild/graphOrdering";
|
||||
import "./unittests/tsbuild/inferredTypeFromTransitiveModule";
|
||||
import "./unittests/tsbuild/javascriptProjectEmit";
|
||||
@@ -84,6 +86,7 @@ import "./unittests/tsbuild/outputPaths";
|
||||
import "./unittests/tsbuild/publicApi";
|
||||
import "./unittests/tsbuild/referencesWithRootDirInParent";
|
||||
import "./unittests/tsbuild/resolveJsonModule";
|
||||
import "./unittests/tsbuild/roots";
|
||||
import "./unittests/tsbuild/sample";
|
||||
import "./unittests/tsbuild/transitiveReferences";
|
||||
import "./unittests/tsbuildWatch/configFileErrors";
|
||||
@@ -188,3 +191,4 @@ import "./unittests/tsserver/typingsInstaller";
|
||||
import "./unittests/tsserver/versionCache";
|
||||
import "./unittests/tsserver/watchEnvironment";
|
||||
import "./unittests/debugDeprecation";
|
||||
import "./unittests/tsserver/inconsistentErrorInEditor";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as Harness from "../../_namespaces/Harness";
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
|
||||
describe("unittests:: config:: commandLineParsing:: parseCommandLine", () => {
|
||||
function assertParseResult(subScenario: string, commandLine: string[], workerDiagnostic?: () => ts.ParseCommandLineWorkerDiagnostics) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as fakes from "../../_namespaces/fakes";
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as vfs from "../../_namespaces/vfs";
|
||||
import * as fakes from "../../_namespaces/fakes";
|
||||
|
||||
function createFileSystem(ignoreCase: boolean, cwd: string, root: string) {
|
||||
return new vfs.FileSystem(ignoreCase, {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as fakes from "../../_namespaces/fakes";
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as vfs from "../../_namespaces/vfs";
|
||||
|
||||
describe("unittests:: config:: convertCompilerOptionsFromJson", () => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as fakes from "../../_namespaces/fakes";
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as vfs from "../../_namespaces/vfs";
|
||||
|
||||
interface ExpectedResult { typeAcquisition: ts.TypeAcquisition; errors: ts.Diagnostic[]; }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as Harness from "../../_namespaces/Harness";
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
|
||||
describe("unittests:: config:: initTSConfig", () => {
|
||||
function initTSConfigCorrectly(name: string, commandLinesArgs: string[]) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as fakes from "../../_namespaces/fakes";
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as vfs from "../../_namespaces/vfs";
|
||||
|
||||
const caseInsensitiveBasePath = "c:/dev/";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as fakes from "../../_namespaces/fakes";
|
||||
import * as ts from "../../_namespaces/ts";
|
||||
import * as vfs from "../../_namespaces/vfs";
|
||||
import { libFile } from "../virtualFileSystemWithWatch";
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user