mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'main' into server-vfs-support
This commit is contained in:
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use node version 14
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
@@ -16,14 +16,14 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.x, 16.x, 17.x]
|
||||
node-version: [14.x, 16.x, 18.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 5
|
||||
- name: Use node version ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Remove existing TypeScript
|
||||
|
||||
@@ -11,6 +11,7 @@ jobs:
|
||||
|
||||
# CodeQL runs on ubuntu-latest and windows-latest
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'microsoft/TypeScript'
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
||||
@@ -14,6 +14,7 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'microsoft/TypeScript'
|
||||
|
||||
steps:
|
||||
- name: Configure git
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Use node version 14.x
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14.x
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -11,11 +11,12 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'microsoft/TypeScript'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use node version 14
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use node version 14
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
- name: Remove existing TypeScript
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 5
|
||||
|
||||
- uses: actions/setup-node@v2
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Use node version 14.x
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14.x
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Use node version 14.x
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14.x
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -20,11 +20,11 @@ on:
|
||||
|
||||
jobs:
|
||||
run:
|
||||
if: ${{ !github.event.label && !github.event.inputs.bisect_issue }}
|
||||
if: ${{ github.repository == 'microsoft/TypeScript' && !github.event.label && !github.event.inputs.bisect_issue }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Use node
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
- uses: microsoft/TypeScript-Twoslash-Repro-Action@master
|
||||
with:
|
||||
github-token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- uses: microsoft/TypeScript-Twoslash-Repro-Action@master
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use node version 14
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
@@ -10,10 +10,11 @@ on:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'microsoft/TypeScript'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
@@ -169,6 +169,7 @@ TypeScript is authored by:
|
||||
- Gabriel Isenberg
|
||||
- Gabriela Araujo Britto
|
||||
- Gabriela Britto
|
||||
- Gao Sheng
|
||||
- gb714us
|
||||
- Gilad Peleg
|
||||
- Godfrey Chan
|
||||
|
||||
Generated
+37
-43
@@ -626,9 +626,9 @@
|
||||
}
|
||||
},
|
||||
"@types/mocha": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.0.tgz",
|
||||
"integrity": "sha512-QCWHkbMv4Y5U9oW10Uxbr45qMMSzl4OzijsozynUAgx3kEHUdXB00udx2dWDQ7f2TU2a2uuiFaRZjCe3unPpeg==",
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz",
|
||||
"integrity": "sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/ms": {
|
||||
@@ -638,9 +638,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "17.0.24",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.24.tgz",
|
||||
"integrity": "sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g==",
|
||||
"version": "17.0.31",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.31.tgz",
|
||||
"integrity": "sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node-fetch": {
|
||||
@@ -3334,12 +3334,6 @@
|
||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
||||
"dev": true
|
||||
},
|
||||
"growl": {
|
||||
"version": "1.10.5",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
||||
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
|
||||
"dev": true
|
||||
},
|
||||
"gulp": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
|
||||
@@ -4328,32 +4322,30 @@
|
||||
"dev": true
|
||||
},
|
||||
"mocha": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
|
||||
"integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==",
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz",
|
||||
"integrity": "sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@ungap/promise-all-settled": "1.1.2",
|
||||
"ansi-colors": "4.1.1",
|
||||
"browser-stdout": "1.3.1",
|
||||
"chokidar": "3.5.3",
|
||||
"debug": "4.3.3",
|
||||
"debug": "4.3.4",
|
||||
"diff": "5.0.0",
|
||||
"escape-string-regexp": "4.0.0",
|
||||
"find-up": "5.0.0",
|
||||
"glob": "7.2.0",
|
||||
"growl": "1.10.5",
|
||||
"he": "1.2.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"log-symbols": "4.1.0",
|
||||
"minimatch": "4.2.1",
|
||||
"minimatch": "5.0.1",
|
||||
"ms": "2.1.3",
|
||||
"nanoid": "3.3.1",
|
||||
"nanoid": "3.3.3",
|
||||
"serialize-javascript": "6.0.0",
|
||||
"strip-json-comments": "3.1.1",
|
||||
"supports-color": "8.1.1",
|
||||
"which": "2.0.2",
|
||||
"workerpool": "6.2.0",
|
||||
"workerpool": "6.2.1",
|
||||
"yargs": "16.2.0",
|
||||
"yargs-parser": "20.2.4",
|
||||
"yargs-unparser": "2.0.0"
|
||||
@@ -4430,9 +4422,9 @@
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
|
||||
"integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
@@ -4570,12 +4562,23 @@
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz",
|
||||
"integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
|
||||
"integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"p-limit": {
|
||||
@@ -4651,15 +4654,6 @@
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
@@ -4726,9 +4720,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
|
||||
"integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz",
|
||||
"integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==",
|
||||
"dev": true
|
||||
},
|
||||
"nanomatch": {
|
||||
@@ -6685,9 +6679,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"workerpool": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
|
||||
"integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
|
||||
"integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
|
||||
"dev": true
|
||||
},
|
||||
"wrap-ansi": {
|
||||
|
||||
@@ -122,7 +122,9 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode,
|
||||
|
||||
try {
|
||||
setNodeEnvToDevelopment();
|
||||
const { exitCode } = await exec("node", args, { cancelToken });
|
||||
const { exitCode } = await exec(process.execPath, args, {
|
||||
cancelToken,
|
||||
});
|
||||
if (exitCode !== 0) {
|
||||
errorStatus = exitCode;
|
||||
error = new Error(`Process exited with status code ${errorStatus}.`);
|
||||
|
||||
+171
-69
@@ -161,6 +161,8 @@ namespace ts {
|
||||
* true if program has been emitted
|
||||
*/
|
||||
programEmitComplete?: true;
|
||||
/** Stores list of files that change signature during emit - test only */
|
||||
filesChangingSignature?: Set<Path>;
|
||||
}
|
||||
|
||||
function hasSameKeys(map1: ReadonlyCollection<string> | undefined, map2: ReadonlyCollection<string> | undefined): boolean {
|
||||
@@ -434,25 +436,35 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function removeDiagnosticsOfLibraryFiles(state: BuilderProgramState) {
|
||||
if (!state.cleanedDiagnosticsOfLibFiles) {
|
||||
state.cleanedDiagnosticsOfLibFiles = true;
|
||||
const program = Debug.checkDefined(state.program);
|
||||
const options = program.getCompilerOptions();
|
||||
forEach(program.getSourceFiles(), f =>
|
||||
program.isSourceFileDefaultLibrary(f) &&
|
||||
!skipTypeChecking(f, options, program) &&
|
||||
removeSemanticDiagnosticsOf(state, f.resolvedPath)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles semantic diagnostics and dts emit for affectedFile and files, that are referencing modules that export entities from affected file
|
||||
* This is because even though js emit doesnt change, dts emit / type used can change resulting in need for dts emit and js change
|
||||
*/
|
||||
function handleDtsMayChangeOfAffectedFile(state: BuilderProgramState, affectedFile: SourceFile, cancellationToken: CancellationToken | undefined, computeHash: BuilderState.ComputeHash, host: BuilderProgramHost) {
|
||||
function handleDtsMayChangeOfAffectedFile(
|
||||
state: BuilderProgramState,
|
||||
affectedFile: SourceFile,
|
||||
cancellationToken: CancellationToken | undefined,
|
||||
computeHash: BuilderState.ComputeHash,
|
||||
host: BuilderProgramHost,
|
||||
) {
|
||||
removeSemanticDiagnosticsOf(state, affectedFile.resolvedPath);
|
||||
|
||||
// If affected files is everything except default library, then nothing more to do
|
||||
if (state.allFilesExcludingDefaultLibraryFile === state.affectedFiles) {
|
||||
if (!state.cleanedDiagnosticsOfLibFiles) {
|
||||
state.cleanedDiagnosticsOfLibFiles = true;
|
||||
const program = Debug.checkDefined(state.program);
|
||||
const options = program.getCompilerOptions();
|
||||
forEach(program.getSourceFiles(), f =>
|
||||
program.isSourceFileDefaultLibrary(f) &&
|
||||
!skipTypeChecking(f, options, program) &&
|
||||
removeSemanticDiagnosticsOf(state, f.resolvedPath)
|
||||
);
|
||||
}
|
||||
removeDiagnosticsOfLibraryFiles(state);
|
||||
// When a change affects the global scope, all files are considered to be affected without updating their signature
|
||||
// That means when affected file is handled, its signature can be out of date
|
||||
// To avoid this, ensure that we update the signature for any affected file in this scenario.
|
||||
@@ -467,20 +479,22 @@ namespace ts {
|
||||
);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
Debug.assert(state.hasCalledUpdateShapeSignature.has(affectedFile.resolvedPath) || state.currentAffectedFilesSignatures?.has(affectedFile.resolvedPath), `Signature not updated for affected file: ${affectedFile.fileName}`);
|
||||
}
|
||||
|
||||
if (!state.compilerOptions.assumeChangesOnlyAffectDirectDependencies) {
|
||||
forEachReferencingModulesOfExportOfAffectedFile(state, affectedFile, (state, path) => handleDtsMayChangeOf(state, path, cancellationToken, computeHash, host));
|
||||
}
|
||||
Debug.assert(state.hasCalledUpdateShapeSignature.has(affectedFile.resolvedPath) || state.currentAffectedFilesSignatures?.has(affectedFile.resolvedPath), `Signature not updated for affected file: ${affectedFile.fileName}`);
|
||||
if (state.compilerOptions.assumeChangesOnlyAffectDirectDependencies) return;
|
||||
handleDtsMayChangeOfReferencingExportOfAffectedFile(state, affectedFile, cancellationToken, computeHash, host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the dts may change, so they need to be added to pending emit if dts emit is enabled,
|
||||
* Also we need to make sure signature is updated for these files
|
||||
*/
|
||||
function handleDtsMayChangeOf(state: BuilderProgramState, path: Path, cancellationToken: CancellationToken | undefined, computeHash: BuilderState.ComputeHash, host: BuilderProgramHost): void {
|
||||
function handleDtsMayChangeOf(
|
||||
state: BuilderProgramState,
|
||||
path: Path,
|
||||
cancellationToken: CancellationToken | undefined,
|
||||
computeHash: BuilderState.ComputeHash,
|
||||
host: BuilderProgramHost
|
||||
): void {
|
||||
removeSemanticDiagnosticsOf(state, path);
|
||||
|
||||
if (!state.changedFilesSet.has(path)) {
|
||||
@@ -529,16 +543,61 @@ namespace ts {
|
||||
return newSignature !== oldSignature;
|
||||
}
|
||||
|
||||
function forEachKeyOfExportedModulesMap<T>(
|
||||
state: BuilderProgramState,
|
||||
filePath: Path,
|
||||
fn: (exportedFromPath: Path) => T | undefined,
|
||||
): T | undefined {
|
||||
// Go through exported modules from cache first
|
||||
let keys = state.currentAffectedFilesExportedModulesMap!.getKeys(filePath);
|
||||
const result = keys && forEachKey(keys, fn);
|
||||
if (result) return result;
|
||||
|
||||
// If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
|
||||
keys = state.exportedModulesMap!.getKeys(filePath);
|
||||
return keys && forEachKey(keys, exportedFromPath =>
|
||||
// If the cache had an updated value, skip
|
||||
!state.currentAffectedFilesExportedModulesMap!.hasKey(exportedFromPath) &&
|
||||
!state.currentAffectedFilesExportedModulesMap!.deletedKeys()?.has(exportedFromPath) ?
|
||||
fn(exportedFromPath) :
|
||||
undefined
|
||||
);
|
||||
}
|
||||
|
||||
function handleDtsMayChangeOfGlobalScope(
|
||||
state: BuilderProgramState,
|
||||
filePath: Path,
|
||||
cancellationToken: CancellationToken | undefined,
|
||||
computeHash: BuilderState.ComputeHash,
|
||||
host: BuilderProgramHost,
|
||||
): boolean {
|
||||
if (!state.fileInfos.get(filePath)?.affectsGlobalScope) return false;
|
||||
// Every file needs to be handled
|
||||
BuilderState.getAllFilesExcludingDefaultLibraryFile(state, state.program!, /*firstSourceFile*/ undefined)
|
||||
.forEach(file => handleDtsMayChangeOf(
|
||||
state,
|
||||
file.resolvedPath,
|
||||
cancellationToken,
|
||||
computeHash,
|
||||
host,
|
||||
));
|
||||
removeDiagnosticsOfLibraryFiles(state);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate on referencing modules that export entities from affected file
|
||||
* Iterate on referencing modules that export entities from affected file and delete diagnostics and add pending emit
|
||||
*/
|
||||
function forEachReferencingModulesOfExportOfAffectedFile(state: BuilderProgramState, affectedFile: SourceFile, fn: (state: BuilderProgramState, filePath: Path) => void) {
|
||||
function handleDtsMayChangeOfReferencingExportOfAffectedFile(
|
||||
state: BuilderProgramState,
|
||||
affectedFile: SourceFile,
|
||||
cancellationToken: CancellationToken | undefined,
|
||||
computeHash: BuilderState.ComputeHash,
|
||||
host: BuilderProgramHost
|
||||
) {
|
||||
// If there was change in signature (dts output) for the changed file,
|
||||
// then only we need to handle pending file emit
|
||||
if (!state.exportedModulesMap || !state.changedFilesSet.has(affectedFile.resolvedPath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!state.exportedModulesMap || !state.changedFilesSet.has(affectedFile.resolvedPath)) return;
|
||||
if (!isChangedSignature(state, affectedFile.resolvedPath)) return;
|
||||
|
||||
// Since isolated modules dont change js files, files affected by change in signature is itself
|
||||
@@ -551,7 +610,8 @@ namespace ts {
|
||||
const currentPath = queue.pop()!;
|
||||
if (!seenFileNamesMap.has(currentPath)) {
|
||||
seenFileNamesMap.set(currentPath, true);
|
||||
fn(state, currentPath);
|
||||
if (handleDtsMayChangeOfGlobalScope(state, currentPath, cancellationToken, computeHash, host)) return;
|
||||
handleDtsMayChangeOf(state, currentPath, cancellationToken, computeHash, host);
|
||||
if (isChangedSignature(state, currentPath)) {
|
||||
const currentSourceFile = Debug.checkDefined(state.program).getSourceFileByPath(currentPath)!;
|
||||
queue.push(...BuilderState.getReferencedByPaths(state, currentSourceFile.resolvedPath));
|
||||
@@ -561,65 +621,69 @@ namespace ts {
|
||||
}
|
||||
|
||||
Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
|
||||
|
||||
const seenFileAndExportsOfFile = new Set<string>();
|
||||
// Go through exported modules from cache first
|
||||
// If exported modules has path, all files referencing file exported from are affected
|
||||
state.currentAffectedFilesExportedModulesMap.getKeys(affectedFile.resolvedPath)?.forEach(exportedFromPath =>
|
||||
forEachFilesReferencingPath(state, exportedFromPath, seenFileAndExportsOfFile, fn)
|
||||
);
|
||||
|
||||
// If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
|
||||
state.exportedModulesMap.getKeys(affectedFile.resolvedPath)?.forEach(exportedFromPath =>
|
||||
// If the cache had an updated value, skip
|
||||
!state.currentAffectedFilesExportedModulesMap!.hasKey(exportedFromPath) &&
|
||||
!state.currentAffectedFilesExportedModulesMap!.deletedKeys()?.has(exportedFromPath) &&
|
||||
forEachFilesReferencingPath(state, exportedFromPath, seenFileAndExportsOfFile, fn)
|
||||
);
|
||||
forEachKeyOfExportedModulesMap(state, affectedFile.resolvedPath, exportedFromPath => {
|
||||
if (handleDtsMayChangeOfGlobalScope(state, exportedFromPath, cancellationToken, computeHash, host)) return true;
|
||||
const references = state.referencedMap!.getKeys(exportedFromPath);
|
||||
return references && forEachKey(references, filePath =>
|
||||
handleDtsMayChangeOfFileAndExportsOfFile(
|
||||
state,
|
||||
filePath,
|
||||
seenFileAndExportsOfFile,
|
||||
cancellationToken,
|
||||
computeHash,
|
||||
host,
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate on files referencing referencedPath
|
||||
* handle dts and semantic diagnostics on file and iterate on anything that exports this file
|
||||
* return true when all work is done and we can exit handling dts emit and semantic diagnostics
|
||||
*/
|
||||
function forEachFilesReferencingPath(state: BuilderProgramState, referencedPath: Path, seenFileAndExportsOfFile: Set<string>, fn: (state: BuilderProgramState, filePath: Path) => void): void {
|
||||
state.referencedMap!.getKeys(referencedPath)?.forEach(filePath =>
|
||||
forEachFileAndExportsOfFile(state, filePath, seenFileAndExportsOfFile, fn)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* fn on file and iterate on anything that exports this file
|
||||
*/
|
||||
function forEachFileAndExportsOfFile(state: BuilderProgramState, filePath: Path, seenFileAndExportsOfFile: Set<string>, fn: (state: BuilderProgramState, filePath: Path) => void): void {
|
||||
if (!tryAddToSet(seenFileAndExportsOfFile, filePath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fn(state, filePath);
|
||||
function handleDtsMayChangeOfFileAndExportsOfFile(
|
||||
state: BuilderProgramState,
|
||||
filePath: Path,
|
||||
seenFileAndExportsOfFile: Set<string>,
|
||||
cancellationToken: CancellationToken | undefined,
|
||||
computeHash: BuilderState.ComputeHash,
|
||||
host: BuilderProgramHost,
|
||||
): boolean | undefined {
|
||||
if (!tryAddToSet(seenFileAndExportsOfFile, filePath)) return undefined;
|
||||
|
||||
if (handleDtsMayChangeOfGlobalScope(state, filePath, cancellationToken, computeHash, host)) return true;
|
||||
handleDtsMayChangeOf(state, filePath, cancellationToken, computeHash, host);
|
||||
Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
|
||||
// Go through exported modules from cache first
|
||||
// If exported modules has path, all files referencing file exported from are affected
|
||||
state.currentAffectedFilesExportedModulesMap.getKeys(filePath)?.forEach(exportedFromPath =>
|
||||
forEachFileAndExportsOfFile(state, exportedFromPath, seenFileAndExportsOfFile, fn)
|
||||
);
|
||||
|
||||
// If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
|
||||
state.exportedModulesMap!.getKeys(filePath)?.forEach(exportedFromPath =>
|
||||
// If the cache had an updated value, skip
|
||||
!state.currentAffectedFilesExportedModulesMap!.hasKey(exportedFromPath) &&
|
||||
!state.currentAffectedFilesExportedModulesMap!.deletedKeys()?.has(exportedFromPath) &&
|
||||
forEachFileAndExportsOfFile(state, exportedFromPath, seenFileAndExportsOfFile, fn)
|
||||
// If exported modules has path, all files referencing file exported from are affected
|
||||
forEachKeyOfExportedModulesMap(state, filePath, exportedFromPath =>
|
||||
handleDtsMayChangeOfFileAndExportsOfFile(
|
||||
state,
|
||||
exportedFromPath,
|
||||
seenFileAndExportsOfFile,
|
||||
cancellationToken,
|
||||
computeHash,
|
||||
host,
|
||||
)
|
||||
);
|
||||
|
||||
// Remove diagnostics of files that import this file (without going to exports of referencing files)
|
||||
state.referencedMap!.getKeys(filePath)?.forEach(referencingFilePath =>
|
||||
!seenFileAndExportsOfFile.has(referencingFilePath) && // Not already removed diagnostic file
|
||||
fn(state, referencingFilePath) // Dont add to seen since this is not yet done with the export removal
|
||||
handleDtsMayChangeOf( // Dont add to seen since this is not yet done with the export removal
|
||||
state,
|
||||
referencingFilePath,
|
||||
cancellationToken,
|
||||
computeHash,
|
||||
host,
|
||||
)
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is called after completing operation on the next affected file.
|
||||
* The operations here are postponed to ensure that cancellation during the iteration is handled correctly
|
||||
@@ -1088,7 +1152,9 @@ namespace ts {
|
||||
// Otherwise just affected file
|
||||
Debug.checkDefined(state.program).emit(
|
||||
affected === state.program ? undefined : affected as SourceFile,
|
||||
writeFile || maybeBind(host, host.writeFile),
|
||||
affected !== state.program && getEmitDeclarations(state.compilerOptions) && !customTransformers ?
|
||||
getWriteFileUpdatingSignatureCallback(writeFile) :
|
||||
writeFile || maybeBind(host, host.writeFile),
|
||||
cancellationToken,
|
||||
emitOnlyDtsFiles || emitKind === BuilderFileEmit.DtsOnly,
|
||||
customTransformers
|
||||
@@ -1099,6 +1165,34 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function getWriteFileUpdatingSignatureCallback(writeFile: WriteFileCallback | undefined): WriteFileCallback {
|
||||
return (fileName, text, writeByteOrderMark, onError, sourceFiles, data) => {
|
||||
if (isDeclarationFileName(fileName)) {
|
||||
Debug.assert(sourceFiles?.length === 1);
|
||||
const file = sourceFiles[0];
|
||||
const info = state.fileInfos.get(file.resolvedPath)!;
|
||||
const signature = state.currentAffectedFilesSignatures?.get(file.resolvedPath) || info.signature;
|
||||
if (signature === file.version) {
|
||||
const newSignature = (computeHash || generateDjb2Hash)(data?.sourceMapUrlPos !== undefined ? text.substring(0, data.sourceMapUrlPos) : text);
|
||||
if (newSignature !== file.version) { // Update it
|
||||
if (host.storeFilesChangingSignatureDuringEmit) (state.filesChangingSignature ||= new Set()).add(file.resolvedPath);
|
||||
if (state.exportedModulesMap) BuilderState.updateExportedModules(file, file.exportedModulesFromDeclarationEmit, state.currentAffectedFilesExportedModulesMap ||= BuilderState.createManyToManyPathMap());
|
||||
if (state.affectedFiles && state.affectedFilesIndex! < state.affectedFiles.length) {
|
||||
state.currentAffectedFilesSignatures!.set(file.resolvedPath, newSignature);
|
||||
}
|
||||
else {
|
||||
info.signature = newSignature;
|
||||
if (state.exportedModulesMap) BuilderState.updateExportedFilesMapFromCache(state, state.currentAffectedFilesExportedModulesMap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (writeFile) writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
|
||||
else if (host.writeFile) host.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
|
||||
else state.program!.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits the JavaScript and declaration files.
|
||||
* When targetSource file is specified, emits the files corresponding to that source file,
|
||||
@@ -1153,7 +1247,15 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
return Debug.checkDefined(state.program).emit(targetSourceFile, writeFile || maybeBind(host, host.writeFile), cancellationToken, emitOnlyDtsFiles, customTransformers);
|
||||
return Debug.checkDefined(state.program).emit(
|
||||
targetSourceFile,
|
||||
!outFile(state.compilerOptions) && getEmitDeclarations(state.compilerOptions) && !customTransformers ?
|
||||
getWriteFileUpdatingSignatureCallback(writeFile) :
|
||||
writeFile || maybeBind(host, host.writeFile),
|
||||
cancellationToken,
|
||||
emitOnlyDtsFiles,
|
||||
customTransformers
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,11 @@ namespace ts {
|
||||
*/
|
||||
/*@internal*/
|
||||
disableUseFileVersionAsSignature?: boolean;
|
||||
/**
|
||||
* Store the list of files that update signature during the emit
|
||||
*/
|
||||
/*@internal*/
|
||||
storeFilesChangingSignatureDuringEmit?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -450,7 +450,7 @@ namespace ts {
|
||||
/**
|
||||
* Coverts the declaration emit result into exported modules map
|
||||
*/
|
||||
function updateExportedModules(sourceFile: SourceFile, exportedModulesFromDeclarationEmit: ExportedModulesFromDeclarationEmit | undefined, exportedModulesMapCache: ManyToManyPathMap) {
|
||||
export function updateExportedModules(sourceFile: SourceFile, exportedModulesFromDeclarationEmit: ExportedModulesFromDeclarationEmit | undefined, exportedModulesMapCache: ManyToManyPathMap) {
|
||||
if (!exportedModulesFromDeclarationEmit) {
|
||||
exportedModulesMapCache.deleteKey(sourceFile.resolvedPath);
|
||||
return;
|
||||
|
||||
+155
-74
@@ -833,6 +833,7 @@ namespace ts {
|
||||
const keyofConstraintType = keyofStringsOnly ? stringType : stringNumberSymbolType;
|
||||
const numberOrBigIntType = getUnionType([numberType, bigintType]);
|
||||
const templateConstraintType = getUnionType([stringType, numberType, booleanType, bigintType, nullType, undefinedType]) as UnionType;
|
||||
const numericStringType = getTemplateLiteralType(["", ""], [numberType]); // The `${number}` type
|
||||
|
||||
const restrictiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? getRestrictiveTypeParameter(t as TypeParameter) : t);
|
||||
const permissiveMapper: TypeMapper = makeFunctionTypeMapper(t => t.flags & TypeFlags.TypeParameter ? wildcardType : t);
|
||||
@@ -1047,7 +1048,7 @@ namespace ts {
|
||||
const builtinGlobals = createSymbolTable();
|
||||
builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
|
||||
|
||||
// Extensions suggested for path imports when module resolution is node12 or higher.
|
||||
// Extensions suggested for path imports when module resolution is node16 or higher.
|
||||
// The first element of each tuple is the extension a file has.
|
||||
// The second element of each tuple is the extension that should be used in a path import.
|
||||
// e.g. if we want to import file `foo.mts`, we should write `import {} from "./foo.mjs".
|
||||
@@ -3527,7 +3528,7 @@ namespace ts {
|
||||
if (resolvedModule.isExternalLibraryImport && !resolutionExtensionIsTSOrJson(resolvedModule.extension)) {
|
||||
errorOnImplicitAnyModule(/*isError*/ false, errorNode, resolvedModule, moduleReference);
|
||||
}
|
||||
if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node12 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) {
|
||||
if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) {
|
||||
const isSyncImport = (currentSourceFile.impliedNodeFormat === ModuleKind.CommonJS && !findAncestor(location, isImportCall)) || !!findAncestor(location, isImportEqualsDeclaration);
|
||||
const overrideClauseHost = findAncestor(location, l => isImportTypeNode(l) || isExportDeclaration(l) || isImportDeclaration(l)) as ImportTypeNode | ImportDeclaration | ExportDeclaration | undefined;
|
||||
const overrideClause = overrideClauseHost && isImportTypeNode(overrideClauseHost) ? overrideClauseHost.assertions?.assertClause : overrideClauseHost?.assertClause;
|
||||
@@ -3536,9 +3537,6 @@ namespace ts {
|
||||
if (isSyncImport && sourceFile.impliedNodeFormat === ModuleKind.ESNext && !getResolutionModeOverrideForClause(overrideClause)) {
|
||||
error(errorNode, Diagnostics.Module_0_cannot_be_imported_using_this_construct_The_specifier_only_resolves_to_an_ES_module_which_cannot_be_imported_synchronously_Use_dynamic_import_instead, moduleReference);
|
||||
}
|
||||
if (mode === ModuleKind.ESNext && compilerOptions.resolveJsonModule && resolvedModule.extension === Extension.Json) {
|
||||
error(errorNode, Diagnostics.JSON_imports_are_experimental_in_ES_module_mode_imports);
|
||||
}
|
||||
}
|
||||
// merged symbol is module declaration symbol combined with all augmentations
|
||||
return getMergedSymbol(sourceFile.symbol);
|
||||
@@ -3595,7 +3593,7 @@ namespace ts {
|
||||
const tsExtension = tryExtractTSExtension(moduleReference);
|
||||
const isExtensionlessRelativePathImport = pathIsRelative(moduleReference) && !hasExtension(moduleReference);
|
||||
const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions);
|
||||
const resolutionIsNode12OrNext = moduleResolutionKind === ModuleResolutionKind.Node12 ||
|
||||
const resolutionIsNode16OrNext = moduleResolutionKind === ModuleResolutionKind.Node16 ||
|
||||
moduleResolutionKind === ModuleResolutionKind.NodeNext;
|
||||
if (tsExtension) {
|
||||
const diag = Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead;
|
||||
@@ -3616,16 +3614,16 @@ namespace ts {
|
||||
hasJsonModuleEmitEnabled(compilerOptions)) {
|
||||
error(errorNode, Diagnostics.Cannot_find_module_0_Consider_using_resolveJsonModule_to_import_module_with_json_extension, moduleReference);
|
||||
}
|
||||
else if (mode === ModuleKind.ESNext && resolutionIsNode12OrNext && isExtensionlessRelativePathImport) {
|
||||
else if (mode === ModuleKind.ESNext && resolutionIsNode16OrNext && isExtensionlessRelativePathImport) {
|
||||
const absoluteRef = getNormalizedAbsolutePath(moduleReference, getDirectoryPath(currentSourceFile.path));
|
||||
const suggestedExt = suggestedExtensions.find(([actualExt, _importExt]) => host.fileExists(absoluteRef + actualExt))?.[1];
|
||||
if (suggestedExt) {
|
||||
error(errorNode,
|
||||
Diagnostics.Relative_import_paths_need_explicit_file_extensions_in_EcmaScript_imports_when_moduleResolution_is_node12_or_nodenext_Did_you_mean_0,
|
||||
Diagnostics.Relative_import_paths_need_explicit_file_extensions_in_EcmaScript_imports_when_moduleResolution_is_node16_or_nodenext_Did_you_mean_0,
|
||||
moduleReference + suggestedExt);
|
||||
}
|
||||
else {
|
||||
error(errorNode, Diagnostics.Relative_import_paths_need_explicit_file_extensions_in_EcmaScript_imports_when_moduleResolution_is_node12_or_nodenext_Consider_adding_an_extension_to_the_import_path);
|
||||
error(errorNode, Diagnostics.Relative_import_paths_need_explicit_file_extensions_in_EcmaScript_imports_when_moduleResolution_is_node16_or_nodenext_Consider_adding_an_extension_to_the_import_path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -4109,7 +4107,7 @@ namespace ts {
|
||||
function getExportSymbolOfValueSymbolIfExported(symbol: Symbol): Symbol;
|
||||
function getExportSymbolOfValueSymbolIfExported(symbol: Symbol | undefined): Symbol | undefined;
|
||||
function getExportSymbolOfValueSymbolIfExported(symbol: Symbol | undefined): Symbol | undefined {
|
||||
return getMergedSymbol(symbol && (symbol.flags & SymbolFlags.ExportValue) !== 0 ? symbol.exportSymbol : symbol);
|
||||
return getMergedSymbol(symbol && (symbol.flags & SymbolFlags.ExportValue) !== 0 && symbol.exportSymbol || symbol);
|
||||
}
|
||||
|
||||
function symbolIsValue(symbol: Symbol): boolean {
|
||||
@@ -6190,7 +6188,7 @@ namespace ts {
|
||||
const targetFile = getSourceFileOfModule(chain[0]);
|
||||
let specifier: string | undefined;
|
||||
let assertion: ImportTypeAssertionContainer | undefined;
|
||||
if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node12 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) {
|
||||
if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) {
|
||||
// An `import` type directed at an esm format file is only going to resolve in esm mode - set the esm mode assertion
|
||||
if (targetFile?.impliedNodeFormat === ModuleKind.ESNext && targetFile.impliedNodeFormat !== contextFile?.impliedNodeFormat) {
|
||||
specifier = getSpecifierForModuleSymbol(chain[0], context, ModuleKind.ESNext);
|
||||
@@ -6207,7 +6205,7 @@ namespace ts {
|
||||
}
|
||||
if (!(context.flags & NodeBuilderFlags.AllowNodeModulesRelativePaths) && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Classic && specifier.indexOf("/node_modules/") >= 0) {
|
||||
const oldSpecifier = specifier;
|
||||
if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node12 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) {
|
||||
if (getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext) {
|
||||
// We might be able to write a portable import type using a mode override; try specifier generation again, but with a different mode set
|
||||
const swappedMode = contextFile?.impliedNodeFormat === ModuleKind.ESNext ? ModuleKind.CommonJS : ModuleKind.ESNext;
|
||||
specifier = getSpecifierForModuleSymbol(chain[0], context, swappedMode);
|
||||
@@ -11506,7 +11504,7 @@ namespace ts {
|
||||
if (symbol === globalThisSymbol) {
|
||||
const varsOnly = new Map<string, Symbol>() as SymbolTable;
|
||||
members.forEach(p => {
|
||||
if (!(p.flags & SymbolFlags.BlockScoped)) {
|
||||
if (!(p.flags & SymbolFlags.BlockScoped) && !(p.flags & SymbolFlags.ValueModule && p.declarations?.length && every(p.declarations, isAmbientModule))) {
|
||||
varsOnly.set(p.escapedName, p);
|
||||
}
|
||||
});
|
||||
@@ -12273,7 +12271,7 @@ namespace ts {
|
||||
const typeVariable = getHomomorphicTypeVariable(type);
|
||||
if (typeVariable && !type.declaration.nameType) {
|
||||
const constraint = getConstraintOfTypeParameter(typeVariable);
|
||||
if (constraint && (isArrayType(constraint) || isTupleType(constraint))) {
|
||||
if (constraint && isArrayOrTupleType(constraint)) {
|
||||
return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
|
||||
}
|
||||
}
|
||||
@@ -12654,10 +12652,10 @@ namespace ts {
|
||||
|
||||
function isApplicableIndexType(source: Type, target: Type): boolean {
|
||||
// A 'string' index signature applies to types assignable to 'string' or 'number', and a 'number' index
|
||||
// signature applies to types assignable to 'number' and numeric string literal types.
|
||||
// signature applies to types assignable to 'number', `${number}` and numeric string literal types.
|
||||
return isTypeAssignableTo(source, target) ||
|
||||
target === stringType && isTypeAssignableTo(source, numberType) ||
|
||||
target === numberType && !!(source.flags & TypeFlags.StringLiteral) && isNumericLiteralName((source as StringLiteralType).value);
|
||||
target === numberType && (source === numericStringType || !!(source.flags & TypeFlags.StringLiteral) && isNumericLiteralName((source as StringLiteralType).value));
|
||||
}
|
||||
|
||||
function getIndexInfosOfStructuredType(type: Type): readonly IndexInfo[] {
|
||||
@@ -13778,6 +13776,20 @@ namespace ts {
|
||||
constraints = append(constraints, constraint);
|
||||
}
|
||||
}
|
||||
// Given a homomorphic mapped type { [K in keyof T]: XXX }, where T is constrained to an array or tuple type, in the
|
||||
// template type XXX, K has an added constraint of number | `${number}`.
|
||||
else if (type.flags & TypeFlags.TypeParameter && parent.kind === SyntaxKind.MappedType && node === (parent as MappedTypeNode).type) {
|
||||
const mappedType = getTypeFromTypeNode(parent as TypeNode) as MappedType;
|
||||
if (getTypeParameterFromMappedType(mappedType) === getActualTypeVariable(type)) {
|
||||
const typeParameter = getHomomorphicTypeVariable(mappedType);
|
||||
if (typeParameter) {
|
||||
const constraint = getConstraintOfTypeParameter(typeParameter);
|
||||
if (constraint && everyType(constraint, isArrayOrTupleType)) {
|
||||
constraints = append(constraints, getUnionType([numberType, numericStringType]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
node = parent;
|
||||
}
|
||||
return constraints ? getSubstitutionType(type, getIntersectionType(append(constraints, type))) : type;
|
||||
@@ -14817,7 +14829,7 @@ namespace ts {
|
||||
i--;
|
||||
const t = types[i];
|
||||
const remove =
|
||||
t.flags & TypeFlags.String && includes & TypeFlags.StringLiteral ||
|
||||
t.flags & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ||
|
||||
t.flags & TypeFlags.Number && includes & TypeFlags.NumberLiteral ||
|
||||
t.flags & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral ||
|
||||
t.flags & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol;
|
||||
@@ -14978,7 +14990,7 @@ namespace ts {
|
||||
if (!strictNullChecks && includes & TypeFlags.Nullable) {
|
||||
return includes & TypeFlags.Undefined ? undefinedType : nullType;
|
||||
}
|
||||
if (includes & TypeFlags.String && includes & TypeFlags.StringLiteral ||
|
||||
if (includes & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ||
|
||||
includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral ||
|
||||
includes & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral ||
|
||||
includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol) {
|
||||
@@ -15737,11 +15749,14 @@ namespace ts {
|
||||
return type[cache] = elementType;
|
||||
}
|
||||
}
|
||||
// If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper
|
||||
// that substitutes the index type for P. For example, for an index access { [P in K]: Box<T[P]> }[X], we
|
||||
// construct the type Box<T[X]>.
|
||||
if (isGenericMappedType(objectType) && !objectType.declaration.nameType) {
|
||||
return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), t => getSimplifiedType(t, writing));
|
||||
// If the object type is a mapped type { [P in K]: E }, where K is generic, or { [P in K as N]: E }, where
|
||||
// K is generic and N is assignable to P, instantiate E using a mapper that substitutes the index type for P.
|
||||
// For example, for an index access { [P in K]: Box<T[P]> }[X], we construct the type Box<T[X]>.
|
||||
if (isGenericMappedType(objectType)) {
|
||||
const nameType = getNameTypeFromMappedType(objectType);
|
||||
if (!nameType || isTypeAssignableTo(nameType, getTypeParameterFromMappedType(objectType))) {
|
||||
return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), t => getSimplifiedType(t, writing));
|
||||
}
|
||||
}
|
||||
return type[cache] = type;
|
||||
}
|
||||
@@ -16993,7 +17008,7 @@ namespace ts {
|
||||
if (!type.declaration.nameType) {
|
||||
let constraint;
|
||||
if (isArrayType(t) || t.flags & TypeFlags.Any && findResolutionCycleStartIndex(typeVariable, TypeSystemPropertyName.ImmediateBaseConstraint) < 0 &&
|
||||
(constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, or(isArrayType, isTupleType))) {
|
||||
(constraint = getConstraintOfTypeParameter(typeVariable)) && everyType(constraint, isArrayOrTupleType)) {
|
||||
return instantiateMappedArrayType(t, type, prependTypeMapping(typeVariable, t, mapper));
|
||||
}
|
||||
if (isGenericTupleType(t)) {
|
||||
@@ -18562,7 +18577,7 @@ namespace ts {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return isTupleType(target) || isArrayType(target);
|
||||
return isArrayOrTupleType(target);
|
||||
}
|
||||
if (isReadonlyArrayType(source) && isMutableArrayOrTuple(target)) {
|
||||
if (reportErrors) {
|
||||
@@ -18697,7 +18712,7 @@ namespace ts {
|
||||
// recursive intersections that are structurally similar but not exactly identical. See #37854.
|
||||
if (result && !inPropertyCheck && (
|
||||
target.flags & TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) ||
|
||||
isNonGenericObjectType(target) && !isArrayType(target) && !isTupleType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((source as IntersectionType).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) {
|
||||
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 &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck, recursionFlags);
|
||||
inPropertyCheck = false;
|
||||
@@ -18754,9 +18769,6 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
reportRelationError(headMessage, source, target);
|
||||
if (strictNullChecks && source.flags & TypeFlags.TypeVariable && source.symbol?.declarations?.[0] && !getConstraintOfType(source as TypeVariable) && isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
|
||||
associateRelatedInfo(createDiagnosticForNode(source.symbol.declarations[0], Diagnostics.This_type_parameter_probably_needs_an_extends_object_constraint));
|
||||
}
|
||||
}
|
||||
|
||||
function traceUnionsOrIntersectionsTooLarge(source: Type, target: Type): void {
|
||||
@@ -19547,7 +19559,7 @@ namespace ts {
|
||||
// IndexedAccess comparisons are handled above in the `targetFlags & TypeFlage.IndexedAccess` branch
|
||||
if (!(sourceFlags & TypeFlags.IndexedAccess && targetFlags & TypeFlags.IndexedAccess)) {
|
||||
const constraint = getConstraintOfType(source as TypeVariable);
|
||||
if (!strictNullChecks && (!constraint || (sourceFlags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any))) {
|
||||
if (!constraint || (sourceFlags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) {
|
||||
// A type variable with no constraint is not related to the non-primitive object type.
|
||||
if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive), RecursionFlags.Both)) {
|
||||
resetErrorInfo(saveErrorInfo);
|
||||
@@ -19555,12 +19567,12 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
// hi-speed no-this-instantiation check (less accurate, but avoids costly `this`-instantiation when the constraint will suffice), see #28231 for report on why this is needed
|
||||
else if (constraint && (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState))) {
|
||||
else if (result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) {
|
||||
resetErrorInfo(saveErrorInfo);
|
||||
return result;
|
||||
}
|
||||
// slower, fuller, this-instantiated check (necessary when comparing raw `this` types from base classes), see `subclassWithPolymorphicThisIsAssignable.ts` test for example
|
||||
else if (constraint && (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && !(targetFlags & sourceFlags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState))) {
|
||||
else if (result = isRelatedTo(getTypeWithThisArgument(constraint, source), target, RecursionFlags.Source, reportErrors && !(targetFlags & sourceFlags & TypeFlags.TypeParameter), /*headMessage*/ undefined, intersectionState)) {
|
||||
resetErrorInfo(saveErrorInfo);
|
||||
return result;
|
||||
}
|
||||
@@ -19705,7 +19717,7 @@ namespace ts {
|
||||
return varianceResult;
|
||||
}
|
||||
}
|
||||
else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
|
||||
else if (isReadonlyArrayType(target) ? isArrayOrTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
|
||||
if (relation !== identityRelation) {
|
||||
return isRelatedTo(getIndexTypeOfType(source, numberType) || anyType, getIndexTypeOfType(target, numberType) || anyType, RecursionFlags.Both, reportErrors);
|
||||
}
|
||||
@@ -20090,7 +20102,7 @@ namespace ts {
|
||||
}
|
||||
let result = Ternary.True;
|
||||
if (isTupleType(target)) {
|
||||
if (isArrayType(source) || isTupleType(source)) {
|
||||
if (isArrayOrTupleType(source)) {
|
||||
if (!target.target.readonly && (isReadonlyArrayType(source) || isTupleType(source) && source.target.readonly)) {
|
||||
return Ternary.False;
|
||||
}
|
||||
@@ -21095,6 +21107,10 @@ namespace ts {
|
||||
return !!(getObjectFlags(type) & ObjectFlags.Reference) && (type as TypeReference).target === globalReadonlyArrayType;
|
||||
}
|
||||
|
||||
function isArrayOrTupleType(type: Type): type is TypeReference {
|
||||
return isArrayType(type) || isTupleType(type);
|
||||
}
|
||||
|
||||
function isMutableArrayOrTuple(type: Type): boolean {
|
||||
return isArrayType(type) && !isReadonlyArrayType(type) || isTupleType(type) && !type.target.readonly;
|
||||
}
|
||||
@@ -21595,7 +21611,7 @@ namespace ts {
|
||||
else if (type.flags & TypeFlags.Intersection) {
|
||||
result = getIntersectionType(sameMap((type as IntersectionType).types, getWidenedType));
|
||||
}
|
||||
else if (isArrayType(type) || isTupleType(type)) {
|
||||
else if (isArrayOrTupleType(type)) {
|
||||
result = createTypeReference(type.target, sameMap(getTypeArguments(type), getWidenedType));
|
||||
}
|
||||
if (result && context === undefined) {
|
||||
@@ -21632,7 +21648,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isArrayType(type) || isTupleType(type)) {
|
||||
if (isArrayOrTupleType(type)) {
|
||||
for (const t of getTypeArguments(type)) {
|
||||
if (reportWideningErrorsInType(t)) {
|
||||
errorReported = true;
|
||||
@@ -22711,7 +22727,7 @@ namespace ts {
|
||||
}
|
||||
// Infer from the members of source and target only if the two types are possibly related
|
||||
if (!typesDefinitelyUnrelated(source, target)) {
|
||||
if (isArrayType(source) || isTupleType(source)) {
|
||||
if (isArrayOrTupleType(source)) {
|
||||
if (isTupleType(target)) {
|
||||
const sourceArity = getTypeReferenceArity(source);
|
||||
const targetArity = getTypeReferenceArity(target);
|
||||
@@ -25509,7 +25525,7 @@ namespace ts {
|
||||
if (isBindingElement(declaration) && !declaration.initializer && !declaration.dotDotDotToken && declaration.parent.elements.length >= 2) {
|
||||
const parent = declaration.parent.parent;
|
||||
if (parent.kind === SyntaxKind.VariableDeclaration && getCombinedNodeFlags(declaration) & NodeFlags.Const || parent.kind === SyntaxKind.Parameter) {
|
||||
const links = getNodeLinks(location);
|
||||
const links = getNodeLinks(parent);
|
||||
if (!(links.flags & NodeCheckFlags.InCheckIdentifier)) {
|
||||
links.flags |= NodeCheckFlags.InCheckIdentifier;
|
||||
const parentType = getTypeForBindingElementParent(parent, CheckMode.Normal);
|
||||
@@ -27983,6 +27999,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
error(attributeDecl.expression, Diagnostics.Spread_types_may_only_be_created_from_object_types);
|
||||
typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
|
||||
}
|
||||
}
|
||||
@@ -28943,10 +28960,17 @@ namespace ts {
|
||||
prop = getPropertyOfType(apparentType, right.escapedText);
|
||||
}
|
||||
// In `Foo.Bar.Baz`, 'Foo' is not referenced if 'Bar' is a const enum or a module containing only const enums.
|
||||
// `Foo` is also not referenced in `enum FooCopy { Bar = Foo.Bar }`, because the enum member value gets inlined
|
||||
// here even if `Foo` is not a const enum.
|
||||
//
|
||||
// The exceptions are:
|
||||
// 1. if 'isolatedModules' is enabled, because the const enum value will not be inlined, and
|
||||
// 2. if 'preserveConstEnums' is enabled and the expression is itself an export, e.g. `export = Foo.Bar.Baz`.
|
||||
if (isIdentifier(left) && parentSymbol && (compilerOptions.isolatedModules || !(prop && isConstEnumOrConstEnumOnlyModule(prop)) || shouldPreserveConstEnums(compilerOptions) && isExportOrExportExpression(node))) {
|
||||
if (isIdentifier(left) && parentSymbol && (
|
||||
compilerOptions.isolatedModules ||
|
||||
!(prop && (isConstEnumOrConstEnumOnlyModule(prop) || prop.flags & SymbolFlags.EnumMember && node.parent.kind === SyntaxKind.EnumMember)) ||
|
||||
shouldPreserveConstEnums(compilerOptions) && isExportOrExportExpression(node)
|
||||
)) {
|
||||
markAliasReferenced(parentSymbol, node);
|
||||
}
|
||||
|
||||
@@ -30383,9 +30407,15 @@ namespace ts {
|
||||
const parameterRange = hasRestParameter ? min
|
||||
: min < max ? min + "-" + max
|
||||
: min;
|
||||
const error = hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1
|
||||
: parameterRange === 1 && args.length === 0 && isPromiseResolveArityError(node) ? Diagnostics.Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise
|
||||
: Diagnostics.Expected_0_arguments_but_got_1;
|
||||
const isVoidPromiseError = !hasRestParameter && parameterRange === 1 && args.length === 0 && isPromiseResolveArityError(node);
|
||||
if (isVoidPromiseError && isInJSFile(node)) {
|
||||
return getDiagnosticForCallNode(node, Diagnostics.Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_without_arguments);
|
||||
}
|
||||
const error = hasRestParameter
|
||||
? Diagnostics.Expected_at_least_0_arguments_but_got_1
|
||||
: isVoidPromiseError
|
||||
? Diagnostics.Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise
|
||||
: Diagnostics.Expected_0_arguments_but_got_1;
|
||||
if (min < args.length && args.length < max) {
|
||||
// between min and max, but with no matching overload
|
||||
return getDiagnosticForCallNode(node, Diagnostics.No_overload_expects_0_arguments_but_overloads_do_exist_that_expect_either_1_or_2_arguments, args.length, maxBelow, minAbove);
|
||||
@@ -30490,6 +30520,7 @@ namespace ts {
|
||||
// decorators are applied to a declaration by the emitter, and not to an expression.
|
||||
const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters;
|
||||
let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal;
|
||||
argCheckMode |= checkMode & CheckMode.IsForStringLiteralArgumentCompletions;
|
||||
|
||||
// The following variables are captured and modified by calls to chooseOverload.
|
||||
// If overload resolution or type argument inference fails, we want to report the
|
||||
@@ -30715,7 +30746,7 @@ namespace ts {
|
||||
// If one or more context sensitive arguments were excluded, we start including
|
||||
// them now (and keeping do so for any subsequent candidates) and perform a second
|
||||
// round of type inference and applicability checking for this particular candidate.
|
||||
argCheckMode = CheckMode.Normal;
|
||||
argCheckMode = checkMode & CheckMode.IsForStringLiteralArgumentCompletions;
|
||||
if (inferenceContext) {
|
||||
const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext);
|
||||
checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters);
|
||||
@@ -32023,13 +32054,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkImportMetaProperty(node: MetaProperty) {
|
||||
if (moduleKind === ModuleKind.Node12 || moduleKind === ModuleKind.NodeNext) {
|
||||
if (moduleKind === ModuleKind.Node16 || moduleKind === ModuleKind.NodeNext) {
|
||||
if (getSourceFileOfNode(node).impliedNodeFormat !== ModuleKind.ESNext) {
|
||||
error(node, Diagnostics.The_import_meta_meta_property_is_not_allowed_in_files_which_will_build_into_CommonJS_output);
|
||||
}
|
||||
}
|
||||
else if (moduleKind < ModuleKind.ES2020 && moduleKind !== ModuleKind.System) {
|
||||
error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_es2020_es2022_esnext_system_node12_or_nodenext);
|
||||
error(node, Diagnostics.The_import_meta_meta_property_is_only_allowed_when_the_module_option_is_es2020_es2022_esnext_system_node16_or_nodenext);
|
||||
}
|
||||
const file = getSourceFileOfNode(node);
|
||||
Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag.");
|
||||
@@ -33059,16 +33090,37 @@ namespace ts {
|
||||
if (!hasParseDiagnostics(sourceFile)) {
|
||||
let span: TextSpan | undefined;
|
||||
if (!isEffectiveExternalModule(sourceFile, compilerOptions)) {
|
||||
if (!span) span = getSpanOfTokenAtPosition(sourceFile, node.pos);
|
||||
span ??= getSpanOfTokenAtPosition(sourceFile, node.pos);
|
||||
const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length,
|
||||
Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module);
|
||||
diagnostics.add(diagnostic);
|
||||
}
|
||||
if ((moduleKind !== ModuleKind.ES2022 && moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System && !(moduleKind === ModuleKind.NodeNext && getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.ESNext)) || languageVersion < ScriptTarget.ES2017) {
|
||||
span = getSpanOfTokenAtPosition(sourceFile, node.pos);
|
||||
const diagnostic = createFileDiagnostic(sourceFile, span.start, span.length,
|
||||
Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher);
|
||||
diagnostics.add(diagnostic);
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.Node16:
|
||||
case ModuleKind.NodeNext:
|
||||
if (sourceFile.impliedNodeFormat === ModuleKind.CommonJS) {
|
||||
span ??= getSpanOfTokenAtPosition(sourceFile, node.pos);
|
||||
diagnostics.add(
|
||||
createFileDiagnostic(sourceFile, span.start, span.length, Diagnostics.The_current_file_is_a_CommonJS_module_and_cannot_use_await_at_the_top_level)
|
||||
);
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
case ModuleKind.ES2022:
|
||||
case ModuleKind.ESNext:
|
||||
case ModuleKind.System:
|
||||
if (languageVersion >= ScriptTarget.ES2017) {
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
default:
|
||||
span ??= getSpanOfTokenAtPosition(sourceFile, node.pos);
|
||||
diagnostics.add(
|
||||
createFileDiagnostic(sourceFile, span.start, span.length,
|
||||
Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35772,8 +35824,8 @@ namespace ts {
|
||||
if (node.assertions) {
|
||||
const override = getResolutionModeOverrideForClause(node.assertions.assertClause, grammarErrorOnNode);
|
||||
if (override) {
|
||||
if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node12 && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) {
|
||||
grammarErrorOnNode(node.assertions.assertClause, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node12_or_nodenext);
|
||||
if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) {
|
||||
grammarErrorOnNode(node.assertions.assertClause, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37391,7 +37443,7 @@ namespace ts {
|
||||
|
||||
function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier | undefined) {
|
||||
// No need to check for require or exports for ES6 modules and later
|
||||
if (moduleKind >= ModuleKind.ES2015 && !(moduleKind >= ModuleKind.Node12 && getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS)) {
|
||||
if (moduleKind >= ModuleKind.ES2015 && !(moduleKind >= ModuleKind.Node16 && getSourceFileOfNode(node).impliedNodeFormat === ModuleKind.CommonJS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -38213,7 +38265,7 @@ namespace ts {
|
||||
|
||||
return (use & IterationUse.PossiblyOutOfBounds) ? includeUndefinedInIndexSignature(arrayElementType) : arrayElementType;
|
||||
|
||||
function getIterationDiagnosticDetails(allowsStrings: boolean, downlevelIteration: boolean | undefined): [DiagnosticMessage, boolean] {
|
||||
function getIterationDiagnosticDetails(allowsStrings: boolean, downlevelIteration: boolean | undefined): [error: DiagnosticMessage, maybeMissingAwait: boolean] {
|
||||
if (downlevelIteration) {
|
||||
return allowsStrings
|
||||
? [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator, true]
|
||||
@@ -38223,7 +38275,7 @@ namespace ts {
|
||||
const yieldType = getIterationTypeOfIterable(use, IterationTypeKind.Yield, inputType, /*errorNode*/ undefined);
|
||||
|
||||
if (yieldType) {
|
||||
return [Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators, false];
|
||||
return [Diagnostics.Type_0_can_only_be_iterated_through_when_using_the_downlevelIteration_flag_or_with_a_target_of_es2015_or_higher, false];
|
||||
}
|
||||
|
||||
if (isES2015OrLaterIterable(inputType.symbol?.escapedName)) {
|
||||
@@ -40221,7 +40273,7 @@ namespace ts {
|
||||
|
||||
function isConstantMemberAccess(node: Expression): node is AccessExpression {
|
||||
const type = getTypeOfExpression(node);
|
||||
if(type === errorType) {
|
||||
if (type === errorType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -40666,8 +40718,8 @@ namespace ts {
|
||||
const validForTypeAssertions = isExclusivelyTypeOnlyImportOrExport(declaration);
|
||||
const override = getResolutionModeOverrideForClause(declaration.assertClause, validForTypeAssertions ? grammarErrorOnNode : undefined);
|
||||
if (validForTypeAssertions && override) {
|
||||
if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node12 && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) {
|
||||
return grammarErrorOnNode(declaration.assertClause, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node12_or_nodenext);
|
||||
if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) {
|
||||
return grammarErrorOnNode(declaration.assertClause, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext);
|
||||
}
|
||||
return; // Other grammar checks do not apply to type-only imports with resolution mode assertions
|
||||
}
|
||||
@@ -41861,7 +41913,7 @@ namespace ts {
|
||||
const symbol = getIntrinsicTagSymbol(name.parent as JsxOpeningLikeElement);
|
||||
return symbol === unknownSymbol ? undefined : symbol;
|
||||
}
|
||||
const result = resolveEntityName(name, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ !isJSDoc, getHostSignatureFromJSDoc(name));
|
||||
const result = resolveEntityName(name, meaning, /*ignoreErrors*/ false, /* dontResolveAlias */ true, getHostSignatureFromJSDoc(name));
|
||||
if (!result && isJSDoc) {
|
||||
const container = findAncestor(name, or(isClassLike, isInterfaceDeclaration));
|
||||
if (container) {
|
||||
@@ -41972,15 +42024,20 @@ namespace ts {
|
||||
return propertyDeclaration;
|
||||
}
|
||||
}
|
||||
else if (isMetaProperty(parent)) {
|
||||
const parentType = getTypeOfNode(parent);
|
||||
const propertyDeclaration = getPropertyOfType(parentType, (node as Identifier).escapedText);
|
||||
if (propertyDeclaration) {
|
||||
return propertyDeclaration;
|
||||
}
|
||||
if (parent.keywordToken === SyntaxKind.NewKeyword) {
|
||||
else if (isMetaProperty(parent) && parent.name === node) {
|
||||
if (parent.keywordToken === SyntaxKind.NewKeyword && idText(node as Identifier) === "target") {
|
||||
// `target` in `new.target`
|
||||
return checkNewTargetMetaProperty(parent).symbol;
|
||||
}
|
||||
// The `meta` in `import.meta` could be given `getTypeOfNode(parent).symbol` (the `ImportMeta` interface symbol), but
|
||||
// we have a fake expression type made for other reasons already, whose transient `meta`
|
||||
// member should more exactly be the kind of (declarationless) symbol we want.
|
||||
// (See #44364 and #45031 for relevant implementation PRs)
|
||||
if (parent.keywordToken === SyntaxKind.ImportKeyword && idText(node as Identifier) === "meta") {
|
||||
return getGlobalImportMetaExpressionType().members!.get("meta" as __String);
|
||||
}
|
||||
// no other meta properties are valid syntax, thus no others should have symbols
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42141,7 +42198,7 @@ namespace ts {
|
||||
if (isDeclaration(node)) {
|
||||
// In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
|
||||
const symbol = getSymbolOfNode(node);
|
||||
return getTypeOfSymbol(symbol);
|
||||
return symbol ? getTypeOfSymbol(symbol) : errorType;
|
||||
}
|
||||
|
||||
if (isDeclarationNameOrImportPropertyName(node)) {
|
||||
@@ -43859,6 +43916,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function checkGrammarExpressionWithTypeArguments(node: ExpressionWithTypeArguments | TypeQueryNode) {
|
||||
if (isExpressionWithTypeArguments(node) && isImportKeyword(node.expression) && node.typeArguments) {
|
||||
return grammarErrorOnNode(node, Diagnostics.This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot_have_type_arguments);
|
||||
}
|
||||
return checkGrammarTypeArguments(node, node.typeArguments);
|
||||
}
|
||||
|
||||
@@ -44131,9 +44191,30 @@ namespace ts {
|
||||
diagnostics.add(createDiagnosticForNode(forInOrOfStatement.awaitModifier,
|
||||
Diagnostics.for_await_loops_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module));
|
||||
}
|
||||
if ((moduleKind !== ModuleKind.ES2022 && moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System && !(moduleKind === ModuleKind.NodeNext && getSourceFileOfNode(forInOrOfStatement).impliedNodeFormat === ModuleKind.ESNext)) || languageVersion < ScriptTarget.ES2017) {
|
||||
diagnostics.add(createDiagnosticForNode(forInOrOfStatement.awaitModifier,
|
||||
Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher));
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.Node16:
|
||||
case ModuleKind.NodeNext:
|
||||
if (sourceFile.impliedNodeFormat === ModuleKind.CommonJS) {
|
||||
diagnostics.add(
|
||||
createDiagnosticForNode(forInOrOfStatement.awaitModifier, Diagnostics.The_current_file_is_a_CommonJS_module_and_cannot_use_await_at_the_top_level)
|
||||
);
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
case ModuleKind.ES2022:
|
||||
case ModuleKind.ESNext:
|
||||
case ModuleKind.System:
|
||||
if (languageVersion >= ScriptTarget.ES2017) {
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
default:
|
||||
diagnostics.add(
|
||||
createDiagnosticForNode(forInOrOfStatement.awaitModifier,
|
||||
Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44905,11 +44986,11 @@ namespace ts {
|
||||
|
||||
function checkGrammarImportCallExpression(node: ImportCall): boolean {
|
||||
if (moduleKind === ModuleKind.ES2015) {
|
||||
return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node12_or_nodenext);
|
||||
return grammarErrorOnNode(node, Diagnostics.Dynamic_imports_are_only_supported_when_the_module_flag_is_set_to_es2020_es2022_esnext_commonjs_amd_system_umd_node16_or_nodenext);
|
||||
}
|
||||
|
||||
if (node.typeArguments) {
|
||||
return grammarErrorOnNode(node, Diagnostics.Dynamic_import_cannot_have_type_arguments);
|
||||
return grammarErrorOnNode(node, Diagnostics.This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot_have_type_arguments);
|
||||
}
|
||||
|
||||
const nodeArguments = node.arguments;
|
||||
@@ -44919,7 +45000,7 @@ namespace ts {
|
||||
|
||||
if (nodeArguments.length > 1) {
|
||||
const assertionArgument = nodeArguments[1];
|
||||
return grammarErrorOnNode(assertionArgument, Diagnostics.Dynamic_imports_only_support_a_second_argument_when_the_module_option_is_set_to_esnext_or_nodenext);
|
||||
return grammarErrorOnNode(assertionArgument, Diagnostics.Dynamic_imports_only_support_a_second_argument_when_the_module_option_is_set_to_esnext_node16_or_nodenext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -423,7 +423,7 @@ namespace ts {
|
||||
es2020: ModuleKind.ES2020,
|
||||
es2022: ModuleKind.ES2022,
|
||||
esnext: ModuleKind.ESNext,
|
||||
node12: ModuleKind.Node12,
|
||||
node16: ModuleKind.Node16,
|
||||
nodenext: ModuleKind.NodeNext,
|
||||
})),
|
||||
affectsModuleResolution: true,
|
||||
@@ -781,7 +781,7 @@ namespace ts {
|
||||
type: new Map(getEntries({
|
||||
node: ModuleResolutionKind.NodeJs,
|
||||
classic: ModuleResolutionKind.Classic,
|
||||
node12: ModuleResolutionKind.Node12,
|
||||
node16: ModuleResolutionKind.Node16,
|
||||
nodenext: ModuleResolutionKind.NodeNext,
|
||||
})),
|
||||
affectsModuleResolution: true,
|
||||
@@ -1263,7 +1263,7 @@ namespace ts {
|
||||
affectsModuleResolution: true,
|
||||
description: Diagnostics.Control_what_method_is_used_to_detect_module_format_JS_files,
|
||||
category: Diagnostics.Language_and_Environment,
|
||||
defaultValueDescription: Diagnostics.auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node12_as_modules,
|
||||
defaultValueDescription: Diagnostics.auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules,
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -900,6 +900,10 @@
|
||||
"category": "Error",
|
||||
"code": 1308
|
||||
},
|
||||
"The current file is a CommonJS module and cannot use 'await' at the top level.": {
|
||||
"category": "Error",
|
||||
"code": 1309
|
||||
},
|
||||
"Did you mean to use a ':'? An '=' can only follow a property name when the containing object literal is part of a destructuring pattern.": {
|
||||
"category": "Error",
|
||||
"code": 1312
|
||||
@@ -944,11 +948,11 @@
|
||||
"category": "Error",
|
||||
"code": 1322
|
||||
},
|
||||
"Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node12', or 'nodenext'.": {
|
||||
"Dynamic imports are only supported when the '--module' flag is set to 'es2020', 'es2022', 'esnext', 'commonjs', 'amd', 'system', 'umd', 'node16', or 'nodenext'.": {
|
||||
"category": "Error",
|
||||
"code": 1323
|
||||
},
|
||||
"Dynamic imports only support a second argument when the '--module' option is set to 'esnext' or 'nodenext'.": {
|
||||
"Dynamic imports only support a second argument when the '--module' option is set to 'esnext', 'node16', or 'nodenext'.": {
|
||||
"category": "Error",
|
||||
"code": 1324
|
||||
},
|
||||
@@ -956,7 +960,7 @@
|
||||
"category": "Error",
|
||||
"code": 1325
|
||||
},
|
||||
"Dynamic import cannot have type arguments.": {
|
||||
"This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.": {
|
||||
"category": "Error",
|
||||
"code": 1326
|
||||
},
|
||||
@@ -1016,7 +1020,7 @@
|
||||
"category": "Error",
|
||||
"code": 1342
|
||||
},
|
||||
"The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node12', or 'nodenext'.": {
|
||||
"The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', or 'nodenext'.": {
|
||||
"category": "Error",
|
||||
"code": 1343
|
||||
},
|
||||
@@ -1140,7 +1144,7 @@
|
||||
"category": "Message",
|
||||
"code": 1377
|
||||
},
|
||||
"Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.": {
|
||||
"Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', or 'nodenext', and the 'target' option is set to 'es2017' or higher.": {
|
||||
"category": "Error",
|
||||
"code": 1378
|
||||
},
|
||||
@@ -1348,7 +1352,7 @@
|
||||
"category": "Error",
|
||||
"code": 1431
|
||||
},
|
||||
"Top-level 'for await' loops are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.": {
|
||||
"Top-level 'for await' loops are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', or 'nodenext', and the 'target' option is set to 'es2017' or higher.": {
|
||||
"category": "Error",
|
||||
"code": 1432
|
||||
},
|
||||
@@ -1420,7 +1424,7 @@
|
||||
"category": "Error",
|
||||
"code": 1451
|
||||
},
|
||||
"Resolution modes are only supported when `moduleResolution` is `node12` or `nodenext`.": {
|
||||
"Resolution modes are only supported when `moduleResolution` is `node16` or `nodenext`.": {
|
||||
"category": "Error",
|
||||
"code": 1452
|
||||
},
|
||||
@@ -1465,7 +1469,7 @@
|
||||
"category": "Message",
|
||||
"code": 1475
|
||||
},
|
||||
"\"auto\": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node12+) as modules.": {
|
||||
"\"auto\": Treat files with imports, exports, import.meta, jsx (with jsx: react-jsx), or esm format (with module: node16+) as modules.": {
|
||||
"category": "Message",
|
||||
"code": 1476
|
||||
},
|
||||
@@ -1506,9 +1510,14 @@
|
||||
"category": "Error",
|
||||
"code": 2207
|
||||
},
|
||||
"This type parameter probably needs an `extends object` constraint.": {
|
||||
|
||||
"The project root is ambiguous, but is required to resolve export map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate.": {
|
||||
"category": "Error",
|
||||
"code": 2208
|
||||
"code": 2209
|
||||
},
|
||||
"The project root is ambiguous, but is required to resolve import map entry '{0}' in file '{1}'. Supply the `rootDir` compiler option to disambiguate.": {
|
||||
"category": "Error",
|
||||
"code": 2210
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
@@ -2511,10 +2520,7 @@
|
||||
"category": "Error",
|
||||
"code": 2568
|
||||
},
|
||||
"Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.": {
|
||||
"category": "Error",
|
||||
"code": 2569
|
||||
},
|
||||
|
||||
"Could not find name '{0}'. Did you mean '{1}'?": {
|
||||
"category": "Error",
|
||||
"code": 2570
|
||||
@@ -3369,6 +3375,10 @@
|
||||
"category": "Error",
|
||||
"code": 2809
|
||||
},
|
||||
"Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.": {
|
||||
"category": "Error",
|
||||
"code": 2810
|
||||
},
|
||||
"Initializer for property '{0}'": {
|
||||
"category": "Error",
|
||||
"code": 2811
|
||||
@@ -3421,11 +3431,11 @@
|
||||
"category": "Error",
|
||||
"code": 2833
|
||||
},
|
||||
"Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node12' or 'nodenext'. Consider adding an extension to the import path.": {
|
||||
"Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Consider adding an extension to the import path.": {
|
||||
"category": "Error",
|
||||
"code": 2834
|
||||
},
|
||||
"Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node12' or 'nodenext'. Did you mean '{0}'?": {
|
||||
"Relative import paths need explicit file extensions in EcmaScript imports when '--moduleResolution' is 'node16' or 'nodenext'. Did you mean '{0}'?": {
|
||||
"category": "Error",
|
||||
"code": 2835
|
||||
},
|
||||
@@ -6109,10 +6119,6 @@
|
||||
"category": "Error",
|
||||
"code": 7061
|
||||
},
|
||||
"JSON imports are experimental in ES module mode imports.": {
|
||||
"category": "Error",
|
||||
"code": 7062
|
||||
},
|
||||
|
||||
"You cannot rename this element.": {
|
||||
"category": "Error",
|
||||
|
||||
+61
-56
@@ -531,6 +531,7 @@ namespace ts {
|
||||
printer.writeFile(sourceFile!, writer, sourceMapGenerator);
|
||||
}
|
||||
|
||||
let sourceMapUrlPos;
|
||||
if (sourceMapGenerator) {
|
||||
if (sourceMapDataList) {
|
||||
sourceMapDataList.push({
|
||||
@@ -548,6 +549,7 @@ namespace ts {
|
||||
|
||||
if (sourceMappingURL) {
|
||||
if (!writer.isAtStartOfLine()) writer.rawWrite(newLine);
|
||||
sourceMapUrlPos = writer.getTextPos();
|
||||
writer.writeComment(`//# ${"sourceMappingURL"}=${sourceMappingURL}`); // Tools can sometimes see this line as a source mapping url comment
|
||||
}
|
||||
|
||||
@@ -562,7 +564,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Write the output file
|
||||
writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), !!compilerOptions.emitBOM, sourceFiles);
|
||||
writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), !!compilerOptions.emitBOM, sourceFiles, { sourceMapUrlPos });
|
||||
|
||||
// Reset state
|
||||
writer.clear();
|
||||
@@ -1170,7 +1172,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getCurrentLineMap() {
|
||||
return currentLineMap || (currentLineMap = getLineStarts(currentSourceFile!));
|
||||
return currentLineMap || (currentLineMap = getLineStarts(Debug.checkDefined(currentSourceFile)));
|
||||
}
|
||||
|
||||
function emit(node: Node, parenthesizerRule?: (node: Node) => Node): void;
|
||||
@@ -1815,7 +1817,7 @@ namespace ts {
|
||||
const numNodes = bundle ? bundle.sourceFiles.length + numPrepends : 1;
|
||||
for (let i = 0; i < numNodes; i++) {
|
||||
const currentNode = bundle ? i < numPrepends ? bundle.prepends[i] : bundle.sourceFiles[i - numPrepends] : node;
|
||||
const sourceFile = isSourceFile(currentNode) ? currentNode : isUnparsedSource(currentNode) ? undefined : currentSourceFile!;
|
||||
const sourceFile = isSourceFile(currentNode) ? currentNode : isUnparsedSource(currentNode) ? undefined : currentSourceFile;
|
||||
const shouldSkip = printerOptions.noEmitHelpers || (!!sourceFile && hasRecordedExternalHelpers(sourceFile));
|
||||
const shouldBundle = (isSourceFile(currentNode) || isUnparsedSource(currentNode)) && !isOwnFileEmit;
|
||||
const helpers = isUnparsedSource(currentNode) ? currentNode.helpers : getSortedEmitHelpers(currentNode);
|
||||
@@ -2465,7 +2467,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None;
|
||||
const allowTrailingComma = currentSourceFile!.languageVersion >= ScriptTarget.ES5 && !isJsonSourceFile(currentSourceFile!) ? ListFormat.AllowTrailingComma : ListFormat.None;
|
||||
const allowTrailingComma = currentSourceFile && currentSourceFile.languageVersion >= ScriptTarget.ES5 && !isJsonSourceFile(currentSourceFile) ? ListFormat.AllowTrailingComma : ListFormat.None;
|
||||
emitList(node, node.properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine);
|
||||
|
||||
if (indentedFlag) {
|
||||
@@ -2880,7 +2882,7 @@ namespace ts {
|
||||
emitExpression(node.expression, parenthesizer.parenthesizeExpressionOfExpressionStatement);
|
||||
// Emit semicolon in non json files
|
||||
// or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation)
|
||||
if (!isJsonSourceFile(currentSourceFile!) || nodeIsSynthesized(node.expression)) {
|
||||
if (!currentSourceFile || !isJsonSourceFile(currentSourceFile) || nodeIsSynthesized(node.expression)) {
|
||||
writeTrailingSemicolon();
|
||||
}
|
||||
}
|
||||
@@ -3207,7 +3209,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!nodeIsSynthesized(body) && !rangeIsOnSingleLine(body, currentSourceFile!)) {
|
||||
if (!nodeIsSynthesized(body) && currentSourceFile && !rangeIsOnSingleLine(body, currentSourceFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3238,12 +3240,7 @@ namespace ts {
|
||||
? emitBlockFunctionBodyOnSingleLine
|
||||
: emitBlockFunctionBodyWorker;
|
||||
|
||||
if (emitBodyWithDetachedComments) {
|
||||
emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody);
|
||||
}
|
||||
else {
|
||||
emitBlockFunctionBody(body);
|
||||
}
|
||||
emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody);
|
||||
|
||||
decreaseIndent();
|
||||
writeToken(SyntaxKind.CloseBraceToken, body.statements.end, writePunctuation, body);
|
||||
@@ -3701,9 +3698,10 @@ namespace ts {
|
||||
statements.length === 1 &&
|
||||
(
|
||||
// treat synthesized nodes as located on the same line for emit purposes
|
||||
!currentSourceFile ||
|
||||
nodeIsSynthesized(parentNode) ||
|
||||
nodeIsSynthesized(statements[0]) ||
|
||||
rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile!)
|
||||
rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile)
|
||||
);
|
||||
|
||||
let format = ListFormat.CaseOrDefaultClauseStatements;
|
||||
@@ -3958,16 +3956,14 @@ namespace ts {
|
||||
function emitSourceFile(node: SourceFile) {
|
||||
writeLine();
|
||||
const statements = node.statements;
|
||||
if (emitBodyWithDetachedComments) {
|
||||
// Emit detached comment if there are no prologue directives or if the first node is synthesized.
|
||||
// The synthesized node will have no leading comment so some comments may be missed.
|
||||
const shouldEmitDetachedComment = statements.length === 0 ||
|
||||
!isPrologueDirective(statements[0]) ||
|
||||
nodeIsSynthesized(statements[0]);
|
||||
if (shouldEmitDetachedComment) {
|
||||
emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
|
||||
return;
|
||||
}
|
||||
// Emit detached comment if there are no prologue directives or if the first node is synthesized.
|
||||
// The synthesized node will have no leading comment so some comments may be missed.
|
||||
const shouldEmitDetachedComment = statements.length === 0 ||
|
||||
!isPrologueDirective(statements[0]) ||
|
||||
nodeIsSynthesized(statements[0]);
|
||||
if (shouldEmitDetachedComment) {
|
||||
emitBodyWithDetachedComments(node, statements, emitSourceFileWorker);
|
||||
return;
|
||||
}
|
||||
emitSourceFileWorker(node);
|
||||
}
|
||||
@@ -4369,7 +4365,7 @@ namespace ts {
|
||||
|
||||
if (isEmpty) {
|
||||
// Write a line terminator if the parent node was multi-line
|
||||
if (format & ListFormat.MultiLine && !(preserveSourceNewlines && (!parentNode || rangeIsOnSingleLine(parentNode, currentSourceFile!)))) {
|
||||
if (format & ListFormat.MultiLine && !(preserveSourceNewlines && (!parentNode || currentSourceFile && rangeIsOnSingleLine(parentNode, currentSourceFile)))) {
|
||||
writeLine();
|
||||
}
|
||||
else if (format & ListFormat.SpaceBetweenBraces && !(format & ListFormat.NoSpaceIfEmpty)) {
|
||||
@@ -4673,7 +4669,7 @@ namespace ts {
|
||||
|
||||
const firstChild = children[0];
|
||||
if (firstChild === undefined) {
|
||||
return !parentNode || rangeIsOnSingleLine(parentNode, currentSourceFile!) ? 0 : 1;
|
||||
return !parentNode || currentSourceFile && rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1;
|
||||
}
|
||||
if (firstChild.pos === nextListElementPos) {
|
||||
// If this child starts at the beginning of a list item in a parent list, its leading
|
||||
@@ -4697,7 +4693,7 @@ namespace ts {
|
||||
// JsxText will be written with its leading whitespace, so don't add more manually.
|
||||
return 0;
|
||||
}
|
||||
if (parentNode &&
|
||||
if (currentSourceFile && parentNode &&
|
||||
!positionIsSynthesized(parentNode.pos) &&
|
||||
!nodeIsSynthesized(firstChild) &&
|
||||
(!firstChild.parent || getOriginalNode(firstChild.parent) === getOriginalNode(parentNode))
|
||||
@@ -4710,7 +4706,7 @@ namespace ts {
|
||||
currentSourceFile!,
|
||||
includeComments));
|
||||
}
|
||||
return rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile!) ? 0 : 1;
|
||||
return rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile) ? 0 : 1;
|
||||
}
|
||||
if (synthesizedNodeStartsOnNewLine(firstChild, format)) {
|
||||
return 1;
|
||||
@@ -4728,7 +4724,7 @@ namespace ts {
|
||||
// JsxText will be written with its leading whitespace, so don't add more manually.
|
||||
return 0;
|
||||
}
|
||||
else if (!nodeIsSynthesized(previousNode) && !nodeIsSynthesized(nextNode)) {
|
||||
else if (currentSourceFile && !nodeIsSynthesized(previousNode) && !nodeIsSynthesized(nextNode)) {
|
||||
if (preserveSourceNewlines && siblingNodePositionsAreComparable(previousNode, nextNode)) {
|
||||
return getEffectiveLines(
|
||||
includeComments => getLinesBetweenRangeEndAndRangeStart(
|
||||
@@ -4743,7 +4739,7 @@ namespace ts {
|
||||
// expensive than checking with `preserveSourceNewlines` as above, but the goal is not to preserve the
|
||||
// effective source lines between two sibling nodes.
|
||||
else if (!preserveSourceNewlines && originalNodesHaveSameParent(previousNode, nextNode)) {
|
||||
return rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile!) ? 0 : 1;
|
||||
return rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile) ? 0 : 1;
|
||||
}
|
||||
// If the two nodes are not comparable, add a line terminator based on the format that can indicate
|
||||
// whether new lines are preferred or not.
|
||||
@@ -4767,9 +4763,9 @@ namespace ts {
|
||||
|
||||
const lastChild = lastOrUndefined(children);
|
||||
if (lastChild === undefined) {
|
||||
return !parentNode || rangeIsOnSingleLine(parentNode, currentSourceFile!) ? 0 : 1;
|
||||
return !parentNode || currentSourceFile && rangeIsOnSingleLine(parentNode, currentSourceFile) ? 0 : 1;
|
||||
}
|
||||
if (parentNode && !positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(lastChild) && (!lastChild.parent || lastChild.parent === parentNode)) {
|
||||
if (currentSourceFile && parentNode && !positionIsSynthesized(parentNode.pos) && !nodeIsSynthesized(lastChild) && (!lastChild.parent || lastChild.parent === parentNode)) {
|
||||
if (preserveSourceNewlines) {
|
||||
const end = isNodeArray(children) && !positionIsSynthesized(children.end) ? children.end : lastChild.end;
|
||||
return getEffectiveLines(
|
||||
@@ -4779,7 +4775,7 @@ namespace ts {
|
||||
currentSourceFile!,
|
||||
includeComments));
|
||||
}
|
||||
return rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile!) ? 0 : 1;
|
||||
return rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile) ? 0 : 1;
|
||||
}
|
||||
if (synthesizedNodeStartsOnNewLine(lastChild, format)) {
|
||||
return 1;
|
||||
@@ -4857,7 +4853,7 @@ namespace ts {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!nodeIsSynthesized(parent) && !nodeIsSynthesized(node1) && !nodeIsSynthesized(node2)) {
|
||||
if (currentSourceFile && !nodeIsSynthesized(parent) && !nodeIsSynthesized(node1) && !nodeIsSynthesized(node2)) {
|
||||
if (preserveSourceNewlines) {
|
||||
return getEffectiveLines(
|
||||
includeComments => getLinesBetweenRangeEndAndRangeStart(
|
||||
@@ -4866,7 +4862,7 @@ namespace ts {
|
||||
currentSourceFile!,
|
||||
includeComments));
|
||||
}
|
||||
return rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile!) ? 0 : 1;
|
||||
return rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile) ? 0 : 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -4874,7 +4870,7 @@ namespace ts {
|
||||
|
||||
function isEmptyBlock(block: BlockLike) {
|
||||
return block.statements.length === 0
|
||||
&& rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile!);
|
||||
&& (!currentSourceFile || rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile));
|
||||
}
|
||||
|
||||
function skipSynthesizedParentheses(node: Node) {
|
||||
@@ -4885,21 +4881,27 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function getTextOfNode(node: Node, includeTrivia?: boolean): string {
|
||||
function getTextOfNode(node: Identifier | PrivateIdentifier | LiteralExpression, includeTrivia?: boolean): string {
|
||||
if (isGeneratedIdentifier(node)) {
|
||||
return generateName(node);
|
||||
}
|
||||
else if ((isIdentifier(node) || isPrivateIdentifier(node)) && (nodeIsSynthesized(node) || !node.parent || !currentSourceFile || (node.parent && currentSourceFile && getSourceFileOfNode(node) !== getOriginalNode(currentSourceFile)))) {
|
||||
return idText(node);
|
||||
if (isStringLiteral(node) && node.textSourceNode) {
|
||||
return getTextOfNode(node.textSourceNode, includeTrivia);
|
||||
}
|
||||
else if (node.kind === SyntaxKind.StringLiteral && (node as StringLiteral).textSourceNode) {
|
||||
return getTextOfNode((node as StringLiteral).textSourceNode!, includeTrivia);
|
||||
const sourceFile = currentSourceFile; // const needed for control flow
|
||||
const canUseSourceFile = !!sourceFile && !!node.parent && !nodeIsSynthesized(node);
|
||||
if (isMemberName(node)) {
|
||||
if (!canUseSourceFile || getSourceFileOfNode(node) !== getOriginalNode(sourceFile)) {
|
||||
return idText(node);
|
||||
}
|
||||
}
|
||||
else if (isLiteralExpression(node) && (nodeIsSynthesized(node) || !node.parent)) {
|
||||
return node.text;
|
||||
else {
|
||||
Debug.assertNode(node, isLiteralExpression); // not strictly necessary
|
||||
if (!canUseSourceFile) {
|
||||
return node.text;
|
||||
}
|
||||
}
|
||||
|
||||
return getSourceTextOfNodeFromSourceFile(currentSourceFile!, node, includeTrivia);
|
||||
return getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia);
|
||||
}
|
||||
|
||||
function getLiteralTextOfNode(node: LiteralLikeNode, neverAsciiEscape: boolean | undefined, jsxAttributeEscape: boolean): string {
|
||||
@@ -4921,7 +4923,7 @@ namespace ts {
|
||||
| (printerOptions.terminateUnterminatedLiterals ? GetLiteralTextFlags.TerminateUnterminatedLiterals : 0)
|
||||
| (printerOptions.target && printerOptions.target === ScriptTarget.ESNext ? GetLiteralTextFlags.AllowNumericSeparator : 0);
|
||||
|
||||
return getLiteralText(node, currentSourceFile!, flags);
|
||||
return getLiteralText(node, currentSourceFile, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5244,7 +5246,7 @@ namespace ts {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return makeUniqueName(
|
||||
getTextOfNode(node),
|
||||
getTextOfNode(node as Identifier),
|
||||
isUniqueName,
|
||||
!!(flags! & GeneratedIdentifierFlags.Optimistic),
|
||||
!!(flags! & GeneratedIdentifierFlags.ReservedInNestedScopes)
|
||||
@@ -5546,7 +5548,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
|
||||
if (!shouldWriteComment(currentSourceFile!.text, commentPos)) return;
|
||||
if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return;
|
||||
if (!hasWrittenComment) {
|
||||
emitNewLineBeforeLeadingCommentOfPosition(getCurrentLineMap(), writer, rangePos, commentPos);
|
||||
hasWrittenComment = true;
|
||||
@@ -5554,7 +5556,7 @@ namespace ts {
|
||||
|
||||
// Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
|
||||
emitPos(commentPos);
|
||||
writeCommentRange(currentSourceFile!.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
||||
writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
||||
emitPos(commentEnd);
|
||||
|
||||
if (hasTrailingNewLine) {
|
||||
@@ -5578,14 +5580,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitTrailingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
if (!shouldWriteComment(currentSourceFile!.text, commentPos)) return;
|
||||
if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return;
|
||||
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
|
||||
if (!writer.isAtStartOfLine()) {
|
||||
writer.writeSpace(" ");
|
||||
}
|
||||
|
||||
emitPos(commentPos);
|
||||
writeCommentRange(currentSourceFile!.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
||||
writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
||||
emitPos(commentEnd);
|
||||
|
||||
if (hasTrailingNewLine) {
|
||||
@@ -5603,10 +5605,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitTrailingCommentOfPositionNoNewline(commentPos: number, commentEnd: number, kind: SyntaxKind) {
|
||||
if (!currentSourceFile) return;
|
||||
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
|
||||
|
||||
emitPos(commentPos);
|
||||
writeCommentRange(currentSourceFile!.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
||||
writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
||||
emitPos(commentEnd);
|
||||
|
||||
if (kind === SyntaxKind.SingleLineCommentTrivia) {
|
||||
@@ -5615,10 +5618,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
if(!currentSourceFile) return;
|
||||
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
|
||||
|
||||
emitPos(commentPos);
|
||||
writeCommentRange(currentSourceFile!.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
||||
writeCommentRange(currentSourceFile.text, getCurrentLineMap(), writer, commentPos, commentEnd, newLine);
|
||||
emitPos(commentEnd);
|
||||
|
||||
if (hasTrailingNewLine) {
|
||||
@@ -5653,6 +5657,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function forEachLeadingCommentWithoutDetachedComments(cb: (commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) => void) {
|
||||
if (!currentSourceFile) return;
|
||||
// get the leading comments from detachedPos
|
||||
const pos = last(detachedCommentsInfo!).detachedCommentEndPos;
|
||||
if (detachedCommentsInfo!.length - 1) {
|
||||
@@ -5662,11 +5667,11 @@ namespace ts {
|
||||
detachedCommentsInfo = undefined;
|
||||
}
|
||||
|
||||
forEachLeadingCommentRange(currentSourceFile!.text, pos, cb, /*state*/ pos);
|
||||
forEachLeadingCommentRange(currentSourceFile.text, pos, cb, /*state*/ pos);
|
||||
}
|
||||
|
||||
function emitDetachedCommentsAndUpdateCommentsInfo(range: TextRange) {
|
||||
const currentDetachedCommentInfo = emitDetachedComments(currentSourceFile!.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled);
|
||||
const currentDetachedCommentInfo = currentSourceFile && emitDetachedComments(currentSourceFile.text, getCurrentLineMap(), writer, emitComment, range, newLine, commentsDisabled);
|
||||
if (currentDetachedCommentInfo) {
|
||||
if (detachedCommentsInfo) {
|
||||
detachedCommentsInfo.push(currentDetachedCommentInfo);
|
||||
@@ -5678,7 +5683,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function emitComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) {
|
||||
if (!shouldWriteComment(currentSourceFile!.text, commentPos)) return;
|
||||
if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return;
|
||||
emitPos(commentPos);
|
||||
writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine);
|
||||
emitPos(commentEnd);
|
||||
@@ -5690,7 +5695,7 @@ namespace ts {
|
||||
* @return true if the comment is a triple-slash comment else false
|
||||
*/
|
||||
function isTripleSlashComment(commentPos: number, commentEnd: number) {
|
||||
return isRecognizedTripleSlashComment(currentSourceFile!.text, commentPos, commentEnd);
|
||||
return !!currentSourceFile && isRecognizedTripleSlashComment(currentSourceFile.text, commentPos, commentEnd);
|
||||
}
|
||||
|
||||
// Source Maps
|
||||
|
||||
@@ -5275,7 +5275,7 @@ namespace ts {
|
||||
hasNoDefaultLib: boolean,
|
||||
libReferences: readonly FileReference[]
|
||||
) {
|
||||
const node = baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile) as Mutable<SourceFile>;
|
||||
const node = (source.redirectInfo ? Object.create(source.redirectInfo.redirectTarget) : baseFactory.createBaseSourceFileNode(SyntaxKind.SourceFile)) as Mutable<SourceFile>;
|
||||
for (const p in source) {
|
||||
if (p === "emitNode" || hasProperty(node, p) || !hasProperty(source, p)) continue;
|
||||
(node as any)[p] = (source as any)[p];
|
||||
|
||||
@@ -86,14 +86,15 @@ namespace ts {
|
||||
return { fileName: resolved.path, packageId: resolved.packageId };
|
||||
}
|
||||
|
||||
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean | undefined, failedLookupLocations: string[], resultFromCache: ResolvedModuleWithFailedLookupLocations | undefined): ResolvedModuleWithFailedLookupLocations {
|
||||
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean | undefined, failedLookupLocations: string[], diagnostics: Diagnostic[], resultFromCache: ResolvedModuleWithFailedLookupLocations | undefined): ResolvedModuleWithFailedLookupLocations {
|
||||
if (resultFromCache) {
|
||||
resultFromCache.failedLookupLocations.push(...failedLookupLocations);
|
||||
return resultFromCache;
|
||||
}
|
||||
return {
|
||||
resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath: resolved.originalPath === true ? undefined : resolved.originalPath, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId },
|
||||
failedLookupLocations
|
||||
failedLookupLocations,
|
||||
resolutionDiagnostics: diagnostics
|
||||
};
|
||||
}
|
||||
|
||||
@@ -107,6 +108,8 @@ namespace ts {
|
||||
packageJsonInfoCache: PackageJsonInfoCache | undefined;
|
||||
features: NodeResolutionFeatures;
|
||||
conditions: string[];
|
||||
requestContainingDirectory: string | undefined;
|
||||
reportDiagnostic: DiagnosticReporter;
|
||||
}
|
||||
|
||||
/** Just the fields that we use for module resolution. */
|
||||
@@ -348,13 +351,24 @@ namespace ts {
|
||||
// set in a non-modal module resolution setting here. Do note that our behavior is not particularly well defined when these mode-overriding imports
|
||||
// are present in a non-modal project; while in theory we'd like to either ignore the mode or provide faithful modern resolution, depending on what we feel is best,
|
||||
// in practice, not every cache has the options available to intelligently make the choice to ignore the mode request, and it's unclear how modern "faithful modern
|
||||
// resolution" should be (`node12`? `nodenext`?). As such, witnessing a mode-overriding triple-slash reference in a non-modal module resolution
|
||||
// resolution" should be (`node16`? `nodenext`?). As such, witnessing a mode-overriding triple-slash reference in a non-modal module resolution
|
||||
// context should _probably_ be an error - and that should likely be handled by the `Program` (which is what we do).
|
||||
if (resolutionMode === ModuleKind.ESNext && (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node12 || getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext)) {
|
||||
if (resolutionMode === ModuleKind.ESNext && (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext)) {
|
||||
features |= NodeResolutionFeatures.EsmMode;
|
||||
}
|
||||
const conditions = features & NodeResolutionFeatures.Exports ? features & NodeResolutionFeatures.EsmMode ? ["node", "import", "types"] : ["node", "require", "types"] : [];
|
||||
const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache, features, conditions };
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
const moduleResolutionState: ModuleResolutionState = {
|
||||
compilerOptions: options,
|
||||
host,
|
||||
traceEnabled,
|
||||
failedLookupLocations,
|
||||
packageJsonInfoCache: cache,
|
||||
features,
|
||||
conditions,
|
||||
requestContainingDirectory: containingDirectory,
|
||||
reportDiagnostic: diag => void diagnostics.push(diag),
|
||||
};
|
||||
let resolved = primaryLookup();
|
||||
let primary = true;
|
||||
if (!resolved) {
|
||||
@@ -374,7 +388,7 @@ namespace ts {
|
||||
isExternalLibraryImport: pathContainsNodeModules(fileName),
|
||||
};
|
||||
}
|
||||
result = { resolvedTypeReferenceDirective, failedLookupLocations };
|
||||
result = { resolvedTypeReferenceDirective, failedLookupLocations, resolutionDiagnostics: diagnostics };
|
||||
perFolderCache?.set(typeReferenceDirectiveName, /*mode*/ resolutionMode, result);
|
||||
if (traceEnabled) traceResult(result);
|
||||
return result;
|
||||
@@ -444,7 +458,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getDefaultNodeResolutionFeatures(options: CompilerOptions) {
|
||||
return getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node12 ? NodeResolutionFeatures.Node12Default :
|
||||
return getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 ? NodeResolutionFeatures.Node16Default :
|
||||
getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext ? NodeResolutionFeatures.NodeNextDefault :
|
||||
NodeResolutionFeatures.None;
|
||||
}
|
||||
@@ -468,6 +482,8 @@ namespace ts {
|
||||
packageJsonInfoCache: cache?.getPackageJsonInfoCache(),
|
||||
conditions: emptyArray,
|
||||
features: NodeResolutionFeatures.None,
|
||||
requestContainingDirectory: containingDirectory,
|
||||
reportDiagnostic: noop
|
||||
};
|
||||
|
||||
return forEachAncestorDirectory(containingDirectory, ancestorDirectory => {
|
||||
@@ -950,8 +966,8 @@ namespace ts {
|
||||
case ModuleKind.CommonJS:
|
||||
moduleResolution = ModuleResolutionKind.NodeJs;
|
||||
break;
|
||||
case ModuleKind.Node12:
|
||||
moduleResolution = ModuleResolutionKind.Node12;
|
||||
case ModuleKind.Node16:
|
||||
moduleResolution = ModuleResolutionKind.Node16;
|
||||
break;
|
||||
case ModuleKind.NodeNext:
|
||||
moduleResolution = ModuleResolutionKind.NodeNext;
|
||||
@@ -972,8 +988,8 @@ namespace ts {
|
||||
|
||||
perfLogger.logStartResolveModule(moduleName /* , containingFile, ModuleResolutionKind[moduleResolution]*/);
|
||||
switch (moduleResolution) {
|
||||
case ModuleResolutionKind.Node12:
|
||||
result = node12ModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode);
|
||||
case ModuleResolutionKind.Node16:
|
||||
result = node16ModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode);
|
||||
break;
|
||||
case ModuleResolutionKind.NodeNext:
|
||||
result = nodeNextModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode);
|
||||
@@ -1231,22 +1247,22 @@ namespace ts {
|
||||
// respecting the `.exports` member of packages' package.json files and its (conditional) mappings of export names
|
||||
Exports = 1 << 3,
|
||||
// allowing `*` in the LHS of an export to be followed by more content, eg `"./whatever/*.js"`
|
||||
// not currently backported to node 12 - https://github.com/nodejs/Release/issues/690
|
||||
// not supported in node 12 - https://github.com/nodejs/Release/issues/690
|
||||
ExportsPatternTrailers = 1 << 4,
|
||||
AllFeatures = Imports | SelfName | Exports | ExportsPatternTrailers,
|
||||
|
||||
Node12Default = Imports | SelfName | Exports,
|
||||
Node16Default = Imports | SelfName | Exports | ExportsPatternTrailers,
|
||||
|
||||
NodeNextDefault = AllFeatures,
|
||||
|
||||
EsmMode = 1 << 5,
|
||||
}
|
||||
|
||||
function node12ModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions,
|
||||
function node16ModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions,
|
||||
host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference,
|
||||
resolutionMode?: ModuleKind.CommonJS | ModuleKind.ESNext): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeNextModuleNameResolverWorker(
|
||||
NodeResolutionFeatures.Node12Default,
|
||||
NodeResolutionFeatures.Node16Default,
|
||||
moduleName,
|
||||
containingFile,
|
||||
compilerOptions,
|
||||
@@ -1310,13 +1326,14 @@ namespace ts {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
|
||||
const failedLookupLocations: string[] = [];
|
||||
// conditions are only used by the node12/nodenext resolver - there's no priority order in the list,
|
||||
// conditions are only used by the node16/nodenext resolver - 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 = features & NodeResolutionFeatures.EsmMode ? ["node", "import", "types"] : ["node", "require", "types"];
|
||||
if (compilerOptions.noDtsResolution) {
|
||||
conditions.pop();
|
||||
}
|
||||
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
const state: ModuleResolutionState = {
|
||||
compilerOptions,
|
||||
host,
|
||||
@@ -1325,10 +1342,12 @@ namespace ts {
|
||||
packageJsonInfoCache: cache,
|
||||
features,
|
||||
conditions,
|
||||
requestContainingDirectory: containingDirectory,
|
||||
reportDiagnostic: diag => void diagnostics.push(diag),
|
||||
};
|
||||
|
||||
const result = forEach(extensions, ext => tryResolve(ext));
|
||||
return createResolvedModuleWithFailedLookupLocations(result?.value?.resolved, result?.value?.isExternalLibraryImport, failedLookupLocations, state.resultFromCache);
|
||||
return createResolvedModuleWithFailedLookupLocations(result?.value?.resolved, result?.value?.isExternalLibraryImport, failedLookupLocations, diagnostics, state.resultFromCache);
|
||||
|
||||
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> {
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ true);
|
||||
@@ -1516,9 +1535,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function loadJSOrExactTSFileName(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined {
|
||||
if ((extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) && isDeclarationFileName(candidate)) {
|
||||
if ((extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) && fileExtensionIsOneOf(candidate, supportedTSExtensionsFlat)) {
|
||||
const result = tryFile(candidate, onlyRecordFailures, state);
|
||||
return result !== undefined ? { path: candidate, ext: forEach(supportedDeclarationExtensions, e => fileExtensionIs(candidate, e) ? e : undefined)! } : undefined;
|
||||
return result !== undefined ? { path: candidate, ext: tryExtractTSExtension(candidate) as Extension } : undefined;
|
||||
}
|
||||
|
||||
return loadModuleFromFileNoImplicitExtensions(extensions, candidate, onlyRecordFailures, state);
|
||||
@@ -1655,6 +1674,8 @@ namespace ts {
|
||||
packageJsonInfoCache: cache?.getPackageJsonInfoCache(),
|
||||
conditions: ["node", "require", "types"],
|
||||
features,
|
||||
requestContainingDirectory: packageJsonInfo.packageDirectory,
|
||||
reportDiagnostic: noop
|
||||
};
|
||||
const requireResolution = loadNodeModuleFromDirectoryWorker(
|
||||
extensions,
|
||||
@@ -1764,6 +1785,8 @@ namespace ts {
|
||||
packageJsonInfoCache: PackageJsonInfoCache | undefined;
|
||||
features: number;
|
||||
conditions: never[];
|
||||
requestContainingDirectory: string | undefined;
|
||||
reportDiagnostic: DiagnosticReporter
|
||||
} = {
|
||||
host,
|
||||
compilerOptions: options,
|
||||
@@ -1772,6 +1795,8 @@ namespace ts {
|
||||
packageJsonInfoCache,
|
||||
features: 0,
|
||||
conditions: [],
|
||||
requestContainingDirectory: undefined,
|
||||
reportDiagnostic: noop
|
||||
};
|
||||
const parts = getPathComponents(fileName);
|
||||
parts.pop();
|
||||
@@ -2112,8 +2137,9 @@ namespace ts {
|
||||
}
|
||||
return toSearchResult(/*value*/ undefined);
|
||||
}
|
||||
const finalPath = getNormalizedAbsolutePath(pattern ? resolvedTarget.replace(/\*/g, subpath) : resolvedTarget + subpath, state.host.getCurrentDirectory?.());
|
||||
|
||||
const finalPath = toAbsolutePath(pattern ? resolvedTarget.replace(/\*/g, subpath) : resolvedTarget + subpath);
|
||||
const inputLink = tryLoadInputFileForPath(finalPath, subpath, combinePaths(scope.packageDirectory, "package.json"), isImports);
|
||||
if (inputLink) return inputLink;
|
||||
return toSearchResult(withPackageId(scope, loadJSOrExactTSFileName(extensions, finalPath, /*onlyRecordFailures*/ false, state)));
|
||||
}
|
||||
else if (typeof target === "object" && target !== null) { // eslint-disable-line no-null/no-null
|
||||
@@ -2154,6 +2180,134 @@ namespace ts {
|
||||
trace(state.host, Diagnostics.package_json_scope_0_has_invalid_type_for_target_of_specifier_1, scope.packageDirectory, moduleName);
|
||||
}
|
||||
return toSearchResult(/*value*/ undefined);
|
||||
|
||||
function toAbsolutePath(path: string): string;
|
||||
function toAbsolutePath(path: string | undefined): string | undefined;
|
||||
function toAbsolutePath(path: string | undefined): string | undefined {
|
||||
if (path === undefined) return path;
|
||||
return hostGetCanonicalFileName({ useCaseSensitiveFileNames })(getNormalizedAbsolutePath(path, state.host.getCurrentDirectory?.()));
|
||||
}
|
||||
|
||||
function combineDirectoryPath(root: string, dir: string) {
|
||||
return ensureTrailingDirectorySeparator(combinePaths(root, dir));
|
||||
}
|
||||
|
||||
function useCaseSensitiveFileNames() {
|
||||
return !state.host.useCaseSensitiveFileNames ? true :
|
||||
typeof state.host.useCaseSensitiveFileNames === "boolean" ? state.host.useCaseSensitiveFileNames :
|
||||
state.host.useCaseSensitiveFileNames();
|
||||
}
|
||||
|
||||
function tryLoadInputFileForPath(finalPath: string, entry: string, packagePath: string, isImports: boolean) {
|
||||
// Replace any references to outputs for files in the program with the input files to support package self-names used with outDir
|
||||
// PROBLEM: We don't know how to calculate the output paths yet, because the "common source directory" we use as the base of the file structure
|
||||
// we reproduce into the output directory is based on the set of input files, which we're still in the process of traversing and resolving!
|
||||
// _Given that_, we have to guess what the base of the output directory is (obviously the user wrote the export map, so has some idea what it is!).
|
||||
// We are going to probe _so many_ possible paths. We limit where we'll do this to try to reduce the possibilities of false positive lookups.
|
||||
if ((extensions === Extensions.TypeScript || extensions === Extensions.JavaScript || extensions === Extensions.Json)
|
||||
&& (state.compilerOptions.declarationDir || state.compilerOptions.outDir)
|
||||
&& finalPath.indexOf("/node_modules/") === -1
|
||||
&& (state.compilerOptions.configFile ? startsWith(toAbsolutePath(state.compilerOptions.configFile.fileName), scope.packageDirectory) : true)
|
||||
) {
|
||||
// So that all means we'll only try these guesses for files outside `node_modules` in a directory where the `package.json` and `tsconfig.json` are siblings.
|
||||
// Even with all that, we still don't know if the root of the output file structure will be (relative to the package file)
|
||||
// `.`, `./src` or any other deeper directory structure. (If project references are used, it's definitely `.` by fiat, so that should be pretty common.)
|
||||
|
||||
const getCanonicalFileName = hostGetCanonicalFileName({ useCaseSensitiveFileNames });
|
||||
const commonSourceDirGuesses: string[] = [];
|
||||
// A `rootDir` compiler option strongly indicates the root location
|
||||
// A `composite` project is using project references and has it's common src dir set to `.`, so it shouldn't need to check any other locations
|
||||
if (state.compilerOptions.rootDir || (state.compilerOptions.composite && state.compilerOptions.configFilePath)) {
|
||||
const commonDir = toAbsolutePath(getCommonSourceDirectory(state.compilerOptions, () => [], state.host.getCurrentDirectory?.() || "", getCanonicalFileName));
|
||||
commonSourceDirGuesses.push(commonDir);
|
||||
}
|
||||
else if (state.requestContainingDirectory) {
|
||||
// However without either of those set we're in the dark. Let's say you have
|
||||
//
|
||||
// ./tools/index.ts
|
||||
// ./src/index.ts
|
||||
// ./dist/index.js
|
||||
// ./package.json <-- references ./dist/index.js
|
||||
// ./tsconfig.json <-- loads ./src/index.ts
|
||||
//
|
||||
// How do we know `./src` is the common src dir, and not `./tools`, given only the `./dist` out dir and `./dist/index.js` filename?
|
||||
// Answer: We... don't. We know we're looking for an `index.ts` input file, but we have _no clue_ which subfolder it's supposed to be loaded from
|
||||
// without more context.
|
||||
// But we do have more context! Just a tiny bit more! We're resolving an import _for some other input file_! And that input file, too
|
||||
// must be inside the common source directory! So we propagate that tidbit of info all the way to here via state.requestContainingDirectory
|
||||
|
||||
const requestingFile = toAbsolutePath(combinePaths(state.requestContainingDirectory, "index.ts"));
|
||||
// And we can try every folder above the common folder for the request folder and the config/package base directory
|
||||
// This technically can be wrong - we may load ./src/index.ts when ./src/sub/index.ts was right because we don't
|
||||
// know if only `./src/sub` files were loaded by the program; but this has the best chance to be right of just about anything
|
||||
// else we have. And, given that we're about to load `./src/index.ts` because we choose it as likely correct, there will then
|
||||
// be a file outside of `./src/sub` in the program (the file we resolved to), making us de-facto right. So this fallback lookup
|
||||
// logic may influence what files are pulled in by self-names, which in turn influences the output path shape, but it's all
|
||||
// internally consistent so the paths should be stable so long as we prefer the "most general" (meaning: top-most-level directory) possible results first.
|
||||
const commonDir = toAbsolutePath(getCommonSourceDirectory(state.compilerOptions, () => [requestingFile, toAbsolutePath(packagePath)], state.host.getCurrentDirectory?.() || "", getCanonicalFileName));
|
||||
commonSourceDirGuesses.push(commonDir);
|
||||
|
||||
let fragment = ensureTrailingDirectorySeparator(commonDir);
|
||||
while (fragment && fragment.length > 1) {
|
||||
const parts = getPathComponents(fragment);
|
||||
parts.pop(); // remove a directory
|
||||
const commonDir = getPathFromPathComponents(parts);
|
||||
commonSourceDirGuesses.unshift(commonDir);
|
||||
fragment = ensureTrailingDirectorySeparator(commonDir);
|
||||
}
|
||||
}
|
||||
if (commonSourceDirGuesses.length > 1) {
|
||||
state.reportDiagnostic(createCompilerDiagnostic(
|
||||
isImports
|
||||
? Diagnostics.The_project_root_is_ambiguous_but_is_required_to_resolve_import_map_entry_0_in_file_1_Supply_the_rootDir_compiler_option_to_disambiguate
|
||||
: Diagnostics.The_project_root_is_ambiguous_but_is_required_to_resolve_export_map_entry_0_in_file_1_Supply_the_rootDir_compiler_option_to_disambiguate,
|
||||
entry === "" ? "." : entry, // replace empty string with `.` - the reverse of the operation done when entries are built - so main entrypoint errors don't look weird
|
||||
packagePath
|
||||
));
|
||||
}
|
||||
for (const commonSourceDirGuess of commonSourceDirGuesses) {
|
||||
const candidateDirectories = getOutputDirectoriesForBaseDirectory(commonSourceDirGuess);
|
||||
for (const candidateDir of candidateDirectories) {
|
||||
if (startsWith(finalPath, candidateDir)) {
|
||||
// The matched export is looking up something in either the out declaration or js dir, now map the written path back into the source dir and source extension
|
||||
const pathFragment = finalPath.slice(candidateDir.length + 1); // +1 to also remove directory seperator
|
||||
const possibleInputBase = combinePaths(commonSourceDirGuess, pathFragment);
|
||||
const jsAndDtsExtensions = [Extension.Mjs, Extension.Cjs, Extension.Js, Extension.Json, Extension.Dmts, Extension.Dcts, Extension.Dts];
|
||||
for (const ext of jsAndDtsExtensions) {
|
||||
if (fileExtensionIs(possibleInputBase, ext)) {
|
||||
const inputExts = getPossibleOriginalInputExtensionForExtension(possibleInputBase);
|
||||
for (const possibleExt of inputExts) {
|
||||
const possibleInputWithInputExtension = changeAnyExtension(possibleInputBase, possibleExt, ext, !useCaseSensitiveFileNames());
|
||||
if ((extensions === Extensions.TypeScript && hasJSFileExtension(possibleInputWithInputExtension)) ||
|
||||
(extensions === Extensions.JavaScript && hasTSFileExtension(possibleInputWithInputExtension))) {
|
||||
continue;
|
||||
}
|
||||
if (state.host.fileExists(possibleInputWithInputExtension)) {
|
||||
return toSearchResult(withPackageId(scope, loadJSOrExactTSFileName(extensions, possibleInputWithInputExtension, /*onlyRecordFailures*/ false, state)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
|
||||
function getOutputDirectoriesForBaseDirectory(commonSourceDirGuess: string) {
|
||||
// Config file ouput paths are processed to be relative to the host's current directory, while
|
||||
// otherwise the paths are resolved relative to the common source dir the compiler puts together
|
||||
const currentDir = state.compilerOptions.configFile ? state.host.getCurrentDirectory?.() || "" : commonSourceDirGuess;
|
||||
const candidateDirectories = [];
|
||||
if (state.compilerOptions.declarationDir) {
|
||||
candidateDirectories.push(toAbsolutePath(combineDirectoryPath(currentDir, state.compilerOptions.declarationDir)));
|
||||
}
|
||||
if (state.compilerOptions.outDir && state.compilerOptions.outDir !== state.compilerOptions.declarationDir) {
|
||||
candidateDirectories.push(toAbsolutePath(combineDirectoryPath(currentDir, state.compilerOptions.outDir)));
|
||||
}
|
||||
return candidateDirectories;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2374,12 +2528,13 @@ namespace ts {
|
||||
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
const failedLookupLocations: string[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache, features: NodeResolutionFeatures.None, conditions: [] };
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache: cache, features: NodeResolutionFeatures.None, conditions: [], requestContainingDirectory: containingDirectory, reportDiagnostic: diag => void diagnostics.push(diag) };
|
||||
|
||||
const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
|
||||
// No originalPath because classic resolution doesn't resolve realPath
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations, state.resultFromCache);
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations, diagnostics, state.resultFromCache);
|
||||
|
||||
function tryResolve(extensions: Extensions): SearchResult<Resolved> {
|
||||
const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, state);
|
||||
@@ -2424,9 +2579,10 @@ namespace ts {
|
||||
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
|
||||
}
|
||||
const failedLookupLocations: string[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache, features: NodeResolutionFeatures.None, conditions: [] };
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations, packageJsonInfoCache, features: NodeResolutionFeatures.None, conditions: [], requestContainingDirectory: undefined, reportDiagnostic: diag => void diagnostics.push(diag) };
|
||||
const resolved = loadModuleFromImmediateNodeModulesDirectory(Extensions.DtsOnly, moduleName, globalCache, state, /*typesScopeOnly*/ false, /*cache*/ undefined, /*redirectedReference*/ undefined);
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations, state.resultFromCache);
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations, diagnostics, state.resultFromCache);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace ts.moduleSpecifiers {
|
||||
}
|
||||
|
||||
function isFormatRequiringExtensions(compilerOptions: CompilerOptions, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost) {
|
||||
if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node12
|
||||
if (getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.Node16
|
||||
&& getEmitModuleResolutionKind(compilerOptions) !== ModuleResolutionKind.NodeNext) {
|
||||
return false;
|
||||
}
|
||||
@@ -734,7 +734,7 @@ namespace ts.moduleSpecifiers {
|
||||
const cachedPackageJson = host.getPackageJsonInfoCache?.()?.getPackageJsonInfo(packageJsonPath);
|
||||
if (typeof cachedPackageJson === "object" || cachedPackageJson === undefined && host.fileExists(packageJsonPath)) {
|
||||
const packageJsonContent = cachedPackageJson?.packageJsonContent || JSON.parse(host.readFile!(packageJsonPath)!);
|
||||
if (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node12 || getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext) {
|
||||
if (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext) {
|
||||
// `conditions` *could* be made to go against `importingSourceFile.impliedNodeFormat` if something wanted to generate
|
||||
// an ImportEqualsDeclaration in an ESM-implied file or an ImportCall in a CJS-implied file. But since this function is
|
||||
// usually called to conjure an import out of thin air, we don't have an existing usage to call `getModeForUsageAtIndex`
|
||||
|
||||
+45
-61
@@ -683,7 +683,7 @@ namespace ts {
|
||||
/**
|
||||
* Controls the format the file is detected as - this can be derived from only the path
|
||||
* and files on disk, but needs to be done with a module resolution cache in scope to be performant.
|
||||
* This is usually `undefined` for compilations that do not have `moduleResolution` values of `node12` or `nodenext`.
|
||||
* This is usually `undefined` for compilations that do not have `moduleResolution` values of `node16` or `nodenext`.
|
||||
*/
|
||||
impliedNodeFormat?: ModuleKind.ESNext | ModuleKind.CommonJS;
|
||||
/**
|
||||
@@ -944,7 +944,7 @@ namespace ts {
|
||||
initializeState("", content, languageVersion, /*syntaxCursor*/ undefined, ScriptKind.JS);
|
||||
// Prime the scanner.
|
||||
nextToken();
|
||||
const entityName = parseEntityName(/*allowReservedWords*/ true, /*allowPrivateIdentifiers*/ false);
|
||||
const entityName = parseEntityName(/*allowReservedWords*/ true);
|
||||
const isInvalid = token() === SyntaxKind.EndOfFileToken && !parseDiagnostics.length;
|
||||
clearState();
|
||||
return isInvalid ? entityName : undefined;
|
||||
@@ -2829,7 +2829,7 @@ namespace ts {
|
||||
return createMissingList<T>();
|
||||
}
|
||||
|
||||
function parseEntityName(allowReservedWords: boolean, allowPrivateIdentifiers: boolean, diagnosticMessage?: DiagnosticMessage): EntityName {
|
||||
function parseEntityName(allowReservedWords: boolean, diagnosticMessage?: DiagnosticMessage): EntityName {
|
||||
const pos = getNodePos();
|
||||
let entity: EntityName = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage);
|
||||
let dotPos = getNodePos();
|
||||
@@ -2843,7 +2843,7 @@ namespace ts {
|
||||
entity = finishNode(
|
||||
factory.createQualifiedName(
|
||||
entity,
|
||||
parseRightSideOfDot(allowReservedWords, allowPrivateIdentifiers) as Identifier
|
||||
parseRightSideOfDot(allowReservedWords, /* allowPrivateIdentifiers */ false) as Identifier
|
||||
),
|
||||
pos
|
||||
);
|
||||
@@ -3028,7 +3028,7 @@ namespace ts {
|
||||
// TYPES
|
||||
|
||||
function parseEntityNameOfTypeReference() {
|
||||
return parseEntityName(/*allowReservedWords*/ true, /*allowPrivateIdentifiers*/ false, Diagnostics.Type_expected);
|
||||
return parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected);
|
||||
}
|
||||
|
||||
function parseTypeArgumentsOfTypeReference() {
|
||||
@@ -3188,8 +3188,9 @@ namespace ts {
|
||||
function parseTypeQuery(): TypeQueryNode {
|
||||
const pos = getNodePos();
|
||||
parseExpected(SyntaxKind.TypeOfKeyword);
|
||||
const entityName = parseEntityName(/*allowReservedWords*/ true, /*allowPrivateIdentifiers*/ true);
|
||||
const typeArguments = tryParseTypeArguments();
|
||||
const entityName = parseEntityName(/*allowReservedWords*/ true);
|
||||
// Make sure we perform ASI to prevent parsing the next line's type arguments as part of an instantiation expression.
|
||||
const typeArguments = !scanner.hasPrecedingLineBreak() ? tryParseTypeArguments() : undefined;
|
||||
return finishNode(factory.createTypeQueryNode(entityName, typeArguments), pos);
|
||||
}
|
||||
|
||||
@@ -4289,10 +4290,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
const pos = getNodePos();
|
||||
let expr = parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
|
||||
let expr = parseAssignmentExpressionOrHigher();
|
||||
let operatorToken: BinaryOperatorToken;
|
||||
while ((operatorToken = parseOptionalToken(SyntaxKind.CommaToken))) {
|
||||
expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false), pos);
|
||||
expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher(), pos);
|
||||
}
|
||||
|
||||
if (saveDecoratorContext) {
|
||||
@@ -4302,10 +4303,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseInitializer(): Expression | undefined {
|
||||
return parseOptional(SyntaxKind.EqualsToken) ? parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false) : undefined;
|
||||
return parseOptional(SyntaxKind.EqualsToken) ? parseAssignmentExpressionOrHigher() : undefined;
|
||||
}
|
||||
|
||||
function parseAssignmentExpressionOrHigher(disallowReturnTypeInArrowFunction: boolean): Expression {
|
||||
function parseAssignmentExpressionOrHigher(): Expression {
|
||||
// AssignmentExpression[in,yield]:
|
||||
// 1) ConditionalExpression[?in,?yield]
|
||||
// 2) LeftHandSideExpression = AssignmentExpression[?in,?yield]
|
||||
@@ -4333,7 +4334,7 @@ namespace ts {
|
||||
// If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is
|
||||
// not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done
|
||||
// with AssignmentExpression if we see one.
|
||||
const arrowExpression = tryParseParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction) || tryParseAsyncSimpleArrowFunctionExpression(disallowReturnTypeInArrowFunction);
|
||||
const arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression();
|
||||
if (arrowExpression) {
|
||||
return arrowExpression;
|
||||
}
|
||||
@@ -4354,7 +4355,7 @@ namespace ts {
|
||||
// parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single
|
||||
// identifier and the current token is an arrow.
|
||||
if (expr.kind === SyntaxKind.Identifier && token() === SyntaxKind.EqualsGreaterThanToken) {
|
||||
return parseSimpleArrowFunctionExpression(pos, expr as Identifier, disallowReturnTypeInArrowFunction, /*asyncModifier*/ undefined);
|
||||
return parseSimpleArrowFunctionExpression(pos, expr as Identifier, /*asyncModifier*/ undefined);
|
||||
}
|
||||
|
||||
// Now see if we might be in cases '2' or '3'.
|
||||
@@ -4364,7 +4365,7 @@ namespace ts {
|
||||
// Note: we call reScanGreaterToken so that we get an appropriately merged token
|
||||
// for cases like `> > =` becoming `>>=`
|
||||
if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) {
|
||||
return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher(disallowReturnTypeInArrowFunction), pos);
|
||||
return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher(), pos);
|
||||
}
|
||||
|
||||
// It wasn't an assignment or a lambda. This is a conditional expression:
|
||||
@@ -4418,7 +4419,7 @@ namespace ts {
|
||||
return finishNode(
|
||||
factory.createYieldExpression(
|
||||
parseOptionalToken(SyntaxKind.AsteriskToken),
|
||||
parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false)
|
||||
parseAssignmentExpressionOrHigher()
|
||||
),
|
||||
pos
|
||||
);
|
||||
@@ -4430,7 +4431,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parseSimpleArrowFunctionExpression(pos: number, identifier: Identifier, disallowReturnTypeInArrowFunction: boolean, asyncModifier?: NodeArray<Modifier> | undefined): ArrowFunction {
|
||||
function parseSimpleArrowFunctionExpression(pos: number, identifier: Identifier, asyncModifier?: NodeArray<Modifier> | undefined): ArrowFunction {
|
||||
Debug.assert(token() === SyntaxKind.EqualsGreaterThanToken, "parseSimpleArrowFunctionExpression should only have been called if we had a =>");
|
||||
const parameter = factory.createParameterDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
@@ -4445,12 +4446,12 @@ namespace ts {
|
||||
|
||||
const parameters = createNodeArray<ParameterDeclaration>([parameter], parameter.pos, parameter.end);
|
||||
const equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken);
|
||||
const body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier, disallowReturnTypeInArrowFunction);
|
||||
const body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier);
|
||||
const node = factory.createArrowFunction(asyncModifier, /*typeParameters*/ undefined, parameters, /*type*/ undefined, equalsGreaterThanToken, body);
|
||||
return addJSDocComment(finishNode(node, pos));
|
||||
}
|
||||
|
||||
function tryParseParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction: boolean): Expression | undefined {
|
||||
function tryParseParenthesizedArrowFunctionExpression(): Expression | undefined {
|
||||
const triState = isParenthesizedArrowFunctionExpression();
|
||||
if (triState === Tristate.False) {
|
||||
// It's definitely not a parenthesized arrow function expression.
|
||||
@@ -4462,8 +4463,8 @@ namespace ts {
|
||||
// it out, but don't allow any ambiguity, and return 'undefined' if this could be an
|
||||
// expression instead.
|
||||
return triState === Tristate.True ?
|
||||
parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ true, /*disallowReturnTypeInArrowFunction*/ false) :
|
||||
tryParse(() => parsePossibleParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction));
|
||||
parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ true) :
|
||||
tryParse(parsePossibleParenthesizedArrowFunctionExpression);
|
||||
}
|
||||
|
||||
// True -> We definitely expect a parenthesized arrow function here.
|
||||
@@ -4609,13 +4610,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parsePossibleParenthesizedArrowFunctionExpression(disallowReturnTypeInArrowFunction: boolean): ArrowFunction | undefined {
|
||||
function parsePossibleParenthesizedArrowFunctionExpression(): ArrowFunction | undefined {
|
||||
const tokenPos = scanner.getTokenPos();
|
||||
if (notParenthesizedArrow?.has(tokenPos)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const result = parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ false, disallowReturnTypeInArrowFunction);
|
||||
const result = parseParenthesizedArrowFunctionExpression(/*allowAmbiguity*/ false);
|
||||
if (!result) {
|
||||
(notParenthesizedArrow || (notParenthesizedArrow = new Set())).add(tokenPos);
|
||||
}
|
||||
@@ -4623,14 +4624,14 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function tryParseAsyncSimpleArrowFunctionExpression(disallowReturnTypeInArrowFunction: boolean): ArrowFunction | undefined {
|
||||
function tryParseAsyncSimpleArrowFunctionExpression(): ArrowFunction | undefined {
|
||||
// We do a check here so that we won't be doing unnecessarily call to "lookAhead"
|
||||
if (token() === SyntaxKind.AsyncKeyword) {
|
||||
if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === Tristate.True) {
|
||||
const pos = getNodePos();
|
||||
const asyncModifier = parseModifiersForArrowFunction();
|
||||
const expr = parseBinaryExpressionOrHigher(OperatorPrecedence.Lowest);
|
||||
return parseSimpleArrowFunctionExpression(pos, expr as Identifier, disallowReturnTypeInArrowFunction, asyncModifier);
|
||||
return parseSimpleArrowFunctionExpression(pos, expr as Identifier, asyncModifier);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
@@ -4657,7 +4658,7 @@ namespace ts {
|
||||
return Tristate.False;
|
||||
}
|
||||
|
||||
function parseParenthesizedArrowFunctionExpression(allowAmbiguity: boolean, disallowReturnTypeInArrowFunction: boolean): ArrowFunction | undefined {
|
||||
function parseParenthesizedArrowFunctionExpression(allowAmbiguity: boolean): ArrowFunction | undefined {
|
||||
const pos = getNodePos();
|
||||
const hasJSDoc = hasPrecedingJSDocComment();
|
||||
const modifiers = parseModifiersForArrowFunction();
|
||||
@@ -4694,24 +4695,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
// Given:
|
||||
// x ? y => ({ y }) : z => ({ z })
|
||||
// We try to parse the body of the first arrow function by looking at:
|
||||
// ({ y }) : z => ({ z })
|
||||
// This is a valid arrow function with "z" as the return type.
|
||||
//
|
||||
// But, if we're in the true side of a conditional expression, this colon
|
||||
// terminates the expression, so we cannot allow a return type if we aren't
|
||||
// certain whether or not the preceding text was parsed as a parameter list.
|
||||
//
|
||||
// For example,
|
||||
// a() ? (b: number, c?: string): void => d() : e
|
||||
// is determined by isParenthesizedArrowFunctionExpression to unambiguously
|
||||
// be an arrow expression, so we allow a return type.
|
||||
if (disallowReturnTypeInArrowFunction && token() === SyntaxKind.ColonToken) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const type = parseReturnType(SyntaxKind.ColonToken, /*isType*/ false);
|
||||
if (type && !allowAmbiguity && typeHasArrowFunctionBlockingParseError(type)) {
|
||||
return undefined;
|
||||
@@ -4744,14 +4727,14 @@ namespace ts {
|
||||
const lastToken = token();
|
||||
const equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken);
|
||||
const body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken)
|
||||
? parseArrowFunctionExpressionBody(some(modifiers, isAsyncModifier), disallowReturnTypeInArrowFunction)
|
||||
? parseArrowFunctionExpressionBody(some(modifiers, isAsyncModifier))
|
||||
: parseIdentifier();
|
||||
|
||||
const node = factory.createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body);
|
||||
return withJSDoc(finishNode(node, pos), hasJSDoc);
|
||||
}
|
||||
|
||||
function parseArrowFunctionExpressionBody(isAsync: boolean, disallowReturnTypeInArrowFunction: boolean): Block | Expression {
|
||||
function parseArrowFunctionExpressionBody(isAsync: boolean): Block | Expression {
|
||||
if (token() === SyntaxKind.OpenBraceToken) {
|
||||
return parseFunctionBlock(isAsync ? SignatureFlags.Await : SignatureFlags.None);
|
||||
}
|
||||
@@ -4781,8 +4764,8 @@ namespace ts {
|
||||
const savedTopLevel = topLevel;
|
||||
topLevel = false;
|
||||
const node = isAsync
|
||||
? doInAwaitContext(() => parseAssignmentExpressionOrHigher(disallowReturnTypeInArrowFunction))
|
||||
: doOutsideOfAwaitContext(() => parseAssignmentExpressionOrHigher(disallowReturnTypeInArrowFunction));
|
||||
? doInAwaitContext(parseAssignmentExpressionOrHigher)
|
||||
: doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
|
||||
topLevel = savedTopLevel;
|
||||
return node;
|
||||
}
|
||||
@@ -4801,10 +4784,10 @@ namespace ts {
|
||||
factory.createConditionalExpression(
|
||||
leftOperand,
|
||||
questionToken,
|
||||
doOutsideOfContext(disallowInAndDecoratorContext, () => parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ true)),
|
||||
doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher),
|
||||
colonToken = parseExpectedToken(SyntaxKind.ColonToken),
|
||||
nodeIsPresent(colonToken)
|
||||
? parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ true)
|
||||
? parseAssignmentExpressionOrHigher()
|
||||
: createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken))
|
||||
),
|
||||
pos
|
||||
@@ -5802,14 +5785,14 @@ namespace ts {
|
||||
function parseSpreadElement(): Expression {
|
||||
const pos = getNodePos();
|
||||
parseExpected(SyntaxKind.DotDotDotToken);
|
||||
const expression = parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
|
||||
const expression = parseAssignmentExpressionOrHigher();
|
||||
return finishNode(factory.createSpreadElement(expression), pos);
|
||||
}
|
||||
|
||||
function parseArgumentOrArrayLiteralElement(): Expression {
|
||||
return token() === SyntaxKind.DotDotDotToken ? parseSpreadElement() :
|
||||
token() === SyntaxKind.CommaToken ? finishNode(factory.createOmittedExpression(), getNodePos()) :
|
||||
parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
|
||||
parseAssignmentExpressionOrHigher();
|
||||
}
|
||||
|
||||
function parseArgumentExpression(): Expression {
|
||||
@@ -5831,7 +5814,7 @@ namespace ts {
|
||||
const hasJSDoc = hasPrecedingJSDocComment();
|
||||
|
||||
if (parseOptionalToken(SyntaxKind.DotDotDotToken)) {
|
||||
const expression = parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
|
||||
const expression = parseAssignmentExpressionOrHigher();
|
||||
return withJSDoc(finishNode(factory.createSpreadAssignment(expression), pos), hasJSDoc);
|
||||
}
|
||||
|
||||
@@ -5866,7 +5849,7 @@ namespace ts {
|
||||
const isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== SyntaxKind.ColonToken);
|
||||
if (isShorthandPropertyAssignment) {
|
||||
const equalsToken = parseOptionalToken(SyntaxKind.EqualsToken);
|
||||
const objectAssignmentInitializer = equalsToken ? allowInAnd(() => parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false)) : undefined;
|
||||
const objectAssignmentInitializer = equalsToken ? allowInAnd(parseAssignmentExpressionOrHigher) : undefined;
|
||||
node = factory.createShorthandPropertyAssignment(name as Identifier, objectAssignmentInitializer);
|
||||
// Save equals token for error reporting.
|
||||
// TODO(rbuckton): Consider manufacturing this when we need to report an error as it is otherwise not useful.
|
||||
@@ -5874,7 +5857,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
const initializer = allowInAnd(() => parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false));
|
||||
const initializer = allowInAnd(parseAssignmentExpressionOrHigher);
|
||||
node = factory.createPropertyAssignment(name, initializer);
|
||||
}
|
||||
// Decorators, Modifiers, questionToken, and exclamationToken are not supported by property assignments and are reported in the grammar checker
|
||||
@@ -6074,7 +6057,7 @@ namespace ts {
|
||||
|
||||
let node: IterationStatement;
|
||||
if (awaitToken ? parseExpected(SyntaxKind.OfKeyword) : parseOptional(SyntaxKind.OfKeyword)) {
|
||||
const expression = allowInAnd(() => parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false));
|
||||
const expression = allowInAnd(parseAssignmentExpressionOrHigher);
|
||||
parseExpected(SyntaxKind.CloseParenToken);
|
||||
node = factory.createForOfStatement(awaitToken, initializer, expression, parseStatement());
|
||||
}
|
||||
@@ -7416,7 +7399,7 @@ namespace ts {
|
||||
const pos = getNodePos();
|
||||
const name = tokenIsIdentifierOrKeyword(token()) ? parseIdentifierName() : parseLiteralLikeNode(SyntaxKind.StringLiteral) as StringLiteral;
|
||||
parseExpected(SyntaxKind.ColonToken);
|
||||
const value = parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
|
||||
const value = parseAssignmentExpressionOrHigher();
|
||||
return finishNode(factory.createAssertEntry(name, value), pos);
|
||||
}
|
||||
|
||||
@@ -7487,7 +7470,7 @@ namespace ts {
|
||||
function parseModuleReference() {
|
||||
return isExternalModuleReference()
|
||||
? parseExternalModuleReference()
|
||||
: parseEntityName(/*allowReservedWords*/ false, /*allowPrivateIdentifiers*/ false);
|
||||
: parseEntityName(/*allowReservedWords*/ false);
|
||||
}
|
||||
|
||||
function parseExternalModuleReference() {
|
||||
@@ -7682,7 +7665,7 @@ namespace ts {
|
||||
else {
|
||||
parseExpected(SyntaxKind.DefaultKeyword);
|
||||
}
|
||||
const expression = parseAssignmentExpressionOrHigher(/*disallowReturnTypeInArrowFunction*/ false);
|
||||
const expression = parseAssignmentExpressionOrHigher();
|
||||
parseSemicolon();
|
||||
setAwaitContext(savedAwaitContext);
|
||||
const node = factory.createExportAssignment(decorators, modifiers, isExportEquals, expression);
|
||||
@@ -7760,7 +7743,7 @@ namespace ts {
|
||||
const pos = getNodePos();
|
||||
const hasBrace = parseOptional(SyntaxKind.OpenBraceToken);
|
||||
const p2 = getNodePos();
|
||||
let entityName: EntityName | JSDocMemberName = parseEntityName(/* allowReservedWords*/ false, /*allowPrivateIdentifiers*/ false);
|
||||
let entityName: EntityName | JSDocMemberName = parseEntityName(/* allowReservedWords*/ false);
|
||||
while (token() === SyntaxKind.PrivateIdentifier) {
|
||||
reScanHashToken(); // rescan #id as # id
|
||||
nextTokenJSDoc(); // then skip the #
|
||||
@@ -8223,7 +8206,7 @@ namespace ts {
|
||||
// parseEntityName logs an error for non-identifier, so create a MissingNode ourselves to avoid the error
|
||||
const p2 = getNodePos();
|
||||
let name: EntityName | JSDocMemberName | undefined = tokenIsIdentifierOrKeyword(token())
|
||||
? parseEntityName(/*allowReservedWords*/ true, /*allowPrivateIdentifiers*/ false)
|
||||
? parseEntityName(/*allowReservedWords*/ true)
|
||||
: undefined;
|
||||
if (name) {
|
||||
while (token() === SyntaxKind.PrivateIdentifier) {
|
||||
@@ -8578,7 +8561,8 @@ namespace ts {
|
||||
if (!comment) {
|
||||
comment = parseTrailingTagComments(start, getNodePos(), indent, indentText);
|
||||
}
|
||||
return finishNode(factory.createJSDocCallbackTag(tagName, typeExpression, fullName, comment), start);
|
||||
const end = comment !== undefined ? getNodePos() : typeExpression.end;
|
||||
return finishNode(factory.createJSDocCallbackTag(tagName, typeExpression, fullName, comment), start, end);
|
||||
}
|
||||
|
||||
function escapedTextsEqual(a: EntityName, b: EntityName): boolean {
|
||||
|
||||
+51
-10
@@ -262,7 +262,7 @@ namespace ts {
|
||||
return newValue;
|
||||
};
|
||||
if (originalWriteFile) {
|
||||
host.writeFile = (fileName, data, writeByteOrderMark, onError, sourceFiles) => {
|
||||
host.writeFile = (fileName, data, ...rest) => {
|
||||
const key = toPath(fileName);
|
||||
fileExistsCache.delete(key);
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace ts {
|
||||
sourceFileCache.delete(key);
|
||||
}
|
||||
}
|
||||
originalWriteFile.call(host, fileName, data, writeByteOrderMark, onError, sourceFiles);
|
||||
originalWriteFile.call(host, fileName, data, ...rest);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -858,7 +858,7 @@ namespace ts {
|
||||
*/
|
||||
export function getImpliedNodeFormatForFile(fileName: Path, packageJsonInfoCache: PackageJsonInfoCache | undefined, host: ModuleResolutionHost, options: CompilerOptions): ModuleKind.ESNext | ModuleKind.CommonJS | undefined {
|
||||
switch (getEmitModuleResolutionKind(options)) {
|
||||
case ModuleResolutionKind.Node12:
|
||||
case ModuleResolutionKind.Node16:
|
||||
case ModuleResolutionKind.NodeNext:
|
||||
return fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Mjs]) ? ModuleKind.ESNext :
|
||||
fileExtensionIsOneOf(fileName, [Extension.Dcts, Extension.Cts, Extension.Cjs]) ? ModuleKind.CommonJS :
|
||||
@@ -913,7 +913,6 @@ namespace ts {
|
||||
Diagnostics.A_rest_parameter_cannot_have_an_initializer.code,
|
||||
Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list.code,
|
||||
Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma.code,
|
||||
Diagnostics.A_return_statement_can_only_be_used_within_a_function_body.code,
|
||||
Diagnostics.A_return_statement_cannot_be_used_inside_a_class_static_block.code,
|
||||
Diagnostics.A_set_accessor_cannot_have_rest_parameter.code,
|
||||
Diagnostics.A_set_accessor_must_have_exactly_one_parameter.code,
|
||||
@@ -1210,7 +1209,7 @@ namespace ts {
|
||||
const containingFilename = combinePaths(containingDirectory, inferredTypesContainingFile);
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename);
|
||||
for (let i = 0; i < typeReferences.length; i++) {
|
||||
// under node12/nodenext module resolution, load `types`/ata include names as cjs resolution results by passing an `undefined` mode
|
||||
// under node16/nodenext module resolution, load `types`/ata include names as cjs resolution results by passing an `undefined` mode
|
||||
processTypeReferenceDirective(typeReferences[i], /*mode*/ undefined, resolutions[i], { kind: FileIncludeKind.AutomaticTypeDirectiveFile, typeReference: typeReferences[i], packageId: resolutions[i]?.packageId });
|
||||
}
|
||||
tracing?.pop();
|
||||
@@ -1340,6 +1339,7 @@ namespace ts {
|
||||
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
|
||||
getFileIncludeReasons: () => fileReasons,
|
||||
structureIsReused,
|
||||
writeFile,
|
||||
};
|
||||
|
||||
onProgramCreateComplete();
|
||||
@@ -1364,6 +1364,36 @@ namespace ts {
|
||||
|
||||
return program;
|
||||
|
||||
function addResolutionDiagnostics(list: Diagnostic[] | undefined) {
|
||||
if (!list) return;
|
||||
for (const elem of list) {
|
||||
programDiagnostics.add(elem);
|
||||
}
|
||||
}
|
||||
|
||||
function pullDiagnosticsFromCache(names: string[] | readonly FileReference[], containingFile: SourceFile) {
|
||||
if (!moduleResolutionCache) return;
|
||||
const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory);
|
||||
const containingFileMode = !isString(containingFile) ? containingFile.impliedNodeFormat : undefined;
|
||||
const containingDir = getDirectoryPath(containingFileName);
|
||||
const redirectedReference = getRedirectReferenceForResolution(containingFile);
|
||||
let i = 0;
|
||||
for (const n of names) {
|
||||
// mimics logic done in the resolution cache, should be resilient to upgrading it to use `FileReference`s for non-type-reference modal lookups to make it rely on the index in the list less
|
||||
const mode = typeof n === "string" ? getModeForResolutionAtIndex(containingFile, i) : getModeForFileReference(n, containingFileMode);
|
||||
const name = typeof n === "string" ? n : n.fileName;
|
||||
i++;
|
||||
// only nonrelative names hit the cache, and, at least as of right now, only nonrelative names can issue diagnostics
|
||||
// (Since diagnostics are only issued via import or export map lookup)
|
||||
// This may totally change if/when the issue of output paths not mapping to input files is fixed in a broader context
|
||||
// When it is, how we extract diagnostics from the module name resolver will have the be refined - the current cache
|
||||
// APIs wrapping the underlying resolver make it almost impossible to smuggle the diagnostics out in a generalized way
|
||||
if (isExternalModuleNameRelative(name)) continue;
|
||||
const diags = moduleResolutionCache.getOrCreateCacheForModuleName(name, mode, redirectedReference).get(containingDir)?.resolutionDiagnostics;
|
||||
addResolutionDiagnostics(diags);
|
||||
}
|
||||
}
|
||||
|
||||
function resolveModuleNamesWorker(moduleNames: string[], containingFile: SourceFile, reusedNames: string[] | undefined): readonly ResolvedModuleFull[] {
|
||||
if (!moduleNames.length) return emptyArray;
|
||||
const containingFileName = getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory);
|
||||
@@ -1374,6 +1404,7 @@ namespace ts {
|
||||
performance.mark("afterResolveModule");
|
||||
performance.measure("ResolveModule", "beforeResolveModule", "afterResolveModule");
|
||||
tracing?.pop();
|
||||
pullDiagnosticsFromCache(moduleNames, containingFile);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1894,8 +1925,7 @@ namespace ts {
|
||||
getProjectReferenceRedirect,
|
||||
isSourceOfProjectReferenceRedirect,
|
||||
getSymlinkCache,
|
||||
writeFile: writeFileCallback || (
|
||||
(fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)),
|
||||
writeFile: writeFileCallback || writeFile,
|
||||
isEmitBlocked,
|
||||
readFile: f => host.readFile(f),
|
||||
fileExists: f => {
|
||||
@@ -1914,6 +1944,17 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function writeFile(
|
||||
fileName: string,
|
||||
text: string,
|
||||
writeByteOrderMark: boolean,
|
||||
onError?: (message: string) => void,
|
||||
sourceFiles?: readonly SourceFile[],
|
||||
data?: WriteFileCallbackData
|
||||
) {
|
||||
host.writeFile(fileName, text, writeByteOrderMark, onError, sourceFiles, data);
|
||||
}
|
||||
|
||||
function emitBuildInfo(writeFileCallback?: WriteFileCallback): EmitResult {
|
||||
Debug.assert(!outFile(options));
|
||||
tracing?.push(tracing.Phase.Emit, "emitBuildInfo", {}, /*separateBeginAndEnd*/ true);
|
||||
@@ -3074,8 +3115,8 @@ namespace ts {
|
||||
const fileName = toFileNameLowerCase(ref.fileName);
|
||||
setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective);
|
||||
const mode = ref.resolutionMode || file.impliedNodeFormat;
|
||||
if (mode && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node12 && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext) {
|
||||
programDiagnostics.add(createDiagnosticForRange(file, ref, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node12_or_nodenext));
|
||||
if (mode && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node16 && getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext) {
|
||||
programDiagnostics.add(createDiagnosticForRange(file, ref, Diagnostics.Resolution_modes_are_only_supported_when_moduleResolution_is_node16_or_nodenext));
|
||||
}
|
||||
processTypeReferenceDirective(fileName, mode, resolvedTypeReferenceDirective, { kind: FileIncludeKind.TypeReferenceDirective, file: file.path, index, });
|
||||
}
|
||||
@@ -3504,7 +3545,7 @@ namespace ts {
|
||||
|
||||
if (options.resolveJsonModule) {
|
||||
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs &&
|
||||
getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node12 &&
|
||||
getEmitModuleResolutionKind(options) !== ModuleResolutionKind.Node16 &&
|
||||
getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeNext) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule");
|
||||
}
|
||||
|
||||
+4
-2
@@ -1210,11 +1210,13 @@ namespace ts {
|
||||
base64decode?(input: string): string;
|
||||
base64encode?(input: string): string;
|
||||
/*@internal*/ bufferFrom?(input: string, encoding?: string): Buffer;
|
||||
/*@internal*/ require?(baseDir: string, moduleName: string): RequireResult;
|
||||
/*@internal*/ defaultWatchFileKind?(): WatchFileKind | undefined;
|
||||
|
||||
// For testing
|
||||
/*@internal*/ now?(): Date;
|
||||
/*@internal*/ disableUseFileVersionAsSignature?: boolean;
|
||||
/*@internal*/ require?(baseDir: string, moduleName: string): RequireResult;
|
||||
/*@internal*/ defaultWatchFileKind?(): WatchFileKind | undefined;
|
||||
/*@internal*/ storeFilesChangingSignatureDuringEmit?: boolean;
|
||||
}
|
||||
|
||||
export interface FileWatcher {
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace ts {
|
||||
return transformECMAScriptModule;
|
||||
case ModuleKind.System:
|
||||
return transformSystemModule;
|
||||
case ModuleKind.Node12:
|
||||
case ModuleKind.Node16:
|
||||
case ModuleKind.NodeNext:
|
||||
return transformNodeModule;
|
||||
default:
|
||||
|
||||
@@ -1294,7 +1294,7 @@ namespace ts {
|
||||
resumeLexicalEnvironment();
|
||||
|
||||
const needsSyntheticConstructor = !constructor && isDerivedClass;
|
||||
let indexOfFirstStatementAfterSuper = 0;
|
||||
let indexOfFirstStatementAfterSuperAndPrologue = 0;
|
||||
let prologueStatementCount = 0;
|
||||
let superStatementIndex = -1;
|
||||
let statements: Statement[] = [];
|
||||
@@ -1305,13 +1305,16 @@ namespace ts {
|
||||
|
||||
// If there was a super call, visit existing statements up to and including it
|
||||
if (superStatementIndex >= 0) {
|
||||
indexOfFirstStatementAfterSuper = superStatementIndex + 1;
|
||||
indexOfFirstStatementAfterSuperAndPrologue = superStatementIndex + 1;
|
||||
statements = [
|
||||
...statements.slice(0, prologueStatementCount),
|
||||
...visitNodes(constructor.body.statements, visitor, isStatement, prologueStatementCount, indexOfFirstStatementAfterSuper - prologueStatementCount),
|
||||
...visitNodes(constructor.body.statements, visitor, isStatement, prologueStatementCount, indexOfFirstStatementAfterSuperAndPrologue - prologueStatementCount),
|
||||
...statements.slice(prologueStatementCount),
|
||||
];
|
||||
}
|
||||
else if (prologueStatementCount >= 0) {
|
||||
indexOfFirstStatementAfterSuperAndPrologue = prologueStatementCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsSyntheticConstructor) {
|
||||
@@ -1354,26 +1357,25 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
if (parameterPropertyDeclarationCount > 0) {
|
||||
const parameterProperties = visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatementAfterSuper, parameterPropertyDeclarationCount);
|
||||
const parameterProperties = visitNodes(constructor.body.statements, visitor, isStatement, indexOfFirstStatementAfterSuperAndPrologue, parameterPropertyDeclarationCount);
|
||||
|
||||
// If there was a super() call found, add parameter properties immediately after it
|
||||
if (superStatementIndex >= 0) {
|
||||
addRange(statements, parameterProperties);
|
||||
}
|
||||
// If a synthetic super() call was added, add them just after it
|
||||
else if (needsSyntheticConstructor) {
|
||||
else {
|
||||
// Add add parameter properties to the top of the constructor after the prologue
|
||||
let superAndPrologueStatementCount = prologueStatementCount;
|
||||
// If a synthetic super() call was added, need to account for that
|
||||
if (needsSyntheticConstructor) superAndPrologueStatementCount++;
|
||||
statements = [
|
||||
statements[0],
|
||||
...statements.slice(0, superAndPrologueStatementCount),
|
||||
...parameterProperties,
|
||||
...statements.slice(1),
|
||||
...statements.slice(superAndPrologueStatementCount),
|
||||
];
|
||||
}
|
||||
// Since there wasn't a super() call, add them to the top of the constructor
|
||||
else {
|
||||
statements = [...parameterProperties, ...statements];
|
||||
}
|
||||
|
||||
indexOfFirstStatementAfterSuper += parameterPropertyDeclarationCount;
|
||||
indexOfFirstStatementAfterSuperAndPrologue += parameterPropertyDeclarationCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1385,7 +1387,7 @@ namespace ts {
|
||||
|
||||
// Add existing statements after the initial prologues and super call
|
||||
if (constructor) {
|
||||
addRange(statements, visitNodes(constructor.body!.statements, visitBodyStatement, isStatement, indexOfFirstStatementAfterSuper + prologueStatementCount));
|
||||
addRange(statements, visitNodes(constructor.body!.statements, visitBodyStatement, isStatement, indexOfFirstStatementAfterSuperAndPrologue));
|
||||
}
|
||||
|
||||
statements = factory.mergeLexicalEnvironment(statements, endLexicalEnvironment());
|
||||
|
||||
@@ -1140,6 +1140,9 @@ namespace ts {
|
||||
const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker), /*initializer*/ undefined);
|
||||
errorFallbackNode = undefined;
|
||||
const statement = factory.createVariableStatement(needsDeclare ? [factory.createModifier(SyntaxKind.DeclareKeyword)] : [], factory.createVariableDeclarationList([varDecl], NodeFlags.Const));
|
||||
|
||||
preserveJsDoc(statement, input);
|
||||
removeAllComments(input);
|
||||
return [statement, factory.updateExportAssignment(input, input.decorators, input.modifiers, newId)];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1146,7 +1146,7 @@ namespace ts {
|
||||
[
|
||||
...existingPrologue,
|
||||
...prologue,
|
||||
...(superStatementIndex <= existingPrologue.length ? emptyArray : visitNodes(constructor.body.statements, visitor, isStatement, existingPrologue.length, superStatementIndex)),
|
||||
...(superStatementIndex <= existingPrologue.length ? emptyArray : visitNodes(constructor.body.statements, visitor, isStatement, existingPrologue.length, superStatementIndex - existingPrologue.length)),
|
||||
...statements
|
||||
]
|
||||
),
|
||||
|
||||
@@ -1896,7 +1896,7 @@ namespace ts {
|
||||
{
|
||||
createNewValue: (path, _input) => state.watchFile(
|
||||
path,
|
||||
() => invalidateProjectAndScheduleBuilds(state, resolvedPath, ConfigFileProgramReloadLevel.Full),
|
||||
() => invalidateProjectAndScheduleBuilds(state, resolvedPath, ConfigFileProgramReloadLevel.None),
|
||||
PollingInterval.High,
|
||||
parsed?.watchOptions,
|
||||
WatchType.PackageJson,
|
||||
|
||||
+24
-12
@@ -3615,7 +3615,7 @@ namespace ts {
|
||||
languageVersion: ScriptTarget;
|
||||
|
||||
/**
|
||||
* When `module` is `Node12` or `NodeNext`, this field controls whether the
|
||||
* When `module` is `Node16` or `NodeNext`, this field controls whether the
|
||||
* source file in question is an ESNext-output-format file, or a CommonJS-output-format
|
||||
* module. This is derived by the module resolver as it looks up the file, since
|
||||
* it is derived from either the file extension of the module, or the containing
|
||||
@@ -3856,12 +3856,16 @@ namespace ts {
|
||||
*/
|
||||
export type ResolvedConfigFileName = string & { _isResolvedConfigFileName: never };
|
||||
|
||||
export interface WriteFileCallbackData {
|
||||
/*@internal*/ sourceMapUrlPos?: number;
|
||||
}
|
||||
export type WriteFileCallback = (
|
||||
fileName: string,
|
||||
data: string,
|
||||
text: string,
|
||||
writeByteOrderMark: boolean,
|
||||
onError?: (message: string) => void,
|
||||
sourceFiles?: readonly SourceFile[],
|
||||
data?: WriteFileCallbackData,
|
||||
) => void;
|
||||
|
||||
export class OperationCanceledException { }
|
||||
@@ -4067,6 +4071,8 @@ namespace ts {
|
||||
* This implementation handles file exists to be true if file is source of project reference redirect when program is created using useSourceOfProjectReferenceRedirect
|
||||
*/
|
||||
/*@internal*/ fileExists(fileName: string): boolean;
|
||||
/** Call compilerHost.writeFile on host program was created with */
|
||||
/*@internal*/ writeFile: WriteFileCallback;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
@@ -6043,11 +6049,12 @@ namespace ts {
|
||||
Classic = 1,
|
||||
NodeJs = 2,
|
||||
// Starting with node12, node's module resolver has significant departures from traditional cjs resolution
|
||||
// to better support ecmascript modules and their use within node - more features are still being added, so
|
||||
// we can expect it to change over time, and as such, offer both a `NodeNext` moving resolution target, and a `Node12`
|
||||
// version-anchored resolution target
|
||||
Node12 = 3,
|
||||
NodeNext = 99, // Not simply `Node12` so that compiled code linked against TS can use the `Next` value reliably (same as with `ModuleKind`)
|
||||
// to better support ecmascript modules and their use within node - however more features are still being added.
|
||||
// TypeScript's Node ESM support was introduced after Node 12 went end-of-life, and Node 14 is the earliest stable
|
||||
// version that supports both pattern trailers - *but*, Node 16 is the first version that also supports ECMASCript 2022.
|
||||
// In turn, we offer both a `NodeNext` moving resolution target, and a `Node16` version-anchored resolution target
|
||||
Node16 = 3,
|
||||
NodeNext = 99, // Not simply `Node16` so that compiled code linked against TS can use the `Next` value reliably (same as with `ModuleKind`)
|
||||
}
|
||||
|
||||
export enum ModuleDetectionKind {
|
||||
@@ -6056,7 +6063,7 @@ namespace ts {
|
||||
*/
|
||||
Legacy = 1,
|
||||
/**
|
||||
* Legacy, but also files with jsx under react-jsx or react-jsxdev and esm mode files under moduleResolution: node12+
|
||||
* Legacy, but also files with jsx under react-jsx or react-jsxdev and esm mode files under moduleResolution: node16+
|
||||
*/
|
||||
Auto = 2,
|
||||
/**
|
||||
@@ -6275,8 +6282,8 @@ namespace ts {
|
||||
ES2022 = 7,
|
||||
ESNext = 99,
|
||||
|
||||
// Node12+ is an amalgam of commonjs (albeit updated) and es2020+, and represents a distinct module system from es2020/esnext
|
||||
Node12 = 100,
|
||||
// Node16+ is an amalgam of commonjs (albeit updated) and es2022+, and represents a distinct module system from es2020/esnext
|
||||
Node16 = 100,
|
||||
NodeNext = 199,
|
||||
}
|
||||
|
||||
@@ -6710,6 +6717,8 @@ namespace ts {
|
||||
readonly resolvedModule: ResolvedModuleFull | undefined;
|
||||
/* @internal */
|
||||
readonly failedLookupLocations: string[];
|
||||
/* @internal */
|
||||
readonly resolutionDiagnostics: Diagnostic[]
|
||||
}
|
||||
|
||||
export interface ResolvedTypeReferenceDirective {
|
||||
@@ -6731,6 +6740,8 @@ namespace ts {
|
||||
export interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
readonly resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined;
|
||||
readonly failedLookupLocations: string[];
|
||||
/* @internal */
|
||||
resolutionDiagnostics: Diagnostic[]
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -6782,6 +6793,7 @@ namespace ts {
|
||||
|
||||
// For testing:
|
||||
/*@internal*/ disableUseFileVersionAsSignature?: boolean;
|
||||
/*@internal*/ storeFilesChangingSignatureDuringEmit?: boolean;
|
||||
}
|
||||
|
||||
/** true if --out otherwise source file name */
|
||||
@@ -8463,7 +8475,7 @@ namespace ts {
|
||||
export interface ResolvedModuleSpecifierInfo {
|
||||
modulePaths: readonly ModulePath[] | undefined;
|
||||
moduleSpecifiers: readonly string[] | undefined;
|
||||
isAutoImportable: boolean | undefined;
|
||||
isBlockedByPackageJsonDependencies: boolean | undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -8475,7 +8487,7 @@ namespace ts {
|
||||
export interface ModuleSpecifierCache {
|
||||
get(fromFileName: Path, toFileName: Path, preferences: UserPreferences, options: ModuleSpecifierOptions): Readonly<ResolvedModuleSpecifierInfo> | undefined;
|
||||
set(fromFileName: Path, toFileName: Path, preferences: UserPreferences, options: ModuleSpecifierOptions, modulePaths: readonly ModulePath[], moduleSpecifiers: readonly string[]): void;
|
||||
setIsAutoImportable(fromFileName: Path, toFileName: Path, preferences: UserPreferences, options: ModuleSpecifierOptions, isAutoImportable: boolean): void;
|
||||
setBlockedByPackageJsonDependencies(fromFileName: Path, toFileName: Path, preferences: UserPreferences, options: ModuleSpecifierOptions, isBlockedByPackageJsonDependencies: boolean): void;
|
||||
setModulePaths(fromFileName: Path, toFileName: Path, preferences: UserPreferences, options: ModuleSpecifierOptions, modulePaths: readonly ModulePath[]): void;
|
||||
clear(): void;
|
||||
count(): number;
|
||||
|
||||
+23
-13
@@ -656,10 +656,10 @@ namespace ts {
|
||||
AllowNumericSeparator = 1 << 3
|
||||
}
|
||||
|
||||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile, flags: GetLiteralTextFlags) {
|
||||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile | undefined, flags: GetLiteralTextFlags) {
|
||||
// If we don't need to downlevel and we can reach the original source text using
|
||||
// the node's parent reference, then simply get the text as it was originally written.
|
||||
if (canUseOriginalText(node, flags)) {
|
||||
if (sourceFile && canUseOriginalText(node, flags)) {
|
||||
return getSourceTextOfNodeFromSourceFile(sourceFile, node);
|
||||
}
|
||||
|
||||
@@ -808,7 +808,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isCommonJSContainingModuleKind(kind: ModuleKind) {
|
||||
return kind === ModuleKind.CommonJS || kind === ModuleKind.Node12 || kind === ModuleKind.NodeNext;
|
||||
return kind === ModuleKind.CommonJS || kind === ModuleKind.Node16 || kind === ModuleKind.NodeNext;
|
||||
}
|
||||
|
||||
export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) {
|
||||
@@ -4387,6 +4387,16 @@ namespace ts {
|
||||
Extension.Dts;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is an inverse of `getDeclarationEmitExtensionForPath`.
|
||||
*/
|
||||
export function getPossibleOriginalInputExtensionForExtension(path: string) {
|
||||
return fileExtensionIsOneOf(path, [Extension.Dmts, Extension.Mjs, Extension.Mts]) ? [Extension.Mts, Extension.Mjs] :
|
||||
fileExtensionIsOneOf(path, [Extension.Dcts, Extension.Cjs, Extension.Cts]) ? [Extension.Cts, Extension.Cjs]:
|
||||
fileExtensionIsOneOf(path, [`.json.d.ts`]) ? [Extension.Json] :
|
||||
[Extension.Tsx, Extension.Ts, Extension.Jsx, Extension.Js];
|
||||
}
|
||||
|
||||
export function outFile(options: CompilerOptions) {
|
||||
return options.outFile || options.out;
|
||||
}
|
||||
@@ -4459,10 +4469,10 @@ namespace ts {
|
||||
return combinePaths(newDirPath, sourceFilePath);
|
||||
}
|
||||
|
||||
export function writeFile(host: { writeFile: WriteFileCallback; }, diagnostics: DiagnosticCollection, fileName: string, data: string, writeByteOrderMark: boolean, sourceFiles?: readonly SourceFile[]) {
|
||||
host.writeFile(fileName, data, writeByteOrderMark, hostErrorMessage => {
|
||||
export function writeFile(host: { writeFile: WriteFileCallback; }, diagnostics: DiagnosticCollection, fileName: string, text: string, writeByteOrderMark: boolean, sourceFiles?: readonly SourceFile[], data?: WriteFileCallbackData) {
|
||||
host.writeFile(fileName, text, writeByteOrderMark, hostErrorMessage => {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
|
||||
}, sourceFiles);
|
||||
}, sourceFiles, data);
|
||||
}
|
||||
|
||||
function ensureDirectoriesExist(
|
||||
@@ -6319,7 +6329,7 @@ namespace ts {
|
||||
file.externalModuleIndicator = isFileProbablyExternalModule(file);
|
||||
};
|
||||
case ModuleDetectionKind.Auto:
|
||||
// If module is nodenext or node12, all esm format files are modules
|
||||
// If module is nodenext or node16, all esm format files are modules
|
||||
// If jsx is react-jsx or react-jsxdev then jsx tags force module-ness
|
||||
// otherwise, the presence of import or export statments (or import.meta) implies module-ness
|
||||
const checks: ((file: SourceFile) => Node | true | undefined)[] = [isFileProbablyExternalModule];
|
||||
@@ -6327,7 +6337,7 @@ namespace ts {
|
||||
checks.push(isFileModuleFromUsingJSXTag);
|
||||
}
|
||||
const moduleKind = getEmitModuleKind(options);
|
||||
if (moduleKind === ModuleKind.Node12 || moduleKind === ModuleKind.NodeNext) {
|
||||
if (moduleKind === ModuleKind.Node16 || moduleKind === ModuleKind.NodeNext) {
|
||||
checks.push(isFileForcedToBeModuleByFormat);
|
||||
}
|
||||
const combined = or(...checks);
|
||||
@@ -6338,7 +6348,7 @@ namespace ts {
|
||||
|
||||
export function getEmitScriptTarget(compilerOptions: {module?: CompilerOptions["module"], target?: CompilerOptions["target"]}) {
|
||||
return compilerOptions.target ||
|
||||
(compilerOptions.module === ModuleKind.Node12 && ScriptTarget.ES2020) ||
|
||||
(compilerOptions.module === ModuleKind.Node16 && ScriptTarget.ES2022) ||
|
||||
(compilerOptions.module === ModuleKind.NodeNext && ScriptTarget.ESNext) ||
|
||||
ScriptTarget.ES3;
|
||||
}
|
||||
@@ -6356,8 +6366,8 @@ namespace ts {
|
||||
case ModuleKind.CommonJS:
|
||||
moduleResolution = ModuleResolutionKind.NodeJs;
|
||||
break;
|
||||
case ModuleKind.Node12:
|
||||
moduleResolution = ModuleResolutionKind.Node12;
|
||||
case ModuleKind.Node16:
|
||||
moduleResolution = ModuleResolutionKind.Node16;
|
||||
break;
|
||||
case ModuleKind.NodeNext:
|
||||
moduleResolution = ModuleResolutionKind.NodeNext;
|
||||
@@ -6382,7 +6392,7 @@ namespace ts {
|
||||
case ModuleKind.ES2020:
|
||||
case ModuleKind.ES2022:
|
||||
case ModuleKind.ESNext:
|
||||
case ModuleKind.Node12:
|
||||
case ModuleKind.Node16:
|
||||
case ModuleKind.NodeNext:
|
||||
return true;
|
||||
default:
|
||||
@@ -6407,7 +6417,7 @@ namespace ts {
|
||||
return compilerOptions.esModuleInterop;
|
||||
}
|
||||
switch (getEmitModuleKind(compilerOptions)) {
|
||||
case ModuleKind.Node12:
|
||||
case ModuleKind.Node16:
|
||||
case ModuleKind.NodeNext:
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -573,6 +573,7 @@ namespace ts {
|
||||
createHash: maybeBind(host, host.createHash),
|
||||
readDirectory: maybeBind(host, host.readDirectory),
|
||||
disableUseFileVersionAsSignature: host.disableUseFileVersionAsSignature,
|
||||
storeFilesChangingSignatureDuringEmit: host.storeFilesChangingSignatureDuringEmit,
|
||||
};
|
||||
|
||||
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, onError: (message: string) => void) {
|
||||
@@ -637,6 +638,7 @@ namespace ts {
|
||||
createHash: maybeBind(system, system.createHash),
|
||||
createProgram: createProgram || createEmitAndSemanticDiagnosticsBuilderProgram as any as CreateProgram<T>,
|
||||
disableUseFileVersionAsSignature: system.disableUseFileVersionAsSignature,
|
||||
storeFilesChangingSignatureDuringEmit: system.storeFilesChangingSignatureDuringEmit,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace ts {
|
||||
const host = createCompilerHostWorker(options, /*setParentNodes*/ undefined, system);
|
||||
host.createHash = maybeBind(system, system.createHash);
|
||||
host.disableUseFileVersionAsSignature = system.disableUseFileVersionAsSignature;
|
||||
host.storeFilesChangingSignatureDuringEmit = system.storeFilesChangingSignatureDuringEmit;
|
||||
setGetSourceFileAsHashVersioned(host, system);
|
||||
changeCompilerHostLikeToUseCache(host, fileName => toPath(fileName, host.getCurrentDirectory(), host.getCanonicalFileName));
|
||||
return host;
|
||||
@@ -114,6 +115,7 @@ namespace ts {
|
||||
writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
// For testing
|
||||
disableUseFileVersionAsSignature?: boolean;
|
||||
storeFilesChangingSignatureDuringEmit?: boolean;
|
||||
}
|
||||
|
||||
export interface WatchCompilerHost<T extends BuilderProgram> extends ProgramHost<T>, WatchHost {
|
||||
|
||||
+16
-2
@@ -38,6 +38,7 @@ namespace ts.server {
|
||||
private lineMaps = new Map<string, number[]>();
|
||||
private messages: string[] = [];
|
||||
private lastRenameEntry: RenameEntry | undefined;
|
||||
private preferences: UserPreferences | undefined;
|
||||
|
||||
constructor(private host: SessionClientHost) {
|
||||
}
|
||||
@@ -124,6 +125,7 @@ namespace ts.server {
|
||||
|
||||
/*@internal*/
|
||||
configure(preferences: UserPreferences) {
|
||||
this.preferences = preferences;
|
||||
const args: protocol.ConfigureRequestArguments = { preferences };
|
||||
const request = this.processRequest(CommandNames.Configure, args);
|
||||
this.processResponse(request, /*expectEmptyBody*/ true);
|
||||
@@ -488,13 +490,25 @@ namespace ts.server {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] {
|
||||
findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean, providePrefixAndSuffixTextForRename?: boolean): RenameLocation[] {
|
||||
if (!this.lastRenameEntry ||
|
||||
this.lastRenameEntry.inputs.fileName !== fileName ||
|
||||
this.lastRenameEntry.inputs.position !== position ||
|
||||
this.lastRenameEntry.inputs.findInStrings !== findInStrings ||
|
||||
this.lastRenameEntry.inputs.findInComments !== findInComments) {
|
||||
this.getRenameInfo(fileName, position, { allowRenameOfImportPath: true }, findInStrings, findInComments);
|
||||
if (providePrefixAndSuffixTextForRename !== undefined) {
|
||||
// User preferences have to be set through the `Configure` command
|
||||
this.configure({ providePrefixAndSuffixTextForRename });
|
||||
// Options argument is not used, so don't pass in options
|
||||
this.getRenameInfo(fileName, position, /*options*/{}, findInStrings, findInComments);
|
||||
// Restore previous user preferences
|
||||
if (this.preferences) {
|
||||
this.configure(this.preferences);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.getRenameInfo(fileName, position, /*options*/{}, findInStrings, findInComments);
|
||||
}
|
||||
}
|
||||
|
||||
return this.lastRenameEntry!.locations;
|
||||
|
||||
@@ -249,7 +249,7 @@ namespace compiler {
|
||||
}
|
||||
|
||||
// establish defaults (aligns with old harness)
|
||||
if (compilerOptions.target === undefined && compilerOptions.module !== ts.ModuleKind.Node12 && compilerOptions.module !== ts.ModuleKind.NodeNext) compilerOptions.target = ts.ScriptTarget.ES3;
|
||||
if (compilerOptions.target === undefined && compilerOptions.module !== ts.ModuleKind.Node16 && compilerOptions.module !== ts.ModuleKind.NodeNext) compilerOptions.target = ts.ScriptTarget.ES3;
|
||||
if (compilerOptions.newLine === undefined) compilerOptions.newLine = ts.NewLineKind.CarriageReturnLineFeed;
|
||||
if (compilerOptions.skipDefaultLibCheck === undefined) compilerOptions.skipDefaultLibCheck = true;
|
||||
if (compilerOptions.noErrorTruncation === undefined) compilerOptions.noErrorTruncation = true;
|
||||
|
||||
+11
-13
@@ -55,12 +55,12 @@ namespace vfs {
|
||||
} = {};
|
||||
|
||||
private _cwd: string; // current working directory
|
||||
private _time: number | Date | (() => number | Date);
|
||||
private _time: number;
|
||||
private _shadowRoot: FileSystem | undefined;
|
||||
private _dirStack: string[] | undefined;
|
||||
|
||||
constructor(ignoreCase: boolean, options: FileSystemOptions = {}) {
|
||||
const { time = -1, files, meta } = options;
|
||||
const { time = ts.VirtualFS.timeIncrements, files, meta } = options;
|
||||
this.ignoreCase = ignoreCase;
|
||||
this.stringComparer = this.ignoreCase ? vpath.compareCaseInsensitive : vpath.compareCaseSensitive;
|
||||
this._time = time;
|
||||
@@ -167,16 +167,15 @@ namespace vfs {
|
||||
*
|
||||
* @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/time.html
|
||||
*/
|
||||
public time(value?: number | Date | (() => number | Date)): number {
|
||||
if (value !== undefined && this.isReadonly) throw createIOError("EPERM");
|
||||
let result = this._time;
|
||||
if (typeof result === "function") result = result();
|
||||
if (typeof result === "object") result = result.getTime();
|
||||
if (result === -1) result = Date.now();
|
||||
public time(value?: number): number {
|
||||
if (value !== undefined) {
|
||||
if (this.isReadonly) throw createIOError("EPERM");
|
||||
this._time = value;
|
||||
}
|
||||
return result;
|
||||
else if (!this.isReadonly) {
|
||||
this._time += ts.VirtualFS.timeIncrements;
|
||||
}
|
||||
return this._time;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -843,7 +842,7 @@ namespace vfs {
|
||||
container[basename] = new Symlink(node.symlink);
|
||||
}
|
||||
else {
|
||||
container[basename] = new File(node.buffer || "");
|
||||
container[basename] = new File(changed._getBuffer(node));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1172,9 +1171,8 @@ namespace vfs {
|
||||
}
|
||||
|
||||
export interface FileSystemOptions {
|
||||
// Sets the initial timestamp for new files and directories, or the function used
|
||||
// to calculate timestamps.
|
||||
time?: number | Date | (() => number | Date);
|
||||
// Sets the initial timestamp for new files and directories
|
||||
time?: number;
|
||||
|
||||
// A set of file system entries to initially add to the file system.
|
||||
files?: FileSet;
|
||||
|
||||
@@ -229,6 +229,7 @@ interface Array<T> { length: number; [n: number]: T; }`
|
||||
export class TestServerHost extends VirtualServerHost implements server.ServerHost {
|
||||
readonly screenClears: number[] = [];
|
||||
private readonly output: string[] = [];
|
||||
|
||||
constructor(
|
||||
public withSafeList: boolean,
|
||||
fileOrFolderorSymLinkList: readonly FileOrFolderOrSymLink[],
|
||||
|
||||
Vendored
+4
-4
@@ -673,6 +673,7 @@ interface DataView {
|
||||
* Gets the BigInt64 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be read.
|
||||
*/
|
||||
getBigInt64(byteOffset: number, littleEndian?: boolean): bigint;
|
||||
|
||||
@@ -680,6 +681,7 @@ interface DataView {
|
||||
* Gets the BigUint64 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be read.
|
||||
*/
|
||||
getBigUint64(byteOffset: number, littleEndian?: boolean): bigint;
|
||||
|
||||
@@ -687,8 +689,7 @@ interface DataView {
|
||||
* Stores a BigInt64 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written.
|
||||
*/
|
||||
setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void;
|
||||
|
||||
@@ -696,8 +697,7 @@ interface DataView {
|
||||
* Stores a BigUint64 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written.
|
||||
*/
|
||||
setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void;
|
||||
}
|
||||
|
||||
Vendored
+14
-14
@@ -52,13 +52,13 @@ declare function decodeURIComponent(encodedURIComponent: string): string;
|
||||
|
||||
/**
|
||||
* Encodes a text string as a valid Uniform Resource Identifier (URI)
|
||||
* @param uri A value representing an encoded URI.
|
||||
* @param uri A value representing an unencoded URI.
|
||||
*/
|
||||
declare function encodeURI(uri: string): string;
|
||||
|
||||
/**
|
||||
* Encodes a text string as a valid component of a Uniform Resource Identifier (URI).
|
||||
* @param uriComponent A value representing an encoded URI component.
|
||||
* @param uriComponent A value representing an unencoded URI component.
|
||||
*/
|
||||
declare function encodeURIComponent(uriComponent: string | number | boolean): string;
|
||||
|
||||
@@ -1669,6 +1669,7 @@ interface DataView {
|
||||
* Gets the Float32 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be read.
|
||||
*/
|
||||
getFloat32(byteOffset: number, littleEndian?: boolean): number;
|
||||
|
||||
@@ -1676,6 +1677,7 @@ interface DataView {
|
||||
* Gets the Float64 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be read.
|
||||
*/
|
||||
getFloat64(byteOffset: number, littleEndian?: boolean): number;
|
||||
|
||||
@@ -1690,12 +1692,14 @@ interface DataView {
|
||||
* Gets the Int16 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be read.
|
||||
*/
|
||||
getInt16(byteOffset: number, littleEndian?: boolean): number;
|
||||
/**
|
||||
* Gets the Int32 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be read.
|
||||
*/
|
||||
getInt32(byteOffset: number, littleEndian?: boolean): number;
|
||||
|
||||
@@ -1710,6 +1714,7 @@ interface DataView {
|
||||
* Gets the Uint16 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be read.
|
||||
*/
|
||||
getUint16(byteOffset: number, littleEndian?: boolean): number;
|
||||
|
||||
@@ -1717,6 +1722,7 @@ interface DataView {
|
||||
* Gets the Uint32 value at the specified byte offset from the start of the view. There is
|
||||
* no alignment constraint; multi-byte values may be fetched from any offset.
|
||||
* @param byteOffset The place in the buffer at which the value should be retrieved.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be read.
|
||||
*/
|
||||
getUint32(byteOffset: number, littleEndian?: boolean): number;
|
||||
|
||||
@@ -1724,8 +1730,7 @@ interface DataView {
|
||||
* Stores an Float32 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written.
|
||||
*/
|
||||
setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void;
|
||||
|
||||
@@ -1733,8 +1738,7 @@ interface DataView {
|
||||
* Stores an Float64 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written.
|
||||
*/
|
||||
setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void;
|
||||
|
||||
@@ -1749,8 +1753,7 @@ interface DataView {
|
||||
* Stores an Int16 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written.
|
||||
*/
|
||||
setInt16(byteOffset: number, value: number, littleEndian?: boolean): void;
|
||||
|
||||
@@ -1758,8 +1761,7 @@ interface DataView {
|
||||
* Stores an Int32 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written.
|
||||
*/
|
||||
setInt32(byteOffset: number, value: number, littleEndian?: boolean): void;
|
||||
|
||||
@@ -1774,8 +1776,7 @@ interface DataView {
|
||||
* Stores an Uint16 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written.
|
||||
*/
|
||||
setUint16(byteOffset: number, value: number, littleEndian?: boolean): void;
|
||||
|
||||
@@ -1783,8 +1784,7 @@ interface DataView {
|
||||
* Stores an Uint32 value at the specified byte offset from the start of the view.
|
||||
* @param byteOffset The place in the buffer at which the value should be set.
|
||||
* @param value The value to set.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written,
|
||||
* otherwise a little-endian value should be written.
|
||||
* @param littleEndian If false or undefined, a big-endian value should be written.
|
||||
*/
|
||||
setUint32(byteOffset: number, value: number, littleEndian?: boolean): void;
|
||||
}
|
||||
|
||||
@@ -5349,18 +5349,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[动态导入不能含有类型参数。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -5997,6 +5985,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[应为 1 个参数,但得到 0。“new Promise()” 需要 JSDoc 提示才能生成可在没有参数的情况下调用的 “resolve”。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13740,6 +13737,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[“import” 的这种用法无效。可以写入 “import()” 调用,但它们必须具有括号,并且不能带有类型参数。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13977,15 +13983,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[类型“{0}”不是数组类型或字符串类型。请使用编译器选项 "--downlevelIteration" 允许迭代器进行迭代。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5349,18 +5349,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[動態匯入不可有型別引數。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -5997,6 +5985,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[需要 1 個引數,但得到 0。'new Promise()' 需要 JSDoc 提示,才能產生可以呼叫而不含引數的 'resolve'。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13740,6 +13737,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[此 'import' 的使用方式無效。'import()' 呼叫可以寫入,但必須有括弧,而且不能有類型引數。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13977,15 +13983,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[類型 '{0}' 不是陣列類型或字串類型。請使用編譯器選項 '-downlevelIteration' 允許逐一查看迭代器。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5358,18 +5358,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dynamický import nemůže mít argumenty typu.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -6006,6 +5994,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Očekával se 1 argument, ale bylo jich 0. New Promise() potřebuje pomocný parametr JSDoc k vytvoření resolve, který se dá volat bez argumentů.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13749,6 +13746,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Toto použití importu není platné. Volání import() se dají zapsat, ale musí mít závorky a nemůžou mít typové argumenty.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13986,15 +13992,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Typ {0} není typem pole ani typem řetězce. Pokud chcete povolit iteraci iterátorů, použijte možnost kompilátoru --downlevelIteration.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5346,18 +5346,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Der dynamische Import kann keine Typargumente aufweisen.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -5994,6 +5982,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[1 Argument erwartet, aber 0 erhalten. „new Promise()“ benötigt einen JSDoc-Hinweis, um einen „resolve“ zu erzeugen, der ohne Argumente aufgerufen werden kann.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13734,6 +13731,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Diese Verwendung von „import“ ist ungültig. „import()“-Aufrufe können geschrieben werden, müssen jedoch Klammern aufweisen und dürfen keine Typargumente aufweisen.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13971,15 +13977,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Der Typ "{0}" ist kein Arraytyp oder Zeichenfolgentyp. Verwenden Sie die Compileroption "--downlevelIteration", um das Durchlaufen von Iteratoren zuzulassen.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5361,18 +5361,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[La importación dinámica no puede tener argumentos de tipo.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -6009,6 +5997,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Se esperaba 1 argumento, pero se obtuvo 0. "new Promise()" necesita una pista de JSDoc para producir un "resolve" que pueda llamarse sin argumentos.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13752,6 +13749,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Este uso de "import" no es válido. Se pueden escribir llamadas "import()", pero deben tener paréntesis y no pueden tener argumentos de tipo.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13989,15 +13995,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA["{0}" no es un tipo de matriz o de cadena. Use la opción del compilador "--downlevelIteration" para permitir la iteración de los iteradores.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5361,18 +5361,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[L'importation dynamique ne peut pas avoir d'arguments de type.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -6009,6 +5997,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[1 argument attendu, mais 0 obtenu. 'new Promise()' a besoin d’un indicateur JSDoc pour produire un 'resolve' qui peut être appelé sans arguments.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13752,6 +13749,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Cette utilisation de « import » n’est pas valide. Les appels « import() » peuvent être écrits, mais ils doivent avoir des parenthèses et ne peuvent pas avoir d’arguments de type.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13989,15 +13995,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Le type '{0}' n’est pas un type de tableau ou un type string. Utilisez l'option du compilateur '--downlevelIteration' pour autoriser l'itération des itérateurs.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5349,18 +5349,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Nell'importazione dinamica non possono essere presenti argomenti tipo.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -5997,6 +5985,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Previsto 1 argomento, ma ottenuto 0. 'new Promise()' richiede un hint JSDoc per produrre un elemento 'resolve' che possa essere chiamato senza argomenti.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13740,6 +13737,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Questo uso di 'import' non è valido. le chiamate 'import()' possono essere scritte, ma devono avere parentesi e non possono avere argomenti di tipo.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13977,15 +13983,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Il tipo '{0}' non è un tipo matrice o stringa. Usare l'opzione del compilatore '--downlevelIteration' per consentire l'iterazione degli iteratori.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5349,18 +5349,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[動的インポートに型引数を指定することはできません。]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -5997,6 +5985,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[1 個の引数が必要ですが、0 個しかありませんでした。'new Promise()' では、引数なしで呼び出すことができる 'resolve' を生成するための JSDoc ヒントが必要です。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13740,6 +13737,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[この 'import' の使用は無効です。'import()' 呼び出しは書き込むことができますが、かっこが必要であり、型引数を指定することはできません。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13977,15 +13983,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[型 '{0}' は配列型でも文字列型でもありません。反復子の反復を許可するには、コンパイラ オプション '--downlevelIteration' を使用します。]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5349,18 +5349,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[동적 가져오기에는 형식 인수를 사용할 수 없습니다.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -5997,6 +5985,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[1개의 인수가 필요하지만 0이 있습니다. 'new Promise()'는 인수 없이 호출할 수 있는 'resolve'를 생성하기 위해 JSDoc 힌트가 필요합니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13740,6 +13737,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[이 '가져오기' 사용은 유효하지 않습니다. 'import()' 호출을 작성할 수 있지만 괄호가 있어야 하며 유형 인수를 가질 수 없습니다.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13977,15 +13983,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' 형식이 배열 형식 또는 문자열 형식이 아닙니다. 컴파일러 옵션 '-downlevelIteration'을 사용하여 반복기의 반복을 허용하세요.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5339,18 +5339,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dynamiczny import nie może mieć argumentów typu.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -5987,6 +5975,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Oczekiwano 1 argumentu, ale otrzymano 0. Element „new Promise()” wymaga wskazówki JSDoc, aby utworzyć element „resolve”, który można wywołać bez argumentów.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13727,6 +13724,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[To użycie elementu „import” jest nieprawidłowe. Wywołania „import()” mogą być zapisywane, ale muszą mieć nawiasy i nie mogą mieć argumentów typu.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13964,15 +13970,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Typ „{0}” nie jest typem tablicy ani typem ciągu. Użyj opcji kompilatora „--downlevelIteration”, aby zezwolić na iterowanie iteratorów.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5342,18 +5342,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[A importação dinâmica não pode ter argumentos de tipo.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -5990,6 +5978,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Esperava 1 argumento, mas obteve 0. 'new Promise()' precisa de uma dica JSDoc para produzir um 'resolver' que pode ser chamado sem argumentos.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13730,6 +13727,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Este uso de 'importar' é inválido. Chamadas 'import()' podem ser escritas, mas devem ter parênteses e não podem ter argumentos de tipo.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13967,15 +13973,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[O tipo '{0}' não é um tipo de matriz nem um tipo de cadeia de caracteres. Use a opção do compilador '--downlevelIteration' para permitir a iteração dos iteradores.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5348,18 +5348,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[При динамическом импорте не могут использоваться аргументы типов.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -5996,6 +5984,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Ожидался 1 аргумент, получено 0. Для "new Promise()" требуется указание JSDoc, чтобы создать "resolve" с возможностью вызова без аргументов.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13739,6 +13736,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Недопустимое использование "import". Можно записывать вызовы "import()", но у них должны быть скобки и не должно быть аргументов типа.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13976,15 +13982,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Тип "{0}" не является типом строки или массива. Используйте параметр компилятора "--downlevelIteration", чтобы разрешить итерацию итераторов.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -5342,18 +5342,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_cannot_have_type_arguments_1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[Dinamik içeri aktarma, tür bağımsız değişkenleri içeremez.]]></Val>
|
||||
</Tgt>
|
||||
<Prev Cat="Text">
|
||||
<Val><![CDATA[Dynamic import cannot have type arguments]]></Val>
|
||||
</Prev>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Dynamic import's specifier must be of type 'string', but here has type '{0}'.]]></Val>
|
||||
@@ -5990,6 +5978,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_2810" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected 1 argument, but got 0. 'new Promise()' needs a JSDoc hint to produce a 'resolve' that can be called without arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA[1 bağımsız değişken bekleniyordu ancak 0 bağımsız değişken var. Bağımsız değişkenler olmadan çağrılabilen bir 'resolve' oluşturmak için 'new Promise()' çağrısında bir JSDoc ipucu bulunması gerekir.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Expected_at_least_0_arguments_but_got_1_2555" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Expected at least {0} arguments, but got {1}.]]></Val>
|
||||
@@ -13733,6 +13730,15 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";This_use_of_import_is_invalid_import_calls_can_be_written_but_they_must_have_parentheses_and_cannot__1326" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[This use of 'import' is invalid. 'import()' calls can be written, but they must have parentheses and cannot have type arguments.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['import' çağrısının bu kullanımı geçersiz. 'import()' çağrıları yazılabilir ancak ayraç içermeleri gerekir ve tür bağımsız değişkenleri içeremezler.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_o_1378" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', or 'nodenext', and the 'target' option is set to 'es2017' or higher.]]></Val>
|
||||
@@ -13970,15 +13976,6 @@
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterati_2569" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.]]></Val>
|
||||
<Tgt Cat="Text" Stat="Loc" Orig="New">
|
||||
<Val><![CDATA['{0}' türü bir dizi türü veya bir dize türü değil. Yineleyicilerin yinelenmesine izin vermek için '--downlevelIteration' derleyici seçeneğini kullanın.]]></Val>
|
||||
</Tgt>
|
||||
</Str>
|
||||
<Disp Icon="Str" />
|
||||
</Item>
|
||||
<Item ItemId=";Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549" ItemType="0" PsrId="306" Leaf="true">
|
||||
<Str Cat="Text">
|
||||
<Val><![CDATA[Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]5D;()' method that returns an iterator.]]></Val>
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace ts.server {
|
||||
return cache.get(toFileName);
|
||||
},
|
||||
set(fromFileName, toFileName, preferences, options, modulePaths, moduleSpecifiers) {
|
||||
ensureCache(fromFileName, preferences, options).set(toFileName, createInfo(modulePaths, moduleSpecifiers, /*isAutoImportable*/ true));
|
||||
ensureCache(fromFileName, preferences, options).set(toFileName, createInfo(modulePaths, moduleSpecifiers, /*isBlockedByPackageJsonDependencies*/ false));
|
||||
|
||||
// If any module specifiers were generated based off paths in node_modules,
|
||||
// a package.json file in that package was read and is an input to the cached.
|
||||
@@ -43,17 +43,17 @@ namespace ts.server {
|
||||
info.modulePaths = modulePaths;
|
||||
}
|
||||
else {
|
||||
cache.set(toFileName, createInfo(modulePaths, /*moduleSpecifiers*/ undefined, /*isAutoImportable*/ undefined));
|
||||
cache.set(toFileName, createInfo(modulePaths, /*moduleSpecifiers*/ undefined, /*isBlockedByPackageJsonDependencies*/ undefined));
|
||||
}
|
||||
},
|
||||
setIsAutoImportable(fromFileName, toFileName, preferences, options, isAutoImportable) {
|
||||
setBlockedByPackageJsonDependencies(fromFileName, toFileName, preferences, options, isBlockedByPackageJsonDependencies) {
|
||||
const cache = ensureCache(fromFileName, preferences, options);
|
||||
const info = cache.get(toFileName);
|
||||
if (info) {
|
||||
info.isAutoImportable = isAutoImportable;
|
||||
info.isBlockedByPackageJsonDependencies = isBlockedByPackageJsonDependencies;
|
||||
}
|
||||
else {
|
||||
cache.set(toFileName, createInfo(/*modulePaths*/ undefined, /*moduleSpecifiers*/ undefined, isAutoImportable));
|
||||
cache.set(toFileName, createInfo(/*modulePaths*/ undefined, /*moduleSpecifiers*/ undefined, isBlockedByPackageJsonDependencies));
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
@@ -87,9 +87,9 @@ namespace ts.server {
|
||||
function createInfo(
|
||||
modulePaths: readonly ModulePath[] | undefined,
|
||||
moduleSpecifiers: readonly string[] | undefined,
|
||||
isAutoImportable: boolean | undefined,
|
||||
isBlockedByPackageJsonDependencies: boolean | undefined,
|
||||
): ResolvedModuleSpecifierInfo {
|
||||
return { modulePaths, moduleSpecifiers, isAutoImportable };
|
||||
return { modulePaths, moduleSpecifiers, isBlockedByPackageJsonDependencies };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2433,6 +2433,7 @@ namespace ts.server.protocol {
|
||||
}
|
||||
|
||||
export interface CompletionInfo {
|
||||
readonly flags?: number;
|
||||
readonly isGlobalCompletion: boolean;
|
||||
readonly isMemberCompletion: boolean;
|
||||
readonly isNewIdentifierLocation: boolean;
|
||||
|
||||
+11
-8
@@ -317,6 +317,7 @@ namespace ts.server {
|
||||
projects,
|
||||
defaultProject,
|
||||
initialLocation,
|
||||
/*isForRename*/ true,
|
||||
(project, location, tryAddToTodo) => {
|
||||
const projectOutputs = project.getLanguageService().findRenameLocations(location.fileName, location.pos, findInStrings, findInComments, providePrefixAndSuffixTextForRename);
|
||||
if (projectOutputs) {
|
||||
@@ -332,8 +333,8 @@ namespace ts.server {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
function getDefinitionLocation(defaultProject: Project, initialLocation: DocumentPosition): DocumentPosition | undefined {
|
||||
const infos = defaultProject.getLanguageService().getDefinitionAtPosition(initialLocation.fileName, initialLocation.pos);
|
||||
function getDefinitionLocation(defaultProject: Project, initialLocation: DocumentPosition, isForRename: boolean): DocumentPosition | undefined {
|
||||
const infos = defaultProject.getLanguageService().getDefinitionAtPosition(initialLocation.fileName, initialLocation.pos, /*searchOtherFilesOnly*/ false, isForRename);
|
||||
const info = infos && firstOrUndefined(infos);
|
||||
return info && !info.isLocal ? { fileName: info.fileName, pos: info.textSpan.start } : undefined;
|
||||
}
|
||||
@@ -350,11 +351,12 @@ namespace ts.server {
|
||||
projects,
|
||||
defaultProject,
|
||||
initialLocation,
|
||||
/*isForRename*/ false,
|
||||
(project, location, getMappedLocation) => {
|
||||
logger.info(`Finding references to ${location.fileName} position ${location.pos} in project ${project.getProjectName()}`);
|
||||
const projectOutputs = project.getLanguageService().findReferences(location.fileName, location.pos);
|
||||
if (projectOutputs) {
|
||||
const clearIsDefinition = projectOutputs[0].references[0].isDefinition === undefined;
|
||||
const clearIsDefinition = projectOutputs[0]?.references[0]?.isDefinition === undefined;
|
||||
for (const referencedSymbol of projectOutputs) {
|
||||
const mappedDefinitionFile = getMappedLocation(project, documentSpanLocation(referencedSymbol.definition));
|
||||
const definition: ReferencedSymbolDefinitionInfo = mappedDefinitionFile === undefined ?
|
||||
@@ -417,7 +419,8 @@ namespace ts.server {
|
||||
projects: Projects,
|
||||
defaultProject: Project,
|
||||
initialLocation: TLocation,
|
||||
cb: CombineProjectOutputCallback<TLocation>
|
||||
isForRename: boolean,
|
||||
cb: CombineProjectOutputCallback<TLocation>,
|
||||
): void {
|
||||
const projectService = defaultProject.projectService;
|
||||
let toDo: ProjectAndLocation<TLocation>[] | undefined;
|
||||
@@ -430,7 +433,7 @@ namespace ts.server {
|
||||
|
||||
// After initial references are collected, go over every other project and see if it has a reference for the symbol definition.
|
||||
if (initialLocation) {
|
||||
const defaultDefinition = getDefinitionLocation(defaultProject, initialLocation);
|
||||
const defaultDefinition = getDefinitionLocation(defaultProject, initialLocation, isForRename);
|
||||
if (defaultDefinition) {
|
||||
const getGeneratedDefinition = memoize(() => defaultProject.isSourceOfProjectReferenceRedirect(defaultDefinition.fileName) ?
|
||||
defaultDefinition :
|
||||
@@ -1247,7 +1250,7 @@ namespace ts.server {
|
||||
definitions?.forEach(d => definitionSet.add(d));
|
||||
const noDtsProject = project.getNoDtsResolutionProject([file]);
|
||||
const ls = noDtsProject.getLanguageService();
|
||||
const jsDefinitions = ls.getDefinitionAtPosition(file, position, /*searchOtherFilesOnly*/ true)
|
||||
const jsDefinitions = ls.getDefinitionAtPosition(file, position, /*searchOtherFilesOnly*/ true, /*stopAtAlias*/ false)
|
||||
?.filter(d => toNormalizedPath(d.fileName) !== file);
|
||||
if (some(jsDefinitions)) {
|
||||
for (const jsDefinition of jsDefinitions) {
|
||||
@@ -1292,7 +1295,7 @@ namespace ts.server {
|
||||
const compilerOptions = project.getCompilationSettings();
|
||||
const packageJson = getPackageScopeForPath(project.toPath(packageDirectory + "/package.json"), packageJsonCache, project, compilerOptions);
|
||||
if (!packageJson) return undefined;
|
||||
// Use fake options instead of actual compiler options to avoid following export map if the project uses node12 or nodenext -
|
||||
// Use fake options instead of actual compiler options to avoid following export map if the project uses node16 or nodenext -
|
||||
// Mapping from an export map entry across packages is out of scope for now. Returned entrypoints will only be what can be
|
||||
// resolved from the package root under --moduleResolution node
|
||||
const entrypoints = getEntrypointsFromPackageJsonInfo(
|
||||
@@ -1334,7 +1337,7 @@ namespace ts.server {
|
||||
if ((isStringLiteralLike(initialNode) || isIdentifier(initialNode)) && isAccessExpression(initialNode.parent)) {
|
||||
return forEachNameInAccessChainWalkingLeft(initialNode, nameInChain => {
|
||||
if (nameInChain === initialNode) return undefined;
|
||||
const candidates = ls.getDefinitionAtPosition(file, nameInChain.getStart(), /*searchOtherFilesOnly*/ true)
|
||||
const candidates = ls.getDefinitionAtPosition(file, nameInChain.getStart(), /*searchOtherFilesOnly*/ true, /*stopAtAlias*/ false)
|
||||
?.filter(d => toNormalizedPath(d.fileName) !== file && d.isAmbient)
|
||||
.map(d => ({
|
||||
fileName: d.fileName,
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace ts.codefix {
|
||||
Diagnostics.This_condition_will_always_return_true_since_this_0_is_always_defined.code,
|
||||
Diagnostics.Type_0_is_not_an_array_type.code,
|
||||
Diagnostics.Type_0_is_not_an_array_type_or_a_string_type.code,
|
||||
Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_Use_compiler_option_downlevelIteration_to_allow_iterating_of_iterators.code,
|
||||
Diagnostics.Type_0_can_only_be_iterated_through_when_using_the_downlevelIteration_flag_or_with_a_target_of_es2015_or_higher.code,
|
||||
Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator.code,
|
||||
Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator.code,
|
||||
Diagnostics.Type_0_must_have_a_Symbol_iterator_method_that_returns_an_iterator.code,
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace ts.codefix {
|
||||
const fixName = "addVoidToPromise";
|
||||
const fixId = "addVoidToPromise";
|
||||
const errorCodes = [
|
||||
Diagnostics.Expected_1_argument_but_got_0_new_Promise_needs_a_JSDoc_hint_to_produce_a_resolve_that_can_be_called_without_arguments.code,
|
||||
Diagnostics.Expected_0_arguments_but_got_1_Did_you_forget_to_include_void_in_your_type_argument_to_Promise.code
|
||||
];
|
||||
registerCodeFix({
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
namespace ts.codefix {
|
||||
registerCodeFix({
|
||||
errorCodes: [
|
||||
Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher.code,
|
||||
Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher.code,
|
||||
Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher.code,
|
||||
Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_es2022_esnext_system_node16_or_nodenext_and_the_target_option_is_set_to_es2017_or_higher.code,
|
||||
],
|
||||
getCodeActions: function getCodeActionsToFixModuleAndTarget(context) {
|
||||
const compilerOptions = context.program.getCompilerOptions();
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace ts.codefix {
|
||||
const symbol = checker.getMergedSymbol(skipAlias(exportedSymbol, checker));
|
||||
const exportInfo = getAllReExportingModules(sourceFile, symbol, moduleSymbol, symbolName, /*isJsxTagName*/ false, host, program, preferences, useAutoImportProvider);
|
||||
const useRequire = shouldUseRequire(sourceFile, program);
|
||||
const fix = getImportFixForSymbol(sourceFile, exportInfo, moduleSymbol, symbolName, program, /*position*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences);
|
||||
const fix = getImportFixForSymbol(sourceFile, exportInfo, moduleSymbol, program, /*useNamespaceInfo*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences);
|
||||
if (fix) {
|
||||
addImport({ fixes: [fix], symbolName, errorIdentifierText: undefined });
|
||||
}
|
||||
@@ -310,7 +310,7 @@ namespace ts.codefix {
|
||||
: getAllReExportingModules(sourceFile, targetSymbol, moduleSymbol, symbolName, isJsxTagName, host, program, preferences, /*useAutoImportProvider*/ true);
|
||||
const useRequire = shouldUseRequire(sourceFile, program);
|
||||
const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite(getTokenAtPosition(sourceFile, position));
|
||||
const fix = Debug.checkDefined(getImportFixForSymbol(sourceFile, exportInfos, moduleSymbol, symbolName, program, position, isValidTypeOnlyUseSite, useRequire, host, preferences));
|
||||
const fix = Debug.checkDefined(getImportFixForSymbol(sourceFile, exportInfos, moduleSymbol, program, { symbolName, position }, isValidTypeOnlyUseSite, useRequire, host, preferences));
|
||||
return {
|
||||
moduleSpecifier: fix.moduleSpecifier,
|
||||
codeAction: codeFixActionToCodeAction(codeActionForFix(
|
||||
@@ -331,10 +331,10 @@ namespace ts.codefix {
|
||||
return fix && codeFixActionToCodeAction(codeActionForFix({ host, formatContext, preferences }, sourceFile, symbolName, fix, includeSymbolNameInDescription, QuotePreference.Double, compilerOptions));
|
||||
}
|
||||
|
||||
function getImportFixForSymbol(sourceFile: SourceFile, exportInfos: readonly SymbolExportInfo[], moduleSymbol: Symbol, symbolName: string, program: Program, position: number | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, host: LanguageServiceHost, preferences: UserPreferences) {
|
||||
function getImportFixForSymbol(sourceFile: SourceFile, exportInfos: readonly SymbolExportInfo[], moduleSymbol: Symbol, program: Program, useNamespaceInfo: { position: number, symbolName: string } | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, host: LanguageServiceHost, preferences: UserPreferences) {
|
||||
Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol || info.symbol.parent === moduleSymbol), "Some exportInfo should match the specified moduleSymbol");
|
||||
const packageJsonImportFilter = createPackageJsonImportFilter(sourceFile, preferences, host);
|
||||
return getBestFix(getImportFixes(exportInfos, symbolName, position, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences), sourceFile, program, packageJsonImportFilter, host);
|
||||
return getBestFix(getImportFixes(exportInfos, useNamespaceInfo, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes, sourceFile, program, packageJsonImportFilter, host);
|
||||
}
|
||||
|
||||
function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAction): CodeAction {
|
||||
@@ -396,6 +396,9 @@ namespace ts.codefix {
|
||||
|
||||
export function getModuleSpecifierForBestExportInfo(
|
||||
exportInfo: readonly SymbolExportInfo[],
|
||||
symbolName: string,
|
||||
position: number,
|
||||
isValidTypeOnlyUseSite: boolean,
|
||||
importingFile: SourceFile,
|
||||
program: Program,
|
||||
host: LanguageServiceHost,
|
||||
@@ -403,13 +406,13 @@ namespace ts.codefix {
|
||||
packageJsonImportFilter?: PackageJsonImportFilter,
|
||||
fromCacheOnly?: boolean,
|
||||
): { exportInfo?: SymbolExportInfo, moduleSpecifier: string, computedWithoutCacheCount: number } | undefined {
|
||||
const { fixes, computedWithoutCacheCount } = getNewImportFixes(
|
||||
const { fixes, computedWithoutCacheCount } = getImportFixes(
|
||||
exportInfo,
|
||||
{ symbolName, position },
|
||||
isValidTypeOnlyUseSite,
|
||||
/*useRequire*/ false,
|
||||
program,
|
||||
importingFile,
|
||||
/*position*/ undefined,
|
||||
/*isValidTypeOnlyUseSite*/ false,
|
||||
/*useRequire*/ false,
|
||||
exportInfo,
|
||||
host,
|
||||
preferences,
|
||||
fromCacheOnly);
|
||||
@@ -419,23 +422,46 @@ namespace ts.codefix {
|
||||
|
||||
function getImportFixes(
|
||||
exportInfos: readonly SymbolExportInfo[],
|
||||
symbolName: string,
|
||||
useNamespaceInfo: {
|
||||
symbolName: string,
|
||||
position: number,
|
||||
} | undefined,
|
||||
/** undefined only for missing JSX namespace */
|
||||
position: number | undefined,
|
||||
isValidTypeOnlyUseSite: boolean,
|
||||
useRequire: boolean,
|
||||
program: Program,
|
||||
sourceFile: SourceFile,
|
||||
host: LanguageServiceHost,
|
||||
preferences: UserPreferences,
|
||||
): readonly ImportFixWithModuleSpecifier[] {
|
||||
fromCacheOnly?: boolean,
|
||||
): { computedWithoutCacheCount: number, fixes: readonly ImportFixWithModuleSpecifier[] } {
|
||||
const checker = program.getTypeChecker();
|
||||
const existingImports = flatMap(exportInfos, info => getExistingImportDeclarations(info, checker, sourceFile, program.getCompilerOptions()));
|
||||
const useNamespace = position === undefined ? undefined : tryUseExistingNamespaceImport(existingImports, symbolName, position, checker);
|
||||
const useNamespace = useNamespaceInfo && tryUseExistingNamespaceImport(existingImports, useNamespaceInfo.symbolName, useNamespaceInfo.position, checker);
|
||||
const addToExisting = tryAddToExistingImport(existingImports, isValidTypeOnlyUseSite, checker, program.getCompilerOptions());
|
||||
// Don't bother providing an action to add a new import if we can add to an existing one.
|
||||
const addImport = addToExisting ? [addToExisting] : getFixesForAddImport(exportInfos, existingImports, program, sourceFile, position, isValidTypeOnlyUseSite, useRequire, host, preferences);
|
||||
return [...(useNamespace ? [useNamespace] : emptyArray), ...addImport];
|
||||
if (addToExisting) {
|
||||
// Don't bother providing an action to add a new import if we can add to an existing one.
|
||||
return {
|
||||
computedWithoutCacheCount: 0,
|
||||
fixes: [...(useNamespace ? [useNamespace] : emptyArray), addToExisting],
|
||||
};
|
||||
}
|
||||
|
||||
const { fixes, computedWithoutCacheCount = 0 } = getFixesForAddImport(
|
||||
exportInfos,
|
||||
existingImports,
|
||||
program,
|
||||
sourceFile,
|
||||
useNamespaceInfo?.position,
|
||||
isValidTypeOnlyUseSite,
|
||||
useRequire,
|
||||
host,
|
||||
preferences,
|
||||
fromCacheOnly);
|
||||
return {
|
||||
computedWithoutCacheCount,
|
||||
fixes: [...(useNamespace ? [useNamespace] : emptyArray), ...fixes],
|
||||
};
|
||||
}
|
||||
|
||||
function tryUseExistingNamespaceImport(existingImports: readonly FixAddToExistingImportInfo[], symbolName: string, position: number, checker: TypeChecker): FixUseNamespaceImport | undefined {
|
||||
@@ -618,6 +644,7 @@ namespace ts.codefix {
|
||||
const compilerOptions = program.getCompilerOptions();
|
||||
const moduleSpecifierResolutionHost = createModuleSpecifierResolutionHost(program, host);
|
||||
const getChecker = memoizeOne((isFromPackageJson: boolean) => isFromPackageJson ? host.getPackageJsonAutoImportProvider!()!.getTypeChecker() : program.getTypeChecker());
|
||||
const rejectNodeModulesRelativePaths = moduleResolutionUsesNodeModules(getEmitModuleResolutionKind(compilerOptions));
|
||||
const getModuleSpecifiers = fromCacheOnly
|
||||
? (moduleSymbol: Symbol) => ({ moduleSpecifiers: moduleSpecifiers.tryGetModuleSpecifiersFromCache(moduleSymbol, sourceFile, moduleSpecifierResolutionHost, preferences), computedWithoutCache: false })
|
||||
: (moduleSymbol: Symbol, checker: TypeChecker) => moduleSpecifiers.getModuleSpecifiersWithCacheInfo(moduleSymbol, checker, compilerOptions, sourceFile, moduleSpecifierResolutionHost, preferences);
|
||||
@@ -629,19 +656,19 @@ namespace ts.codefix {
|
||||
const importedSymbolHasValueMeaning = !!(exportInfo.targetFlags & SymbolFlags.Value);
|
||||
const addAsTypeOnly = getAddAsTypeOnly(isValidTypeOnlyUseSite, /*isForNewImportDeclaration*/ true, exportInfo.symbol, exportInfo.targetFlags, checker, compilerOptions);
|
||||
computedWithoutCacheCount += computedWithoutCache ? 1 : 0;
|
||||
return moduleSpecifiers?.map((moduleSpecifier): FixAddNewImport | FixAddJsdocTypeImport =>
|
||||
return mapDefined(moduleSpecifiers, (moduleSpecifier): FixAddNewImport | FixAddJsdocTypeImport | undefined =>
|
||||
rejectNodeModulesRelativePaths && pathContainsNodeModules(moduleSpecifier) ? undefined :
|
||||
// `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types.
|
||||
!importedSymbolHasValueMeaning && isJs && position !== undefined
|
||||
? { kind: ImportFixKind.JsdocTypeImport, moduleSpecifier, position, exportInfo, isReExport: i > 0 }
|
||||
: {
|
||||
kind: ImportFixKind.AddNew,
|
||||
moduleSpecifier,
|
||||
importKind: getImportKind(sourceFile, exportInfo.exportKind, compilerOptions),
|
||||
useRequire,
|
||||
addAsTypeOnly,
|
||||
exportInfo,
|
||||
isReExport: i > 0,
|
||||
}
|
||||
!importedSymbolHasValueMeaning && isJs && position !== undefined ? { kind: ImportFixKind.JsdocTypeImport, moduleSpecifier, position, exportInfo, isReExport: i > 0 } :
|
||||
{
|
||||
kind: ImportFixKind.AddNew,
|
||||
moduleSpecifier,
|
||||
importKind: getImportKind(sourceFile, exportInfo.exportKind, compilerOptions),
|
||||
useRequire,
|
||||
addAsTypeOnly,
|
||||
exportInfo,
|
||||
isReExport: i > 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -658,9 +685,10 @@ namespace ts.codefix {
|
||||
useRequire: boolean,
|
||||
host: LanguageServiceHost,
|
||||
preferences: UserPreferences,
|
||||
): readonly (FixAddNewImport | FixAddJsdocTypeImport)[] {
|
||||
fromCacheOnly?: boolean,
|
||||
): { computedWithoutCacheCount?: number, fixes: readonly (FixAddNewImport | FixAddJsdocTypeImport)[] } {
|
||||
const existingDeclaration = firstDefined(existingImports, info => newImportInfoFromExistingSpecifier(info, isValidTypeOnlyUseSite, useRequire, program.getTypeChecker(), program.getCompilerOptions()));
|
||||
return existingDeclaration ? [existingDeclaration] : getNewImportFixes(program, sourceFile, position, isValidTypeOnlyUseSite, useRequire, exportInfos, host, preferences).fixes;
|
||||
return existingDeclaration ? { fixes: [existingDeclaration] } : getNewImportFixes(program, sourceFile, position, isValidTypeOnlyUseSite, useRequire, exportInfos, host, preferences, fromCacheOnly);
|
||||
}
|
||||
|
||||
function newImportInfoFromExistingSpecifier(
|
||||
@@ -782,7 +810,8 @@ namespace ts.codefix {
|
||||
const symbolName = umdSymbol.name;
|
||||
const exportInfo: readonly SymbolExportInfo[] = [{ symbol: umdSymbol, moduleSymbol: symbol, moduleFileName: undefined, exportKind: ExportKind.UMD, targetFlags: symbol.flags, isFromPackageJson: false }];
|
||||
const useRequire = shouldUseRequire(sourceFile, program);
|
||||
const fixes = getImportFixes(exportInfo, symbolName, isIdentifier(token) ? token.getStart(sourceFile) : undefined, /*isValidTypeOnlyUseSite*/ false, useRequire, program, sourceFile, host, preferences);
|
||||
const position = isIdentifier(token) ? token.getStart(sourceFile) : undefined;
|
||||
const fixes = getImportFixes(exportInfo, position ? { position, symbolName } : undefined, /*isValidTypeOnlyUseSite*/ false, useRequire, program, sourceFile, host, preferences).fixes;
|
||||
return { fixes, symbolName, errorIdentifierText: tryCast(token, isIdentifier)?.text };
|
||||
}
|
||||
function getUmdSymbol(token: Node, checker: TypeChecker): Symbol | undefined {
|
||||
@@ -835,7 +864,7 @@ namespace ts.codefix {
|
||||
case ModuleKind.None:
|
||||
// Fall back to the `import * as ns` style import.
|
||||
return ImportKind.Namespace;
|
||||
case ModuleKind.Node12:
|
||||
case ModuleKind.Node16:
|
||||
case ModuleKind.NodeNext:
|
||||
return importingFile.impliedNodeFormat === ModuleKind.ESNext ? ImportKind.Namespace : ImportKind.CommonJS;
|
||||
default:
|
||||
@@ -855,7 +884,7 @@ namespace ts.codefix {
|
||||
const useRequire = shouldUseRequire(sourceFile, program);
|
||||
const exportInfo = getExportInfos(symbolName, isJSXTagName(symbolToken), getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, program, useAutoImportProvider, host, preferences);
|
||||
const fixes = arrayFrom(flatMapIterator(exportInfo.entries(), ([_, exportInfos]) =>
|
||||
getImportFixes(exportInfos, symbolName, symbolToken.getStart(sourceFile), isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences)));
|
||||
getImportFixes(exportInfos, { symbolName, position: symbolToken.getStart(sourceFile) }, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes));
|
||||
return { fixes, symbolName, errorIdentifierText: symbolToken.text };
|
||||
}
|
||||
|
||||
|
||||
+123
-38
@@ -164,71 +164,86 @@ namespace ts.Completions {
|
||||
TypeAssertionKeywords,
|
||||
TypeKeywords,
|
||||
TypeKeyword, // Literally just `type`
|
||||
Last = TypeKeywords
|
||||
Last = TypeKeyword
|
||||
}
|
||||
|
||||
const enum GlobalsSearch { Continue, Success, Fail }
|
||||
|
||||
interface ModuleSpecifierResolutioContext {
|
||||
tryResolve: (exportInfo: readonly SymbolExportInfo[], isFromAmbientModule: boolean) => ModuleSpecifierResolutionResult | undefined;
|
||||
resolutionLimitExceeded: () => boolean;
|
||||
tryResolve: (exportInfo: readonly SymbolExportInfo[], symbolName: string, isFromAmbientModule: boolean) => ModuleSpecifierResolutionResult;
|
||||
resolvedAny: () => boolean;
|
||||
skippedAny: () => boolean;
|
||||
resolvedBeyondLimit: () => boolean;
|
||||
}
|
||||
|
||||
interface ModuleSpecifierResolutionResult {
|
||||
type ModuleSpecifierResolutionResult = "skipped" | "failed" | {
|
||||
exportInfo?: SymbolExportInfo;
|
||||
moduleSpecifier: string;
|
||||
}
|
||||
};
|
||||
|
||||
function resolvingModuleSpecifiers<TReturn>(
|
||||
logPrefix: string,
|
||||
host: LanguageServiceHost,
|
||||
program: Program,
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
preferences: UserPreferences,
|
||||
isForImportStatementCompletion: boolean,
|
||||
isValidTypeOnlyUseSite: boolean,
|
||||
cb: (context: ModuleSpecifierResolutioContext) => TReturn,
|
||||
): TReturn {
|
||||
const start = timestamp();
|
||||
const packageJsonImportFilter = createPackageJsonImportFilter(sourceFile, preferences, host);
|
||||
let resolutionLimitExceeded = false;
|
||||
// Under `--moduleResolution nodenext`, we have to resolve module specifiers up front, because
|
||||
// package.json exports can mean we *can't* resolve a module specifier (that doesn't include a
|
||||
// relative path into node_modules), and we want to filter those completions out entirely.
|
||||
// Import statement completions always need specifier resolution because the module specifier is
|
||||
// part of their `insertText`, not the `codeActions` creating edits away from the cursor.
|
||||
const needsFullResolution = isForImportStatementCompletion || moduleResolutionRespectsExports(getEmitModuleResolutionKind(program.getCompilerOptions()));
|
||||
let skippedAny = false;
|
||||
let ambientCount = 0;
|
||||
let resolvedCount = 0;
|
||||
let resolvedFromCacheCount = 0;
|
||||
let cacheAttemptCount = 0;
|
||||
|
||||
const result = cb({ tryResolve, resolutionLimitExceeded: () => resolutionLimitExceeded });
|
||||
const result = cb({
|
||||
tryResolve,
|
||||
skippedAny: () => skippedAny,
|
||||
resolvedAny: () => resolvedCount > 0,
|
||||
resolvedBeyondLimit: () => resolvedCount > moduleSpecifierResolutionLimit,
|
||||
});
|
||||
|
||||
const hitRateMessage = cacheAttemptCount ? ` (${(resolvedFromCacheCount / cacheAttemptCount * 100).toFixed(1)}% hit rate)` : "";
|
||||
host.log?.(`${logPrefix}: resolved ${resolvedCount} module specifiers, plus ${ambientCount} ambient and ${resolvedFromCacheCount} from cache${hitRateMessage}`);
|
||||
host.log?.(`${logPrefix}: response is ${resolutionLimitExceeded ? "incomplete" : "complete"}`);
|
||||
host.log?.(`${logPrefix}: response is ${skippedAny ? "incomplete" : "complete"}`);
|
||||
host.log?.(`${logPrefix}: ${timestamp() - start}`);
|
||||
return result;
|
||||
|
||||
function tryResolve(exportInfo: readonly SymbolExportInfo[], isFromAmbientModule: boolean): ModuleSpecifierResolutionResult | undefined {
|
||||
function tryResolve(exportInfo: readonly SymbolExportInfo[], symbolName: string, isFromAmbientModule: boolean): ModuleSpecifierResolutionResult {
|
||||
if (isFromAmbientModule) {
|
||||
const result = codefix.getModuleSpecifierForBestExportInfo(exportInfo, sourceFile, program, host, preferences);
|
||||
const result = codefix.getModuleSpecifierForBestExportInfo(exportInfo, symbolName, position, isValidTypeOnlyUseSite, sourceFile, program, host, preferences);
|
||||
if (result) {
|
||||
ambientCount++;
|
||||
}
|
||||
return result;
|
||||
return result || "failed";
|
||||
}
|
||||
const shouldResolveModuleSpecifier = isForImportStatementCompletion || preferences.allowIncompleteCompletions && resolvedCount < moduleSpecifierResolutionLimit;
|
||||
const shouldResolveModuleSpecifier = needsFullResolution || preferences.allowIncompleteCompletions && resolvedCount < moduleSpecifierResolutionLimit;
|
||||
const shouldGetModuleSpecifierFromCache = !shouldResolveModuleSpecifier && preferences.allowIncompleteCompletions && cacheAttemptCount < moduleSpecifierResolutionCacheAttemptLimit;
|
||||
const result = (shouldResolveModuleSpecifier || shouldGetModuleSpecifierFromCache)
|
||||
? codefix.getModuleSpecifierForBestExportInfo(exportInfo, sourceFile, program, host, preferences, packageJsonImportFilter, shouldGetModuleSpecifierFromCache)
|
||||
? codefix.getModuleSpecifierForBestExportInfo(exportInfo, symbolName, position, isValidTypeOnlyUseSite, sourceFile, program, host, preferences, packageJsonImportFilter, shouldGetModuleSpecifierFromCache)
|
||||
: undefined;
|
||||
|
||||
if (!shouldResolveModuleSpecifier && !shouldGetModuleSpecifierFromCache || shouldGetModuleSpecifierFromCache && !result) {
|
||||
resolutionLimitExceeded = true;
|
||||
skippedAny = true;
|
||||
}
|
||||
|
||||
resolvedCount += result?.computedWithoutCacheCount || 0;
|
||||
resolvedFromCacheCount += exportInfo.length - resolvedCount;
|
||||
resolvedFromCacheCount += exportInfo.length - (result?.computedWithoutCacheCount || 0);
|
||||
if (shouldGetModuleSpecifierFromCache) {
|
||||
cacheAttemptCount++;
|
||||
}
|
||||
|
||||
return result;
|
||||
return result || (needsFullResolution ? "failed" : "skipped");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,8 +373,10 @@ namespace ts.Completions {
|
||||
host,
|
||||
program,
|
||||
file,
|
||||
location.getStart(),
|
||||
preferences,
|
||||
/*isForImportStatementCompletion*/ false,
|
||||
isValidTypeOnlyAliasUseSite(location),
|
||||
context => {
|
||||
const entries = mapDefined(previousResponse.entries, entry => {
|
||||
if (!entry.hasAction || !entry.source || !entry.data || completionEntryDataIsResolved(entry.data)) {
|
||||
@@ -374,8 +391,12 @@ namespace ts.Completions {
|
||||
const { origin } = Debug.checkDefined(getAutoImportSymbolFromCompletionEntryData(entry.name, entry.data, program, host));
|
||||
const info = exportMap.get(file.path, entry.data.exportMapKey);
|
||||
|
||||
const result = info && context.tryResolve(info, !isExternalModuleNameRelative(stripQuotes(origin.moduleSymbol.name)));
|
||||
if (!result) return entry;
|
||||
const result = info && context.tryResolve(info, entry.name, !isExternalModuleNameRelative(stripQuotes(origin.moduleSymbol.name)));
|
||||
if (result === "skipped") return entry;
|
||||
if (!result || result === "failed") {
|
||||
host.log?.(`Unexpected failure resolving auto import for '${entry.name}' from '${entry.source}'`);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const newOrigin: SymbolOriginInfoResolvedExport = {
|
||||
...origin,
|
||||
@@ -390,7 +411,7 @@ namespace ts.Completions {
|
||||
return entry;
|
||||
});
|
||||
|
||||
if (!context.resolutionLimitExceeded()) {
|
||||
if (!context.skippedAny()) {
|
||||
previousResponse.isIncomplete = undefined;
|
||||
}
|
||||
|
||||
@@ -399,6 +420,7 @@ namespace ts.Completions {
|
||||
);
|
||||
|
||||
previousResponse.entries = newEntries;
|
||||
previousResponse.flags = (previousResponse.flags || 0) | CompletionInfoFlags.IsContinuation;
|
||||
return previousResponse;
|
||||
}
|
||||
|
||||
@@ -552,7 +574,7 @@ namespace ts.Completions {
|
||||
if (keywordFilters !== KeywordCompletionFilters.None) {
|
||||
const entryNames = new Set(entries.map(e => e.name));
|
||||
for (const keywordEntry of getKeywordCompletions(keywordFilters, !insideJsDocTagTypeExpression && isSourceFileJS(sourceFile))) {
|
||||
if (!entryNames.has(keywordEntry.name)) {
|
||||
if (isTypeOnlyLocation && isTypeKeyword(stringToToken(keywordEntry.name)!) || !entryNames.has(keywordEntry.name)) {
|
||||
insertSorted(entries, keywordEntry, compareCompletionEntries, /*allowDuplicates*/ true);
|
||||
}
|
||||
}
|
||||
@@ -570,12 +592,13 @@ namespace ts.Completions {
|
||||
}
|
||||
|
||||
return {
|
||||
flags: completionData.flags,
|
||||
isGlobalCompletion: isInSnippetScope,
|
||||
isIncomplete: preferences.allowIncompleteCompletions && hasUnresolvedAutoImports ? true : undefined,
|
||||
isMemberCompletion: isMemberCompletionKind(completionKind),
|
||||
isNewIdentifierLocation,
|
||||
optionalReplacementSpan: getOptionalReplacementSpan(location),
|
||||
entries
|
||||
entries,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1199,18 +1222,19 @@ namespace ts.Completions {
|
||||
function createSnippetPrinter(
|
||||
printerOptions: PrinterOptions,
|
||||
) {
|
||||
let escapes: TextChange[] | undefined;
|
||||
const baseWriter = textChanges.createWriter(getNewLineCharacter(printerOptions));
|
||||
const printer = createPrinter(printerOptions, baseWriter);
|
||||
const writer: EmitTextWriter = {
|
||||
...baseWriter,
|
||||
write: s => baseWriter.write(escapeSnippetText(s)),
|
||||
write: s => escapingWrite(s, () => baseWriter.write(s)),
|
||||
nonEscapingWrite: baseWriter.write,
|
||||
writeLiteral: s => baseWriter.writeLiteral(escapeSnippetText(s)),
|
||||
writeStringLiteral: s => baseWriter.writeStringLiteral(escapeSnippetText(s)),
|
||||
writeSymbol: (s, symbol) => baseWriter.writeSymbol(escapeSnippetText(s), symbol),
|
||||
writeParameter: s => baseWriter.writeParameter(escapeSnippetText(s)),
|
||||
writeComment: s => baseWriter.writeComment(escapeSnippetText(s)),
|
||||
writeProperty: s => baseWriter.writeProperty(escapeSnippetText(s)),
|
||||
writeLiteral: s => escapingWrite(s, () => baseWriter.writeLiteral(s)),
|
||||
writeStringLiteral: s => escapingWrite(s, () => baseWriter.writeStringLiteral(s)),
|
||||
writeSymbol: (s, symbol) => escapingWrite(s, () => baseWriter.writeSymbol(s, symbol)),
|
||||
writeParameter: s => escapingWrite(s, () => baseWriter.writeParameter(s)),
|
||||
writeComment: s => escapingWrite(s, () => baseWriter.writeComment(s)),
|
||||
writeProperty: s => escapingWrite(s, () => baseWriter.writeProperty(s)),
|
||||
};
|
||||
|
||||
return {
|
||||
@@ -1218,12 +1242,39 @@ namespace ts.Completions {
|
||||
printAndFormatSnippetList,
|
||||
};
|
||||
|
||||
// The formatter/scanner will have issues with snippet-escaped text,
|
||||
// so instead of writing the escaped text directly to the writer,
|
||||
// generate a set of changes that can be applied to the unescaped text
|
||||
// to escape it post-formatting.
|
||||
function escapingWrite(s: string, write: () => void) {
|
||||
const escaped = escapeSnippetText(s);
|
||||
if (escaped !== s) {
|
||||
const start = baseWriter.getTextPos();
|
||||
write();
|
||||
const end = baseWriter.getTextPos();
|
||||
escapes = append(escapes ||= [], { newText: escaped, span: { start, length: end - start } });
|
||||
}
|
||||
else {
|
||||
write();
|
||||
}
|
||||
}
|
||||
|
||||
/* Snippet-escaping version of `printer.printList`. */
|
||||
function printSnippetList(
|
||||
format: ListFormat,
|
||||
list: NodeArray<Node>,
|
||||
sourceFile: SourceFile | undefined,
|
||||
): string {
|
||||
const unescaped = printUnescapedSnippetList(format, list, sourceFile);
|
||||
return escapes ? textChanges.applyChanges(unescaped, escapes) : unescaped;
|
||||
}
|
||||
|
||||
function printUnescapedSnippetList(
|
||||
format: ListFormat,
|
||||
list: NodeArray<Node>,
|
||||
sourceFile: SourceFile | undefined,
|
||||
): string {
|
||||
escapes = undefined;
|
||||
writer.clear();
|
||||
printer.writeList(format, list, sourceFile, writer);
|
||||
return writer.getText();
|
||||
@@ -1236,7 +1287,7 @@ namespace ts.Completions {
|
||||
formatContext: formatting.FormatContext,
|
||||
): string {
|
||||
const syntheticFile = {
|
||||
text: printSnippetList(
|
||||
text: printUnescapedSnippetList(
|
||||
format,
|
||||
list,
|
||||
sourceFile),
|
||||
@@ -1256,7 +1307,11 @@ namespace ts.Completions {
|
||||
/* delta */ 0,
|
||||
{ ...formatContext, options: formatOptions });
|
||||
});
|
||||
return textChanges.applyChanges(syntheticFile.text, changes);
|
||||
|
||||
const allChanges = escapes
|
||||
? stableSort(concatenate(changes, escapes), (a, b) => compareTextSpans(a.span, b.span))
|
||||
: changes;
|
||||
return textChanges.applyChanges(syntheticFile.text, allChanges);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1805,6 +1860,7 @@ namespace ts.Completions {
|
||||
readonly isRightOfOpenTag: boolean;
|
||||
readonly importCompletionNode?: Node;
|
||||
readonly hasUnresolvedAutoImports?: boolean;
|
||||
readonly flags: CompletionInfoFlags;
|
||||
}
|
||||
type Request =
|
||||
| { readonly kind: CompletionDataKind.JsDocTagName | CompletionDataKind.JsDocTag }
|
||||
@@ -1989,6 +2045,7 @@ namespace ts.Completions {
|
||||
let location = getTouchingPropertyName(sourceFile, position);
|
||||
let keywordFilters = KeywordCompletionFilters.None;
|
||||
let isNewIdentifierLocation = false;
|
||||
let flags = CompletionInfoFlags.None;
|
||||
|
||||
if (contextToken) {
|
||||
const importStatementCompletion = getImportStatementCompletionInfo(contextToken);
|
||||
@@ -2009,6 +2066,7 @@ namespace ts.Completions {
|
||||
// is not backward compatible with older clients, the language service defaults to disabling it, allowing newer clients
|
||||
// to opt in with the `includeCompletionsForImportStatements` user preference.
|
||||
importCompletionNode = importStatementCompletion.replacementNode;
|
||||
flags |= CompletionInfoFlags.IsImportStatementCompletion;
|
||||
}
|
||||
// Bail out if this is a known invalid completion location
|
||||
if (!importCompletionNode && isCompletionListBlocker(contextToken)) {
|
||||
@@ -2216,6 +2274,7 @@ namespace ts.Completions {
|
||||
isRightOfOpenTag,
|
||||
importCompletionNode,
|
||||
hasUnresolvedAutoImports,
|
||||
flags,
|
||||
};
|
||||
|
||||
type JSDocTagWithTypeExpression = JSDocParameterTag | JSDocPropertyTag | JSDocReturnTag | JSDocTypeTag | JSDocTypedefTag | JSDocTemplateTag;
|
||||
@@ -2396,7 +2455,7 @@ namespace ts.Completions {
|
||||
moduleSymbol,
|
||||
symbol: firstAccessibleSymbol,
|
||||
targetFlags: skipAlias(firstAccessibleSymbol, typeChecker).flags,
|
||||
}], sourceFile, program, host, preferences) || {};
|
||||
}], firstAccessibleSymbol.name, position, isValidTypeOnlyAliasUseSite(location), sourceFile, program, host, preferences) || {};
|
||||
|
||||
if (moduleSpecifier) {
|
||||
const origin: SymbolOriginInfoResolvedExport = {
|
||||
@@ -2656,6 +2715,7 @@ namespace ts.Completions {
|
||||
return;
|
||||
}
|
||||
|
||||
flags |= CompletionInfoFlags.MayIncludeAutoImports;
|
||||
// import { type | -> token text should be blank
|
||||
const isAfterTypeOnlyImportSpecifierModifier = previousToken === contextToken
|
||||
&& importCompletionNode
|
||||
@@ -2675,8 +2735,10 @@ namespace ts.Completions {
|
||||
host,
|
||||
program,
|
||||
sourceFile,
|
||||
position,
|
||||
preferences,
|
||||
!!importCompletionNode,
|
||||
isValidTypeOnlyAliasUseSite(location),
|
||||
context => {
|
||||
exportInfo.search(
|
||||
sourceFile.path,
|
||||
@@ -2698,14 +2760,34 @@ namespace ts.Completions {
|
||||
return;
|
||||
}
|
||||
|
||||
const defaultExportInfo = find(info, isImportableExportInfo);
|
||||
if (!defaultExportInfo) {
|
||||
// Do a relatively cheap check to bail early if all re-exports are non-importable
|
||||
// due to file location or package.json dependency filtering. For non-node16+
|
||||
// module resolution modes, getting past this point guarantees that we'll be
|
||||
// able to generate a suitable module specifier, so we can safely show a completion,
|
||||
// even if we defer computing the module specifier.
|
||||
const firstImportableExportInfo = find(info, isImportableExportInfo);
|
||||
if (!firstImportableExportInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't need to resolve module specifiers, we can use any re-export that is importable at all
|
||||
// (We need to ensure that at least one is importable to show a completion.)
|
||||
const { exportInfo = defaultExportInfo, moduleSpecifier } = context.tryResolve(info, isFromAmbientModule) || {};
|
||||
// In node16+, module specifier resolution can fail due to modules being blocked
|
||||
// by package.json `exports`. If that happens, don't show a completion item.
|
||||
// N.B. in this resolution mode we always try to resolve module specifiers here,
|
||||
// because we have to know now if it's going to fail so we can omit the completion
|
||||
// from the list.
|
||||
const result = context.tryResolve(info, symbolName, isFromAmbientModule) || {};
|
||||
if (result === "failed") return;
|
||||
|
||||
// If we skipped resolving module specifiers, our selection of which ExportInfo
|
||||
// to use here is arbitrary, since the info shown in the completion list derived from
|
||||
// it should be identical regardless of which one is used. During the subsequent
|
||||
// `CompletionEntryDetails` request, we'll get all the ExportInfos again and pick
|
||||
// the best one based on the module specifier it produces.
|
||||
let exportInfo = firstImportableExportInfo, moduleSpecifier;
|
||||
if (result !== "skipped") {
|
||||
({ exportInfo = firstImportableExportInfo, moduleSpecifier } = result);
|
||||
}
|
||||
|
||||
const isDefaultExport = exportInfo.exportKind === ExportKind.Default;
|
||||
const symbol = isDefaultExport && getLocalSymbolForExportDefault(exportInfo.symbol) || exportInfo.symbol;
|
||||
|
||||
@@ -2723,7 +2805,9 @@ namespace ts.Completions {
|
||||
}
|
||||
);
|
||||
|
||||
hasUnresolvedAutoImports = context.resolutionLimitExceeded();
|
||||
hasUnresolvedAutoImports = context.skippedAny();
|
||||
flags |= context.resolvedAny() ? CompletionInfoFlags.ResolvedModuleSpecifiers : 0;
|
||||
flags |= context.resolvedBeyondLimit() ? CompletionInfoFlags.ResolvedModuleSpecifiersBeyondLimit : 0;
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2793,6 +2877,7 @@ namespace ts.Completions {
|
||||
return;
|
||||
}
|
||||
const origin: SymbolOriginInfoObjectLiteralMethod = { kind: SymbolOriginInfoKind.ObjectLiteralMethod, ...entryProps };
|
||||
flags |= CompletionInfoFlags.MayIncludeMethodSnippets;
|
||||
symbolToOriginInfoMap[symbols.length] = origin;
|
||||
symbols.push(member);
|
||||
});
|
||||
@@ -3024,7 +3109,7 @@ namespace ts.Completions {
|
||||
// through type declaration or inference.
|
||||
// Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed -
|
||||
// type of parameter will flow in from the contextual type of the function
|
||||
let canGetType = hasInitializer(rootDeclaration) || hasType(rootDeclaration) || rootDeclaration.parent.parent.kind === SyntaxKind.ForOfStatement;
|
||||
let canGetType = hasInitializer(rootDeclaration) || !!getEffectiveTypeAnnotationNode(rootDeclaration) || rootDeclaration.parent.parent.kind === SyntaxKind.ForOfStatement;
|
||||
if (!canGetType && rootDeclaration.kind === SyntaxKind.Parameter) {
|
||||
if (isExpression(rootDeclaration.parent)) {
|
||||
canGetType = !!typeChecker.getContextualType(rootDeclaration.parent as Expression);
|
||||
|
||||
@@ -93,6 +93,8 @@ namespace ts {
|
||||
return highlightSpans(getAsyncAndAwaitOccurrences(node));
|
||||
case SyntaxKind.YieldKeyword:
|
||||
return highlightSpans(getYieldOccurrences(node));
|
||||
case SyntaxKind.InKeyword:
|
||||
return undefined;
|
||||
default:
|
||||
return isModifierKind(node.kind) && (isDeclaration(node.parent) || isVariableStatement(node.parent))
|
||||
? highlightSpans(getModifierOccurrences(node.kind, node.parent))
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace ts {
|
||||
* shape of a the resulting SourceFile. This allows the DocumentRegistry to store
|
||||
* multiple copies of the same file for different compilation settings. A minimal
|
||||
* resolution cache is needed to fully define a source file's shape when
|
||||
* the compilation settings include `module: node12`+, so providing a cache host
|
||||
* the compilation settings include `module: node16`+, so providing a cache host
|
||||
* object should be preferred. A common host is a language service `ConfiguredProject`.
|
||||
* @param scriptSnapshot Text of the file. Only used if the file was not found
|
||||
* in the registry and a new one was created.
|
||||
@@ -58,7 +58,7 @@ namespace ts {
|
||||
* shape of a the resulting SourceFile. This allows the DocumentRegistry to store
|
||||
* multiple copies of the same file for different compilation settings. A minimal
|
||||
* resolution cache is needed to fully define a source file's shape when
|
||||
* the compilation settings include `module: node12`+, so providing a cache host
|
||||
* the compilation settings include `module: node16`+, so providing a cache host
|
||||
* object should be preferred. A common host is a language service `ConfiguredProject`.
|
||||
* @param scriptSnapshot Text of the file.
|
||||
* @param version Current version of the file.
|
||||
|
||||
@@ -291,8 +291,8 @@ namespace ts {
|
||||
): boolean {
|
||||
if (from === to) return false;
|
||||
const cachedResult = moduleSpecifierCache?.get(from.path, to.path, preferences, {});
|
||||
if (cachedResult?.isAutoImportable !== undefined) {
|
||||
return cachedResult.isAutoImportable;
|
||||
if (cachedResult?.isBlockedByPackageJsonDependencies !== undefined) {
|
||||
return !cachedResult.isBlockedByPackageJsonDependencies;
|
||||
}
|
||||
|
||||
const getCanonicalFileName = hostGetCanonicalFileName(moduleSpecifierResolutionHost);
|
||||
@@ -313,7 +313,7 @@ namespace ts {
|
||||
|
||||
if (packageJsonFilter) {
|
||||
const isAutoImportable = hasImportablePath && packageJsonFilter.allowsImportingSourceFile(to, moduleSpecifierResolutionHost);
|
||||
moduleSpecifierCache?.setIsAutoImportable(from.path, to.path, preferences, {}, isAutoImportable);
|
||||
moduleSpecifierCache?.setBlockedByPackageJsonDependencies(from.path, to.path, preferences, {}, !isAutoImportable);
|
||||
return isAutoImportable;
|
||||
}
|
||||
|
||||
@@ -381,38 +381,45 @@ namespace ts {
|
||||
host.log?.("getExportInfoMap: cache miss or empty; calculating new results");
|
||||
const compilerOptions = program.getCompilerOptions();
|
||||
let moduleCount = 0;
|
||||
forEachExternalModuleToImportFrom(program, host, /*useAutoImportProvider*/ true, (moduleSymbol, moduleFile, program, isFromPackageJson) => {
|
||||
if (++moduleCount % 100 === 0) cancellationToken?.throwIfCancellationRequested();
|
||||
const seenExports = new Map<__String, true>();
|
||||
const checker = program.getTypeChecker();
|
||||
const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions);
|
||||
// Note: I think we shouldn't actually see resolved module symbols here, but weird merges
|
||||
// can cause it to happen: see 'completionsImport_mergedReExport.ts'
|
||||
if (defaultInfo && isImportableSymbol(defaultInfo.symbol, checker)) {
|
||||
cache.add(
|
||||
importingFile.path,
|
||||
defaultInfo.symbol,
|
||||
defaultInfo.exportKind === ExportKind.Default ? InternalSymbolName.Default : InternalSymbolName.ExportEquals,
|
||||
moduleSymbol,
|
||||
moduleFile,
|
||||
defaultInfo.exportKind,
|
||||
isFromPackageJson,
|
||||
checker);
|
||||
}
|
||||
checker.forEachExportAndPropertyOfModule(moduleSymbol, (exported, key) => {
|
||||
if (exported !== defaultInfo?.symbol && isImportableSymbol(exported, checker) && addToSeen(seenExports, key)) {
|
||||
try {
|
||||
forEachExternalModuleToImportFrom(program, host, /*useAutoImportProvider*/ true, (moduleSymbol, moduleFile, program, isFromPackageJson) => {
|
||||
if (++moduleCount % 100 === 0) cancellationToken?.throwIfCancellationRequested();
|
||||
const seenExports = new Map<__String, true>();
|
||||
const checker = program.getTypeChecker();
|
||||
const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions);
|
||||
// Note: I think we shouldn't actually see resolved module symbols here, but weird merges
|
||||
// can cause it to happen: see 'completionsImport_mergedReExport.ts'
|
||||
if (defaultInfo && isImportableSymbol(defaultInfo.symbol, checker)) {
|
||||
cache.add(
|
||||
importingFile.path,
|
||||
exported,
|
||||
key,
|
||||
defaultInfo.symbol,
|
||||
defaultInfo.exportKind === ExportKind.Default ? InternalSymbolName.Default : InternalSymbolName.ExportEquals,
|
||||
moduleSymbol,
|
||||
moduleFile,
|
||||
ExportKind.Named,
|
||||
defaultInfo.exportKind,
|
||||
isFromPackageJson,
|
||||
checker);
|
||||
}
|
||||
checker.forEachExportAndPropertyOfModule(moduleSymbol, (exported, key) => {
|
||||
if (exported !== defaultInfo?.symbol && isImportableSymbol(exported, checker) && addToSeen(seenExports, key)) {
|
||||
cache.add(
|
||||
importingFile.path,
|
||||
exported,
|
||||
key,
|
||||
moduleSymbol,
|
||||
moduleFile,
|
||||
ExportKind.Named,
|
||||
isFromPackageJson,
|
||||
checker);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
// Ensure cache is reset if operation is cancelled
|
||||
cache.clear();
|
||||
throw err;
|
||||
}
|
||||
|
||||
host.log?.(`getExportInfoMap: done in ${timestamp() - start} ms`);
|
||||
return cache;
|
||||
|
||||
@@ -691,6 +691,10 @@ namespace ts.formatting {
|
||||
isListItem: boolean,
|
||||
isFirstListItem?: boolean): number {
|
||||
|
||||
if (nodeIsMissing(child)) {
|
||||
return inheritedIndentation;
|
||||
}
|
||||
|
||||
const childStartPos = child.getStart(sourceFile);
|
||||
|
||||
const childStartLine = sourceFile.getLineAndCharacterOfPosition(childStartPos).line;
|
||||
@@ -778,6 +782,13 @@ namespace ts.formatting {
|
||||
|
||||
let listDynamicIndentation = parentDynamicIndentation;
|
||||
let startLine = parentStartLine;
|
||||
// node range is outside the target range - do not dive inside
|
||||
if (!rangeOverlapsWithStartEnd(originalRange, nodes.pos, nodes.end)) {
|
||||
if (nodes.end < originalRange.pos) {
|
||||
formattingScanner.skipToEndOf(nodes);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (listStartToken !== SyntaxKind.Unknown) {
|
||||
// introduce a new indentation scope for lists (including list start and end tokens)
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace ts.formatting {
|
||||
readEOFTokenRange(): TextRangeWithKind;
|
||||
getCurrentLeadingTrivia(): TextRangeWithKind[] | undefined;
|
||||
lastTrailingTriviaWasNewLine(): boolean;
|
||||
skipToEndOf(node: Node): void;
|
||||
skipToEndOf(node: Node | NodeArray<Node>): void;
|
||||
skipToStartOf(node: Node): void;
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ namespace ts.formatting {
|
||||
return tokenInfo;
|
||||
}
|
||||
|
||||
function skipToEndOf(node: Node): void {
|
||||
function skipToEndOf(node: Node | NodeArray<Node>): void {
|
||||
scanner.setTextPos(node.end);
|
||||
savedPos = scanner.getStartPos();
|
||||
lastScanAction = undefined;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* @internal */
|
||||
namespace ts.GoToDefinition {
|
||||
export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile, position: number, searchOtherFilesOnly?: boolean): readonly DefinitionInfo[] | undefined {
|
||||
export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile, position: number, searchOtherFilesOnly?: boolean, stopAtAlias?: boolean): readonly DefinitionInfo[] | undefined {
|
||||
const resolvedRef = getReferenceAtPosition(sourceFile, position, program);
|
||||
const fileReferenceDefinition = resolvedRef && [getDefinitionInfoForFileReference(resolvedRef.reference.fileName, resolvedRef.fileName, resolvedRef.unverified)] || emptyArray;
|
||||
if (resolvedRef?.file) {
|
||||
@@ -28,7 +28,7 @@ namespace ts.GoToDefinition {
|
||||
|
||||
if (isStaticModifier(node) && isClassStaticBlockDeclaration(node.parent)) {
|
||||
const classDecl = node.parent.parent;
|
||||
const { symbol, failedAliasResolution } = getSymbol(classDecl, typeChecker);
|
||||
const { symbol, failedAliasResolution } = getSymbol(classDecl, typeChecker, stopAtAlias);
|
||||
|
||||
const staticBlocks = filter(classDecl.members, isClassStaticBlockDeclaration);
|
||||
const containerName = symbol ? typeChecker.symbolToString(symbol, classDecl) : "";
|
||||
@@ -40,7 +40,7 @@ namespace ts.GoToDefinition {
|
||||
});
|
||||
}
|
||||
|
||||
let { symbol, failedAliasResolution } = getSymbol(node, typeChecker);
|
||||
let { symbol, failedAliasResolution } = getSymbol(node, typeChecker, stopAtAlias);
|
||||
let fallbackNode = node;
|
||||
|
||||
if (searchOtherFilesOnly && failedAliasResolution) {
|
||||
@@ -48,7 +48,7 @@ namespace ts.GoToDefinition {
|
||||
const importDeclaration = forEach([node, ...symbol?.declarations || emptyArray], n => findAncestor(n, isAnyImportOrBareOrAccessedRequire));
|
||||
const moduleSpecifier = importDeclaration && tryGetModuleSpecifierFromDeclaration(importDeclaration);
|
||||
if (moduleSpecifier) {
|
||||
({ symbol, failedAliasResolution } = getSymbol(moduleSpecifier, typeChecker));
|
||||
({ symbol, failedAliasResolution } = getSymbol(moduleSpecifier, typeChecker, stopAtAlias));
|
||||
fallbackNode = moduleSpecifier;
|
||||
}
|
||||
}
|
||||
@@ -235,7 +235,7 @@ namespace ts.GoToDefinition {
|
||||
return definitionFromType(typeChecker.getTypeAtLocation(node.parent), typeChecker, node.parent, /*failedAliasResolution*/ false);
|
||||
}
|
||||
|
||||
const { symbol, failedAliasResolution } = getSymbol(node, typeChecker);
|
||||
const { symbol, failedAliasResolution } = getSymbol(node, typeChecker, /*stopAtAlias*/ false);
|
||||
if (!symbol) return undefined;
|
||||
|
||||
const typeAtLocation = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
|
||||
@@ -292,14 +292,14 @@ namespace ts.GoToDefinition {
|
||||
return mapDefined(checker.getIndexInfosAtLocation(node), info => info.declaration && createDefinitionFromSignatureDeclaration(checker, info.declaration));
|
||||
}
|
||||
|
||||
function getSymbol(node: Node, checker: TypeChecker) {
|
||||
function getSymbol(node: Node, checker: TypeChecker, stopAtAlias: boolean | undefined) {
|
||||
const symbol = checker.getSymbolAtLocation(node);
|
||||
// If this is an alias, and the request came at the declaration location
|
||||
// get the aliased symbol instead. This allows for goto def on an import e.g.
|
||||
// import {A, B} from "mod";
|
||||
// to jump to the implementation directly.
|
||||
let failedAliasResolution = false;
|
||||
if (symbol?.declarations && symbol.flags & SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
|
||||
if (symbol?.declarations && symbol.flags & SymbolFlags.Alias && !stopAtAlias && shouldSkipAlias(node, symbol.declarations[0])) {
|
||||
const aliased = checker.getAliasedSymbol(symbol);
|
||||
if (aliased.declarations) {
|
||||
return { symbol: aliased };
|
||||
|
||||
@@ -1768,9 +1768,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
/// Goto definition
|
||||
function getDefinitionAtPosition(fileName: string, position: number, searchOtherFilesOnly?: boolean): readonly DefinitionInfo[] | undefined {
|
||||
function getDefinitionAtPosition(fileName: string, position: number, searchOtherFilesOnly?: boolean, stopAtAlias?: boolean): readonly DefinitionInfo[] | undefined {
|
||||
synchronizeHostData();
|
||||
return GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position, searchOtherFilesOnly);
|
||||
return GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position, searchOtherFilesOnly, stopAtAlias);
|
||||
}
|
||||
|
||||
function getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan | undefined {
|
||||
|
||||
@@ -377,12 +377,12 @@ namespace ts.Completions.StringCompletions {
|
||||
|
||||
function isEmitResolutionKindUsingNodeModules(compilerOptions: CompilerOptions): boolean {
|
||||
return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs ||
|
||||
getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node12 ||
|
||||
getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 ||
|
||||
getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext;
|
||||
}
|
||||
|
||||
function isEmitModuleResolutionRespectingExportMaps(compilerOptions: CompilerOptions) {
|
||||
return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node12 ||
|
||||
return getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node16 ||
|
||||
getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeNext;
|
||||
}
|
||||
|
||||
|
||||
+18
-2
@@ -267,7 +267,7 @@ namespace ts {
|
||||
|
||||
/*
|
||||
* Unlike `realpath and `readDirectory`, `readFile` and `fileExists` are now _required_
|
||||
* to properly acquire and setup source files under module: node12+ modes.
|
||||
* to properly acquire and setup source files under module: node16+ modes.
|
||||
*/
|
||||
readFile(path: string, encoding?: string): string | undefined;
|
||||
fileExists(path: string): boolean;
|
||||
@@ -474,7 +474,10 @@ namespace ts {
|
||||
|
||||
/*@internal*/
|
||||
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
||||
getDefinitionAtPosition(fileName: string, position: number, searchOtherFilesOnly: boolean): readonly DefinitionInfo[] | undefined;
|
||||
getDefinitionAtPosition(fileName: string, position: number, searchOtherFilesOnly: false, stopAtAlias: boolean): readonly DefinitionInfo[] | undefined;
|
||||
/*@internal*/
|
||||
// eslint-disable-next-line @typescript-eslint/unified-signatures
|
||||
getDefinitionAtPosition(fileName: string, position: number, searchOtherFilesOnly: boolean, stopAtAlias: false): readonly DefinitionInfo[] | undefined;
|
||||
getDefinitionAtPosition(fileName: string, position: number): readonly DefinitionInfo[] | undefined;
|
||||
getDefinitionAndBoundSpan(fileName: string, position: number): DefinitionInfoAndBoundSpan | undefined;
|
||||
getTypeDefinitionAtPosition(fileName: string, position: number): readonly DefinitionInfo[] | undefined;
|
||||
@@ -1176,7 +1179,20 @@ namespace ts {
|
||||
argumentCount: number;
|
||||
}
|
||||
|
||||
// Do not change existing values, as they exist in telemetry.
|
||||
export const enum CompletionInfoFlags {
|
||||
None = 0,
|
||||
MayIncludeAutoImports = 1 << 0,
|
||||
IsImportStatementCompletion = 1 << 1,
|
||||
IsContinuation = 1 << 2,
|
||||
ResolvedModuleSpecifiers = 1 << 3,
|
||||
ResolvedModuleSpecifiersBeyondLimit = 1 << 4,
|
||||
MayIncludeMethodSnippets = 1 << 5,
|
||||
}
|
||||
|
||||
export interface CompletionInfo {
|
||||
/** For performance telemetry. */
|
||||
flags?: CompletionInfoFlags;
|
||||
/** Not true for all global completions. This will be true if the enclosing scope matches a few syntax kinds. See `isSnippetScope`. */
|
||||
isGlobalCompletion: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
|
||||
@@ -1928,6 +1928,14 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function moduleResolutionRespectsExports(moduleResolution: ModuleResolutionKind): boolean {
|
||||
return moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext;
|
||||
}
|
||||
|
||||
export function moduleResolutionUsesNodeModules(moduleResolution: ModuleResolutionKind): boolean {
|
||||
return moduleResolution === ModuleResolutionKind.NodeJs || moduleResolution >= ModuleResolutionKind.Node16 && moduleResolution <= ModuleResolutionKind.NodeNext;
|
||||
}
|
||||
|
||||
export function makeImportIfNecessary(defaultImport: Identifier | undefined, namedImports: readonly ImportSpecifier[] | undefined, moduleSpecifier: string, quotePreference: QuotePreference): ImportDeclaration | undefined {
|
||||
return defaultImport || namedImports && namedImports.length ? makeImport(defaultImport, namedImports, moduleSpecifier, quotePreference) : undefined;
|
||||
}
|
||||
|
||||
@@ -155,6 +155,7 @@
|
||||
"unittests/tsc/incremental.ts",
|
||||
"unittests/tsc/listFilesOnly.ts",
|
||||
"unittests/tsc/projectReferences.ts",
|
||||
"unittests/tsc/redirect.ts",
|
||||
"unittests/tsc/runWithoutArgs.ts",
|
||||
"unittests/tscWatch/consoleClearing.ts",
|
||||
"unittests/tscWatch/emit.ts",
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext', 'node12', 'nodenext'.",
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext', 'node16', 'nodenext'.",
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic', 'node12', 'nodenext'.",
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic', 'node16', 'nodenext'.",
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
|
||||
@@ -215,6 +215,7 @@ namespace ts {
|
||||
extension: Extension.Ts,
|
||||
},
|
||||
failedLookupLocations: [],
|
||||
resolutionDiagnostics: [],
|
||||
});
|
||||
assert.isDefined(cache.get("/sub"));
|
||||
assert.isUndefined(cache.get("/"));
|
||||
@@ -228,6 +229,7 @@ namespace ts {
|
||||
extension: Extension.Ts,
|
||||
},
|
||||
failedLookupLocations: [],
|
||||
resolutionDiagnostics: [],
|
||||
});
|
||||
assert.isDefined(cache.get("/sub/dir/foo"));
|
||||
assert.isDefined(cache.get("/sub/dir"));
|
||||
@@ -243,6 +245,7 @@ namespace ts {
|
||||
extension: Extension.Ts,
|
||||
},
|
||||
failedLookupLocations: [],
|
||||
resolutionDiagnostics: [],
|
||||
});
|
||||
assert.isDefined(cache.get("/foo/bar"));
|
||||
assert.isDefined(cache.get("/foo"));
|
||||
@@ -257,6 +260,7 @@ namespace ts {
|
||||
extension: Extension.Ts,
|
||||
},
|
||||
failedLookupLocations: [],
|
||||
resolutionDiagnostics: [],
|
||||
});
|
||||
assert.isDefined(cache.get("/foo"));
|
||||
assert.isUndefined(cache.get("/"));
|
||||
@@ -270,6 +274,7 @@ namespace ts {
|
||||
extension: Extension.Ts,
|
||||
},
|
||||
failedLookupLocations: [],
|
||||
resolutionDiagnostics: [],
|
||||
});
|
||||
assert.isDefined(cache.get("c:/foo"));
|
||||
assert.isDefined(cache.get("c:/"));
|
||||
@@ -279,6 +284,7 @@ namespace ts {
|
||||
cache.set("/foo/bar/baz", {
|
||||
resolvedModule: undefined,
|
||||
failedLookupLocations: [],
|
||||
resolutionDiagnostics: [],
|
||||
});
|
||||
assert.isDefined(cache.get("/foo/bar/baz"));
|
||||
assert.isDefined(cache.get("/foo/bar"));
|
||||
|
||||
@@ -130,6 +130,26 @@ describe("unittests:: Public APIs:: getTypeAtLocation", () => {
|
||||
const type = checker.getTypeAtLocation(file);
|
||||
assert.equal(type.flags, ts.TypeFlags.Any);
|
||||
});
|
||||
|
||||
it("returns an errorType for VariableDeclaration with BindingPattern name", () => {
|
||||
const content = "const foo = [1];\n" + "const [a] = foo;";
|
||||
|
||||
const host = new fakes.CompilerHost(vfs.createFromFileSystem(
|
||||
Harness.IO,
|
||||
/*ignoreCase*/ true,
|
||||
{ documents: [new documents.TextDocument("/file.ts", content)], cwd: "/" }));
|
||||
|
||||
const program = ts.createProgram({
|
||||
host,
|
||||
rootNames: ["/file.ts"],
|
||||
options: { noLib: true }
|
||||
});
|
||||
|
||||
const checker = program.getTypeChecker();
|
||||
const file = program.getSourceFile("/file.ts")!;
|
||||
const [declaration] = (ts.findLast(file.statements, ts.isVariableStatement) as ts.VariableStatement).declarationList.declarations;
|
||||
assert.equal(checker.getTypeAtLocation(declaration).flags, ts.TypeFlags.Any);
|
||||
});
|
||||
});
|
||||
|
||||
describe("unittests:: Public APIs:: validateLocaleAndSetLanguage", () => {
|
||||
|
||||
@@ -78,26 +78,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function getTime() {
|
||||
let currentTime = 100;
|
||||
return { tick, time, touch };
|
||||
|
||||
function tick() {
|
||||
currentTime += 60_000;
|
||||
}
|
||||
|
||||
function time() {
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
function touch(fs: vfs.FileSystem, path: string) {
|
||||
if (!fs.statSync(path).isFile()) {
|
||||
throw new Error(`File ${path} does not exist`);
|
||||
}
|
||||
fs.utimesSync(path, new Date(time()), new Date(time()));
|
||||
}
|
||||
}
|
||||
|
||||
export const libContent = `${VirtualFS.libFile.content}
|
||||
interface ReadonlyArray<T> {}
|
||||
declare const console: { log(msg: any): void; };`;
|
||||
@@ -154,26 +134,6 @@ interface Symbol {
|
||||
fs.makeReadonly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the FS mountuing existing fs's /src and /lib folder
|
||||
*/
|
||||
export function getFsWithTime(baseFs: vfs.FileSystem) {
|
||||
const { time, tick } = getTime();
|
||||
const host = new fakes.System(baseFs) as any as vfs.FileSystemResolverHost;
|
||||
host.getWorkspaceRoot = notImplemented;
|
||||
const resolver = vfs.createResolver(host);
|
||||
const fs = new vfs.FileSystem(/*ignoreCase*/ true, {
|
||||
files: {
|
||||
["/src"]: new vfs.Mount("/src", resolver),
|
||||
["/lib"]: new vfs.Mount("/lib", resolver)
|
||||
},
|
||||
cwd: "/",
|
||||
meta: { defaultLibLocation: "/lib" },
|
||||
time
|
||||
});
|
||||
return { fs, time, tick };
|
||||
}
|
||||
|
||||
export function verifyOutputsPresent(fs: vfs.FileSystem, outputs: readonly string[]) {
|
||||
for (const output of outputs) {
|
||||
assert(fs.existsSync(output), `Expect file ${output} to exist`);
|
||||
@@ -249,7 +209,7 @@ interface Symbol {
|
||||
affectedFilesPendingEmit?: readonly ReadableProgramBuilderInfoFilePendingEmit[];
|
||||
}
|
||||
type ReadableBuildInfo = Omit<BuildInfo, "program"> & { program: ReadableProgramBuildInfo | undefined; size: number; };
|
||||
function generateBuildInfoProgramBaseline(sys: System, originalWriteFile: System["writeFile"], buildInfoPath: string, buildInfo: BuildInfo) {
|
||||
function generateBuildInfoProgramBaseline(sys: System, buildInfoPath: string, buildInfo: BuildInfo) {
|
||||
const fileInfos: ReadableProgramBuildInfo["fileInfos"] = {};
|
||||
buildInfo.program?.fileInfos.forEach((fileInfo, index) => fileInfos[toFileName(index + 1 as ProgramBuildInfoFileId)] = toBuilderStateFileInfo(fileInfo));
|
||||
const fileNamesList = buildInfo.program?.fileIdsList?.map(fileIdsListId => fileIdsListId.map(toFileName));
|
||||
@@ -280,7 +240,7 @@ interface Symbol {
|
||||
size: getBuildInfoText({ ...buildInfo, version }).length,
|
||||
};
|
||||
// For now its just JSON.stringify
|
||||
originalWriteFile.call(sys, `${buildInfoPath}.readable.baseline.txt`, JSON.stringify(result, /*replacer*/ undefined, 2));
|
||||
sys.writeFile(`${buildInfoPath}.readable.baseline.txt`, JSON.stringify(result, /*replacer*/ undefined, 2));
|
||||
|
||||
function toFileName(fileId: ProgramBuildInfoFileId) {
|
||||
return buildInfo.program!.fileNames[fileId - 1];
|
||||
@@ -306,16 +266,15 @@ interface Symbol {
|
||||
|
||||
export function baselineBuildInfo(
|
||||
options: CompilerOptions,
|
||||
sys: System & { writtenFiles: ReadonlyCollection<Path>; },
|
||||
sys: TscCompileSystem | tscWatch.WatchedSystem,
|
||||
originalReadCall?: System["readFile"],
|
||||
originalWriteFile?: System["writeFile"],
|
||||
) {
|
||||
const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options);
|
||||
if (!buildInfoPath || !sys.writtenFiles.has(toPathWithSystem(sys, buildInfoPath))) return;
|
||||
if (!buildInfoPath || !sys.writtenFiles!.has(toPathWithSystem(sys, buildInfoPath))) return;
|
||||
if (!sys.fileExists(buildInfoPath)) return;
|
||||
|
||||
const buildInfo = getBuildInfo((originalReadCall || sys.readFile).call(sys, buildInfoPath, "utf8")!);
|
||||
generateBuildInfoProgramBaseline(sys, originalWriteFile || sys.writeFile, buildInfoPath, buildInfo);
|
||||
generateBuildInfoProgramBaseline(sys, buildInfoPath, buildInfo);
|
||||
|
||||
if (!outFile(options)) return;
|
||||
const { jsFilePath, declarationFilePath } = getOutputPathsForBundle(options, /*forceDts*/ false);
|
||||
@@ -328,136 +287,173 @@ interface Symbol {
|
||||
generateBundleFileSectionInfo(sys, originalReadCall || sys.readFile, baselineRecorder, bundle.dts, declarationFilePath);
|
||||
baselineRecorder.Close();
|
||||
const text = baselineRecorder.lines.join("\r\n");
|
||||
(originalWriteFile || sys.writeFile).call(sys, `${buildInfoPath}.baseline.txt`, text);
|
||||
sys.writeFile(`${buildInfoPath}.baseline.txt`, text);
|
||||
}
|
||||
|
||||
interface VerifyTscEditCorrectnessInput {
|
||||
interface VerifyTscEditDiscrepanciesInput {
|
||||
index: number;
|
||||
scenario: TestTscCompile["scenario"];
|
||||
subScenario: TestTscCompile["subScenario"];
|
||||
baselines: string[] | undefined;
|
||||
commandLineArgs: TestTscCompile["commandLineArgs"];
|
||||
modifyFs: TestTscCompile["modifyFs"];
|
||||
editFs: TestTscEdit["modifyFs"];
|
||||
tick: () => void;
|
||||
baseFs: vfs.FileSystem;
|
||||
newSys: TscCompileSystem;
|
||||
cleanBuildDiscrepancies: TestTscEdit["cleanBuildDiscrepancies"];
|
||||
discrepancyExplanation: TestTscEdit["discrepancyExplanation"];
|
||||
}
|
||||
/** Verify that emit is same as clean build vs building after edit */
|
||||
function verifyTscEditCorrectness(input: () => VerifyTscEditCorrectnessInput, index: number, subScenario: TestTscCompile["subScenario"]) {
|
||||
it(`Verify emit output file text is same when built clean for incremental edit scenario at:: ${index} ${subScenario}`, () => {
|
||||
const {
|
||||
scenario, commandLineArgs, cleanBuildDiscrepancies,
|
||||
modifyFs, editFs,
|
||||
tick, baseFs, newSys
|
||||
} = input();
|
||||
const sys = testTscCompile({
|
||||
scenario,
|
||||
subScenario,
|
||||
fs: () => baseFs.makeReadonly(),
|
||||
commandLineArgs,
|
||||
modifyFs: fs => {
|
||||
tick();
|
||||
if (modifyFs) modifyFs(fs);
|
||||
editFs(fs);
|
||||
},
|
||||
disableUseFileVersionAsSignature: true,
|
||||
});
|
||||
const discrepancies = cleanBuildDiscrepancies?.();
|
||||
for (const outputFile of arrayFrom(sys.writtenFiles.keys())) {
|
||||
const cleanBuildText = sys.readFile(outputFile);
|
||||
const incrementalBuildText = newSys.readFile(outputFile);
|
||||
const descrepancyInClean = discrepancies?.get(outputFile);
|
||||
if (isBuildInfoFile(outputFile)) {
|
||||
// Check only presence and absence and not text as we will do that for readable baseline
|
||||
assert.isTrue(sys.fileExists(`${outputFile}.readable.baseline.txt`), `Readable baseline should be present in clean build:: File:: ${outputFile}`);
|
||||
assert.isTrue(newSys.fileExists(`${outputFile}.readable.baseline.txt`), `Readable baseline should be present in incremental build:: File:: ${outputFile}`);
|
||||
if (descrepancyInClean === undefined) {
|
||||
verifyPresenceAbsence(incrementalBuildText, cleanBuildText, `Incremental and clean tsbuildinfo file presence should match:: File:: ${outputFile}`);
|
||||
}
|
||||
else {
|
||||
verifyTextEqual(incrementalBuildText, cleanBuildText, descrepancyInClean, `File: ${outputFile}`);
|
||||
}
|
||||
}
|
||||
else if (!fileExtensionIs(outputFile, ".tsbuildinfo.readable.baseline.txt")) {
|
||||
verifyTextEqual(incrementalBuildText, cleanBuildText, descrepancyInClean, `File: ${outputFile}`);
|
||||
}
|
||||
else if (incrementalBuildText !== cleanBuildText) {
|
||||
// Verify build info without affectedFilesPendingEmit
|
||||
const { buildInfo: incrementalBuildInfo, readableBuildInfo: incrementalReadableBuildInfo } = getBuildInfoForIncrementalCorrectnessCheck(incrementalBuildText);
|
||||
const { buildInfo: cleanBuildInfo, readableBuildInfo: cleanReadableBuildInfo } = getBuildInfoForIncrementalCorrectnessCheck(cleanBuildText);
|
||||
verifyTextEqual(incrementalBuildInfo, cleanBuildInfo, descrepancyInClean, `TsBuild info text without affectedFilesPendingEmit ${subScenario}:: ${outputFile}::\nIncremental buildInfoText:: ${incrementalBuildText}\nClean buildInfoText:: ${cleanBuildText}`);
|
||||
if (descrepancyInClean === undefined) {
|
||||
// Verify file info sigantures
|
||||
verifyMapLike(
|
||||
incrementalReadableBuildInfo?.program?.fileInfos,
|
||||
cleanReadableBuildInfo?.program?.fileInfos,
|
||||
(key, incrementalFileInfo, cleanFileInfo) => {
|
||||
if (incrementalFileInfo.signature !== cleanFileInfo.signature && incrementalFileInfo.signature !== incrementalFileInfo.version) {
|
||||
assert.fail(`Incremental signature should either be dts signature or file version for File:: ${key}:: Incremental:: ${JSON.stringify(incrementalFileInfo)}, Clean:: ${JSON.stringify(cleanFileInfo)}}`);
|
||||
}
|
||||
},
|
||||
`FileInfos:: File:: ${outputFile}`
|
||||
);
|
||||
// Verify exportedModulesMap
|
||||
verifyMapLike(
|
||||
incrementalReadableBuildInfo?.program?.exportedModulesMap,
|
||||
cleanReadableBuildInfo?.program?.exportedModulesMap,
|
||||
(key, incrementalReferenceSet, cleanReferenceSet) => {
|
||||
if (!arrayIsEqualTo(incrementalReferenceSet, cleanReferenceSet) && !arrayIsEqualTo(incrementalReferenceSet, incrementalReadableBuildInfo!.program!.referencedMap![key])) {
|
||||
assert.fail(`Incremental Reference set should either be from dts or files reference map for File:: ${key}:: Incremental:: ${JSON.stringify(incrementalReferenceSet)}, Clean:: ${JSON.stringify(cleanReferenceSet)}, referenceMap:: ${JSON.stringify(incrementalReadableBuildInfo!.program!.referencedMap![key])}}`);
|
||||
}
|
||||
},
|
||||
`exportedModulesMap:: File:: ${outputFile}`
|
||||
);
|
||||
// Verify that incrementally pending affected file emit are in clean build since clean build can contain more files compared to incremental depending of noEmitOnError option
|
||||
if (incrementalReadableBuildInfo?.program?.affectedFilesPendingEmit) {
|
||||
assert.isDefined(cleanReadableBuildInfo?.program?.affectedFilesPendingEmit, `Incremental build contains affectedFilesPendingEmit, clean build should also have it: ${outputFile}::\nIncremental buildInfoText:: ${incrementalBuildText}\nClean buildInfoText:: ${cleanBuildText}`);
|
||||
let expectedIndex = 0;
|
||||
incrementalReadableBuildInfo.program.affectedFilesPendingEmit.forEach(([actualFile]) => {
|
||||
expectedIndex = findIndex(cleanReadableBuildInfo!.program!.affectedFilesPendingEmit!, ([expectedFile]) => actualFile === expectedFile, expectedIndex);
|
||||
assert.notEqual(expectedIndex, -1, `Incremental build contains ${actualFile} file as pending emit, clean build should also have it: ${outputFile}::\nIncremental buildInfoText:: ${incrementalBuildText}\nClean buildInfoText:: ${cleanBuildText}`);
|
||||
expectedIndex++;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function verifyTextEqual(incrementalText: string | undefined, cleanText: string | undefined, descrepancyInClean: CleanBuildDescrepancy | undefined, message: string) {
|
||||
if (descrepancyInClean === undefined) {
|
||||
assert.equal(incrementalText, cleanText, message);
|
||||
return;
|
||||
}
|
||||
switch (descrepancyInClean) {
|
||||
case CleanBuildDescrepancy.CleanFileTextDifferent:
|
||||
assert.isDefined(incrementalText, `Incremental file should be present:: ${message}`);
|
||||
assert.isDefined(cleanText, `Clean file should be present present:: ${message}`);
|
||||
assert.notEqual(incrementalText, cleanText, message);
|
||||
return;
|
||||
case CleanBuildDescrepancy.CleanFilePresent:
|
||||
assert.isUndefined(incrementalText, `Incremental file should be absent:: ${message}`);
|
||||
assert.isDefined(cleanText, `Clean file should be present:: ${message}`);
|
||||
return;
|
||||
default:
|
||||
Debug.assertNever(descrepancyInClean);
|
||||
}
|
||||
}
|
||||
|
||||
function verifyMapLike<T>(incremental: MapLike<T> | undefined, clean: MapLike<T> | undefined, verifyValue: (key: string, incrementalValue: T, cleanValue: T) => void, message: string) {
|
||||
verifyPresenceAbsence(incremental, clean, `Incremental and clean presence should match:: ${message}`);
|
||||
if (!incremental) return;
|
||||
const incrementalMap = new Map(getEntries(incremental));
|
||||
const cleanMap = new Map(getEntries(clean!));
|
||||
assert.equal(incrementalMap.size, cleanMap.size, `Incremental and clean size of map should match:: ${message}, Incremental keys: ${arrayFrom(incrementalMap.keys())} Clean: ${arrayFrom(cleanMap.keys())}${VirtualFS.getDiffInKeys(incrementalMap, arrayFrom(cleanMap.keys()))}`);
|
||||
cleanMap.forEach((cleanValue, key) => {
|
||||
assert.isTrue(incrementalMap.has(key), `Expected to contain ${key} in incremental map:: ${message}, Incremental keys: ${arrayFrom(incrementalMap.keys())}`);
|
||||
verifyValue(key, incrementalMap.get(key)!, cleanValue);
|
||||
});
|
||||
}
|
||||
function verifyTscEditDiscrepancies({
|
||||
index, scenario, subScenario, commandLineArgs,
|
||||
discrepancyExplanation, baselines,
|
||||
modifyFs, editFs, baseFs, newSys
|
||||
}: VerifyTscEditDiscrepanciesInput): string[] | undefined {
|
||||
const sys = testTscCompile({
|
||||
scenario,
|
||||
subScenario,
|
||||
fs: () => baseFs.makeReadonly(),
|
||||
commandLineArgs,
|
||||
modifyFs: fs => {
|
||||
if (modifyFs) modifyFs(fs);
|
||||
editFs(fs);
|
||||
},
|
||||
disableUseFileVersionAsSignature: true,
|
||||
});
|
||||
}
|
||||
let headerAdded = false;
|
||||
for (const outputFile of arrayFrom(sys.writtenFiles.keys())) {
|
||||
const cleanBuildText = sys.readFile(outputFile);
|
||||
const incrementalBuildText = newSys.readFile(outputFile);
|
||||
if (isBuildInfoFile(outputFile)) {
|
||||
// Check only presence and absence and not text as we will do that for readable baseline
|
||||
if (!sys.fileExists(`${outputFile}.readable.baseline.txt`)) addBaseline(`Readable baseline not present in clean build:: File:: ${outputFile}`);
|
||||
if (!newSys.fileExists(`${outputFile}.readable.baseline.txt`)) addBaseline(`Readable baseline not present in incremental build:: File:: ${outputFile}`);
|
||||
verifyPresenceAbsence(incrementalBuildText, cleanBuildText, `Incremental and clean tsbuildinfo file presence differs:: File:: ${outputFile}`);
|
||||
}
|
||||
else if (!fileExtensionIs(outputFile, ".tsbuildinfo.readable.baseline.txt")) {
|
||||
verifyTextEqual(incrementalBuildText, cleanBuildText, `File: ${outputFile}`);
|
||||
}
|
||||
else if (incrementalBuildText !== cleanBuildText) {
|
||||
// Verify build info without affectedFilesPendingEmit
|
||||
const { buildInfo: incrementalBuildInfo, readableBuildInfo: incrementalReadableBuildInfo } = getBuildInfoForIncrementalCorrectnessCheck(incrementalBuildText);
|
||||
const { buildInfo: cleanBuildInfo, readableBuildInfo: cleanReadableBuildInfo } = getBuildInfoForIncrementalCorrectnessCheck(cleanBuildText);
|
||||
verifyTextEqual(incrementalBuildInfo, cleanBuildInfo, `TsBuild info text without affectedFilesPendingEmit:: ${outputFile}::`);
|
||||
// Verify file info sigantures
|
||||
verifyMapLike(
|
||||
incrementalReadableBuildInfo?.program?.fileInfos,
|
||||
cleanReadableBuildInfo?.program?.fileInfos,
|
||||
(key, incrementalFileInfo, cleanFileInfo) => {
|
||||
if (incrementalFileInfo.signature !== cleanFileInfo.signature && incrementalFileInfo.signature !== incrementalFileInfo.version) {
|
||||
return [
|
||||
`Incremental signature is neither dts signature nor file version for File:: ${key}`,
|
||||
`Incremental:: ${JSON.stringify(incrementalFileInfo, /*replacer*/ undefined, 2)}`,
|
||||
`Clean:: ${JSON.stringify(cleanFileInfo, /*replacer*/ undefined, 2)}`
|
||||
];
|
||||
}
|
||||
},
|
||||
`FileInfos:: File:: ${outputFile}`
|
||||
);
|
||||
// Verify exportedModulesMap
|
||||
verifyMapLike(
|
||||
incrementalReadableBuildInfo?.program?.exportedModulesMap,
|
||||
cleanReadableBuildInfo?.program?.exportedModulesMap,
|
||||
(key, incrementalReferenceSet, cleanReferenceSet) => {
|
||||
if (!arrayIsEqualTo(incrementalReferenceSet, cleanReferenceSet) && !arrayIsEqualTo(incrementalReferenceSet, incrementalReadableBuildInfo!.program!.referencedMap![key])) {
|
||||
return [
|
||||
`Incremental Reference set is neither from dts nor files reference map for File:: ${key}::`,
|
||||
`Incremental:: ${JSON.stringify(incrementalReferenceSet, /*replacer*/ undefined, 2)}`,
|
||||
`Clean:: ${JSON.stringify(cleanReferenceSet, /*replacer*/ undefined, 2)}`,
|
||||
`IncrementalReferenceMap:: ${JSON.stringify(incrementalReadableBuildInfo!.program!.referencedMap![key], /*replacer*/ undefined, 2)}`,
|
||||
`CleanReferenceMap:: ${JSON.stringify(cleanReadableBuildInfo!.program!.referencedMap![key], /*replacer*/ undefined, 2)}`,
|
||||
];
|
||||
}
|
||||
},
|
||||
`exportedModulesMap:: File:: ${outputFile}`
|
||||
);
|
||||
// Verify that incrementally pending affected file emit are in clean build since clean build can contain more files compared to incremental depending of noEmitOnError option
|
||||
if (incrementalReadableBuildInfo?.program?.affectedFilesPendingEmit) {
|
||||
if (cleanReadableBuildInfo?.program?.affectedFilesPendingEmit === undefined) {
|
||||
addBaseline(
|
||||
`Incremental build contains affectedFilesPendingEmit, clean build does not have it: ${outputFile}::`,
|
||||
`Incremental buildInfoText:: ${incrementalBuildText}`,
|
||||
`Clean buildInfoText:: ${cleanBuildText}`
|
||||
);
|
||||
}
|
||||
let expectedIndex = 0;
|
||||
incrementalReadableBuildInfo.program.affectedFilesPendingEmit.forEach(([actualFile]) => {
|
||||
expectedIndex = findIndex(cleanReadableBuildInfo!.program!.affectedFilesPendingEmit!, ([expectedFile]) => actualFile === expectedFile, expectedIndex);
|
||||
if (expectedIndex === -1) {
|
||||
addBaseline(
|
||||
`Incremental build contains ${actualFile} file as pending emit, clean build does not have it: ${outputFile}::`,
|
||||
`Incremental buildInfoText:: ${incrementalBuildText}`,
|
||||
`Clean buildInfoText:: ${cleanBuildText}`
|
||||
);
|
||||
}
|
||||
expectedIndex++;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!headerAdded && discrepancyExplanation) addBaseline("*** Supplied discrepancy explanation but didnt file any difference");
|
||||
return baselines;
|
||||
|
||||
function verifyPresenceAbsence<T>(actual: T | undefined, expected: T | undefined, message: string) {
|
||||
(expected !== undefined ? assert.isDefined : assert.isUndefined)(actual, message);
|
||||
function verifyTextEqual(incrementalText: string | undefined, cleanText: string | undefined, message: string) {
|
||||
if (incrementalText !== cleanText) writeNotEqual(incrementalText, cleanText, message);
|
||||
}
|
||||
|
||||
function verifyMapLike<T>(incremental: MapLike<T> | undefined, clean: MapLike<T> | undefined, verifyValue: (key: string, incrementalValue: T, cleanValue: T) => string[] | undefined, message: string) {
|
||||
verifyPresenceAbsence(incremental, clean, `Incremental and clean do not match:: ${message}`);
|
||||
if (!incremental || !clean) return;
|
||||
const incrementalMap = new Map(getEntries(incremental));
|
||||
const cleanMap = new Map(getEntries(clean));
|
||||
if (incrementalMap.size !== cleanMap.size) {
|
||||
addBaseline(
|
||||
`Incremental and clean size of maps do not match:: ${message}`,
|
||||
`Incremental: ${JSON.stringify(incremental, /*replacer*/ undefined, 2)}`,
|
||||
`Clean: ${JSON.stringify(clean, /*replacer*/ undefined, 2)}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
cleanMap.forEach((cleanValue, key) => {
|
||||
const incrementalValue = incrementalMap.get(key);
|
||||
if (!incrementalValue) {
|
||||
addBaseline(
|
||||
`Incremental does not contain ${key} which is present in clean:: ${message}`,
|
||||
`Incremental: ${JSON.stringify(incremental, /*replacer*/ undefined, 2)}`,
|
||||
`Clean: ${JSON.stringify(clean, /*replacer*/ undefined, 2)}`,
|
||||
);
|
||||
}
|
||||
else {
|
||||
const result = verifyValue(key, incrementalMap.get(key)!, cleanValue);
|
||||
if (result) addBaseline(...result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function verifyPresenceAbsence<T>(actual: T | undefined, expected: T | undefined, message: string) {
|
||||
if (expected === undefined) {
|
||||
if (actual === undefined) return;
|
||||
}
|
||||
else {
|
||||
if (actual !== undefined) return;
|
||||
}
|
||||
writeNotEqual(actual, expected, message);
|
||||
}
|
||||
|
||||
function writeNotEqual<T>(actual: T | undefined, expected: T | undefined, message: string) {
|
||||
addBaseline(
|
||||
message,
|
||||
"CleanBuild:",
|
||||
isString(expected) ? expected : JSON.stringify(expected),
|
||||
"IncrementalBuild:",
|
||||
isString(actual) ? actual : JSON.stringify(actual),
|
||||
);
|
||||
}
|
||||
|
||||
function addBaseline(...text: string[]) {
|
||||
if (!baselines || !headerAdded) {
|
||||
(baselines ||= []).push(`${index}:: ${subScenario}`, ...(discrepancyExplanation?.()|| ["*** Needs explanation"]));
|
||||
headerAdded = true;
|
||||
}
|
||||
baselines.push(...text);
|
||||
}
|
||||
}
|
||||
|
||||
function getBuildInfoForIncrementalCorrectnessCheck(text: string | undefined): {
|
||||
@@ -467,7 +463,7 @@ interface Symbol {
|
||||
if (!text) return { buildInfo: text };
|
||||
const readableBuildInfo = JSON.parse(text) as ReadableBuildInfo;
|
||||
let sanitizedFileInfos: MapLike<BuilderState.FileInfo> | undefined;
|
||||
if (readableBuildInfo.program) {
|
||||
if (readableBuildInfo.program?.fileInfos) {
|
||||
sanitizedFileInfos = {};
|
||||
for (const id in readableBuildInfo.program.fileInfos) {
|
||||
if (hasProperty(readableBuildInfo.program.fileInfos, id)) {
|
||||
@@ -503,51 +499,35 @@ interface Symbol {
|
||||
modifyFs: (fs: vfs.FileSystem) => void;
|
||||
subScenario: string;
|
||||
commandLineArgs?: readonly string[];
|
||||
cleanBuildDiscrepancies?: () => ESMap<string, CleanBuildDescrepancy>;
|
||||
/** An array of lines to be printed in order when a discrepancy is detected */
|
||||
discrepancyExplanation?: () => readonly string[];
|
||||
}
|
||||
|
||||
export interface VerifyTscWithEditsInput extends VerifyTscWithEditsWorkerInput {
|
||||
baselineIncremental?: boolean;
|
||||
}
|
||||
export interface VerifyTscWithEditsWorkerInput extends TestTscCompile {
|
||||
export interface VerifyTscWithEditsInput extends TestTscCompile {
|
||||
edits: TestTscEdit[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify non watch tsc invokcation after each edit
|
||||
*/
|
||||
export function verifyTscWithEdits(input: VerifyTscWithEditsInput) {
|
||||
verifyTscWithEditsWorker(input);
|
||||
if (input.baselineIncremental) {
|
||||
verifyTscWithEditsWorker({
|
||||
...input,
|
||||
subScenario: `${input.subScenario} with incremental`,
|
||||
commandLineArgs: [...input.commandLineArgs, "--incremental"],
|
||||
});
|
||||
}
|
||||
}
|
||||
function verifyTscWithEditsWorker({
|
||||
export function verifyTscWithEdits({
|
||||
subScenario, fs, scenario, commandLineArgs,
|
||||
baselineSourceMap, modifyFs, baselineReadFileCalls, baselinePrograms,
|
||||
edits
|
||||
}: VerifyTscWithEditsWorkerInput) {
|
||||
}: VerifyTscWithEditsInput) {
|
||||
describe(`tsc ${commandLineArgs.join(" ")} ${scenario}:: ${subScenario} serializedEdits`, () => {
|
||||
let tick: () => void;
|
||||
let sys: TscCompileSystem;
|
||||
let baseFs: vfs.FileSystem;
|
||||
let editsSys: TscCompileSystem[];
|
||||
before(() => {
|
||||
Debug.assert(!!edits.length, `${scenario}/${subScenario}:: No incremental scenarios, you probably want to use verifyTsc instead.`);
|
||||
({ fs: baseFs, tick } = getFsWithTime(fs()));
|
||||
baseFs = fs().makeReadonly();
|
||||
sys = testTscCompile({
|
||||
scenario,
|
||||
subScenario,
|
||||
fs: () => baseFs.makeReadonly(),
|
||||
fs: () => baseFs,
|
||||
commandLineArgs,
|
||||
modifyFs: fs => {
|
||||
if (modifyFs) modifyFs(fs);
|
||||
tick();
|
||||
},
|
||||
modifyFs,
|
||||
baselineSourceMap,
|
||||
baselineReadFileCalls,
|
||||
baselinePrograms
|
||||
@@ -556,18 +536,13 @@ interface Symbol {
|
||||
{ modifyFs, subScenario: editScenario, commandLineArgs: editCommandLineArgs },
|
||||
index
|
||||
) => {
|
||||
tick();
|
||||
(editsSys || (editsSys = [])).push(testTscCompile({
|
||||
scenario,
|
||||
subScenario: editScenario || subScenario,
|
||||
diffWithInitial: true,
|
||||
fs: () => index === 0 ? sys.vfs : editsSys[index - 1].vfs,
|
||||
commandLineArgs: editCommandLineArgs || commandLineArgs,
|
||||
modifyFs: fs => {
|
||||
tick();
|
||||
modifyFs(fs);
|
||||
tick();
|
||||
},
|
||||
modifyFs,
|
||||
baselineSourceMap,
|
||||
baselineReadFileCalls,
|
||||
baselinePrograms
|
||||
@@ -577,39 +552,45 @@ interface Symbol {
|
||||
after(() => {
|
||||
baseFs = undefined!;
|
||||
sys = undefined!;
|
||||
tick = undefined!;
|
||||
editsSys = undefined!;
|
||||
});
|
||||
describe("tsc invocation after edit", () => {
|
||||
verifyTscBaseline(() => ({
|
||||
baseLine: () => {
|
||||
const { file, text } = sys.baseLine();
|
||||
const texts: string[] = [text];
|
||||
editsSys.forEach((sys, index) => {
|
||||
const incrementalScenario = edits[index];
|
||||
texts.push("");
|
||||
texts.push(`Change:: ${incrementalScenario.subScenario}`);
|
||||
texts.push(sys.baseLine().text);
|
||||
});
|
||||
return { file, text: texts.join("\r\n") };
|
||||
}
|
||||
}));
|
||||
});
|
||||
describe("tsc invocation after edit and clean build correctness", () => {
|
||||
edits.forEach(({ commandLineArgs: editCommandLineArgs, subScenario, cleanBuildDiscrepancies }, index) => verifyTscEditCorrectness(() => ({
|
||||
scenario,
|
||||
baseFs,
|
||||
newSys: editsSys[index],
|
||||
commandLineArgs: editCommandLineArgs || commandLineArgs,
|
||||
cleanBuildDiscrepancies,
|
||||
editFs: fs => {
|
||||
for (let i = 0; i <= index; i++) {
|
||||
edits[i].modifyFs(fs);
|
||||
}
|
||||
},
|
||||
modifyFs,
|
||||
tick
|
||||
}), index, subScenario));
|
||||
verifyTscBaseline(() => ({
|
||||
baseLine: () => {
|
||||
const { file, text } = sys.baseLine();
|
||||
const texts: string[] = [text];
|
||||
editsSys.forEach((sys, index) => {
|
||||
const incrementalScenario = edits[index];
|
||||
texts.push("");
|
||||
texts.push(`Change:: ${incrementalScenario.subScenario}`);
|
||||
texts.push(sys.baseLine().text);
|
||||
});
|
||||
return { file, text: texts.join("\r\n") };
|
||||
}
|
||||
}));
|
||||
it("tsc invocation after edit and clean build correctness", () => {
|
||||
let baselines: string[] | undefined;
|
||||
for (let index = 0; index < edits.length; index++) {
|
||||
baselines = verifyTscEditDiscrepancies({
|
||||
index,
|
||||
scenario,
|
||||
subScenario: edits[index].subScenario,
|
||||
baselines,
|
||||
baseFs,
|
||||
newSys: editsSys[index],
|
||||
commandLineArgs: edits[index].commandLineArgs || commandLineArgs,
|
||||
discrepancyExplanation: edits[index].discrepancyExplanation,
|
||||
editFs: fs => {
|
||||
for (let i = 0; i <= index; i++) {
|
||||
edits[i].modifyFs(fs);
|
||||
}
|
||||
},
|
||||
modifyFs
|
||||
});
|
||||
}
|
||||
Harness.Baseline.runBaseline(
|
||||
`${isBuild(commandLineArgs) ? "tsbuild" : "tsc"}/${scenario}/${subScenario.split(" ").join("-")}-discrepancies.js`,
|
||||
baselines ? baselines.join("\r\n") : null // eslint-disable-line no-null/no-null
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace ts.tscWatch {
|
||||
content: JSON.stringify({
|
||||
compilerOptions: {
|
||||
outDir: "build",
|
||||
module: "node12",
|
||||
module: "node16",
|
||||
},
|
||||
references: [{ path: "../pkg2" }]
|
||||
})
|
||||
@@ -109,7 +109,7 @@ namespace ts.tscWatch {
|
||||
compilerOptions: {
|
||||
composite: true,
|
||||
outDir: "build",
|
||||
module: "node12",
|
||||
module: "node16",
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -126,7 +126,7 @@ namespace ts.tscWatch {
|
||||
path: `${projectRoot}/node_modules/pkg2`,
|
||||
symLink: `${projectRoot}/packages/pkg2`,
|
||||
},
|
||||
{ ...libFile, path: `/a/lib/lib.es2020.full.d.ts` }
|
||||
{ ...libFile, path: `/a/lib/lib.es2022.full.d.ts` }
|
||||
], { currentDirectory: projectRoot }),
|
||||
commandLineArgs: ["-b", "packages/pkg1", "-w", "--verbose", "--traceResolution"],
|
||||
changes: [
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace ts {
|
||||
});
|
||||
});
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/44434 but with `module: node12`, some `exports` maps blocking direct access, and no `baseUrl`
|
||||
// https://github.com/microsoft/TypeScript/issues/44434 but with `module: node16`, some `exports` maps blocking direct access, and no `baseUrl`
|
||||
describe("unittests:: tsbuild:: moduleSpecifiers:: synthesized module specifiers across referenced projects resolve correctly", () => {
|
||||
verifyTsc({
|
||||
scenario: "moduleSpecifiers",
|
||||
@@ -140,7 +140,7 @@ namespace ts {
|
||||
{
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"module": "node12"
|
||||
"module": "node16"
|
||||
}
|
||||
}`,
|
||||
"/src/src-types/package.json": Utils.dedent`
|
||||
@@ -178,7 +178,7 @@ namespace ts {
|
||||
}`,
|
||||
}, ""),
|
||||
modifyFs: fs => {
|
||||
fs.writeFileSync("/lib/lib.es2020.full.d.ts", tscWatch.libFile.content);
|
||||
fs.writeFileSync("/lib/lib.es2022.full.d.ts", tscWatch.libFile.content);
|
||||
fs.symlinkSync("/src", "/src/src-types/node_modules");
|
||||
fs.symlinkSync("/src", "/src/src-dogs/node_modules");
|
||||
},
|
||||
|
||||
@@ -8,40 +8,81 @@ namespace ts {
|
||||
projFs = undefined!;
|
||||
});
|
||||
|
||||
function verifyNoEmitOnError(subScenario: string, fixModifyFs: TestTscEdit["modifyFs"], modifyFs?: TestTscEdit["modifyFs"]) {
|
||||
verifyTscWithEdits({
|
||||
scenario: "noEmitOnError",
|
||||
subScenario,
|
||||
fs: () => projFs,
|
||||
modifyFs,
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json"],
|
||||
edits: [
|
||||
noChangeRun,
|
||||
{
|
||||
subScenario: "Fix error",
|
||||
modifyFs: fixModifyFs,
|
||||
},
|
||||
noChangeRun,
|
||||
],
|
||||
baselinePrograms: true,
|
||||
baselineIncremental: true
|
||||
});
|
||||
}
|
||||
|
||||
verifyNoEmitOnError(
|
||||
"syntax errors",
|
||||
fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db";
|
||||
verifyTscWithEdits({
|
||||
scenario: "noEmitOnError",
|
||||
subScenario: "syntax errors",
|
||||
fs: () => projFs,
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json"],
|
||||
edits: [
|
||||
noChangeRun,
|
||||
{
|
||||
subScenario: "Fix error",
|
||||
modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db";
|
||||
const a = {
|
||||
lastName: 'sdsd'
|
||||
};`, "utf-8")
|
||||
);
|
||||
};`, "utf-8"),
|
||||
},
|
||||
noChangeRun,
|
||||
],
|
||||
baselinePrograms: true,
|
||||
});
|
||||
|
||||
verifyNoEmitOnError(
|
||||
"semantic errors",
|
||||
fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db";
|
||||
verifyTscWithEdits({
|
||||
scenario: "noEmitOnError",
|
||||
subScenario: "syntax errors with incremental",
|
||||
fs: () => projFs,
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json", "--incremental"],
|
||||
edits: [
|
||||
noChangeRun,
|
||||
{
|
||||
subScenario: "Fix error",
|
||||
modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db";
|
||||
const a = {
|
||||
lastName: 'sdsd'
|
||||
};`, "utf-8"),
|
||||
discrepancyExplanation: noChangeWithExportsDiscrepancyRun.discrepancyExplanation,
|
||||
},
|
||||
noChangeWithExportsDiscrepancyRun,
|
||||
],
|
||||
baselinePrograms: true,
|
||||
});
|
||||
|
||||
verifyTscWithEdits({
|
||||
scenario: "noEmitOnError",
|
||||
subScenario: "semantic errors",
|
||||
fs: () => projFs,
|
||||
modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db";
|
||||
const a: string = 10;`, "utf-8"),
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json"],
|
||||
edits: [
|
||||
noChangeRun,
|
||||
{
|
||||
subScenario: "Fix error",
|
||||
modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db";
|
||||
const a: string = "hello";`, "utf-8"),
|
||||
fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db";
|
||||
const a: string = 10;`, "utf-8")
|
||||
);
|
||||
},
|
||||
noChangeRun,
|
||||
],
|
||||
baselinePrograms: true,
|
||||
});
|
||||
|
||||
verifyTscWithEdits({
|
||||
scenario: "noEmitOnError",
|
||||
subScenario: "semantic errors with incremental",
|
||||
fs: () => projFs,
|
||||
modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db";
|
||||
const a: string = 10;`, "utf-8"),
|
||||
commandLineArgs: ["--b", "/src/tsconfig.json", "--incremental"],
|
||||
edits: [
|
||||
noChangeWithExportsDiscrepancyRun,
|
||||
{
|
||||
subScenario: "Fix error",
|
||||
modifyFs: fs => fs.writeFileSync("/src/src/main.ts", `import { A } from "../shared/types/db";
|
||||
const a: string = "hello";`, "utf-8"),
|
||||
},
|
||||
noChangeRun,
|
||||
],
|
||||
baselinePrograms: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,10 +10,6 @@ namespace ts {
|
||||
outFileWithBuildFs = undefined!;
|
||||
});
|
||||
|
||||
function createSolutionBuilder(host: fakes.SolutionBuilderHost, baseOptions?: BuildOptions) {
|
||||
return ts.createSolutionBuilder(host, ["/src/third"], { dry: false, force: false, verbose: true, ...(baseOptions || {}) });
|
||||
}
|
||||
|
||||
interface VerifyOutFileScenarioInput {
|
||||
subScenario: string;
|
||||
modifyFs?: (fs: vfs.FileSystem) => void;
|
||||
@@ -108,8 +104,9 @@ namespace ts {
|
||||
function getOutFileFsAfterBuild() {
|
||||
if (outFileWithBuildFs) return outFileWithBuildFs;
|
||||
const fs = outFileFs.shadow();
|
||||
const host = fakes.SolutionBuilderHost.create(fs);
|
||||
const builder = createSolutionBuilder(host);
|
||||
const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" });
|
||||
const host = createSolutionBuilderHostForBaseline(sys as TscCompileSystem);
|
||||
const builder = createSolutionBuilder(host, ["/src/third"], { dry: false, force: false, verbose: true });
|
||||
builder.build();
|
||||
fs.makeReadonly();
|
||||
return outFileWithBuildFs = fs;
|
||||
@@ -147,7 +144,7 @@ namespace ts {
|
||||
compile: sys => {
|
||||
// Buildinfo will have version which does not match with current ts version
|
||||
const buildHost = createSolutionBuilderHostForBaseline(sys, "FakeTSCurrentVersion");
|
||||
const builder = ts.createSolutionBuilder(buildHost, ["/src/third"], { verbose: true });
|
||||
const builder = createSolutionBuilder(buildHost, ["/src/third"], { verbose: true });
|
||||
sys.exit(builder.build());
|
||||
}
|
||||
});
|
||||
@@ -181,7 +178,7 @@ namespace ts {
|
||||
commandLineArgs: ["--build", "/src/second/tsconfig.json"],
|
||||
compile: sys => {
|
||||
const buildHost = createSolutionBuilderHostForBaseline(sys);
|
||||
const builder = ts.createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], {});
|
||||
const builder = createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], {});
|
||||
sys.exit(builder.build("/src/second/tsconfig.json"));
|
||||
}
|
||||
});
|
||||
@@ -193,7 +190,7 @@ namespace ts {
|
||||
commandLineArgs: ["--build", "--clean", "/src/second/tsconfig.json"],
|
||||
compile: sys => {
|
||||
const buildHost = createSolutionBuilderHostForBaseline(sys);
|
||||
const builder = ts.createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], { verbose: true });
|
||||
const builder = createSolutionBuilder(buildHost, ["/src/third/tsconfig.json"], { verbose: true });
|
||||
sys.exit(builder.clean("/src/second/tsconfig.json"));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -55,16 +55,7 @@ namespace ts {
|
||||
}
|
||||
})
|
||||
}),
|
||||
edits: [
|
||||
noChangeRun,
|
||||
{
|
||||
...noChangeProject,
|
||||
cleanBuildDiscrepancies: () => new Map([
|
||||
["/src/dist/tsconfig.tsbuildinfo", CleanBuildDescrepancy.CleanFileTextDifferent], // tsbuildinfo will have -p setting when built using -p vs no build happens incrementally because of no change.
|
||||
["/src/dist/tsconfig.tsbuildinfo.readable.baseline.txt", CleanBuildDescrepancy.CleanFileTextDifferent] // tsbuildinfo will have -p setting when built using -p vs no build happens incrementally because of no change.
|
||||
]),
|
||||
}
|
||||
],
|
||||
edits,
|
||||
}, ["/src/dist/src/index.js", "/src/dist/src/index.d.ts"]);
|
||||
|
||||
verify({
|
||||
|
||||
@@ -2,7 +2,7 @@ namespace ts {
|
||||
describe("unittests:: tsbuild:: Public API with custom transformers when passed to build", () => {
|
||||
let sys: TscCompileSystem;
|
||||
before(() => {
|
||||
const initialFs = getFsWithTime(loadProjectFromFiles({
|
||||
const inputFs = loadProjectFromFiles({
|
||||
"/src/tsconfig.json": JSON.stringify({
|
||||
references: [
|
||||
{ path: "./shared/tsconfig.json" },
|
||||
@@ -29,9 +29,7 @@ export class c2 { }
|
||||
export enum e2 { }
|
||||
// leading
|
||||
export function f22() { } // trailing`,
|
||||
})).fs.makeReadonly();
|
||||
const inputFs = initialFs.shadow();
|
||||
inputFs.makeReadonly();
|
||||
}).makeReadonly();
|
||||
const fs = inputFs.shadow();
|
||||
|
||||
// Create system
|
||||
@@ -48,7 +46,7 @@ export function f22() { } // trailing`,
|
||||
writtenFiles.add(path);
|
||||
return originalWriteFile.call(sys, fileName, content, writeByteOrderMark);
|
||||
};
|
||||
const { cb, getPrograms } = commandLineCallbacks(sys, /*originalReadCall*/ undefined, originalWriteFile);
|
||||
const { cb, getPrograms } = commandLineCallbacks(sys, /*originalReadCall*/ undefined);
|
||||
const buildHost = createSolutionBuilderHost(
|
||||
sys,
|
||||
/*createProgram*/ undefined,
|
||||
|
||||
@@ -21,7 +21,8 @@ namespace ts {
|
||||
function getSampleFsAfterBuild() {
|
||||
if (projFsWithBuild) return projFsWithBuild;
|
||||
const fs = projFs.shadow();
|
||||
const host = fakes.SolutionBuilderHost.create(fs);
|
||||
const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc" });
|
||||
const host = createSolutionBuilderHostForBaseline(sys as TscCompileSystem);
|
||||
const builder = createSolutionBuilder(host, ["/src/tests"], {});
|
||||
builder.build();
|
||||
fs.makeReadonly();
|
||||
@@ -245,7 +246,7 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
const host = createSolutionBuilderHost(system);
|
||||
const host = createSolutionBuilderHostForBaseline(system);
|
||||
const builder = createSolutionBuilder(host, [testsConfig.path], {});
|
||||
baseline.push("Input::");
|
||||
baselineState();
|
||||
@@ -316,7 +317,7 @@ namespace ts {
|
||||
)
|
||||
);
|
||||
|
||||
const host = createSolutionBuilderHost(system);
|
||||
const host = createSolutionBuilderHostForBaseline(system);
|
||||
const builder = createSolutionBuilder(host, [testsConfig.path], { dry: false, force: false, verbose: false });
|
||||
builder.build();
|
||||
baselineState("Build of project");
|
||||
|
||||
@@ -3,13 +3,22 @@ namespace ts {
|
||||
writtenFiles: Set<Path>;
|
||||
baseLine(): { file: string; text: string; };
|
||||
disableUseFileVersionAsSignature?: boolean;
|
||||
storeFilesChangingSignatureDuringEmit?: boolean;
|
||||
};
|
||||
|
||||
export const noChangeRun: TestTscEdit = {
|
||||
subScenario: "no-change-run",
|
||||
modifyFs: noop
|
||||
};
|
||||
export const noChangeWithExportsDiscrepancyRun: TestTscEdit = {
|
||||
...noChangeRun,
|
||||
discrepancyExplanation: () => [
|
||||
"Incremental build did not emit and has .ts as signature so exports has all imported modules/referenced files",
|
||||
"Clean build always uses d.ts for signature for testing thus does not contain non exported modules/referenced files that arent needed"
|
||||
]
|
||||
};
|
||||
export const noChangeOnlyRuns = [noChangeRun];
|
||||
export const noChangeWithExportsDiscrepancyOnlyRuns = [noChangeWithExportsDiscrepancyRun];
|
||||
|
||||
export interface TestTscCompile extends TestTscCompileLikeBase {
|
||||
baselineSourceMap?: boolean;
|
||||
@@ -28,23 +37,22 @@ namespace ts {
|
||||
return !!(program as Program | BuilderProgram).getCompilerOptions;
|
||||
}
|
||||
export function commandLineCallbacks(
|
||||
sys: System & { writtenFiles: ReadonlyCollection<Path>; },
|
||||
sys: TscCompileSystem | tscWatch.WatchedSystem,
|
||||
originalReadCall?: System["readFile"],
|
||||
originalWriteFile?: System["writeFile"],
|
||||
): CommandLineCallbacks {
|
||||
let programs: CommandLineProgram[] | undefined;
|
||||
|
||||
return {
|
||||
cb: program => {
|
||||
if (isAnyProgram(program)) {
|
||||
baselineBuildInfo(program.getCompilerOptions(), sys, originalReadCall, originalWriteFile);
|
||||
baselineBuildInfo(program.getCompilerOptions(), sys, originalReadCall);
|
||||
(programs || (programs = [])).push(isBuilderProgram(program) ?
|
||||
[program.getProgram(), program] :
|
||||
[program]
|
||||
);
|
||||
}
|
||||
else {
|
||||
baselineBuildInfo(program.options, sys, originalReadCall, originalWriteFile);
|
||||
baselineBuildInfo(program.options, sys, originalReadCall);
|
||||
}
|
||||
},
|
||||
getPrograms: () => {
|
||||
@@ -84,6 +92,7 @@ namespace ts {
|
||||
// Create system
|
||||
const sys = new fakes.System(fs, { executingFilePath: "/lib/tsc", env: environmentVariables }) as TscCompileSystem;
|
||||
if (input.disableUseFileVersionAsSignature) sys.disableUseFileVersionAsSignature = true;
|
||||
sys.storeFilesChangingSignatureDuringEmit = true;
|
||||
sys.write(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}\n`);
|
||||
sys.exit = exitCode => sys.exitCode = exitCode;
|
||||
worker(sys);
|
||||
@@ -120,16 +129,22 @@ ${patch ? vfs.formatPatch(patch) : ""}`
|
||||
const originalWriteFile = sys.writeFile;
|
||||
sys.writeFile = (fileName, content, writeByteOrderMark) => {
|
||||
const path = toPathWithSystem(sys, fileName);
|
||||
assert.isFalse(writtenFiles.has(path));
|
||||
// When buildinfo is same for two projects,
|
||||
// it gives error and doesnt write buildinfo but because buildInfo is written for one project,
|
||||
// readable baseline will be written two times for those two projects with same contents and is ok
|
||||
Debug.assert(!writtenFiles.has(path) || endsWith(path, "baseline.txt"));
|
||||
writtenFiles.add(path);
|
||||
return originalWriteFile.call(sys, fileName, content, writeByteOrderMark);
|
||||
};
|
||||
return originalWriteFile;
|
||||
}
|
||||
|
||||
export function createSolutionBuilderHostForBaseline(sys: TscCompileSystem, versionToWrite?: string) {
|
||||
makeSystemReadyForBaseline(sys, versionToWrite);
|
||||
const { cb } = commandLineCallbacks(sys);
|
||||
export function createSolutionBuilderHostForBaseline(
|
||||
sys: TscCompileSystem | tscWatch.WatchedSystem,
|
||||
versionToWrite?: string,
|
||||
originalRead?: (TscCompileSystem | tscWatch.WatchedSystem)["readFile"]
|
||||
) {
|
||||
if (sys instanceof fakes.System) makeSystemReadyForBaseline(sys, versionToWrite);
|
||||
const { cb } = commandLineCallbacks(sys, originalRead);
|
||||
const host = createSolutionBuilderHost(sys,
|
||||
/*createProgram*/ undefined,
|
||||
createDiagnosticReporter(sys, /*pretty*/ true),
|
||||
@@ -153,7 +168,7 @@ ${patch ? vfs.formatPatch(patch) : ""}`
|
||||
});
|
||||
|
||||
function commandLineCompile(sys: TscCompileSystem) {
|
||||
const originalWriteFile = makeSystemReadyForBaseline(sys);
|
||||
makeSystemReadyForBaseline(sys);
|
||||
actualReadFileMap = {};
|
||||
const originalReadFile = sys.readFile;
|
||||
sys.readFile = path => {
|
||||
@@ -164,7 +179,7 @@ ${patch ? vfs.formatPatch(patch) : ""}`
|
||||
return originalReadFile.call(sys, path);
|
||||
};
|
||||
|
||||
const result = commandLineCallbacks(sys, originalReadFile, originalWriteFile);
|
||||
const result = commandLineCallbacks(sys, originalReadFile);
|
||||
executeCommandLine(
|
||||
sys,
|
||||
result.cb,
|
||||
@@ -212,7 +227,7 @@ ${patch ? vfs.formatPatch(patch) : ""}`
|
||||
describe(input.subScenario, () => {
|
||||
verifyTscBaseline(() => verifier({
|
||||
...input,
|
||||
fs: () => getFsWithTime(input.fs()).fs.makeReadonly()
|
||||
fs: () => input.fs().makeReadonly()
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace ts {
|
||||
commandLineArgs: ["--incremental", "-p", "src"],
|
||||
modifyFs,
|
||||
edits: [
|
||||
noChangeRun,
|
||||
noChangeWithExportsDiscrepancyRun,
|
||||
{
|
||||
subScenario: "incremental-declaration-doesnt-change",
|
||||
modifyFs: fixModifyFs
|
||||
@@ -123,15 +123,20 @@ const a: string = 10;`, "utf-8"),
|
||||
verifyNoEmitChanges({ composite: true });
|
||||
|
||||
function verifyNoEmitChanges(compilerOptions: CompilerOptions) {
|
||||
const discrepancyIfNoDtsEmit = getEmitDeclarations(compilerOptions) ?
|
||||
undefined :
|
||||
noChangeWithExportsDiscrepancyRun.discrepancyExplanation;
|
||||
const noChangeRunWithNoEmit: TestTscEdit = {
|
||||
...noChangeRun,
|
||||
subScenario: "No Change run with noEmit",
|
||||
commandLineArgs: ["--p", "src/project", "--noEmit"],
|
||||
discrepancyExplanation: discrepancyIfNoDtsEmit,
|
||||
};
|
||||
const noChangeRunWithEmit: TestTscEdit = {
|
||||
...noChangeRun,
|
||||
subScenario: "No Change run with emit",
|
||||
commandLineArgs: ["--p", "src/project"],
|
||||
discrepancyExplanation: discrepancyIfNoDtsEmit,
|
||||
};
|
||||
let optionsString = "";
|
||||
for (const key in compilerOptions) {
|
||||
@@ -152,10 +157,12 @@ const a: string = 10;`, "utf-8"),
|
||||
subScenario: "Introduce error but still noEmit",
|
||||
commandLineArgs: ["--p", "src/project", "--noEmit"],
|
||||
modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop", "prop1"),
|
||||
discrepancyExplanation: getEmitDeclarations(compilerOptions) ? noChangeWithExportsDiscrepancyRun.discrepancyExplanation : undefined,
|
||||
},
|
||||
{
|
||||
subScenario: "Fix error and emit",
|
||||
modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop1", "prop"),
|
||||
discrepancyExplanation: discrepancyIfNoDtsEmit
|
||||
},
|
||||
noChangeRunWithEmit,
|
||||
noChangeRunWithNoEmit,
|
||||
@@ -164,6 +171,7 @@ const a: string = 10;`, "utf-8"),
|
||||
{
|
||||
subScenario: "Introduce error and emit",
|
||||
modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop", "prop1"),
|
||||
discrepancyExplanation: discrepancyIfNoDtsEmit
|
||||
},
|
||||
noChangeRunWithEmit,
|
||||
noChangeRunWithNoEmit,
|
||||
@@ -173,6 +181,7 @@ const a: string = 10;`, "utf-8"),
|
||||
subScenario: "Fix error and no emit",
|
||||
commandLineArgs: ["--p", "src/project", "--noEmit"],
|
||||
modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop1", "prop"),
|
||||
discrepancyExplanation: noChangeWithExportsDiscrepancyRun.discrepancyExplanation,
|
||||
},
|
||||
noChangeRunWithEmit,
|
||||
noChangeRunWithNoEmit,
|
||||
@@ -196,6 +205,7 @@ const a: string = 10;`, "utf-8"),
|
||||
{
|
||||
subScenario: "Fix error and no emit",
|
||||
modifyFs: fs => replaceText(fs, "/src/project/src/class.ts", "prop1", "prop"),
|
||||
discrepancyExplanation: noChangeWithExportsDiscrepancyRun.discrepancyExplanation
|
||||
},
|
||||
noChangeRunWithEmit,
|
||||
],
|
||||
@@ -352,11 +362,10 @@ declare global {
|
||||
{
|
||||
subScenario: "Add class3 to project1 and build it",
|
||||
modifyFs: fs => fs.writeFileSync("/src/projects/project1/class3.ts", `class class3 {}`, "utf-8"),
|
||||
cleanBuildDiscrepancies: () => new Map<string, CleanBuildDescrepancy>([
|
||||
// Ts buildinfo will not be updated in incremental build so it will have semantic diagnostics cached from previous build
|
||||
// But in clean build because of global diagnostics, semantic diagnostics are not queried so not cached in tsbuildinfo
|
||||
["/src/projects/project2/tsconfig.tsbuildinfo", CleanBuildDescrepancy.CleanFileTextDifferent]
|
||||
]),
|
||||
discrepancyExplanation: () => [
|
||||
"Ts buildinfo will not be updated in incremental build so it will have semantic diagnostics cached from previous build",
|
||||
"But in clean build because of global diagnostics, semantic diagnostics are not queried so not cached in tsbuildinfo",
|
||||
],
|
||||
},
|
||||
{
|
||||
subScenario: "Add output of class3",
|
||||
@@ -372,11 +381,10 @@ declare global {
|
||||
{
|
||||
subScenario: "Delete output for class3",
|
||||
modifyFs: fs => fs.unlinkSync("/src/projects/project1/class3.d.ts"),
|
||||
cleanBuildDiscrepancies: () => new Map<string, CleanBuildDescrepancy>([
|
||||
// Ts buildinfo willbe updated but will retain lib file errors from previous build and not others because they are emitted because of change which results in clearing their semantic diagnostics cache
|
||||
// But in clean build because of global diagnostics, semantic diagnostics are not queried so not cached in tsbuildinfo
|
||||
["/src/projects/project2/tsconfig.tsbuildinfo", CleanBuildDescrepancy.CleanFileTextDifferent]
|
||||
]),
|
||||
discrepancyExplanation: () => [
|
||||
"Ts buildinfo will be updated but will retain lib file errors from previous build and not others because they are emitted because of change which results in clearing their semantic diagnostics cache",
|
||||
"But in clean build because of global diagnostics, semantic diagnostics are not queried so not cached in tsbuildinfo",
|
||||
],
|
||||
},
|
||||
{
|
||||
subScenario: "Create output for class3",
|
||||
@@ -464,5 +472,40 @@ declare global {
|
||||
fs.writeFileSync("/lib/lib.esnext.d.ts", libContent);
|
||||
}
|
||||
});
|
||||
|
||||
verifyTscWithEdits({
|
||||
scenario: "incremental",
|
||||
subScenario: "change to type that gets used as global through export in another file",
|
||||
commandLineArgs: ["-p", `src/project`],
|
||||
fs: () => loadProjectFromFiles({
|
||||
"/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { composite: true }, }),
|
||||
"/src/project/class1.ts": `const a: MagicNumber = 1;
|
||||
console.log(a);`,
|
||||
"/src/project/constants.ts": "export default 1;",
|
||||
"/src/project/types.d.ts": `type MagicNumber = typeof import('./constants').default`,
|
||||
}),
|
||||
edits: [{
|
||||
subScenario: "Modify imports used in global file",
|
||||
modifyFs: fs => fs.writeFileSync("/src/project/constants.ts", "export default 2;"),
|
||||
}],
|
||||
});
|
||||
|
||||
verifyTscWithEdits({
|
||||
scenario: "incremental",
|
||||
subScenario: "change to type that gets used as global through export in another file through indirect import",
|
||||
commandLineArgs: ["-p", `src/project`],
|
||||
fs: () => loadProjectFromFiles({
|
||||
"/src/project/tsconfig.json": JSON.stringify({ compilerOptions: { composite: true }, }),
|
||||
"/src/project/class1.ts": `const a: MagicNumber = 1;
|
||||
console.log(a);`,
|
||||
"/src/project/constants.ts": "export default 1;",
|
||||
"/src/project/reexport.ts": `export { default as ConstantNumber } from "./constants"`,
|
||||
"/src/project/types.d.ts": `type MagicNumber = typeof import('./reexport').ConstantNumber`,
|
||||
}),
|
||||
edits: [{
|
||||
subScenario: "Modify imports used in global file",
|
||||
modifyFs: fs => fs.writeFileSync("/src/project/constants.ts", "export default 2;"),
|
||||
}],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
namespace ts {
|
||||
describe("unittests:: tsc:: redirect::", () => {
|
||||
verifyTsc({
|
||||
scenario: "redirect",
|
||||
subScenario: "when redirecting ts file",
|
||||
fs: () => loadProjectFromFiles({
|
||||
"/src/project/tsconfig.json": JSON.stringify({
|
||||
compilerOptions: {
|
||||
outDir: "out"
|
||||
},
|
||||
include: [
|
||||
"copy1/node_modules/target/*",
|
||||
"copy2/node_modules/target/*",
|
||||
]
|
||||
}),
|
||||
"/src/project/copy1/node_modules/target/index.ts": "export const a = 1;",
|
||||
"/src/project/copy1/node_modules/target/import.ts": `import {} from "./";`,
|
||||
"/src/project/copy1/node_modules/target/package.json": JSON.stringify({
|
||||
name: "target",
|
||||
version: "1.0.0",
|
||||
main: "index.js",
|
||||
}),
|
||||
"/src/project/copy2/node_modules/target/index.ts": "export const a = 1;",
|
||||
"/src/project/copy2/node_modules/target/import.ts": `import {} from "./";`,
|
||||
"/src/project/copy2/node_modules/target/package.json": JSON.stringify({
|
||||
name: "target",
|
||||
version: "1.0.0",
|
||||
main: "index.js",
|
||||
}),
|
||||
}),
|
||||
commandLineArgs: ["-p", "src/project"],
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -171,9 +171,10 @@ namespace ts.tscWatch {
|
||||
export interface Baseline extends BaselineBase, CommandLineCallbacks {
|
||||
}
|
||||
|
||||
export function createBaseline(system: WatchedSystem, modifySystem?: (sys: WatchedSystem) => void): Baseline {
|
||||
export function createBaseline(system: WatchedSystem, modifySystem?: (sys: WatchedSystem, originalRead: WatchedSystem["readFile"]) => void): Baseline {
|
||||
const originalRead = system.readFile;
|
||||
const initialSys = fakes.patchHostForBuildInfoReadWrite(system);
|
||||
modifySystem?.(initialSys);
|
||||
modifySystem?.(initialSys, originalRead);
|
||||
const sys = VirtualFS.changeToHostTrackingWrittenFiles(initialSys);
|
||||
const baseline: string[] = [];
|
||||
baseline.push("Input::");
|
||||
@@ -336,7 +337,7 @@ namespace ts.tscWatch {
|
||||
if (!builderProgram) return;
|
||||
if (builderProgram !== oldProgram?.[1]) {
|
||||
const state = builderProgram.getState();
|
||||
const internalState = state as unknown as BuilderState;
|
||||
const internalState = state as unknown as BuilderProgramState;
|
||||
if (state.semanticDiagnosticsPerFile?.size) {
|
||||
baseline.push("Semantic diagnostics in builder refreshed for::");
|
||||
for (const file of program.getSourceFiles()) {
|
||||
@@ -354,9 +355,12 @@ namespace ts.tscWatch {
|
||||
baseline.push("Shape signatures in builder refreshed for::");
|
||||
internalState.hasCalledUpdateShapeSignature.forEach((path: Path) => {
|
||||
const info = state.fileInfos.get(path);
|
||||
if(info?.version === info?.signature || !info?.signature) {
|
||||
if (info?.version === info?.signature || !info?.signature) {
|
||||
baseline.push(path + " (used version)");
|
||||
}
|
||||
else if (internalState.filesChangingSignature?.has(path)) {
|
||||
baseline.push(path + " (computed .d.ts during emit)");
|
||||
}
|
||||
else {
|
||||
baseline.push(path + " (computed .d.ts)");
|
||||
}
|
||||
@@ -407,30 +411,32 @@ namespace ts.tscWatch {
|
||||
sys.writeFile(file, content.replace(searchValue, replaceValue));
|
||||
}
|
||||
|
||||
export function createSolutionBuilder(system: WatchedSystem, rootNames: readonly string[], defaultOptions?: BuildOptions) {
|
||||
const host = createSolutionBuilderHost(system);
|
||||
return ts.createSolutionBuilder(host, rootNames, defaultOptions || {});
|
||||
export function createSolutionBuilder(system: WatchedSystem, rootNames: readonly string[], originalRead?: WatchedSystem["readFile"]) {
|
||||
const host = createSolutionBuilderHostForBaseline(system, /*versionToWrite*/ undefined, originalRead);
|
||||
return ts.createSolutionBuilder(host, rootNames, {});
|
||||
}
|
||||
|
||||
export function ensureErrorFreeBuild(host: WatchedSystem, rootNames: readonly string[]) {
|
||||
// ts build should succeed
|
||||
const solutionBuilder = createSolutionBuilder(host, rootNames, {});
|
||||
solutionBuilder.build();
|
||||
solutionBuildWithBaseline(host, rootNames);
|
||||
assert.equal(host.getOutput().length, 0, JSON.stringify(host.getOutput(), /*replacer*/ undefined, " "));
|
||||
}
|
||||
|
||||
export function createSystemWithSolutionBuild(solutionRoots: readonly string[], files: readonly VirtualFS.FileOrFolderOrSymLink[], params?: VirtualFS.TestServerHostCreationParameters) {
|
||||
const sys = createWatchedSystem(files, params);
|
||||
export function solutionBuildWithBaseline(sys: WatchedSystem, solutionRoots: readonly string[], originalRead?: WatchedSystem["readFile"]) {
|
||||
const originalReadFile = sys.readFile;
|
||||
const originalWrite = sys.write;
|
||||
const originalWriteFile = sys.writeFile;
|
||||
const solutionBuilder = createSolutionBuilder(VirtualFS.changeToHostTrackingWrittenFiles(
|
||||
fakes.patchHostForBuildInfoReadWrite(sys)
|
||||
), solutionRoots, {});
|
||||
), solutionRoots, originalRead);
|
||||
solutionBuilder.build();
|
||||
sys.readFile = originalReadFile;
|
||||
sys.write = originalWrite;
|
||||
sys.writeFile = originalWriteFile;
|
||||
return sys;
|
||||
}
|
||||
|
||||
export function createSystemWithSolutionBuild(solutionRoots: readonly string[], files: readonly VirtualFS.FileOrFolderOrSymLink[], params?: VirtualFS.TestServerHostCreationParameters) {
|
||||
return solutionBuildWithBaseline(createWatchedSystem(files, params), solutionRoots);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,10 +10,8 @@ namespace ts.tscWatch {
|
||||
function verifyWatch({ files, config, subScenario }: VerifyWatchInput, alreadyBuilt: boolean) {
|
||||
const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(
|
||||
createWatchedSystem(files),
|
||||
alreadyBuilt ? sys => {
|
||||
const solutionBuilder = createSolutionBuilder(sys, [config], {});
|
||||
solutionBuilder.build();
|
||||
solutionBuilder.close();
|
||||
alreadyBuilt ? (sys, originalRead) => {
|
||||
solutionBuildWithBaseline(sys, [config], originalRead);
|
||||
sys.clearOutput();
|
||||
} : undefined
|
||||
);
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace ts.projectSystem {
|
||||
assert.isString(exportMapKey);
|
||||
delete (response?.entries[0].data as any).exportMapKey;
|
||||
assert.deepEqual<protocol.CompletionInfo | undefined>(response, {
|
||||
flags: CompletionInfoFlags.MayIncludeAutoImports,
|
||||
isGlobalCompletion: true,
|
||||
isIncomplete: undefined,
|
||||
isMemberCompletion: false,
|
||||
|
||||
@@ -77,6 +77,7 @@ namespace ts.projectSystem {
|
||||
command: protocol.CommandTypes.CompletionInfo,
|
||||
arguments: completionRequestArgs
|
||||
}, {
|
||||
flags: 0,
|
||||
isGlobalCompletion: false,
|
||||
isMemberCompletion: true,
|
||||
isNewIdentifierLocation: false,
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace ts.projectSystem {
|
||||
describe("unittests:: tsserver:: moduleSpecifierCache", () => {
|
||||
it("caches importability within a file", () => {
|
||||
const { moduleSpecifierCache } = setup();
|
||||
assert.isTrue(moduleSpecifierCache.get(bTs.path as Path, aTs.path as Path, {}, {})?.isAutoImportable);
|
||||
assert.isFalse(moduleSpecifierCache.get(bTs.path as Path, aTs.path as Path, {}, {})?.isBlockedByPackageJsonDependencies);
|
||||
});
|
||||
|
||||
it("caches module specifiers within a file", () => {
|
||||
@@ -54,7 +54,7 @@ namespace ts.projectSystem {
|
||||
isRedirect: false
|
||||
}],
|
||||
moduleSpecifiers: ["mobx"],
|
||||
isAutoImportable: true,
|
||||
isBlockedByPackageJsonDependencies: false,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -72,7 +72,7 @@ namespace ts.projectSystem {
|
||||
const { host, moduleSpecifierCache } = setup();
|
||||
host.writeFile("/src/a2.ts", aTs.content);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
assert.isTrue(moduleSpecifierCache.get(bTs.path as Path, aTs.path as Path, {}, {})?.isAutoImportable);
|
||||
assert.isFalse(moduleSpecifierCache.get(bTs.path as Path, aTs.path as Path, {}, {})?.isBlockedByPackageJsonDependencies);
|
||||
});
|
||||
|
||||
it("invalidates the cache when symlinks are added or removed", () => {
|
||||
|
||||
@@ -1278,8 +1278,7 @@ bar;`
|
||||
const files = [solnConfig, sharedConfig, sharedIndex, sharedPackage, appConfig, appBar, appIndex, sharedSymlink, libFile];
|
||||
const host = createServerHost(files);
|
||||
if (built) {
|
||||
const solutionBuilder = tscWatch.createSolutionBuilder(host, [solnConfig.path], {});
|
||||
solutionBuilder.build();
|
||||
tscWatch.solutionBuildWithBaseline(host, [solnConfig.path]);
|
||||
host.clearOutput();
|
||||
}
|
||||
const session = createSession(host, { logger: createLoggerWithInMemoryLogs() });
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace ts.VirtualFS {
|
||||
DynamicPolling = "RecursiveDirectoryUsingDynamicPriorityPolling"
|
||||
}
|
||||
|
||||
const timeIncrements = 1000;
|
||||
export const timeIncrements = 1000;
|
||||
/**
|
||||
* also implements {server.ServerHost} but that would create a circular dependency
|
||||
*/
|
||||
@@ -204,6 +204,7 @@ namespace ts.VirtualFS {
|
||||
private readonly currentDirectory: string;
|
||||
public require: ((initialPath: string, moduleName: string) => RequireResult) | undefined;
|
||||
public defaultWatchFileKind?: () => WatchFileKind | undefined;
|
||||
public storeFilesChangingSignatureDuringEmit = true;
|
||||
watchFile: HostWatchFile;
|
||||
watchDirectory: HostWatchDirectory;
|
||||
constructor(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts(4,19): error TS2569: Type 'Set<string>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts(4,19): error TS2802: Type 'Set<string>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.
|
||||
|
||||
|
||||
==== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts (1 errors) ====
|
||||
@@ -7,4 +7,4 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck13.ts(4,19
|
||||
strSet.add('World')
|
||||
for (const str of strSet) { }
|
||||
~~~~~~
|
||||
!!! error TS2569: Type 'Set<string>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
|
||||
!!! error TS2802: Type 'Set<string>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.
|
||||
@@ -1,8 +1,8 @@
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts(2,17): error TS2569: Type 'Set<number>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
|
||||
tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts(2,17): error TS2802: Type 'Set<number>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.
|
||||
|
||||
|
||||
==== tests/cases/conformance/statements/for-ofStatements/ES5For-ofTypeCheck14.ts (1 errors) ====
|
||||
var union: string | Set<number>
|
||||
for (const e of union) { }
|
||||
~~~~~
|
||||
!!! error TS2569: Type 'Set<number>' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators.
|
||||
!!! error TS2802: Type 'Set<number>' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher.
|
||||
+22
-8
@@ -2063,7 +2063,7 @@ declare namespace ts {
|
||||
hasNoDefaultLib: boolean;
|
||||
languageVersion: ScriptTarget;
|
||||
/**
|
||||
* When `module` is `Node12` or `NodeNext`, this field controls whether the
|
||||
* When `module` is `Node16` or `NodeNext`, this field controls whether the
|
||||
* source file in question is an ESNext-output-format file, or a CommonJS-output-format
|
||||
* module. This is derived by the module resolver as it looks up the file, since
|
||||
* it is derived from either the file extension of the module, or the containing
|
||||
@@ -2172,7 +2172,9 @@ declare namespace ts {
|
||||
export type ResolvedConfigFileName = string & {
|
||||
_isResolvedConfigFileName: never;
|
||||
};
|
||||
export type WriteFileCallback = (fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: readonly SourceFile[]) => void;
|
||||
export interface WriteFileCallbackData {
|
||||
}
|
||||
export type WriteFileCallback = (fileName: string, text: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: readonly SourceFile[], data?: WriteFileCallbackData) => void;
|
||||
export class OperationCanceledException {
|
||||
}
|
||||
export interface CancellationToken {
|
||||
@@ -2891,7 +2893,7 @@ declare namespace ts {
|
||||
export enum ModuleResolutionKind {
|
||||
Classic = 1,
|
||||
NodeJs = 2,
|
||||
Node12 = 3,
|
||||
Node16 = 3,
|
||||
NodeNext = 99
|
||||
}
|
||||
export enum ModuleDetectionKind {
|
||||
@@ -2900,7 +2902,7 @@ declare namespace ts {
|
||||
*/
|
||||
Legacy = 1,
|
||||
/**
|
||||
* Legacy, but also files with jsx under react-jsx or react-jsxdev and esm mode files under moduleResolution: node12+
|
||||
* Legacy, but also files with jsx under react-jsx or react-jsxdev and esm mode files under moduleResolution: node16+
|
||||
*/
|
||||
Auto = 2,
|
||||
/**
|
||||
@@ -3072,7 +3074,7 @@ declare namespace ts {
|
||||
ES2020 = 6,
|
||||
ES2022 = 7,
|
||||
ESNext = 99,
|
||||
Node12 = 100,
|
||||
Node16 = 100,
|
||||
NodeNext = 199
|
||||
}
|
||||
export enum JsxEmit {
|
||||
@@ -4816,7 +4818,7 @@ declare namespace ts {
|
||||
/**
|
||||
* Controls the format the file is detected as - this can be derived from only the path
|
||||
* and files on disk, but needs to be done with a module resolution cache in scope to be performant.
|
||||
* This is usually `undefined` for compilations that do not have `moduleResolution` values of `node12` or `nodenext`.
|
||||
* This is usually `undefined` for compilations that do not have `moduleResolution` values of `node16` or `nodenext`.
|
||||
*/
|
||||
impliedNodeFormat?: ModuleKind.ESNext | ModuleKind.CommonJS;
|
||||
/**
|
||||
@@ -6433,7 +6435,18 @@ declare namespace ts {
|
||||
argumentIndex: number;
|
||||
argumentCount: number;
|
||||
}
|
||||
enum CompletionInfoFlags {
|
||||
None = 0,
|
||||
MayIncludeAutoImports = 1,
|
||||
IsImportStatementCompletion = 2,
|
||||
IsContinuation = 4,
|
||||
ResolvedModuleSpecifiers = 8,
|
||||
ResolvedModuleSpecifiersBeyondLimit = 16,
|
||||
MayIncludeMethodSnippets = 32
|
||||
}
|
||||
interface CompletionInfo {
|
||||
/** For performance telemetry. */
|
||||
flags?: CompletionInfoFlags;
|
||||
/** Not true for all global completions. This will be true if the enclosing scope matches a few syntax kinds. See `isSnippetScope`. */
|
||||
isGlobalCompletion: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
@@ -6809,7 +6822,7 @@ declare namespace ts {
|
||||
* shape of a the resulting SourceFile. This allows the DocumentRegistry to store
|
||||
* multiple copies of the same file for different compilation settings. A minimal
|
||||
* resolution cache is needed to fully define a source file's shape when
|
||||
* the compilation settings include `module: node12`+, so providing a cache host
|
||||
* the compilation settings include `module: node16`+, so providing a cache host
|
||||
* object should be preferred. A common host is a language service `ConfiguredProject`.
|
||||
* @param scriptSnapshot Text of the file. Only used if the file was not found
|
||||
* in the registry and a new one was created.
|
||||
@@ -6828,7 +6841,7 @@ declare namespace ts {
|
||||
* shape of a the resulting SourceFile. This allows the DocumentRegistry to store
|
||||
* multiple copies of the same file for different compilation settings. A minimal
|
||||
* resolution cache is needed to fully define a source file's shape when
|
||||
* the compilation settings include `module: node12`+, so providing a cache host
|
||||
* the compilation settings include `module: node16`+, so providing a cache host
|
||||
* object should be preferred. A common host is a language service `ConfiguredProject`.
|
||||
* @param scriptSnapshot Text of the file.
|
||||
* @param version Current version of the file.
|
||||
@@ -8848,6 +8861,7 @@ declare namespace ts.server.protocol {
|
||||
body?: CompletionInfo;
|
||||
}
|
||||
interface CompletionInfo {
|
||||
readonly flags?: number;
|
||||
readonly isGlobalCompletion: boolean;
|
||||
readonly isMemberCompletion: boolean;
|
||||
readonly isNewIdentifierLocation: boolean;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user