mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge remote-tracking branch 'origin/main' into release-5.4
This commit is contained in:
+8
-3
@@ -105,9 +105,14 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
// Todo: For each of these, investigate whether we want to enable them ✨
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
// Ignore: (solely underscores | starting with exactly one underscore)
|
||||
"argsIgnorePattern": "^(_+$|_[^_])",
|
||||
"varsIgnorePattern": "^(_+$|_[^_])"
|
||||
}
|
||||
],
|
||||
|
||||
// Pending https://github.com/typescript-eslint/typescript-eslint/issues/4820
|
||||
"@typescript-eslint/prefer-optional-chain": "off",
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
|
||||
- name: Configure Git, Run Tests, Update Baselines, Apply Fixes
|
||||
run: |
|
||||
|
||||
+10
-10
@@ -41,7 +41,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Use node version ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
check-latest: true
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
@@ -91,7 +91,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
@@ -123,7 +123,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
@@ -171,7 +171,7 @@ jobs:
|
||||
path: base
|
||||
ref: ${{ github.base_ref }}
|
||||
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
@@ -205,7 +205,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
@@ -222,7 +222,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
@@ -242,7 +242,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||
uses: github/codeql-action/init@e675ced7a7522a761fc9c8eb26682c8b27c42b2b # v3.24.1
|
||||
with:
|
||||
config-file: ./.github/codeql/codeql-configuration.yml
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below).
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||
uses: github/codeql-action/autobuild@e675ced7a7522a761fc9c8eb26682c8b27c42b2b # v3.24.1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
@@ -70,4 +70,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||
uses: github/codeql-action/analyze@e675ced7a7522a761fc9c8eb26682c8b27c42b2b # v3.24.1
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
filter: blob:none # https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/
|
||||
fetch-depth: 0 # Default is 1; need to set to 0 to get the benefits of blob:none.
|
||||
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
- run: |
|
||||
npm --version
|
||||
# corepack enable npm
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
# Use NODE_AUTH_TOKEN environment variable to authenticate to this registry.
|
||||
registry-url: https://registry.npmjs.org/
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
- run: |
|
||||
npm --version
|
||||
# corepack enable npm
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
npm pack ./
|
||||
mv typescript-*.tgz typescript.tgz
|
||||
- name: Upload built tarfile
|
||||
uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: tgz
|
||||
path: typescript.tgz
|
||||
|
||||
@@ -26,12 +26,12 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- uses: microsoft/RichCodeNavIndexer@e444937494b8941cc2bcccf2bcf2cd595d402f6b # v0.1
|
||||
- uses: microsoft/RichCodeNavIndexer@c8b97bc908f7bc0151fe4872aa029e99b2a0b96b # v0.1
|
||||
with:
|
||||
languages: typescript
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: 'Upload artifact'
|
||||
uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
@@ -55,6 +55,6 @@ jobs:
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: 'Upload to code-scanning'
|
||||
uses: github/codeql-action/upload-sarif@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||
uses: github/codeql-action/upload-sarif@e675ced7a7522a761fc9c8eb26682c8b27c42b2b # v3.24.1
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
with:
|
||||
ref: ${{ github.event.client_payload.branch_name }}
|
||||
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
- run: |
|
||||
npm --version
|
||||
# corepack enable npm
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
ref: ${{ github.event.inputs.branch_name || github.event.client_payload.branch_name }}
|
||||
|
||||
@@ -40,8 +40,8 @@ jobs:
|
||||
fetch-depth: 0 # Default is 1; need to set to 0 to get the benefits of blob:none.
|
||||
- if: ${{ !github.event.inputs.bisect }}
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: microsoft/TypeScript-Twoslash-Repro-Action@80178415feb0ebd3ed88d09e263a7cb8c8d6e1d2 # master
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
- uses: microsoft/TypeScript-Twoslash-Repro-Action@8680b5b290d48a7badbc7ba65971d526c61b86b8 # master
|
||||
with:
|
||||
github-token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
issue: ${{ github.event.inputs.issue }}
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
|
||||
Vendored
+1
-1
@@ -38,7 +38,7 @@
|
||||
"0"
|
||||
],
|
||||
"env": {
|
||||
"NODE_ENV": "testing"
|
||||
"NODE_ENV": "development"
|
||||
},
|
||||
"outFiles": [
|
||||
"${workspaceFolder}/built/**/*.js",
|
||||
|
||||
+4
-2
@@ -159,13 +159,15 @@ export const cleanSrc = task({
|
||||
run: () => cleanProject("src"),
|
||||
});
|
||||
|
||||
const dtsBundlerPath = "./scripts/dtsBundler.mjs";
|
||||
|
||||
/**
|
||||
* @param {string} entrypoint
|
||||
* @param {string} output
|
||||
*/
|
||||
async function runDtsBundler(entrypoint, output) {
|
||||
await exec(process.execPath, [
|
||||
"./scripts/dtsBundler.mjs",
|
||||
dtsBundlerPath,
|
||||
"--entrypoint",
|
||||
entrypoint,
|
||||
"--output",
|
||||
@@ -392,7 +394,7 @@ export const dtsServices = task({
|
||||
description: "Bundles typescript.d.ts",
|
||||
dependencies: [buildServices],
|
||||
run: async () => {
|
||||
if (needsUpdate("./built/local/typescript/tsconfig.tsbuildinfo", ["./built/local/typescript.d.ts", "./built/local/typescript.internal.d.ts"])) {
|
||||
if (needsUpdate(["./built/local/typescript/tsconfig.tsbuildinfo", dtsBundlerPath], ["./built/local/typescript.d.ts", "./built/local/typescript.internal.d.ts"])) {
|
||||
await runDtsBundler("./built/local/typescript/typescript.d.ts", "./built/local/typescript.d.ts");
|
||||
}
|
||||
},
|
||||
|
||||
@@ -47,4 +47,4 @@ with any additional questions or comments.
|
||||
|
||||
## Roadmap
|
||||
|
||||
For details on our planned features and future direction please refer to our [roadmap](https://github.com/microsoft/TypeScript/wiki/Roadmap).
|
||||
For details on our planned features and future direction, please refer to our [roadmap](https://github.com/microsoft/TypeScript/wiki/Roadmap).
|
||||
|
||||
Generated
+582
-553
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -60,7 +60,7 @@
|
||||
"chokidar": "^3.5.3",
|
||||
"diff": "^5.1.0",
|
||||
"dprint": "^0.45.0",
|
||||
"esbuild": "^0.19.11",
|
||||
"esbuild": "^0.20.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-formatter-autolinkable-stylish": "^1.3.0",
|
||||
"eslint-plugin-local": "^3.1.0",
|
||||
|
||||
+9
-11
@@ -19,18 +19,16 @@ async function checkErrorBaselines() {
|
||||
|
||||
const files = (await fsPromises.readdir(baseDir)).filter(f => f.endsWith(".errors.txt"));
|
||||
|
||||
files.forEach(f => {
|
||||
fs.readFile(baseDir + f, "utf-8", (err, baseline) => {
|
||||
if (err) throw err;
|
||||
for (const f of files) {
|
||||
const baseline = fs.readFileSync(baseDir + f, "utf-8");
|
||||
|
||||
let g;
|
||||
while (g = errRegex.exec(baseline)) {
|
||||
const errCode = +g[1];
|
||||
const msg = keys.filter(k => messages[k].code === errCode)[0];
|
||||
messages[msg].seen = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
let g;
|
||||
while (g = errRegex.exec(baseline)) {
|
||||
const errCode = +g[1];
|
||||
const msg = keys.filter(k => messages[k].code === errCode)[0];
|
||||
messages[msg].seen = true;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("== List of errors not present in baselines ==");
|
||||
let count = 0;
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
const { AST_NODE_TYPES, TSESTree, ESLintUtils } = require("@typescript-eslint/utils");
|
||||
const { AST_NODE_TYPES, ESLintUtils } = require("@typescript-eslint/utils");
|
||||
const { createRule } = require("./utils.cjs");
|
||||
const ts = require("typescript");
|
||||
|
||||
/**
|
||||
* @typedef {import("@typescript-eslint/utils").TSESTree.CallExpression | import("@typescript-eslint/utils").TSESTree.NewExpression} CallOrNewExpression
|
||||
*/
|
||||
|
||||
const unset = Symbol();
|
||||
/**
|
||||
* @template T
|
||||
@@ -42,7 +46,7 @@ module.exports = createRule({
|
||||
|
||||
/** @type {(name: string) => boolean} */
|
||||
const isSetOrAssert = name => name.startsWith("set") || name.startsWith("assert");
|
||||
/** @type {(node: TSESTree.Node) => boolean} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */
|
||||
const isTrivia = node => {
|
||||
if (node.type === AST_NODE_TYPES.Identifier) {
|
||||
return node.name === "undefined";
|
||||
@@ -56,7 +60,7 @@ module.exports = createRule({
|
||||
return false;
|
||||
};
|
||||
|
||||
/** @type {(node: TSESTree.CallExpression | TSESTree.NewExpression) => boolean} */
|
||||
/** @type {(node: CallOrNewExpression) => boolean} */
|
||||
const shouldIgnoreCalledExpression = node => {
|
||||
if (node.callee && node.callee.type === AST_NODE_TYPES.MemberExpression) {
|
||||
const methodName = node.callee.property.type === AST_NODE_TYPES.Identifier
|
||||
@@ -97,7 +101,7 @@ module.exports = createRule({
|
||||
return false;
|
||||
};
|
||||
|
||||
/** @type {(node: TSESTree.Node, i: number, getSignature: () => ts.Signature | undefined) => void} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node, i: number, getSignature: () => ts.Signature | undefined) => void} */
|
||||
const checkArg = (node, i, getSignature) => {
|
||||
if (!isTrivia(node)) {
|
||||
return;
|
||||
@@ -119,7 +123,7 @@ module.exports = createRule({
|
||||
});
|
||||
|
||||
const comments = sourceCode.getCommentsBefore(node);
|
||||
/** @type {TSESTree.Comment | undefined} */
|
||||
/** @type {import("@typescript-eslint/utils").TSESTree.Comment | undefined} */
|
||||
const comment = comments[comments.length - 1];
|
||||
|
||||
if (!comment || comment.type !== "Block") {
|
||||
@@ -170,7 +174,7 @@ module.exports = createRule({
|
||||
}
|
||||
};
|
||||
|
||||
/** @type {(node: TSESTree.CallExpression | TSESTree.NewExpression) => void} */
|
||||
/** @type {(node: CallOrNewExpression) => void} */
|
||||
const checkArgumentTrivia = node => {
|
||||
if (shouldIgnoreCalledExpression(node)) {
|
||||
return;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { AST_NODE_TYPES, TSESTree } = require("@typescript-eslint/utils");
|
||||
const { AST_NODE_TYPES } = require("@typescript-eslint/utils");
|
||||
const { createRule } = require("./utils.cjs");
|
||||
|
||||
module.exports = createRule({
|
||||
@@ -17,14 +17,14 @@ module.exports = createRule({
|
||||
defaultOptions: [],
|
||||
|
||||
create(context) {
|
||||
/** @type {(node: TSESTree.Node) => boolean} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */
|
||||
const isArrowFunction = node => node.type === AST_NODE_TYPES.ArrowFunctionExpression;
|
||||
/** @type {(node: TSESTree.Node) => boolean} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */
|
||||
const isStringLiteral = node => (
|
||||
(node.type === AST_NODE_TYPES.Literal && typeof node.value === "string") || node.type === AST_NODE_TYPES.TemplateLiteral
|
||||
);
|
||||
|
||||
/** @type {(node: TSESTree.MemberExpression) => boolean} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.MemberExpression) => boolean} */
|
||||
const isDebugAssert = node => (
|
||||
node.object.type === AST_NODE_TYPES.Identifier
|
||||
&& node.object.name === "Debug"
|
||||
@@ -32,7 +32,7 @@ module.exports = createRule({
|
||||
&& node.property.name === "assert"
|
||||
);
|
||||
|
||||
/** @type {(node: TSESTree.CallExpression) => void} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.CallExpression) => void} */
|
||||
const checkDebugAssert = node => {
|
||||
const args = node.arguments;
|
||||
const argsLen = args.length;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
const { TSESTree } = require("@typescript-eslint/utils");
|
||||
const { createRule } = require("./utils.cjs");
|
||||
|
||||
module.exports = createRule({
|
||||
@@ -29,7 +28,7 @@ module.exports = createRule({
|
||||
return text.startsWith(jsdocStart);
|
||||
}
|
||||
|
||||
/** @type {(c: TSESTree.Comment, indexInComment: number) => TSESTree.SourceLocation} */
|
||||
/** @type {(c: import("@typescript-eslint/utils").TSESTree.Comment, indexInComment: number) => import("@typescript-eslint/utils").TSESTree.SourceLocation} */
|
||||
const getAtInternalLoc = (c, indexInComment) => {
|
||||
const line = c.loc.start.line;
|
||||
return {
|
||||
@@ -44,7 +43,7 @@ module.exports = createRule({
|
||||
};
|
||||
};
|
||||
|
||||
/** @type {(c: TSESTree.Comment) => TSESTree.SourceLocation} */
|
||||
/** @type {(c: import("@typescript-eslint/utils").TSESTree.Comment) => import("@typescript-eslint/utils").TSESTree.SourceLocation} */
|
||||
const getJSDocStartLoc = c => {
|
||||
return {
|
||||
start: c.loc.start,
|
||||
@@ -55,7 +54,7 @@ module.exports = createRule({
|
||||
};
|
||||
};
|
||||
|
||||
/** @type {(node: TSESTree.Node) => void} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => void} */
|
||||
const checkDeclaration = node => {
|
||||
const blockComments = sourceCode.getCommentsBefore(node).filter(c => c.type === "Block");
|
||||
if (blockComments.length === 0) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
const { TSESTree } = require("@typescript-eslint/utils");
|
||||
const { createRule } = require("./utils.cjs");
|
||||
|
||||
module.exports = createRule({
|
||||
@@ -17,7 +16,7 @@ module.exports = createRule({
|
||||
|
||||
create(context) {
|
||||
const IN_OPERATOR = "in";
|
||||
/** @type {(node: TSESTree.BinaryExpression) => void} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.BinaryExpression) => void} */
|
||||
const checkInOperator = node => {
|
||||
if (node.operator === IN_OPERATOR) {
|
||||
context.report({ messageId: "noInOperatorError", node });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { TSESTree, AST_NODE_TYPES } = require("@typescript-eslint/utils");
|
||||
const { AST_NODE_TYPES } = require("@typescript-eslint/utils");
|
||||
const { createRule } = require("./utils.cjs");
|
||||
|
||||
module.exports = createRule({
|
||||
@@ -37,12 +37,12 @@ module.exports = createRule({
|
||||
/** @type {(name: string) => boolean} */
|
||||
const isKeyword = name => keywords.includes(name);
|
||||
|
||||
/** @type {(node: TSESTree.Identifier) => void} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Identifier) => void} */
|
||||
const report = node => {
|
||||
context.report({ messageId: "noKeywordsError", data: { name: node.name }, node });
|
||||
};
|
||||
|
||||
/** @type {(node: TSESTree.ObjectPattern) => void} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.ObjectPattern) => void} */
|
||||
const checkProperties = node => {
|
||||
node.properties.forEach(property => {
|
||||
if (
|
||||
@@ -56,7 +56,7 @@ module.exports = createRule({
|
||||
});
|
||||
};
|
||||
|
||||
/** @type {(node: TSESTree.ArrayPattern) => void} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.ArrayPattern) => void} */
|
||||
const checkElements = node => {
|
||||
node.elements.forEach(element => {
|
||||
if (
|
||||
@@ -69,7 +69,7 @@ module.exports = createRule({
|
||||
});
|
||||
};
|
||||
|
||||
/** @type {(node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.TSMethodSignature | TSESTree.TSFunctionType) => void} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.ArrowFunctionExpression | import("@typescript-eslint/utils").TSESTree.FunctionDeclaration | import("@typescript-eslint/utils").TSESTree.FunctionExpression | import("@typescript-eslint/utils").TSESTree.TSMethodSignature | import("@typescript-eslint/utils").TSESTree.TSFunctionType) => void} */
|
||||
const checkParams = node => {
|
||||
if (!node || !node.params || !node.params.length) {
|
||||
return;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
const { AST_NODE_TYPES, TSESTree } = require("@typescript-eslint/utils");
|
||||
const { AST_NODE_TYPES } = require("@typescript-eslint/utils");
|
||||
const { createRule } = require("./utils.cjs");
|
||||
|
||||
/** @typedef {import("@typescript-eslint/utils").TSESTree.FunctionDeclaration | import("@typescript-eslint/utils").TSESTree.FunctionExpression} FunctionDeclarationOrExpression */
|
||||
|
||||
module.exports = createRule({
|
||||
name: "only-arrow-functions",
|
||||
meta: {
|
||||
@@ -27,10 +29,10 @@ module.exports = createRule({
|
||||
}],
|
||||
|
||||
create(context, [{ allowNamedFunctions, allowDeclarations }]) {
|
||||
/** @type {(node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression) => boolean} */
|
||||
/** @type {(node: FunctionDeclarationOrExpression) => boolean} */
|
||||
const isThisParameter = node => !!node.params.length && !!node.params.find(param => param.type === AST_NODE_TYPES.Identifier && param.name === "this");
|
||||
|
||||
/** @type {(node: TSESTree.Node) => boolean} */
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */
|
||||
const isMethodType = node => {
|
||||
const types = [
|
||||
AST_NODE_TYPES.MethodDefinition,
|
||||
@@ -57,7 +59,7 @@ module.exports = createRule({
|
||||
}
|
||||
};
|
||||
|
||||
/** @type {(node: TSESTree.FunctionDeclaration | TSESTree.FunctionExpression) => void} */
|
||||
/** @type {(node: FunctionDeclarationOrExpression) => void} */
|
||||
const exitFunction = node => {
|
||||
const methodUsesThis = stack.pop();
|
||||
|
||||
|
||||
@@ -13,11 +13,8 @@
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"allowUnusedLabels": false,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"allowJs": true,
|
||||
"checkJs": true
|
||||
},
|
||||
|
||||
+120
-99
@@ -3924,6 +3924,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
else if (result.flags & SymbolFlags.RegularEnum) {
|
||||
diagnosticMessage = error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationName);
|
||||
}
|
||||
else {
|
||||
Debug.assert(!!(result.flags & SymbolFlags.ConstEnum));
|
||||
if (getIsolatedModules(compilerOptions)) {
|
||||
diagnosticMessage = error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationName);
|
||||
}
|
||||
}
|
||||
|
||||
if (diagnosticMessage) {
|
||||
addRelatedInfo(diagnosticMessage, createDiagnosticForNode(declaration, Diagnostics._0_is_declared_here, declarationName));
|
||||
@@ -13535,6 +13541,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (paramMapper) {
|
||||
result.mapper = left.compositeKind !== TypeFlags.Intersection && left.mapper && left.compositeSignatures ? combineTypeMappers(left.mapper, paramMapper) : paramMapper;
|
||||
}
|
||||
else if (left.compositeKind !== TypeFlags.Intersection && left.mapper && left.compositeSignatures) {
|
||||
result.mapper = left.mapper;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -14230,7 +14239,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function getConstraintFromIndexedAccess(type: IndexedAccessType) {
|
||||
if (isMappedTypeGenericIndexedAccess(type) || isGenericMappedType(type.objectType)) {
|
||||
if (isMappedTypeGenericIndexedAccess(type)) {
|
||||
// For indexed access types of the form { [P in K]: E }[X], where K is non-generic and X is generic,
|
||||
// we substitute an instantiation of E where P is replaced with X.
|
||||
return substituteIndexedMappedType(type.objectType as MappedType, type.indexType);
|
||||
@@ -14542,11 +14551,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function getResolvedApparentTypeOfMappedType(type: MappedType) {
|
||||
const typeVariable = getHomomorphicTypeVariable(type);
|
||||
if (typeVariable && !type.declaration.nameType) {
|
||||
const constraint = getConstraintOfTypeParameter(typeVariable);
|
||||
if (constraint && everyType(constraint, isArrayOrTupleType)) {
|
||||
return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
|
||||
const target = (type.target ?? type) as MappedType;
|
||||
const typeVariable = getHomomorphicTypeVariable(target);
|
||||
if (typeVariable && !target.declaration.nameType) {
|
||||
const constraint = getConstraintTypeFromMappedType(type);
|
||||
if (constraint.flags & TypeFlags.Index) {
|
||||
const baseConstraint = getBaseConstraintOfType((constraint as IndexType).type);
|
||||
if (baseConstraint && everyType(baseConstraint, isArrayOrTupleType)) {
|
||||
return instantiateType(target, prependTypeMapping(typeVariable, baseConstraint, type.mapper));
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
@@ -14908,6 +14921,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (type.flags & TypeFlags.Object) {
|
||||
const resolved = resolveStructuredTypeMembers(type as ObjectType);
|
||||
const symbol = resolved.members.get(name);
|
||||
if (symbol && !includeTypeOnlyMembers && type.symbol?.flags & SymbolFlags.ValueModule && getSymbolLinks(type.symbol).typeOnlyExportStarMap?.has(name)) {
|
||||
// If this is the type of a module, `resolved.members.get(name)` might have effectively skipped over
|
||||
// an `export type * from './foo'`, leaving `symbolIsValue` unable to see that the symbol is being
|
||||
// viewed through a type-only export.
|
||||
return undefined;
|
||||
}
|
||||
if (symbol && symbolIsValue(symbol, includeTypeOnlyMembers)) {
|
||||
return symbol;
|
||||
}
|
||||
@@ -16868,7 +16887,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const type = elementTypes[i];
|
||||
const flags = target.elementFlags[i];
|
||||
if (flags & ElementFlags.Variadic) {
|
||||
if (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) {
|
||||
if (type.flags & TypeFlags.Any) {
|
||||
addElement(type, ElementFlags.Rest, target.labeledElementDeclarations?.[i]);
|
||||
}
|
||||
else if (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type)) {
|
||||
// Generic variadic elements stay as they are.
|
||||
addElement(type, ElementFlags.Variadic, target.labeledElementDeclarations?.[i]);
|
||||
}
|
||||
@@ -18624,11 +18646,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return type;
|
||||
}
|
||||
|
||||
function maybeCloneTypeParameter(p: TypeParameter) {
|
||||
const constraint = getConstraintOfTypeParameter(p);
|
||||
return constraint && (isGenericObjectType(constraint) || isGenericIndexType(constraint)) ? cloneTypeParameter(p) : p;
|
||||
}
|
||||
|
||||
function isSimpleTupleType(node: TypeNode): boolean {
|
||||
return isTupleTypeNode(node) && length(node.elements) > 0 &&
|
||||
!some(node.elements, e => isOptionalTypeNode(e) || isRestTypeNode(e) || isNamedTupleMember(e) && !!(e.questionToken || e.dotDotDotToken));
|
||||
@@ -18671,7 +18688,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
let combinedMapper: TypeMapper | undefined;
|
||||
if (root.inferTypeParameters) {
|
||||
// When we're looking at making an inference for an infer type, when we get its constraint, it'll automagically be
|
||||
// instantiated with the context, so it doesn't need the mapper for the inference contex - however the constraint
|
||||
// instantiated with the context, so it doesn't need the mapper for the inference context - however the constraint
|
||||
// may refer to another _root_, _uncloned_ `infer` type parameter [1], or to something mapped by `mapper` [2].
|
||||
// [1] Eg, if we have `Foo<T, U extends T>` and `Foo<number, infer B>` - `B` is constrained to `T`, which, in turn, has been instantiated
|
||||
// as `number`
|
||||
@@ -18679,36 +18696,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// [2] Eg, if we have `Foo<T, U extends T>` and `Foo<Q, infer B>` where `Q` is mapped by `mapper` into `number` - `B` is constrained to `T`
|
||||
// which is in turn instantiated as `Q`, which is in turn instantiated as `number`.
|
||||
// So we need to:
|
||||
// * Clone the type parameters so their constraints can be instantiated in the context of `mapper` (otherwise theyd only get inference context information)
|
||||
// * Set the clones to both map the conditional's enclosing `mapper` and the original params
|
||||
// * instantiate the extends type with the clones
|
||||
// * combine `context.nonFixingMapper` with `mapper` so their constraints can be instantiated in the context of `mapper` (otherwise they'd only get inference context information)
|
||||
// * incorporate all of the component mappers into the combined mapper for the true and false members
|
||||
// This means we have three mappers that need applying:
|
||||
// This means we have two mappers that need applying:
|
||||
// * The original `mapper` used to create this conditional
|
||||
// * The mapper that maps the old root type parameter to the clone (`freshMapper`)
|
||||
// * The mapper that maps the clone to its inference result (`context.mapper`)
|
||||
const freshParams = sameMap(root.inferTypeParameters, maybeCloneTypeParameter);
|
||||
const freshMapper = freshParams !== root.inferTypeParameters ? createTypeMapper(root.inferTypeParameters, freshParams) : undefined;
|
||||
const context = createInferenceContext(freshParams, /*signature*/ undefined, InferenceFlags.None);
|
||||
if (freshMapper) {
|
||||
const freshCombinedMapper = combineTypeMappers(mapper, freshMapper);
|
||||
for (let i = 0; i < freshParams.length; i++) {
|
||||
if (freshParams[i] !== root.inferTypeParameters[i]) {
|
||||
freshParams[i].mapper = freshCombinedMapper;
|
||||
}
|
||||
}
|
||||
// * The mapper that maps the infer type parameter to its inference result (`context.mapper`)
|
||||
const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None);
|
||||
if (mapper) {
|
||||
context.nonFixingMapper = combineTypeMappers(context.nonFixingMapper, mapper);
|
||||
}
|
||||
if (!checkTypeDeferred) {
|
||||
// We don't want inferences from constraints as they may cause us to eagerly resolve the
|
||||
// conditional type instead of deferring resolution. Also, we always want strict function
|
||||
// types rules (i.e. proper contravariance) for inferences.
|
||||
inferTypes(context.inferences, checkType, instantiateType(extendsType, freshMapper), InferencePriority.NoConstraints | InferencePriority.AlwaysStrict);
|
||||
inferTypes(context.inferences, checkType, extendsType, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict);
|
||||
}
|
||||
const innerMapper = combineTypeMappers(freshMapper, context.mapper);
|
||||
// It's possible for 'infer T' type paramteters to be given uninstantiated constraints when the
|
||||
// those type parameters are used in type references (see getInferredTypeParameterConstraint). For
|
||||
// that reason we need context.mapper to be first in the combined mapper. See #42636 for examples.
|
||||
combinedMapper = mapper ? combineTypeMappers(innerMapper, mapper) : innerMapper;
|
||||
combinedMapper = mapper ? combineTypeMappers(context.mapper, mapper) : context.mapper;
|
||||
}
|
||||
// Instantiate the extends type including inferences for 'infer T' type parameters
|
||||
const inferredExtendsType = combinedMapper ? instantiateType(root.extendsType, combinedMapper) : extendsType;
|
||||
@@ -19865,12 +19871,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (!result) {
|
||||
const newMapper = createTypeMapper(root.outerTypeParameters, typeArguments);
|
||||
const checkType = root.checkType;
|
||||
const distributionType = root.isDistributive ? getMappedType(checkType, newMapper) : undefined;
|
||||
const distributionType = root.isDistributive ? getReducedType(getMappedType(checkType, newMapper)) : undefined;
|
||||
// Distributive conditional types are distributed over union types. For example, when the
|
||||
// distributive conditional type T extends U ? X : Y is instantiated with A | B for T, the
|
||||
// result is (A extends U ? X : Y) | (B extends U ? X : Y).
|
||||
result = distributionType && checkType !== distributionType && distributionType.flags & (TypeFlags.Union | TypeFlags.Never) ?
|
||||
mapTypeWithAlias(getReducedType(distributionType), t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper), forConstraint), aliasSymbol, aliasTypeArguments) :
|
||||
mapTypeWithAlias(distributionType, t => getConditionalType(root, prependTypeMapping(checkType, t, newMapper), forConstraint), aliasSymbol, aliasTypeArguments) :
|
||||
getConditionalType(root, newMapper, forConstraint, aliasSymbol, aliasTypeArguments);
|
||||
root.instantiations!.set(id, result);
|
||||
}
|
||||
@@ -20818,8 +20824,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const restIndex = sourceRestType || targetRestType ? paramCount - 1 : -1;
|
||||
|
||||
for (let i = 0; i < paramCount; i++) {
|
||||
const sourceType = i === restIndex ? getRestTypeAtPosition(source, i) : tryGetTypeAtPosition(source, i);
|
||||
const targetType = i === restIndex ? getRestTypeAtPosition(target, i) : tryGetTypeAtPosition(target, i);
|
||||
const sourceType = i === restIndex ? getRestOrAnyTypeAtPosition(source, i) : tryGetTypeAtPosition(source, i);
|
||||
const targetType = i === restIndex ? getRestOrAnyTypeAtPosition(target, i) : tryGetTypeAtPosition(target, i);
|
||||
if (sourceType && targetType) {
|
||||
// In order to ensure that any generic type Foo<T> is at least co-variant with respect to T no matter
|
||||
// how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions,
|
||||
@@ -26728,7 +26734,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function hasMatchingArgument(expression: CallExpression | NewExpression, reference: Node) {
|
||||
if (expression.arguments) {
|
||||
for (const argument of expression.arguments) {
|
||||
if (isOrContainsMatchingReference(reference, argument) || optionalChainContainsReference(argument, reference)) {
|
||||
if (
|
||||
isOrContainsMatchingReference(reference, argument)
|
||||
|| optionalChainContainsReference(argument, reference)
|
||||
|| getCandidateDiscriminantPropertyAccess(argument, reference)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -26742,6 +26752,51 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return false;
|
||||
}
|
||||
|
||||
function getCandidateDiscriminantPropertyAccess(expr: Expression, reference: Node) {
|
||||
if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) {
|
||||
// When the reference is a binding pattern or function or arrow expression, we are narrowing a pesudo-reference in
|
||||
// getNarrowedTypeOfSymbol. An identifier for a destructuring variable declared in the same binding pattern or
|
||||
// parameter declared in the same parameter list is a candidate.
|
||||
if (isIdentifier(expr)) {
|
||||
const symbol = getResolvedSymbol(expr);
|
||||
const declaration = symbol.valueDeclaration;
|
||||
if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) {
|
||||
return declaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isAccessExpression(expr)) {
|
||||
// An access expression is a candidate if the reference matches the left hand expression.
|
||||
if (isMatchingReference(reference, expr.expression)) {
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
else if (isIdentifier(expr)) {
|
||||
const symbol = getResolvedSymbol(expr);
|
||||
if (isConstantVariable(symbol)) {
|
||||
const declaration = symbol.valueDeclaration!;
|
||||
// Given 'const x = obj.kind', allow 'x' as an alias for 'obj.kind'
|
||||
if (
|
||||
isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) &&
|
||||
isMatchingReference(reference, declaration.initializer.expression)
|
||||
) {
|
||||
return declaration.initializer;
|
||||
}
|
||||
// Given 'const { kind: x } = obj', allow 'x' as an alias for 'obj.kind'
|
||||
if (isBindingElement(declaration) && !declaration.initializer) {
|
||||
const parent = declaration.parent.parent;
|
||||
if (
|
||||
isVariableDeclaration(parent) && !parent.type && parent.initializer && (isIdentifier(parent.initializer) || isAccessExpression(parent.initializer)) &&
|
||||
isMatchingReference(reference, parent.initializer)
|
||||
) {
|
||||
return declaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getFlowNodeId(flow: FlowNode): number {
|
||||
if (!flow.id || flow.id < 0) {
|
||||
flow.id = nextFlowId;
|
||||
@@ -28098,57 +28153,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getCandidateDiscriminantPropertyAccess(expr: Expression) {
|
||||
if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) {
|
||||
// When the reference is a binding pattern or function or arrow expression, we are narrowing a pesudo-reference in
|
||||
// getNarrowedTypeOfSymbol. An identifier for a destructuring variable declared in the same binding pattern or
|
||||
// parameter declared in the same parameter list is a candidate.
|
||||
if (isIdentifier(expr)) {
|
||||
const symbol = getResolvedSymbol(expr);
|
||||
const declaration = symbol.valueDeclaration;
|
||||
if (declaration && (isBindingElement(declaration) || isParameter(declaration)) && reference === declaration.parent && !declaration.initializer && !declaration.dotDotDotToken) {
|
||||
return declaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isAccessExpression(expr)) {
|
||||
// An access expression is a candidate if the reference matches the left hand expression.
|
||||
if (isMatchingReference(reference, expr.expression)) {
|
||||
return expr;
|
||||
}
|
||||
}
|
||||
else if (isIdentifier(expr)) {
|
||||
const symbol = getResolvedSymbol(expr);
|
||||
if (isConstantVariable(symbol)) {
|
||||
const declaration = symbol.valueDeclaration!;
|
||||
// Given 'const x = obj.kind', allow 'x' as an alias for 'obj.kind'
|
||||
if (
|
||||
isVariableDeclaration(declaration) && !declaration.type && declaration.initializer && isAccessExpression(declaration.initializer) &&
|
||||
isMatchingReference(reference, declaration.initializer.expression)
|
||||
) {
|
||||
return declaration.initializer;
|
||||
}
|
||||
// Given 'const { kind: x } = obj', allow 'x' as an alias for 'obj.kind'
|
||||
if (isBindingElement(declaration) && !declaration.initializer) {
|
||||
const parent = declaration.parent.parent;
|
||||
if (
|
||||
isVariableDeclaration(parent) && !parent.type && parent.initializer && (isIdentifier(parent.initializer) || isAccessExpression(parent.initializer)) &&
|
||||
isMatchingReference(reference, parent.initializer)
|
||||
) {
|
||||
return declaration;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getDiscriminantPropertyAccess(expr: Expression, computedType: Type) {
|
||||
// As long as the computed type is a subset of the declared type, we use the full declared type to detect
|
||||
// a discriminant property. In cases where the computed type isn't a subset, e.g because of a preceding type
|
||||
// predicate narrowing, we use the actual computed type.
|
||||
if (declaredType.flags & TypeFlags.Union || computedType.flags & TypeFlags.Union) {
|
||||
const access = getCandidateDiscriminantPropertyAccess(expr);
|
||||
const access = getCandidateDiscriminantPropertyAccess(expr, reference);
|
||||
if (access) {
|
||||
const name = getAccessedPropertyName(access);
|
||||
if (name) {
|
||||
@@ -36441,6 +36451,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return createTupleType(types, flags, readonly, names);
|
||||
}
|
||||
|
||||
// Return the rest type at the given position, transforming `any[]` into just `any`. We do this because
|
||||
// in signatures we want `any[]` in a rest position to be compatible with anything, but `any[]` isn't
|
||||
// assignable to tuple types with required elements.
|
||||
function getRestOrAnyTypeAtPosition(source: Signature, pos: number): Type {
|
||||
const restType = getRestTypeAtPosition(source, pos);
|
||||
const elementType = restType && getElementTypeOfArrayType(restType);
|
||||
return elementType && isTypeAny(elementType) ? anyType : restType;
|
||||
}
|
||||
|
||||
// Return the number of parameters in a signature. The rest parameter, if present, counts as one
|
||||
// parameter. For example, the parameter count of (x: number, y: number, ...z: string[]) is 3 and
|
||||
// the parameter count of (x: number, ...args: [number, ...string[], boolean])) is also 3. In the
|
||||
@@ -36504,7 +36523,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
if (signatureHasRestParameter(signature)) {
|
||||
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
|
||||
if (!isTupleType(restType)) {
|
||||
return restType;
|
||||
return isTypeAny(restType) ? anyArrayType : restType;
|
||||
}
|
||||
if (restType.target.hasRestElement) {
|
||||
return sliceTupleType(restType, restType.target.fixedLength);
|
||||
@@ -40504,7 +40523,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const objectIndexType = isGenericMappedType(objectType) && getMappedTypeNameTypeKind(objectType) === MappedTypeNameTypeKind.Remapping
|
||||
? getIndexTypeForMappedType(objectType, IndexFlags.None)
|
||||
: getIndexType(objectType, IndexFlags.None);
|
||||
if (isTypeAssignableTo(indexType, objectIndexType)) {
|
||||
const hasNumberIndexInfo = !!getIndexInfoOfType(objectType, numberType);
|
||||
if (everyType(indexType, t => isTypeAssignableTo(t, objectIndexType) || hasNumberIndexInfo && isApplicableIndexType(t, numberType))) {
|
||||
if (
|
||||
accessNode.kind === SyntaxKind.ElementAccessExpression && isAssignmentTarget(accessNode) &&
|
||||
getObjectFlags(objectType) & ObjectFlags.Mapped && getMappedTypeModifiers(objectType as MappedType) & MappedTypeModifiers.IncludeReadonly
|
||||
@@ -40513,16 +40533,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
return type;
|
||||
}
|
||||
// Check if we're indexing with a numeric type and if either object or index types
|
||||
// is a generic type with a constraint that has a numeric index signature.
|
||||
const apparentObjectType = getApparentType(objectType);
|
||||
if (getIndexInfoOfType(apparentObjectType, numberType) && isTypeAssignableToKind(indexType, TypeFlags.NumberLike)) {
|
||||
return type;
|
||||
}
|
||||
if (isGenericObjectType(objectType)) {
|
||||
const propertyName = getPropertyNameFromIndex(indexType, accessNode);
|
||||
if (propertyName) {
|
||||
const propertySymbol = forEachType(apparentObjectType, t => getPropertyOfType(t, propertyName));
|
||||
const propertySymbol = forEachType(getApparentType(objectType), t => getPropertyOfType(t, propertyName));
|
||||
if (propertySymbol && getDeclarationModifierFlagsFromSymbol(propertySymbol) & ModifierFlags.NonPublicAccessibilityModifier) {
|
||||
error(accessNode, Diagnostics.Private_or_protected_member_0_cannot_be_accessed_on_a_type_parameter, unescapeLeadingUnderscores(propertyName));
|
||||
return errorType;
|
||||
@@ -48300,28 +48314,35 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
isTypeOnly = !!rootValueSymbol?.declarations?.every(isTypeOnlyImportOrExportDeclaration);
|
||||
}
|
||||
const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, location);
|
||||
const resolvedSymbol = valueSymbol && valueSymbol.flags & SymbolFlags.Alias ? resolveAlias(valueSymbol) : valueSymbol;
|
||||
const resolvedValueSymbol = valueSymbol && valueSymbol.flags & SymbolFlags.Alias ? resolveAlias(valueSymbol) : valueSymbol;
|
||||
isTypeOnly ||= !!(valueSymbol && getTypeOnlyAliasDeclaration(valueSymbol, SymbolFlags.Value));
|
||||
|
||||
// Resolve the symbol as a type so that we can provide a more useful hint for the type serializer.
|
||||
const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
|
||||
if (resolvedSymbol && resolvedSymbol === typeSymbol) {
|
||||
const typeSymbol = resolveEntityName(typeName, SymbolFlags.Type, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, location);
|
||||
const resolvedTypeSymbol = typeSymbol && typeSymbol.flags & SymbolFlags.Alias ? resolveAlias(typeSymbol) : typeSymbol;
|
||||
|
||||
// In case the value symbol can't be resolved (e.g. because of missing declarations), use type symbol for reachability check.
|
||||
if (!valueSymbol) {
|
||||
isTypeOnly ||= !!(typeSymbol && getTypeOnlyAliasDeclaration(typeSymbol, SymbolFlags.Type));
|
||||
}
|
||||
|
||||
if (resolvedValueSymbol && resolvedValueSymbol === resolvedTypeSymbol) {
|
||||
const globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false);
|
||||
if (globalPromiseSymbol && resolvedSymbol === globalPromiseSymbol) {
|
||||
if (globalPromiseSymbol && resolvedValueSymbol === globalPromiseSymbol) {
|
||||
return TypeReferenceSerializationKind.Promise;
|
||||
}
|
||||
|
||||
const constructorType = getTypeOfSymbol(resolvedSymbol);
|
||||
const constructorType = getTypeOfSymbol(resolvedValueSymbol);
|
||||
if (constructorType && isConstructorType(constructorType)) {
|
||||
return isTypeOnly ? TypeReferenceSerializationKind.TypeWithCallSignature : TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
|
||||
}
|
||||
}
|
||||
|
||||
// We might not be able to resolve type symbol so use unknown type in that case (eg error case)
|
||||
if (!typeSymbol) {
|
||||
if (!resolvedTypeSymbol) {
|
||||
return isTypeOnly ? TypeReferenceSerializationKind.ObjectType : TypeReferenceSerializationKind.Unknown;
|
||||
}
|
||||
const type = getDeclaredTypeOfSymbol(typeSymbol);
|
||||
const type = getDeclaredTypeOfSymbol(resolvedTypeSymbol);
|
||||
if (isErrorType(type)) {
|
||||
return isTypeOnly ? TypeReferenceSerializationKind.ObjectType : TypeReferenceSerializationKind.Unknown;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
__String,
|
||||
CharacterCodes,
|
||||
Comparer,
|
||||
Comparison,
|
||||
@@ -286,7 +285,7 @@ export function filter<T>(array: T[], f: (x: T) => boolean): T[];
|
||||
/** @internal */
|
||||
export function filter<T, U extends T>(array: readonly T[], f: (x: T) => x is U): readonly U[];
|
||||
/** @internal */
|
||||
export function filter<T, U extends T>(array: readonly T[], f: (x: T) => boolean): readonly T[];
|
||||
export function filter<T>(array: readonly T[], f: (x: T) => boolean): readonly T[];
|
||||
/** @internal */
|
||||
export function filter<T, U extends T>(array: T[] | undefined, f: (x: T) => x is U): U[] | undefined;
|
||||
/** @internal */
|
||||
@@ -294,7 +293,7 @@ export function filter<T>(array: T[] | undefined, f: (x: T) => boolean): T[] | u
|
||||
/** @internal */
|
||||
export function filter<T, U extends T>(array: readonly T[] | undefined, f: (x: T) => x is U): readonly U[] | undefined;
|
||||
/** @internal */
|
||||
export function filter<T, U extends T>(array: readonly T[] | undefined, f: (x: T) => boolean): readonly T[] | undefined;
|
||||
export function filter<T>(array: readonly T[] | undefined, f: (x: T) => boolean): readonly T[] | undefined;
|
||||
/** @internal */
|
||||
export function filter<T>(array: readonly T[] | undefined, f: (x: T) => boolean): readonly T[] | undefined {
|
||||
if (array) {
|
||||
@@ -830,7 +829,7 @@ export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Compa
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function sortAndDeduplicate<T>(array: readonly string[]): SortedReadonlyArray<string>;
|
||||
export function sortAndDeduplicate(array: readonly string[]): SortedReadonlyArray<string>;
|
||||
/** @internal */
|
||||
export function sortAndDeduplicate<T>(array: readonly T[], comparer: Comparer<T>, equalityComparer?: EqualityComparer<T>): SortedReadonlyArray<T>;
|
||||
/** @internal */
|
||||
|
||||
@@ -4723,10 +4723,6 @@
|
||||
"category": "Message",
|
||||
"code": 6080
|
||||
},
|
||||
"File '{0}' has an unsupported extension, so skipping it.": {
|
||||
"category": "Message",
|
||||
"code": 6081
|
||||
},
|
||||
"Only 'amd' and 'system' modules are supported alongside --{0}.": {
|
||||
"category": "Error",
|
||||
"code": 6082
|
||||
|
||||
@@ -4131,6 +4131,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
|
||||
writeSpace();
|
||||
nextPos = emitTokenWithComment(SyntaxKind.AsKeyword, nextPos, writeKeyword, node);
|
||||
writeSpace();
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
nextPos = emitTokenWithComment(SyntaxKind.NamespaceKeyword, nextPos, writeKeyword, node);
|
||||
writeSpace();
|
||||
emit(node.name);
|
||||
@@ -5656,7 +5657,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
|
||||
const flags = (neverAsciiEscape ? GetLiteralTextFlags.NeverAsciiEscape : 0)
|
||||
| (jsxAttributeEscape ? GetLiteralTextFlags.JsxAttributeEscape : 0)
|
||||
| (printerOptions.terminateUnterminatedLiterals ? GetLiteralTextFlags.TerminateUnterminatedLiterals : 0)
|
||||
| (printerOptions.target && printerOptions.target === ScriptTarget.ESNext ? GetLiteralTextFlags.AllowNumericSeparator : 0);
|
||||
| (printerOptions.target && printerOptions.target >= ScriptTarget.ES2021 ? GetLiteralTextFlags.AllowNumericSeparator : 0);
|
||||
|
||||
return getLiteralText(node, currentSourceFile, flags);
|
||||
}
|
||||
|
||||
@@ -1675,7 +1675,7 @@ export function createAccessorPropertyGetRedirector(factory: NodeFactory, node:
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function createAccessorPropertySetRedirector(factory: NodeFactory, node: PropertyDeclaration, modifiers: readonly Modifier[] | undefined, name: PropertyName, receiver: Expression = factory.createThis()) {
|
||||
export function createAccessorPropertySetRedirector(factory: NodeFactory, node: PropertyDeclaration, modifiers: readonly Modifier[] | undefined, name: PropertyName, receiver: Expression = factory.createThis()): SetAccessorDeclaration {
|
||||
return factory.createSetAccessorDeclaration(
|
||||
modifiers,
|
||||
name,
|
||||
|
||||
@@ -348,7 +348,7 @@ interface PackageJson extends PackageJsonPathFields {
|
||||
version?: string;
|
||||
}
|
||||
|
||||
function readPackageJsonField<TMatch, K extends MatchingKeys<PackageJson, string | undefined>>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string", state: ModuleResolutionState): PackageJson[K] | undefined;
|
||||
function readPackageJsonField<K extends MatchingKeys<PackageJson, string | undefined>>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string", state: ModuleResolutionState): PackageJson[K] | undefined;
|
||||
function readPackageJsonField<K extends MatchingKeys<PackageJson, object | undefined>>(jsonContent: PackageJson, fieldName: K, typeOfTag: "object", state: ModuleResolutionState): PackageJson[K] | undefined;
|
||||
function readPackageJsonField<K extends keyof PackageJson>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string" | "object", state: ModuleResolutionState): PackageJson[K] | undefined {
|
||||
if (!hasProperty(jsonContent, fieldName)) {
|
||||
@@ -2090,7 +2090,6 @@ function loadModuleFromFileNoImplicitExtensions(extensions: Extensions, candidat
|
||||
/**
|
||||
* This function is only ever called with paths written in package.json files - never
|
||||
* module specifiers written in source files - and so it always allows the
|
||||
|
||||
* candidate to end with a TS extension (but will also try substituting a JS extension for a TS extension).
|
||||
*/
|
||||
function loadFileNameFromPackageJsonField(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined {
|
||||
@@ -2459,15 +2458,9 @@ function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: st
|
||||
}
|
||||
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => {
|
||||
const fromFile = tryFile(candidate, onlyRecordFailures, state);
|
||||
const fromFile = loadFileNameFromPackageJsonField(extensions, candidate, onlyRecordFailures, state);
|
||||
if (fromFile) {
|
||||
const resolved = resolvedIfExtensionMatches(extensions, fromFile);
|
||||
if (resolved) {
|
||||
return noPackageId(resolved);
|
||||
}
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile);
|
||||
}
|
||||
return noPackageId(fromFile);
|
||||
}
|
||||
|
||||
// Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types"
|
||||
@@ -2514,12 +2507,6 @@ function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: st
|
||||
}
|
||||
}
|
||||
|
||||
/** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
|
||||
function resolvedIfExtensionMatches(extensions: Extensions, path: string, resolvedUsingTsExtension?: boolean): PathAndExtension | undefined {
|
||||
const ext = tryGetExtensionFromPath(path);
|
||||
return ext !== undefined && extensionIsOk(extensions, ext) ? { path, ext, resolvedUsingTsExtension } : undefined;
|
||||
}
|
||||
|
||||
/** True if `extension` is one of the supported `extensions`. */
|
||||
function extensionIsOk(extensions: Extensions, extension: string): boolean {
|
||||
return extensions & Extensions.JavaScript && (extension === Extension.Js || extension === Extension.Jsx || extension === Extension.Mjs || extension === Extension.Cjs)
|
||||
|
||||
@@ -120,15 +120,16 @@ import {
|
||||
|
||||
// Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers.
|
||||
|
||||
const enum RelativePreference {
|
||||
/** @internal */
|
||||
export const enum RelativePreference {
|
||||
Relative,
|
||||
NonRelative,
|
||||
Shortest,
|
||||
ExternalNonRelative,
|
||||
}
|
||||
|
||||
// Processed preferences
|
||||
interface Preferences {
|
||||
/** @internal */
|
||||
export interface ModuleSpecifierPreferences {
|
||||
readonly relativePreference: RelativePreference;
|
||||
/**
|
||||
* @param syntaxImpliedNodeFormat Used when the import syntax implies ESM or CJS irrespective of the mode of the file.
|
||||
@@ -136,13 +137,14 @@ interface Preferences {
|
||||
getAllowedEndingsInPreferredOrder(syntaxImpliedNodeFormat?: SourceFile["impliedNodeFormat"]): ModuleSpecifierEnding[];
|
||||
}
|
||||
|
||||
function getPreferences(
|
||||
/** @internal */
|
||||
export function getModuleSpecifierPreferences(
|
||||
{ importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences,
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
oldImportSpecifier?: string,
|
||||
): Preferences {
|
||||
const preferredEnding = getPreferredEnding();
|
||||
): ModuleSpecifierPreferences {
|
||||
const filePreferredEnding = getPreferredEnding();
|
||||
return {
|
||||
relativePreference: oldImportSpecifier !== undefined ? (isExternalModuleNameRelative(oldImportSpecifier) ?
|
||||
RelativePreference.Relative :
|
||||
@@ -152,6 +154,7 @@ function getPreferences(
|
||||
importModuleSpecifierPreference === "project-relative" ? RelativePreference.ExternalNonRelative :
|
||||
RelativePreference.Shortest,
|
||||
getAllowedEndingsInPreferredOrder: syntaxImpliedNodeFormat => {
|
||||
const preferredEnding = syntaxImpliedNodeFormat !== importingSourceFile.impliedNodeFormat ? getPreferredEnding(syntaxImpliedNodeFormat) : filePreferredEnding;
|
||||
if ((syntaxImpliedNodeFormat ?? importingSourceFile.impliedNodeFormat) === ModuleKind.ESNext) {
|
||||
if (shouldAllowImportingTsExtension(compilerOptions, importingSourceFile.fileName)) {
|
||||
return [ModuleSpecifierEnding.TsExtension, ModuleSpecifierEnding.JsExtension];
|
||||
@@ -185,14 +188,14 @@ function getPreferences(
|
||||
},
|
||||
};
|
||||
|
||||
function getPreferredEnding(): ModuleSpecifierEnding {
|
||||
function getPreferredEnding(resolutionMode?: ResolutionMode): ModuleSpecifierEnding {
|
||||
if (oldImportSpecifier !== undefined) {
|
||||
if (hasJSFileExtension(oldImportSpecifier)) return ModuleSpecifierEnding.JsExtension;
|
||||
if (endsWith(oldImportSpecifier, "/index")) return ModuleSpecifierEnding.Index;
|
||||
}
|
||||
return getModuleSpecifierEndingPreference(
|
||||
importModuleSpecifierEnding,
|
||||
importingSourceFile.impliedNodeFormat,
|
||||
resolutionMode ?? importingSourceFile.impliedNodeFormat,
|
||||
compilerOptions,
|
||||
importingSourceFile,
|
||||
);
|
||||
@@ -213,7 +216,7 @@ export function updateModuleSpecifier(
|
||||
oldImportSpecifier: string,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
): string | undefined {
|
||||
const res = getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getPreferences({}, compilerOptions, importingSourceFile, oldImportSpecifier), {}, options);
|
||||
const res = getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getModuleSpecifierPreferences({}, compilerOptions, importingSourceFile, oldImportSpecifier), {}, options);
|
||||
if (res === oldImportSpecifier) return undefined;
|
||||
return res;
|
||||
}
|
||||
@@ -233,7 +236,7 @@ export function getModuleSpecifier(
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
): string {
|
||||
return getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getPreferences({}, compilerOptions, importingSourceFile), {}, options);
|
||||
return getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getModuleSpecifierPreferences({}, compilerOptions, importingSourceFile), {}, options);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -256,7 +259,7 @@ function getModuleSpecifierWorker(
|
||||
importingSourceFileName: string,
|
||||
toFileName: string,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
preferences: Preferences,
|
||||
preferences: ModuleSpecifierPreferences,
|
||||
userPreferences: UserPreferences,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
): string {
|
||||
@@ -377,7 +380,7 @@ function computeModuleSpecifiers(
|
||||
forAutoImport: boolean,
|
||||
): readonly string[] {
|
||||
const info = getInfo(importingSourceFile.fileName, host);
|
||||
const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile);
|
||||
const preferences = getModuleSpecifierPreferences(userPreferences, compilerOptions, importingSourceFile);
|
||||
const existingSpecifier = forEach(modulePaths, modulePath =>
|
||||
forEach(
|
||||
host.getFileIncludeReasons().get(toPath(modulePath.path, host.getCurrentDirectory(), info.getCanonicalFileName)),
|
||||
@@ -488,9 +491,9 @@ function getInfo(importingSourceFileName: string, host: ModuleSpecifierResolutio
|
||||
};
|
||||
}
|
||||
|
||||
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, preferences: Preferences): string;
|
||||
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, preferences: Preferences, pathsOnly?: boolean): string | undefined;
|
||||
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, { getAllowedEndingsInPreferredOrder: getAllowedEndingsInPrefererredOrder, relativePreference }: Preferences, pathsOnly?: boolean): string | undefined {
|
||||
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, preferences: ModuleSpecifierPreferences): string;
|
||||
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, preferences: ModuleSpecifierPreferences, pathsOnly?: boolean): string | undefined;
|
||||
function getLocalModuleSpecifier(moduleFileName: string, info: Info, compilerOptions: CompilerOptions, host: ModuleSpecifierResolutionHost, importMode: ResolutionMode, { getAllowedEndingsInPreferredOrder: getAllowedEndingsInPrefererredOrder, relativePreference }: ModuleSpecifierPreferences, pathsOnly?: boolean): string | undefined {
|
||||
const { baseUrl, paths, rootDirs } = compilerOptions;
|
||||
if (pathsOnly && !paths) {
|
||||
return undefined;
|
||||
@@ -1015,7 +1018,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan
|
||||
|
||||
// Simplify the full file path to something that can be resolved by Node.
|
||||
|
||||
const preferences = getPreferences(userPreferences, options, importingSourceFile);
|
||||
const preferences = getModuleSpecifierPreferences(userPreferences, options, importingSourceFile);
|
||||
const allowedEndings = preferences.getAllowedEndingsInPreferredOrder();
|
||||
let moduleSpecifier = path;
|
||||
let isPackageRootPath = false;
|
||||
|
||||
@@ -8760,7 +8760,7 @@ namespace Parser {
|
||||
if (!jsDocDiagnostics) {
|
||||
jsDocDiagnostics = [];
|
||||
}
|
||||
jsDocDiagnostics.push(...parseDiagnostics);
|
||||
addRange(jsDocDiagnostics, parseDiagnostics, saveParseDiagnosticsLength);
|
||||
}
|
||||
currentToken = saveToken;
|
||||
parseDiagnostics.length = saveParseDiagnosticsLength;
|
||||
|
||||
@@ -86,7 +86,10 @@ import {
|
||||
isComputedPropertyName,
|
||||
isDecorator,
|
||||
isElementAccessExpression,
|
||||
isEntityName,
|
||||
isEnumConst,
|
||||
isExportAssignment,
|
||||
isExportDeclaration,
|
||||
isExportOrDefaultModifier,
|
||||
isExportSpecifier,
|
||||
isExpression,
|
||||
@@ -96,6 +99,8 @@ import {
|
||||
isHeritageClause,
|
||||
isIdentifier,
|
||||
isImportClause,
|
||||
isImportDeclaration,
|
||||
isImportEqualsDeclaration,
|
||||
isImportSpecifier,
|
||||
isInJSFile,
|
||||
isInstantiatedModule,
|
||||
@@ -425,13 +430,65 @@ export function transformTypeScript(context: TransformationContext) {
|
||||
}
|
||||
}
|
||||
|
||||
function visitElidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult<Node | undefined> {
|
||||
/**
|
||||
* Determines whether import/export elision is blocked for this statement.
|
||||
*
|
||||
* @description
|
||||
* We generally block import/export elision if the statement was modified by a `before` custom
|
||||
* transform, although we will continue to allow it if the statement hasn't replaced a node of a different kind and
|
||||
* as long as the local bindings for the declarations are unchanged.
|
||||
*/
|
||||
function isElisionBlocked(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration) {
|
||||
const parsed = getParseTreeNode(node);
|
||||
if (parsed !== node) {
|
||||
// If the node has been transformed by a `before` transformer, perform no ellision on it
|
||||
// As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes
|
||||
// We do not reuse `visitorWorker`, as the ellidable statement syntax kinds are technically unrecognized by the switch-case in `visitTypeScript`,
|
||||
// and will trigger debug failures when debug verbosity is turned up
|
||||
if (parsed === node || isExportAssignment(node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parsed || parsed.kind !== node.kind) {
|
||||
// no longer safe to elide as the declaration was replaced with a node of a different kind
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportDeclaration:
|
||||
Debug.assertNode(parsed, isImportDeclaration);
|
||||
if (node.importClause !== parsed.importClause) {
|
||||
return true; // no longer safe to elide as the import clause has changed
|
||||
}
|
||||
if (node.attributes !== parsed.attributes) {
|
||||
return true; // no longer safe to elide as the import attributes have changed
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
Debug.assertNode(parsed, isImportEqualsDeclaration);
|
||||
if (node.name !== parsed.name) {
|
||||
return true; // no longer safe to elide as local binding has changed
|
||||
}
|
||||
if (node.isTypeOnly !== parsed.isTypeOnly) {
|
||||
return true; // no longer safe to elide as `type` modifier has changed
|
||||
}
|
||||
if (node.moduleReference !== parsed.moduleReference && (isEntityName(node.moduleReference) || isEntityName(parsed.moduleReference))) {
|
||||
return true; // no longer safe to elide as EntityName reference has changed.
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
Debug.assertNode(parsed, isExportDeclaration);
|
||||
if (node.exportClause !== parsed.exportClause) {
|
||||
return true; // no longer safe to elide as the export clause has changed
|
||||
}
|
||||
if (node.attributes !== parsed.attributes) {
|
||||
return true; // no longer safe to elide as the export attributes have changed
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function visitElidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult<Node | undefined> {
|
||||
if (isElisionBlocked(node)) {
|
||||
// We do not reuse `visitorWorker`, as the ellidable statement syntax kinds are technically unrecognized by
|
||||
// the switch-case in `visitTypeScript`, and will trigger debug failures when debug verbosity is turned up.
|
||||
if (node.transformFlags & TransformFlags.ContainsTypeScript) {
|
||||
// This node contains TypeScript, so we should visit its children.
|
||||
return visitEachChild(node, visitor, context);
|
||||
|
||||
@@ -187,6 +187,7 @@ import {
|
||||
getLineAndCharacterOfPosition,
|
||||
getLinesBetweenPositions,
|
||||
getLineStarts,
|
||||
getModeForUsageLocation,
|
||||
getNameOfDeclaration,
|
||||
getNormalizedAbsolutePath,
|
||||
getNormalizedPathComponents,
|
||||
@@ -9590,7 +9591,8 @@ export function usesExtensionsOnImports({ imports }: SourceFile, hasExtension: (
|
||||
/** @internal */
|
||||
export function getModuleSpecifierEndingPreference(preference: UserPreferences["importModuleSpecifierEnding"], resolutionMode: ResolutionMode, compilerOptions: CompilerOptions, sourceFile: SourceFile): ModuleSpecifierEnding {
|
||||
const moduleResolution = getEmitModuleResolutionKind(compilerOptions);
|
||||
if (preference === "js" || resolutionMode === ModuleKind.ESNext && ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext) {
|
||||
const moduleResolutionIsNodeNext = ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext;
|
||||
if (preference === "js" || resolutionMode === ModuleKind.ESNext && moduleResolutionIsNodeNext) {
|
||||
// Extensions are explicitly requested or required. Now choose between .js and .ts.
|
||||
if (!shouldAllowImportingTsExtension(compilerOptions)) {
|
||||
return ModuleSpecifierEnding.JsExtension;
|
||||
@@ -9621,19 +9623,27 @@ export function getModuleSpecifierEndingPreference(preference: UserPreferences["
|
||||
|
||||
function inferPreference() {
|
||||
let usesJsExtensions = false;
|
||||
const specifiers = sourceFile.imports.length ? sourceFile.imports.map(i => i.text) :
|
||||
isSourceFileJS(sourceFile) ? getRequiresAtTopOfFile(sourceFile).map(r => r.arguments[0].text) :
|
||||
const specifiers = sourceFile.imports.length ? sourceFile.imports :
|
||||
isSourceFileJS(sourceFile) ? getRequiresAtTopOfFile(sourceFile).map(r => r.arguments[0]) :
|
||||
emptyArray;
|
||||
for (const specifier of specifiers) {
|
||||
if (pathIsRelative(specifier)) {
|
||||
if (fileExtensionIsOneOf(specifier, extensionsNotSupportingExtensionlessResolution)) {
|
||||
if (pathIsRelative(specifier.text)) {
|
||||
if (
|
||||
moduleResolutionIsNodeNext &&
|
||||
resolutionMode === ModuleKind.CommonJS &&
|
||||
getModeForUsageLocation(sourceFile, specifier, compilerOptions) === ModuleKind.ESNext
|
||||
) {
|
||||
// We're trying to decide a preference for a CommonJS module specifier, but looking at an ESM import.
|
||||
continue;
|
||||
}
|
||||
if (fileExtensionIsOneOf(specifier.text, extensionsNotSupportingExtensionlessResolution)) {
|
||||
// These extensions are not optional, so do not indicate a preference.
|
||||
continue;
|
||||
}
|
||||
if (hasTSFileExtension(specifier)) {
|
||||
if (hasTSFileExtension(specifier.text)) {
|
||||
return ModuleSpecifierEnding.TsExtension;
|
||||
}
|
||||
if (hasJSFileExtension(specifier)) {
|
||||
if (hasJSFileExtension(specifier.text)) {
|
||||
usesJsExtensions = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,18 +258,18 @@ export interface ProgramHost<T extends BuilderProgram> {
|
||||
getModuleResolutionCache?(): ModuleResolutionCache | undefined;
|
||||
|
||||
jsDocParsingMode?: JSDocParsingMode;
|
||||
}
|
||||
/**
|
||||
* Internal interface used to wire emit through same host
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export interface ProgramHost<T extends BuilderProgram> {
|
||||
|
||||
// Internal interface used to wire emit through same host
|
||||
|
||||
// TODO: GH#18217 Optional methods are frequently asserted
|
||||
/** @internal */
|
||||
createDirectory?(path: string): void;
|
||||
/** @internal */
|
||||
writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
|
||||
// For testing
|
||||
/** @internal */
|
||||
storeFilesChangingSignatureDuringEmit?: boolean;
|
||||
/** @internal */
|
||||
now?(): Date;
|
||||
}
|
||||
|
||||
|
||||
@@ -1418,6 +1418,7 @@ export namespace Completion {
|
||||
"typeof",
|
||||
"unique",
|
||||
"unknown",
|
||||
"using",
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
@@ -1530,6 +1531,7 @@ export namespace Completion {
|
||||
"try",
|
||||
"type",
|
||||
"typeof",
|
||||
"using",
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
@@ -1635,6 +1637,7 @@ export namespace Completion {
|
||||
"typeof",
|
||||
"unique",
|
||||
"unknown",
|
||||
"using",
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
@@ -1686,6 +1689,7 @@ export namespace Completion {
|
||||
"try",
|
||||
"type",
|
||||
"typeof",
|
||||
"using",
|
||||
"var",
|
||||
"void",
|
||||
"while",
|
||||
|
||||
@@ -14,6 +14,9 @@ import * as vpath from "./_namespaces/vpath";
|
||||
import {
|
||||
incrementalVerifier,
|
||||
} from "./incrementalUtils";
|
||||
import {
|
||||
patchServiceForStateBaseline,
|
||||
} from "./projectServiceStateLogger";
|
||||
import {
|
||||
createLoggerWithInMemoryLogs,
|
||||
HarnessLSCouldNotResolveModule,
|
||||
@@ -595,6 +598,7 @@ class SessionServerHost implements ts.server.ServerHost {
|
||||
class FourslashSession extends ts.server.Session {
|
||||
constructor(opts: ts.server.SessionOptions, readonly baselineHost: (when: string) => void) {
|
||||
super(opts);
|
||||
patchServiceForStateBaseline(this.projectService);
|
||||
}
|
||||
getText(fileName: string) {
|
||||
return ts.getSnapshotText(this.projectService.getDefaultProjectForFile(ts.server.toNormalizedPath(fileName), /*ensureProject*/ true)!.getScriptSnapshot(fileName)!);
|
||||
@@ -609,6 +613,10 @@ class FourslashSession extends ts.server.Session {
|
||||
super.onMessage(message);
|
||||
this.baselineHost("After Request");
|
||||
}
|
||||
|
||||
getProjectService() {
|
||||
return this.projectService;
|
||||
}
|
||||
}
|
||||
|
||||
export class ServerLanguageServiceAdapter implements LanguageServiceAdapter {
|
||||
@@ -642,6 +650,10 @@ export class ServerLanguageServiceAdapter implements LanguageServiceAdapter {
|
||||
if (baseline.length) {
|
||||
this.logger.log(when);
|
||||
baseline.forEach(s => this.logger.log(s));
|
||||
this.server.getProjectService().baseline();
|
||||
}
|
||||
else {
|
||||
this.server.getProjectService().baseline(when);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,368 @@
|
||||
import {
|
||||
arrayFrom,
|
||||
compareStringsCaseSensitive,
|
||||
Debug,
|
||||
identity,
|
||||
isString,
|
||||
noop,
|
||||
} from "./_namespaces/ts";
|
||||
import {
|
||||
AutoImportProviderProject,
|
||||
AuxiliaryProject,
|
||||
isBackgroundProject,
|
||||
isConfiguredProject,
|
||||
LogLevel,
|
||||
Project,
|
||||
ProjectKind,
|
||||
ProjectService,
|
||||
ScriptInfo,
|
||||
SourceMapFileWatcher,
|
||||
TextStorage,
|
||||
} from "./_namespaces/ts.server";
|
||||
import {
|
||||
LoggerWithInMemoryLogs,
|
||||
} from "./tsserverLogger";
|
||||
|
||||
interface ProjectData {
|
||||
projectStateVersion: Project["projectStateVersion"];
|
||||
projectProgramVersion: Project["projectProgramVersion"];
|
||||
dirty: Project["dirty"];
|
||||
isClosed: ReturnType<Project["isClosed"]>;
|
||||
isOrphan: ReturnType<Project["isOrphan"]>;
|
||||
noOpenRef: boolean;
|
||||
autoImportProviderHost: Project["autoImportProviderHost"];
|
||||
noDtsResolutionProject: Project["noDtsResolutionProject"];
|
||||
originalConfiguredProjects: Project["originalConfiguredProjects"];
|
||||
}
|
||||
|
||||
interface SourceMapFileWatcherData {
|
||||
sourceInfos: SourceMapFileWatcher["sourceInfos"];
|
||||
}
|
||||
|
||||
interface ScriptInfoData {
|
||||
open: ReturnType<ScriptInfo["isScriptOpen"]>;
|
||||
version: ReturnType<TextStorage["getVersion"]>;
|
||||
pendingReloadFromDisk: TextStorage["pendingReloadFromDisk"];
|
||||
sourceMapFilePath: Exclude<ScriptInfo["sourceMapFilePath"], SourceMapFileWatcher> | SourceMapFileWatcherData | undefined;
|
||||
declarationInfoPath: ScriptInfo["declarationInfoPath"];
|
||||
sourceInfos: ScriptInfo["sourceInfos"];
|
||||
documentPositionMapper: ScriptInfo["documentPositionMapper"];
|
||||
containingProjects: Set<Project>;
|
||||
}
|
||||
|
||||
enum Diff {
|
||||
None = "",
|
||||
New = " *new*",
|
||||
Change = " *changed*",
|
||||
Deleted = " *deleted*",
|
||||
}
|
||||
|
||||
type StatePropertyLog = string | string[];
|
||||
type StateItemLog = [string, StatePropertyLog[]];
|
||||
|
||||
export function patchServiceForStateBaseline(service: ProjectService) {
|
||||
if (!service.logger.isTestLogger || !service.logger.hasLevel(LogLevel.verbose)) return;
|
||||
if (service.baseline !== noop) return; // Already patched
|
||||
|
||||
const projects = new Map<Project, ProjectData>();
|
||||
const scriptInfos = new Map<ScriptInfo, ScriptInfoData>();
|
||||
const logger = service.logger as LoggerWithInMemoryLogs;
|
||||
service.baseline = title => {
|
||||
const projectLogs = baselineProjects();
|
||||
const infoLogs = baselineScriptInfos();
|
||||
if (projectLogs?.length || infoLogs?.length) {
|
||||
if (title) logger.log(title);
|
||||
sendLogsToLogger("Projects::", projectLogs);
|
||||
sendLogsToLogger("ScriptInfos::", infoLogs);
|
||||
}
|
||||
};
|
||||
|
||||
function sendLogsToLogger(title: string, logs: StateItemLog[] | undefined) {
|
||||
if (!logs) return;
|
||||
logger.log(title);
|
||||
logs.sort((a, b) => compareStringsCaseSensitive(a[0], b[0]))
|
||||
.forEach(([title, propertyLogs]) => {
|
||||
logger.log(title);
|
||||
propertyLogs.forEach(p => isString(p) ? logger.log(p) : p.forEach(s => logger.log(s)));
|
||||
});
|
||||
logger.log("");
|
||||
}
|
||||
|
||||
function baselineProjects() {
|
||||
const autoImportProviderProjects = [] as AutoImportProviderProject[];
|
||||
const auxiliaryProjects = [] as AuxiliaryProject[];
|
||||
return baselineState(
|
||||
[service.externalProjects, service.configuredProjects, service.inferredProjects, autoImportProviderProjects, auxiliaryProjects],
|
||||
projects,
|
||||
(logs, project, data) => {
|
||||
if (project.autoImportProviderHost) autoImportProviderProjects.push(project.autoImportProviderHost);
|
||||
if (project.noDtsResolutionProject) auxiliaryProjects.push(project.noDtsResolutionProject);
|
||||
let projectDiff = newOrDeleted(project, projects, data);
|
||||
const projectPropertyLogs = [] as string[];
|
||||
projectDiff = printProperty(PrintPropertyWhen.Always, data, "projectStateVersion", project.projectStateVersion, projectDiff, projectPropertyLogs);
|
||||
projectDiff = printProperty(PrintPropertyWhen.Always, data, "projectProgramVersion", project.projectProgramVersion, projectDiff, projectPropertyLogs);
|
||||
projectDiff = printProperty(PrintPropertyWhen.TruthyOrChangedOrNew, data, "dirty", project.dirty, projectDiff, projectPropertyLogs);
|
||||
projectDiff = printProperty(PrintPropertyWhen.TruthyOrChangedOrNew, data, "isClosed", project.isClosed(), projectDiff, projectPropertyLogs);
|
||||
projectDiff = printProperty(PrintPropertyWhen.TruthyOrChangedOrNew, data, "isOrphan", !isBackgroundProject(project) && project.isOrphan(), projectDiff, projectPropertyLogs);
|
||||
projectDiff = printProperty(PrintPropertyWhen.TruthyOrChangedOrNew, data, "noOpenRef", isConfiguredProject(project) && !project.hasOpenRef(), projectDiff, projectPropertyLogs);
|
||||
projectDiff = printProperty(PrintPropertyWhen.DefinedOrChangedOrNew, data, "autoImportProviderHost", project.autoImportProviderHost, projectDiff, projectPropertyLogs, project.autoImportProviderHost ? project.autoImportProviderHost.projectName : project.autoImportProviderHost);
|
||||
projectDiff = printProperty(PrintPropertyWhen.DefinedOrChangedOrNew, data, "noDtsResolutionProject", project.noDtsResolutionProject, projectDiff, projectPropertyLogs, project.noDtsResolutionProject ? project.noDtsResolutionProject.projectName : project.noDtsResolutionProject);
|
||||
return printSetPropertyAndCreateStatementLog(
|
||||
logs,
|
||||
`${project.projectName} (${ProjectKind[project.projectKind]})`,
|
||||
PrintPropertyWhen.DefinedOrChangedOrNew,
|
||||
data?.originalConfiguredProjects,
|
||||
"originalConfiguredProjects",
|
||||
project.originalConfiguredProjects,
|
||||
projectDiff,
|
||||
projectPropertyLogs,
|
||||
identity,
|
||||
);
|
||||
},
|
||||
project => ({
|
||||
projectStateVersion: project.projectStateVersion,
|
||||
projectProgramVersion: project.projectProgramVersion,
|
||||
dirty: project.dirty,
|
||||
isClosed: project.isClosed(),
|
||||
isOrphan: !isBackgroundProject(project) && project.isOrphan(),
|
||||
noOpenRef: isConfiguredProject(project) && !project.hasOpenRef(),
|
||||
autoImportProviderHost: project.autoImportProviderHost,
|
||||
noDtsResolutionProject: project.noDtsResolutionProject,
|
||||
originalConfiguredProjects: project.originalConfiguredProjects && new Set(project.originalConfiguredProjects),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
function baselineScriptInfos() {
|
||||
return baselineState(
|
||||
[service.filenameToScriptInfo],
|
||||
scriptInfos,
|
||||
(logs, info, data) => {
|
||||
let infoDiff = newOrDeleted(info, scriptInfos, data);
|
||||
const infoPropertyLogs = [] as string[];
|
||||
const isOpen = info.isScriptOpen();
|
||||
infoDiff = printProperty(PrintPropertyWhen.Changed, data, "open", isOpen, infoDiff, infoPropertyLogs);
|
||||
infoDiff = printProperty(PrintPropertyWhen.Always, data, "version", info.textStorage.getVersion(), infoDiff, infoPropertyLogs);
|
||||
infoDiff = printProperty(PrintPropertyWhen.TruthyOrChangedOrNew, data, "pendingReloadFromDisk", info.textStorage.pendingReloadFromDisk, infoDiff, infoPropertyLogs);
|
||||
infoDiff = printScriptInfoSourceMapFilePath(data, info, infoDiff, infoPropertyLogs);
|
||||
infoDiff = printProperty(PrintPropertyWhen.DefinedOrChangedOrNew, data, "declarationInfoPath", info.declarationInfoPath, infoDiff, infoPropertyLogs);
|
||||
infoDiff = printSetPropertyValueWorker(PrintPropertyWhen.DefinedOrChangedOrNew, data?.sourceInfos, "sourceInfos", info.sourceInfos, infoDiff, infoPropertyLogs, identity);
|
||||
infoDiff = printProperty(PrintPropertyWhen.DefinedOrChangedOrNew, data, "documentPositionMapper", info.documentPositionMapper, infoDiff, infoPropertyLogs, info.documentPositionMapper ? "DocumentPositionMapper" : undefined);
|
||||
let defaultProject: Project | undefined;
|
||||
try {
|
||||
if (isOpen) defaultProject = info.getDefaultProject();
|
||||
}
|
||||
catch (e) {
|
||||
Debug.assert(e.message === "No Project.");
|
||||
}
|
||||
return printSetPropertyAndCreateStatementLog(
|
||||
logs,
|
||||
`${info.fileName}${info.isDynamic ? " (Dynamic)" : ""}${isOpen ? " (Open)" : ""}`,
|
||||
PrintPropertyWhen.Always,
|
||||
data?.containingProjects,
|
||||
"containingProjects",
|
||||
new Set(info.containingProjects),
|
||||
infoDiff,
|
||||
infoPropertyLogs,
|
||||
project => `${project.projectName}${defaultProject === project ? " *default*" : ""}`,
|
||||
);
|
||||
},
|
||||
info => ({
|
||||
open: info.isScriptOpen(),
|
||||
version: info.textStorage.getVersion(),
|
||||
pendingReloadFromDisk: info.textStorage.pendingReloadFromDisk,
|
||||
sourceMapFilePath: info.sourceMapFilePath && !isString(info.sourceMapFilePath) ?
|
||||
{ original: info.sourceMapFilePath, sourceInfos: new Set(info.sourceMapFilePath.sourceInfos) } :
|
||||
info.sourceMapFilePath,
|
||||
declarationInfoPath: info.declarationInfoPath,
|
||||
sourceInfos: info.sourceInfos && new Set(info.sourceInfos),
|
||||
documentPositionMapper: info.documentPositionMapper,
|
||||
containingProjects: new Set(info.containingProjects),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
function baselineState<T, Data>(
|
||||
currentCaches: (T[] | Map<any, T>)[],
|
||||
dataMap: Map<T, Data>,
|
||||
printWorker: (logs: StateItemLog[], current: T, data: Data | undefined) => Diff,
|
||||
toData: (current: T) => Data,
|
||||
) {
|
||||
const logs = [] as StateItemLog[];
|
||||
let hasChange = false;
|
||||
const currentSet = new Set<T>();
|
||||
currentCaches.forEach(currentCache => currentCache.forEach(printCurrent));
|
||||
if (currentSet.size !== dataMap.size) {
|
||||
for (const [key, data] of arrayFrom(dataMap.entries())) {
|
||||
if (!currentSet.has(key)) {
|
||||
dataMap.delete(key);
|
||||
printWorker(logs, key, data);
|
||||
}
|
||||
}
|
||||
hasChange = true;
|
||||
}
|
||||
return hasChange ? logs : undefined;
|
||||
|
||||
function printCurrent(current: T) {
|
||||
if (!current) return;
|
||||
currentSet.add(current);
|
||||
if (printWorker(logs, current, dataMap.get(current))) {
|
||||
hasChange = true;
|
||||
dataMap.set(current, toData(current));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function newOrDeleted<T, Data>(current: T, dataMap: Map<T, Data>, data: Data | undefined) {
|
||||
return !data ? Diff.New : !dataMap.has(current) ? Diff.Deleted : Diff.None;
|
||||
}
|
||||
|
||||
enum PrintPropertyWhen {
|
||||
Always,
|
||||
TruthyOrChangedOrNew,
|
||||
Changed,
|
||||
DefinedOrChangedOrNew,
|
||||
}
|
||||
function printProperty<Data, Key extends keyof Data & string>(
|
||||
printWhen: PrintPropertyWhen,
|
||||
data: Data | undefined,
|
||||
key: Key,
|
||||
value: Data[Key],
|
||||
dataDiff: Diff,
|
||||
propertyLogs: StatePropertyLog[],
|
||||
stringValue?: Data[Key] | string,
|
||||
) {
|
||||
return printPropertyWorker(
|
||||
printWhen,
|
||||
value,
|
||||
!!data && data[key] !== value,
|
||||
Diff.Change,
|
||||
dataDiff,
|
||||
propertyLogs,
|
||||
`${key}: ${stringValue === undefined ? value : stringValue}`,
|
||||
);
|
||||
}
|
||||
|
||||
function printSetPropertyValueWorker<T>(
|
||||
printWhen: PrintPropertyWhen.Always | PrintPropertyWhen.DefinedOrChangedOrNew,
|
||||
dataValue: Set<T> | undefined,
|
||||
propertyName: string,
|
||||
propertyValue: Set<T> | undefined,
|
||||
dataDiff: Diff,
|
||||
propertyLogs: StatePropertyLog[],
|
||||
toStringPropertyValue: (v: T) => string,
|
||||
) {
|
||||
const setPropertyLogs = [] as string[];
|
||||
let setPropertyDiff = Diff.None;
|
||||
propertyValue?.forEach(p =>
|
||||
setPropertyDiff = printPropertyWorker(
|
||||
PrintPropertyWhen.Always,
|
||||
p,
|
||||
dataDiff !== Diff.New && !dataValue?.has(p),
|
||||
Diff.New,
|
||||
setPropertyDiff,
|
||||
setPropertyLogs,
|
||||
` ${toStringPropertyValue(p)}`,
|
||||
)
|
||||
);
|
||||
dataValue?.forEach(p => {
|
||||
if (propertyValue?.has(p)) return;
|
||||
setPropertyDiff = Diff.Change;
|
||||
setPropertyLogs.push(` ${toStringPropertyValue(p)}${Diff.Deleted}`);
|
||||
});
|
||||
dataDiff = printPropertyWorker(
|
||||
printWhen,
|
||||
propertyValue,
|
||||
!!setPropertyDiff,
|
||||
Diff.Change,
|
||||
dataDiff,
|
||||
propertyLogs,
|
||||
`${propertyName}: ${propertyValue?.size || 0}`,
|
||||
);
|
||||
propertyLogs.push(setPropertyLogs);
|
||||
return dataDiff;
|
||||
}
|
||||
|
||||
function printPropertyWorker(
|
||||
printWhen: PrintPropertyWhen,
|
||||
value: any,
|
||||
propertyChanged: boolean,
|
||||
propertyChangeDiff: Diff.Change | Diff.New,
|
||||
dataDiff: Diff,
|
||||
propertyLogs: StatePropertyLog[],
|
||||
stringValue: string,
|
||||
) {
|
||||
const propertyDiff = propertyChanged ? propertyChangeDiff : Diff.None;
|
||||
const result = !dataDiff && propertyDiff ? propertyChangeDiff : dataDiff;
|
||||
switch (printWhen) {
|
||||
case PrintPropertyWhen.Changed:
|
||||
if (!propertyDiff) return result;
|
||||
break;
|
||||
case PrintPropertyWhen.TruthyOrChangedOrNew:
|
||||
if (!value && !propertyDiff) return result;
|
||||
break;
|
||||
case PrintPropertyWhen.Always:
|
||||
break;
|
||||
case PrintPropertyWhen.DefinedOrChangedOrNew:
|
||||
if (value === undefined && !propertyDiff) return result;
|
||||
break;
|
||||
default:
|
||||
Debug.assertNever(printWhen);
|
||||
}
|
||||
propertyLogs.push(` ${stringValue}${propertyDiff}`);
|
||||
return result;
|
||||
}
|
||||
|
||||
function printSetPropertyAndCreateStatementLog<T>(
|
||||
logs: StateItemLog[],
|
||||
header: string,
|
||||
printWhen: PrintPropertyWhen.Always | PrintPropertyWhen.DefinedOrChangedOrNew,
|
||||
dataValue: Set<T> | undefined,
|
||||
propertyName: string,
|
||||
propertyValue: Set<T> | undefined,
|
||||
dataDiff: Diff,
|
||||
propertyLogs: StatePropertyLog[],
|
||||
toStringPropertyValue: (v: T) => string,
|
||||
) {
|
||||
dataDiff = printSetPropertyValueWorker(
|
||||
printWhen,
|
||||
dataValue,
|
||||
propertyName,
|
||||
propertyValue,
|
||||
dataDiff,
|
||||
propertyLogs,
|
||||
toStringPropertyValue,
|
||||
);
|
||||
logs.push([
|
||||
`${header}${dataDiff}`,
|
||||
propertyLogs,
|
||||
]);
|
||||
return dataDiff;
|
||||
}
|
||||
|
||||
function printScriptInfoSourceMapFilePath(
|
||||
data: ScriptInfoData | undefined,
|
||||
info: ScriptInfo,
|
||||
infoDiff: Diff,
|
||||
infoPropertyLogs: StatePropertyLog[],
|
||||
) {
|
||||
return !info.sourceMapFilePath || isString(info.sourceMapFilePath) ?
|
||||
printProperty(
|
||||
PrintPropertyWhen.DefinedOrChangedOrNew,
|
||||
data,
|
||||
"sourceMapFilePath",
|
||||
info.sourceMapFilePath,
|
||||
infoDiff,
|
||||
infoPropertyLogs,
|
||||
) :
|
||||
printSetPropertyValueWorker(
|
||||
PrintPropertyWhen.DefinedOrChangedOrNew,
|
||||
data?.sourceMapFilePath && !isString(data?.sourceMapFilePath) ? data.sourceMapFilePath.sourceInfos : undefined,
|
||||
"sourceMapFilePath sourceInfos",
|
||||
info.sourceMapFilePath.sourceInfos,
|
||||
infoDiff,
|
||||
infoPropertyLogs,
|
||||
identity,
|
||||
);
|
||||
}
|
||||
}
|
||||
+132
-145
@@ -85,6 +85,7 @@ import {
|
||||
normalizeSlashes,
|
||||
optionDeclarations,
|
||||
optionsForWatch,
|
||||
orderedRemoveItem,
|
||||
PackageJsonAutoImportPreference,
|
||||
ParsedCommandLine,
|
||||
parseJsonSourceFileConfigFileContent,
|
||||
@@ -504,7 +505,7 @@ export function convertScriptKindName(scriptKindName: protocol.ScriptKindName) {
|
||||
|
||||
/** @internal */
|
||||
export function convertUserPreferences(preferences: protocol.UserPreferences): UserPreferences {
|
||||
const { lazyConfiguredProjectsFromExternalProject, ...userPreferences } = preferences;
|
||||
const { lazyConfiguredProjectsFromExternalProject: _, ...userPreferences } = preferences;
|
||||
return userPreferences;
|
||||
}
|
||||
|
||||
@@ -1029,7 +1030,7 @@ export class ProjectService {
|
||||
/**
|
||||
* maps external project file name to list of config files that were the part of this project
|
||||
*/
|
||||
private readonly externalProjectToConfiguredProjectMap = new Map<string, NormalizedPath[]>();
|
||||
private readonly externalProjectToConfiguredProjectMap = new Map<string, Set<ConfiguredProject>>();
|
||||
|
||||
/**
|
||||
* external projects (configuration and list of root files is not controlled by tsserver)
|
||||
@@ -1139,6 +1140,7 @@ export class ProjectService {
|
||||
private pendingPluginEnablements?: Map<Project, Promise<BeginEnablePluginResult>[]>;
|
||||
private currentPluginEnablementPromise?: Promise<void>;
|
||||
|
||||
/** @internal */ baseline: (title?: string) => void = noop;
|
||||
/** @internal */ verifyDocumentRegistry = noop;
|
||||
/** @internal */ verifyProgram: (project: Project) => void = noop;
|
||||
/** @internal */ onProjectCreation: (project: Project) => void = noop;
|
||||
@@ -1881,7 +1883,7 @@ export class ProjectService {
|
||||
project.addRoot(info);
|
||||
if (info.containingProjects[0] !== project) {
|
||||
// Ensure this is first project, we could be in this scenario because info could be part of orphan project
|
||||
info.detachFromProject(project);
|
||||
orderedRemoveItem(info.containingProjects, project);
|
||||
info.containingProjects.unshift(project);
|
||||
}
|
||||
project.updateGraph();
|
||||
@@ -2286,8 +2288,7 @@ export class ProjectService {
|
||||
* otherwise just file name
|
||||
*/
|
||||
private getConfigFileNameForFile(info: OpenScriptInfoOrClosedOrConfigFileInfo) {
|
||||
if (isOpenScriptInfo(info)) {
|
||||
Debug.assert(info.isScriptOpen());
|
||||
if (!isAncestorConfigFileInfo(info)) {
|
||||
const result = this.configFileForOpenFiles.get(info.path);
|
||||
if (result !== undefined) return result || undefined;
|
||||
}
|
||||
@@ -3427,15 +3428,18 @@ export class ProjectService {
|
||||
this.hostConfiguration.preferences = { ...this.hostConfiguration.preferences, ...args.preferences };
|
||||
if (lazyConfiguredProjectsFromExternalProject && !this.hostConfiguration.preferences.lazyConfiguredProjectsFromExternalProject) {
|
||||
// Load configured projects for external projects that are pending reload
|
||||
this.configuredProjects.forEach(project => {
|
||||
if (
|
||||
project.hasExternalProjectRef() &&
|
||||
project.pendingUpdateLevel === ProgramUpdateLevel.Full &&
|
||||
!this.pendingProjectUpdates.has(project.getProjectName())
|
||||
) {
|
||||
project.updateGraph();
|
||||
}
|
||||
});
|
||||
this.externalProjectToConfiguredProjectMap.forEach(projects =>
|
||||
projects.forEach(project => {
|
||||
if (
|
||||
!project.isClosed() &&
|
||||
project.hasExternalProjectRef() &&
|
||||
project.pendingUpdateLevel === ProgramUpdateLevel.Full &&
|
||||
!this.pendingProjectUpdates.has(project.getProjectName())
|
||||
) {
|
||||
project.updateGraph();
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
if (includePackageJsonAutoImports !== args.preferences.includePackageJsonAutoImports) {
|
||||
this.forEachProject(project => {
|
||||
@@ -3513,6 +3517,9 @@ export class ProjectService {
|
||||
});
|
||||
this.inferredProjects.forEach(project => this.clearSemanticCache(project));
|
||||
this.ensureProjectForOpenFiles();
|
||||
|
||||
this.logger.info("After reloading projects..");
|
||||
this.printProjects();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4184,24 +4191,23 @@ export class ProjectService {
|
||||
}
|
||||
}
|
||||
|
||||
private closeConfiguredProjectReferencedFromExternalProject(configFile: NormalizedPath) {
|
||||
const configuredProject = this.findConfiguredProjectByProjectName(configFile);
|
||||
if (configuredProject) {
|
||||
configuredProject.deleteExternalProjectReference();
|
||||
if (!configuredProject.hasOpenRef()) {
|
||||
this.removeProject(configuredProject);
|
||||
return;
|
||||
private closeConfiguredProjectReferencedFromExternalProject(configuredProjects: Set<ConfiguredProject> | undefined) {
|
||||
configuredProjects?.forEach(configuredProject => {
|
||||
if (!configuredProject.isClosed()) {
|
||||
configuredProject.deleteExternalProjectReference();
|
||||
if (!configuredProject.hasOpenRef()) this.removeProject(configuredProject);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
closeExternalProject(uncheckedFileName: string): void {
|
||||
closeExternalProject(uncheckedFileName: string): void;
|
||||
/** @internal */
|
||||
closeExternalProject(uncheckedFileName: string, print: boolean): void;
|
||||
closeExternalProject(uncheckedFileName: string, print?: boolean): void {
|
||||
const fileName = toNormalizedPath(uncheckedFileName);
|
||||
const configFiles = this.externalProjectToConfiguredProjectMap.get(fileName);
|
||||
if (configFiles) {
|
||||
for (const configFile of configFiles) {
|
||||
this.closeConfiguredProjectReferencedFromExternalProject(configFile);
|
||||
}
|
||||
const configuredProjects = this.externalProjectToConfiguredProjectMap.get(fileName);
|
||||
if (configuredProjects) {
|
||||
this.closeConfiguredProjectReferencedFromExternalProject(configuredProjects);
|
||||
this.externalProjectToConfiguredProjectMap.delete(fileName);
|
||||
}
|
||||
else {
|
||||
@@ -4211,6 +4217,7 @@ export class ProjectService {
|
||||
this.removeProject(externalProject);
|
||||
}
|
||||
}
|
||||
if (print) this.printProjects();
|
||||
}
|
||||
|
||||
openExternalProjects(projects: protocol.ExternalProject[]): void {
|
||||
@@ -4221,15 +4228,17 @@ export class ProjectService {
|
||||
});
|
||||
|
||||
for (const externalProject of projects) {
|
||||
this.openExternalProject(externalProject);
|
||||
this.openExternalProject(externalProject, /*print*/ false);
|
||||
// delete project that is present in input list
|
||||
projectsToClose.delete(externalProject.projectFileName);
|
||||
}
|
||||
|
||||
// close projects that were missing in the input list
|
||||
forEachKey(projectsToClose, externalProjectName => {
|
||||
this.closeExternalProject(externalProjectName);
|
||||
this.closeExternalProject(externalProjectName, /*print*/ false);
|
||||
});
|
||||
|
||||
this.printProjects();
|
||||
}
|
||||
|
||||
/** Makes a filename safe to insert in a RegExp */
|
||||
@@ -4243,20 +4252,21 @@ export class ProjectService {
|
||||
}
|
||||
|
||||
applySafeList(proj: protocol.ExternalProject): NormalizedPath[] {
|
||||
const { rootFiles } = proj;
|
||||
const typeAcquisition = proj.typeAcquisition!;
|
||||
Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now");
|
||||
const result = this.applySafeListWorker(proj, proj.rootFiles, typeAcquisition);
|
||||
return result?.excludedFiles ?? [];
|
||||
}
|
||||
|
||||
private applySafeListWorker(proj: protocol.ExternalProject, rootFiles: protocol.ExternalFile[], typeAcquisition: TypeAcquisition) {
|
||||
if (typeAcquisition.enable === false || typeAcquisition.disableFilenameBasedTypeAcquisition) {
|
||||
return [];
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const typeAcqInclude = typeAcquisition.include || (typeAcquisition.include = []);
|
||||
const excludeRules: string[] = [];
|
||||
|
||||
const normalizedNames = rootFiles.map(f => normalizeSlashes(f.fileName)) as NormalizedPath[];
|
||||
const excludedFiles: NormalizedPath[] = [];
|
||||
|
||||
for (const name of Object.keys(this.safelist)) {
|
||||
const rule = this.safelist[name];
|
||||
for (const root of normalizedNames) {
|
||||
@@ -4310,13 +4320,13 @@ export class ProjectService {
|
||||
}
|
||||
|
||||
const excludeRegexes = excludeRules.map(e => new RegExp(e, "i"));
|
||||
const filesToKeep: protocol.ExternalFile[] = [];
|
||||
for (let i = 0; i < proj.rootFiles.length; i++) {
|
||||
let filesToKeep: protocol.ExternalFile[] | undefined;
|
||||
let excludedFiles: NormalizedPath[] | undefined;
|
||||
for (let i = 0; i < rootFiles.length; i++) {
|
||||
if (excludeRegexes.some(re => re.test(normalizedNames[i]))) {
|
||||
excludedFiles.push(normalizedNames[i]);
|
||||
addExcludedFile(i);
|
||||
}
|
||||
else {
|
||||
let exclude = false;
|
||||
if (typeAcquisition.enable) {
|
||||
const baseName = getBaseFileName(toFileNameLowerCase(normalizedNames[i]));
|
||||
if (fileExtensionIs(baseName, "js")) {
|
||||
@@ -4325,49 +4335,68 @@ export class ProjectService {
|
||||
const typeName = this.legacySafelist.get(cleanedTypingName);
|
||||
if (typeName !== undefined) {
|
||||
this.logger.info(`Excluded '${normalizedNames[i]}' because it matched ${cleanedTypingName} from the legacy safelist`);
|
||||
excludedFiles.push(normalizedNames[i]);
|
||||
addExcludedFile(i);
|
||||
// *exclude* it from the project...
|
||||
exclude = true;
|
||||
// ... but *include* it in the list of types to acquire
|
||||
// Same best-effort dedupe as above
|
||||
if (!typeAcqInclude.includes(typeName)) {
|
||||
typeAcqInclude.push(typeName);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!exclude) {
|
||||
// Exclude any minified files that get this far
|
||||
if (/^.+[.-]min\.js$/.test(normalizedNames[i])) {
|
||||
excludedFiles.push(normalizedNames[i]);
|
||||
}
|
||||
else {
|
||||
filesToKeep.push(proj.rootFiles[i]);
|
||||
}
|
||||
// Exclude any minified files that get this far
|
||||
if (/^.+[.-]min\.js$/.test(normalizedNames[i])) {
|
||||
addExcludedFile(i);
|
||||
}
|
||||
else {
|
||||
filesToKeep?.push(rootFiles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
proj.rootFiles = filesToKeep;
|
||||
return excludedFiles;
|
||||
|
||||
return excludedFiles ? {
|
||||
rootFiles: filesToKeep!,
|
||||
excludedFiles,
|
||||
} : undefined;
|
||||
|
||||
function addExcludedFile(index: number) {
|
||||
if (!excludedFiles) {
|
||||
Debug.assert(!filesToKeep);
|
||||
filesToKeep = rootFiles.slice(0, index);
|
||||
excludedFiles = [];
|
||||
}
|
||||
excludedFiles.push(normalizedNames[index]);
|
||||
}
|
||||
}
|
||||
|
||||
openExternalProject(proj: protocol.ExternalProject): void {
|
||||
proj.typeAcquisition = proj.typeAcquisition || {};
|
||||
proj.typeAcquisition.include = proj.typeAcquisition.include || [];
|
||||
proj.typeAcquisition.exclude = proj.typeAcquisition.exclude || [];
|
||||
if (proj.typeAcquisition.enable === undefined) {
|
||||
proj.typeAcquisition.enable = hasNoTypeScriptSource(proj.rootFiles.map(f => f.fileName));
|
||||
}
|
||||
openExternalProject(proj: protocol.ExternalProject): void;
|
||||
/** @internal */
|
||||
openExternalProject(proj: protocol.ExternalProject, print: boolean): void;
|
||||
openExternalProject(proj: protocol.ExternalProject, print?: boolean): void {
|
||||
const existingExternalProject = this.findExternalProjectByProjectName(proj.projectFileName);
|
||||
const existingConfiguredProjects = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName);
|
||||
|
||||
const excludedFiles = this.applySafeList(proj);
|
||||
|
||||
let tsConfigFiles: NormalizedPath[] | undefined;
|
||||
const rootFiles: protocol.ExternalFile[] = [];
|
||||
let configuredProjects: Set<ConfiguredProject> | undefined;
|
||||
let rootFiles: protocol.ExternalFile[] = [];
|
||||
for (const file of proj.rootFiles) {
|
||||
const normalized = toNormalizedPath(file.fileName);
|
||||
if (getBaseConfigFileName(normalized)) {
|
||||
if (this.serverMode === LanguageServiceMode.Semantic && this.host.fileExists(normalized)) {
|
||||
(tsConfigFiles || (tsConfigFiles = [])).push(normalized);
|
||||
let project = this.findConfiguredProjectByProjectName(normalized);
|
||||
if (!project) {
|
||||
// errors are stored in the project, do not need to update the graph
|
||||
project = this.getHostPreferences().lazyConfiguredProjectsFromExternalProject ?
|
||||
this.createConfiguredProjectWithDelayLoad(normalized, `Creating configured project in external project: ${proj.projectFileName}`) :
|
||||
this.createLoadAndUpdateConfiguredProject(normalized, `Creating configured project in external project: ${proj.projectFileName}`);
|
||||
}
|
||||
if (!existingConfiguredProjects?.has(project)) {
|
||||
// keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project
|
||||
project.addExternalProjectReference();
|
||||
}
|
||||
(configuredProjects ??= new Set()).add(project);
|
||||
existingConfiguredProjects?.delete(project);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -4375,95 +4404,53 @@ export class ProjectService {
|
||||
}
|
||||
}
|
||||
|
||||
// sort config files to simplify comparison later
|
||||
if (tsConfigFiles) {
|
||||
tsConfigFiles.sort();
|
||||
}
|
||||
|
||||
const externalProject = this.findExternalProjectByProjectName(proj.projectFileName);
|
||||
let exisingConfigFiles: string[] | undefined;
|
||||
if (externalProject) {
|
||||
externalProject.excludedFiles = excludedFiles;
|
||||
if (!tsConfigFiles) {
|
||||
const compilerOptions = convertCompilerOptions(proj.options);
|
||||
const watchOptionsAndErrors = convertWatchOptions(proj.options, externalProject.getCurrentDirectory());
|
||||
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader);
|
||||
if (lastFileExceededProgramSize) {
|
||||
externalProject.disableLanguageService(lastFileExceededProgramSize);
|
||||
}
|
||||
else {
|
||||
externalProject.enableLanguageService();
|
||||
}
|
||||
externalProject.setProjectErrors(watchOptionsAndErrors?.errors);
|
||||
// external project already exists and not config files were added - update the project and return;
|
||||
// The graph update here isnt postponed since any file open operation needs all updated external projects
|
||||
this.updateRootAndOptionsOfNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, compilerOptions, proj.typeAcquisition, proj.options.compileOnSave, watchOptionsAndErrors?.watchOptions);
|
||||
externalProject.updateGraph();
|
||||
return;
|
||||
}
|
||||
// some config files were added to external project (that previously were not there)
|
||||
// close existing project and later we'll open a set of configured projects for these files
|
||||
this.closeExternalProject(proj.projectFileName);
|
||||
}
|
||||
else if (this.externalProjectToConfiguredProjectMap.get(proj.projectFileName)) {
|
||||
// this project used to include config files
|
||||
if (!tsConfigFiles) {
|
||||
// config files were removed from the project - close existing external project which in turn will close configured projects
|
||||
this.closeExternalProject(proj.projectFileName);
|
||||
}
|
||||
else {
|
||||
// project previously had some config files - compare them with new set of files and close all configured projects that correspond to unused files
|
||||
const oldConfigFiles = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName)!;
|
||||
let iNew = 0;
|
||||
let iOld = 0;
|
||||
while (iNew < tsConfigFiles.length && iOld < oldConfigFiles.length) {
|
||||
const newConfig = tsConfigFiles[iNew];
|
||||
const oldConfig = oldConfigFiles[iOld];
|
||||
if (oldConfig < newConfig) {
|
||||
this.closeConfiguredProjectReferencedFromExternalProject(oldConfig);
|
||||
iOld++;
|
||||
}
|
||||
else if (oldConfig > newConfig) {
|
||||
iNew++;
|
||||
}
|
||||
else {
|
||||
// record existing config files so avoid extra add-refs
|
||||
(exisingConfigFiles || (exisingConfigFiles = [])).push(oldConfig);
|
||||
iOld++;
|
||||
iNew++;
|
||||
}
|
||||
}
|
||||
for (let i = iOld; i < oldConfigFiles.length; i++) {
|
||||
// projects for all remaining old config files should be closed
|
||||
this.closeConfiguredProjectReferencedFromExternalProject(oldConfigFiles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tsConfigFiles) {
|
||||
if (configuredProjects) {
|
||||
// store the list of tsconfig files that belong to the external project
|
||||
this.externalProjectToConfiguredProjectMap.set(proj.projectFileName, tsConfigFiles);
|
||||
for (const tsconfigFile of tsConfigFiles) {
|
||||
let project = this.findConfiguredProjectByProjectName(tsconfigFile);
|
||||
if (!project) {
|
||||
// errors are stored in the project, do not need to update the graph
|
||||
project = this.getHostPreferences().lazyConfiguredProjectsFromExternalProject ?
|
||||
this.createConfiguredProjectWithDelayLoad(tsconfigFile, `Creating configured project in external project: ${proj.projectFileName}`) :
|
||||
this.createLoadAndUpdateConfiguredProject(tsconfigFile, `Creating configured project in external project: ${proj.projectFileName}`);
|
||||
}
|
||||
if (project && !contains(exisingConfigFiles, tsconfigFile)) {
|
||||
// keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project
|
||||
project.addExternalProjectReference();
|
||||
}
|
||||
}
|
||||
this.externalProjectToConfiguredProjectMap.set(proj.projectFileName, configuredProjects);
|
||||
// Close external project if present
|
||||
if (existingExternalProject) this.removeProject(existingExternalProject);
|
||||
}
|
||||
else {
|
||||
// no config files - remove the item from the collection
|
||||
// Create external project and update its graph, do not delay update since
|
||||
// any file open operation needs all updated external projects
|
||||
this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName);
|
||||
const project = this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition, excludedFiles);
|
||||
project.updateGraph();
|
||||
const typeAcquisition = proj.typeAcquisition || {};
|
||||
typeAcquisition.include = typeAcquisition.include || [];
|
||||
typeAcquisition.exclude = typeAcquisition.exclude || [];
|
||||
if (typeAcquisition.enable === undefined) {
|
||||
typeAcquisition.enable = hasNoTypeScriptSource(rootFiles.map(f => f.fileName));
|
||||
}
|
||||
const excludeResult = this.applySafeListWorker(proj, rootFiles, typeAcquisition);
|
||||
const excludedFiles = excludeResult?.excludedFiles ?? [];
|
||||
rootFiles = excludeResult?.rootFiles ?? rootFiles;
|
||||
if (existingExternalProject) {
|
||||
existingExternalProject.excludedFiles = excludedFiles;
|
||||
const compilerOptions = convertCompilerOptions(proj.options);
|
||||
const watchOptionsAndErrors = convertWatchOptions(proj.options, existingExternalProject.getCurrentDirectory());
|
||||
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, rootFiles, externalFilePropertyReader);
|
||||
if (lastFileExceededProgramSize) {
|
||||
existingExternalProject.disableLanguageService(lastFileExceededProgramSize);
|
||||
}
|
||||
else {
|
||||
existingExternalProject.enableLanguageService();
|
||||
}
|
||||
existingExternalProject.setProjectErrors(watchOptionsAndErrors?.errors);
|
||||
// external project already exists and not config files were added - update the project and return;
|
||||
// The graph update here isnt postponed since any file open operation needs all updated external projects
|
||||
this.updateRootAndOptionsOfNonInferredProject(existingExternalProject, rootFiles, externalFilePropertyReader, compilerOptions, typeAcquisition, proj.options.compileOnSave, watchOptionsAndErrors?.watchOptions);
|
||||
existingExternalProject.updateGraph();
|
||||
}
|
||||
else {
|
||||
// Create external project and update its graph, do not delay update since
|
||||
// any file open operation needs all updated external projects
|
||||
const project = this.createExternalProject(proj.projectFileName, rootFiles, proj.options, typeAcquisition, excludedFiles);
|
||||
project.updateGraph();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove unused configured projects
|
||||
this.closeConfiguredProjectReferencedFromExternalProject(existingConfiguredProjects);
|
||||
|
||||
if (print) this.printProjects();
|
||||
}
|
||||
|
||||
hasDeferredExtension() {
|
||||
|
||||
@@ -372,15 +372,17 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
/**
|
||||
* Current project's program version. (incremented everytime new program is created that is not complete reuse from the old one)
|
||||
* This property is changed in 'updateGraph' based on the set of files in program
|
||||
* @internal
|
||||
*/
|
||||
private projectProgramVersion = 0;
|
||||
projectProgramVersion = 0;
|
||||
/**
|
||||
* Current version of the project state. It is changed when:
|
||||
* - new root file was added/removed
|
||||
* - edit happen in some file that is currently included in the project.
|
||||
* This property is different from projectStructureVersion since in most cases edits don't affect set of files in the project
|
||||
* @internal
|
||||
*/
|
||||
private projectStateVersion = 0;
|
||||
projectStateVersion = 0;
|
||||
|
||||
protected projectErrors: Diagnostic[] | undefined;
|
||||
|
||||
@@ -1664,7 +1666,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
);
|
||||
const elapsed = timestamp() - start;
|
||||
this.sendPerformanceEvent("UpdateGraph", elapsed);
|
||||
this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} Version: ${this.getProjectVersion()} structureChanged: ${hasNewProgram}${this.program ? ` structureIsReused:: ${(ts as any).StructureIsReused[this.program.structureIsReused]}` : ""} Elapsed: ${elapsed}ms`);
|
||||
this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} projectStateVersion: ${this.projectStateVersion} projectProgramVersion: ${this.projectProgramVersion} structureChanged: ${hasNewProgram}${this.program ? ` structureIsReused:: ${(ts as any).StructureIsReused[this.program.structureIsReused]}` : ""} Elapsed: ${elapsed}ms`);
|
||||
if (this.projectService.logger.isTestLogger) {
|
||||
if (this.program !== oldProgram) {
|
||||
this.print(/*writeProjectFileNames*/ true, this.hasAddedorRemovedFiles, /*writeFileVersionAndText*/ true);
|
||||
@@ -1836,6 +1838,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
if (this.autoImportProviderHost) {
|
||||
this.autoImportProviderHost.print(/*writeProjectFileNames*/ false, /*writeFileExplaination*/ false, /*writeFileVersionAndText*/ false);
|
||||
}
|
||||
this.noDtsResolutionProject?.print(/*writeProjectFileNames*/ false, /*writeFileExplaination*/ false, /*writeFileVersionAndText*/ false);
|
||||
}
|
||||
|
||||
setCompilerOptions(compilerOptions: CompilerOptions) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
IScriptSnapshot,
|
||||
isString,
|
||||
LineInfo,
|
||||
orderedRemoveItem,
|
||||
Path,
|
||||
ScriptKind,
|
||||
ScriptSnapshot,
|
||||
@@ -32,7 +33,6 @@ import {
|
||||
SourceFile,
|
||||
SourceFileLike,
|
||||
TextSpan,
|
||||
unorderedRemoveItem,
|
||||
} from "./_namespaces/ts";
|
||||
import {
|
||||
AbsolutePositionAndLineText,
|
||||
@@ -93,7 +93,7 @@ export class TextStorage {
|
||||
/**
|
||||
* True when reloading contents of file from the disk is pending
|
||||
*/
|
||||
private pendingReloadFromDisk = false;
|
||||
pendingReloadFromDisk = false;
|
||||
|
||||
constructor(private readonly host: ServerHost, private readonly info: ScriptInfo, initialVersion?: number) {
|
||||
this.version = initialVersion || 0;
|
||||
@@ -536,7 +536,8 @@ export class ScriptInfo {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (unorderedRemoveItem(this.containingProjects, project)) {
|
||||
// We use first configured project as default so we shouldnt change the order of the containing projects
|
||||
if (orderedRemoveItem(this.containingProjects, project)) {
|
||||
project.onFileAddedOrRemoved(this.isSymlink());
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -3190,7 +3190,7 @@ export class Session<TMessage = string> implements EventSender {
|
||||
return this.requiredResponse(response);
|
||||
},
|
||||
[protocol.CommandTypes.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => {
|
||||
this.projectService.openExternalProject(request.arguments);
|
||||
this.projectService.openExternalProject(request.arguments, /*print*/ true);
|
||||
// TODO: GH#20447 report errors
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
@@ -3200,7 +3200,7 @@ export class Session<TMessage = string> implements EventSender {
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
[protocol.CommandTypes.CloseExternalProject]: (request: protocol.CloseExternalProjectRequest) => {
|
||||
this.projectService.closeExternalProject(request.arguments.projectFileName);
|
||||
this.projectService.closeExternalProject(request.arguments.projectFileName, /*print*/ true);
|
||||
// TODO: GH#20447 report errors
|
||||
return this.requiredResponse(/*response*/ true);
|
||||
},
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
const errorCodes = [
|
||||
Diagnostics.This_import_is_never_used_as_a_value_and_must_use_import_type_because_importsNotUsedAsValues_is_set_to_error.code,
|
||||
Diagnostics._0_is_a_type_and_must_be_imported_using_a_type_only_import_when_verbatimModuleSyntax_is_enabled.code,
|
||||
Diagnostics._0_resolves_to_a_type_only_declaration_and_must_be_imported_using_a_type_only_import_when_verbatimModuleSyntax_is_enabled.code,
|
||||
];
|
||||
const fixId = "convertToTypeOnlyImport";
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ function addMissingConstraint(changes: textChanges.ChangeTracker, program: Progr
|
||||
}
|
||||
|
||||
function tryGetConstraintFromDiagnosticMessage(messageText: string | DiagnosticMessageChain) {
|
||||
const [_, constraint] = flattenDiagnosticMessageText(messageText, "\n", 0).match(/`extends (.*)`/) || [];
|
||||
const [, constraint] = flattenDiagnosticMessageText(messageText, "\n", 0).match(/`extends (.*)`/) || [];
|
||||
return constraint;
|
||||
}
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ registerCodeFix({
|
||||
return createCombinedCodeActions(textChanges.ChangeTracker.with(context, changes => {
|
||||
eachDiagnostic(context, errorCodes, diag => {
|
||||
const info = getInfo(diag.file, diag.start, diag.code, checker, context.program);
|
||||
if (!info || !addToSeen(seen, getNodeId(info.parentDeclaration) + "#" + info.token.text)) {
|
||||
if (!info || !addToSeen(seen, getNodeId(info.parentDeclaration) + "#" + (info.kind === InfoKind.ObjectLiteral ? info.identifier : info.token.text))) {
|
||||
return;
|
||||
}
|
||||
if (fixId === fixMissingFunctionDeclaration && (info.kind === InfoKind.Function || info.kind === InfoKind.Signature)) {
|
||||
@@ -273,7 +273,8 @@ interface FunctionInfo {
|
||||
|
||||
interface ObjectLiteralInfo {
|
||||
readonly kind: InfoKind.ObjectLiteral;
|
||||
readonly token: Identifier;
|
||||
readonly token: Node;
|
||||
readonly identifier: string;
|
||||
readonly properties: Symbol[];
|
||||
readonly parentDeclaration: ObjectLiteralExpression;
|
||||
readonly indentation?: number;
|
||||
@@ -315,7 +316,18 @@ function getInfo(sourceFile: SourceFile, tokenPos: number, errorCode: number, ch
|
||||
|
||||
const properties = arrayFrom(checker.getUnmatchedProperties(checker.getTypeAtLocation(parent), checker.getParameterType(signature, argIndex), /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ false));
|
||||
if (!length(properties)) return undefined;
|
||||
return { kind: InfoKind.ObjectLiteral, token: param.name, properties, parentDeclaration: parent };
|
||||
return { kind: InfoKind.ObjectLiteral, token: param.name, identifier: param.name.text, properties, parentDeclaration: parent };
|
||||
}
|
||||
|
||||
if (token.kind === SyntaxKind.OpenBraceToken && isObjectLiteralExpression(parent)) {
|
||||
const targetType = checker.getContextualType(parent) || checker.getTypeAtLocation(parent);
|
||||
const properties = arrayFrom(checker.getUnmatchedProperties(checker.getTypeAtLocation(parent), targetType, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ false));
|
||||
if (!length(properties)) return undefined;
|
||||
|
||||
// no identifier needed because the whole parentDeclaration has the error
|
||||
const identifier = "";
|
||||
|
||||
return { kind: InfoKind.ObjectLiteral, token: parent, identifier, properties, parentDeclaration: parent };
|
||||
}
|
||||
|
||||
if (!isMemberName(token)) return undefined;
|
||||
@@ -325,7 +337,7 @@ function getInfo(sourceFile: SourceFile, tokenPos: number, errorCode: number, ch
|
||||
const properties = arrayFrom(checker.getUnmatchedProperties(checker.getTypeAtLocation(parent.initializer), targetType, /*requireOptionalProperties*/ false, /*matchDiscriminantProperties*/ false));
|
||||
if (!length(properties)) return undefined;
|
||||
|
||||
return { kind: InfoKind.ObjectLiteral, token, properties, parentDeclaration: parent.initializer };
|
||||
return { kind: InfoKind.ObjectLiteral, token, identifier: token.text, properties, parentDeclaration: parent.initializer };
|
||||
}
|
||||
|
||||
if (isIdentifier(token) && isJsxOpeningLikeElement(token.parent)) {
|
||||
|
||||
@@ -87,6 +87,6 @@ function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, ar
|
||||
}
|
||||
|
||||
function getSuggestion(messageText: string | DiagnosticMessageChain) {
|
||||
const [_, suggestion] = flattenDiagnosticMessageText(messageText, "\n", 0).match(/'(.*)'/) || [];
|
||||
const [, suggestion] = flattenDiagnosticMessageText(messageText, "\n", 0).match(/'(.*)'/) || [];
|
||||
return suggestion;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,6 @@ import {
|
||||
mapDefined,
|
||||
memoizeOne,
|
||||
ModuleKind,
|
||||
ModuleResolutionKind,
|
||||
moduleResolutionUsesNodeModules,
|
||||
moduleSpecifiers,
|
||||
MultiMap,
|
||||
@@ -1054,13 +1053,11 @@ function compareModuleSpecifiers(
|
||||
// This is a simple heuristic to try to avoid creating an import cycle with a barrel re-export.
|
||||
// E.g., do not `import { Foo } from ".."` when you could `import { Foo } from "../Foo"`.
|
||||
// This can produce false positives or negatives if re-exports cross into sibling directories
|
||||
// (e.g. `export * from "../whatever"`) or are not named "index" (we don't even try to consider
|
||||
// this if we're in a resolution mode where you can't drop trailing "/index" from paths).
|
||||
// (e.g. `export * from "../whatever"`) or are not named "index".
|
||||
function isFixPossiblyReExportingImportingFile(fix: ImportFixWithModuleSpecifier, importingFile: SourceFile, compilerOptions: CompilerOptions, toPath: (fileName: string) => Path): boolean {
|
||||
if (
|
||||
fix.isReExport &&
|
||||
fix.exportInfo?.moduleFileName &&
|
||||
getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.Node10 &&
|
||||
isIndexFileName(fix.exportInfo.moduleFileName)
|
||||
) {
|
||||
const reExportDir = toPath(getDirectoryPath(fix.exportInfo.moduleFileName));
|
||||
|
||||
@@ -5335,6 +5335,7 @@ function isClassMemberCompletionKeyword(kind: SyntaxKind) {
|
||||
function isFunctionLikeBodyKeyword(kind: SyntaxKind) {
|
||||
return kind === SyntaxKind.AsyncKeyword
|
||||
|| kind === SyntaxKind.AwaitKeyword
|
||||
|| kind === SyntaxKind.UsingKeyword
|
||||
|| kind === SyntaxKind.AsKeyword
|
||||
|| kind === SyntaxKind.SatisfiesKeyword
|
||||
|| kind === SyntaxKind.TypeKeyword
|
||||
|
||||
@@ -59,6 +59,7 @@ import {
|
||||
Scanner,
|
||||
setEmitFlags,
|
||||
some,
|
||||
sort,
|
||||
SortKind,
|
||||
SourceFile,
|
||||
stableSort,
|
||||
@@ -322,96 +323,111 @@ function coalesceImportsWorker(importGroup: readonly ImportDeclaration[], compar
|
||||
return importGroup;
|
||||
}
|
||||
|
||||
const { importWithoutClause, typeOnlyImports, regularImports } = getCategorizedImports(importGroup);
|
||||
const importGroupsByAttributes = groupBy(importGroup, decl => {
|
||||
if (decl.attributes) {
|
||||
let attrs = decl.attributes.token + " ";
|
||||
for (const x of sort(decl.attributes.elements, (x, y) => compareStringsCaseSensitive(x.name.text, y.name.text))) {
|
||||
attrs += x.name.text + ":";
|
||||
attrs += isStringLiteralLike(x.value) ? `"${x.value.text}"` : x.value.getText() + " ";
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
|
||||
const coalescedImports: ImportDeclaration[] = [];
|
||||
for (const attribute in importGroupsByAttributes) {
|
||||
const importGroupSameAttrs = importGroupsByAttributes[attribute] as ImportDeclaration[];
|
||||
const { importWithoutClause, typeOnlyImports, regularImports } = getCategorizedImports(importGroupSameAttrs);
|
||||
|
||||
if (importWithoutClause) {
|
||||
coalescedImports.push(importWithoutClause);
|
||||
}
|
||||
|
||||
for (const group of [regularImports, typeOnlyImports]) {
|
||||
const isTypeOnly = group === typeOnlyImports;
|
||||
const { defaultImports, namespaceImports, namedImports } = group;
|
||||
// Normally, we don't combine default and namespace imports, but it would be silly to
|
||||
// produce two import declarations in this special case.
|
||||
if (!isTypeOnly && defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) {
|
||||
// Add the namespace import to the existing default ImportDeclaration.
|
||||
const defaultImport = defaultImports[0];
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(defaultImport, defaultImport.importClause.name, namespaceImports[0].importClause.namedBindings),
|
||||
);
|
||||
|
||||
continue;
|
||||
if (importWithoutClause) {
|
||||
coalescedImports.push(importWithoutClause);
|
||||
}
|
||||
|
||||
const sortedNamespaceImports = stableSort(namespaceImports, (i1, i2) => comparer(i1.importClause.namedBindings.name.text, i2.importClause.namedBindings.name.text));
|
||||
for (const group of [regularImports, typeOnlyImports]) {
|
||||
const isTypeOnly = group === typeOnlyImports;
|
||||
const { defaultImports, namespaceImports, namedImports } = group;
|
||||
// Normally, we don't combine default and namespace imports, but it would be silly to
|
||||
// produce two import declarations in this special case.
|
||||
if (!isTypeOnly && defaultImports.length === 1 && namespaceImports.length === 1 && namedImports.length === 0) {
|
||||
// Add the namespace import to the existing default ImportDeclaration.
|
||||
const defaultImport = defaultImports[0];
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(defaultImport, defaultImport.importClause.name, namespaceImports[0].importClause.namedBindings),
|
||||
);
|
||||
|
||||
for (const namespaceImport of sortedNamespaceImports) {
|
||||
// Drop the name, if any
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(namespaceImport, /*name*/ undefined, namespaceImport.importClause.namedBindings),
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const firstDefaultImport = firstOrUndefined(defaultImports);
|
||||
const firstNamedImport = firstOrUndefined(namedImports);
|
||||
const importDecl = firstDefaultImport ?? firstNamedImport;
|
||||
if (!importDecl) {
|
||||
continue;
|
||||
}
|
||||
const sortedNamespaceImports = stableSort(namespaceImports, (i1, i2) => comparer(i1.importClause.namedBindings.name.text, i2.importClause.namedBindings.name.text));
|
||||
|
||||
let newDefaultImport: Identifier | undefined;
|
||||
const newImportSpecifiers: ImportSpecifier[] = [];
|
||||
if (defaultImports.length === 1) {
|
||||
newDefaultImport = defaultImports[0].importClause.name;
|
||||
}
|
||||
else {
|
||||
for (const defaultImport of defaultImports) {
|
||||
newImportSpecifiers.push(
|
||||
factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("default"), defaultImport.importClause.name),
|
||||
for (const namespaceImport of sortedNamespaceImports) {
|
||||
// Drop the name, if any
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(namespaceImport, /*name*/ undefined, namespaceImport.importClause.namedBindings),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
newImportSpecifiers.push(...getNewImportSpecifiers(namedImports));
|
||||
const firstDefaultImport = firstOrUndefined(defaultImports);
|
||||
const firstNamedImport = firstOrUndefined(namedImports);
|
||||
const importDecl = firstDefaultImport ?? firstNamedImport;
|
||||
if (!importDecl) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const sortedImportSpecifiers = factory.createNodeArray(
|
||||
sortSpecifiers(newImportSpecifiers, comparer, preferences),
|
||||
firstNamedImport?.importClause.namedBindings.elements.hasTrailingComma,
|
||||
);
|
||||
let newDefaultImport: Identifier | undefined;
|
||||
const newImportSpecifiers: ImportSpecifier[] = [];
|
||||
if (defaultImports.length === 1) {
|
||||
newDefaultImport = defaultImports[0].importClause.name;
|
||||
}
|
||||
else {
|
||||
for (const defaultImport of defaultImports) {
|
||||
newImportSpecifiers.push(
|
||||
factory.createImportSpecifier(/*isTypeOnly*/ false, factory.createIdentifier("default"), defaultImport.importClause.name),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const newNamedImports = sortedImportSpecifiers.length === 0
|
||||
? newDefaultImport
|
||||
? undefined
|
||||
: factory.createNamedImports(emptyArray)
|
||||
: firstNamedImport
|
||||
? factory.updateNamedImports(firstNamedImport.importClause.namedBindings, sortedImportSpecifiers)
|
||||
: factory.createNamedImports(sortedImportSpecifiers);
|
||||
newImportSpecifiers.push(...getNewImportSpecifiers(namedImports));
|
||||
|
||||
if (
|
||||
sourceFile &&
|
||||
newNamedImports &&
|
||||
firstNamedImport?.importClause.namedBindings &&
|
||||
!rangeIsOnSingleLine(firstNamedImport.importClause.namedBindings, sourceFile)
|
||||
) {
|
||||
setEmitFlags(newNamedImports, EmitFlags.MultiLine);
|
||||
}
|
||||
|
||||
// Type-only imports are not allowed to mix default, namespace, and named imports in any combination.
|
||||
// We could rewrite a default import as a named import (`import { default as name }`), but we currently
|
||||
// choose not to as a stylistic preference.
|
||||
if (isTypeOnly && newDefaultImport && newNamedImports) {
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(importDecl, newDefaultImport, /*namedBindings*/ undefined),
|
||||
);
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(firstNamedImport ?? importDecl, /*name*/ undefined, newNamedImports),
|
||||
);
|
||||
}
|
||||
else {
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(importDecl, newDefaultImport, newNamedImports),
|
||||
const sortedImportSpecifiers = factory.createNodeArray(
|
||||
sortSpecifiers(newImportSpecifiers, comparer, preferences),
|
||||
firstNamedImport?.importClause.namedBindings.elements.hasTrailingComma,
|
||||
);
|
||||
|
||||
const newNamedImports = sortedImportSpecifiers.length === 0
|
||||
? newDefaultImport
|
||||
? undefined
|
||||
: factory.createNamedImports(emptyArray)
|
||||
: firstNamedImport
|
||||
? factory.updateNamedImports(firstNamedImport.importClause.namedBindings, sortedImportSpecifiers)
|
||||
: factory.createNamedImports(sortedImportSpecifiers);
|
||||
|
||||
if (
|
||||
sourceFile &&
|
||||
newNamedImports &&
|
||||
firstNamedImport?.importClause.namedBindings &&
|
||||
!rangeIsOnSingleLine(firstNamedImport.importClause.namedBindings, sourceFile)
|
||||
) {
|
||||
setEmitFlags(newNamedImports, EmitFlags.MultiLine);
|
||||
}
|
||||
|
||||
// Type-only imports are not allowed to mix default, namespace, and named imports in any combination.
|
||||
// We could rewrite a default import as a named import (`import { default as name }`), but we currently
|
||||
// choose not to as a stylistic preference.
|
||||
if (isTypeOnly && newDefaultImport && newNamedImports) {
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(importDecl, newDefaultImport, /*namedBindings*/ undefined),
|
||||
);
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(firstNamedImport ?? importDecl, /*name*/ undefined, newNamedImports),
|
||||
);
|
||||
}
|
||||
else {
|
||||
coalescedImports.push(
|
||||
updateImportDeclarationAndClause(importDecl, newDefaultImport, newNamedImports),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
getModuleSpecifier,
|
||||
} from "../../compiler/moduleSpecifiers";
|
||||
import {
|
||||
__String,
|
||||
AnyImportOrRequireStatement,
|
||||
append,
|
||||
ApplicableRefactorInfo,
|
||||
@@ -894,12 +893,10 @@ export interface TopLevelVariableDeclaration extends VariableDeclaration {
|
||||
export type TopLevelDeclaration = NonVariableTopLevelDeclaration | TopLevelVariableDeclaration | BindingElement;
|
||||
|
||||
/** @internal */
|
||||
export function createNewFileName(oldFile: SourceFile, program: Program, context: RefactorContext, host: LanguageServiceHost): string {
|
||||
export function createNewFileName(oldFile: SourceFile, program: Program, host: LanguageServiceHost, toMove: ToMove | undefined): string {
|
||||
const checker = program.getTypeChecker();
|
||||
const toMove = getStatementsToMove(context);
|
||||
let usage;
|
||||
if (toMove) {
|
||||
usage = getUsageInfo(oldFile, toMove.all, checker);
|
||||
const usage = getUsageInfo(oldFile, toMove.all, checker);
|
||||
const currentDirectory = getDirectoryPath(oldFile.fileName);
|
||||
const extension = extensionFromPath(oldFile.fileName);
|
||||
const newFileName = combinePaths(
|
||||
@@ -975,6 +972,11 @@ export function getStatementsToMove(context: RefactorContext): ToMove | undefine
|
||||
return all.length === 0 ? undefined : { all, ranges };
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function containsJsx(statements: readonly Statement[] | undefined) {
|
||||
return find(statements, statement => !!(statement.transformFlags & TransformFlags.ContainsJsx));
|
||||
}
|
||||
|
||||
function isAllowedStatementToMove(statement: Statement): boolean {
|
||||
// Filters imports and prologue directives out of the range of statements to move.
|
||||
// Imports will be copied to the new file anyway, and may still be needed in the old file.
|
||||
@@ -1001,8 +1003,7 @@ export function getUsageInfo(oldFile: SourceFile, toMove: readonly Statement[],
|
||||
const oldImportsNeededByTargetFile = new Map<Symbol, /*isValidTypeOnlyUseSite*/ boolean>();
|
||||
const targetFileImportsFromOldFile = new Set<Symbol>();
|
||||
|
||||
const containsJsx = find(toMove, statement => !!(statement.transformFlags & TransformFlags.ContainsJsx));
|
||||
const jsxNamespaceSymbol = getJsxNamespaceSymbol(containsJsx);
|
||||
const jsxNamespaceSymbol = getJsxNamespaceSymbol(containsJsx(toMove));
|
||||
|
||||
if (jsxNamespaceSymbol) { // Might not exist (e.g. in non-compiling code)
|
||||
oldImportsNeededByTargetFile.set(jsxNamespaceSymbol, false);
|
||||
|
||||
@@ -18,7 +18,6 @@ import {
|
||||
nodeSeenTracker,
|
||||
Program,
|
||||
QuotePreference,
|
||||
RefactorContext,
|
||||
RefactorEditInfo,
|
||||
SourceFile,
|
||||
Symbol,
|
||||
@@ -75,16 +74,15 @@ registerRefactor(refactorName, {
|
||||
getEditsForAction: function getRefactorEditsToMoveToNewFile(context, actionName): RefactorEditInfo {
|
||||
Debug.assert(actionName === refactorName, "Wrong refactor invoked");
|
||||
const statements = Debug.checkDefined(getStatementsToMove(context));
|
||||
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, statements, t, context.host, context.preferences, context));
|
||||
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, statements, t, context.host, context.preferences));
|
||||
return { edits, renameFilename: undefined, renameLocation: undefined };
|
||||
},
|
||||
});
|
||||
|
||||
function doChange(oldFile: SourceFile, program: Program, toMove: ToMove, changes: textChanges.ChangeTracker, host: LanguageServiceHost, preferences: UserPreferences, context: RefactorContext): void {
|
||||
function doChange(oldFile: SourceFile, program: Program, toMove: ToMove, changes: textChanges.ChangeTracker, host: LanguageServiceHost, preferences: UserPreferences): void {
|
||||
const checker = program.getTypeChecker();
|
||||
const usage = getUsageInfo(oldFile, toMove.all, checker);
|
||||
|
||||
const newFilename = createNewFileName(oldFile, program, context, host);
|
||||
const newFilename = createNewFileName(oldFile, program, host, toMove);
|
||||
|
||||
// If previous file was global, this is easy.
|
||||
changes.createNewFile(oldFile, newFilename, getNewStatementsAndRemoveFromOldFile(oldFile, usage, changes, toMove, program, host, newFilename, preferences));
|
||||
|
||||
+26
-12
@@ -323,7 +323,9 @@ import {
|
||||
import * as NavigateTo from "./_namespaces/ts.NavigateTo";
|
||||
import * as NavigationBar from "./_namespaces/ts.NavigationBar";
|
||||
import {
|
||||
containsJsx,
|
||||
createNewFileName,
|
||||
getStatementsToMove,
|
||||
} from "./_namespaces/ts.refactor";
|
||||
import * as classifier from "./classifier";
|
||||
import * as classifier2020 from "./classifier2020";
|
||||
@@ -2562,20 +2564,25 @@ export function createLanguageService(
|
||||
const openTag = tag.parent.openingElement;
|
||||
const closeTag = tag.parent.closingElement;
|
||||
|
||||
const openTagStart = openTag.tagName.getStart(sourceFile);
|
||||
const openTagEnd = openTag.tagName.end;
|
||||
const closeTagStart = closeTag.tagName.getStart(sourceFile);
|
||||
const closeTagEnd = closeTag.tagName.end;
|
||||
const openTagNameStart = openTag.tagName.getStart(sourceFile);
|
||||
const openTagNameEnd = openTag.tagName.end;
|
||||
const closeTagNameStart = closeTag.tagName.getStart(sourceFile);
|
||||
const closeTagNameEnd = closeTag.tagName.end;
|
||||
// do not return linked cursors if tags are not well-formed
|
||||
if (
|
||||
openTagNameStart === openTag.getStart(sourceFile) || closeTagNameStart === closeTag.getStart(sourceFile)
|
||||
|| openTagNameEnd === openTag.getEnd() || closeTagNameEnd === closeTag.getEnd()
|
||||
) return undefined;
|
||||
|
||||
// only return linked cursors if the cursor is within a tag name
|
||||
if (!(openTagStart <= position && position <= openTagEnd || closeTagStart <= position && position <= closeTagEnd)) return undefined;
|
||||
if (!(openTagNameStart <= position && position <= openTagNameEnd || closeTagNameStart <= position && position <= closeTagNameEnd)) return undefined;
|
||||
|
||||
// only return linked cursors if text in both tags is identical
|
||||
const openingTagText = openTag.tagName.getText(sourceFile);
|
||||
if (openingTagText !== closeTag.tagName.getText(sourceFile)) return undefined;
|
||||
|
||||
return {
|
||||
ranges: [{ start: openTagStart, length: openTagEnd - openTagStart }, { start: closeTagStart, length: closeTagEnd - closeTagStart }],
|
||||
ranges: [{ start: openTagNameStart, length: openTagNameEnd - openTagNameStart }, { start: closeTagNameStart, length: closeTagNameEnd - closeTagNameStart }],
|
||||
wordPattern: jsxTagWordPattern,
|
||||
};
|
||||
}
|
||||
@@ -3025,13 +3032,20 @@ export function createLanguageService(
|
||||
const sourceFile = getValidSourceFile(fileName);
|
||||
const allFiles = Debug.checkDefined(program.getSourceFiles());
|
||||
const extension = extensionFromPath(fileName);
|
||||
const files = mapDefined(allFiles, file =>
|
||||
!program?.isSourceFileFromExternalLibrary(sourceFile) &&
|
||||
!(sourceFile === getValidSourceFile(file.fileName) || extension === Extension.Ts && extensionFromPath(file.fileName) === Extension.Dts || extension === Extension.Dts && startsWith(getBaseFileName(file.fileName), "lib.") && extensionFromPath(file.fileName) === Extension.Dts)
|
||||
&& extension === extensionFromPath(file.fileName) ? file.fileName : undefined);
|
||||
const toMove = getStatementsToMove(getRefactorContext(sourceFile, positionOrRange, preferences, emptyOptions));
|
||||
const toMoveContainsJsx = containsJsx(toMove?.all);
|
||||
|
||||
const newFileName = createNewFileName(sourceFile, program, getRefactorContext(sourceFile, positionOrRange, preferences, emptyOptions), host);
|
||||
return { newFileName, files };
|
||||
const files = mapDefined(allFiles, file => {
|
||||
const fileNameExtension = extensionFromPath(file.fileName);
|
||||
const isValidSourceFile = !program?.isSourceFileFromExternalLibrary(sourceFile) && !(
|
||||
sourceFile === getValidSourceFile(file.fileName) ||
|
||||
extension === Extension.Ts && fileNameExtension === Extension.Dts ||
|
||||
extension === Extension.Dts && startsWith(getBaseFileName(file.fileName), "lib.") && fileNameExtension === Extension.Dts
|
||||
);
|
||||
return isValidSourceFile && (extension === fileNameExtension || (extension === Extension.Tsx && fileNameExtension === Extension.Ts || extension === Extension.Jsx && fileNameExtension === Extension.Js) && !toMoveContainsJsx) ? file.fileName : undefined;
|
||||
});
|
||||
|
||||
return { newFileName: createNewFileName(sourceFile, program, host, toMove), files };
|
||||
}
|
||||
|
||||
function getEditsForRefactor(
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import {
|
||||
getModuleSpecifierPreferences,
|
||||
} from "../compiler/moduleSpecifiers";
|
||||
import {
|
||||
addToSeen,
|
||||
altDirectorySeparator,
|
||||
@@ -52,7 +55,6 @@ import {
|
||||
getEffectiveTypeRoots,
|
||||
getEmitModuleResolutionKind,
|
||||
getLeadingCommentRanges,
|
||||
getModuleSpecifierEndingPreference,
|
||||
getOwnKeys,
|
||||
getPackageJsonTypesVersionsPaths,
|
||||
getPathComponents,
|
||||
@@ -668,7 +670,10 @@ function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[]
|
||||
const basePath = compilerOptions.project || host.getCurrentDirectory();
|
||||
const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames());
|
||||
const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptDirectory, ignoreCase);
|
||||
return flatMap(baseDirectories, baseDirectory => arrayFrom(getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, /*moduleSpecifierIsRelative*/ true, exclude).values()));
|
||||
return deduplicate<NameAndKind>(
|
||||
flatMap(baseDirectories, baseDirectory => arrayFrom(getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, /*moduleSpecifierIsRelative*/ true, exclude).values())),
|
||||
(itemA, itemB) => itemA.name === itemB.name && itemA.kind === itemB.kind && itemA.extension === itemB.extension,
|
||||
);
|
||||
}
|
||||
|
||||
const enum ReferenceKind {
|
||||
@@ -744,7 +749,7 @@ function getCompletionEntriesForDirectoryFragment(
|
||||
continue;
|
||||
}
|
||||
|
||||
const { name, extension } = getFilenameWithExtensionOption(getBaseFileName(filePath), host.getCompilationSettings(), extensionOptions);
|
||||
const { name, extension } = getFilenameWithExtensionOption(getBaseFileName(filePath), host.getCompilationSettings(), extensionOptions, /*isExportsWildcard*/ false);
|
||||
result.add(nameAndKind(name, ScriptElementKind.scriptElement, extension));
|
||||
}
|
||||
}
|
||||
@@ -764,7 +769,7 @@ function getCompletionEntriesForDirectoryFragment(
|
||||
return result;
|
||||
}
|
||||
|
||||
function getFilenameWithExtensionOption(name: string, compilerOptions: CompilerOptions, extensionOptions: ExtensionOptions): { name: string; extension: Extension | undefined; } {
|
||||
function getFilenameWithExtensionOption(name: string, compilerOptions: CompilerOptions, extensionOptions: ExtensionOptions, isExportsWildcard: boolean): { name: string; extension: Extension | undefined; } {
|
||||
const nonJsResult = moduleSpecifiers.tryGetRealFileNameForNonJsDeclarationFileName(name);
|
||||
if (nonJsResult) {
|
||||
return { name: nonJsResult, extension: tryGetExtensionFromPath(nonJsResult) };
|
||||
@@ -773,8 +778,19 @@ function getFilenameWithExtensionOption(name: string, compilerOptions: CompilerO
|
||||
return { name, extension: tryGetExtensionFromPath(name) };
|
||||
}
|
||||
|
||||
const endingPreference = getModuleSpecifierEndingPreference(extensionOptions.endingPreference, extensionOptions.resolutionMode, compilerOptions, extensionOptions.importingSourceFile);
|
||||
if (endingPreference === ModuleSpecifierEnding.TsExtension) {
|
||||
let allowedEndings = getModuleSpecifierPreferences(
|
||||
{ importModuleSpecifierEnding: extensionOptions.endingPreference },
|
||||
compilerOptions,
|
||||
extensionOptions.importingSourceFile,
|
||||
).getAllowedEndingsInPreferredOrder(extensionOptions.resolutionMode);
|
||||
|
||||
if (isExportsWildcard) {
|
||||
// If we're completing `import {} from "foo/|"` and subpaths are available via `"exports": { "./*": "./src/*" }`,
|
||||
// the completion must be a (potentially extension-swapped) file name. Dropping extensions and index files is not allowed.
|
||||
allowedEndings = allowedEndings.filter(e => e !== ModuleSpecifierEnding.Minimal && e !== ModuleSpecifierEnding.Index);
|
||||
}
|
||||
|
||||
if (allowedEndings[0] === ModuleSpecifierEnding.TsExtension) {
|
||||
if (fileExtensionIsOneOf(name, supportedTSImplementationExtensions)) {
|
||||
return { name, extension: tryGetExtensionFromPath(name) };
|
||||
}
|
||||
@@ -785,7 +801,8 @@ function getFilenameWithExtensionOption(name: string, compilerOptions: CompilerO
|
||||
}
|
||||
|
||||
if (
|
||||
(endingPreference === ModuleSpecifierEnding.Minimal || endingPreference === ModuleSpecifierEnding.Index) &&
|
||||
!isExportsWildcard &&
|
||||
(allowedEndings[0] === ModuleSpecifierEnding.Minimal || allowedEndings[0] === ModuleSpecifierEnding.Index) &&
|
||||
fileExtensionIsOneOf(name, [Extension.Js, Extension.Jsx, Extension.Ts, Extension.Tsx, Extension.Dts])
|
||||
) {
|
||||
return { name: removeFileExtension(name), extension: tryGetExtensionFromPath(name) };
|
||||
@@ -814,12 +831,13 @@ function addCompletionEntriesFromPaths(
|
||||
const lengthB = typeof patternB === "object" ? patternB.prefix.length : b.length;
|
||||
return compareValues(lengthB, lengthA);
|
||||
};
|
||||
return addCompletionEntriesFromPathsOrExports(result, fragment, baseDirectory, extensionOptions, host, getOwnKeys(paths), getPatternsForKey, comparePaths);
|
||||
return addCompletionEntriesFromPathsOrExports(result, /*isExports*/ false, fragment, baseDirectory, extensionOptions, host, getOwnKeys(paths), getPatternsForKey, comparePaths);
|
||||
}
|
||||
|
||||
/** @returns whether `fragment` was a match for any `paths` (which should indicate whether any other path completions should be offered) */
|
||||
function addCompletionEntriesFromPathsOrExports(
|
||||
result: NameAndKindSet,
|
||||
isExports: boolean,
|
||||
fragment: string,
|
||||
baseDirectory: string,
|
||||
extensionOptions: ExtensionOptions,
|
||||
@@ -857,7 +875,7 @@ function addCompletionEntriesFromPathsOrExports(
|
||||
if (typeof pathPattern === "string" || matchedPath === undefined || comparePaths(key, matchedPath) !== Comparison.GreaterThan) {
|
||||
pathResults.push({
|
||||
matchedPattern: isMatch,
|
||||
results: getCompletionsForPathMapping(keyWithoutLeadingDotSlash, patterns, fragment, baseDirectory, extensionOptions, host)
|
||||
results: getCompletionsForPathMapping(keyWithoutLeadingDotSlash, patterns, fragment, baseDirectory, extensionOptions, isExports && isMatch, host)
|
||||
.map(({ name, kind, extension }) => nameAndKind(name, kind, extension)),
|
||||
});
|
||||
}
|
||||
@@ -956,6 +974,7 @@ function getCompletionEntriesForNonRelativeModules(
|
||||
const conditions = getConditions(compilerOptions, mode);
|
||||
addCompletionEntriesFromPathsOrExports(
|
||||
result,
|
||||
/*isExports*/ true,
|
||||
fragmentSubpath,
|
||||
packageDirectory,
|
||||
extensionOptions,
|
||||
@@ -1001,6 +1020,7 @@ function getCompletionsForPathMapping(
|
||||
fragment: string,
|
||||
packageDirectory: string,
|
||||
extensionOptions: ExtensionOptions,
|
||||
isExportsWildcard: boolean,
|
||||
host: LanguageServiceHost,
|
||||
): readonly NameAndKind[] {
|
||||
if (!endsWith(path, "*")) {
|
||||
@@ -1012,9 +1032,9 @@ function getCompletionsForPathMapping(
|
||||
const remainingFragment = tryRemovePrefix(fragment, pathPrefix);
|
||||
if (remainingFragment === undefined) {
|
||||
const starIsFullPathComponent = path[path.length - 2] === "/";
|
||||
return starIsFullPathComponent ? justPathMappingName(pathPrefix, ScriptElementKind.directory) : flatMap(patterns, pattern => getModulesForPathsPattern("", packageDirectory, pattern, extensionOptions, host)?.map(({ name, ...rest }) => ({ name: pathPrefix + name, ...rest })));
|
||||
return starIsFullPathComponent ? justPathMappingName(pathPrefix, ScriptElementKind.directory) : flatMap(patterns, pattern => getModulesForPathsPattern("", packageDirectory, pattern, extensionOptions, isExportsWildcard, host)?.map(({ name, ...rest }) => ({ name: pathPrefix + name, ...rest })));
|
||||
}
|
||||
return flatMap(patterns, pattern => getModulesForPathsPattern(remainingFragment, packageDirectory, pattern, extensionOptions, host));
|
||||
return flatMap(patterns, pattern => getModulesForPathsPattern(remainingFragment, packageDirectory, pattern, extensionOptions, isExportsWildcard, host));
|
||||
|
||||
function justPathMappingName(name: string, kind: ScriptElementKind.directory | ScriptElementKind.scriptElement): readonly NameAndKind[] {
|
||||
return startsWith(name, fragment) ? [{ name: removeTrailingDirectorySeparator(name), kind, extension: undefined }] : emptyArray;
|
||||
@@ -1026,6 +1046,7 @@ function getModulesForPathsPattern(
|
||||
packageDirectory: string,
|
||||
pattern: string,
|
||||
extensionOptions: ExtensionOptions,
|
||||
isExportsWildcard: boolean,
|
||||
host: LanguageServiceHost,
|
||||
): readonly NameAndKind[] | undefined {
|
||||
if (!host.readDirectory) {
|
||||
@@ -1074,7 +1095,7 @@ function getModulesForPathsPattern(
|
||||
if (containsSlash(trimmedWithPattern)) {
|
||||
return directoryResult(getPathComponents(removeLeadingDirectorySeparator(trimmedWithPattern))[1]);
|
||||
}
|
||||
const { name, extension } = getFilenameWithExtensionOption(trimmedWithPattern, host.getCompilationSettings(), extensionOptions);
|
||||
const { name, extension } = getFilenameWithExtensionOption(trimmedWithPattern, host.getCompilationSettings(), extensionOptions, isExportsWildcard);
|
||||
return nameAndKind(name, ScriptElementKind.scriptElement, extension);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -164,4 +164,49 @@ describe("unittests:: customTransforms", () => {
|
||||
},
|
||||
],
|
||||
}, { sourceMap: true, outFile: "source.js" });
|
||||
|
||||
emitsCorrectly("importDeclarationBeforeTransformElision", [
|
||||
{
|
||||
file: "a.ts",
|
||||
text: "export type A = string;",
|
||||
},
|
||||
{
|
||||
file: "index.ts",
|
||||
text: "import { A } from './a.js';\nexport { A } from './a.js';",
|
||||
},
|
||||
], {
|
||||
before: [
|
||||
context => {
|
||||
const { factory } = context;
|
||||
return (s: ts.SourceFile) => ts.visitEachChild(s, visitor, context);
|
||||
|
||||
function visitor(node: ts.Node): ts.Node {
|
||||
if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
|
||||
return factory.updateImportDeclaration(
|
||||
node,
|
||||
node.modifiers,
|
||||
node.importClause,
|
||||
factory.createStringLiteral(node.moduleSpecifier.text),
|
||||
node.attributes,
|
||||
);
|
||||
}
|
||||
|
||||
if (ts.isExportDeclaration(node) && node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier)) {
|
||||
return factory.updateExportDeclaration(
|
||||
node,
|
||||
node.modifiers,
|
||||
node.isTypeOnly,
|
||||
node.exportClause,
|
||||
factory.createStringLiteral(node.moduleSpecifier.text),
|
||||
node.attributes,
|
||||
);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
},
|
||||
],
|
||||
}, {
|
||||
target: ts.ScriptTarget.ESNext,
|
||||
module: ts.ModuleKind.ESNext,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import {
|
||||
incrementalVerifier,
|
||||
} from "../../../harness/incrementalUtils";
|
||||
import {
|
||||
patchServiceForStateBaseline,
|
||||
} from "../../../harness/projectServiceStateLogger";
|
||||
import {
|
||||
createLoggerWithInMemoryLogs,
|
||||
LoggerWithInMemoryLogs,
|
||||
@@ -31,13 +34,6 @@ export function baselineTsserverLogs(scenario: string, subScenario: string, sess
|
||||
Harness.Baseline.runBaseline(`tsserver/${scenario}/${subScenario.split(" ").join("-")}.js`, sessionOrService.logger.logs.join("\r\n"));
|
||||
}
|
||||
|
||||
export function appendAllScriptInfos(session: TestSession) {
|
||||
session.logger.log("");
|
||||
session.logger.log(`ScriptInfos:`);
|
||||
session.getProjectService().filenameToScriptInfo.forEach(info => session.logger.log(`path: ${info.path} fileName: ${info.fileName}`));
|
||||
session.logger.log("");
|
||||
}
|
||||
|
||||
export function toExternalFile(fileName: string): ts.server.protocol.ExternalFile {
|
||||
return { fileName };
|
||||
}
|
||||
@@ -52,9 +48,12 @@ export type TestSessionAndServiceHost = TestServerHostTrackingWrittenFiles & {
|
||||
};
|
||||
export function patchHostTimeouts(
|
||||
inputHost: TestServerHostTrackingWrittenFiles,
|
||||
session: TestSession | undefined,
|
||||
logger: LoggerWithInMemoryLogs,
|
||||
) {
|
||||
const host = inputHost as TestSessionAndServiceHost;
|
||||
host.service = session?.getProjectService();
|
||||
if (session) patchServiceForStateBaseline(session.getProjectService());
|
||||
if (host.patched) return host;
|
||||
host.patched = true;
|
||||
if (!logger.hasLevel(ts.server.LogLevel.verbose)) {
|
||||
@@ -134,6 +133,7 @@ export class TestSession extends ts.server.Session {
|
||||
this.serverCancellationToken = cancellationToken as TestServerCancellationToken;
|
||||
patchHostTimeouts(
|
||||
changeToHostTrackingWrittenFiles(this.host),
|
||||
this,
|
||||
this.logger,
|
||||
);
|
||||
}
|
||||
@@ -479,21 +479,9 @@ export function verifyGetErrScenario(scenario: VerifyGetErrScenario) {
|
||||
verifyErrorsUsingSyncMethods(scenario);
|
||||
}
|
||||
|
||||
export function verifyDynamic(session: TestSession, path: string) {
|
||||
session.logger.log(`${path} isDynamic:: ${session.getProjectService().filenameToScriptInfo.get(path)!.isDynamic}`);
|
||||
}
|
||||
|
||||
export function createHostWithSolutionBuild(files: readonly FileOrFolderOrSymLink[], rootNames: readonly string[]) {
|
||||
const host = createServerHost(files);
|
||||
// ts build should succeed
|
||||
ensureErrorFreeBuild(host, rootNames);
|
||||
return host;
|
||||
}
|
||||
|
||||
export function logInferredProjectsOrphanStatus(session: TestSession) {
|
||||
session.getProjectService().inferredProjects.forEach(inferredProject => session.logger.log(`Inferred project: ${inferredProject.projectName} isOrphan:: ${inferredProject.isOrphan()} isClosed: ${inferredProject.isClosed()}`));
|
||||
}
|
||||
|
||||
export function logConfiguredProjectsHasOpenRefStatus(session: TestSession) {
|
||||
session.getProjectService().configuredProjects.forEach(configuredProject => session.logger.log(`Configured project: ${configuredProject.projectName} hasOpenRef:: ${configuredProject.hasOpenRef()} isClosed: ${configuredProject.isClosed()}`));
|
||||
}
|
||||
|
||||
@@ -356,6 +356,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost,
|
||||
private inodeWatching: boolean | undefined;
|
||||
private readonly inodes?: Map<Path, number>;
|
||||
watchDirectory: HostWatchDirectory;
|
||||
service?: server.ProjectService;
|
||||
constructor(
|
||||
fileOrFolderorSymLinkList: FileOrFolderOrSymLinkMap | readonly FileOrFolderOrSymLink[],
|
||||
{
|
||||
@@ -1038,6 +1039,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost,
|
||||
this.timeoutCallbacks.serialize(baseline);
|
||||
this.immediateCallbacks.serialize(baseline);
|
||||
this.pendingInstalls.serialize(baseline);
|
||||
this.service?.baseline();
|
||||
}
|
||||
|
||||
writtenFiles?: Map<Path, number>;
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
} from "../helpers";
|
||||
import {
|
||||
baselineTsserverLogs,
|
||||
closeFilesForSession,
|
||||
openFilesForSession,
|
||||
TestSession,
|
||||
} from "../helpers/tsserver";
|
||||
@@ -52,6 +53,7 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
]);
|
||||
openFilesForSession([indexTs], session);
|
||||
assert.isUndefined(session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider());
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "without dependencies listed", session);
|
||||
});
|
||||
|
||||
@@ -65,6 +67,7 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
]);
|
||||
openFilesForSession([indexTs], session);
|
||||
assert.isUndefined(session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider());
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "dependencies are already in main program", session);
|
||||
});
|
||||
|
||||
@@ -85,18 +88,16 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
.getLanguageService()
|
||||
.getAutoImportProvider(),
|
||||
);
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "projects already inside node_modules", session);
|
||||
});
|
||||
|
||||
it("Auto-importable file is in inferred project until imported", () => {
|
||||
const { session, updateFile } = setup([angularFormsDts, angularFormsPackageJson, tsconfig, packageJson, indexTs]);
|
||||
openFilesForSession([angularFormsDts], session);
|
||||
session.logger.log(`Default Project for ${angularFormsDts.path}:: ${session.getProjectService().getDefaultProjectForFile(angularFormsDts.path as ts.server.NormalizedPath, /*ensureProject*/ true)?.projectName}`);
|
||||
|
||||
updateFile(indexTs.path, "import '@angular/forms'");
|
||||
session.logger.log(`Default Project for ${angularFormsDts.path}:: ${session.getProjectService().getDefaultProjectForFile(angularFormsDts.path as ts.server.NormalizedPath, /*ensureProject*/ true)?.projectName}`);
|
||||
|
||||
assert.isUndefined(session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider());
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "Auto-importable file is in inferred project until imported", session);
|
||||
});
|
||||
|
||||
@@ -111,9 +112,12 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
|
||||
openFilesForSession([indexTs], session);
|
||||
assert.isUndefined(session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider());
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
|
||||
host.writeFile(packageJson.path, packageJson.content);
|
||||
session.host.baselineHost("Before getAutoImportProvider");
|
||||
assert.ok(session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider());
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "Responds to package_json changes", session);
|
||||
});
|
||||
|
||||
@@ -129,12 +133,14 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
openFilesForSession([indexTs], session);
|
||||
const autoImportProvider = session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider();
|
||||
assert.ok(autoImportProvider);
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
|
||||
updateFile(indexTs.path, "console.log(0)");
|
||||
assert.strictEqual(
|
||||
session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider(),
|
||||
autoImportProvider,
|
||||
);
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "Reuses autoImportProvider when program structure is unchanged", session);
|
||||
});
|
||||
|
||||
@@ -152,8 +158,11 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
hostProject.getPackageJsonAutoImportProvider();
|
||||
const autoImportProviderProject = hostProject.autoImportProviderHost;
|
||||
assert.ok(autoImportProviderProject);
|
||||
session.host.baselineHost("After getPackageJsonAutoImportProvider");
|
||||
|
||||
hostProject.close();
|
||||
closeFilesForSession([indexTs], session);
|
||||
openFilesForSession([{ file: "/random/random.ts", content: "export const y = 10;", projectRootPath: "/random" }], session);
|
||||
assert.isTrue(hostProject.isClosed());
|
||||
assert.ok(autoImportProviderProject && autoImportProviderProject.isClosed());
|
||||
assert.isUndefined(hostProject.autoImportProviderHost);
|
||||
baselineTsserverLogs("autoImportProvider", "Closes AutoImportProviderProject when host project closes", session);
|
||||
@@ -176,8 +185,10 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
|
||||
// Create auto import provider project, ensure still !session.getProjectService().pendingEnsureProjectForOpenFiles
|
||||
host.writeFile(packageJson.path, packageJson.content);
|
||||
session.host.baselineHost("Before getPackageJsonAutoImportProvider");
|
||||
hostProject.getPackageJsonAutoImportProvider();
|
||||
assert.isFalse(session.getProjectService().pendingEnsureProjectForOpenFiles);
|
||||
session.host.baselineHost("After getPackageJsonAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "Does not schedule ensureProjectForOpenFiles on AutoImportProviderProject creation", session);
|
||||
});
|
||||
|
||||
@@ -196,16 +207,20 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
const project = session.getProjectService().configuredProjects.get(tsconfig.path)!;
|
||||
const completionsBefore = project.getLanguageService().getCompletionsAtPosition(indexTs.path, 0, { includeCompletionsForModuleExports: true });
|
||||
assert.isTrue(completionsBefore?.entries.some(c => c.name === "PatternValidator"));
|
||||
session.host.baselineHost("After completions");
|
||||
|
||||
// Directory watchers only fire for add/remove, not change.
|
||||
// This is ok since a real `npm install` will always trigger add/remove events.
|
||||
host.deleteFile(angularFormsDts.path);
|
||||
host.writeFile(angularFormsDts.path, "");
|
||||
|
||||
session.host.baselineHost("Before getAutoImportProvider");
|
||||
const autoImportProvider = project.getLanguageService().getAutoImportProvider();
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
const completionsAfter = project.getLanguageService().getCompletionsAtPosition(indexTs.path, 0, { includeCompletionsForModuleExports: true });
|
||||
assert.equal(autoImportProvider!.getSourceFile(angularFormsDts.path)!.getText(), "");
|
||||
assert.isFalse(completionsAfter?.entries.some(c => c.name === "PatternValidator"));
|
||||
session.host.baselineHost("After Completions");
|
||||
baselineTsserverLogs("autoImportProvider", "Responds to automatic changes in node_modules", session);
|
||||
});
|
||||
|
||||
@@ -243,9 +258,12 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
|
||||
openFilesForSession([indexTs], session);
|
||||
assert.isUndefined(session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider());
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
|
||||
host.writeFile(packageJson.path, packageJson.content);
|
||||
session.host.baselineHost("Before getAutoImportProvider");
|
||||
assert.ok(session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getAutoImportProvider());
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "Recovers from an unparseable package_json", session);
|
||||
});
|
||||
|
||||
@@ -267,6 +285,7 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
openFilesForSession([indexTs], session);
|
||||
const project = session.getProjectService().configuredProjects.get(tsconfig.path)!;
|
||||
assert.isUndefined(project.getPackageJsonAutoImportProvider());
|
||||
session.host.baselineHost("After getPackageJsonAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "Does not create an auto import provider if there are too many dependencies", session);
|
||||
});
|
||||
|
||||
@@ -291,6 +310,7 @@ describe("unittests:: tsserver:: autoImportProvider", () => {
|
||||
const project = session.getProjectService().configuredProjects.get("/tsconfig.json")!;
|
||||
const autoImportProvider = project.getPackageJsonAutoImportProvider()!;
|
||||
assert.isDefined(autoImportProvider);
|
||||
session.host.baselineHost("After getPackageJsonAutoImportProvider");
|
||||
|
||||
// Trigger completions to ensure export info map is populated
|
||||
triggerCompletions("/index.ts", 0, 0);
|
||||
@@ -336,6 +356,7 @@ describe("unittests:: tsserver:: autoImportProvider - monorepo", () => {
|
||||
|
||||
// Project for A is created - ensure it doesn't have an autoImportProvider
|
||||
assert.isUndefined(session.getProjectService().configuredProjects.get("/packages/a/tsconfig.json")!.getLanguageService().getAutoImportProvider());
|
||||
session.host.baselineHost("After getAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "Does not create auto import providers upon opening projects for find-all-references", session);
|
||||
});
|
||||
|
||||
@@ -355,7 +376,9 @@ describe("unittests:: tsserver:: autoImportProvider - monorepo", () => {
|
||||
const { session } = setup(files);
|
||||
openFilesForSession([files[2]], session);
|
||||
assert.isDefined(session.getProjectService().configuredProjects.get("/packages/a/tsconfig.json")!.getPackageJsonAutoImportProvider());
|
||||
session.host.baselineHost("After getPackageJsonAutoImportProvider");
|
||||
assert.isDefined(session.getProjectService().configuredProjects.get("/packages/a/tsconfig.json")!.getPackageJsonAutoImportProvider());
|
||||
session.host.baselineHost("After getPackageJsonAutoImportProvider");
|
||||
baselineTsserverLogs("autoImportProvider", "Does not close when root files are redirects that dont actually exist", session);
|
||||
});
|
||||
|
||||
|
||||
@@ -1022,11 +1022,6 @@ describe("unittests:: tsserver:: compileOnSave:: CompileOnSaveAffectedFileListRe
|
||||
});
|
||||
}
|
||||
|
||||
function logDirtyOfProjects(session: TestSession) {
|
||||
session.logger.log(`Project1 is dirty: ${session.getProjectService().configuredProjects.get(`/user/username/projects/myproject/app1/tsconfig.json`)!.dirty}`);
|
||||
session.logger.log(`Project2 is dirty: ${session.getProjectService().configuredProjects.get(`/user/username/projects/myproject/app2/tsconfig.json`)!.dirty}`);
|
||||
}
|
||||
|
||||
function verify(subScenario: string, commandArgs: ts.server.protocol.FileRequestArgs) {
|
||||
it(subScenario, () => {
|
||||
const core: File = {
|
||||
@@ -1063,12 +1058,10 @@ describe("unittests:: tsserver:: compileOnSave:: CompileOnSaveAffectedFileListRe
|
||||
openFilesForSession([app1, app2, core], session);
|
||||
insertString(session, app1);
|
||||
insertString(session, app2);
|
||||
logDirtyOfProjects(session);
|
||||
session.executeCommandSeq<ts.server.protocol.CompileOnSaveAffectedFileListRequest>({
|
||||
command: ts.server.protocol.CommandTypes.CompileOnSaveAffectedFileList,
|
||||
arguments: commandArgs,
|
||||
});
|
||||
logDirtyOfProjects(session);
|
||||
baselineTsserverLogs("compileOnSave", subScenario, session);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ import {
|
||||
import {
|
||||
baselineTsserverLogs,
|
||||
closeFilesForSession,
|
||||
logConfiguredProjectsHasOpenRefStatus,
|
||||
logInferredProjectsOrphanStatus,
|
||||
openFilesForSession,
|
||||
TestSession,
|
||||
verifyGetErrRequest,
|
||||
@@ -230,8 +228,6 @@ describe("unittests:: tsserver:: ConfiguredProjects", () => {
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
// will not remove project 1
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
// Open random file and it will reuse first inferred project
|
||||
openFilesForSession([randomFile], session);
|
||||
baselineTsserverLogs("configuredProjects", "should properly handle module resolution changes in config file", session);
|
||||
@@ -301,13 +297,8 @@ describe("unittests:: tsserver:: ConfiguredProjects", () => {
|
||||
const host = createServerHost([file1, file2, configFile, libFile]);
|
||||
const session = new TestSession({ host, useSingleInferredProject: true });
|
||||
openFilesForSession([file1], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // file1
|
||||
|
||||
closeFilesForSession([file1], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // No open files
|
||||
|
||||
openFilesForSession([file2], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // file2
|
||||
baselineTsserverLogs("configuredProjects", "should reuse same project if file is opened from the configured project that has no open files", session);
|
||||
});
|
||||
|
||||
@@ -328,13 +319,8 @@ describe("unittests:: tsserver:: ConfiguredProjects", () => {
|
||||
const host = createServerHost([file1, configFile, libFile]);
|
||||
const session = new TestSession({ host, useSingleInferredProject: true });
|
||||
openFilesForSession([file1], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // file1
|
||||
|
||||
closeFilesForSession([file1], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // No files
|
||||
|
||||
openFilesForSession([libFile], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // No files + project closed
|
||||
baselineTsserverLogs("configuredProjects", "should not close configured project after closing last open file, but should be closed on next file open if its not the file from same project", session);
|
||||
});
|
||||
|
||||
@@ -362,7 +348,6 @@ describe("unittests:: tsserver:: ConfiguredProjects", () => {
|
||||
|
||||
host.writeFile(configFile.path, configFile.content);
|
||||
host.runQueuedTimeoutCallbacks(); // load configured project from disk + ensureProjectsForOpenFiles
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
baselineTsserverLogs("configuredProjects", "open file become a part of configured project if it is referenced from root file", session);
|
||||
});
|
||||
|
||||
@@ -466,24 +451,11 @@ describe("unittests:: tsserver:: ConfiguredProjects", () => {
|
||||
const session = new TestSession(host);
|
||||
openFilesForSession([file1, file2, file3, file4], session);
|
||||
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // file1 and file3
|
||||
|
||||
host.writeFile(configFile.path, "{}");
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // file1, file2, file3
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
closeFilesForSession([file1, file2, file4], session);
|
||||
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // file3
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
openFilesForSession([file4], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // file3
|
||||
|
||||
closeFilesForSession([file3], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // No files
|
||||
|
||||
const file5: File = {
|
||||
path: "/file5.ts",
|
||||
@@ -523,23 +495,15 @@ describe("unittests:: tsserver:: ConfiguredProjects", () => {
|
||||
const host = createServerHost(hostFiles);
|
||||
const session = new TestSession(host);
|
||||
openFilesForSession([file1, file2, file3], session);
|
||||
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // file1 and file3
|
||||
|
||||
closeFilesForSession([file1, file3], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // No files
|
||||
|
||||
host.writeFile(configFile.path, "{}");
|
||||
session.host.baselineHost("configFile updated");
|
||||
// Time out is not yet run so there is project update pending
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // Pending update and file2 might get into the project
|
||||
|
||||
openFilesForSession([file4], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // Pending update and F2 might get into the project
|
||||
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // file2
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
baselineTsserverLogs("configuredProjects", "Open ref of configured project when open file gets added to the project as part of configured file update buts its open file references are all closed when the update happens", session);
|
||||
});
|
||||
|
||||
@@ -566,29 +530,13 @@ describe("unittests:: tsserver:: ConfiguredProjects", () => {
|
||||
|
||||
const session = new TestSession(host);
|
||||
openFilesForSession([f1], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // f1
|
||||
|
||||
closeFilesForSession([f1], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // No files
|
||||
|
||||
for (const f of [f1, f2, f3]) {
|
||||
// All the script infos should be present and contain the project since it is still alive.
|
||||
const scriptInfo = session.getProjectService().getScriptInfoForNormalizedPath(ts.server.toNormalizedPath(f.path))!;
|
||||
session.logger.log(`Containing projects for ${f.path}:: ${scriptInfo.containingProjects.map(p => p.projectName).join(",")}`);
|
||||
}
|
||||
|
||||
const f4 = {
|
||||
path: "/aa.js",
|
||||
content: "var x = 1",
|
||||
};
|
||||
host.writeFile(f4.path, f4.content);
|
||||
openFilesForSession([f4], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session); // No files
|
||||
|
||||
for (const f of [f1, f2, f3]) {
|
||||
// All the script infos should not be present since the project is closed and orphan script infos are collected
|
||||
assert.isUndefined(session.getProjectService().getScriptInfoForNormalizedPath(ts.server.toNormalizedPath(f.path)));
|
||||
}
|
||||
baselineTsserverLogs("configuredProjects", "files are properly detached when language service is disabled", session);
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
protocolFileLocationFromSubstring,
|
||||
setCompilerOptionsForInferredProjectsRequestForSession,
|
||||
TestSession,
|
||||
verifyDynamic,
|
||||
} from "../helpers/tsserver";
|
||||
import {
|
||||
createServerHost,
|
||||
@@ -25,8 +24,6 @@ var x = 10;`,
|
||||
const host = createServerHost([libFile]);
|
||||
const session = new TestSession(host);
|
||||
openFilesForSession([{ file, content: file.content }], session);
|
||||
verifyDynamic(session, session.getProjectService().toPath(file.path));
|
||||
|
||||
baselineTsserverLogs("dynamicFiles", subscenario, session);
|
||||
});
|
||||
}
|
||||
@@ -50,7 +47,6 @@ describe("unittests:: tsserver:: dynamicFiles:: Untitled files", () => {
|
||||
projectRootPath: "/proj",
|
||||
},
|
||||
});
|
||||
verifyDynamic(session, `/proj/untitled:^untitled-1`);
|
||||
session.executeCommandSeq<ts.server.protocol.CodeFixRequest>({
|
||||
command: ts.server.protocol.CommandTypes.GetCodeFixes,
|
||||
arguments: {
|
||||
@@ -77,7 +73,6 @@ describe("unittests:: tsserver:: dynamicFiles:: Untitled files", () => {
|
||||
content: "const x = 10;",
|
||||
projectRootPath: "/user/username/projects/myproject",
|
||||
}], session);
|
||||
verifyDynamic(session, `/user/username/projects/myproject/${untitledFile}`);
|
||||
|
||||
const untitled: File = {
|
||||
path: `/user/username/projects/myproject/Untitled-1.ts`,
|
||||
@@ -97,7 +92,6 @@ describe("unittests:: tsserver:: dynamicFiles:: Untitled files", () => {
|
||||
content: "const x = 10;",
|
||||
projectRootPath: "/user/username/projects/myproject",
|
||||
}], session);
|
||||
verifyDynamic(session, `/user/username/projects/myproject/${untitledFile}`);
|
||||
baselineTsserverLogs("dynamicFiles", "opening untitled files", session);
|
||||
});
|
||||
|
||||
@@ -117,7 +111,6 @@ describe("unittests:: tsserver:: dynamicFiles:: Untitled files", () => {
|
||||
content: "const x = 10;",
|
||||
projectRootPath: "/user/username/projects/myproject",
|
||||
}], session);
|
||||
verifyDynamic(session, `/user/username/projects/myproject/${untitledFile}`);
|
||||
|
||||
// Close untitled file
|
||||
closeFilesForSession([untitledFile], session);
|
||||
@@ -173,8 +166,6 @@ describe("unittests:: tsserver:: dynamicFiles:: ", () => {
|
||||
}, session);
|
||||
openFilesForSession([{ file: file.path, content: "var x = 10;" }], session);
|
||||
|
||||
verifyDynamic(session, `/${file.path}`);
|
||||
|
||||
session.executeCommandSeq<ts.server.protocol.QuickInfoRequest>({
|
||||
command: ts.server.protocol.CommandTypes.Quickinfo,
|
||||
arguments: protocolFileLocationFromSubstring(file, "x"),
|
||||
@@ -202,8 +193,6 @@ describe("unittests:: tsserver:: dynamicFiles:: ", () => {
|
||||
const session = new TestSession({ host, useInferredProjectPerProjectRoot: true });
|
||||
openFilesForSession([{ file: file.path, projectRootPath: "/user/username/projects/myproject" }], session);
|
||||
|
||||
verifyDynamic(session, `/user/username/projects/myproject/${file.path}`);
|
||||
|
||||
session.executeCommandSeq<ts.server.protocol.OutliningSpansRequest>({
|
||||
command: ts.server.protocol.CommandTypes.GetOutliningSpans,
|
||||
arguments: {
|
||||
|
||||
@@ -83,6 +83,7 @@ describe("unittests:: tsserver:: exportMapCache", () => {
|
||||
project.getPackageJsonAutoImportProvider();
|
||||
assert.ok(exportMapCache.isUsableByFile(bTs.path as ts.Path));
|
||||
assert.ok(!exportMapCache.isEmpty());
|
||||
session.host.baselineHost("After getPackageJsonAutoImportProvider");
|
||||
baselineTsserverLogs("exportMapCache", "does not invalidate the cache when package.json is changed inconsequentially", session);
|
||||
});
|
||||
|
||||
@@ -93,6 +94,7 @@ describe("unittests:: tsserver:: exportMapCache", () => {
|
||||
project.getPackageJsonAutoImportProvider();
|
||||
assert.ok(!exportMapCache.isUsableByFile(bTs.path as ts.Path));
|
||||
assert.ok(exportMapCache.isEmpty());
|
||||
session.host.baselineHost("After getPackageJsonAutoImportProvider");
|
||||
baselineTsserverLogs("exportMapCache", "invalidates the cache when package.json change results in AutoImportProvider change", session);
|
||||
});
|
||||
|
||||
@@ -206,6 +208,7 @@ describe("unittests:: tsserver:: exportMapCache", () => {
|
||||
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
project.getPackageJsonAutoImportProvider();
|
||||
session.host.baselineHost("After getPackageJsonAutoImportProvider");
|
||||
|
||||
// Cache is invalidated because other file has changed
|
||||
assert.ok(!exportMapCache.isUsableByFile(classesTs.path as ts.Path));
|
||||
|
||||
@@ -6,15 +6,12 @@ import {
|
||||
import {
|
||||
baselineTsserverLogs,
|
||||
closeFilesForSession,
|
||||
logConfiguredProjectsHasOpenRefStatus,
|
||||
logInferredProjectsOrphanStatus,
|
||||
openExternalProjectForSession,
|
||||
openExternalProjectsForSession,
|
||||
openFilesForSession,
|
||||
TestSession,
|
||||
toExternalFile,
|
||||
toExternalFiles,
|
||||
verifyDynamic,
|
||||
} from "../helpers/tsserver";
|
||||
import {
|
||||
createServerHost,
|
||||
@@ -176,8 +173,6 @@ describe("unittests:: tsserver:: externalProjects", () => {
|
||||
projectFileName,
|
||||
}, session);
|
||||
|
||||
verifyDynamic(session, "/^scriptdocument1 file1.ts");
|
||||
|
||||
externalFiles[0].content = "let x =1;";
|
||||
session.executeCommandSeq<ts.server.protocol.ApplyChangedToOpenFilesRequest>({
|
||||
command: ts.server.protocol.CommandTypes.ApplyChangedToOpenFiles,
|
||||
@@ -252,23 +247,16 @@ describe("unittests:: tsserver:: externalProjects", () => {
|
||||
|
||||
// open client file - should not lead to creation of inferred project
|
||||
openFilesForSession([file1], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
openFilesForSession([file3], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
session.executeCommandSeq<ts.server.protocol.CloseExternalProjectRequest>({
|
||||
command: ts.server.protocol.CommandTypes.CloseExternalProject,
|
||||
arguments: { projectFileName },
|
||||
});
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
// open file 'file1' from configured project keeps project alive
|
||||
|
||||
closeFilesForSession([file3], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
closeFilesForSession([file1], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
openFilesForSession([file2], session);
|
||||
baselineTsserverLogs("externalProjects", "external project that included config files", session);
|
||||
@@ -714,12 +702,9 @@ describe("unittests:: tsserver:: externalProjects", () => {
|
||||
const host = createServerHost([f, config]);
|
||||
const session = new TestSession(host);
|
||||
openFilesForSession([f], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session);
|
||||
closeFilesForSession([f], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session);
|
||||
|
||||
openFilesForSession([f], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session);
|
||||
baselineTsserverLogs("externalProjects", "should handle non-existing directories in config file", session);
|
||||
});
|
||||
|
||||
@@ -814,7 +799,6 @@ describe("unittests:: tsserver:: externalProjects", () => {
|
||||
rootFiles: [{ fileName: jsConfig.path }, { fileName: tsconfig.path }, { fileName: jsFilePath }],
|
||||
options: { allowJs: false },
|
||||
}], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
baselineTsserverLogs("externalProjects", "handles creation of external project with jsconfig before jsconfig creation watcher is invoked", session);
|
||||
});
|
||||
|
||||
|
||||
@@ -116,4 +116,61 @@ import { value1 } from "../node_modules/.cache/someFile.d.ts";`,
|
||||
});
|
||||
baselineTsserverLogs("getMoveToRefactoringFileSuggestions", "skips lib.d.ts files", session);
|
||||
});
|
||||
|
||||
it("should show ts files when moving non-tsx content from tsx file", () => {
|
||||
const file1: File = {
|
||||
path: "/bar.tsx",
|
||||
content: `export function bar() { }`,
|
||||
};
|
||||
const file2: File = {
|
||||
path: "/foo.ts",
|
||||
content: "export function foo() { }",
|
||||
};
|
||||
const tsconfig: File = {
|
||||
path: "/tsconfig.json",
|
||||
content: jsonToReadableText({
|
||||
jsx: "preserve",
|
||||
files: ["./foo.ts", "./bar.tsx"],
|
||||
}),
|
||||
};
|
||||
|
||||
const host = createServerHost([file1, file2, tsconfig]);
|
||||
const session = new TestSession(host);
|
||||
openFilesForSession([file1], session);
|
||||
|
||||
session.executeCommandSeq<ts.server.protocol.GetMoveToRefactoringFileSuggestionsRequest>({
|
||||
command: ts.server.protocol.CommandTypes.GetMoveToRefactoringFileSuggestions,
|
||||
arguments: { file: file1.path, line: 1, offset: 7 },
|
||||
});
|
||||
baselineTsserverLogs("getMoveToRefactoringFileSuggestions", "should show ts files when moving non-tsx content from tsx file", session);
|
||||
});
|
||||
|
||||
it("should show js files when moving non-jsx content from jsx file", () => {
|
||||
const file1: File = {
|
||||
path: "/bar.jsx",
|
||||
content: `export function bar() { }`,
|
||||
};
|
||||
const file2: File = {
|
||||
path: "/foo.js",
|
||||
content: "export function foo() { }",
|
||||
};
|
||||
const tsconfig: File = {
|
||||
path: "/tsconfig.json",
|
||||
content: jsonToReadableText({
|
||||
allowJS: true,
|
||||
jsx: "preserve",
|
||||
files: ["./foo.js", "./bar.jsx"],
|
||||
}),
|
||||
};
|
||||
|
||||
const host = createServerHost([file1, file2, tsconfig]);
|
||||
const session = new TestSession(host);
|
||||
openFilesForSession([file1], session);
|
||||
|
||||
session.executeCommandSeq<ts.server.protocol.GetMoveToRefactoringFileSuggestionsRequest>({
|
||||
command: ts.server.protocol.CommandTypes.GetMoveToRefactoringFileSuggestions,
|
||||
arguments: { file: file1.path, line: 1, offset: 7 },
|
||||
});
|
||||
baselineTsserverLogs("getMoveToRefactoringFileSuggestions", "should show js files when moving non-jsx content from jsx file", session);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
import {
|
||||
baselineTsserverLogs,
|
||||
closeFilesForSession,
|
||||
logInferredProjectsOrphanStatus,
|
||||
openFilesForSession,
|
||||
setCompilerOptionsForInferredProjectsRequestForSession,
|
||||
TestSession,
|
||||
@@ -107,7 +106,6 @@ describe("unittests:: tsserver:: inferredProjects", () => {
|
||||
moduleResolution: ts.server.protocol.ModuleResolutionKind.Classic,
|
||||
}, session);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
baselineTsserverLogs("inferredProjects", "project settings for inferred projects", session);
|
||||
});
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ function fooB() { }`,
|
||||
const project = service.inferredProjects[0];
|
||||
assert.isFalse(project.autoImportProviderHost);
|
||||
assert.isUndefined(project.getPackageJsonAutoImportProvider());
|
||||
session.host.baselineHost("After getPackageJsonAutoImportProvider");
|
||||
assert.deepEqual(project.getPackageJsonsForAutoImport(), ts.emptyArray);
|
||||
baselineTsserverLogs("partialSemanticServer", "should not create autoImportProvider or handle package jsons", session);
|
||||
});
|
||||
|
||||
@@ -3,7 +3,6 @@ import {
|
||||
jsonToReadableText,
|
||||
} from "../helpers";
|
||||
import {
|
||||
appendAllScriptInfos,
|
||||
baselineTsserverLogs,
|
||||
closeFilesForSession,
|
||||
openExternalProjectForSession,
|
||||
@@ -241,7 +240,6 @@ describe("unittests:: tsserver:: projectErrors:: are reported as appropriate", (
|
||||
projectRootPath: useProjectRoot ? folderPath : undefined,
|
||||
},
|
||||
});
|
||||
appendAllScriptInfos(session);
|
||||
|
||||
// Since this is not js project so no typings are queued
|
||||
verifyGetErrRequest({ session, files: [untitledFile] });
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,8 +12,6 @@ import {
|
||||
import {
|
||||
baselineTsserverLogs,
|
||||
closeFilesForSession,
|
||||
logConfiguredProjectsHasOpenRefStatus,
|
||||
logInferredProjectsOrphanStatus,
|
||||
openExternalProjectForSession,
|
||||
openFilesForSession,
|
||||
protocolFileLocationFromSubstring,
|
||||
@@ -185,7 +183,7 @@ describe("unittests:: tsserver:: projects::", () => {
|
||||
};
|
||||
session.host.baselineHost("Before request");
|
||||
session.logger.info(`request:${ts.server.stringifyIndented(request)}`);
|
||||
session.getProjectService().openExternalProject(request.arguments);
|
||||
session.getProjectService().openExternalProject(request.arguments, /*print*/ true);
|
||||
session.host.baselineHost("After request");
|
||||
baselineTsserverLogs("projects", "external project including config file", session);
|
||||
});
|
||||
@@ -325,7 +323,6 @@ describe("unittests:: tsserver:: projects::", () => {
|
||||
|
||||
host.writeFile(file2.path, `export * from "../c/f3"`); // now inferred project should inclule file3
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
baselineTsserverLogs("projects", "changes in closed files are reflected in project structure", session);
|
||||
});
|
||||
|
||||
@@ -512,22 +509,11 @@ describe("unittests:: tsserver:: projects::", () => {
|
||||
const session = new TestSession(host);
|
||||
|
||||
openFilesForSession([file2], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
openFilesForSession([file3], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
closeFilesForSession([file1], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
closeFilesForSession([file3], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
|
||||
openFilesForSession([file3], session);
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
baselineTsserverLogs("projects", "correctly migrate files between projects", session);
|
||||
});
|
||||
|
||||
@@ -892,19 +878,10 @@ describe("unittests:: tsserver:: projects::", () => {
|
||||
const session = new TestSession(host);
|
||||
|
||||
openFilesForSession([file2], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session);
|
||||
|
||||
openFilesForSession([file1], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session);
|
||||
|
||||
closeFilesForSession([file2], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session);
|
||||
|
||||
closeFilesForSession([file1], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session);
|
||||
|
||||
openFilesForSession([file2], session);
|
||||
logConfiguredProjectsHasOpenRefStatus(session);
|
||||
baselineTsserverLogs("projects", "File in multiple projects at opened and closed correctly", session);
|
||||
});
|
||||
|
||||
@@ -1183,19 +1160,11 @@ describe("unittests:: tsserver:: projects::", () => {
|
||||
host.writeFile(config.path, config.content);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
verifyFile2InfoIsOrphan();
|
||||
|
||||
file2.content += "export let z = 10;";
|
||||
host.writeFile(file2.path, file2.content);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
verifyFile2InfoIsOrphan();
|
||||
baselineTsserverLogs("projects", "Orphan source files are handled correctly on watch trigger", session);
|
||||
|
||||
function verifyFile2InfoIsOrphan() {
|
||||
const info = ts.Debug.checkDefined(session.getProjectService().getScriptInfoForPath(file2.path as ts.Path));
|
||||
session.logger.log(`Containing projects for ${file2.path}:: ${info.containingProjects.map(p => p.projectName).join(",")}`);
|
||||
}
|
||||
});
|
||||
|
||||
it("no project structure update on directory watch invoke on open file save", () => {
|
||||
|
||||
@@ -2,7 +2,6 @@ import * as ts from "../../_namespaces/ts";
|
||||
import {
|
||||
baselineTsserverLogs,
|
||||
closeFilesForSession,
|
||||
logInferredProjectsOrphanStatus,
|
||||
openFilesForSession,
|
||||
TestSession,
|
||||
} from "../helpers/tsserver";
|
||||
@@ -71,7 +70,6 @@ describe("unittests:: tsserver:: reload", () => {
|
||||
// send close request
|
||||
closeFilesForSession([f1], session);
|
||||
checkScriptInfoAndProjects("contents of closed file");
|
||||
checkInferredProjectIsOrphan();
|
||||
|
||||
// Can reload contents of the file when its not open and has no project
|
||||
// reload from temp file
|
||||
@@ -80,7 +78,6 @@ describe("unittests:: tsserver:: reload", () => {
|
||||
arguments: { file: f1.path, tmpfile: tmp.path },
|
||||
});
|
||||
checkScriptInfoAndProjects("contents of temp file");
|
||||
checkInferredProjectIsOrphan();
|
||||
|
||||
// reload from own file
|
||||
session.executeCommandSeq<ts.server.protocol.ReloadRequest>({
|
||||
@@ -88,7 +85,6 @@ describe("unittests:: tsserver:: reload", () => {
|
||||
arguments: { file: f1.path, tmpfile: undefined! },
|
||||
});
|
||||
checkScriptInfoAndProjects("contents of closed file");
|
||||
checkInferredProjectIsOrphan();
|
||||
|
||||
// Open file again without setting its content
|
||||
openFilesForSession([f1], session);
|
||||
@@ -99,7 +95,6 @@ describe("unittests:: tsserver:: reload", () => {
|
||||
closeFilesForSession([f1], session);
|
||||
checkScriptInfoAndProjects("contents of closed file");
|
||||
assert.strictEqual(info.getSnapshot(), snap);
|
||||
checkInferredProjectIsOrphan();
|
||||
|
||||
// reload from temp file
|
||||
session.executeCommandSeq<ts.server.protocol.ReloadRequest>({
|
||||
@@ -108,7 +103,6 @@ describe("unittests:: tsserver:: reload", () => {
|
||||
});
|
||||
checkScriptInfoAndProjects("contents of temp file");
|
||||
assert.notStrictEqual(info.getSnapshot(), snap);
|
||||
checkInferredProjectIsOrphan();
|
||||
|
||||
// reload from own file
|
||||
session.executeCommandSeq<ts.server.protocol.ReloadRequest>({
|
||||
@@ -117,14 +111,8 @@ describe("unittests:: tsserver:: reload", () => {
|
||||
});
|
||||
checkScriptInfoAndProjects("contents of closed file");
|
||||
assert.notStrictEqual(info.getSnapshot(), snap);
|
||||
checkInferredProjectIsOrphan();
|
||||
baselineTsserverLogs("reload", "should work when script info doesnt have any project open", session);
|
||||
|
||||
function checkInferredProjectIsOrphan() {
|
||||
logInferredProjectsOrphanStatus(session);
|
||||
session.logger.log(`info:: ${info.path}:: ${info.containingProjects.map(p => p.projectName).join(",")}`);
|
||||
}
|
||||
|
||||
function checkScriptInfoAndProjects(captionForContents: string) {
|
||||
assert.strictEqual(session.getProjectService().getScriptInfo(f1.path), info);
|
||||
checkScriptInfoContents(captionForContents);
|
||||
|
||||
@@ -1667,6 +1667,7 @@ describe("unittests:: tsserver:: typingsInstaller:: discover typings", () => {
|
||||
const log = loggerToTypingsInstallerLog(logger);
|
||||
const testhost = patchHostTimeouts(
|
||||
changeToHostTrackingWrittenFiles(host),
|
||||
/*session*/ undefined,
|
||||
logger,
|
||||
);
|
||||
testhost.baselineHost("");
|
||||
|
||||
@@ -21,10 +21,6 @@
|
||||
"useUnknownInCatchVariables": false,
|
||||
"noImplicitOverride": true,
|
||||
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"allowUnusedLabels": false,
|
||||
|
||||
"skipLibCheck": true,
|
||||
|
||||
"alwaysStrict": true,
|
||||
|
||||
+1
-12
@@ -3332,18 +3332,6 @@ declare namespace ts {
|
||||
* Last version that was reported.
|
||||
*/
|
||||
private lastReportedVersion;
|
||||
/**
|
||||
* Current project's program version. (incremented everytime new program is created that is not complete reuse from the old one)
|
||||
* This property is changed in 'updateGraph' based on the set of files in program
|
||||
*/
|
||||
private projectProgramVersion;
|
||||
/**
|
||||
* Current version of the project state. It is changed when:
|
||||
* - new root file was added/removed
|
||||
* - edit happen in some file that is currently included in the project.
|
||||
* This property is different from projectStructureVersion since in most cases edits don't affect set of files in the project
|
||||
*/
|
||||
private projectStateVersion;
|
||||
protected projectErrors: Diagnostic[] | undefined;
|
||||
protected isInitialLoadPending: () => boolean;
|
||||
private readonly cancellationToken;
|
||||
@@ -3918,6 +3906,7 @@ declare namespace ts {
|
||||
private static escapeFilenameForRegex;
|
||||
resetSafeList(): void;
|
||||
applySafeList(proj: protocol.ExternalProject): NormalizedPath[];
|
||||
private applySafeListWorker;
|
||||
openExternalProject(proj: protocol.ExternalProject): void;
|
||||
hasDeferredExtension(): boolean;
|
||||
private enableRequestedPluginsAsync;
|
||||
|
||||
@@ -24,10 +24,10 @@ declare const itNum: Iterable<number>
|
||||
|
||||
;(function(a, ...rest) {})('', true, ...itNum)
|
||||
>(function(a, ...rest) {})('', true, ...itNum) : void
|
||||
>(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest_1: any[]) => void
|
||||
>function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest_1: any[]) => void
|
||||
>(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest_1: Iterable<number>[]) => void
|
||||
>function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest_1: Iterable<number>[]) => void
|
||||
>a : string
|
||||
>rest : [boolean, ...any[]]
|
||||
>rest : [boolean, ...Iterable<number>[]]
|
||||
>'' : ""
|
||||
>true : true
|
||||
>...itNum : Iterable<number>
|
||||
@@ -60,8 +60,8 @@ const res3 = fn1(true, ..."hello");
|
||||
>"hello" : "hello"
|
||||
|
||||
const res4 = fn1(true, ...itNum);
|
||||
>res4 : readonly [true, ...any[]]
|
||||
>fn1(true, ...itNum) : readonly [true, ...any[]]
|
||||
>res4 : readonly [true, ...Iterable<number>[]]
|
||||
>fn1(true, ...itNum) : readonly [true, ...Iterable<number>[]]
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>...itNum : Iterable<number>
|
||||
@@ -95,8 +95,8 @@ const p3 = foo(true, ..."hello");
|
||||
>"hello" : "hello"
|
||||
|
||||
const p4 = foo(true, ...itNum);
|
||||
>p4 : [boolean, ...any[]]
|
||||
>foo(true, ...itNum) : [boolean, ...any[]]
|
||||
>p4 : [boolean, ...Iterable<number>[]]
|
||||
>foo(true, ...itNum) : [boolean, ...Iterable<number>[]]
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>...itNum : Iterable<number>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
assignmentToAnyArrayRestParameters.ts(15,25): error TS2339: Property '0.0' does not exist on type 'string[]'.
|
||||
assignmentToAnyArrayRestParameters.ts(18,16): error TS2536: Type '"0.0"' cannot be used to index type 'T'.
|
||||
|
||||
|
||||
==== assignmentToAnyArrayRestParameters.ts (2 errors) ====
|
||||
// Repros from #57122
|
||||
|
||||
function foo<T extends string[]>(
|
||||
fa: (s: string, ...args: string[]) => string,
|
||||
fb: (s: string, ...args: T) => string
|
||||
) {
|
||||
const f1: (...args: any) => string = fa;
|
||||
const f2: (...args: any[]) => string = fa;
|
||||
const f3: (...args: any) => string = fb;
|
||||
const f4: (...args: any[]) => string = fb;
|
||||
}
|
||||
|
||||
function bar<T extends string[], K extends number>() {
|
||||
type T00 = string[]["0"];
|
||||
type T01 = string[]["0.0"]; // Error
|
||||
~~~~~
|
||||
!!! error TS2339: Property '0.0' does not exist on type 'string[]'.
|
||||
type T02 = string[][K | "0"];
|
||||
type T10 = T["0"];
|
||||
type T11 = T["0.0"]; // Error
|
||||
~~~~~~~~
|
||||
!!! error TS2536: Type '"0.0"' cannot be used to index type 'T'.
|
||||
type T12 = T[K | "0"];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
//// [tests/cases/compiler/assignmentToAnyArrayRestParameters.ts] ////
|
||||
|
||||
=== assignmentToAnyArrayRestParameters.ts ===
|
||||
// Repros from #57122
|
||||
|
||||
function foo<T extends string[]>(
|
||||
>foo : Symbol(foo, Decl(assignmentToAnyArrayRestParameters.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(assignmentToAnyArrayRestParameters.ts, 2, 13))
|
||||
|
||||
fa: (s: string, ...args: string[]) => string,
|
||||
>fa : Symbol(fa, Decl(assignmentToAnyArrayRestParameters.ts, 2, 33))
|
||||
>s : Symbol(s, Decl(assignmentToAnyArrayRestParameters.ts, 3, 9))
|
||||
>args : Symbol(args, Decl(assignmentToAnyArrayRestParameters.ts, 3, 19))
|
||||
|
||||
fb: (s: string, ...args: T) => string
|
||||
>fb : Symbol(fb, Decl(assignmentToAnyArrayRestParameters.ts, 3, 49))
|
||||
>s : Symbol(s, Decl(assignmentToAnyArrayRestParameters.ts, 4, 9))
|
||||
>args : Symbol(args, Decl(assignmentToAnyArrayRestParameters.ts, 4, 19))
|
||||
>T : Symbol(T, Decl(assignmentToAnyArrayRestParameters.ts, 2, 13))
|
||||
|
||||
) {
|
||||
const f1: (...args: any) => string = fa;
|
||||
>f1 : Symbol(f1, Decl(assignmentToAnyArrayRestParameters.ts, 6, 9))
|
||||
>args : Symbol(args, Decl(assignmentToAnyArrayRestParameters.ts, 6, 15))
|
||||
>fa : Symbol(fa, Decl(assignmentToAnyArrayRestParameters.ts, 2, 33))
|
||||
|
||||
const f2: (...args: any[]) => string = fa;
|
||||
>f2 : Symbol(f2, Decl(assignmentToAnyArrayRestParameters.ts, 7, 9))
|
||||
>args : Symbol(args, Decl(assignmentToAnyArrayRestParameters.ts, 7, 15))
|
||||
>fa : Symbol(fa, Decl(assignmentToAnyArrayRestParameters.ts, 2, 33))
|
||||
|
||||
const f3: (...args: any) => string = fb;
|
||||
>f3 : Symbol(f3, Decl(assignmentToAnyArrayRestParameters.ts, 8, 9))
|
||||
>args : Symbol(args, Decl(assignmentToAnyArrayRestParameters.ts, 8, 15))
|
||||
>fb : Symbol(fb, Decl(assignmentToAnyArrayRestParameters.ts, 3, 49))
|
||||
|
||||
const f4: (...args: any[]) => string = fb;
|
||||
>f4 : Symbol(f4, Decl(assignmentToAnyArrayRestParameters.ts, 9, 9))
|
||||
>args : Symbol(args, Decl(assignmentToAnyArrayRestParameters.ts, 9, 15))
|
||||
>fb : Symbol(fb, Decl(assignmentToAnyArrayRestParameters.ts, 3, 49))
|
||||
}
|
||||
|
||||
function bar<T extends string[], K extends number>() {
|
||||
>bar : Symbol(bar, Decl(assignmentToAnyArrayRestParameters.ts, 10, 1))
|
||||
>T : Symbol(T, Decl(assignmentToAnyArrayRestParameters.ts, 12, 13))
|
||||
>K : Symbol(K, Decl(assignmentToAnyArrayRestParameters.ts, 12, 32))
|
||||
|
||||
type T00 = string[]["0"];
|
||||
>T00 : Symbol(T00, Decl(assignmentToAnyArrayRestParameters.ts, 12, 54))
|
||||
|
||||
type T01 = string[]["0.0"]; // Error
|
||||
>T01 : Symbol(T01, Decl(assignmentToAnyArrayRestParameters.ts, 13, 29))
|
||||
|
||||
type T02 = string[][K | "0"];
|
||||
>T02 : Symbol(T02, Decl(assignmentToAnyArrayRestParameters.ts, 14, 31))
|
||||
>K : Symbol(K, Decl(assignmentToAnyArrayRestParameters.ts, 12, 32))
|
||||
|
||||
type T10 = T["0"];
|
||||
>T10 : Symbol(T10, Decl(assignmentToAnyArrayRestParameters.ts, 15, 33))
|
||||
>T : Symbol(T, Decl(assignmentToAnyArrayRestParameters.ts, 12, 13))
|
||||
|
||||
type T11 = T["0.0"]; // Error
|
||||
>T11 : Symbol(T11, Decl(assignmentToAnyArrayRestParameters.ts, 16, 22))
|
||||
>T : Symbol(T, Decl(assignmentToAnyArrayRestParameters.ts, 12, 13))
|
||||
|
||||
type T12 = T[K | "0"];
|
||||
>T12 : Symbol(T12, Decl(assignmentToAnyArrayRestParameters.ts, 17, 24))
|
||||
>T : Symbol(T, Decl(assignmentToAnyArrayRestParameters.ts, 12, 13))
|
||||
>K : Symbol(K, Decl(assignmentToAnyArrayRestParameters.ts, 12, 32))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
//// [tests/cases/compiler/assignmentToAnyArrayRestParameters.ts] ////
|
||||
|
||||
=== assignmentToAnyArrayRestParameters.ts ===
|
||||
// Repros from #57122
|
||||
|
||||
function foo<T extends string[]>(
|
||||
>foo : <T extends string[]>(fa: (s: string, ...args: string[]) => string, fb: (s: string, ...args: T) => string) => void
|
||||
|
||||
fa: (s: string, ...args: string[]) => string,
|
||||
>fa : (s: string, ...args: string[]) => string
|
||||
>s : string
|
||||
>args : string[]
|
||||
|
||||
fb: (s: string, ...args: T) => string
|
||||
>fb : (s: string, ...args: T) => string
|
||||
>s : string
|
||||
>args : T
|
||||
|
||||
) {
|
||||
const f1: (...args: any) => string = fa;
|
||||
>f1 : (...args: any) => string
|
||||
>args : any
|
||||
>fa : (s: string, ...args: string[]) => string
|
||||
|
||||
const f2: (...args: any[]) => string = fa;
|
||||
>f2 : (...args: any[]) => string
|
||||
>args : any[]
|
||||
>fa : (s: string, ...args: string[]) => string
|
||||
|
||||
const f3: (...args: any) => string = fb;
|
||||
>f3 : (...args: any) => string
|
||||
>args : any
|
||||
>fb : (s: string, ...args: T) => string
|
||||
|
||||
const f4: (...args: any[]) => string = fb;
|
||||
>f4 : (...args: any[]) => string
|
||||
>args : any[]
|
||||
>fb : (s: string, ...args: T) => string
|
||||
}
|
||||
|
||||
function bar<T extends string[], K extends number>() {
|
||||
>bar : <T extends string[], K extends number>() => void
|
||||
|
||||
type T00 = string[]["0"];
|
||||
>T00 : string
|
||||
|
||||
type T01 = string[]["0.0"]; // Error
|
||||
>T01 : any
|
||||
|
||||
type T02 = string[][K | "0"];
|
||||
>T02 : string[][K | "0"]
|
||||
|
||||
type T10 = T["0"];
|
||||
>T10 : T["0"]
|
||||
|
||||
type T11 = T["0.0"]; // Error
|
||||
>T11 : T["0.0"]
|
||||
|
||||
type T12 = T[K | "0"];
|
||||
>T12 : T[K | "0"]
|
||||
}
|
||||
|
||||
@@ -13,4 +13,13 @@ blockScopedEnumVariablesUseBeforeDef.ts(2,12): error TS2450: Enum 'E' used befor
|
||||
function foo2() {
|
||||
return E.A
|
||||
const enum E { A }
|
||||
}
|
||||
}
|
||||
|
||||
const config = {
|
||||
a: AfterObject.A,
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
A = 2,
|
||||
}
|
||||
|
||||
@@ -9,7 +9,16 @@ function foo1() {
|
||||
function foo2() {
|
||||
return E.A
|
||||
const enum E { A }
|
||||
}
|
||||
}
|
||||
|
||||
const config = {
|
||||
a: AfterObject.A,
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
A = 2,
|
||||
}
|
||||
|
||||
|
||||
//// [blockScopedEnumVariablesUseBeforeDef.js]
|
||||
function foo1() {
|
||||
@@ -22,3 +31,6 @@ function foo1() {
|
||||
function foo2() {
|
||||
return 0 /* E.A */;
|
||||
}
|
||||
var config = {
|
||||
a: 2 /* AfterObject.A */,
|
||||
};
|
||||
|
||||
@@ -26,3 +26,22 @@ function foo2() {
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 6, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 7, 18))
|
||||
}
|
||||
|
||||
const config = {
|
||||
>config : Symbol(config, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 10, 5))
|
||||
|
||||
a: AfterObject.A,
|
||||
>a : Symbol(a, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 10, 16))
|
||||
>AfterObject.A : Symbol(AfterObject.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 14, 24))
|
||||
>AfterObject : Symbol(AfterObject, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 12, 2))
|
||||
>A : Symbol(AfterObject.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 14, 24))
|
||||
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
>AfterObject : Symbol(AfterObject, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 12, 2))
|
||||
|
||||
A = 2,
|
||||
>A : Symbol(AfterObject.A, Decl(blockScopedEnumVariablesUseBeforeDef.ts, 14, 24))
|
||||
}
|
||||
|
||||
|
||||
@@ -26,3 +26,24 @@ function foo2() {
|
||||
>E : E
|
||||
>A : E.A
|
||||
}
|
||||
|
||||
const config = {
|
||||
>config : { a: AfterObject; }
|
||||
>{ a: AfterObject.A,} : { a: AfterObject; }
|
||||
|
||||
a: AfterObject.A,
|
||||
>a : AfterObject
|
||||
>AfterObject.A : AfterObject
|
||||
>AfterObject : typeof AfterObject
|
||||
>A : AfterObject
|
||||
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
>AfterObject : AfterObject
|
||||
|
||||
A = 2,
|
||||
>A : AfterObject.A
|
||||
>2 : 2
|
||||
}
|
||||
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts(2,12): error TS2450: Enum 'E' used before its declaration.
|
||||
blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts(7,12): error TS2450: Enum 'E' used before its declaration.
|
||||
blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts(12,8): error TS2450: Enum 'AfterObject' used before its declaration.
|
||||
|
||||
|
||||
==== blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts (3 errors) ====
|
||||
function foo1() {
|
||||
return E.A
|
||||
~
|
||||
!!! error TS2450: Enum 'E' used before its declaration.
|
||||
!!! related TS2728 blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts:3:10: 'E' is declared here.
|
||||
enum E { A }
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
return E.A
|
||||
~
|
||||
!!! error TS2450: Enum 'E' used before its declaration.
|
||||
!!! related TS2728 blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts:8:16: 'E' is declared here.
|
||||
const enum E { A }
|
||||
}
|
||||
|
||||
const config = {
|
||||
a: AfterObject.A,
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2450: Enum 'AfterObject' used before its declaration.
|
||||
!!! related TS2728 blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts:15:12: 'AfterObject' is declared here.
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
A = 2,
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
//// [tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts] ////
|
||||
|
||||
//// [blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts]
|
||||
function foo1() {
|
||||
return E.A
|
||||
enum E { A }
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
return E.A
|
||||
const enum E { A }
|
||||
}
|
||||
|
||||
const config = {
|
||||
a: AfterObject.A,
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
A = 2,
|
||||
}
|
||||
|
||||
|
||||
//// [blockScopedEnumVariablesUseBeforeDef_isolatedModules.js]
|
||||
function foo1() {
|
||||
return E.A;
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["A"] = 0] = "A";
|
||||
})(E || (E = {}));
|
||||
}
|
||||
function foo2() {
|
||||
return E.A;
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["A"] = 0] = "A";
|
||||
})(E || (E = {}));
|
||||
}
|
||||
var config = {
|
||||
a: AfterObject.A,
|
||||
};
|
||||
var AfterObject;
|
||||
(function (AfterObject) {
|
||||
AfterObject[AfterObject["A"] = 2] = "A";
|
||||
})(AfterObject || (AfterObject = {}));
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
//// [tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts] ////
|
||||
|
||||
=== blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts ===
|
||||
function foo1() {
|
||||
>foo1 : Symbol(foo1, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 0, 0))
|
||||
|
||||
return E.A
|
||||
>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 2, 12))
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 1, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 2, 12))
|
||||
|
||||
enum E { A }
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 1, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 2, 12))
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
>foo2 : Symbol(foo2, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 3, 1))
|
||||
|
||||
return E.A
|
||||
>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 7, 18))
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 6, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 7, 18))
|
||||
|
||||
const enum E { A }
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 6, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 7, 18))
|
||||
}
|
||||
|
||||
const config = {
|
||||
>config : Symbol(config, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 10, 5))
|
||||
|
||||
a: AfterObject.A,
|
||||
>a : Symbol(a, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 10, 16))
|
||||
>AfterObject.A : Symbol(AfterObject.A, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 14, 24))
|
||||
>AfterObject : Symbol(AfterObject, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 12, 2))
|
||||
>A : Symbol(AfterObject.A, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 14, 24))
|
||||
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
>AfterObject : Symbol(AfterObject, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 12, 2))
|
||||
|
||||
A = 2,
|
||||
>A : Symbol(AfterObject.A, Decl(blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts, 14, 24))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
//// [tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts] ////
|
||||
|
||||
=== blockScopedEnumVariablesUseBeforeDef_isolatedModules.ts ===
|
||||
function foo1() {
|
||||
>foo1 : () => E
|
||||
|
||||
return E.A
|
||||
>E.A : E
|
||||
>E : typeof E
|
||||
>A : E
|
||||
|
||||
enum E { A }
|
||||
>E : E
|
||||
>A : E.A
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
>foo2 : () => E
|
||||
|
||||
return E.A
|
||||
>E.A : E
|
||||
>E : typeof E
|
||||
>A : E
|
||||
|
||||
const enum E { A }
|
||||
>E : E
|
||||
>A : E.A
|
||||
}
|
||||
|
||||
const config = {
|
||||
>config : { a: AfterObject; }
|
||||
>{ a: AfterObject.A,} : { a: AfterObject; }
|
||||
|
||||
a: AfterObject.A,
|
||||
>a : AfterObject
|
||||
>AfterObject.A : AfterObject
|
||||
>AfterObject : typeof AfterObject
|
||||
>A : AfterObject
|
||||
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
>AfterObject : AfterObject
|
||||
|
||||
A = 2,
|
||||
>A : AfterObject.A
|
||||
>2 : 2
|
||||
}
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts(2,12): error TS2450: Enum 'E' used before its declaration.
|
||||
blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts(7,12): error TS2450: Enum 'E' used before its declaration.
|
||||
blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts(12,8): error TS2450: Enum 'AfterObject' used before its declaration.
|
||||
|
||||
|
||||
==== blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts (3 errors) ====
|
||||
function foo1() {
|
||||
return E.A
|
||||
~
|
||||
!!! error TS2450: Enum 'E' used before its declaration.
|
||||
!!! related TS2728 blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts:3:10: 'E' is declared here.
|
||||
enum E { A }
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
return E.A
|
||||
~
|
||||
!!! error TS2450: Enum 'E' used before its declaration.
|
||||
!!! related TS2728 blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts:8:16: 'E' is declared here.
|
||||
const enum E { A }
|
||||
}
|
||||
|
||||
const config = {
|
||||
a: AfterObject.A,
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2450: Enum 'AfterObject' used before its declaration.
|
||||
!!! related TS2728 blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts:15:12: 'AfterObject' is declared here.
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
A = 2,
|
||||
}
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
//// [tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts] ////
|
||||
|
||||
//// [blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts]
|
||||
function foo1() {
|
||||
return E.A
|
||||
enum E { A }
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
return E.A
|
||||
const enum E { A }
|
||||
}
|
||||
|
||||
const config = {
|
||||
a: AfterObject.A,
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
A = 2,
|
||||
}
|
||||
|
||||
|
||||
//// [blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.js]
|
||||
function foo1() {
|
||||
return E.A;
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["A"] = 0] = "A";
|
||||
})(E || (E = {}));
|
||||
}
|
||||
function foo2() {
|
||||
return E.A;
|
||||
var E;
|
||||
(function (E) {
|
||||
E[E["A"] = 0] = "A";
|
||||
})(E || (E = {}));
|
||||
}
|
||||
var config = {
|
||||
a: AfterObject.A,
|
||||
};
|
||||
var AfterObject;
|
||||
(function (AfterObject) {
|
||||
AfterObject[AfterObject["A"] = 2] = "A";
|
||||
})(AfterObject || (AfterObject = {}));
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
//// [tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts] ////
|
||||
|
||||
=== blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts ===
|
||||
function foo1() {
|
||||
>foo1 : Symbol(foo1, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 0, 0))
|
||||
|
||||
return E.A
|
||||
>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 2, 12))
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 1, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 2, 12))
|
||||
|
||||
enum E { A }
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 1, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 2, 12))
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
>foo2 : Symbol(foo2, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 3, 1))
|
||||
|
||||
return E.A
|
||||
>E.A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 7, 18))
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 6, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 7, 18))
|
||||
|
||||
const enum E { A }
|
||||
>E : Symbol(E, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 6, 14))
|
||||
>A : Symbol(E.A, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 7, 18))
|
||||
}
|
||||
|
||||
const config = {
|
||||
>config : Symbol(config, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 10, 5))
|
||||
|
||||
a: AfterObject.A,
|
||||
>a : Symbol(a, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 10, 16))
|
||||
>AfterObject.A : Symbol(AfterObject.A, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 14, 24))
|
||||
>AfterObject : Symbol(AfterObject, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 12, 2))
|
||||
>A : Symbol(AfterObject.A, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 14, 24))
|
||||
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
>AfterObject : Symbol(AfterObject, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 12, 2))
|
||||
|
||||
A = 2,
|
||||
>A : Symbol(AfterObject.A, Decl(blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts, 14, 24))
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
//// [tests/cases/compiler/blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts] ////
|
||||
|
||||
=== blockScopedEnumVariablesUseBeforeDef_verbatimModuleSyntax.ts ===
|
||||
function foo1() {
|
||||
>foo1 : () => E
|
||||
|
||||
return E.A
|
||||
>E.A : E
|
||||
>E : typeof E
|
||||
>A : E
|
||||
|
||||
enum E { A }
|
||||
>E : E
|
||||
>A : E.A
|
||||
}
|
||||
|
||||
function foo2() {
|
||||
>foo2 : () => E
|
||||
|
||||
return E.A
|
||||
>E.A : E
|
||||
>E : typeof E
|
||||
>A : E
|
||||
|
||||
const enum E { A }
|
||||
>E : E
|
||||
>A : E.A
|
||||
}
|
||||
|
||||
const config = {
|
||||
>config : { a: AfterObject; }
|
||||
>{ a: AfterObject.A,} : { a: AfterObject; }
|
||||
|
||||
a: AfterObject.A,
|
||||
>a : AfterObject
|
||||
>AfterObject.A : AfterObject
|
||||
>AfterObject : typeof AfterObject
|
||||
>A : AfterObject
|
||||
|
||||
};
|
||||
|
||||
const enum AfterObject {
|
||||
>AfterObject : AfterObject
|
||||
|
||||
A = 2,
|
||||
>A : AfterObject.A
|
||||
>2 : 2
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
error TS5095: Option 'bundler' can only be used when 'module' is set to 'preserve' or to 'es2015' or later.
|
||||
error TS5109: Option 'moduleResolution' must be set to 'NodeNext' (or left unspecified) when option 'module' is set to 'NodeNext'.
|
||||
|
||||
|
||||
!!! error TS5095: Option 'bundler' can only be used when 'module' is set to 'preserve' or to 'es2015' or later.
|
||||
!!! error TS5109: Option 'moduleResolution' must be set to 'NodeNext' (or left unspecified) when option 'module' is set to 'NodeNext'.
|
||||
==== /app/test.ts (0 errors) ====
|
||||
import { test } from '../lib';
|
||||
|
||||
==== /lib/package.json (0 errors) ====
|
||||
{
|
||||
"main": "./cjs/index.js"
|
||||
}
|
||||
|
||||
==== /lib/cjs/index.js (0 errors) ====
|
||||
export function test() {}
|
||||
|
||||
==== /lib/cjs/index.d.ts (0 errors) ====
|
||||
export function test(): void;
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
[
|
||||
"======== Resolving module '../lib' from '/app/test.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Bundler'.",
|
||||
"Resolving in CJS mode with conditions 'import', 'types'.",
|
||||
"Loading module as file / folder, candidate module location '/lib', target file types: TypeScript, JavaScript, Declaration, JSON.",
|
||||
"File '/lib.ts' does not exist.",
|
||||
"File '/lib.tsx' does not exist.",
|
||||
"File '/lib.d.ts' does not exist.",
|
||||
"File '/lib.js' does not exist.",
|
||||
"File '/lib.jsx' does not exist.",
|
||||
"Found 'package.json' at '/lib/package.json'.",
|
||||
"'package.json' does not have a 'typesVersions' field.",
|
||||
"'package.json' does not have a 'typings' field.",
|
||||
"'package.json' does not have a 'types' field.",
|
||||
"'package.json' has 'main' field './cjs/index.js' that references '/lib/cjs/index.js'.",
|
||||
"File name '/lib/cjs/index.js' has a '.js' extension - stripping it.",
|
||||
"File '/lib/cjs/index.ts' does not exist.",
|
||||
"File '/lib/cjs/index.tsx' does not exist.",
|
||||
"File '/lib/cjs/index.d.ts' exists - use it as a name resolution result.",
|
||||
"======== Module name '../lib' was successfully resolved to '/lib/cjs/index.d.ts'. ========",
|
||||
"======== Resolving module '@typescript/lib-es5' from '/.src/__lib_node_modules_lookup_lib.es5.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-es5' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-es5'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-es5'",
|
||||
"Loading module '@typescript/lib-es5' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-es5' was not resolved. ========",
|
||||
"======== Resolving module '@typescript/lib-decorators' from '/.src/__lib_node_modules_lookup_lib.decorators.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-decorators' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-decorators'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-decorators'",
|
||||
"Loading module '@typescript/lib-decorators' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-decorators' was not resolved. ========",
|
||||
"======== Resolving module '@typescript/lib-decorators/legacy' from '/.src/__lib_node_modules_lookup_lib.decorators.legacy.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-decorators/legacy' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-decorators/legacy'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-decorators/legacy'",
|
||||
"Loading module '@typescript/lib-decorators/legacy' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-decorators/legacy' was not resolved. ========",
|
||||
"======== Resolving module '@typescript/lib-dom' from '/.src/__lib_node_modules_lookup_lib.dom.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-dom' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-dom'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-dom'",
|
||||
"Loading module '@typescript/lib-dom' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-dom' was not resolved. ========",
|
||||
"======== Resolving module '@typescript/lib-webworker/importscripts' from '/.src/__lib_node_modules_lookup_lib.webworker.importscripts.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-webworker/importscripts' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-webworker/importscripts'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-webworker/importscripts'",
|
||||
"Loading module '@typescript/lib-webworker/importscripts' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-webworker/importscripts' was not resolved. ========",
|
||||
"======== Resolving module '@typescript/lib-scripthost' from '/.src/__lib_node_modules_lookup_lib.scripthost.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-scripthost' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-scripthost'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-scripthost'",
|
||||
"Loading module '@typescript/lib-scripthost' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-scripthost' was not resolved. ========"
|
||||
]
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
[
|
||||
"File '/app/package.json' does not exist.",
|
||||
"File '/package.json' does not exist.",
|
||||
"======== Resolving module '../lib' from '/app/test.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'NodeNext'.",
|
||||
"Resolving in CJS mode with conditions 'require', 'types', 'node'.",
|
||||
"Loading module as file / folder, candidate module location '/lib', target file types: TypeScript, JavaScript, Declaration.",
|
||||
"File '/lib.ts' does not exist.",
|
||||
"File '/lib.tsx' does not exist.",
|
||||
"File '/lib.d.ts' does not exist.",
|
||||
"File '/lib.js' does not exist.",
|
||||
"File '/lib.jsx' does not exist.",
|
||||
"Found 'package.json' at '/lib/package.json'.",
|
||||
"'package.json' does not have a 'typesVersions' field.",
|
||||
"'package.json' does not have a 'typings' field.",
|
||||
"'package.json' does not have a 'types' field.",
|
||||
"'package.json' has 'main' field './cjs/index.js' that references '/lib/cjs/index.js'.",
|
||||
"File name '/lib/cjs/index.js' has a '.js' extension - stripping it.",
|
||||
"File '/lib/cjs/index.ts' does not exist.",
|
||||
"File '/lib/cjs/index.tsx' does not exist.",
|
||||
"File '/lib/cjs/index.d.ts' exists - use it as a name resolution result.",
|
||||
"======== Module name '../lib' was successfully resolved to '/lib/cjs/index.d.ts'. ========",
|
||||
"File '/lib/cjs/package.json' does not exist.",
|
||||
"File '/lib/package.json' exists according to earlier cached lookups.",
|
||||
"File '/.ts/package.json' does not exist.",
|
||||
"File '/package.json' does not exist according to earlier cached lookups.",
|
||||
"======== Resolving module '@typescript/lib-es5' from '/.src/__lib_node_modules_lookup_lib.es5.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-es5' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-es5'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-es5'",
|
||||
"Loading module '@typescript/lib-es5' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-es5' was not resolved. ========",
|
||||
"File '/.ts/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/package.json' does not exist according to earlier cached lookups.",
|
||||
"======== Resolving module '@typescript/lib-decorators' from '/.src/__lib_node_modules_lookup_lib.decorators.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-decorators' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-decorators'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-decorators'",
|
||||
"Loading module '@typescript/lib-decorators' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-decorators' was not resolved. ========",
|
||||
"File '/.ts/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/package.json' does not exist according to earlier cached lookups.",
|
||||
"======== Resolving module '@typescript/lib-decorators/legacy' from '/.src/__lib_node_modules_lookup_lib.decorators.legacy.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-decorators/legacy' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-decorators/legacy'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-decorators/legacy'",
|
||||
"Loading module '@typescript/lib-decorators/legacy' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-decorators/legacy' was not resolved. ========",
|
||||
"File '/.ts/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/package.json' does not exist according to earlier cached lookups.",
|
||||
"======== Resolving module '@typescript/lib-dom' from '/.src/__lib_node_modules_lookup_lib.dom.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-dom' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-dom'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-dom'",
|
||||
"Loading module '@typescript/lib-dom' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-dom' was not resolved. ========",
|
||||
"File '/.ts/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/package.json' does not exist according to earlier cached lookups.",
|
||||
"======== Resolving module '@typescript/lib-webworker/importscripts' from '/.src/__lib_node_modules_lookup_lib.webworker.importscripts.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-webworker/importscripts' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-webworker/importscripts'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-webworker/importscripts'",
|
||||
"Loading module '@typescript/lib-webworker/importscripts' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-webworker/importscripts' was not resolved. ========",
|
||||
"File '/.ts/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/package.json' does not exist according to earlier cached lookups.",
|
||||
"======== Resolving module '@typescript/lib-scripthost' from '/.src/__lib_node_modules_lookup_lib.scripthost.d.ts__.ts'. ========",
|
||||
"Explicitly specified module resolution kind: 'Node10'.",
|
||||
"Loading module '@typescript/lib-scripthost' from 'node_modules' folder, target file types: TypeScript, Declaration.",
|
||||
"Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-scripthost'",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Scoped package detected, looking in 'typescript__lib-scripthost'",
|
||||
"Loading module '@typescript/lib-scripthost' from 'node_modules' folder, target file types: JavaScript.",
|
||||
"Searching all ancestor node_modules directories for fallback extensions: JavaScript.",
|
||||
"Directory '/.src/node_modules' does not exist, skipping all lookups in it.",
|
||||
"Directory '/node_modules' does not exist, skipping all lookups in it.",
|
||||
"======== Module name '@typescript/lib-scripthost' was not resolved. ========",
|
||||
"File '/.ts/package.json' does not exist according to earlier cached lookups.",
|
||||
"File '/package.json' does not exist according to earlier cached lookups."
|
||||
]
|
||||
@@ -45,7 +45,6 @@
|
||||
"'package.json' does not have a 'typings' field.",
|
||||
"'package.json' does not have a 'types' field.",
|
||||
"'package.json' has 'main' field '../foo' that references '/foo'.",
|
||||
"File '/foo' does not exist.",
|
||||
"Loading module as file / folder, candidate module location '/foo', target file types: TypeScript, JavaScript, Declaration, JSON.",
|
||||
"File '/foo.ts' does not exist.",
|
||||
"File '/foo.tsx' does not exist.",
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
"'package.json' does not have a 'typings' field.",
|
||||
"'package.json' does not have a 'types' field.",
|
||||
"'package.json' has 'main' field '../foo' that references '/foo'.",
|
||||
"File '/foo' does not exist.",
|
||||
"Loading module as file / folder, candidate module location '/foo', target file types: TypeScript, JavaScript, Declaration, JSON.",
|
||||
"File '/foo.ts' does not exist.",
|
||||
"File '/foo.tsx' does not exist.",
|
||||
|
||||
@@ -134,6 +134,7 @@
|
||||
// | unknown
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -3335,6 +3336,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
|
||||
@@ -186,6 +186,7 @@
|
||||
// | unknown
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -3926,6 +3927,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -372,6 +373,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -538,6 +540,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -751,6 +754,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -905,6 +909,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -1067,6 +1072,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -1215,6 +1221,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -1376,6 +1383,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -1542,6 +1550,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -1704,6 +1713,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -1866,6 +1876,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -2015,6 +2026,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -2166,6 +2178,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -2315,6 +2328,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -2466,6 +2480,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -2615,6 +2630,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -2766,6 +2782,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -2949,6 +2966,7 @@
|
||||
// | unknown
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -3138,6 +3156,7 @@
|
||||
// | unknown
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -3323,6 +3342,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -7930,6 +7950,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -15015,6 +15047,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -19853,6 +19897,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -26938,6 +26994,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -31027,6 +31095,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -36272,6 +36352,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -40315,6 +40407,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -45514,6 +45618,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -50759,6 +50875,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -56004,6 +56132,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -61249,6 +61389,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -65333,6 +65485,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -69417,6 +69581,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -73501,6 +73677,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -77585,6 +77773,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -81669,6 +81869,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -85753,6 +85965,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -90322,6 +90546,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -95692,6 +95928,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -100174,6 +100422,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
|
||||
@@ -241,6 +241,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -407,6 +408,7 @@
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | (message?: string) => URIError (+1 overload)
|
||||
// | interface URIError
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -577,6 +579,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -748,6 +751,7 @@
|
||||
// | unknown
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -951,6 +955,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -1117,6 +1122,7 @@
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | (message?: string) => URIError (+1 overload)
|
||||
// | interface URIError
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -1311,6 +1317,7 @@
|
||||
// | unknown
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -6752,6 +6759,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -13220,6 +13239,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -18868,6 +18899,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -24581,6 +24624,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -30348,6 +30403,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -36816,6 +36883,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -42529,6 +42608,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | (message?: string) => URIError (+1 overload)
|
||||
// | interface URIError
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -267,6 +268,7 @@
|
||||
// | var undefined
|
||||
// | interface URIError
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -408,6 +410,7 @@
|
||||
// | var URIError: URIErrorConstructor
|
||||
// | (message?: string) => URIError (+1 overload)
|
||||
// | interface URIError
|
||||
// | using
|
||||
// | var
|
||||
// | void
|
||||
// | while
|
||||
@@ -4516,6 +4519,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -8017,6 +8032,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
@@ -12352,6 +12379,18 @@
|
||||
],
|
||||
"documentation": []
|
||||
},
|
||||
{
|
||||
"name": "using",
|
||||
"kind": "keyword",
|
||||
"kindModifiers": "",
|
||||
"sortText": "15",
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "using",
|
||||
"kind": "keyword"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "var",
|
||||
"kind": "keyword",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user