mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'main' into enforceReadonly
# Conflicts: # src/compiler/diagnosticMessages.json # tests/baselines/reference/es2018IntlAPIs.types # tests/baselines/reference/es2020IntlAPIs.types # tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.types # tests/baselines/reference/instantiationExpressions.types # tests/baselines/reference/localesObjectArgument.types # tests/baselines/reference/mappedTypeConstraints2.types # tests/baselines/reference/mappedTypeRecursiveInference.types # tests/baselines/reference/unionTypeInference.types # tests/baselines/reference/useObjectValuesAndEntries1.types # tests/baselines/reference/useObjectValuesAndEntries4.types
This commit is contained in:
+13
-5
@@ -17,7 +17,6 @@
|
||||
],
|
||||
"plugins": [
|
||||
"@typescript-eslint",
|
||||
"no-null",
|
||||
"eslint-plugin-local"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
@@ -60,6 +59,18 @@
|
||||
"prefer-object-spread": "error",
|
||||
"unicode-bom": ["error", "never"],
|
||||
|
||||
"no-restricted-syntax": [
|
||||
"error",
|
||||
{
|
||||
"selector": "Literal[raw=null]",
|
||||
"message": "Avoid using null; use undefined instead."
|
||||
},
|
||||
{
|
||||
"selector": "TSNullKeyword",
|
||||
"message": "Avoid using null; use undefined instead."
|
||||
}
|
||||
],
|
||||
|
||||
// Enabled in eslint:recommended, but not applicable here
|
||||
"no-extra-boolean-cast": "off",
|
||||
"no-case-declarations": "off",
|
||||
@@ -132,10 +143,7 @@
|
||||
"local/no-in-operator": "error",
|
||||
"local/debug-assert": "error",
|
||||
"local/no-keywords": "error",
|
||||
"local/jsdoc-format": "error",
|
||||
|
||||
// eslint-plugin-no-null
|
||||
"no-null/no-null": "error"
|
||||
"local/jsdoc-format": "error"
|
||||
},
|
||||
"overrides": [
|
||||
// By default, the ESLint CLI only looks at .js files. But, it will also look at
|
||||
|
||||
@@ -3,7 +3,10 @@ description: 'Create a report to help us improve TypeScript'
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Please fill in each section completely. Thank you!
|
||||
value: |
|
||||
🔍 Please [search thoroughly in GitHub](https://github.com/Microsoft/TypeScript/search?type=Issues) or by the query `site:github.com/microsoft/TypeScript <your keywords>` in your favorite search engine before reporting a new bug as most bugs are very likely to find precedents.
|
||||
|
||||
Please fill in each section completely. Thank you!
|
||||
- type: textarea
|
||||
id: search_terms
|
||||
attributes:
|
||||
|
||||
@@ -3,17 +3,22 @@ description: 'Suggest an idea'
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: 'Please fill in each section completely. Thank you!'
|
||||
value: |
|
||||
💡 Did you know? TypeScript has over 2,000 open suggestions!
|
||||
|
||||
🔎 Please [search thoroughly in GitHub](https://github.com/Microsoft/TypeScript/search?type=Issues) or by the query `site:github.com/microsoft/TypeScript <your keywords>` in your favorite search engine before logging new feature requests as most common ideas already have a proposal in progress.
|
||||
|
||||
The "Common Feature Requests" section of the FAQ lists many popular requests: https://github.com/Microsoft/TypeScript/wiki/FAQ#common-feature-requests
|
||||
|
||||
Please fill in each section completely. Thank you!
|
||||
- type: textarea
|
||||
id: search_terms
|
||||
attributes:
|
||||
label: '🔍 Search Terms'
|
||||
description: |
|
||||
💡 Did you know? TypeScript has over 2,000 open suggestions!
|
||||
What search terms did you use when trying to find an existing suggestion?
|
||||
|
||||
🔎 Please search thoroughly before logging new feature requests as most common ideas already have a proposal in progress.
|
||||
|
||||
The "Common Feature Requests" section of the FAQ lists many popular requests: https://github.com/Microsoft/TypeScript/wiki/FAQ#common-feature-requests
|
||||
List them here so people in the future can find this one more easily.
|
||||
placeholder: |
|
||||
List of keywords you searched for before creating this issue. Write them down here so that others can find this suggestion more easily and help provide feedback.
|
||||
|
||||
|
||||
@@ -17,10 +17,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
|
||||
- name: Configure Git, Run Tests, Update Baselines, Apply Fixes
|
||||
run: |
|
||||
|
||||
+13
-12
@@ -48,7 +48,7 @@ jobs:
|
||||
name: Test Node ${{ matrix.node-version }} on ${{ matrix.os }}${{ (!matrix.bundle && ' with --no-bundle') || '' }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- name: Use node version ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
@@ -72,7 +72,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
@@ -86,14 +86,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
check-latest: true
|
||||
- run: npm ci
|
||||
|
||||
- uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 # v4.0.1
|
||||
- uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
|
||||
with:
|
||||
path: ~/.cache/dprint
|
||||
key: ${{ runner.os }}-dprint-${{ hashFiles('package-lock.json', '.dprint.jsonc') }}
|
||||
@@ -107,7 +107,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
@@ -124,7 +124,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
@@ -138,7 +138,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
@@ -154,6 +154,7 @@ jobs:
|
||||
|
||||
- run: npx hereby lkg
|
||||
- run: |
|
||||
node ./scripts/addPackageJsonGitHead.mjs package.json
|
||||
npm pack
|
||||
mv typescript*.tgz typescript.tgz
|
||||
echo "package=$PWD/typescript.tgz" >> "$GITHUB_OUTPUT"
|
||||
@@ -179,11 +180,11 @@ jobs:
|
||||
if: github.event_name == 'pull_request'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
path: pr
|
||||
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
path: base
|
||||
ref: ${{ github.base_ref }}
|
||||
@@ -221,7 +222,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
@@ -238,7 +239,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
@@ -258,7 +259,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: '*'
|
||||
|
||||
@@ -42,11 +42,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6
|
||||
uses: github/codeql-action/init@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
|
||||
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@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6
|
||||
uses: github/codeql-action/autobuild@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
|
||||
|
||||
# ℹ️ 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@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6
|
||||
uses: github/codeql-action/analyze@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
|
||||
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
if: github.repository == 'microsoft/TypeScript'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
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.
|
||||
|
||||
@@ -20,8 +20,10 @@ jobs:
|
||||
if: github.repository == 'microsoft/TypeScript'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- run: |
|
||||
npm --version
|
||||
# corepack enable npm
|
||||
@@ -40,9 +42,10 @@ jobs:
|
||||
if: github.repository == 'microsoft/TypeScript'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
# Use NODE_AUTH_TOKEN environment variable to authenticate to this registry.
|
||||
registry-url: https://registry.npmjs.org/
|
||||
- run: |
|
||||
@@ -56,6 +59,7 @@ jobs:
|
||||
npm ci
|
||||
npx hereby configure-insiders
|
||||
npx hereby LKG
|
||||
node ./scripts/addPackageJsonGitHead.mjs package.json
|
||||
npm publish --tag insiders
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
||||
|
||||
@@ -27,11 +27,13 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
ref: ${{ inputs.branch_name }}
|
||||
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- run: |
|
||||
npm --version
|
||||
# corepack enable npm
|
||||
|
||||
@@ -50,12 +50,14 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
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@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- run: |
|
||||
npm --version
|
||||
# corepack enable npm
|
||||
|
||||
@@ -21,8 +21,10 @@ jobs:
|
||||
if: github.repository == 'microsoft/TypeScript'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- run: |
|
||||
npm --version
|
||||
# corepack enable npm
|
||||
@@ -40,9 +42,10 @@ jobs:
|
||||
if: github.repository == 'microsoft/TypeScript'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
# Use NODE_AUTH_TOKEN environment variable to authenticate to this registry.
|
||||
registry-url: https://registry.npmjs.org/
|
||||
- run: |
|
||||
@@ -56,6 +59,7 @@ jobs:
|
||||
npm ci
|
||||
npx hereby configure-nightly
|
||||
npx hereby LKG
|
||||
node ./scripts/addPackageJsonGitHead.mjs package.json
|
||||
npm publish --tag next
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
||||
|
||||
@@ -19,8 +19,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- run: |
|
||||
npm --version
|
||||
# corepack enable npm
|
||||
@@ -38,6 +40,7 @@ jobs:
|
||||
run: |
|
||||
npx hereby LKG
|
||||
npx hereby clean
|
||||
node ./scripts/addPackageJsonGitHead.mjs package.json
|
||||
npm pack ./
|
||||
mv typescript-*.tgz typescript.tgz
|
||||
- name: Upload built tarfile
|
||||
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: 'Checkout code'
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -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@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6
|
||||
uses: github/codeql-action/upload-sarif@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
@@ -49,11 +49,13 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
ref: ${{ inputs.branch_name }}
|
||||
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- run: |
|
||||
npm --version
|
||||
# corepack enable npm
|
||||
|
||||
@@ -43,7 +43,9 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
ref: ${{ inputs.branch_name }}
|
||||
filter: blob:none # https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
- name: Get repo name
|
||||
run: R=${GITHUB_REPOSITORY%?wiki}; echo "BASENAME=${R##*/}" >> $GITHUB_ENV
|
||||
- name: Checkout ${{ env.BASENAME }}-wiki
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
repository: '${{ GITHUB.repository_owner }}/${{ env.BASENAME }}-wiki'
|
||||
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
|
||||
@@ -49,13 +49,15 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- if: ${{ github.event.inputs.bisect }}
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
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.
|
||||
- if: ${{ !github.event.inputs.bisect }}
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
with:
|
||||
node-version: 'lts/*'
|
||||
- uses: microsoft/TypeScript-Twoslash-Repro-Action@8680b5b290d48a7badbc7ba65971d526c61b86b8 # master
|
||||
with:
|
||||
github-token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
if: github.repository == 'microsoft/TypeScript'
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
|
||||
with:
|
||||
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
|
||||
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ Issues that ask questions answered in the FAQ will be closed without elaboration
|
||||
|
||||
## 2. Search for Duplicates
|
||||
|
||||
[Search the existing issues](https://github.com/Microsoft/TypeScript/search?type=Issues) before logging a new one.
|
||||
[Search the existing issues in GitHub](https://github.com/Microsoft/TypeScript/search?type=Issues) or by the query `site:github.com/microsoft/TypeScript <your keywords>` in your favorite search engine before logging a new one. Search engines generally list more relevant and accurate results at the top than the GitHub searching feature.
|
||||
|
||||
Some search tips:
|
||||
* *Don't* restrict your search to only open issues. An issue with a title similar to yours may have been closed as a duplicate of one with a less-findable title.
|
||||
|
||||
@@ -77,6 +77,7 @@ extends:
|
||||
- script: |
|
||||
npx hereby LKG
|
||||
npx hereby clean
|
||||
node ./scripts/addPackageJsonGitHead.mjs package.json
|
||||
npm pack
|
||||
displayName: 'LKG, clean, pack'
|
||||
|
||||
|
||||
Generated
+168
-188
@@ -37,7 +37,6 @@
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-formatter-autolinkable-stylish": "^1.3.0",
|
||||
"eslint-plugin-local": "^4.2.1",
|
||||
"eslint-plugin-no-null": "^1.0.2",
|
||||
"fast-xml-parser": "^4.3.6",
|
||||
"glob": "^10.3.10",
|
||||
"hereby": "^1.8.9",
|
||||
@@ -858,9 +857,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/openapi-types": {
|
||||
"version": "21.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-21.2.0.tgz",
|
||||
"integrity": "sha512-xx+Xd6I7rYvul/hgUDqv6TeGX0IOGnhSg9IOeYgd/uI7IAqUy6DE2B6Ipv2M4mWoxaMcWjIzgTIcv8pMO3F3vw==",
|
||||
"version": "22.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.1.0.tgz",
|
||||
"integrity": "sha512-pGUdSP+eEPfZiQHNkZI0U01HLipxncisdJQB4G//OAmfeO8sqTQ9KRa0KF03TUPCziNsoXUrTg4B2Q1EX++T0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@octokit/plugin-paginate-rest": {
|
||||
@@ -936,14 +935,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/request": {
|
||||
"version": "8.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.3.1.tgz",
|
||||
"integrity": "sha512-fin4cl5eHN5Ybmb/gtn7YZ+ycyUlcyqqkg5lfxeSChqj7sUt6TNaJPehREi+0PABKLREYL8pfaUhH3TicEWNoA==",
|
||||
"version": "8.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz",
|
||||
"integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@octokit/endpoint": "^9.0.1",
|
||||
"@octokit/request-error": "^5.1.0",
|
||||
"@octokit/types": "^13.0.0",
|
||||
"@octokit/types": "^13.1.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -980,12 +979,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@octokit/types": {
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.1.0.tgz",
|
||||
"integrity": "sha512-nBwAFOYqVUUJ2AZFK4ZzESQptaAVqdTDKk8gE0Xr0o99WuPDSrhUC38x0F40xD9OUxXhOOuZKWNNVVLPSHQDvQ==",
|
||||
"version": "13.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.4.1.tgz",
|
||||
"integrity": "sha512-Y73oOAzRBAUzR/iRAbGULzpNkX8vaxKCqEtg6K74Ff3w9f5apFnWtE/2nade7dMWWW3bS5Kkd6DJS4HF04xreg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@octokit/openapi-types": "^21.0.0"
|
||||
"@octokit/openapi-types": "^22.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
@@ -1053,9 +1052,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.12.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.5.tgz",
|
||||
"integrity": "sha512-BD+BjQ9LS/D8ST9p5uqBxghlN+S42iuNxjsUGjeZobe/ciXzk2qb1B6IXc6AnRLS+yFJRpN2IPEHMzwspfDJNw==",
|
||||
"version": "20.12.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
|
||||
"integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~5.26.4"
|
||||
@@ -1083,22 +1082,22 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz",
|
||||
"integrity": "sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.0.tgz",
|
||||
"integrity": "sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.5.1",
|
||||
"@typescript-eslint/scope-manager": "7.5.0",
|
||||
"@typescript-eslint/type-utils": "7.5.0",
|
||||
"@typescript-eslint/utils": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0",
|
||||
"@eslint-community/regexpp": "^4.10.0",
|
||||
"@typescript-eslint/scope-manager": "7.7.0",
|
||||
"@typescript-eslint/type-utils": "7.7.0",
|
||||
"@typescript-eslint/utils": "7.7.0",
|
||||
"@typescript-eslint/visitor-keys": "7.7.0",
|
||||
"debug": "^4.3.4",
|
||||
"graphemer": "^1.4.0",
|
||||
"ignore": "^5.2.4",
|
||||
"ignore": "^5.3.1",
|
||||
"natural-compare": "^1.4.0",
|
||||
"semver": "^7.5.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
"semver": "^7.6.0",
|
||||
"ts-api-utils": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
@@ -1118,15 +1117,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.5.0.tgz",
|
||||
"integrity": "sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz",
|
||||
"integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "7.5.0",
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/typescript-estree": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0",
|
||||
"@typescript-eslint/scope-manager": "7.7.0",
|
||||
"@typescript-eslint/types": "7.7.0",
|
||||
"@typescript-eslint/typescript-estree": "7.7.0",
|
||||
"@typescript-eslint/visitor-keys": "7.7.0",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1146,13 +1145,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz",
|
||||
"integrity": "sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz",
|
||||
"integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0"
|
||||
"@typescript-eslint/types": "7.7.0",
|
||||
"@typescript-eslint/visitor-keys": "7.7.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
@@ -1163,15 +1162,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz",
|
||||
"integrity": "sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz",
|
||||
"integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/typescript-estree": "7.5.0",
|
||||
"@typescript-eslint/utils": "7.5.0",
|
||||
"@typescript-eslint/typescript-estree": "7.7.0",
|
||||
"@typescript-eslint/utils": "7.7.0",
|
||||
"debug": "^4.3.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
"ts-api-utils": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
@@ -1190,9 +1189,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.5.0.tgz",
|
||||
"integrity": "sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz",
|
||||
"integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
@@ -1203,19 +1202,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz",
|
||||
"integrity": "sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz",
|
||||
"integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0",
|
||||
"@typescript-eslint/types": "7.7.0",
|
||||
"@typescript-eslint/visitor-keys": "7.7.0",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
"minimatch": "9.0.3",
|
||||
"semver": "^7.5.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
"minimatch": "^9.0.4",
|
||||
"semver": "^7.6.0",
|
||||
"ts-api-utils": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
@@ -1231,18 +1230,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz",
|
||||
"integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz",
|
||||
"integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"@types/json-schema": "^7.0.12",
|
||||
"@types/semver": "^7.5.0",
|
||||
"@typescript-eslint/scope-manager": "7.5.0",
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/typescript-estree": "7.5.0",
|
||||
"semver": "^7.5.4"
|
||||
"@types/json-schema": "^7.0.15",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@typescript-eslint/scope-manager": "7.7.0",
|
||||
"@typescript-eslint/types": "7.7.0",
|
||||
"@typescript-eslint/typescript-estree": "7.7.0",
|
||||
"semver": "^7.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
@@ -1256,13 +1255,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz",
|
||||
"integrity": "sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz",
|
||||
"integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"eslint-visitor-keys": "^3.4.1"
|
||||
"@typescript-eslint/types": "7.7.0",
|
||||
"eslint-visitor-keys": "^3.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || >=20.0.0"
|
||||
@@ -2117,18 +2116,6 @@
|
||||
"eslint": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-no-null": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-no-null/-/eslint-plugin-no-null-1.0.2.tgz",
|
||||
"integrity": "sha512-uRDiz88zCO/2rzGfgG15DBjNsgwWtWiSo4Ezy7zzajUgpnFIqd1TjepKeRmJZHEfBGu58o2a8S0D7vglvvhkVA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=5.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "7.2.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
|
||||
@@ -3056,9 +3043,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"version": "9.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
|
||||
"integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
@@ -3513,12 +3500,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.43.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.0.tgz",
|
||||
"integrity": "sha512-SiOKHbVjTSf6wHuGCbqrEyzlm6qvXcv7mENP+OZon1I07brfZLGdfWV0l/efAzVx7TF3Z45ov1gPEkku9q25YQ==",
|
||||
"version": "1.43.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.1.tgz",
|
||||
"integrity": "sha512-V7SoH0ai2kNt1Md9E3Gwas5B9m8KR2GVvwZnAI6Pg0m3sh7UvgiYhRrhsziCmqMJNouPckiOhk8T+9bSAK0VIA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"playwright-core": "1.43.0"
|
||||
"playwright-core": "1.43.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
@@ -3531,9 +3518,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.43.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.0.tgz",
|
||||
"integrity": "sha512-iWFjyBUH97+pUFiyTqSLd8cDMMOS0r2ZYz2qEsPjH8/bX++sbIJT35MSwKnp1r/OQBAqC5XO99xFbJ9XClhf4w==",
|
||||
"version": "1.43.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.1.tgz",
|
||||
"integrity": "sha512-EI36Mto2Vrx6VF7rm708qSnesVQKbxEWvPrfA1IPY6HgczBplDx7ENtx+K2n4kJ41sLLkuGfmb0ZLSSXlDhqPg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
@@ -3605,9 +3592,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.12.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz",
|
||||
"integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==",
|
||||
"version": "6.12.1",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz",
|
||||
"integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.6"
|
||||
@@ -4210,9 +4197,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.4.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz",
|
||||
"integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==",
|
||||
"version": "5.4.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
@@ -4985,9 +4972,9 @@
|
||||
}
|
||||
},
|
||||
"@octokit/openapi-types": {
|
||||
"version": "21.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-21.2.0.tgz",
|
||||
"integrity": "sha512-xx+Xd6I7rYvul/hgUDqv6TeGX0IOGnhSg9IOeYgd/uI7IAqUy6DE2B6Ipv2M4mWoxaMcWjIzgTIcv8pMO3F3vw==",
|
||||
"version": "22.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.1.0.tgz",
|
||||
"integrity": "sha512-pGUdSP+eEPfZiQHNkZI0U01HLipxncisdJQB4G//OAmfeO8sqTQ9KRa0KF03TUPCziNsoXUrTg4B2Q1EX++T0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@octokit/plugin-paginate-rest": {
|
||||
@@ -5050,14 +5037,14 @@
|
||||
}
|
||||
},
|
||||
"@octokit/request": {
|
||||
"version": "8.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.3.1.tgz",
|
||||
"integrity": "sha512-fin4cl5eHN5Ybmb/gtn7YZ+ycyUlcyqqkg5lfxeSChqj7sUt6TNaJPehREi+0PABKLREYL8pfaUhH3TicEWNoA==",
|
||||
"version": "8.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.4.0.tgz",
|
||||
"integrity": "sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@octokit/endpoint": "^9.0.1",
|
||||
"@octokit/request-error": "^5.1.0",
|
||||
"@octokit/types": "^13.0.0",
|
||||
"@octokit/types": "^13.1.0",
|
||||
"universal-user-agent": "^6.0.0"
|
||||
}
|
||||
},
|
||||
@@ -5085,12 +5072,12 @@
|
||||
}
|
||||
},
|
||||
"@octokit/types": {
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.1.0.tgz",
|
||||
"integrity": "sha512-nBwAFOYqVUUJ2AZFK4ZzESQptaAVqdTDKk8gE0Xr0o99WuPDSrhUC38x0F40xD9OUxXhOOuZKWNNVVLPSHQDvQ==",
|
||||
"version": "13.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.4.1.tgz",
|
||||
"integrity": "sha512-Y73oOAzRBAUzR/iRAbGULzpNkX8vaxKCqEtg6K74Ff3w9f5apFnWtE/2nade7dMWWW3bS5Kkd6DJS4HF04xreg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@octokit/openapi-types": "^21.0.0"
|
||||
"@octokit/openapi-types": "^22.1.0"
|
||||
}
|
||||
},
|
||||
"@pkgjs/parseargs": {
|
||||
@@ -5152,9 +5139,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "20.12.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.5.tgz",
|
||||
"integrity": "sha512-BD+BjQ9LS/D8ST9p5uqBxghlN+S42iuNxjsUGjeZobe/ciXzk2qb1B6IXc6AnRLS+yFJRpN2IPEHMzwspfDJNw==",
|
||||
"version": "20.12.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
|
||||
"integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"undici-types": "~5.26.4"
|
||||
@@ -5182,104 +5169,104 @@
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/eslint-plugin": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz",
|
||||
"integrity": "sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.0.tgz",
|
||||
"integrity": "sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint-community/regexpp": "^4.5.1",
|
||||
"@typescript-eslint/scope-manager": "7.5.0",
|
||||
"@typescript-eslint/type-utils": "7.5.0",
|
||||
"@typescript-eslint/utils": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0",
|
||||
"@eslint-community/regexpp": "^4.10.0",
|
||||
"@typescript-eslint/scope-manager": "7.7.0",
|
||||
"@typescript-eslint/type-utils": "7.7.0",
|
||||
"@typescript-eslint/utils": "7.7.0",
|
||||
"@typescript-eslint/visitor-keys": "7.7.0",
|
||||
"debug": "^4.3.4",
|
||||
"graphemer": "^1.4.0",
|
||||
"ignore": "^5.2.4",
|
||||
"ignore": "^5.3.1",
|
||||
"natural-compare": "^1.4.0",
|
||||
"semver": "^7.5.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
"semver": "^7.6.0",
|
||||
"ts-api-utils": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/parser": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.5.0.tgz",
|
||||
"integrity": "sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz",
|
||||
"integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/scope-manager": "7.5.0",
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/typescript-estree": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0",
|
||||
"@typescript-eslint/scope-manager": "7.7.0",
|
||||
"@typescript-eslint/types": "7.7.0",
|
||||
"@typescript-eslint/typescript-estree": "7.7.0",
|
||||
"@typescript-eslint/visitor-keys": "7.7.0",
|
||||
"debug": "^4.3.4"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz",
|
||||
"integrity": "sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.0.tgz",
|
||||
"integrity": "sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0"
|
||||
"@typescript-eslint/types": "7.7.0",
|
||||
"@typescript-eslint/visitor-keys": "7.7.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/type-utils": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz",
|
||||
"integrity": "sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz",
|
||||
"integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/typescript-estree": "7.5.0",
|
||||
"@typescript-eslint/utils": "7.5.0",
|
||||
"@typescript-eslint/typescript-estree": "7.7.0",
|
||||
"@typescript-eslint/utils": "7.7.0",
|
||||
"debug": "^4.3.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
"ts-api-utils": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.5.0.tgz",
|
||||
"integrity": "sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz",
|
||||
"integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz",
|
||||
"integrity": "sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz",
|
||||
"integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/visitor-keys": "7.5.0",
|
||||
"@typescript-eslint/types": "7.7.0",
|
||||
"@typescript-eslint/visitor-keys": "7.7.0",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
"minimatch": "9.0.3",
|
||||
"semver": "^7.5.4",
|
||||
"ts-api-utils": "^1.0.1"
|
||||
"minimatch": "^9.0.4",
|
||||
"semver": "^7.6.0",
|
||||
"ts-api-utils": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/utils": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.5.0.tgz",
|
||||
"integrity": "sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz",
|
||||
"integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint-community/eslint-utils": "^4.4.0",
|
||||
"@types/json-schema": "^7.0.12",
|
||||
"@types/semver": "^7.5.0",
|
||||
"@typescript-eslint/scope-manager": "7.5.0",
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"@typescript-eslint/typescript-estree": "7.5.0",
|
||||
"semver": "^7.5.4"
|
||||
"@types/json-schema": "^7.0.15",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@typescript-eslint/scope-manager": "7.7.0",
|
||||
"@typescript-eslint/types": "7.7.0",
|
||||
"@typescript-eslint/typescript-estree": "7.7.0",
|
||||
"semver": "^7.6.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "7.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz",
|
||||
"integrity": "sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==",
|
||||
"version": "7.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz",
|
||||
"integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "7.5.0",
|
||||
"eslint-visitor-keys": "^3.4.1"
|
||||
"@typescript-eslint/types": "7.7.0",
|
||||
"eslint-visitor-keys": "^3.4.3"
|
||||
}
|
||||
},
|
||||
"@ungap/structured-clone": {
|
||||
@@ -5952,13 +5939,6 @@
|
||||
"chalk": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"eslint-plugin-no-null": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-no-null/-/eslint-plugin-no-null-1.0.2.tgz",
|
||||
"integrity": "sha512-uRDiz88zCO/2rzGfgG15DBjNsgwWtWiSo4Ezy7zzajUgpnFIqd1TjepKeRmJZHEfBGu58o2a8S0D7vglvvhkVA==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "7.2.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
|
||||
@@ -6588,9 +6568,9 @@
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"version": "9.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
|
||||
"integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
@@ -6907,13 +6887,13 @@
|
||||
"dev": true
|
||||
},
|
||||
"playwright": {
|
||||
"version": "1.43.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.0.tgz",
|
||||
"integrity": "sha512-SiOKHbVjTSf6wHuGCbqrEyzlm6qvXcv7mENP+OZon1I07brfZLGdfWV0l/efAzVx7TF3Z45ov1gPEkku9q25YQ==",
|
||||
"version": "1.43.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.1.tgz",
|
||||
"integrity": "sha512-V7SoH0ai2kNt1Md9E3Gwas5B9m8KR2GVvwZnAI6Pg0m3sh7UvgiYhRrhsziCmqMJNouPckiOhk8T+9bSAK0VIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fsevents": "2.3.2",
|
||||
"playwright-core": "1.43.0"
|
||||
"playwright-core": "1.43.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"fsevents": {
|
||||
@@ -6926,9 +6906,9 @@
|
||||
}
|
||||
},
|
||||
"playwright-core": {
|
||||
"version": "1.43.0",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.0.tgz",
|
||||
"integrity": "sha512-iWFjyBUH97+pUFiyTqSLd8cDMMOS0r2ZYz2qEsPjH8/bX++sbIJT35MSwKnp1r/OQBAqC5XO99xFbJ9XClhf4w==",
|
||||
"version": "1.43.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.1.tgz",
|
||||
"integrity": "sha512-EI36Mto2Vrx6VF7rm708qSnesVQKbxEWvPrfA1IPY6HgczBplDx7ENtx+K2n4kJ41sLLkuGfmb0ZLSSXlDhqPg==",
|
||||
"dev": true
|
||||
},
|
||||
"plur": {
|
||||
@@ -6962,9 +6942,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.12.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.12.0.tgz",
|
||||
"integrity": "sha512-trVZiI6RMOkO476zLGaBIzszOdFPnCCXHPG9kn0yuS1uz6xdVxPfZdB3vUig9pxPFDM9BRAgz/YUIVQ1/vuiUg==",
|
||||
"version": "6.12.1",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz",
|
||||
"integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"side-channel": "^1.0.6"
|
||||
@@ -7386,9 +7366,9 @@
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "5.4.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz",
|
||||
"integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==",
|
||||
"version": "5.4.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
|
||||
"integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
|
||||
"dev": true
|
||||
},
|
||||
"typical": {
|
||||
|
||||
@@ -63,7 +63,6 @@
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-formatter-autolinkable-stylish": "^1.3.0",
|
||||
"eslint-plugin-local": "^4.2.1",
|
||||
"eslint-plugin-no-null": "^1.0.2",
|
||||
"fast-xml-parser": "^4.3.6",
|
||||
"glob": "^10.3.10",
|
||||
"hereby": "^1.8.9",
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { execFileSync } from "child_process";
|
||||
import {
|
||||
readFileSync,
|
||||
writeFileSync,
|
||||
} from "fs";
|
||||
import {
|
||||
dirname,
|
||||
resolve,
|
||||
} from "path";
|
||||
|
||||
const packageJsonFilePath = process.argv[2];
|
||||
if (!packageJsonFilePath) {
|
||||
console.error("Usage: node addPackageJsonGitHead.mjs <package.json location>");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const packageJsonValue = JSON.parse(readFileSync(packageJsonFilePath, "utf8"));
|
||||
|
||||
const cwd = dirname(resolve(packageJsonFilePath));
|
||||
const gitHead = execFileSync("git", ["rev-parse", "HEAD"], { cwd, encoding: "utf8" }).trim();
|
||||
|
||||
packageJsonValue.gitHead = gitHead;
|
||||
|
||||
writeFileSync(packageJsonFilePath, JSON.stringify(packageJsonValue, undefined, 4) + "\n");
|
||||
@@ -1,5 +1,4 @@
|
||||
import assert from "assert";
|
||||
import { execFileSync } from "child_process";
|
||||
import {
|
||||
readFileSync,
|
||||
writeFileSync,
|
||||
@@ -18,7 +17,6 @@ const __filename = url.fileURLToPath(new URL(import.meta.url));
|
||||
name: string;
|
||||
version: string;
|
||||
keywords: string[];
|
||||
gitHead?: string;
|
||||
}} PackageJson
|
||||
*/
|
||||
|
||||
@@ -59,12 +57,11 @@ function main() {
|
||||
// Finally write the changes to disk.
|
||||
// Modify the package.json structure
|
||||
packageJsonValue.version = `${majorMinor}.${prereleasePatch}`;
|
||||
packageJsonValue.gitHead = execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();
|
||||
writeFileSync(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4));
|
||||
writeFileSync(tsFilePath, modifiedTsFileContents);
|
||||
}
|
||||
|
||||
/* eslint-disable no-null/no-null */
|
||||
/* eslint-disable no-restricted-syntax */
|
||||
/**
|
||||
* @param {string} tsFilePath
|
||||
* @param {string} tsFileContents
|
||||
@@ -101,7 +98,7 @@ function parsePackageJsonVersion(versionString) {
|
||||
assert(match !== null, "package.json 'version' should match " + versionRgx.toString());
|
||||
return { majorMinor: match[1], patch: match[2] };
|
||||
}
|
||||
/* eslint-enable no-null/no-null */
|
||||
/* eslint-enable no-restricted-syntax */
|
||||
|
||||
/**
|
||||
* e.g. 0-dev.20170707
|
||||
|
||||
@@ -53,7 +53,7 @@ module.exports = createRule({
|
||||
}
|
||||
|
||||
if (node.type === AST_NODE_TYPES.Literal) {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
return node.value === null || node.value === true || node.value === false;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ module.exports = createRule({
|
||||
internalCommentNotLastError: `@internal should only appear in final JSDoc comment for declaration.`,
|
||||
multipleJSDocError: `Declaration has multiple JSDoc comments.`,
|
||||
internalCommentOnParameterProperty: `@internal cannot appear on a JSDoc comment; use a declared property and an assignment in the constructor instead.`,
|
||||
internalCommentOnUnexported: `@internal should not appear on an unexported declaration.`,
|
||||
},
|
||||
schema: [],
|
||||
type: "problem",
|
||||
@@ -23,6 +24,31 @@ module.exports = createRule({
|
||||
const atInternal = "@internal";
|
||||
const jsdocStart = "/**";
|
||||
|
||||
/** @type {Map<import("@typescript-eslint/utils").TSESTree.Node, boolean>} */
|
||||
const isExportedCache = new Map();
|
||||
|
||||
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */
|
||||
function isExported(node) {
|
||||
const exported = isExportedCache.get(node);
|
||||
if (exported !== undefined) {
|
||||
return exported;
|
||||
}
|
||||
|
||||
/** @type {import("@typescript-eslint/utils").TSESTree.Node | undefined} */
|
||||
let current = node;
|
||||
while (current) {
|
||||
// https://github.com/typescript-eslint/typescript-eslint/blob/e44a1a280f08f9fd0d29f74e5c3e73b7b64a9606/packages/eslint-plugin/src/util/collectUnusedVariables.ts#L440
|
||||
if (current.type.startsWith("Export")) {
|
||||
isExportedCache.set(node, true);
|
||||
return true;
|
||||
}
|
||||
isExportedCache.set(current, false);
|
||||
current = current.parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @type {(text: string) => boolean} */
|
||||
function isJSDocText(text) {
|
||||
return text.startsWith(jsdocStart);
|
||||
@@ -81,12 +107,15 @@ module.exports = createRule({
|
||||
if (!isJSDoc) {
|
||||
context.report({ messageId: "internalCommentInNonJSDocError", node: c, loc: getAtInternalLoc(c, indexInComment) });
|
||||
}
|
||||
else if (i !== last) {
|
||||
context.report({ messageId: "internalCommentNotLastError", node: c, loc: getAtInternalLoc(c, indexInComment) });
|
||||
}
|
||||
else if (node.type === "TSParameterProperty") {
|
||||
context.report({ messageId: "internalCommentOnParameterProperty", node: c, loc: getAtInternalLoc(c, indexInComment) });
|
||||
}
|
||||
else if (!isExported(node)) {
|
||||
context.report({ messageId: "internalCommentOnUnexported", node: c, loc: getAtInternalLoc(c, indexInComment) });
|
||||
}
|
||||
else if (i !== last) {
|
||||
context.report({ messageId: "internalCommentNotLastError", node: c, loc: getAtInternalLoc(c, indexInComment) });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ module.exports = createRule({
|
||||
return;
|
||||
}
|
||||
|
||||
if ((allowNamedFunctions && node.id !== null) || isMethodType(node)) { // eslint-disable-line no-null/no-null
|
||||
if ((allowNamedFunctions && node.id !== null) || isMethodType(node)) { // eslint-disable-line no-restricted-syntax
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ export * from "../transformers/generators";
|
||||
export * from "../transformers/module/module";
|
||||
export * from "../transformers/module/system";
|
||||
export * from "../transformers/module/esnextAnd2015";
|
||||
export * from "../transformers/module/node";
|
||||
export * from "../transformers/module/impliedNodeFormatDependent";
|
||||
export * from "../transformers/declarations/diagnostics";
|
||||
export * from "../transformers/declarations";
|
||||
export * from "../transformer";
|
||||
@@ -72,6 +72,7 @@ export * from "../watchPublic";
|
||||
export * from "../tsbuild";
|
||||
export * from "../tsbuildPublic";
|
||||
export * from "../executeCommandLine";
|
||||
export * from "../expressionToTypeNode";
|
||||
import * as moduleSpecifiers from "./ts.moduleSpecifiers";
|
||||
export { moduleSpecifiers };
|
||||
import * as performance from "./ts.performance";
|
||||
|
||||
@@ -200,9 +200,9 @@ import {
|
||||
isOptionalChain,
|
||||
isOptionalChainRoot,
|
||||
isOutermostOptionalChain,
|
||||
isParameterDeclaration,
|
||||
isParameterPropertyDeclaration,
|
||||
isParenthesizedExpression,
|
||||
isPartOfParameterDeclaration,
|
||||
isPartOfTypeQuery,
|
||||
isPrefixUnaryExpression,
|
||||
isPrivateIdentifier,
|
||||
@@ -3647,7 +3647,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
|
||||
else if (isBlockOrCatchScoped(node)) {
|
||||
bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
|
||||
}
|
||||
else if (isParameterDeclaration(node)) {
|
||||
else if (isPartOfParameterDeclaration(node)) {
|
||||
// It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration
|
||||
// because its parent chain has already been set up, since parents are set before descending into children.
|
||||
//
|
||||
|
||||
+579
-877
File diff suppressed because it is too large
Load Diff
@@ -53,6 +53,7 @@ import {
|
||||
getFileMatcherPatterns,
|
||||
getLocaleSpecificMessage,
|
||||
getNormalizedAbsolutePath,
|
||||
getOwnKeys,
|
||||
getRegexFromPattern,
|
||||
getRegularExpressionForWildcard,
|
||||
getRegularExpressionsForWildcards,
|
||||
@@ -235,6 +236,7 @@ const libEntries: [string, string][] = [
|
||||
["esnext.object", "lib.esnext.object.d.ts"],
|
||||
["esnext.array", "lib.esnext.array.d.ts"],
|
||||
["esnext.regexp", "lib.esnext.regexp.d.ts"],
|
||||
["esnext.string", "lib.esnext.string.d.ts"],
|
||||
["decorators", "lib.decorators.d.ts"],
|
||||
["decorators.legacy", "lib.decorators.legacy.d.ts"],
|
||||
];
|
||||
@@ -313,6 +315,7 @@ export const optionsForWatch: CommandLineOption[] = [
|
||||
isFilePath: true,
|
||||
extraValidation: specToDiagnostic,
|
||||
},
|
||||
allowConfigDirTemplateSubstitution: true,
|
||||
category: Diagnostics.Watch_and_Build_Modes,
|
||||
description: Diagnostics.Remove_a_list_of_directories_from_the_watch_process,
|
||||
},
|
||||
@@ -325,6 +328,7 @@ export const optionsForWatch: CommandLineOption[] = [
|
||||
isFilePath: true,
|
||||
extraValidation: specToDiagnostic,
|
||||
},
|
||||
allowConfigDirTemplateSubstitution: true,
|
||||
category: Diagnostics.Watch_and_Build_Modes,
|
||||
description: Diagnostics.Remove_a_list_of_files_from_the_watch_mode_s_processing,
|
||||
},
|
||||
@@ -534,6 +538,7 @@ export const targetOptionDeclaration: CommandLineOptionOfCustomType = {
|
||||
es2020: ScriptTarget.ES2020,
|
||||
es2021: ScriptTarget.ES2021,
|
||||
es2022: ScriptTarget.ES2022,
|
||||
es2023: ScriptTarget.ES2023,
|
||||
esnext: ScriptTarget.ESNext,
|
||||
})),
|
||||
affectsSourceFile: true,
|
||||
@@ -826,6 +831,15 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
|
||||
description: Diagnostics.Do_not_transform_or_elide_any_imports_or_exports_not_marked_as_type_only_ensuring_they_are_written_in_the_output_file_s_format_based_on_the_module_setting,
|
||||
defaultValueDescription: false,
|
||||
},
|
||||
{
|
||||
name: "isolatedDeclarations",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Interop_Constraints,
|
||||
description: Diagnostics.Require_sufficient_annotation_on_exports_so_other_tools_can_trivially_generate_declaration_files,
|
||||
defaultValueDescription: false,
|
||||
affectsBuildInfo: true,
|
||||
affectsSemanticDiagnostics: true,
|
||||
},
|
||||
|
||||
// Strict Type Checks
|
||||
{
|
||||
@@ -1042,6 +1056,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
|
||||
name: "paths",
|
||||
type: "object",
|
||||
affectsModuleResolution: true,
|
||||
allowConfigDirTemplateSubstitution: true,
|
||||
isTSConfigOnly: true,
|
||||
category: Diagnostics.Modules,
|
||||
description: Diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations,
|
||||
@@ -1059,6 +1074,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
|
||||
isFilePath: true,
|
||||
},
|
||||
affectsModuleResolution: true,
|
||||
allowConfigDirTemplateSubstitution: true,
|
||||
category: Diagnostics.Modules,
|
||||
description: Diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules,
|
||||
transpileOptionValue: undefined,
|
||||
@@ -1073,6 +1089,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
|
||||
isFilePath: true,
|
||||
},
|
||||
affectsModuleResolution: true,
|
||||
allowConfigDirTemplateSubstitution: true,
|
||||
category: Diagnostics.Modules,
|
||||
description: Diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types,
|
||||
},
|
||||
@@ -1608,6 +1625,15 @@ export const optionsAffectingProgramStructure: readonly CommandLineOption[] = op
|
||||
/** @internal */
|
||||
export const transpileOptionValueCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option => hasProperty(option, "transpileOptionValue"));
|
||||
|
||||
/** @internal */
|
||||
export const configDirTemplateSubstitutionOptions: readonly CommandLineOption[] = optionDeclarations.filter(
|
||||
option => option.allowConfigDirTemplateSubstitution || (!option.isCommandLineOnly && option.isFilePath),
|
||||
);
|
||||
/** @internal */
|
||||
export const configDirTemplateSubstitutionWatchOptions: readonly CommandLineOption[] = optionsForWatch.filter(
|
||||
option => option.allowConfigDirTemplateSubstitution || (!option.isCommandLineOnly && option.isFilePath),
|
||||
);
|
||||
|
||||
// Build related options
|
||||
/** @internal */
|
||||
export const optionsForBuild: CommandLineOption[] = [
|
||||
@@ -2387,7 +2413,7 @@ export function convertToJson(
|
||||
return false;
|
||||
|
||||
case SyntaxKind.NullKeyword:
|
||||
return null; // eslint-disable-line no-null/no-null
|
||||
return null; // eslint-disable-line no-restricted-syntax
|
||||
|
||||
case SyntaxKind.StringLiteral:
|
||||
if (!isDoubleQuotedString(valueExpression)) {
|
||||
@@ -2636,6 +2662,9 @@ function serializeOptionBaseObject(
|
||||
if (pathOptions && optionDefinition.isFilePath) {
|
||||
result.set(name, getRelativePathFromFile(pathOptions.configFilePath, getNormalizedAbsolutePath(value as string, getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName!));
|
||||
}
|
||||
else if (pathOptions && optionDefinition.type === "list" && optionDefinition.element.isFilePath) {
|
||||
result.set(name, (value as string[]).map(v => getRelativePathFromFile(pathOptions.configFilePath, getNormalizedAbsolutePath(v, getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName!)));
|
||||
}
|
||||
else {
|
||||
result.set(name, value);
|
||||
}
|
||||
@@ -2859,8 +2888,8 @@ export function setConfigFileInOptions(options: CompilerOptions, configFile: TsC
|
||||
}
|
||||
}
|
||||
|
||||
function isNullOrUndefined(x: any): x is null | undefined {
|
||||
return x === undefined || x === null; // eslint-disable-line no-null/no-null
|
||||
function isNullOrUndefined(x: any): x is null | undefined { // eslint-disable-line no-restricted-syntax
|
||||
return x === undefined || x === null; // eslint-disable-line no-restricted-syntax
|
||||
}
|
||||
|
||||
function directoryOfCombinedPath(fileName: string, basePath: string) {
|
||||
@@ -2898,17 +2927,23 @@ function parseJsonConfigFileContentWorker(
|
||||
|
||||
const parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors, extendedConfigCache);
|
||||
const { raw } = parsedConfig;
|
||||
const options = extend(existingOptions, parsedConfig.options || {});
|
||||
const watchOptions = existingWatchOptions && parsedConfig.watchOptions ?
|
||||
extend(existingWatchOptions, parsedConfig.watchOptions) :
|
||||
parsedConfig.watchOptions || existingWatchOptions;
|
||||
|
||||
const options = handleOptionConfigDirTemplateSubstitution(
|
||||
extend(existingOptions, parsedConfig.options || {}),
|
||||
configDirTemplateSubstitutionOptions,
|
||||
basePath,
|
||||
) as CompilerOptions;
|
||||
const watchOptions = handleWatchOptionsConfigDirTemplateSubstitution(
|
||||
existingWatchOptions && parsedConfig.watchOptions ?
|
||||
extend(existingWatchOptions, parsedConfig.watchOptions) :
|
||||
parsedConfig.watchOptions || existingWatchOptions,
|
||||
basePath,
|
||||
);
|
||||
options.configFilePath = configFileName && normalizeSlashes(configFileName);
|
||||
const basePathForFileNames = normalizePath(configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath);
|
||||
const configFileSpecs = getConfigFileSpecs();
|
||||
if (sourceFile) sourceFile.configFileSpecs = configFileSpecs;
|
||||
setConfigFileInOptions(options, sourceFile);
|
||||
|
||||
const basePathForFileNames = normalizePath(configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath);
|
||||
return {
|
||||
options,
|
||||
watchOptions,
|
||||
@@ -2963,6 +2998,7 @@ function parseJsonConfigFileContentWorker(
|
||||
includeSpecs = [defaultIncludeSpec];
|
||||
isDefaultIncludeSpec = true;
|
||||
}
|
||||
let validatedIncludeSpecsBeforeSubstitution: readonly string[] | undefined, validatedExcludeSpecsBeforeSubstitution: readonly string[] | undefined;
|
||||
let validatedIncludeSpecs: readonly string[] | undefined, validatedExcludeSpecs: readonly string[] | undefined;
|
||||
|
||||
// The exclude spec list is converted into a regular expression, which allows us to quickly
|
||||
@@ -2970,20 +3006,37 @@ function parseJsonConfigFileContentWorker(
|
||||
// file system.
|
||||
|
||||
if (includeSpecs) {
|
||||
validatedIncludeSpecs = validateSpecs(includeSpecs, errors, /*disallowTrailingRecursion*/ true, sourceFile, "include");
|
||||
validatedIncludeSpecsBeforeSubstitution = validateSpecs(includeSpecs, errors, /*disallowTrailingRecursion*/ true, sourceFile, "include");
|
||||
validatedIncludeSpecs = getSubstitutedStringArrayWithConfigDirTemplate(
|
||||
validatedIncludeSpecsBeforeSubstitution,
|
||||
basePathForFileNames,
|
||||
) || validatedIncludeSpecsBeforeSubstitution;
|
||||
}
|
||||
|
||||
if (excludeSpecs) {
|
||||
validatedExcludeSpecs = validateSpecs(excludeSpecs, errors, /*disallowTrailingRecursion*/ false, sourceFile, "exclude");
|
||||
validatedExcludeSpecsBeforeSubstitution = validateSpecs(excludeSpecs, errors, /*disallowTrailingRecursion*/ false, sourceFile, "exclude");
|
||||
validatedExcludeSpecs = getSubstitutedStringArrayWithConfigDirTemplate(
|
||||
validatedExcludeSpecsBeforeSubstitution,
|
||||
basePathForFileNames,
|
||||
) || validatedExcludeSpecsBeforeSubstitution;
|
||||
}
|
||||
|
||||
const validatedFilesSpecBeforeSubstitution = filter(filesSpecs, isString);
|
||||
const validatedFilesSpec = getSubstitutedStringArrayWithConfigDirTemplate(
|
||||
validatedFilesSpecBeforeSubstitution,
|
||||
basePathForFileNames,
|
||||
) || validatedFilesSpecBeforeSubstitution;
|
||||
|
||||
return {
|
||||
filesSpecs,
|
||||
includeSpecs,
|
||||
excludeSpecs,
|
||||
validatedFilesSpec: filter(filesSpecs, isString),
|
||||
validatedFilesSpec,
|
||||
validatedIncludeSpecs,
|
||||
validatedExcludeSpecs,
|
||||
validatedFilesSpecBeforeSubstitution,
|
||||
validatedIncludeSpecsBeforeSubstitution,
|
||||
validatedExcludeSpecsBeforeSubstitution,
|
||||
pathPatterns: undefined, // Initialized on first use
|
||||
isDefaultIncludeSpec,
|
||||
};
|
||||
@@ -3051,6 +3104,84 @@ function parseJsonConfigFileContentWorker(
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function handleWatchOptionsConfigDirTemplateSubstitution(
|
||||
watchOptions: WatchOptions | undefined,
|
||||
basePath: string,
|
||||
) {
|
||||
return handleOptionConfigDirTemplateSubstitution(watchOptions, configDirTemplateSubstitutionWatchOptions, basePath) as WatchOptions | undefined;
|
||||
}
|
||||
|
||||
function handleOptionConfigDirTemplateSubstitution(
|
||||
options: OptionsBase | undefined,
|
||||
optionDeclarations: readonly CommandLineOption[],
|
||||
basePath: string,
|
||||
) {
|
||||
if (!options) return options;
|
||||
let result: OptionsBase | undefined;
|
||||
for (const option of optionDeclarations) {
|
||||
if (options[option.name] !== undefined) {
|
||||
const value = options[option.name];
|
||||
switch (option.type) {
|
||||
case "string":
|
||||
Debug.assert(option.isFilePath);
|
||||
if (startsWithConfigDirTemplate(value)) {
|
||||
setOptionValue(option, getSubstitutedPathWithConfigDirTemplate(value, basePath));
|
||||
}
|
||||
break;
|
||||
case "list":
|
||||
Debug.assert(option.element.isFilePath);
|
||||
const listResult = getSubstitutedStringArrayWithConfigDirTemplate(value as string[], basePath);
|
||||
if (listResult) setOptionValue(option, listResult);
|
||||
break;
|
||||
case "object":
|
||||
Debug.assert(option.name === "paths");
|
||||
const objectResult = getSubstitutedMapLikeOfStringArrayWithConfigDirTemplate(value as MapLike<string[]>, basePath);
|
||||
if (objectResult) setOptionValue(option, objectResult);
|
||||
break;
|
||||
default:
|
||||
Debug.fail("option type not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
return result || options;
|
||||
|
||||
function setOptionValue(option: CommandLineOption, value: CompilerOptionsValue) {
|
||||
(result ??= assign({}, options))[option.name] = value;
|
||||
}
|
||||
}
|
||||
|
||||
const configDirTemplate = `\${configDir}`;
|
||||
function startsWithConfigDirTemplate(value: any): value is string {
|
||||
return isString(value) && startsWith(value, configDirTemplate, /*ignoreCase*/ true);
|
||||
}
|
||||
|
||||
function getSubstitutedPathWithConfigDirTemplate(value: string, basePath: string) {
|
||||
return getNormalizedAbsolutePath(value.replace(configDirTemplate, "./"), basePath);
|
||||
}
|
||||
|
||||
function getSubstitutedStringArrayWithConfigDirTemplate(list: readonly string[] | undefined, basePath: string) {
|
||||
if (!list) return list;
|
||||
let result: string[] | undefined;
|
||||
list.forEach((element, index) => {
|
||||
if (!startsWithConfigDirTemplate(element)) return;
|
||||
(result ??= list.slice())[index] = getSubstitutedPathWithConfigDirTemplate(element, basePath);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function getSubstitutedMapLikeOfStringArrayWithConfigDirTemplate(mapLike: MapLike<string[]>, basePath: string) {
|
||||
let result: MapLike<string[]> | undefined;
|
||||
const ownKeys = getOwnKeys(mapLike);
|
||||
ownKeys.forEach(key => {
|
||||
if (!isArray(mapLike[key])) return;
|
||||
const subStitution = getSubstitutedStringArrayWithConfigDirTemplate(mapLike[key], basePath);
|
||||
if (!subStitution) return;
|
||||
(result ??= assign({}, mapLike))[key] = subStitution;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
function isErrorNoInputFiles(error: Diagnostic) {
|
||||
return error.code === Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code;
|
||||
}
|
||||
@@ -3152,9 +3283,10 @@ function parseConfig(
|
||||
else {
|
||||
ownConfig.extendedConfigPath.forEach(extendedConfigPath => applyExtendedConfig(result, extendedConfigPath));
|
||||
}
|
||||
if (!ownConfig.raw.include && result.include) ownConfig.raw.include = result.include;
|
||||
if (!ownConfig.raw.exclude && result.exclude) ownConfig.raw.exclude = result.exclude;
|
||||
if (!ownConfig.raw.files && result.files) ownConfig.raw.files = result.files;
|
||||
if (result.include) ownConfig.raw.include = result.include;
|
||||
if (result.exclude) ownConfig.raw.exclude = result.exclude;
|
||||
if (result.files) ownConfig.raw.files = result.files;
|
||||
|
||||
if (ownConfig.raw.compileOnSave === undefined && result.compileOnSave) ownConfig.raw.compileOnSave = result.compileOnSave;
|
||||
if (sourceFile && result.extendedSourceFiles) sourceFile.extendedSourceFiles = arrayFrom(result.extendedSourceFiles.keys());
|
||||
|
||||
@@ -3171,12 +3303,15 @@ function parseConfig(
|
||||
const extendsRaw = extendedConfig.raw;
|
||||
let relativeDifference: string | undefined;
|
||||
const setPropertyInResultIfNotUndefined = (propertyName: "include" | "exclude" | "files") => {
|
||||
if (ownConfig.raw[propertyName]) return; // No need to calculate if already set in own config
|
||||
if (extendsRaw[propertyName]) {
|
||||
result[propertyName] = map(extendsRaw[propertyName], (path: string) =>
|
||||
isRootedDiskPath(path) ? path : combinePaths(
|
||||
relativeDifference ||= convertToRelativePath(getDirectoryPath(extendedConfigPath), basePath, createGetCanonicalFileName(host.useCaseSensitiveFileNames)),
|
||||
path,
|
||||
));
|
||||
startsWithConfigDirTemplate(path) || isRootedDiskPath(path) ?
|
||||
path :
|
||||
combinePaths(
|
||||
relativeDifference ||= convertToRelativePath(getDirectoryPath(extendedConfigPath), basePath, createGetCanonicalFileName(host.useCaseSensitiveFileNames)),
|
||||
path,
|
||||
));
|
||||
}
|
||||
};
|
||||
setPropertyInResultIfNotUndefined("include");
|
||||
@@ -3535,7 +3670,8 @@ export function convertJsonOption(
|
||||
|
||||
function normalizeNonListOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue {
|
||||
if (option.isFilePath) {
|
||||
value = getNormalizedAbsolutePath(value, basePath);
|
||||
value = normalizeSlashes(value);
|
||||
value = !startsWithConfigDirTemplate(value) ? getNormalizedAbsolutePath(value, basePath) : value;
|
||||
if (value === "") {
|
||||
value = ".";
|
||||
}
|
||||
|
||||
@@ -872,9 +872,9 @@ export function arrayIsEqualTo<T>(array1: readonly T[] | undefined, array2: read
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function compact<T>(array: (T | undefined | null | false | 0 | "")[]): T[];
|
||||
export function compact<T>(array: (T | undefined | null | false | 0 | "")[]): T[]; // eslint-disable-line no-restricted-syntax
|
||||
/** @internal */
|
||||
export function compact<T>(array: readonly (T | undefined | null | false | 0 | "")[]): readonly T[];
|
||||
export function compact<T>(array: readonly (T | undefined | null | false | 0 | "")[]): readonly T[]; // eslint-disable-line no-restricted-syntax
|
||||
// ESLint thinks these can be combined with the above - they cannot; they'd produce higher-priority inferences and prevent the falsey types from being stripped
|
||||
/** @internal */
|
||||
export function compact<T>(array: T[]): T[]; // eslint-disable-line @typescript-eslint/unified-signatures
|
||||
@@ -1511,8 +1511,8 @@ export function group<T, K>(values: readonly T[], getGroupId: (value: T) => K, r
|
||||
/** @internal */
|
||||
export function groupBy<T, U extends T>(values: readonly T[] | undefined, keySelector: (value: T) => value is U): { true?: U[]; false?: Exclude<T, U>[]; };
|
||||
/** @internal */
|
||||
export function groupBy<T, K extends string | number | boolean | null | undefined>(values: readonly T[] | undefined, keySelector: (value: T) => K): { [P in K as `${P}`]?: T[]; };
|
||||
export function groupBy<T, K extends string | number | boolean | null | undefined>(values: readonly T[] | undefined, keySelector: (value: T) => K): { [P in K as `${P}`]?: T[]; } {
|
||||
export function groupBy<T, K extends string | number | boolean | null | undefined>(values: readonly T[] | undefined, keySelector: (value: T) => K): { [P in K as `${P}`]?: T[]; }; // eslint-disable-line no-restricted-syntax
|
||||
export function groupBy<T, K extends string | number | boolean | null | undefined>(values: readonly T[] | undefined, keySelector: (value: T) => K): { [P in K as `${P}`]?: T[]; } { // eslint-disable-line no-restricted-syntax
|
||||
const result: Record<string, T[]> = {};
|
||||
if (values) {
|
||||
for (const value of values) {
|
||||
@@ -2289,7 +2289,7 @@ export function compareBooleans(a: boolean, b: boolean): Comparison {
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function getSpellingSuggestion<T>(name: string, candidates: T[], getName: (candidate: T) => string | undefined): T | undefined {
|
||||
export function getSpellingSuggestion<T>(name: string, candidates: Iterable<T>, getName: (candidate: T) => string | undefined): T | undefined {
|
||||
const maximumLengthDifference = Math.max(2, Math.floor(name.length * 0.34));
|
||||
let bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result is worse than this, don't bother.
|
||||
let bestCandidate: T | undefined;
|
||||
|
||||
@@ -244,13 +244,13 @@ export namespace Debug {
|
||||
}
|
||||
|
||||
export function assertIsDefined<T>(value: T, message?: string, stackCrawlMark?: AnyFunction): asserts value is NonNullable<T> {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
if (value === undefined || value === null) {
|
||||
fail(message, stackCrawlMark || assertIsDefined);
|
||||
}
|
||||
}
|
||||
|
||||
export function checkDefined<T>(value: T | null | undefined, message?: string, stackCrawlMark?: AnyFunction): T {
|
||||
export function checkDefined<T>(value: T | null | undefined, message?: string, stackCrawlMark?: AnyFunction): T { // eslint-disable-line no-restricted-syntax
|
||||
assertIsDefined(value, message, stackCrawlMark || checkDefined);
|
||||
return value;
|
||||
}
|
||||
@@ -935,7 +935,7 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
|
||||
FlowFlags.Condition |
|
||||
FlowFlags.ArrayMutation;
|
||||
|
||||
const links: Record<number, FlowGraphNode> = Object.create(/*o*/ null); // eslint-disable-line no-null/no-null
|
||||
const links: Record<number, FlowGraphNode> = Object.create(/*o*/ null); // eslint-disable-line no-restricted-syntax
|
||||
const nodes: FlowGraphNode[] = [];
|
||||
const edges: FlowGraphEdge[] = [];
|
||||
const root = buildGraphNode(flowNode, new Set());
|
||||
|
||||
@@ -967,6 +967,10 @@
|
||||
"category": "Error",
|
||||
"code": 1292
|
||||
},
|
||||
"ESM syntax is not allowed in a CommonJS module when 'module' is set to 'preserve'.": {
|
||||
"category": "Error",
|
||||
"code": 1293
|
||||
},
|
||||
|
||||
"'with' statements are not allowed in an async function block.": {
|
||||
"category": "Error",
|
||||
@@ -1645,6 +1649,154 @@
|
||||
"category": "Error",
|
||||
"code": 1498
|
||||
},
|
||||
"Unknown regular expression flag.": {
|
||||
"category": "Error",
|
||||
"code": 1499
|
||||
},
|
||||
"Duplicate regular expression flag.": {
|
||||
"category": "Error",
|
||||
"code": 1500
|
||||
},
|
||||
"This regular expression flag is only available when targeting '{0}' or later.": {
|
||||
"category": "Error",
|
||||
"code": 1501
|
||||
},
|
||||
"The Unicode (u) flag and the Unicode Sets (v) flag cannot be set simultaneously.": {
|
||||
"category": "Error",
|
||||
"code": 1502
|
||||
},
|
||||
"Named capturing groups are only available when targeting 'ES2018' or later.": {
|
||||
"category": "Error",
|
||||
"code": 1503
|
||||
},
|
||||
"Subpattern flags must be present when there is a minus sign.": {
|
||||
"category": "Error",
|
||||
"code": 1504
|
||||
},
|
||||
"Incomplete quantifier. Digit expected.": {
|
||||
"category": "Error",
|
||||
"code": 1505
|
||||
},
|
||||
"Numbers out of order in quantifier.": {
|
||||
"category": "Error",
|
||||
"code": 1506
|
||||
},
|
||||
"There is nothing available for repetition.": {
|
||||
"category": "Error",
|
||||
"code": 1507
|
||||
},
|
||||
"Unexpected '{0}'. Did you mean to escape it with backslash?": {
|
||||
"category": "Error",
|
||||
"code": 1508
|
||||
},
|
||||
"This regular expression flag cannot be toggled within a subpattern.": {
|
||||
"category": "Error",
|
||||
"code": 1509
|
||||
},
|
||||
"'\\k' must be followed by a capturing group name enclosed in angle brackets.": {
|
||||
"category": "Error",
|
||||
"code": 1510
|
||||
},
|
||||
"'\\q' is only available inside character class.": {
|
||||
"category": "Error",
|
||||
"code": 1511
|
||||
},
|
||||
"'\\c' must be followed by an ASCII letter.": {
|
||||
"category": "Error",
|
||||
"code": 1512
|
||||
},
|
||||
"Undetermined character escape.": {
|
||||
"category": "Error",
|
||||
"code": 1513
|
||||
},
|
||||
"Expected a capturing group name.": {
|
||||
"category": "Error",
|
||||
"code": 1514
|
||||
},
|
||||
"Named capturing groups with the same name must be mutually exclusive to each other.": {
|
||||
"category": "Error",
|
||||
"code": 1515
|
||||
},
|
||||
"A character class range must not be bounded by another character class.": {
|
||||
"category": "Error",
|
||||
"code": 1516
|
||||
},
|
||||
"Range out of order in character class.": {
|
||||
"category": "Error",
|
||||
"code": 1517
|
||||
},
|
||||
"Anything that would possibly match more than a single character is invalid inside a negated character class.": {
|
||||
"category": "Error",
|
||||
"code": 1518
|
||||
},
|
||||
"Operators must not be mixed within a character class. Wrap it in a nested class instead.": {
|
||||
"category": "Error",
|
||||
"code": 1519
|
||||
},
|
||||
"Expected a class set oprand.": {
|
||||
"category": "Error",
|
||||
"code": 1520
|
||||
},
|
||||
"'\\q' must be followed by string alternatives enclosed in braces.": {
|
||||
"category": "Error",
|
||||
"code": 1521
|
||||
},
|
||||
"A character class must not contain a reserved double punctuator. Did you mean to escape it with backslash?": {
|
||||
"category": "Error",
|
||||
"code": 1522
|
||||
},
|
||||
"Expected a Unicode property name.": {
|
||||
"category": "Error",
|
||||
"code": 1523
|
||||
},
|
||||
"Unknown Unicode property name.": {
|
||||
"category": "Error",
|
||||
"code": 1524
|
||||
},
|
||||
"Expected a Unicode property value.": {
|
||||
"category": "Error",
|
||||
"code": 1525
|
||||
},
|
||||
"Unknown Unicode property value.": {
|
||||
"category": "Error",
|
||||
"code": 1526
|
||||
},
|
||||
"Expected a Unicode property name or value.": {
|
||||
"category": "Error",
|
||||
"code": 1527
|
||||
},
|
||||
"Any Unicode property that would possibly match more than a single character is only available when the Unicode Sets (v) flag is set.": {
|
||||
"category": "Error",
|
||||
"code": 1528
|
||||
},
|
||||
"Unknown Unicode property name or value.": {
|
||||
"category": "Error",
|
||||
"code": 1529
|
||||
},
|
||||
"Unicode property value expressions are only available when the Unicode (u) flag or the Unicode Sets (v) flag is set.": {
|
||||
"category": "Error",
|
||||
"code": 1530
|
||||
},
|
||||
"'\\{0}' must be followed by a Unicode property value expression enclosed in braces.": {
|
||||
"category": "Error",
|
||||
"code": 1531
|
||||
},
|
||||
"There is no capturing group named '{0}' in this regular expression.": {
|
||||
"category": "Error",
|
||||
"code": 1532
|
||||
},
|
||||
"A decimal escape must refer to an existent capturing group. There are only {0} capturing groups in this regular expression.": {
|
||||
"category": "Error",
|
||||
"code": 1533
|
||||
},
|
||||
"Decimal escapes are invalid when there are no capturing groups in a regular expression.": {
|
||||
"category": "Error",
|
||||
"code": 1534
|
||||
},
|
||||
"This character cannot be escaped in a regular expression.": {
|
||||
"category": "Error",
|
||||
"code": 1535
|
||||
},
|
||||
|
||||
"The types of '{0}' are incompatible between these types.": {
|
||||
"category": "Error",
|
||||
@@ -6231,10 +6383,15 @@
|
||||
"category": "Message",
|
||||
"code": 6718
|
||||
},
|
||||
"Ensure that 'readonly' properties remain read-only in type relationships.": {
|
||||
"Require sufficient annotation on exports so other tools can trivially generate declaration files.": {
|
||||
"category": "Message",
|
||||
"code": 6719
|
||||
},
|
||||
"Ensure that 'readonly' properties remain read-only in type relationships.": {
|
||||
"category": "Message",
|
||||
"code": 6720
|
||||
},
|
||||
|
||||
"Default catch clause variables as 'unknown' instead of 'any'.": {
|
||||
"category": "Message",
|
||||
"code": 6803
|
||||
@@ -6749,6 +6906,126 @@
|
||||
"category": "Error",
|
||||
"code": 9006
|
||||
},
|
||||
"Function must have an explicit return type annotation with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9007
|
||||
},
|
||||
"Method must have an explicit return type annotation with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9008
|
||||
},
|
||||
"At least one accessor must have an explicit return type annotation with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9009
|
||||
},
|
||||
"Variable must have an explicit type annotation with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9010
|
||||
},
|
||||
"Parameter must have an explicit type annotation with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9011
|
||||
},
|
||||
"Property must have an explicit type annotation with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9012
|
||||
},
|
||||
"Expression type can't be inferred with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9013
|
||||
},
|
||||
"Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9014
|
||||
},
|
||||
"Objects that contain spread assignments can't be inferred with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9015
|
||||
},
|
||||
"Objects that contain shorthand properties can't be inferred with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9016
|
||||
},
|
||||
"Only const arrays can be inferred with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9017
|
||||
},
|
||||
"Arrays with spread elements can't inferred with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9018
|
||||
},
|
||||
"Binding elements can't be exported directly with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9019
|
||||
},
|
||||
"Enum member initializers must be computable without references to external symbols with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9020
|
||||
},
|
||||
"Extends clause can't contain an expression with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9021
|
||||
},
|
||||
"Inference from class expressions is not supported with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9022
|
||||
},
|
||||
"Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function.": {
|
||||
"category": "Error",
|
||||
"code": 9023
|
||||
},
|
||||
"Declaration emit for this parameter requires implicitly adding undefined to it's type. This is not supported with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9025
|
||||
},
|
||||
"Declaration emit for this file requires preserving this import for augmentations. This is not supported with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9026
|
||||
},
|
||||
"Add a type annotation to the variable {0}.": {
|
||||
"category": "Error",
|
||||
"code": 9027
|
||||
},
|
||||
"Add a type annotation to the parameter {0}.": {
|
||||
"category": "Error",
|
||||
"code": 9028
|
||||
},
|
||||
"Add a type annotation to the property {0}.": {
|
||||
"category": "Error",
|
||||
"code": 9029
|
||||
},
|
||||
"Add a return type to the function expression.": {
|
||||
"category": "Error",
|
||||
"code": 9030
|
||||
},
|
||||
"Add a return type to the function declaration.": {
|
||||
"category": "Error",
|
||||
"code": 9031
|
||||
},
|
||||
"Add a return type to the get accessor declaration.": {
|
||||
"category": "Error",
|
||||
"code": 9032
|
||||
},
|
||||
"Add a type to parameter of the set accessor declaration.": {
|
||||
"category": "Error",
|
||||
"code": 9033
|
||||
},
|
||||
"Add a return type to the method": {
|
||||
"category": "Error",
|
||||
"code": 9034
|
||||
},
|
||||
"Add satisfies and a type assertion to this expression (satisfies T as T) to make the type explicit.": {
|
||||
"category": "Error",
|
||||
"code": 9035
|
||||
},
|
||||
"Move the expression in default export to a variable and add a type annotation to it.": {
|
||||
"category": "Error",
|
||||
"code": 9036
|
||||
},
|
||||
"Default exports can't be inferred with --isolatedDeclarations.": {
|
||||
"category": "Error",
|
||||
"code": 9037
|
||||
},
|
||||
"JSX attributes must only be assigned a non-empty 'expression'.": {
|
||||
"category": "Error",
|
||||
"code": 17000
|
||||
|
||||
@@ -130,6 +130,7 @@ import {
|
||||
getEmitFlags,
|
||||
getEmitHelpers,
|
||||
getEmitModuleKind,
|
||||
getEmitModuleResolutionKind,
|
||||
getEmitScriptTarget,
|
||||
getExternalModuleName,
|
||||
getIdentifierTypeArguments,
|
||||
@@ -800,6 +801,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
|
||||
newLine: compilerOptions.newLine,
|
||||
noEmitHelpers: compilerOptions.noEmitHelpers,
|
||||
module: getEmitModuleKind(compilerOptions),
|
||||
moduleResolution: getEmitModuleResolutionKind(compilerOptions),
|
||||
target: getEmitScriptTarget(compilerOptions),
|
||||
sourceMap: compilerOptions.sourceMap,
|
||||
inlineSourceMap: compilerOptions.inlineSourceMap,
|
||||
@@ -867,6 +869,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
|
||||
newLine: compilerOptions.newLine,
|
||||
noEmitHelpers: true,
|
||||
module: compilerOptions.module,
|
||||
moduleResolution: compilerOptions.moduleResolution,
|
||||
target: compilerOptions.target,
|
||||
sourceMap: !forceDtsEmit && compilerOptions.declarationMap,
|
||||
inlineSourceMap: compilerOptions.inlineSourceMap,
|
||||
@@ -1111,6 +1114,7 @@ export const notImplementedResolver: EmitResolver = {
|
||||
isArgumentsLocalBinding: notImplemented,
|
||||
getExternalModuleFileFromDeclaration: notImplemented,
|
||||
isLiteralConstDeclaration: notImplemented,
|
||||
isNonNarrowedBindableName: notImplemented,
|
||||
getJsxFactoryEntity: notImplemented,
|
||||
getJsxFragmentFactoryEntity: notImplemented,
|
||||
isBindingCapturedByNode: notImplemented,
|
||||
|
||||
@@ -653,7 +653,7 @@ function executeCommandLineWorker(
|
||||
configParseResult.errors.forEach(reportDiagnostic);
|
||||
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
|
||||
}
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
sys.write(JSON.stringify(convertToTSConfig(configParseResult, configFileName, sys), null, 4) + sys.newLine);
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
@@ -693,7 +693,7 @@ function executeCommandLineWorker(
|
||||
}
|
||||
else {
|
||||
if (commandLineOptions.showConfig) {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
sys.write(JSON.stringify(convertToTSConfig(commandLine, combinePaths(currentDirectory, "tsconfig.json"), sys), null, 4) + sys.newLine);
|
||||
return sys.exit(ExitStatus.Success);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,506 @@
|
||||
import {
|
||||
AccessorDeclaration,
|
||||
AllAccessorDeclarations,
|
||||
ArrayLiteralExpression,
|
||||
ArrowFunction,
|
||||
AsExpression,
|
||||
BinaryExpression,
|
||||
BindingElement,
|
||||
ClassExpression,
|
||||
CompilerOptions,
|
||||
Debug,
|
||||
ElementAccessExpression,
|
||||
ExportAssignment,
|
||||
Expression,
|
||||
forEachReturnStatement,
|
||||
FunctionExpression,
|
||||
FunctionLikeDeclaration,
|
||||
GetAccessorDeclaration,
|
||||
getEffectiveReturnTypeNode,
|
||||
getEffectiveTypeAnnotationNode,
|
||||
getJSDocTypeAssertionType,
|
||||
getStrictOptionValue,
|
||||
HasInferredType,
|
||||
Identifier,
|
||||
IntersectionTypeNode,
|
||||
isBlock,
|
||||
isConstTypeReference,
|
||||
isDeclarationReadonly,
|
||||
isEntityNameExpression,
|
||||
isGetAccessor,
|
||||
isIdentifier,
|
||||
isJSDocTypeAssertion,
|
||||
isKeyword,
|
||||
isParameter,
|
||||
isPrimitiveLiteralValue,
|
||||
isShorthandPropertyAssignment,
|
||||
isSpreadAssignment,
|
||||
isValueSignatureDeclaration,
|
||||
isVarConstLike,
|
||||
JSDocSignature,
|
||||
MethodDeclaration,
|
||||
Node,
|
||||
NodeArray,
|
||||
NodeFlags,
|
||||
nodeIsMissing,
|
||||
ObjectLiteralExpression,
|
||||
ParameterDeclaration,
|
||||
ParenthesizedExpression,
|
||||
ParenthesizedTypeNode,
|
||||
PrefixUnaryExpression,
|
||||
PropertyAccessExpression,
|
||||
PropertyAssignment,
|
||||
PropertyDeclaration,
|
||||
PropertyName,
|
||||
PropertySignature,
|
||||
SetAccessorDeclaration,
|
||||
SignatureDeclaration,
|
||||
SymbolAccessibility,
|
||||
SyntacticTypeNodeBuilderContext,
|
||||
SyntacticTypeNodeBuilderResolver,
|
||||
SyntaxKind,
|
||||
TypeAssertion,
|
||||
TypeNode,
|
||||
TypeParameterDeclaration,
|
||||
UnionTypeNode,
|
||||
VariableDeclaration,
|
||||
} from "./_namespaces/ts";
|
||||
|
||||
/** @internal */
|
||||
export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolver: SyntacticTypeNodeBuilderResolver) {
|
||||
const strictNullChecks = getStrictOptionValue(options, "strictNullChecks");
|
||||
|
||||
return {
|
||||
typeFromExpression,
|
||||
serializeTypeOfDeclaration,
|
||||
serializeReturnTypeForSignature,
|
||||
serializeTypeOfExpression,
|
||||
};
|
||||
function serializeExistingTypeAnnotation(type: TypeNode | undefined) {
|
||||
return type === undefined ? undefined : !type.parent || !isParameter(type.parent) || !resolver.requiresAddingImplicitUndefined(type.parent) || canAddUndefined(type);
|
||||
}
|
||||
function serializeTypeOfExpression(expr: Expression, context: SyntacticTypeNodeBuilderContext, addUndefined?: boolean, preserveLiterals?: boolean) {
|
||||
return typeFromExpression(expr, context, /*isConstContext*/ false, addUndefined, preserveLiterals) ?? inferExpressionType(expr, context);
|
||||
}
|
||||
function serializeTypeOfDeclaration(node: HasInferredType, context: SyntacticTypeNodeBuilderContext) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertySignature:
|
||||
return serializeExistingTypeAnnotation(getEffectiveTypeAnnotationNode(node));
|
||||
case SyntaxKind.Parameter:
|
||||
return typeFromParameter(node, context);
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return typeFromVariable(node, context);
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
return typeFromProperty(node, context);
|
||||
case SyntaxKind.BindingElement:
|
||||
return inferTypeOfDeclaration(node, context);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return serializeTypeOfExpression(node.expression, context, /*addUndefined*/ undefined, /*preserveLiterals*/ true);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
case SyntaxKind.BinaryExpression:
|
||||
return serializeExistingTypeAnnotation(getEffectiveTypeAnnotationNode(node)) || inferTypeOfDeclaration(node, context);
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return typeFromExpression(node.initializer, context) || inferTypeOfDeclaration(node, context);
|
||||
default:
|
||||
Debug.assertNever(node, `Node needs to be an inferrable node, found ${Debug.formatSyntaxKind((node as Node).kind)}`);
|
||||
}
|
||||
}
|
||||
function serializeReturnTypeForSignature(node: SignatureDeclaration | JSDocSignature, context: SyntacticTypeNodeBuilderContext): boolean | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
return typeFromAccessor(node, context);
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.IndexSignature:
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.JSDocFunctionType:
|
||||
case SyntaxKind.JSDocSignature:
|
||||
return createReturnFromSignature(node, context);
|
||||
default:
|
||||
Debug.assertNever(node, `Node needs to be an inferrable node, found ${Debug.formatSyntaxKind((node as Node).kind)}`);
|
||||
}
|
||||
}
|
||||
function getTypeAnnotationFromAccessor(accessor: AccessorDeclaration): TypeNode | undefined {
|
||||
if (accessor) {
|
||||
return accessor.kind === SyntaxKind.GetAccessor
|
||||
? getEffectiveReturnTypeNode(accessor) // Getter - return type
|
||||
: accessor.parameters.length > 0
|
||||
? getEffectiveTypeAnnotationNode(accessor.parameters[0]) // Setter parameter type
|
||||
: undefined;
|
||||
}
|
||||
}
|
||||
function getTypeAnnotationFromAllAccessorDeclarations(node: AccessorDeclaration, accessors: AllAccessorDeclarations) {
|
||||
let accessorType = getTypeAnnotationFromAccessor(node);
|
||||
if (!accessorType && node !== accessors.firstAccessor) {
|
||||
accessorType = getTypeAnnotationFromAccessor(accessors.firstAccessor);
|
||||
}
|
||||
if (!accessorType && accessors.secondAccessor && node !== accessors.secondAccessor) {
|
||||
accessorType = getTypeAnnotationFromAccessor(accessors.secondAccessor);
|
||||
}
|
||||
return accessorType;
|
||||
}
|
||||
|
||||
function typeFromAccessor(node: AccessorDeclaration, context: SyntacticTypeNodeBuilderContext) {
|
||||
const accessorDeclarations = resolver.getAllAccessorDeclarations(node);
|
||||
const accessorType = getTypeAnnotationFromAllAccessorDeclarations(node, accessorDeclarations);
|
||||
if (accessorType) {
|
||||
return serializeExistingTypeAnnotation(accessorType);
|
||||
}
|
||||
if (accessorDeclarations.getAccessor) {
|
||||
return createReturnFromSignature(accessorDeclarations.getAccessor, context);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function typeFromVariable(node: VariableDeclaration, context: SyntacticTypeNodeBuilderContext) {
|
||||
const declaredType = getEffectiveTypeAnnotationNode(node);
|
||||
if (declaredType) {
|
||||
return serializeExistingTypeAnnotation(declaredType);
|
||||
}
|
||||
let resultType;
|
||||
if (node.initializer) {
|
||||
if (!resolver.isExpandoFunctionDeclaration(node)) {
|
||||
resultType = typeFromExpression(node.initializer, context, /*isConstContext*/ undefined, /*requiresAddingUndefined*/ undefined, isVarConstLike(node));
|
||||
}
|
||||
}
|
||||
return resultType ?? inferTypeOfDeclaration(node, context);
|
||||
}
|
||||
function typeFromParameter(node: ParameterDeclaration, context: SyntacticTypeNodeBuilderContext) {
|
||||
const parent = node.parent;
|
||||
if (parent.kind === SyntaxKind.SetAccessor) {
|
||||
return typeFromAccessor(parent, context);
|
||||
}
|
||||
const declaredType = getEffectiveTypeAnnotationNode(node);
|
||||
const addUndefined = resolver.requiresAddingImplicitUndefined(node);
|
||||
let resultType;
|
||||
if (!addUndefined) {
|
||||
if (declaredType) {
|
||||
return serializeExistingTypeAnnotation(declaredType);
|
||||
}
|
||||
if (node.initializer && isIdentifier(node.name)) {
|
||||
resultType = typeFromExpression(node.initializer, context);
|
||||
}
|
||||
}
|
||||
return resultType ?? inferTypeOfDeclaration(node, context);
|
||||
}
|
||||
function typeFromProperty(node: PropertyDeclaration, context: SyntacticTypeNodeBuilderContext) {
|
||||
const declaredType = getEffectiveTypeAnnotationNode(node);
|
||||
if (declaredType) {
|
||||
return serializeExistingTypeAnnotation(declaredType);
|
||||
}
|
||||
let resultType;
|
||||
if (node.initializer) {
|
||||
const isReadonly = isDeclarationReadonly(node);
|
||||
resultType = typeFromExpression(node.initializer, context, /*isConstContext*/ undefined, /*requiresAddingUndefined*/ undefined, isReadonly);
|
||||
}
|
||||
return resultType ?? inferTypeOfDeclaration(node, context);
|
||||
}
|
||||
|
||||
function inferTypeOfDeclaration(
|
||||
node: PropertyAssignment | PropertyAccessExpression | BinaryExpression | ElementAccessExpression | VariableDeclaration | ParameterDeclaration | BindingElement | PropertyDeclaration | PropertySignature | ExportAssignment,
|
||||
context: SyntacticTypeNodeBuilderContext,
|
||||
) {
|
||||
context.tracker.reportInferenceFallback(node);
|
||||
return false;
|
||||
}
|
||||
|
||||
function inferExpressionType(node: Expression, context: SyntacticTypeNodeBuilderContext) {
|
||||
context.tracker.reportInferenceFallback(node);
|
||||
return false;
|
||||
}
|
||||
|
||||
function inferReturnTypeOfSignatureSignature(node: SignatureDeclaration | JSDocSignature, context: SyntacticTypeNodeBuilderContext) {
|
||||
context.tracker.reportInferenceFallback(node);
|
||||
return false;
|
||||
}
|
||||
|
||||
function inferAccessorType(node: GetAccessorDeclaration | SetAccessorDeclaration, allAccessors: AllAccessorDeclarations, context: SyntacticTypeNodeBuilderContext) {
|
||||
if (node.kind === SyntaxKind.GetAccessor) {
|
||||
return createReturnFromSignature(node, context);
|
||||
}
|
||||
else {
|
||||
context.tracker.reportInferenceFallback(node);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function typeFromTypeAssertion(expression: Expression, type: TypeNode, context: SyntacticTypeNodeBuilderContext, requiresAddingUndefined: boolean) {
|
||||
if (isConstTypeReference(type)) {
|
||||
return typeFromExpression(expression, context, /*isConstContext*/ true, requiresAddingUndefined);
|
||||
}
|
||||
if (requiresAddingUndefined && !canAddUndefined(type)) {
|
||||
context.tracker.reportInferenceFallback(type);
|
||||
}
|
||||
return serializeExistingTypeAnnotation(type);
|
||||
}
|
||||
function typeFromExpression(node: Expression, context: SyntacticTypeNodeBuilderContext, isConstContext = false, requiresAddingUndefined = false, preserveLiterals = false): boolean | undefined {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
if (isJSDocTypeAssertion(node)) {
|
||||
return typeFromTypeAssertion(node.expression, getJSDocTypeAssertionType(node), context, requiresAddingUndefined);
|
||||
}
|
||||
return typeFromExpression((node as ParenthesizedExpression).expression, context, isConstContext, requiresAddingUndefined);
|
||||
case SyntaxKind.Identifier:
|
||||
if (resolver.isUndefinedIdentifierExpression(node as Identifier)) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.NullKeyword:
|
||||
return true;
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
return typeFromFunctionLikeExpression(node as ArrowFunction | FunctionExpression, context);
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
case SyntaxKind.AsExpression:
|
||||
const asExpression = node as AsExpression | TypeAssertion;
|
||||
return typeFromTypeAssertion(asExpression.expression, asExpression.type, context, requiresAddingUndefined);
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
const unaryExpression = node as PrefixUnaryExpression;
|
||||
if (isPrimitiveLiteralValue(unaryExpression)) {
|
||||
if (unaryExpression.operand.kind === SyntaxKind.BigIntLiteral) {
|
||||
return typeFromPrimitiveLiteral();
|
||||
}
|
||||
if (unaryExpression.operand.kind === SyntaxKind.NumericLiteral) {
|
||||
return typeFromPrimitiveLiteral();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return typeFromPrimitiveLiteral();
|
||||
case SyntaxKind.TemplateExpression:
|
||||
if (!isConstContext && !preserveLiterals) {
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
return typeFromPrimitiveLiteral();
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
return typeFromPrimitiveLiteral();
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
return typeFromPrimitiveLiteral();
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
return typeFromArrayLiteral(node as ArrayLiteralExpression, context, isConstContext);
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return typeFromObjectLiteral(node as ObjectLiteralExpression, context, isConstContext);
|
||||
case SyntaxKind.ClassExpression:
|
||||
return inferExpressionType(node as ClassExpression, context);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
function typeFromFunctionLikeExpression(fnNode: FunctionExpression | ArrowFunction, context: SyntacticTypeNodeBuilderContext) {
|
||||
const returnType = serializeExistingTypeAnnotation(fnNode.type) ?? createReturnFromSignature(fnNode, context);
|
||||
const typeParameters = reuseTypeParameters(fnNode.typeParameters);
|
||||
const parameters = fnNode.parameters.every(p => ensureParameter(p, context));
|
||||
return returnType && typeParameters && parameters;
|
||||
}
|
||||
function canGetTypeFromArrayLiteral(arrayLiteral: ArrayLiteralExpression, context: SyntacticTypeNodeBuilderContext, isConstContext: boolean) {
|
||||
if (!isConstContext) {
|
||||
context.tracker.reportInferenceFallback(arrayLiteral);
|
||||
return false;
|
||||
}
|
||||
for (const element of arrayLiteral.elements) {
|
||||
if (element.kind === SyntaxKind.SpreadElement) {
|
||||
context.tracker.reportInferenceFallback(element);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function typeFromArrayLiteral(arrayLiteral: ArrayLiteralExpression, context: SyntacticTypeNodeBuilderContext, isConstContext: boolean) {
|
||||
if (!canGetTypeFromArrayLiteral(arrayLiteral, context, isConstContext)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let canInferArray = true;
|
||||
for (const element of arrayLiteral.elements) {
|
||||
Debug.assert(element.kind !== SyntaxKind.SpreadElement);
|
||||
if (element.kind !== SyntaxKind.OmittedExpression) {
|
||||
canInferArray = (typeFromExpression(element, context, isConstContext) ?? inferExpressionType(element, context)) && canInferArray;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
function canGetTypeFromObjectLiteral(objectLiteral: ObjectLiteralExpression, context: SyntacticTypeNodeBuilderContext) {
|
||||
let result = true;
|
||||
for (const prop of objectLiteral.properties) {
|
||||
if (prop.flags & NodeFlags.ThisNodeHasError) {
|
||||
result = false;
|
||||
break; // Bail if parse errors
|
||||
}
|
||||
if (prop.kind === SyntaxKind.ShorthandPropertyAssignment || prop.kind === SyntaxKind.SpreadAssignment) {
|
||||
context.tracker.reportInferenceFallback(prop);
|
||||
result = false;
|
||||
}
|
||||
else if (prop.name.flags & NodeFlags.ThisNodeHasError) {
|
||||
result = false;
|
||||
break; // Bail if parse errors
|
||||
}
|
||||
else if (prop.name.kind === SyntaxKind.PrivateIdentifier) {
|
||||
// Not valid in object literals but the compiler will complain about this, we just ignore it here.
|
||||
result = false;
|
||||
}
|
||||
else if (prop.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
const expression = prop.name.expression;
|
||||
if (!isPrimitiveLiteralValue(expression, /*includeBigInt*/ false) && !isEntityNameExpression(expression)) {
|
||||
context.tracker.reportInferenceFallback(prop.name);
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function typeFromObjectLiteral(objectLiteral: ObjectLiteralExpression, context: SyntacticTypeNodeBuilderContext, isConstContext: boolean): boolean {
|
||||
if (!canGetTypeFromObjectLiteral(objectLiteral, context)) return false;
|
||||
|
||||
let canInferObjectLiteral = true;
|
||||
for (const prop of objectLiteral.properties) {
|
||||
Debug.assert(!isShorthandPropertyAssignment(prop) && !isSpreadAssignment(prop));
|
||||
|
||||
const name = prop.name;
|
||||
if (prop.name.kind === SyntaxKind.ComputedPropertyName) {
|
||||
if (!resolver.isNonNarrowedBindableName(prop.name)) {
|
||||
context.tracker.reportInferenceFallback(prop.name);
|
||||
}
|
||||
else if (isEntityNameExpression(prop.name.expression)) {
|
||||
const visibilityResult = resolver.isEntityNameVisible(prop.name.expression, context.enclosingDeclaration!, /*shouldComputeAliasToMakeVisible*/ false);
|
||||
if (visibilityResult.accessibility !== SymbolAccessibility.Accessible) {
|
||||
context.tracker.reportInferenceFallback(prop.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (prop.kind) {
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
canInferObjectLiteral = !!typeFromObjectLiteralMethod(prop, name, context) && canInferObjectLiteral;
|
||||
break;
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
canInferObjectLiteral = !!typeFromObjectLiteralPropertyAssignment(prop, name, context, isConstContext) && canInferObjectLiteral;
|
||||
break;
|
||||
case SyntaxKind.SetAccessor:
|
||||
case SyntaxKind.GetAccessor:
|
||||
canInferObjectLiteral = !!typeFromObjectLiteralAccessor(prop, name, context) && canInferObjectLiteral;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return canInferObjectLiteral;
|
||||
}
|
||||
|
||||
function typeFromObjectLiteralPropertyAssignment(prop: PropertyAssignment, name: PropertyName, context: SyntacticTypeNodeBuilderContext, isConstContext: boolean) {
|
||||
return typeFromExpression(prop.initializer, context, isConstContext) ?? inferTypeOfDeclaration(prop, context);
|
||||
}
|
||||
|
||||
function ensureParameter(p: ParameterDeclaration, context: SyntacticTypeNodeBuilderContext) {
|
||||
return typeFromParameter(p, context);
|
||||
}
|
||||
function reuseTypeParameters(typeParameters: NodeArray<TypeParameterDeclaration> | undefined) {
|
||||
// TODO: We will probably need to add a fake scopes for the signature (to hold the type parameters and the parameter)
|
||||
// For now this is good enough since the new serialization is used for Nodes in the same context.
|
||||
return typeParameters?.every(tp =>
|
||||
serializeExistingTypeAnnotation(tp.constraint) &&
|
||||
serializeExistingTypeAnnotation(tp.default)
|
||||
) ?? true;
|
||||
}
|
||||
function typeFromObjectLiteralMethod(method: MethodDeclaration, name: PropertyName, context: SyntacticTypeNodeBuilderContext): boolean {
|
||||
const returnType = createReturnFromSignature(method, context);
|
||||
const typeParameters = reuseTypeParameters(method.typeParameters);
|
||||
const parameters = method.parameters.every(p => ensureParameter(p, context));
|
||||
return returnType && typeParameters && parameters;
|
||||
}
|
||||
function typeFromObjectLiteralAccessor(accessor: GetAccessorDeclaration | SetAccessorDeclaration, name: PropertyName, context: SyntacticTypeNodeBuilderContext) {
|
||||
const allAccessors = resolver.getAllAccessorDeclarations(accessor);
|
||||
const getAccessorType = allAccessors.getAccessor && getTypeAnnotationFromAccessor(allAccessors.getAccessor);
|
||||
const setAccessorType = allAccessors.setAccessor && getTypeAnnotationFromAccessor(allAccessors.setAccessor);
|
||||
// We have types for both accessors, we can't know if they are the same type so we keep both accessors
|
||||
if (getAccessorType !== undefined && setAccessorType !== undefined) {
|
||||
const parameters = accessor.parameters.every(p => ensureParameter(p, context));
|
||||
|
||||
if (isGetAccessor(accessor)) {
|
||||
return parameters && serializeExistingTypeAnnotation(getAccessorType);
|
||||
}
|
||||
else {
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
else if (allAccessors.firstAccessor === accessor) {
|
||||
const foundType = getAccessorType ?? setAccessorType;
|
||||
const propertyType = foundType ? serializeExistingTypeAnnotation(foundType) : inferAccessorType(accessor, allAccessors, context);
|
||||
|
||||
return propertyType;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function typeFromPrimitiveLiteral() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function canAddUndefined(node: TypeNode): boolean {
|
||||
if (!strictNullChecks) return true;
|
||||
if (
|
||||
isKeyword(node.kind)
|
||||
|| node.kind === SyntaxKind.LiteralType
|
||||
|| node.kind === SyntaxKind.FunctionType
|
||||
|| node.kind === SyntaxKind.ConstructorType
|
||||
|| node.kind === SyntaxKind.ArrayType
|
||||
|| node.kind === SyntaxKind.TupleType
|
||||
|| node.kind === SyntaxKind.TypeLiteral
|
||||
|| node.kind === SyntaxKind.TemplateLiteralType
|
||||
|| node.kind === SyntaxKind.ThisType
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (node.kind === SyntaxKind.ParenthesizedType) {
|
||||
return canAddUndefined((node as ParenthesizedTypeNode).type);
|
||||
}
|
||||
if (node.kind === SyntaxKind.UnionType || node.kind === SyntaxKind.IntersectionType) {
|
||||
return (node as UnionTypeNode | IntersectionTypeNode).types.every(canAddUndefined);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function createReturnFromSignature(fn: SignatureDeclaration | JSDocSignature, context: SyntacticTypeNodeBuilderContext) {
|
||||
let returnType;
|
||||
const returnTypeNode = getEffectiveReturnTypeNode(fn);
|
||||
if (returnTypeNode) {
|
||||
returnType = serializeExistingTypeAnnotation(returnTypeNode);
|
||||
}
|
||||
if (!returnType && isValueSignatureDeclaration(fn)) {
|
||||
returnType = typeFromSingleReturnExpression(fn, context);
|
||||
}
|
||||
return returnType ?? inferReturnTypeOfSignatureSignature(fn, context);
|
||||
}
|
||||
|
||||
function typeFromSingleReturnExpression(declaration: FunctionLikeDeclaration | undefined, context: SyntacticTypeNodeBuilderContext): boolean | undefined {
|
||||
let candidateExpr: Expression | undefined;
|
||||
if (declaration && !nodeIsMissing(declaration.body)) {
|
||||
const body = declaration.body;
|
||||
if (body && isBlock(body)) {
|
||||
forEachReturnStatement(body, s => {
|
||||
if (!candidateExpr) {
|
||||
candidateExpr = s.expression;
|
||||
}
|
||||
else {
|
||||
candidateExpr = undefined;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
candidateExpr = body;
|
||||
}
|
||||
}
|
||||
if (candidateExpr) {
|
||||
return typeFromExpression(candidateExpr, context);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,20 @@
|
||||
import { Node } from "../_namespaces/ts";
|
||||
import {
|
||||
emptyArray,
|
||||
isNodeKind,
|
||||
Node,
|
||||
} from "../_namespaces/ts";
|
||||
|
||||
const nodeChildren = new WeakMap<Node, Node[] | undefined>();
|
||||
const nodeChildren = new WeakMap<Node, readonly Node[] | undefined>();
|
||||
|
||||
/** @internal */
|
||||
export function getNodeChildren(node: Node): Node[] | undefined {
|
||||
export function getNodeChildren(node: Node): readonly Node[] | undefined {
|
||||
if (!isNodeKind(node.kind)) return emptyArray;
|
||||
|
||||
return nodeChildren.get(node);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function setNodeChildren(node: Node, children: Node[]): Node[] {
|
||||
export function setNodeChildren(node: Node, children: readonly Node[]): readonly Node[] {
|
||||
nodeChildren.set(node, children);
|
||||
return children;
|
||||
}
|
||||
|
||||
@@ -6209,7 +6209,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
|
||||
}
|
||||
|
||||
// @api
|
||||
function createSyntaxList(children: Node[]) {
|
||||
function createSyntaxList(children: readonly Node[]) {
|
||||
const node = createBaseNode<SyntaxList>(SyntaxKind.SyntaxList);
|
||||
setNodeChildren(node, children);
|
||||
return node;
|
||||
|
||||
@@ -53,10 +53,12 @@ import {
|
||||
getAllAccessorDeclarations,
|
||||
getEmitFlags,
|
||||
getEmitHelpers,
|
||||
getEmitModuleFormatOfFileWorker,
|
||||
getEmitModuleKind,
|
||||
getESModuleInterop,
|
||||
getExternalModuleName,
|
||||
getExternalModuleNameFromPath,
|
||||
getImpliedNodeFormatForEmitWorker,
|
||||
getJSDocType,
|
||||
getJSDocTypeTag,
|
||||
getModifiers,
|
||||
@@ -712,7 +714,7 @@ export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: Node
|
||||
if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) {
|
||||
let namedBindings: NamedImportBindings | undefined;
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
if ((moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) || sourceFile.impliedNodeFormat === ModuleKind.ESNext) {
|
||||
if ((moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) || getImpliedNodeFormatForEmitWorker(sourceFile, compilerOptions) === ModuleKind.ESNext) {
|
||||
// use named imports
|
||||
const helpers = getEmitHelpers(sourceFile);
|
||||
if (helpers) {
|
||||
@@ -769,10 +771,8 @@ export function getOrCreateExternalHelpersModuleNameIfNeeded(factory: NodeFactor
|
||||
return externalHelpersModuleName;
|
||||
}
|
||||
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
let create = (hasExportStarsToExportValues || (getESModuleInterop(compilerOptions) && hasImportStarOrImportDefault))
|
||||
&& moduleKind !== ModuleKind.System
|
||||
&& (moduleKind < ModuleKind.ES2015 || node.impliedNodeFormat === ModuleKind.CommonJS);
|
||||
&& getEmitModuleFormatOfFileWorker(node, compilerOptions) < ModuleKind.System;
|
||||
if (!create) {
|
||||
const helpers = getEmitHelpers(node);
|
||||
if (helpers) {
|
||||
|
||||
@@ -342,12 +342,14 @@ export interface PackageJsonPathFields {
|
||||
imports?: object;
|
||||
exports?: object;
|
||||
name?: string;
|
||||
dependencies?: MapLike<string>;
|
||||
peerDependencies?: MapLike<string>;
|
||||
optionalDependencies?: MapLike<string>;
|
||||
}
|
||||
|
||||
interface PackageJson extends PackageJsonPathFields {
|
||||
name?: string;
|
||||
version?: string;
|
||||
peerDependencies?: MapLike<string>;
|
||||
}
|
||||
|
||||
function readPackageJsonField<K extends MatchingKeys<PackageJson, string | undefined>>(jsonContent: PackageJson, fieldName: K, typeOfTag: "string", state: ModuleResolutionState): PackageJson[K] | undefined;
|
||||
@@ -360,9 +362,9 @@ function readPackageJsonField<K extends keyof PackageJson>(jsonContent: PackageJ
|
||||
return;
|
||||
}
|
||||
const value = jsonContent[fieldName];
|
||||
if (typeof value !== typeOfTag || value === null) { // eslint-disable-line no-null/no-null
|
||||
if (typeof value !== typeOfTag || value === null) { // eslint-disable-line no-restricted-syntax
|
||||
if (state.traceEnabled) {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_1_got_2, fieldName, typeOfTag, value === null ? "null" : typeof value);
|
||||
}
|
||||
return;
|
||||
@@ -822,7 +824,7 @@ export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: M
|
||||
const packageJsonPath = combinePaths(root, normalized, "package.json");
|
||||
// `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types.
|
||||
// See `createNotNeededPackageJSON` in the types-publisher` repo.
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const isNotNeededPackage = host.fileExists(packageJsonPath) && (readJson(packageJsonPath, host) as PackageJson).typings === null;
|
||||
if (!isNotNeededPackage) {
|
||||
const baseFileName = getBaseFileName(normalized);
|
||||
@@ -934,7 +936,7 @@ export interface PackageJsonInfoCache {
|
||||
export type PerModuleNameCache = PerNonRelativeNameCache<ResolvedModuleWithFailedLookupLocations>;
|
||||
|
||||
function compilerOptionValueToString(value: unknown): string {
|
||||
if (value === null || typeof value !== "object") { // eslint-disable-line no-null/no-null
|
||||
if (value === null || typeof value !== "object") { // eslint-disable-line no-restricted-syntax
|
||||
return "" + value;
|
||||
}
|
||||
if (isArray(value)) {
|
||||
@@ -2276,7 +2278,7 @@ function loadEntrypointsFromExportMap(
|
||||
loadEntrypointsFromTargetExports(target);
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
else if (typeof exports === "object" && exports !== null && allKeysStartWithDot(exports as MapLike<unknown>)) {
|
||||
for (const key in exports) {
|
||||
loadEntrypointsFromTargetExports((exports as MapLike<unknown>)[key]);
|
||||
@@ -2331,7 +2333,7 @@ function loadEntrypointsFromExportMap(
|
||||
}
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
else if (typeof target === "object" && target !== null) {
|
||||
return forEach(getOwnKeys(target as MapLike<unknown>), key => {
|
||||
if (key === "default" || contains(state.conditions, key) || isApplicableVersionedTypesKey(state.conditions, key)) {
|
||||
@@ -2703,7 +2705,7 @@ function loadModuleFromImportsOrExports(extensions: Extensions, state: ModuleRes
|
||||
const target = (lookupTable as { [idx: string]: unknown; })[moduleName];
|
||||
return loadModuleFromTargetImportOrExport(target, /*subpath*/ "", /*pattern*/ false, moduleName);
|
||||
}
|
||||
const expandingKeys = sort(filter(getOwnKeys(lookupTable as MapLike<unknown>), k => k.includes("*") || endsWith(k, "/")), comparePatternKeys);
|
||||
const expandingKeys = sort(filter(getOwnKeys(lookupTable as MapLike<unknown>), k => hasOneAsterisk(k) || endsWith(k, "/")), comparePatternKeys);
|
||||
for (const potentialTarget of expandingKeys) {
|
||||
if (state.features & NodeResolutionFeatures.ExportsPatternTrailers && matchesPatternWithTrailer(potentialTarget, moduleName)) {
|
||||
const target = (lookupTable as { [idx: string]: unknown; })[potentialTarget];
|
||||
@@ -2731,6 +2733,11 @@ function loadModuleFromImportsOrExports(extensions: Extensions, state: ModuleRes
|
||||
}
|
||||
}
|
||||
|
||||
function hasOneAsterisk(patternKey: string): boolean {
|
||||
const firstStar = patternKey.indexOf("*");
|
||||
return firstStar !== -1 && firstStar === patternKey.lastIndexOf("*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the self-recursive function specialized to retrieving the targeted import/export element for the given resolution configuration
|
||||
*/
|
||||
@@ -2792,7 +2799,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
|
||||
if (inputLink) return inputLink;
|
||||
return toSearchResult(withPackageId(scope, loadFileNameFromPackageJsonField(extensions, finalPath, /*onlyRecordFailures*/ false, state), state));
|
||||
}
|
||||
else if (typeof target === "object" && target !== null) { // eslint-disable-line no-null/no-null
|
||||
else if (typeof target === "object" && target !== null) { // eslint-disable-line no-restricted-syntax
|
||||
if (!Array.isArray(target)) {
|
||||
traceIfEnabled(state, Diagnostics.Entering_conditional_exports);
|
||||
for (const condition of getOwnKeys(target as MapLike<unknown>)) {
|
||||
@@ -2831,7 +2838,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (target === null) { // eslint-disable-line no-null/no-null
|
||||
else if (target === null) { // eslint-disable-line no-restricted-syntax
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_scope_0_explicitly_maps_specifier_1_to_null, scope.packageDirectory, moduleName);
|
||||
}
|
||||
@@ -3087,7 +3094,7 @@ function loadModuleFromSpecificNodeModulesDirectory(extensions: Extensions, modu
|
||||
);
|
||||
if (
|
||||
!pathAndExtension && packageInfo
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
&& (packageInfo.contents.packageJsonContent.exports === undefined || packageInfo.contents.packageJsonContent.exports === null)
|
||||
&& state.features & NodeResolutionFeatures.EsmMode
|
||||
) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
comparePaths,
|
||||
Comparison,
|
||||
CompilerOptions,
|
||||
concatenate,
|
||||
containsIgnoredPath,
|
||||
containsPath,
|
||||
createGetCanonicalFileName,
|
||||
@@ -32,12 +33,13 @@ import {
|
||||
flatten,
|
||||
forEach,
|
||||
forEachAncestorDirectory,
|
||||
FutureSourceFile,
|
||||
getBaseFileName,
|
||||
GetCanonicalFileName,
|
||||
getConditions,
|
||||
getDefaultResolutionModeForFileWorker,
|
||||
getDirectoryPath,
|
||||
getEmitModuleResolutionKind,
|
||||
getModeForResolutionAtIndex,
|
||||
getModuleNameStringLiteralAt,
|
||||
getModuleSpecifierEndingPreference,
|
||||
getNodeModulePathParts,
|
||||
@@ -47,6 +49,7 @@ import {
|
||||
getOwnKeys,
|
||||
getPackageJsonTypesVersionsPaths,
|
||||
getPackageNameFromTypesPackageName,
|
||||
getPackageScopeForPath,
|
||||
getPathsBasePath,
|
||||
getRelativePathFromDirectory,
|
||||
getRelativePathToDirectoryOrUrl,
|
||||
@@ -54,6 +57,7 @@ import {
|
||||
getResolvePackageJsonImports,
|
||||
getSourceFileOfModule,
|
||||
getSupportedExtensions,
|
||||
getTemporaryModuleResolutionState,
|
||||
getTextOfIdentifierOrLiteral,
|
||||
hasJSFileExtension,
|
||||
hasTSFileExtension,
|
||||
@@ -65,6 +69,7 @@ import {
|
||||
isDeclarationFileName,
|
||||
isExternalModuleAugmentation,
|
||||
isExternalModuleNameRelative,
|
||||
isFullSourceFile,
|
||||
isMissingPackageJsonInfo,
|
||||
isModuleBlock,
|
||||
isModuleDeclaration,
|
||||
@@ -82,6 +87,7 @@ import {
|
||||
ModuleDeclaration,
|
||||
ModuleKind,
|
||||
ModulePath,
|
||||
ModuleResolutionHost,
|
||||
ModuleResolutionKind,
|
||||
ModuleSpecifierCache,
|
||||
ModuleSpecifierEnding,
|
||||
@@ -90,6 +96,7 @@ import {
|
||||
NodeFlags,
|
||||
NodeModulePathParts,
|
||||
normalizePath,
|
||||
PackageJsonPathFields,
|
||||
pathContainsNodeModules,
|
||||
pathIsBareSpecifier,
|
||||
pathIsRelative,
|
||||
@@ -100,6 +107,7 @@ import {
|
||||
removeTrailingDirectorySeparator,
|
||||
replaceFirstStar,
|
||||
ResolutionMode,
|
||||
resolveModuleName,
|
||||
resolvePath,
|
||||
ScriptKind,
|
||||
shouldAllowImportingTsExtension,
|
||||
@@ -134,14 +142,15 @@ export interface ModuleSpecifierPreferences {
|
||||
/**
|
||||
* @param syntaxImpliedNodeFormat Used when the import syntax implies ESM or CJS irrespective of the mode of the file.
|
||||
*/
|
||||
getAllowedEndingsInPreferredOrder(syntaxImpliedNodeFormat?: SourceFile["impliedNodeFormat"]): ModuleSpecifierEnding[];
|
||||
getAllowedEndingsInPreferredOrder(syntaxImpliedNodeFormat?: ResolutionMode): ModuleSpecifierEnding[];
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getModuleSpecifierPreferences(
|
||||
{ importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences,
|
||||
host: Pick<ModuleSpecifierResolutionHost, "getDefaultResolutionModeForFile">,
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
importingSourceFile: Pick<SourceFile, "fileName" | "impliedNodeFormat">,
|
||||
oldImportSpecifier?: string,
|
||||
): ModuleSpecifierPreferences {
|
||||
const filePreferredEnding = getPreferredEnding();
|
||||
@@ -154,8 +163,10 @@ export function getModuleSpecifierPreferences(
|
||||
importModuleSpecifierPreference === "project-relative" ? RelativePreference.ExternalNonRelative :
|
||||
RelativePreference.Shortest,
|
||||
getAllowedEndingsInPreferredOrder: syntaxImpliedNodeFormat => {
|
||||
const preferredEnding = syntaxImpliedNodeFormat !== importingSourceFile.impliedNodeFormat ? getPreferredEnding(syntaxImpliedNodeFormat) : filePreferredEnding;
|
||||
if ((syntaxImpliedNodeFormat ?? importingSourceFile.impliedNodeFormat) === ModuleKind.ESNext) {
|
||||
const impliedNodeFormat = getDefaultResolutionModeForFile(importingSourceFile, host, compilerOptions);
|
||||
const preferredEnding = syntaxImpliedNodeFormat !== impliedNodeFormat ? getPreferredEnding(syntaxImpliedNodeFormat) : filePreferredEnding;
|
||||
const moduleResolution = getEmitModuleResolutionKind(compilerOptions);
|
||||
if ((syntaxImpliedNodeFormat ?? impliedNodeFormat) === ModuleKind.ESNext && ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext) {
|
||||
if (shouldAllowImportingTsExtension(compilerOptions, importingSourceFile.fileName)) {
|
||||
return [ModuleSpecifierEnding.TsExtension, ModuleSpecifierEnding.JsExtension];
|
||||
}
|
||||
@@ -195,9 +206,9 @@ export function getModuleSpecifierPreferences(
|
||||
}
|
||||
return getModuleSpecifierEndingPreference(
|
||||
importModuleSpecifierEnding,
|
||||
resolutionMode ?? importingSourceFile.impliedNodeFormat,
|
||||
resolutionMode ?? getDefaultResolutionModeForFile(importingSourceFile, host, compilerOptions),
|
||||
compilerOptions,
|
||||
importingSourceFile,
|
||||
isFullSourceFile(importingSourceFile) ? importingSourceFile : undefined,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -216,7 +227,7 @@ export function updateModuleSpecifier(
|
||||
oldImportSpecifier: string,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
): string | undefined {
|
||||
const res = getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getModuleSpecifierPreferences({}, compilerOptions, importingSourceFile, oldImportSpecifier), {}, options);
|
||||
const res = getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getModuleSpecifierPreferences({}, host, compilerOptions, importingSourceFile, oldImportSpecifier), {}, options);
|
||||
if (res === oldImportSpecifier) return undefined;
|
||||
return res;
|
||||
}
|
||||
@@ -230,32 +241,32 @@ export function updateModuleSpecifier(
|
||||
/** @internal */
|
||||
export function getModuleSpecifier(
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
importingSourceFile: SourceFile | FutureSourceFile,
|
||||
importingSourceFileName: string,
|
||||
toFileName: string,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
): string {
|
||||
return getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getModuleSpecifierPreferences({}, compilerOptions, importingSourceFile), {}, options);
|
||||
return getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getModuleSpecifierPreferences({}, host, compilerOptions, importingSourceFile), {}, options);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getNodeModulesPackageName(
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
importingSourceFile: SourceFile | FutureSourceFile,
|
||||
nodeModulesFileName: string,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
preferences: UserPreferences,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
): string | undefined {
|
||||
const info = getInfo(importingSourceFile.fileName, host);
|
||||
const modulePaths = getAllModulePaths(info, nodeModulesFileName, host, preferences, options);
|
||||
const modulePaths = getAllModulePaths(info, nodeModulesFileName, host, preferences, compilerOptions, options);
|
||||
return firstDefined(modulePaths, modulePath => tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, preferences, /*packageNameOnly*/ true, options.overrideImportMode));
|
||||
}
|
||||
|
||||
function getModuleSpecifierWorker(
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
importingSourceFile: SourceFile | FutureSourceFile,
|
||||
importingSourceFileName: string,
|
||||
toFileName: string,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
@@ -264,15 +275,15 @@ function getModuleSpecifierWorker(
|
||||
options: ModuleSpecifierOptions = {},
|
||||
): string {
|
||||
const info = getInfo(importingSourceFileName, host);
|
||||
const modulePaths = getAllModulePaths(info, toFileName, host, userPreferences, options);
|
||||
const modulePaths = getAllModulePaths(info, toFileName, host, userPreferences, compilerOptions, options);
|
||||
return firstDefined(modulePaths, modulePath => tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode)) ||
|
||||
getLocalModuleSpecifier(toFileName, info, compilerOptions, host, options.overrideImportMode || importingSourceFile.impliedNodeFormat, preferences);
|
||||
getLocalModuleSpecifier(toFileName, info, compilerOptions, host, options.overrideImportMode || getDefaultResolutionModeForFile(importingSourceFile, host, compilerOptions), preferences);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function tryGetModuleSpecifiersFromCache(
|
||||
moduleSymbol: Symbol,
|
||||
importingSourceFile: SourceFile,
|
||||
importingSourceFile: SourceFile | FutureSourceFile,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
userPreferences: UserPreferences,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
@@ -288,7 +299,7 @@ export function tryGetModuleSpecifiersFromCache(
|
||||
|
||||
function tryGetModuleSpecifiersFromCacheWorker(
|
||||
moduleSymbol: Symbol,
|
||||
importingSourceFile: SourceFile,
|
||||
importingSourceFile: SourceFile | FutureSourceFile,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
userPreferences: UserPreferences,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
@@ -334,7 +345,7 @@ export function getModuleSpecifiersWithCacheInfo(
|
||||
moduleSymbol: Symbol,
|
||||
checker: TypeChecker,
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
importingSourceFile: SourceFile | FutureSourceFile,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
userPreferences: UserPreferences,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
@@ -356,7 +367,7 @@ export function getModuleSpecifiersWithCacheInfo(
|
||||
if (!moduleSourceFile) return { moduleSpecifiers: emptyArray, computedWithoutCache };
|
||||
|
||||
computedWithoutCache = true;
|
||||
modulePaths ||= getAllModulePathsWorker(getInfo(importingSourceFile.fileName, host), moduleSourceFile.originalFileName, host);
|
||||
modulePaths ||= getAllModulePathsWorker(getInfo(importingSourceFile.fileName, host), moduleSourceFile.originalFileName, host, compilerOptions, options);
|
||||
const result = computeModuleSpecifiers(
|
||||
modulePaths,
|
||||
compilerOptions,
|
||||
@@ -370,25 +381,49 @@ export function getModuleSpecifiersWithCacheInfo(
|
||||
return { moduleSpecifiers: result, computedWithoutCache };
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getLocalModuleSpecifierBetweenFileNames(
|
||||
importingFile: Pick<SourceFile, "fileName" | "impliedNodeFormat">,
|
||||
targetFileName: string,
|
||||
compilerOptions: CompilerOptions,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
): string {
|
||||
const info = getInfo(importingFile.fileName, host);
|
||||
const importMode = options.overrideImportMode ?? importingFile.impliedNodeFormat;
|
||||
return getLocalModuleSpecifier(
|
||||
targetFileName,
|
||||
info,
|
||||
compilerOptions,
|
||||
host,
|
||||
importMode,
|
||||
getModuleSpecifierPreferences({}, host, compilerOptions, importingFile),
|
||||
);
|
||||
}
|
||||
|
||||
function computeModuleSpecifiers(
|
||||
modulePaths: readonly ModulePath[],
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
importingSourceFile: SourceFile | FutureSourceFile,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
userPreferences: UserPreferences,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
forAutoImport: boolean,
|
||||
): readonly string[] {
|
||||
const info = getInfo(importingSourceFile.fileName, host);
|
||||
const preferences = getModuleSpecifierPreferences(userPreferences, compilerOptions, importingSourceFile);
|
||||
const existingSpecifier = forEach(modulePaths, modulePath =>
|
||||
const preferences = getModuleSpecifierPreferences(userPreferences, host, compilerOptions, importingSourceFile);
|
||||
const existingSpecifier = isFullSourceFile(importingSourceFile) && forEach(modulePaths, modulePath =>
|
||||
forEach(
|
||||
host.getFileIncludeReasons().get(toPath(modulePath.path, host.getCurrentDirectory(), info.getCanonicalFileName)),
|
||||
reason => {
|
||||
if (reason.kind !== FileIncludeKind.Import || reason.file !== importingSourceFile.path) return undefined;
|
||||
// If the candidate import mode doesn't match the mode we're generating for, don't consider it
|
||||
// TODO: maybe useful to keep around as an alternative option for certain contexts where the mode is overridable
|
||||
if (importingSourceFile.impliedNodeFormat && importingSourceFile.impliedNodeFormat !== getModeForResolutionAtIndex(importingSourceFile, reason.index, compilerOptions)) return undefined;
|
||||
const existingMode = host.getModeForResolutionAtIndex(importingSourceFile, reason.index);
|
||||
const targetMode = options.overrideImportMode ?? host.getDefaultResolutionModeForFile(importingSourceFile);
|
||||
if (existingMode !== targetMode && existingMode !== undefined && targetMode !== undefined) {
|
||||
return undefined;
|
||||
}
|
||||
const specifier = getModuleNameStringLiteralAt(importingSourceFile, reason.index).text;
|
||||
// If the preference is for non relative and the module specifier is relative, ignore it
|
||||
return preferences.relativePreference !== RelativePreference.NonRelative || !pathIsRelative(specifier) ?
|
||||
@@ -662,6 +697,7 @@ function getAllModulePaths(
|
||||
importedFileName: string,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
preferences: UserPreferences,
|
||||
compilerOptions: CompilerOptions,
|
||||
options: ModuleSpecifierOptions = {},
|
||||
) {
|
||||
const importingFilePath = toPath(info.importingSourceFileName, host.getCurrentDirectory(), hostGetCanonicalFileName(host));
|
||||
@@ -671,14 +707,45 @@ function getAllModulePaths(
|
||||
const cached = cache.get(importingFilePath, importedFilePath, preferences, options);
|
||||
if (cached?.modulePaths) return cached.modulePaths;
|
||||
}
|
||||
const modulePaths = getAllModulePathsWorker(info, importedFileName, host);
|
||||
const modulePaths = getAllModulePathsWorker(info, importedFileName, host, compilerOptions, options);
|
||||
if (cache) {
|
||||
cache.setModulePaths(importingFilePath, importedFilePath, preferences, options, modulePaths);
|
||||
}
|
||||
return modulePaths;
|
||||
}
|
||||
|
||||
function getAllModulePathsWorker(info: Info, importedFileName: string, host: ModuleSpecifierResolutionHost): readonly ModulePath[] {
|
||||
const runtimeDependencyFields = ["dependencies", "peerDependencies", "optionalDependencies"] as const;
|
||||
|
||||
function getAllRuntimeDependencies(packageJson: PackageJsonPathFields) {
|
||||
let result;
|
||||
for (const field of runtimeDependencyFields) {
|
||||
const deps = packageJson[field];
|
||||
if (deps && typeof deps === "object") {
|
||||
result = concatenate(result, getOwnKeys(deps));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getAllModulePathsWorker(info: Info, importedFileName: string, host: ModuleSpecifierResolutionHost, compilerOptions: CompilerOptions, options: ModuleSpecifierOptions): readonly ModulePath[] {
|
||||
const cache = host.getModuleResolutionCache?.();
|
||||
const links = host.getSymlinkCache?.();
|
||||
if (cache && links && host.readFile && !pathContainsNodeModules(info.importingSourceFileName)) {
|
||||
Debug.type<ModuleResolutionHost>(host);
|
||||
// Cache resolutions for all `dependencies` of the `package.json` context of the input file.
|
||||
// This should populate all the relevant symlinks in the symlink cache, and most, if not all, of these resolutions
|
||||
// should get (re)used.
|
||||
const state = getTemporaryModuleResolutionState(cache.getPackageJsonInfoCache(), host, {});
|
||||
const packageJson = getPackageScopeForPath(info.importingSourceFileName, state);
|
||||
if (packageJson) {
|
||||
const toResolve = getAllRuntimeDependencies(packageJson.contents.packageJsonContent);
|
||||
for (const depName of (toResolve || emptyArray)) {
|
||||
const resolved = resolveModuleName(depName, combinePaths(packageJson.packageDirectory, "package.json"), compilerOptions, host, cache, /*redirectedReference*/ undefined, options.overrideImportMode);
|
||||
links.setSymlinksFromResolution(resolved.resolvedModule);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const allFileNames = new Map<string, { path: string; isRedirect: boolean; isInNodeModules: boolean; }>();
|
||||
let importedFileFromNodeModules = false;
|
||||
forEachFileNameOfModule(
|
||||
@@ -935,7 +1002,7 @@ function tryGetModuleNameFromExportsOrImports(options: CompilerOptions, host: Mo
|
||||
else if (Array.isArray(exports)) {
|
||||
return forEach(exports, e => tryGetModuleNameFromExportsOrImports(options, host, targetFilePath, packageDirectory, packageName, e, conditions, mode, isImports));
|
||||
}
|
||||
else if (typeof exports === "object" && exports !== null) { // eslint-disable-line no-null/no-null
|
||||
else if (typeof exports === "object" && exports !== null) { // eslint-disable-line no-restricted-syntax
|
||||
// conditional mapping
|
||||
for (const key of getOwnKeys(exports as MapLike<unknown>)) {
|
||||
if (key === "default" || conditions.indexOf(key) >= 0 || isApplicableVersionedTypesKey(conditions, key)) {
|
||||
@@ -951,7 +1018,7 @@ function tryGetModuleNameFromExportsOrImports(options: CompilerOptions, host: Mo
|
||||
}
|
||||
|
||||
function tryGetModuleNameFromExports(options: CompilerOptions, host: ModuleSpecifierResolutionHost, targetFilePath: string, packageDirectory: string, packageName: string, exports: unknown, conditions: string[]): { moduleFileToTry: string; } | undefined {
|
||||
if (typeof exports === "object" && exports !== null && !Array.isArray(exports) && allKeysStartWithDot(exports as MapLike<unknown>)) { // eslint-disable-line no-null/no-null
|
||||
if (typeof exports === "object" && exports !== null && !Array.isArray(exports) && allKeysStartWithDot(exports as MapLike<unknown>)) { // eslint-disable-line no-restricted-syntax
|
||||
// sub-mappings
|
||||
// 3 cases:
|
||||
// * directory mappings (legacyish, key ends with / (technically allows index/extension resolution under cjs mode))
|
||||
@@ -1014,7 +1081,7 @@ function tryGetModuleNameFromRootDirs(rootDirs: readonly string[], moduleFileNam
|
||||
return processEnding(shortest, allowedEndings, compilerOptions);
|
||||
}
|
||||
|
||||
function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCanonicalFileName, canonicalSourceDirectory }: Info, importingSourceFile: SourceFile, host: ModuleSpecifierResolutionHost, options: CompilerOptions, userPreferences: UserPreferences, packageNameOnly?: boolean, overrideMode?: ResolutionMode): string | undefined {
|
||||
function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCanonicalFileName, canonicalSourceDirectory }: Info, importingSourceFile: SourceFile | FutureSourceFile, host: ModuleSpecifierResolutionHost, options: CompilerOptions, userPreferences: UserPreferences, packageNameOnly?: boolean, overrideMode?: ResolutionMode): string | undefined {
|
||||
if (!host.fileExists || !host.readFile) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1025,7 +1092,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan
|
||||
|
||||
// Simplify the full file path to something that can be resolved by Node.
|
||||
|
||||
const preferences = getModuleSpecifierPreferences(userPreferences, options, importingSourceFile);
|
||||
const preferences = getModuleSpecifierPreferences(userPreferences, host, options, importingSourceFile);
|
||||
const allowedEndings = preferences.getAllowedEndingsInPreferredOrder();
|
||||
let moduleSpecifier = path;
|
||||
let isPackageRootPath = false;
|
||||
@@ -1085,7 +1152,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan
|
||||
const cachedPackageJson = host.getPackageJsonInfoCache?.()?.getPackageJsonInfo(packageJsonPath);
|
||||
if (isPackageJsonInfo(cachedPackageJson) || cachedPackageJson === undefined && host.fileExists(packageJsonPath)) {
|
||||
const packageJsonContent: Record<string, any> | undefined = cachedPackageJson?.contents.packageJsonContent || tryParseJson(host.readFile!(packageJsonPath)!);
|
||||
const importMode = overrideMode || importingSourceFile.impliedNodeFormat;
|
||||
const importMode = overrideMode || getDefaultResolutionModeForFile(importingSourceFile, host, options);
|
||||
if (getResolvePackageJsonExports(options)) {
|
||||
// The package name that we found in node_modules could be different from the package
|
||||
// name in the package.json content via url/filepath dependency specifiers. We need to
|
||||
@@ -1280,3 +1347,7 @@ function getRelativePathIfInSameVolume(path: string, directoryPath: string, getC
|
||||
function isPathRelativeToParent(path: string): boolean {
|
||||
return startsWith(path, "..");
|
||||
}
|
||||
|
||||
function getDefaultResolutionModeForFile(file: Pick<SourceFile, "fileName" | "impliedNodeFormat" | "packageJsonScope">, host: Pick<ModuleSpecifierResolutionHost, "getDefaultResolutionModeForFile">, compilerOptions: CompilerOptions) {
|
||||
return isFullSourceFile(file) ? host.getDefaultResolutionModeForFile(file) : getDefaultResolutionModeForFileWorker(file, compilerOptions);
|
||||
}
|
||||
|
||||
+54
-45
@@ -62,6 +62,7 @@ import {
|
||||
DeleteExpression,
|
||||
Diagnostic,
|
||||
DiagnosticArguments,
|
||||
DiagnosticCategory,
|
||||
DiagnosticMessage,
|
||||
Diagnostics,
|
||||
DiagnosticWithDetachedLocation,
|
||||
@@ -113,6 +114,7 @@ import {
|
||||
HasModifiers,
|
||||
HeritageClause,
|
||||
Identifier,
|
||||
identity,
|
||||
idText,
|
||||
IfStatement,
|
||||
ImportAttribute,
|
||||
@@ -318,7 +320,6 @@ import {
|
||||
QuestionToken,
|
||||
ReadonlyKeyword,
|
||||
ReadonlyPragmaMap,
|
||||
ReadonlyTextRange,
|
||||
ResolutionMode,
|
||||
RestTypeNode,
|
||||
ReturnStatement,
|
||||
@@ -1950,7 +1951,7 @@ namespace Parser {
|
||||
function currentNode(position: number) {
|
||||
const node = baseSyntaxCursor.currentNode(position);
|
||||
if (topLevel && node && containsPossibleTopLevelAwait(node)) {
|
||||
node.intersectsChange = true;
|
||||
markAsIntersectingIncrementalChange(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
@@ -2143,7 +2144,11 @@ namespace Parser {
|
||||
// Don't report another error if it would just be at the same position as the last error.
|
||||
const lastError = lastOrUndefined(parseDiagnostics);
|
||||
let result: DiagnosticWithDetachedLocation | undefined;
|
||||
if (!lastError || start !== lastError.start) {
|
||||
if (message.category === DiagnosticCategory.Message && lastError && start === lastError.start && length === lastError.length) {
|
||||
result = createDetachedDiagnostic(fileName, sourceText, start, length, message, ...args);
|
||||
addRelatedInfo(lastError, result);
|
||||
}
|
||||
else if (!lastError || start !== lastError.start) {
|
||||
result = createDetachedDiagnostic(fileName, sourceText, start, length, message, ...args);
|
||||
parseDiagnostics.push(result);
|
||||
}
|
||||
@@ -2399,7 +2404,7 @@ namespace Parser {
|
||||
}
|
||||
|
||||
// The user alternatively might have misspelled or forgotten to add a space after a common keyword.
|
||||
const suggestion = getSpellingSuggestion(expressionText, viableKeywordSuggestions, n => n) ?? getSpaceSuggestion(expressionText);
|
||||
const suggestion = getSpellingSuggestion(expressionText, viableKeywordSuggestions, identity) ?? getSpaceSuggestion(expressionText);
|
||||
if (suggestion) {
|
||||
parseErrorAt(pos, node.end, Diagnostics.Unknown_keyword_or_identifier_Did_you_mean_0, suggestion);
|
||||
return;
|
||||
@@ -3120,7 +3125,7 @@ namespace Parser {
|
||||
// Can't reuse a node that intersected the change range.
|
||||
// Can't reuse a node that contains a parse error. This is necessary so that we
|
||||
// produce the same set of errors again.
|
||||
if (nodeIsMissing(node) || node.intersectsChange || containsParseError(node)) {
|
||||
if (nodeIsMissing(node) || intersectsIncrementalChange(node) || containsParseError(node)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -9844,6 +9849,25 @@ namespace Parser {
|
||||
}
|
||||
}
|
||||
|
||||
const incrementallyParsedFiles = new WeakSet<SourceFile>();
|
||||
|
||||
function markAsIncrementallyParsed(sourceFile: SourceFile) {
|
||||
if (incrementallyParsedFiles.has(sourceFile)) {
|
||||
Debug.fail("Source file has already been incrementally parsed");
|
||||
}
|
||||
incrementallyParsedFiles.add(sourceFile);
|
||||
}
|
||||
|
||||
const intersectingChangeSet = new WeakSet<Node | NodeArray<Node>>();
|
||||
|
||||
function intersectsIncrementalChange(node: Node | NodeArray<Node>): boolean {
|
||||
return intersectingChangeSet.has(node);
|
||||
}
|
||||
|
||||
function markAsIntersectingIncrementalChange(node: Node | NodeArray<Node>) {
|
||||
intersectingChangeSet.add(node);
|
||||
}
|
||||
|
||||
namespace IncrementalParser {
|
||||
export function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks: boolean): SourceFile {
|
||||
aggressiveChecks = aggressiveChecks || Debug.shouldAssert(AssertionLevel.Aggressive);
|
||||
@@ -9866,10 +9890,8 @@ namespace IncrementalParser {
|
||||
// This is because we do incremental parsing in-place. i.e. we take nodes from the old
|
||||
// tree and give them new positions and parents. From that point on, trusting the old
|
||||
// tree at all is not possible as far too much of it may violate invariants.
|
||||
const incrementalSourceFile = sourceFile as Node as IncrementalNode;
|
||||
Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed);
|
||||
incrementalSourceFile.hasBeenIncrementallyParsed = true;
|
||||
Parser.fixupParentReferences(incrementalSourceFile);
|
||||
markAsIncrementallyParsed(sourceFile);
|
||||
Parser.fixupParentReferences(sourceFile);
|
||||
const oldText = sourceFile.text;
|
||||
const syntaxCursor = createSyntaxCursor(sourceFile);
|
||||
|
||||
@@ -9908,7 +9930,7 @@ namespace IncrementalParser {
|
||||
//
|
||||
// Also, mark any syntax elements that intersect the changed span. We know, up front,
|
||||
// that we cannot reuse these elements.
|
||||
updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, textSpanEnd(changeRange.span), textSpanEnd(textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
|
||||
updateTokenPositionsAndMarkElements(sourceFile, changeRange.span.start, textSpanEnd(changeRange.span), textSpanEnd(textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks);
|
||||
|
||||
// Now that we've set up our internal incremental state just proceed and parse the
|
||||
// source file in the normal fashion. When possible the parser will retrieve and
|
||||
@@ -9984,18 +10006,18 @@ namespace IncrementalParser {
|
||||
}
|
||||
}
|
||||
|
||||
function moveElementEntirelyPastChangeRange(element: IncrementalNode, isArray: false, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void;
|
||||
function moveElementEntirelyPastChangeRange(element: IncrementalNodeArray, isArray: true, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void;
|
||||
function moveElementEntirelyPastChangeRange(element: IncrementalNode | IncrementalNodeArray, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) {
|
||||
function moveElementEntirelyPastChangeRange(element: Node, isArray: false, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void;
|
||||
function moveElementEntirelyPastChangeRange(element: NodeArray<Node>, isArray: true, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void;
|
||||
function moveElementEntirelyPastChangeRange(element: Node | NodeArray<Node>, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) {
|
||||
if (isArray) {
|
||||
visitArray(element as IncrementalNodeArray);
|
||||
visitArray(element as NodeArray<Node>);
|
||||
}
|
||||
else {
|
||||
visitNode(element as IncrementalNode);
|
||||
visitNode(element as Node);
|
||||
}
|
||||
return;
|
||||
|
||||
function visitNode(node: IncrementalNode) {
|
||||
function visitNode(node: Node) {
|
||||
let text = "";
|
||||
if (aggressiveChecks && shouldCheckNode(node)) {
|
||||
text = oldText.substring(node.pos, node.end);
|
||||
@@ -10014,13 +10036,13 @@ namespace IncrementalParser {
|
||||
forEachChild(node, visitNode as (node: Node) => void, visitArray as (nodes: NodeArray<Node>) => void);
|
||||
if (hasJSDocNodes(node)) {
|
||||
for (const jsDocComment of node.jsDoc!) {
|
||||
visitNode(jsDocComment as Node as IncrementalNode);
|
||||
visitNode(jsDocComment);
|
||||
}
|
||||
}
|
||||
checkNodePositions(node, aggressiveChecks);
|
||||
}
|
||||
|
||||
function visitArray(array: IncrementalNodeArray) {
|
||||
function visitArray(array: NodeArray<Node>) {
|
||||
setTextRangePosEnd(array, array.pos + delta, array.end + delta);
|
||||
|
||||
for (const node of array) {
|
||||
@@ -10040,7 +10062,7 @@ namespace IncrementalParser {
|
||||
return false;
|
||||
}
|
||||
|
||||
function adjustIntersectingElement(element: IncrementalElement, changeStart: number, changeRangeOldEnd: number, changeRangeNewEnd: number, delta: number) {
|
||||
function adjustIntersectingElement(element: Node | NodeArray<Node>, changeStart: number, changeRangeOldEnd: number, changeRangeNewEnd: number, delta: number) {
|
||||
Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range");
|
||||
Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range");
|
||||
Debug.assert(element.pos <= element.end);
|
||||
@@ -10106,9 +10128,10 @@ namespace IncrementalParser {
|
||||
Math.min(element.end, changeRangeNewEnd);
|
||||
|
||||
Debug.assert(pos <= end);
|
||||
if (element.parent) {
|
||||
Debug.assertGreaterThanOrEqual(pos, element.parent.pos);
|
||||
Debug.assertLessThanOrEqual(end, element.parent.end);
|
||||
if ((element as any).parent) {
|
||||
const parent = (element as any).parent as Node;
|
||||
Debug.assertGreaterThanOrEqual(pos, parent.pos);
|
||||
Debug.assertLessThanOrEqual(end, parent.end);
|
||||
}
|
||||
|
||||
setTextRangePosEnd(element, pos, end);
|
||||
@@ -10132,7 +10155,7 @@ namespace IncrementalParser {
|
||||
}
|
||||
|
||||
function updateTokenPositionsAndMarkElements(
|
||||
sourceFile: IncrementalNode,
|
||||
sourceFile: SourceFile,
|
||||
changeStart: number,
|
||||
changeRangeOldEnd: number,
|
||||
changeRangeNewEnd: number,
|
||||
@@ -10144,7 +10167,7 @@ namespace IncrementalParser {
|
||||
visitNode(sourceFile);
|
||||
return;
|
||||
|
||||
function visitNode(child: IncrementalNode) {
|
||||
function visitNode(child: Node) {
|
||||
Debug.assert(child.pos <= child.end);
|
||||
if (child.pos > changeRangeOldEnd) {
|
||||
// Node is entirely past the change range. We need to move both its pos and
|
||||
@@ -10158,7 +10181,7 @@ namespace IncrementalParser {
|
||||
// be able to use.
|
||||
const fullEnd = child.end;
|
||||
if (fullEnd >= changeStart) {
|
||||
child.intersectsChange = true;
|
||||
markAsIntersectingIncrementalChange(child);
|
||||
unsetNodeChildren(child);
|
||||
|
||||
// Adjust the pos or end (or both) of the intersecting element accordingly.
|
||||
@@ -10166,7 +10189,7 @@ namespace IncrementalParser {
|
||||
forEachChild(child, visitNode as (node: Node) => void, visitArray as (nodes: NodeArray<Node>) => void);
|
||||
if (hasJSDocNodes(child)) {
|
||||
for (const jsDocComment of child.jsDoc!) {
|
||||
visitNode(jsDocComment as Node as IncrementalNode);
|
||||
visitNode(jsDocComment);
|
||||
}
|
||||
}
|
||||
checkNodePositions(child, aggressiveChecks);
|
||||
@@ -10177,7 +10200,7 @@ namespace IncrementalParser {
|
||||
Debug.assert(fullEnd < changeStart);
|
||||
}
|
||||
|
||||
function visitArray(array: IncrementalNodeArray) {
|
||||
function visitArray(array: NodeArray<Node>) {
|
||||
Debug.assert(array.pos <= array.end);
|
||||
if (array.pos > changeRangeOldEnd) {
|
||||
// Array is entirely after the change range. We need to move it, and move any of
|
||||
@@ -10191,7 +10214,7 @@ namespace IncrementalParser {
|
||||
// be able to use.
|
||||
const fullEnd = array.end;
|
||||
if (fullEnd >= changeStart) {
|
||||
array.intersectsChange = true;
|
||||
markAsIntersectingIncrementalChange(array);
|
||||
|
||||
// Adjust the pos or end (or both) of the intersecting array accordingly.
|
||||
adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
|
||||
@@ -10340,25 +10363,11 @@ namespace IncrementalParser {
|
||||
}
|
||||
}
|
||||
|
||||
interface IncrementalElement extends ReadonlyTextRange {
|
||||
readonly parent: Node;
|
||||
intersectsChange: boolean;
|
||||
length?: number;
|
||||
}
|
||||
|
||||
export interface IncrementalNode extends Node, IncrementalElement {
|
||||
hasBeenIncrementallyParsed: boolean;
|
||||
}
|
||||
|
||||
interface IncrementalNodeArray extends NodeArray<IncrementalNode>, IncrementalElement {
|
||||
length: number;
|
||||
}
|
||||
|
||||
// Allows finding nodes in the source file at a certain position in an efficient manner.
|
||||
// The implementation takes advantage of the calling pattern it knows the parser will
|
||||
// make in order to optimize finding nodes as quickly as possible.
|
||||
export interface SyntaxCursor {
|
||||
currentNode(position: number): IncrementalNode;
|
||||
currentNode(position: number): Node;
|
||||
}
|
||||
|
||||
export function createSyntaxCursor(sourceFile: SourceFile): SyntaxCursor {
|
||||
@@ -10400,7 +10409,7 @@ namespace IncrementalParser {
|
||||
|
||||
// Either we don'd have a node, or we have a node at the position being asked for.
|
||||
Debug.assert(!current || current.pos === position);
|
||||
return current as IncrementalNode;
|
||||
return current;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -10672,7 +10681,7 @@ function extractPragmas(pragmas: PragmaPseudoMapEntry[], range: CommentRange, te
|
||||
|
||||
if (range.kind === SyntaxKind.MultiLineCommentTrivia) {
|
||||
const multiLinePragmaRegEx = /@(\S+)(\s+.*)?$/gim; // Defined inline since it uses the "g" flag, which keeps a persistent index (for iterating)
|
||||
let multiLineMatch: RegExpExecArray | null;
|
||||
let multiLineMatch: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax
|
||||
while (multiLineMatch = multiLinePragmaRegEx.exec(text)) {
|
||||
addPragmaForMatch(pragmas, range, PragmaKindFlags.MultiLine, multiLineMatch);
|
||||
}
|
||||
|
||||
+199
-49
@@ -126,6 +126,7 @@ import {
|
||||
getLineStarts,
|
||||
getMatchedFileSpec,
|
||||
getMatchedIncludeSpec,
|
||||
getNameOfScriptTarget,
|
||||
getNewLineCharacter,
|
||||
getNormalizedAbsolutePath,
|
||||
getNormalizedAbsolutePathWithoutRoot,
|
||||
@@ -168,6 +169,7 @@ import {
|
||||
ImportClause,
|
||||
ImportDeclaration,
|
||||
ImportOrExportSpecifier,
|
||||
importSyntaxAffectsModuleResolution,
|
||||
InternalEmitFlags,
|
||||
inverseJsxOptionMap,
|
||||
isAmbientModule,
|
||||
@@ -306,12 +308,12 @@ import {
|
||||
SyntaxKind,
|
||||
sys,
|
||||
System,
|
||||
targetOptionDeclaration,
|
||||
toFileNameLowerCase,
|
||||
tokenToString,
|
||||
toPath as ts_toPath,
|
||||
trace,
|
||||
tracing,
|
||||
tryCast,
|
||||
TsConfigSourceFile,
|
||||
TypeChecker,
|
||||
typeDirectiveIsEqualTo,
|
||||
@@ -834,9 +836,11 @@ export function flattenDiagnosticMessageText(diag: string | DiagnosticMessageCha
|
||||
* @internal
|
||||
*/
|
||||
export interface SourceFileImportsList {
|
||||
/** @internal */ imports: SourceFile["imports"];
|
||||
/** @internal */ moduleAugmentations: SourceFile["moduleAugmentations"];
|
||||
imports: SourceFile["imports"];
|
||||
moduleAugmentations: SourceFile["moduleAugmentations"];
|
||||
impliedNodeFormat?: ResolutionMode;
|
||||
fileName: string;
|
||||
packageJsonScope?: SourceFile["packageJsonScope"];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -882,22 +886,47 @@ export function isExclusivelyTypeOnlyImportOrExport(decl: ImportDeclaration | Ex
|
||||
|
||||
/**
|
||||
* Use `program.getModeForUsageLocation`, which retrieves the correct `compilerOptions`, instead of this function whenever possible.
|
||||
* Calculates the final resolution mode for a given module reference node. This is the resolution mode explicitly provided via import
|
||||
* attributes, if present, or the syntax the usage would have if emitted to JavaScript. In `--module node16` or `nodenext`, this may
|
||||
* depend on the file's `impliedNodeFormat`. In `--module preserve`, it depends only on the input syntax of the reference. In other
|
||||
* `module` modes, when overriding import attributes are not provided, this function returns `undefined`, as the result would have no
|
||||
* impact on module resolution, emit, or type checking.
|
||||
* Calculates the final resolution mode for a given module reference node. This function only returns a result when module resolution
|
||||
* settings allow differing resolution between ESM imports and CJS requires, or when a mode is explicitly provided via import attributes,
|
||||
* which cause an `import` or `require` condition to be used during resolution regardless of module resolution settings. In absence of
|
||||
* overriding attributes, and in modes that support differing resolution, the result indicates the syntax the usage would emit to JavaScript.
|
||||
* Some examples:
|
||||
*
|
||||
* ```ts
|
||||
* // tsc foo.mts --module nodenext
|
||||
* import {} from "mod";
|
||||
* // Result: ESNext - the import emits as ESM due to `impliedNodeFormat` set by .mts file extension
|
||||
*
|
||||
* // tsc foo.cts --module nodenext
|
||||
* import {} from "mod";
|
||||
* // Result: CommonJS - the import emits as CJS due to `impliedNodeFormat` set by .cts file extension
|
||||
*
|
||||
* // tsc foo.ts --module preserve --moduleResolution bundler
|
||||
* import {} from "mod";
|
||||
* // Result: ESNext - the import emits as ESM due to `--module preserve` and `--moduleResolution bundler`
|
||||
* // supports conditional imports/exports
|
||||
*
|
||||
* // tsc foo.ts --module preserve --moduleResolution node10
|
||||
* import {} from "mod";
|
||||
* // Result: undefined - the import emits as ESM due to `--module preserve`, but `--moduleResolution node10`
|
||||
* // does not support conditional imports/exports
|
||||
*
|
||||
* // tsc foo.ts --module commonjs --moduleResolution node10
|
||||
* import type {} from "mod" with { "resolution-mode": "import" };
|
||||
* // Result: ESNext - conditional imports/exports always supported with "resolution-mode" attribute
|
||||
* ```
|
||||
*
|
||||
* @param file The file the import or import-like reference is contained within
|
||||
* @param usage The module reference string
|
||||
* @param compilerOptions The compiler options for the program that owns the file. If the file belongs to a referenced project, the compiler options
|
||||
* should be the options of the referenced project, not the referencing project.
|
||||
* @returns The final resolution mode of the import
|
||||
*/
|
||||
export function getModeForUsageLocation(file: { impliedNodeFormat?: ResolutionMode; }, usage: StringLiteralLike, compilerOptions: CompilerOptions) {
|
||||
export function getModeForUsageLocation(file: SourceFile, usage: StringLiteralLike, compilerOptions: CompilerOptions) {
|
||||
return getModeForUsageLocationWorker(file, usage, compilerOptions);
|
||||
}
|
||||
|
||||
function getModeForUsageLocationWorker(file: { impliedNodeFormat?: ResolutionMode; }, usage: StringLiteralLike, compilerOptions?: CompilerOptions) {
|
||||
function getModeForUsageLocationWorker(file: Pick<SourceFile, "fileName" | "impliedNodeFormat" | "packageJsonScope">, usage: StringLiteralLike, compilerOptions?: CompilerOptions) {
|
||||
if ((isImportDeclaration(usage.parent) || isExportDeclaration(usage.parent))) {
|
||||
const isTypeOnly = isExclusivelyTypeOnlyImportOrExport(usage.parent);
|
||||
if (isTypeOnly) {
|
||||
@@ -913,20 +942,36 @@ function getModeForUsageLocationWorker(file: { impliedNodeFormat?: ResolutionMod
|
||||
return override;
|
||||
}
|
||||
}
|
||||
if (compilerOptions && getEmitModuleKind(compilerOptions) === ModuleKind.Preserve) {
|
||||
return (usage.parent.parent && isImportEqualsDeclaration(usage.parent.parent) || isRequireCall(usage.parent, /*requireStringLiteralLikeArgument*/ false))
|
||||
? ModuleKind.CommonJS
|
||||
: ModuleKind.ESNext;
|
||||
|
||||
if (compilerOptions && importSyntaxAffectsModuleResolution(compilerOptions)) {
|
||||
return getEmitSyntaxForUsageLocationWorker(file, usage, compilerOptions);
|
||||
}
|
||||
if (file.impliedNodeFormat === undefined) return undefined;
|
||||
if (file.impliedNodeFormat !== ModuleKind.ESNext) {
|
||||
// in cjs files, import call expressions are esm format, otherwise everything is cjs
|
||||
return isImportCall(walkUpParenthesizedExpressions(usage.parent)) ? ModuleKind.ESNext : ModuleKind.CommonJS;
|
||||
}
|
||||
|
||||
function getEmitSyntaxForUsageLocationWorker(file: Pick<SourceFile, "fileName" | "impliedNodeFormat" | "packageJsonScope">, usage: StringLiteralLike, compilerOptions?: CompilerOptions): ResolutionMode {
|
||||
if (!compilerOptions) {
|
||||
// This should always be provided, but we try to fail somewhat
|
||||
// gracefully to allow projects like ts-node time to update.
|
||||
return undefined;
|
||||
}
|
||||
// in esm files, import=require statements are cjs format, otherwise everything is esm
|
||||
// imports are only parent'd up to their containing declaration/expression, so access farther parents with care
|
||||
const exprParentParent = walkUpParenthesizedExpressions(usage.parent)?.parent;
|
||||
return exprParentParent && isImportEqualsDeclaration(exprParentParent) ? ModuleKind.CommonJS : ModuleKind.ESNext;
|
||||
if (exprParentParent && isImportEqualsDeclaration(exprParentParent) || isRequireCall(usage.parent, /*requireStringLiteralLikeArgument*/ false)) {
|
||||
return ModuleKind.CommonJS;
|
||||
}
|
||||
if (isImportCall(walkUpParenthesizedExpressions(usage.parent))) {
|
||||
return shouldTransformImportCallWorker(file, compilerOptions) ? ModuleKind.CommonJS : ModuleKind.ESNext;
|
||||
}
|
||||
// If we're in --module preserve on an input file, we know that an import
|
||||
// is an import. But if this is a declaration file, we'd prefer to use the
|
||||
// impliedNodeFormat. Since we want things to be consistent between the two,
|
||||
// we need to issue errors when the user writes ESM syntax in a definitely-CJS
|
||||
// file, until/unless declaration emit can indicate a true ESM import. On the
|
||||
// other hand, writing CJS syntax in a definitely-ESM file is fine, since declaration
|
||||
// emit preserves the CJS syntax.
|
||||
const fileEmitMode = getEmitModuleFormatOfFileWorker(file, compilerOptions);
|
||||
return fileEmitMode === ModuleKind.CommonJS ? ModuleKind.CommonJS :
|
||||
emitModuleKindIsNonNodeESM(fileEmitMode) || fileEmitMode === ModuleKind.Preserve ? ModuleKind.ESNext :
|
||||
undefined;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -1017,7 +1062,7 @@ function getTypeReferenceResolutionName<T extends FileReference | string>(entry:
|
||||
|
||||
const typeReferenceResolutionNameAndModeGetter: ResolutionNameAndModeGetter<FileReference | string, SourceFile | undefined> = {
|
||||
getName: getTypeReferenceResolutionName,
|
||||
getMode: (entry, file) => getModeForFileReference(entry, file?.impliedNodeFormat),
|
||||
getMode: (entry, file, compilerOptions) => getModeForFileReference(entry, file && getDefaultResolutionModeForFileWorker(file, compilerOptions)),
|
||||
};
|
||||
|
||||
/** @internal */
|
||||
@@ -1339,16 +1384,11 @@ export function getImpliedNodeFormatForFileWorker(
|
||||
host: ModuleResolutionHost,
|
||||
options: CompilerOptions,
|
||||
) {
|
||||
switch (getEmitModuleResolutionKind(options)) {
|
||||
case ModuleResolutionKind.Node16:
|
||||
case ModuleResolutionKind.NodeNext:
|
||||
return fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Mjs]) ? ModuleKind.ESNext :
|
||||
fileExtensionIsOneOf(fileName, [Extension.Dcts, Extension.Cts, Extension.Cjs]) ? ModuleKind.CommonJS :
|
||||
fileExtensionIsOneOf(fileName, [Extension.Dts, Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx]) ? lookupFromPackageJson() :
|
||||
undefined; // other extensions, like `json` or `tsbuildinfo`, are set as `undefined` here but they should never be fed through the transformer pipeline
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
return fileExtensionIsOneOf(fileName, [Extension.Dmts, Extension.Mts, Extension.Mjs]) ? ModuleKind.ESNext :
|
||||
fileExtensionIsOneOf(fileName, [Extension.Dcts, Extension.Cts, Extension.Cjs]) ? ModuleKind.CommonJS :
|
||||
fileExtensionIsOneOf(fileName, [Extension.Dts, Extension.Ts, Extension.Tsx, Extension.Js, Extension.Jsx]) ? lookupFromPackageJson() :
|
||||
undefined; // other extensions, like `json` or `tsbuildinfo`, are set as `undefined` here but they should never be fed through the transformer pipeline
|
||||
|
||||
function lookupFromPackageJson(): Partial<CreateSourceFileOptions> {
|
||||
const state = getTemporaryModuleResolutionState(packageJsonInfoCache, host, options);
|
||||
const packageJsonLocations: string[] = [];
|
||||
@@ -1579,6 +1619,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
// Map storing if there is emit blocking diagnostics for given input
|
||||
const hasEmitBlockingDiagnostics = new Map<string, boolean>();
|
||||
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression | false | undefined;
|
||||
let _compilerOptionsPropertySyntax: PropertyAssignment | false | undefined;
|
||||
|
||||
let moduleResolutionCache: ModuleResolutionCache | undefined;
|
||||
let actualResolveModuleNamesWorker: (
|
||||
@@ -1899,6 +1940,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
isSourceFileFromExternalLibrary,
|
||||
isSourceFileDefaultLibrary,
|
||||
getModeForUsageLocation,
|
||||
getEmitSyntaxForUsageLocation,
|
||||
getModeForResolutionAtIndex,
|
||||
getSourceFileFromReference,
|
||||
getLibFileFromReference,
|
||||
@@ -1926,6 +1968,11 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
forEachResolvedProjectReference,
|
||||
isSourceOfProjectReferenceRedirect,
|
||||
getRedirectReferenceForResolutionFromSourceOfProject,
|
||||
getCompilerOptionsForFile,
|
||||
getDefaultResolutionModeForFile,
|
||||
getEmitModuleFormatOfFile,
|
||||
getImpliedNodeFormatForEmit,
|
||||
shouldTransformImportCall,
|
||||
emitBuildInfo,
|
||||
fileExists,
|
||||
readFile,
|
||||
@@ -2640,6 +2687,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
getSymlinkCache,
|
||||
writeFile: writeFileCallback || writeFile,
|
||||
isEmitBlocked,
|
||||
shouldTransformImportCall,
|
||||
getEmitModuleFormatOfFile,
|
||||
getDefaultResolutionModeForFile,
|
||||
getModeForResolutionAtIndex,
|
||||
readFile: f => host.readFile(f),
|
||||
fileExists: f => {
|
||||
// Use local caches
|
||||
@@ -2649,12 +2700,15 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
// Before falling back to the host
|
||||
return host.fileExists(f);
|
||||
},
|
||||
realpath: maybeBind(host, host.realpath),
|
||||
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
|
||||
getBuildInfo: () => program.getBuildInfo?.(),
|
||||
getSourceFileFromReference: (file, ref) => program.getSourceFileFromReference(file, ref),
|
||||
redirectTargetsMap,
|
||||
getFileIncludeReasons: program.getFileIncludeReasons,
|
||||
createHash: maybeBind(host, host.createHash),
|
||||
getModuleResolutionCache: () => program.getModuleResolutionCache(),
|
||||
trace: maybeBind(host, host.trace),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3408,7 +3462,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
|
||||
function collectDynamicImportOrRequireOrJsDocImportCalls(file: SourceFile) {
|
||||
const r = /import|require/g;
|
||||
while (r.exec(file.text) !== null) { // eslint-disable-line no-null/no-null
|
||||
while (r.exec(file.text) !== null) { // eslint-disable-line no-restricted-syntax
|
||||
const node = getNodeAtPosition(file, r.lastIndex);
|
||||
if (isJavaScriptFile && isRequireCall(node, /*requireStringLiteralLikeArgument*/ true)) {
|
||||
setParentRecursive(node, /*incremental*/ false); // we need parent data on imports before the program is fully bound, so we ensure it's set here
|
||||
@@ -3871,11 +3925,15 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
// store resolved type directive on the file
|
||||
const fileName = toFileNameLowerCase(ref.fileName);
|
||||
resolutionsInFile.set(fileName, getModeForFileReference(ref, file.impliedNodeFormat), resolvedTypeReferenceDirective);
|
||||
const mode = ref.resolutionMode || file.impliedNodeFormat;
|
||||
const mode = ref.resolutionMode || getDefaultResolutionModeForFile(file);
|
||||
processTypeReferenceDirective(fileName, mode, resolvedTypeReferenceDirective, { kind: FileIncludeKind.TypeReferenceDirective, file: file.path, index });
|
||||
}
|
||||
}
|
||||
|
||||
function getCompilerOptionsForFile(file: SourceFile): CompilerOptions {
|
||||
return getRedirectReferenceForResolution(file)?.commandLine.options || options;
|
||||
}
|
||||
|
||||
function processTypeReferenceDirective(
|
||||
typeReferenceDirective: string,
|
||||
mode: ResolutionMode,
|
||||
@@ -4033,7 +4091,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
const resolutions = resolvedModulesProcessing?.get(file.path) ||
|
||||
resolveModuleNamesReusingOldState(moduleNames, file);
|
||||
Debug.assert(resolutions.length === moduleNames.length);
|
||||
const optionsForFile = getRedirectReferenceForResolution(file)?.commandLine.options || options;
|
||||
const optionsForFile = getCompilerOptionsForFile(file);
|
||||
const resolutionsInFile = createModeAwareCache<ResolutionWithFailedLookupLocations>();
|
||||
(resolvedModules ??= new Map()).set(file.path, resolutionsInFile);
|
||||
for (let index = 0; index < moduleNames.length; index++) {
|
||||
@@ -4176,6 +4234,15 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
}
|
||||
}
|
||||
|
||||
if (options.isolatedDeclarations) {
|
||||
if (getAllowJSCompilerOption(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "isolatedDeclarations");
|
||||
}
|
||||
if (!getEmitDeclarations(options)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1_or_option_2, "isolatedDeclarations", "declaration", "composite");
|
||||
}
|
||||
}
|
||||
|
||||
if (options.inlineSourceMap) {
|
||||
if (options.sourceMap) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap");
|
||||
@@ -4344,7 +4411,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
}
|
||||
|
||||
if (options.checkJs && !getAllowJSCompilerOption(options)) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs"));
|
||||
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs");
|
||||
}
|
||||
|
||||
if (options.emitDeclarationOnly) {
|
||||
@@ -4604,7 +4671,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
if (locationReason && fileIncludeReasons?.length === 1) fileIncludeReasons = undefined;
|
||||
const location = locationReason && getReferencedFileLocation(program, locationReason);
|
||||
const fileIncludeReasonDetails = fileIncludeReasons && chainDiagnosticMessages(fileIncludeReasons, Diagnostics.The_file_is_in_the_program_because_Colon);
|
||||
const redirectInfo = file && explainIfFileIsRedirectAndImpliedFormat(file);
|
||||
const optionsForFile = file && getCompilerOptionsForFile(file) || options;
|
||||
const redirectInfo = file && explainIfFileIsRedirectAndImpliedFormat(file, optionsForFile);
|
||||
const chain = chainDiagnosticMessages(redirectInfo ? fileIncludeReasonDetails ? [fileIncludeReasonDetails, ...redirectInfo] : redirectInfo : fileIncludeReasonDetails, diagnostic, ...args || emptyArray);
|
||||
return location && isReferenceFileLocation(location) ?
|
||||
createFileDiagnosticFromMessageChain(location.file, location.pos, location.end - location.pos, chain, relatedInfo) :
|
||||
@@ -4712,7 +4780,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
message = Diagnostics.File_is_library_specified_here;
|
||||
break;
|
||||
}
|
||||
const target = forEachEntry(targetOptionDeclaration.type, (value, key) => value === getEmitScriptTarget(options) ? key : undefined);
|
||||
const target = getNameOfScriptTarget(getEmitScriptTarget(options));
|
||||
configFileNode = target ? getOptionsSyntaxByValue("target", target) : undefined;
|
||||
message = Diagnostics.File_is_default_library_for_target_specified_here;
|
||||
break;
|
||||
@@ -4766,7 +4834,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
}
|
||||
});
|
||||
if (needCompilerDiagnostic) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, ...args));
|
||||
createCompilerOptionsDiagnostic(message, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4788,7 +4856,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
}
|
||||
});
|
||||
if (needCompilerDiagnostic) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, ...args));
|
||||
createCompilerOptionsDiagnostic(message, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4836,27 +4904,52 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
!createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, ...args);
|
||||
|
||||
if (needCompilerDiagnostic) {
|
||||
createCompilerOptionsDiagnostic(message, ...args);
|
||||
}
|
||||
}
|
||||
|
||||
function createCompilerOptionsDiagnostic(message: DiagnosticMessageChain): void;
|
||||
function createCompilerOptionsDiagnostic(message: DiagnosticMessage, ...args: DiagnosticArguments): void;
|
||||
function createCompilerOptionsDiagnostic(message: DiagnosticMessage | DiagnosticMessageChain, ...args: DiagnosticArguments): void;
|
||||
function createCompilerOptionsDiagnostic(message: DiagnosticMessage | DiagnosticMessageChain, ...args: DiagnosticArguments): void {
|
||||
const compilerOptionsProperty = getCompilerOptionsPropertySyntax();
|
||||
if (compilerOptionsProperty) {
|
||||
// eslint-disable-next-line local/no-in-operator
|
||||
if ("messageText" in message) {
|
||||
programDiagnostics.add(createCompilerDiagnosticFromMessageChain(message));
|
||||
programDiagnostics.add(createDiagnosticForNodeFromMessageChain(options.configFile!, compilerOptionsProperty.name, message));
|
||||
}
|
||||
else {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, ...args));
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, compilerOptionsProperty.name, message, ...args));
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line local/no-in-operator
|
||||
else if ("messageText" in message) {
|
||||
programDiagnostics.add(createCompilerDiagnosticFromMessageChain(message));
|
||||
}
|
||||
else {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, ...args));
|
||||
}
|
||||
}
|
||||
|
||||
function getCompilerOptionsObjectLiteralSyntax() {
|
||||
if (_compilerOptionsObjectLiteralSyntax === undefined) {
|
||||
_compilerOptionsObjectLiteralSyntax = forEachPropertyAssignment(
|
||||
getTsConfigObjectLiteralExpression(options.configFile),
|
||||
"compilerOptions",
|
||||
prop => isObjectLiteralExpression(prop.initializer) ? prop.initializer : undefined,
|
||||
) || false;
|
||||
const compilerOptionsProperty = getCompilerOptionsPropertySyntax();
|
||||
_compilerOptionsObjectLiteralSyntax = compilerOptionsProperty ? tryCast(compilerOptionsProperty.initializer, isObjectLiteralExpression) || false : false;
|
||||
}
|
||||
return _compilerOptionsObjectLiteralSyntax || undefined;
|
||||
}
|
||||
|
||||
function getCompilerOptionsPropertySyntax() {
|
||||
if (_compilerOptionsPropertySyntax === undefined) {
|
||||
_compilerOptionsPropertySyntax = forEachPropertyAssignment(
|
||||
getTsConfigObjectLiteralExpression(options.configFile),
|
||||
"compilerOptions",
|
||||
identity,
|
||||
) || false;
|
||||
}
|
||||
return _compilerOptionsPropertySyntax || undefined;
|
||||
}
|
||||
|
||||
function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, messageChain: DiagnosticMessageChain): boolean;
|
||||
function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): boolean;
|
||||
function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: DiagnosticArguments): boolean;
|
||||
@@ -4934,13 +5027,70 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
|
||||
}
|
||||
|
||||
function getModeForUsageLocation(file: SourceFile, usage: StringLiteralLike): ResolutionMode {
|
||||
const optionsForFile = getRedirectReferenceForResolution(file)?.commandLine.options || options;
|
||||
return getModeForUsageLocationWorker(file, usage, optionsForFile);
|
||||
return getModeForUsageLocationWorker(file, usage, getCompilerOptionsForFile(file));
|
||||
}
|
||||
|
||||
function getEmitSyntaxForUsageLocation(file: SourceFile, usage: StringLiteralLike): ResolutionMode {
|
||||
return getEmitSyntaxForUsageLocationWorker(file, usage, getCompilerOptionsForFile(file));
|
||||
}
|
||||
|
||||
function getModeForResolutionAtIndex(file: SourceFile, index: number): ResolutionMode {
|
||||
return getModeForUsageLocation(file, getModuleNameStringLiteralAt(file, index));
|
||||
}
|
||||
|
||||
function getDefaultResolutionModeForFile(sourceFile: SourceFile): ResolutionMode {
|
||||
return getDefaultResolutionModeForFileWorker(sourceFile, getCompilerOptionsForFile(sourceFile));
|
||||
}
|
||||
|
||||
function getImpliedNodeFormatForEmit(sourceFile: SourceFile): ResolutionMode {
|
||||
return getImpliedNodeFormatForEmitWorker(sourceFile, getCompilerOptionsForFile(sourceFile));
|
||||
}
|
||||
|
||||
function getEmitModuleFormatOfFile(sourceFile: SourceFile): ModuleKind {
|
||||
return getEmitModuleFormatOfFileWorker(sourceFile, getCompilerOptionsForFile(sourceFile));
|
||||
}
|
||||
|
||||
function shouldTransformImportCall(sourceFile: SourceFile): boolean {
|
||||
return shouldTransformImportCallWorker(sourceFile, getCompilerOptionsForFile(sourceFile));
|
||||
}
|
||||
}
|
||||
|
||||
function shouldTransformImportCallWorker(sourceFile: Pick<SourceFile, "fileName" | "impliedNodeFormat" | "packageJsonScope">, options: CompilerOptions): boolean {
|
||||
const moduleKind = getEmitModuleKind(options);
|
||||
if (ModuleKind.Node16 <= moduleKind && moduleKind <= ModuleKind.NodeNext || moduleKind === ModuleKind.Preserve) {
|
||||
return false;
|
||||
}
|
||||
return getEmitModuleFormatOfFileWorker(sourceFile, options) < ModuleKind.ES2015;
|
||||
}
|
||||
/** @internal Prefer `program.getEmitModuleFormatOfFile` when possible. */
|
||||
export function getEmitModuleFormatOfFileWorker(sourceFile: Pick<SourceFile, "fileName" | "impliedNodeFormat" | "packageJsonScope">, options: CompilerOptions): ModuleKind {
|
||||
return getImpliedNodeFormatForEmitWorker(sourceFile, options) ?? getEmitModuleKind(options);
|
||||
}
|
||||
/** @internal Prefer `program.getImpliedNodeFormatForEmit` when possible. */
|
||||
export function getImpliedNodeFormatForEmitWorker(sourceFile: Pick<SourceFile, "fileName" | "impliedNodeFormat" | "packageJsonScope">, options: CompilerOptions): ResolutionMode {
|
||||
const moduleKind = getEmitModuleKind(options);
|
||||
if (ModuleKind.Node16 <= moduleKind && moduleKind <= ModuleKind.NodeNext) {
|
||||
return sourceFile.impliedNodeFormat;
|
||||
}
|
||||
if (
|
||||
sourceFile.impliedNodeFormat === ModuleKind.CommonJS
|
||||
&& (sourceFile.packageJsonScope?.contents.packageJsonContent.type === "commonjs"
|
||||
|| fileExtensionIsOneOf(sourceFile.fileName, [Extension.Cjs, Extension.Cts]))
|
||||
) {
|
||||
return ModuleKind.CommonJS;
|
||||
}
|
||||
if (
|
||||
sourceFile.impliedNodeFormat === ModuleKind.ESNext
|
||||
&& (sourceFile.packageJsonScope?.contents.packageJsonContent.type === "module"
|
||||
|| fileExtensionIsOneOf(sourceFile.fileName, [Extension.Mjs, Extension.Mts]))
|
||||
) {
|
||||
return ModuleKind.ESNext;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/** @internal Prefer `program.getDefaultResolutionModeForFile` when possible. */
|
||||
export function getDefaultResolutionModeForFileWorker(sourceFile: Pick<SourceFile, "fileName" | "impliedNodeFormat" | "packageJsonScope">, options: CompilerOptions): ResolutionMode {
|
||||
return importSyntaxAffectsModuleResolution(options) ? getImpliedNodeFormatForEmitWorker(sourceFile, options) : undefined;
|
||||
}
|
||||
|
||||
interface HostForUseSourceOfProjectReferenceRedirect {
|
||||
|
||||
+168
-12
@@ -98,6 +98,8 @@ export interface ResolutionCache {
|
||||
resolutionsWithOnlyAffectingLocations: Set<ResolutionWithFailedLookupLocations>;
|
||||
directoryWatchesOfFailedLookups: Map<string, DirectoryWatchesOfFailedLookup>;
|
||||
fileWatchesOfAffectingLocations: Map<string, FileWatcherOfAffectingLocation>;
|
||||
packageDirWatchers: Map<Path, PackageDirWatcher>;
|
||||
dirPathToSymlinkPackageRefCount: Map<Path, number>;
|
||||
startRecordingFilesWithChangedResolutions(): void;
|
||||
finishRecordingFilesWithChangedResolutions(): Path[] | undefined;
|
||||
|
||||
@@ -236,12 +238,24 @@ export interface DirectoryWatchesOfFailedLookup {
|
||||
/** is the directory watched being non recursive */
|
||||
nonRecursive?: boolean;
|
||||
}
|
||||
/** @internal */
|
||||
export interface DirPathToWatcherOfPackageDirWatcher {
|
||||
watcher: DirectoryWatchesOfFailedLookup;
|
||||
refCount: number;
|
||||
}
|
||||
/** @internal */
|
||||
export interface PackageDirWatcher {
|
||||
dirPathToWatcher: Map<Path, DirPathToWatcherOfPackageDirWatcher>;
|
||||
isSymlink: boolean;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface DirectoryOfFailedLookupWatch {
|
||||
dir: string;
|
||||
dirPath: Path;
|
||||
nonRecursive?: boolean;
|
||||
packageDir?: string;
|
||||
packageDirPath?: Path;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -347,10 +361,16 @@ export function getDirectoryToWatchFailedLookupLocation(
|
||||
// If directory path contains node module, get the most parent node_modules directory for watching
|
||||
const nodeModulesIndex = failedLookupPathComponents.indexOf("node_modules" as Path);
|
||||
if (nodeModulesIndex !== -1 && nodeModulesIndex + 1 <= perceivedOsRootLength + 1) return undefined; // node_modules not at position where it can be watched
|
||||
const lastNodeModulesIndex = failedLookupPathComponents.lastIndexOf("node_modules" as Path);
|
||||
if (isInDirectoryPath(rootPathComponents, failedLookupPathComponents)) {
|
||||
if (failedLookupPathComponents.length > rootPathComponents.length + 1) {
|
||||
// Instead of watching root, watch directory in root to avoid watching excluded directories not needed for module resolution
|
||||
return getDirectoryOfFailedLookupWatch(failedLookupComponents, failedLookupPathComponents, Math.max(rootPathComponents.length + 1, perceivedOsRootLength + 1));
|
||||
return getDirectoryOfFailedLookupWatch(
|
||||
failedLookupComponents,
|
||||
failedLookupPathComponents,
|
||||
Math.max(rootPathComponents.length + 1, perceivedOsRootLength + 1),
|
||||
lastNodeModulesIndex,
|
||||
);
|
||||
}
|
||||
else {
|
||||
// Always watch root directory non recursively
|
||||
@@ -369,6 +389,7 @@ export function getDirectoryToWatchFailedLookupLocation(
|
||||
perceivedOsRootLength,
|
||||
nodeModulesIndex,
|
||||
rootPathComponents,
|
||||
lastNodeModulesIndex,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -379,11 +400,17 @@ function getDirectoryToWatchFromFailedLookupLocationDirectory(
|
||||
perceivedOsRootLength: number,
|
||||
nodeModulesIndex: number,
|
||||
rootPathComponents: Readonly<PathPathComponents>,
|
||||
lastNodeModulesIndex: number,
|
||||
): DirectoryOfFailedLookupWatch | undefined {
|
||||
// If directory path contains node module, get the most parent node_modules directory for watching
|
||||
if (nodeModulesIndex !== -1) {
|
||||
// If the directory is node_modules use it to watch, always watch it recursively
|
||||
return getDirectoryOfFailedLookupWatch(dirComponents, dirPathComponents, nodeModulesIndex + 1);
|
||||
return getDirectoryOfFailedLookupWatch(
|
||||
dirComponents,
|
||||
dirPathComponents,
|
||||
nodeModulesIndex + 1,
|
||||
lastNodeModulesIndex,
|
||||
);
|
||||
}
|
||||
// Use some ancestor of the root directory
|
||||
let nonRecursive = true;
|
||||
@@ -395,19 +422,37 @@ function getDirectoryToWatchFromFailedLookupLocationDirectory(
|
||||
break;
|
||||
}
|
||||
}
|
||||
return getDirectoryOfFailedLookupWatch(dirComponents, dirPathComponents, length, nonRecursive);
|
||||
return getDirectoryOfFailedLookupWatch(
|
||||
dirComponents,
|
||||
dirPathComponents,
|
||||
length,
|
||||
lastNodeModulesIndex,
|
||||
nonRecursive,
|
||||
);
|
||||
}
|
||||
|
||||
function getDirectoryOfFailedLookupWatch(
|
||||
dirComponents: readonly string[],
|
||||
dirPathComponents: Readonly<PathPathComponents>,
|
||||
length: number,
|
||||
lastNodeModulesIndex: number,
|
||||
nonRecursive?: boolean,
|
||||
): DirectoryOfFailedLookupWatch {
|
||||
let packageDirLength;
|
||||
if (lastNodeModulesIndex !== -1 && lastNodeModulesIndex + 1 >= length && lastNodeModulesIndex + 2 < dirPathComponents.length) {
|
||||
if (!startsWith(dirPathComponents[lastNodeModulesIndex + 1], "@")) {
|
||||
packageDirLength = lastNodeModulesIndex + 2;
|
||||
}
|
||||
else if (lastNodeModulesIndex + 3 < dirPathComponents.length) {
|
||||
packageDirLength = lastNodeModulesIndex + 3;
|
||||
}
|
||||
}
|
||||
return {
|
||||
dir: getPathFromPathComponents(dirComponents, length),
|
||||
dirPath: getPathFromPathComponents(dirPathComponents, length),
|
||||
nonRecursive,
|
||||
packageDir: packageDirLength !== undefined ? getPathFromPathComponents(dirComponents, packageDirLength) : undefined,
|
||||
packageDirPath: packageDirLength !== undefined ? getPathFromPathComponents(dirPathComponents, packageDirLength) : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -433,6 +478,7 @@ export function getDirectoryToWatchFailedLookupLocationFromTypeRoot(
|
||||
perceivedOsRootLengthForWatching(typeRootPathComponents, typeRootPathComponents.length),
|
||||
typeRootPathComponents.indexOf("node_modules" as Path),
|
||||
rootPathComponents,
|
||||
typeRootPathComponents.lastIndexOf("node_modules" as Path),
|
||||
);
|
||||
return toWatch && filterCustomPath(toWatch.dirPath) ? toWatch.dirPath : undefined;
|
||||
}
|
||||
@@ -543,7 +589,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
let isInDirectoryChecks: Set<Path> | undefined;
|
||||
let allModuleAndTypeResolutionsAreInvalidated = false;
|
||||
|
||||
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory!()); // TODO: GH#18217
|
||||
const getCurrentDirectory = memoize(() => resolutionHost.getCurrentDirectory!());
|
||||
const cachedDirectoryStructureHost = resolutionHost.getCachedDirectoryStructureHost();
|
||||
|
||||
// The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file.
|
||||
@@ -579,6 +625,10 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
const rootPath = resolutionHost.toPath(rootDir);
|
||||
const rootPathComponents = getPathComponents(rootPath);
|
||||
|
||||
const isSymlinkCache = new Map<Path, boolean>();
|
||||
const packageDirWatchers = new Map<Path, PackageDirWatcher>(); // Watching packageDir if symlink otherwise watching dirPath
|
||||
const dirPathToSymlinkPackageRefCount = new Map<Path, number>(); // Refcount for dirPath watches when watching symlinked packageDir
|
||||
|
||||
// TypeRoot watches for the types that get added as part of getAutomaticTypeDirectiveNames
|
||||
const typeRootsWatches = new Map<string, FileWatcher>();
|
||||
|
||||
@@ -592,6 +642,8 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
resolutionsWithOnlyAffectingLocations,
|
||||
directoryWatchesOfFailedLookups,
|
||||
fileWatchesOfAffectingLocations,
|
||||
packageDirWatchers,
|
||||
dirPathToSymlinkPackageRefCount,
|
||||
watchFailedLookupLocationsOfExternalModuleResolutions,
|
||||
getModuleResolutionCache: () => moduleResolutionCache,
|
||||
startRecordingFilesWithChangedResolutions,
|
||||
@@ -629,6 +681,9 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
function clear() {
|
||||
clearMap(directoryWatchesOfFailedLookups, closeFileWatcherOf);
|
||||
clearMap(fileWatchesOfAffectingLocations, closeFileWatcherOf);
|
||||
isSymlinkCache.clear();
|
||||
packageDirWatchers.clear();
|
||||
dirPathToSymlinkPackageRefCount.clear();
|
||||
nonRelativeExternalModuleResolutions.clear();
|
||||
closeTypeRootsWatch();
|
||||
resolvedModuleNames.clear();
|
||||
@@ -712,6 +767,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
// (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
|
||||
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
|
||||
nonRelativeExternalModuleResolutions.clear();
|
||||
isSymlinkCache.clear();
|
||||
}
|
||||
|
||||
function cleanupLibResolutionWatching(newProgram: Program | undefined) {
|
||||
@@ -759,11 +815,19 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
}
|
||||
directoryWatchesOfFailedLookups.forEach(closeDirectoryWatchesOfFailedLookup);
|
||||
fileWatchesOfAffectingLocations.forEach(closeFileWatcherOfAffectingLocation);
|
||||
packageDirWatchers.forEach(closePackageDirWatcher);
|
||||
hasChangedAutomaticTypeDirectiveNames = false;
|
||||
moduleResolutionCache.isReadonly = true;
|
||||
typeReferenceDirectiveResolutionCache.isReadonly = true;
|
||||
libraryResolutionCache.isReadonly = true;
|
||||
moduleResolutionCache.getPackageJsonInfoCache().isReadonly = true;
|
||||
isSymlinkCache.clear();
|
||||
}
|
||||
|
||||
function closePackageDirWatcher(watcher: PackageDirWatcher, packageDirPath: Path) {
|
||||
if (watcher.dirPathToWatcher.size === 0) {
|
||||
packageDirWatchers.delete(packageDirPath);
|
||||
}
|
||||
}
|
||||
|
||||
function closeDirectoryWatchesOfFailedLookup(watcher: DirectoryWatchesOfFailedLookup, path: Path) {
|
||||
@@ -1078,13 +1142,14 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
getCurrentDirectory,
|
||||
);
|
||||
if (toWatch) {
|
||||
const { dir, dirPath, nonRecursive } = toWatch;
|
||||
const { dir, dirPath, nonRecursive, packageDir, packageDirPath } = toWatch;
|
||||
if (dirPath === rootPath) {
|
||||
Debug.assert(nonRecursive);
|
||||
Debug.assert(!packageDir);
|
||||
setAtRoot = true;
|
||||
}
|
||||
else {
|
||||
setDirectoryWatcher(dir, dirPath, nonRecursive);
|
||||
setDirectoryWatcher(dir, dirPath, packageDir, packageDirPath, nonRecursive);
|
||||
}
|
||||
}
|
||||
return setAtRoot;
|
||||
@@ -1106,7 +1171,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
if (alternateResult) setAtRoot = watchFailedLookupLocation(alternateResult, setAtRoot);
|
||||
if (setAtRoot) {
|
||||
// This is always non recursive
|
||||
setDirectoryWatcher(rootDir, rootPath, /*nonRecursive*/ true);
|
||||
setDirectoryWatcher(rootDir, rootPath, /*packageDir*/ undefined, /*packageDirPath*/ undefined, /*nonRecursive*/ true);
|
||||
}
|
||||
watchAffectingLocationsOfResolution(resolution, !failedLookupLocations?.length && !alternateResult);
|
||||
}
|
||||
@@ -1197,15 +1262,87 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
}
|
||||
}
|
||||
|
||||
function setDirectoryWatcher(dir: string, dirPath: Path, nonRecursive?: boolean) {
|
||||
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
function createDirectoryWatcherForPackageDir(
|
||||
dir: string,
|
||||
dirPath: Path,
|
||||
packageDir: string,
|
||||
packageDirPath: Path,
|
||||
nonRecursive: boolean | undefined,
|
||||
) {
|
||||
Debug.assert(!nonRecursive);
|
||||
// Check if this is symlink:
|
||||
let isSymlink = isSymlinkCache.get(packageDirPath);
|
||||
let packageDirWatcher = packageDirWatchers.get(packageDirPath);
|
||||
if (isSymlink === undefined) {
|
||||
const realPath = resolutionHost.realpath!(packageDir);
|
||||
isSymlink = realPath !== packageDir && resolutionHost.toPath(realPath) !== packageDirPath;
|
||||
isSymlinkCache.set(packageDirPath, isSymlink);
|
||||
if (!packageDirWatcher) {
|
||||
packageDirWatchers.set(
|
||||
packageDirPath,
|
||||
packageDirWatcher = {
|
||||
dirPathToWatcher: new Map(),
|
||||
isSymlink,
|
||||
},
|
||||
);
|
||||
}
|
||||
else if (packageDirWatcher.isSymlink !== isSymlink) {
|
||||
// Handle the change
|
||||
packageDirWatcher.dirPathToWatcher.forEach(watcher => {
|
||||
removeDirectoryWatcher(packageDirWatcher!.isSymlink ? packageDirPath : dirPath, /*syncDirWatcherRemove*/ false);
|
||||
watcher.watcher = createDirPathToWatcher();
|
||||
});
|
||||
packageDirWatcher.isSymlink = isSymlink;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Debug.assertIsDefined(packageDirWatcher);
|
||||
Debug.assert(isSymlink === packageDirWatcher.isSymlink);
|
||||
}
|
||||
const forDirPath = packageDirWatcher.dirPathToWatcher.get(dirPath);
|
||||
if (forDirPath) {
|
||||
forDirPath.refCount++;
|
||||
}
|
||||
else {
|
||||
packageDirWatcher.dirPathToWatcher.set(dirPath, {
|
||||
watcher: createDirPathToWatcher(),
|
||||
refCount: 1,
|
||||
});
|
||||
if (isSymlink) dirPathToSymlinkPackageRefCount.set(dirPath, (dirPathToSymlinkPackageRefCount.get(dirPath) ?? 0) + 1);
|
||||
}
|
||||
|
||||
function createDirPathToWatcher() {
|
||||
return isSymlink ?
|
||||
createOrAddRefToDirectoryWatchOfFailedLookups(packageDir, packageDirPath, nonRecursive) :
|
||||
createOrAddRefToDirectoryWatchOfFailedLookups(dir, dirPath, nonRecursive);
|
||||
}
|
||||
}
|
||||
|
||||
function setDirectoryWatcher(
|
||||
dir: string,
|
||||
dirPath: Path,
|
||||
packageDir: string | undefined,
|
||||
packageDirPath: Path | undefined,
|
||||
nonRecursive: boolean | undefined,
|
||||
) {
|
||||
if (!packageDirPath || !resolutionHost.realpath) {
|
||||
createOrAddRefToDirectoryWatchOfFailedLookups(dir, dirPath, nonRecursive);
|
||||
}
|
||||
else {
|
||||
createDirectoryWatcherForPackageDir(dir, dirPath, packageDir!, packageDirPath, nonRecursive);
|
||||
}
|
||||
}
|
||||
|
||||
function createOrAddRefToDirectoryWatchOfFailedLookups(dir: string, dirPath: Path, nonRecursive: boolean | undefined) {
|
||||
let dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
|
||||
if (dirWatcher) {
|
||||
Debug.assert(!!nonRecursive === !!dirWatcher.nonRecursive);
|
||||
dirWatcher.refCount++;
|
||||
}
|
||||
else {
|
||||
directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath, nonRecursive), refCount: 1, nonRecursive });
|
||||
directoryWatchesOfFailedLookups.set(dirPath, dirWatcher = { watcher: createDirectoryWatcher(dir, dirPath, nonRecursive), refCount: 1, nonRecursive });
|
||||
}
|
||||
return dirWatcher;
|
||||
}
|
||||
|
||||
function stopWatchFailedLookupLocation(failedLookupLocation: string, removeAtRoot: boolean, syncDirWatcherRemove: boolean | undefined) {
|
||||
@@ -1219,10 +1356,29 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
getCurrentDirectory,
|
||||
);
|
||||
if (toWatch) {
|
||||
const { dirPath } = toWatch;
|
||||
const { dirPath, packageDirPath } = toWatch;
|
||||
if (dirPath === rootPath) {
|
||||
removeAtRoot = true;
|
||||
}
|
||||
else if (packageDirPath && resolutionHost.realpath) {
|
||||
const packageDirWatcher = packageDirWatchers.get(packageDirPath)!;
|
||||
const forDirPath = packageDirWatcher.dirPathToWatcher.get(dirPath)!;
|
||||
forDirPath.refCount--;
|
||||
if (forDirPath.refCount === 0) {
|
||||
removeDirectoryWatcher(packageDirWatcher.isSymlink ? packageDirPath : dirPath, syncDirWatcherRemove);
|
||||
packageDirWatcher.dirPathToWatcher.delete(dirPath);
|
||||
if (packageDirWatcher.isSymlink) {
|
||||
const refCount = dirPathToSymlinkPackageRefCount.get(dirPath)! - 1;
|
||||
if (refCount === 0) {
|
||||
dirPathToSymlinkPackageRefCount.delete(dirPath);
|
||||
}
|
||||
else {
|
||||
dirPathToSymlinkPackageRefCount.set(dirPath, refCount);
|
||||
}
|
||||
}
|
||||
if (syncDirWatcherRemove) closePackageDirWatcher(packageDirWatcher, packageDirPath);
|
||||
}
|
||||
}
|
||||
else {
|
||||
removeDirectoryWatcher(dirPath, syncDirWatcherRemove);
|
||||
}
|
||||
@@ -1506,7 +1662,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
|
||||
rootPath,
|
||||
rootPathComponents,
|
||||
getCurrentDirectory,
|
||||
dirPath => directoryWatchesOfFailedLookups.has(dirPath),
|
||||
dirPath => directoryWatchesOfFailedLookups.has(dirPath) || dirPathToSymlinkPackageRefCount.has(dirPath),
|
||||
);
|
||||
if (dirPath) {
|
||||
scheduleInvalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath);
|
||||
|
||||
+1143
-93
File diff suppressed because it is too large
Load Diff
@@ -45,7 +45,7 @@ export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoo
|
||||
var rawSources: string[] = [];
|
||||
var sources: string[] = [];
|
||||
var sourceToSourceIndexMap = new Map<string, number>();
|
||||
var sourcesContent: (string | null)[] | undefined;
|
||||
var sourcesContent: (string | null)[] | undefined; // eslint-disable-line no-restricted-syntax
|
||||
|
||||
var names: string[] = [];
|
||||
var nameToNameIndexMap: Map<string, number> | undefined;
|
||||
@@ -98,7 +98,7 @@ export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoo
|
||||
return sourceIndex;
|
||||
}
|
||||
|
||||
/* eslint-disable no-null/no-null */
|
||||
/* eslint-disable no-restricted-syntax */
|
||||
function setSourceContent(sourceIndex: number, content: string | null) {
|
||||
enter();
|
||||
if (content !== null) {
|
||||
@@ -110,7 +110,7 @@ export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoo
|
||||
}
|
||||
exit();
|
||||
}
|
||||
/* eslint-enable no-null/no-null */
|
||||
/* eslint-enable no-restricted-syntax */
|
||||
|
||||
function addName(name: string) {
|
||||
enter();
|
||||
@@ -400,7 +400,7 @@ export function tryGetSourceMappingURL(lineInfo: LineInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable no-null/no-null */
|
||||
/* eslint-disable no-restricted-syntax */
|
||||
function isStringOrNull(x: any) {
|
||||
return typeof x === "string" || x === null;
|
||||
}
|
||||
@@ -417,7 +417,7 @@ export function isRawSourceMap(x: any): x is RawSourceMap {
|
||||
&& (x.sourcesContent === undefined || x.sourcesContent === null || isArray(x.sourcesContent) && every(x.sourcesContent, isStringOrNull))
|
||||
&& (x.names === undefined || x.names === null || isArray(x.names) && every(x.names, isString));
|
||||
}
|
||||
/* eslint-enable no-null/no-null */
|
||||
/* eslint-enable no-restricted-syntax */
|
||||
|
||||
/** @internal */
|
||||
export function tryParseRawSourceMap(text: string) {
|
||||
|
||||
+72
-25
@@ -18,6 +18,7 @@ import {
|
||||
getDirectoryPath,
|
||||
getFallbackOptions,
|
||||
getNormalizedAbsolutePath,
|
||||
getRelativePathFromDirectory,
|
||||
getRelativePathToDirectoryOrUrl,
|
||||
getRootLength,
|
||||
getStringComparer,
|
||||
@@ -607,15 +608,17 @@ function createDirectoryWatcherSupportingRecursive({
|
||||
watcher: FileWatcher;
|
||||
childWatches: ChildWatches;
|
||||
refCount: number;
|
||||
targetWatcher: ChildDirectoryWatcher | undefined;
|
||||
links: Set<string> | undefined;
|
||||
}
|
||||
|
||||
const cache = new Map<string, HostDirectoryWatcher>();
|
||||
const cache = new Map<Path, HostDirectoryWatcher>();
|
||||
const callbackCache = createMultiMap<Path, { dirName: string; callback: DirectoryWatcherCallback; }>();
|
||||
const cacheToUpdateChildWatches = new Map<Path, { dirName: string; options: WatchOptions | undefined; fileNames: string[]; }>();
|
||||
let timerToUpdateChildWatches: any;
|
||||
|
||||
const filePathComparer = getStringComparer(!useCaseSensitiveFileNames);
|
||||
const toCanonicalFilePath = createGetCanonicalFileName(useCaseSensitiveFileNames);
|
||||
const toCanonicalFilePath = createGetCanonicalFileName(useCaseSensitiveFileNames) as (fileName: string) => Path;
|
||||
|
||||
return (dirName, callback, recursive, options) =>
|
||||
recursive ?
|
||||
@@ -625,8 +628,13 @@ function createDirectoryWatcherSupportingRecursive({
|
||||
/**
|
||||
* Create the directory watcher for the dirPath.
|
||||
*/
|
||||
function createDirectoryWatcher(dirName: string, options: WatchOptions | undefined, callback?: DirectoryWatcherCallback): ChildDirectoryWatcher {
|
||||
const dirPath = toCanonicalFilePath(dirName) as Path;
|
||||
function createDirectoryWatcher(
|
||||
dirName: string,
|
||||
options: WatchOptions | undefined,
|
||||
callback?: DirectoryWatcherCallback,
|
||||
link?: string,
|
||||
): ChildDirectoryWatcher {
|
||||
const dirPath = toCanonicalFilePath(dirName);
|
||||
let directoryWatcher = cache.get(dirPath);
|
||||
if (directoryWatcher) {
|
||||
directoryWatcher.refCount++;
|
||||
@@ -640,7 +648,7 @@ function createDirectoryWatcherSupportingRecursive({
|
||||
|
||||
if (options?.synchronousWatchDirectory) {
|
||||
// Call the actual callback
|
||||
invokeCallbacks(dirPath, fileName);
|
||||
if (!cache.get(dirPath)?.targetWatcher) invokeCallbacks(dirName, dirPath, fileName);
|
||||
|
||||
// Iterate through existing children and update the watches if needed
|
||||
updateChildWatches(dirName, dirPath, options);
|
||||
@@ -654,11 +662,15 @@ function createDirectoryWatcherSupportingRecursive({
|
||||
),
|
||||
refCount: 1,
|
||||
childWatches: emptyArray,
|
||||
targetWatcher: undefined,
|
||||
links: undefined,
|
||||
};
|
||||
cache.set(dirPath, directoryWatcher);
|
||||
updateChildWatches(dirName, dirPath, options);
|
||||
}
|
||||
|
||||
if (link) (directoryWatcher.links ??= new Set()).add(link);
|
||||
|
||||
const callbackToAdd = callback && { dirName, callback };
|
||||
if (callbackToAdd) {
|
||||
callbackCache.add(dirPath, callbackToAdd);
|
||||
@@ -669,21 +681,24 @@ function createDirectoryWatcherSupportingRecursive({
|
||||
close: () => {
|
||||
const directoryWatcher = Debug.checkDefined(cache.get(dirPath));
|
||||
if (callbackToAdd) callbackCache.remove(dirPath, callbackToAdd);
|
||||
if (link) directoryWatcher.links?.delete(link);
|
||||
directoryWatcher.refCount--;
|
||||
|
||||
if (directoryWatcher.refCount) return;
|
||||
|
||||
cache.delete(dirPath);
|
||||
directoryWatcher.links = undefined;
|
||||
closeFileWatcherOf(directoryWatcher);
|
||||
closeTargetWatcher(directoryWatcher);
|
||||
directoryWatcher.childWatches.forEach(closeFileWatcher);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
type InvokeMap = Map<Path, string[] | true>;
|
||||
function invokeCallbacks(dirPath: Path, fileName: string): void;
|
||||
function invokeCallbacks(dirPath: Path, invokeMap: InvokeMap, fileNames: string[] | undefined): void;
|
||||
function invokeCallbacks(dirPath: Path, fileNameOrInvokeMap: string | InvokeMap, fileNames?: string[]) {
|
||||
function invokeCallbacks(dirName: string, dirPath: Path, fileName: string): void;
|
||||
function invokeCallbacks(dirName: string, dirPath: Path, invokeMap: InvokeMap, fileNames: string[] | undefined): void;
|
||||
function invokeCallbacks(dirName: string, dirPath: Path, fileNameOrInvokeMap: string | InvokeMap, fileNames?: string[]) {
|
||||
let fileName: string | undefined;
|
||||
let invokeMap: InvokeMap | undefined;
|
||||
if (isString(fileNameOrInvokeMap)) {
|
||||
@@ -715,6 +730,15 @@ function createDirectoryWatcherSupportingRecursive({
|
||||
}
|
||||
}
|
||||
});
|
||||
cache.get(dirPath)?.links?.forEach(link => {
|
||||
const toPathInLink = (fileName: string) => combinePaths(link, getRelativePathFromDirectory(dirName, fileName, toCanonicalFilePath));
|
||||
if (invokeMap) {
|
||||
invokeCallbacks(link, toCanonicalFilePath(link), invokeMap, fileNames?.map(toPathInLink));
|
||||
}
|
||||
else {
|
||||
invokeCallbacks(link, toCanonicalFilePath(link), toPathInLink(fileName!));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function nonSyncUpdateChildWatches(dirName: string, dirPath: Path, fileName: string, options: WatchOptions | undefined) {
|
||||
@@ -727,7 +751,8 @@ function createDirectoryWatcherSupportingRecursive({
|
||||
}
|
||||
|
||||
// Call the actual callbacks and remove child watches
|
||||
invokeCallbacks(dirPath, fileName);
|
||||
invokeCallbacks(dirName, dirPath, fileName);
|
||||
closeTargetWatcher(parentWatcher);
|
||||
removeChildWatches(parentWatcher);
|
||||
}
|
||||
|
||||
@@ -760,7 +785,7 @@ function createDirectoryWatcherSupportingRecursive({
|
||||
// Because the child refresh is fresh, we would need to invalidate whole root directory being watched
|
||||
// to ensure that all the changes are reflected at this time
|
||||
const hasChanges = updateChildWatches(dirName, dirPath, options);
|
||||
invokeCallbacks(dirPath, invokeMap, hasChanges ? undefined : fileNames);
|
||||
if (!cache.get(dirPath)?.targetWatcher) invokeCallbacks(dirName, dirPath, invokeMap, hasChanges ? undefined : fileNames);
|
||||
}
|
||||
|
||||
sysLog(`sysLog:: invokingWatchers:: Elapsed:: ${timestamp() - start}ms:: ${cacheToUpdateChildWatches.size}`);
|
||||
@@ -792,24 +817,46 @@ function createDirectoryWatcherSupportingRecursive({
|
||||
}
|
||||
}
|
||||
|
||||
function closeTargetWatcher(watcher: HostDirectoryWatcher | undefined) {
|
||||
if (watcher?.targetWatcher) {
|
||||
watcher.targetWatcher.close();
|
||||
watcher.targetWatcher = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function updateChildWatches(parentDir: string, parentDirPath: Path, options: WatchOptions | undefined) {
|
||||
// Iterate through existing children and update the watches if needed
|
||||
const parentWatcher = cache.get(parentDirPath);
|
||||
if (!parentWatcher) return false;
|
||||
const target = normalizePath(realpath(parentDir));
|
||||
let hasChanges;
|
||||
let newChildWatches: ChildDirectoryWatcher[] | undefined;
|
||||
const hasChanges = enumerateInsertsAndDeletes<string, ChildDirectoryWatcher>(
|
||||
fileSystemEntryExists(parentDir, FileSystemEntryKind.Directory) ? mapDefined(getAccessibleSortedChildDirectories(parentDir), child => {
|
||||
const childFullName = getNormalizedAbsolutePath(child, parentDir);
|
||||
// Filter our the symbolic link directories since those arent included in recursive watch
|
||||
// which is same behaviour when recursive: true is passed to fs.watch
|
||||
return !isIgnoredPath(childFullName, options) && filePathComparer(childFullName, normalizePath(realpath(childFullName))) === Comparison.EqualTo ? childFullName : undefined;
|
||||
}) : emptyArray,
|
||||
parentWatcher.childWatches,
|
||||
(child, childWatcher) => filePathComparer(child, childWatcher.dirName),
|
||||
createAndAddChildDirectoryWatcher,
|
||||
closeFileWatcher,
|
||||
addChildDirectoryWatcher,
|
||||
);
|
||||
if (filePathComparer(target, parentDir) === Comparison.EqualTo) {
|
||||
// if (parentWatcher.target) closeFileWatcher
|
||||
hasChanges = enumerateInsertsAndDeletes<string, ChildDirectoryWatcher>(
|
||||
fileSystemEntryExists(parentDir, FileSystemEntryKind.Directory) ? mapDefined(getAccessibleSortedChildDirectories(parentDir), child => {
|
||||
const childFullName = getNormalizedAbsolutePath(child, parentDir);
|
||||
// Filter our the symbolic link directories since those arent included in recursive watch
|
||||
// which is same behaviour when recursive: true is passed to fs.watch
|
||||
return !isIgnoredPath(childFullName, options) && filePathComparer(childFullName, normalizePath(realpath(childFullName))) === Comparison.EqualTo ? childFullName : undefined;
|
||||
}) : emptyArray,
|
||||
parentWatcher.childWatches,
|
||||
(child, childWatcher) => filePathComparer(child, childWatcher.dirName),
|
||||
createAndAddChildDirectoryWatcher,
|
||||
closeFileWatcher,
|
||||
addChildDirectoryWatcher,
|
||||
);
|
||||
}
|
||||
else if (parentWatcher.targetWatcher && filePathComparer(target, parentWatcher.targetWatcher.dirName) === Comparison.EqualTo) {
|
||||
hasChanges = false;
|
||||
Debug.assert(parentWatcher.childWatches === emptyArray);
|
||||
}
|
||||
else {
|
||||
closeTargetWatcher(parentWatcher);
|
||||
parentWatcher.targetWatcher = createDirectoryWatcher(target, options, /*callback*/ undefined, parentDir);
|
||||
parentWatcher.childWatches.forEach(closeFileWatcher);
|
||||
hasChanges = true;
|
||||
}
|
||||
parentWatcher.childWatches = newChildWatches || emptyArray;
|
||||
return hasChanges;
|
||||
|
||||
@@ -842,7 +889,7 @@ function createDirectoryWatcherSupportingRecursive({
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export type FsWatchCallback = (eventName: "rename" | "change", relativeFileName: string | undefined | null, modifiedTime?: Date) => void;
|
||||
export type FsWatchCallback = (eventName: "rename" | "change", relativeFileName: string | undefined | null, modifiedTime?: Date) => void; // eslint-disable-line no-restricted-syntax
|
||||
/** @internal */
|
||||
export type FsWatch = (fileOrDirectory: string, entryKind: FileSystemEntryKind, callback: FsWatchCallback, recursive: boolean, fallbackPollingInterval: PollingInterval, fallbackOptions: WatchOptions | undefined) => FileWatcher;
|
||||
/** @internal */
|
||||
@@ -1237,7 +1284,7 @@ export function createSystemWatchFunctions({
|
||||
}
|
||||
}
|
||||
|
||||
function callbackChangingToMissingFileSystemEntry(event: "rename" | "change", relativeName: string | undefined | null) {
|
||||
function callbackChangingToMissingFileSystemEntry(event: "rename" | "change", relativeName: string | undefined | null) { // eslint-disable-line no-restricted-syntax
|
||||
// In some scenarios, file save operation fires event with fileName.ext~ instead of fileName.ext
|
||||
// To ensure we see the file going missing and coming back up (file delete and then recreated)
|
||||
// and watches being updated correctly we are calling back with fileName.ext as well as fileName.ext~
|
||||
|
||||
@@ -51,7 +51,7 @@ export namespace tracingEnabled {
|
||||
|
||||
// The actual constraint is that JSON.stringify be able to serialize it without throwing.
|
||||
interface Args {
|
||||
[key: string]: string | number | boolean | null | undefined | Args | readonly (string | number | boolean | null | undefined | Args)[];
|
||||
[key: string]: string | number | boolean | null | undefined | Args | readonly (string | number | boolean | null | undefined | Args)[]; // eslint-disable-line no-restricted-syntax
|
||||
}
|
||||
|
||||
/** Starts tracing for the given project. */
|
||||
|
||||
@@ -65,10 +65,10 @@ import {
|
||||
transformESDecorators,
|
||||
transformESNext,
|
||||
transformGenerators,
|
||||
transformImpliedNodeFormatDependentModule,
|
||||
transformJsx,
|
||||
transformLegacyDecorators,
|
||||
transformModule,
|
||||
transformNodeModule,
|
||||
transformSystemModule,
|
||||
transformTypeScript,
|
||||
VariableDeclaration,
|
||||
@@ -77,17 +77,23 @@ import * as performance from "./_namespaces/ts.performance";
|
||||
|
||||
function getModuleTransformer(moduleKind: ModuleKind): TransformerFactory<SourceFile | Bundle> {
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.Preserve:
|
||||
// `transformECMAScriptModule` contains logic for preserving
|
||||
// CJS input syntax in `--module preserve`
|
||||
return transformECMAScriptModule;
|
||||
case ModuleKind.ESNext:
|
||||
case ModuleKind.ES2022:
|
||||
case ModuleKind.ES2020:
|
||||
case ModuleKind.ES2015:
|
||||
case ModuleKind.Preserve:
|
||||
return transformECMAScriptModule;
|
||||
case ModuleKind.System:
|
||||
return transformSystemModule;
|
||||
case ModuleKind.Node16:
|
||||
case ModuleKind.NodeNext:
|
||||
return transformNodeModule;
|
||||
case ModuleKind.CommonJS:
|
||||
// Wraps `transformModule` and `transformECMAScriptModule` and
|
||||
// selects between them based on the `impliedNodeFormat` of the
|
||||
// source file.
|
||||
return transformImpliedNodeFormatDependentModule;
|
||||
case ModuleKind.System:
|
||||
return transformSystemModule;
|
||||
default:
|
||||
return transformModule;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
contains,
|
||||
createDiagnosticForNode,
|
||||
createEmptyExports,
|
||||
createGetIsolatedDeclarationErrors,
|
||||
createGetSymbolAccessibilityDiagnosticForNode,
|
||||
createGetSymbolAccessibilityDiagnosticForNodeName,
|
||||
createSymbolTable,
|
||||
@@ -39,6 +40,7 @@ import {
|
||||
EnumDeclaration,
|
||||
ExportAssignment,
|
||||
ExportDeclaration,
|
||||
Expression,
|
||||
ExpressionWithTypeArguments,
|
||||
factory,
|
||||
FileReference,
|
||||
@@ -87,6 +89,7 @@ import {
|
||||
isAmbientModule,
|
||||
isArray,
|
||||
isArrayBindingElement,
|
||||
isBinaryExpression,
|
||||
isBindingElement,
|
||||
isBindingPattern,
|
||||
isClassDeclaration,
|
||||
@@ -122,6 +125,7 @@ import {
|
||||
isModuleDeclaration,
|
||||
isObjectLiteralExpression,
|
||||
isOmittedExpression,
|
||||
isPrimitiveLiteralValue,
|
||||
isPrivateIdentifier,
|
||||
isSemicolonClassElement,
|
||||
isSetAccessorDeclaration,
|
||||
@@ -196,6 +200,7 @@ import {
|
||||
TypeParameterDeclaration,
|
||||
TypeReferenceNode,
|
||||
unescapeLeadingUnderscores,
|
||||
unwrapParenthesizedExpression,
|
||||
VariableDeclaration,
|
||||
VariableDeclarationList,
|
||||
VariableStatement,
|
||||
@@ -255,6 +260,7 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
moduleResolverHost: host,
|
||||
reportNonlocalAugmentation,
|
||||
reportNonSerializableProperty,
|
||||
reportInferenceFallback,
|
||||
};
|
||||
let errorNameNode: DeclarationName | undefined;
|
||||
let errorFallbackNode: Declaration | undefined;
|
||||
@@ -265,9 +271,33 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
let rawLibReferenceDirectives: readonly FileReference[];
|
||||
const resolver = context.getEmitResolver();
|
||||
const options = context.getCompilerOptions();
|
||||
const { stripInternal } = options;
|
||||
const getIsolatedDeclarationError = createGetIsolatedDeclarationErrors(resolver);
|
||||
const { stripInternal, isolatedDeclarations } = options;
|
||||
return transformRoot;
|
||||
|
||||
function reportExpandoFunctionErrors(node: FunctionDeclaration | VariableDeclaration) {
|
||||
resolver.getPropertiesOfContainerFunction(node).forEach(p => {
|
||||
if (isExpandoPropertyDeclaration(p.valueDeclaration)) {
|
||||
const errorTarget = isBinaryExpression(p.valueDeclaration) ?
|
||||
p.valueDeclaration.left :
|
||||
p.valueDeclaration;
|
||||
|
||||
context.addDiagnostic(createDiagnosticForNode(
|
||||
errorTarget,
|
||||
Diagnostics.Assigning_properties_to_functions_without_declaring_them_is_not_supported_with_isolatedDeclarations_Add_an_explicit_declaration_for_the_properties_assigned_to_this_function,
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
function reportInferenceFallback(node: Node) {
|
||||
if (!isolatedDeclarations || isSourceFileJS(currentSourceFile)) return;
|
||||
if (isVariableDeclaration(node) && resolver.isExpandoFunctionDeclaration(node)) {
|
||||
reportExpandoFunctionErrors(node);
|
||||
}
|
||||
else {
|
||||
context.addDiagnostic(getIsolatedDeclarationError(node));
|
||||
}
|
||||
}
|
||||
function handleSymbolAccessibilityError(symbolAccessibilityResult: SymbolAccessibilityResult) {
|
||||
if (symbolAccessibilityResult.accessibility === SymbolAccessibility.Accessible) {
|
||||
// Add aliases back onto the possible imports list if they're not there so we can try them again with updated visibility info
|
||||
@@ -561,7 +591,7 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
elem.dotDotDotToken,
|
||||
elem.propertyName,
|
||||
filterBindingPatternInitializers(elem.name),
|
||||
shouldPrintWithInitializer(elem) ? elem.initializer : undefined,
|
||||
/*initializer*/ undefined,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -587,13 +617,19 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
return newParam;
|
||||
}
|
||||
|
||||
function shouldPrintWithInitializer(node: Node) {
|
||||
return canHaveLiteralInitializer(node) && resolver.isLiteralConstDeclaration(getParseTreeNode(node) as CanHaveLiteralInitializer); // TODO: Make safe
|
||||
function shouldPrintWithInitializer(node: Node): node is CanHaveLiteralInitializer & { initializer: Expression; } {
|
||||
return canHaveLiteralInitializer(node)
|
||||
&& !!node.initializer
|
||||
&& resolver.isLiteralConstDeclaration(getParseTreeNode(node) as CanHaveLiteralInitializer); // TODO: Make safea
|
||||
}
|
||||
|
||||
function ensureNoInitializer(node: CanHaveLiteralInitializer) {
|
||||
if (shouldPrintWithInitializer(node)) {
|
||||
return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer, symbolTracker); // TODO: Make safe
|
||||
const unwrappedInitializer = unwrapParenthesizedExpression(node.initializer);
|
||||
if (!isPrimitiveLiteralValue(unwrappedInitializer)) {
|
||||
reportInferenceFallback(node);
|
||||
}
|
||||
return resolver.createLiteralConstValue(getParseTreeNode(node, canHaveLiteralInitializer)!, symbolTracker);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -638,7 +674,7 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.BindingElement:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
typeNode = resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker, shouldAddImplicitUndefined);
|
||||
typeNode = resolver.createTypeOfDeclaration(node, enclosingDeclaration, declarationEmitNodeBuilderFlags, symbolTracker);
|
||||
break;
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
@@ -871,6 +907,9 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
}
|
||||
// Augmentation of export depends on import
|
||||
if (resolver.isImportRequiredByAugmentation(decl)) {
|
||||
if (isolatedDeclarations) {
|
||||
context.addDiagnostic(createDiagnosticForNode(decl, Diagnostics.Declaration_emit_for_this_file_requires_preserving_this_import_for_augmentations_This_is_not_supported_with_isolatedDeclarations));
|
||||
}
|
||||
return factory.updateImportDeclaration(
|
||||
decl,
|
||||
decl.modifiers,
|
||||
@@ -945,6 +984,18 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
if (isDeclaration(input)) {
|
||||
if (isDeclarationAndNotVisible(input)) return;
|
||||
if (hasDynamicName(input) && !resolver.isLateBound(getParseTreeNode(input) as Declaration)) {
|
||||
if (
|
||||
isolatedDeclarations
|
||||
// Classes usually elide properties with computed names that are not of a literal type
|
||||
// In isolated declarations TSC needs to error on these as we don't know the type in a DTE.
|
||||
&& isClassDeclaration(input.parent)
|
||||
&& isEntityNameExpression(input.name.expression)
|
||||
// If the symbol is not accessible we get another TS error no need to add to that
|
||||
&& resolver.isEntityNameVisible(input.name.expression, input.parent).accessibility === SymbolAccessibility.Accessible
|
||||
&& !resolver.isNonNarrowedBindableName(input.name)
|
||||
) {
|
||||
context.addDiagnostic(createDiagnosticForNode(input, Diagnostics.Computed_properties_must_be_number_or_string_literals_variables_or_dotted_expressions_with_isolatedDeclarations));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1371,6 +1422,10 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
));
|
||||
if (clean && resolver.isExpandoFunctionDeclaration(input) && shouldEmitFunctionProperties(input)) {
|
||||
const props = resolver.getPropertiesOfContainerFunction(input);
|
||||
|
||||
if (isolatedDeclarations) {
|
||||
reportExpandoFunctionErrors(input);
|
||||
}
|
||||
// Use parseNodeFactory so it is usable as an enclosing declaration
|
||||
const fakespace = parseNodeFactory.createModuleDeclaration(/*modifiers*/ undefined, clean.name || factory.createIdentifier("_default"), factory.createModuleBlock([]), NodeFlags.Namespace);
|
||||
setParent(fakespace, enclosingDeclaration as SourceFile | NamespaceDeclaration);
|
||||
@@ -1386,7 +1441,7 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
return undefined; // unique symbol or non-identifier name - omit, since there's no syntax that can preserve it
|
||||
}
|
||||
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(p.valueDeclaration);
|
||||
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags, symbolTracker);
|
||||
const type = resolver.createTypeOfDeclaration(p.valueDeclaration, fakespace, declarationEmitNodeBuilderFlags | NodeBuilderFlags.NoSyntacticPrinter, symbolTracker);
|
||||
getSymbolAccessibilityDiagnostic = oldDiag;
|
||||
const isNonContextualKeywordName = isStringANonContextualKeyword(nameStr);
|
||||
const name = isNonContextualKeywordName ? factory.getGeneratedNameForNode(p.valueDeclaration) : factory.createIdentifier(nameStr);
|
||||
@@ -1628,7 +1683,15 @@ export function transformDeclarations(context: TransformationContext) {
|
||||
factory.createNodeArray(mapDefined(input.members, m => {
|
||||
if (shouldStripInternal(m)) return;
|
||||
// Rewrite enum values to their constants, if available
|
||||
const constValue = resolver.getConstantValue(m);
|
||||
const enumValue = resolver.getEnumMemberValue(m);
|
||||
const constValue = enumValue?.value;
|
||||
if (
|
||||
isolatedDeclarations && m.initializer && enumValue?.hasExternalReferences &&
|
||||
// This will be its own compiler error instead, so don't report.
|
||||
!isComputedPropertyName(m.name)
|
||||
) {
|
||||
context.addDiagnostic(createDiagnosticForNode(m, Diagnostics.Enum_member_initializers_must_be_computable_without_references_to_external_symbols_with_isolatedDeclarations));
|
||||
}
|
||||
const newInitializer = constValue === undefined ? undefined
|
||||
: typeof constValue === "string" ? factory.createStringLiteral(constValue)
|
||||
: constValue < 0 ? factory.createPrefixUnaryExpression(SyntaxKind.MinusToken, factory.createNumericLiteral(-constValue))
|
||||
@@ -1816,7 +1879,7 @@ function getTypeAnnotationFromAccessor(accessor: AccessorDeclaration): TypeNode
|
||||
}
|
||||
|
||||
type CanHaveLiteralInitializer = VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration;
|
||||
function canHaveLiteralInitializer(node: Node): boolean {
|
||||
function canHaveLiteralInitializer(node: Node): node is CanHaveLiteralInitializer {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.PropertySignature:
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
import {
|
||||
addRelatedInfo,
|
||||
ArrayLiteralExpression,
|
||||
ArrowFunction,
|
||||
assertType,
|
||||
BinaryExpression,
|
||||
BindingElement,
|
||||
CallSignatureDeclaration,
|
||||
ClassExpression,
|
||||
ComputedPropertyName,
|
||||
ConstructorDeclaration,
|
||||
ConstructSignatureDeclaration,
|
||||
createDiagnosticForNode,
|
||||
Debug,
|
||||
Declaration,
|
||||
DeclarationName,
|
||||
DiagnosticMessage,
|
||||
Diagnostics,
|
||||
DiagnosticWithLocation,
|
||||
ElementAccessExpression,
|
||||
EmitResolver,
|
||||
ExportAssignment,
|
||||
Expression,
|
||||
ExpressionWithTypeArguments,
|
||||
findAncestor,
|
||||
FunctionDeclaration,
|
||||
FunctionExpression,
|
||||
GetAccessorDeclaration,
|
||||
getAllAccessorDeclarations,
|
||||
getNameOfDeclaration,
|
||||
getTextOfNode,
|
||||
hasSyntacticModifier,
|
||||
ImportEqualsDeclaration,
|
||||
IndexSignatureDeclaration,
|
||||
isAsExpression,
|
||||
isBinaryExpression,
|
||||
isBindingElement,
|
||||
isCallSignatureDeclaration,
|
||||
@@ -24,6 +40,7 @@ import {
|
||||
isConstructorDeclaration,
|
||||
isConstructSignatureDeclaration,
|
||||
isElementAccessExpression,
|
||||
isExportAssignment,
|
||||
isExpressionWithTypeArguments,
|
||||
isFunctionDeclaration,
|
||||
isGetAccessor,
|
||||
@@ -35,12 +52,15 @@ import {
|
||||
isMethodSignature,
|
||||
isParameter,
|
||||
isParameterPropertyDeclaration,
|
||||
isParenthesizedExpression,
|
||||
isPropertyAccessExpression,
|
||||
isPropertyDeclaration,
|
||||
isPropertySignature,
|
||||
isSetAccessor,
|
||||
isStatement,
|
||||
isStatic,
|
||||
isTypeAliasDeclaration,
|
||||
isTypeAssertionExpression,
|
||||
isTypeParameterDeclaration,
|
||||
isVariableDeclaration,
|
||||
JSDocCallbackTag,
|
||||
@@ -53,10 +73,14 @@ import {
|
||||
Node,
|
||||
ParameterDeclaration,
|
||||
PropertyAccessExpression,
|
||||
PropertyAssignment,
|
||||
PropertyDeclaration,
|
||||
PropertySignature,
|
||||
QualifiedName,
|
||||
SetAccessorDeclaration,
|
||||
ShorthandPropertyAssignment,
|
||||
SpreadAssignment,
|
||||
SpreadElement,
|
||||
SymbolAccessibility,
|
||||
SymbolAccessibilityResult,
|
||||
SyntaxKind,
|
||||
@@ -569,3 +593,200 @@ export function createGetSymbolAccessibilityDiagnosticForNode(node: DeclarationD
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
|
||||
const relatedSuggestionByDeclarationKind = {
|
||||
[SyntaxKind.ArrowFunction]: Diagnostics.Add_a_return_type_to_the_function_expression,
|
||||
[SyntaxKind.FunctionExpression]: Diagnostics.Add_a_return_type_to_the_function_expression,
|
||||
[SyntaxKind.MethodDeclaration]: Diagnostics.Add_a_return_type_to_the_method,
|
||||
[SyntaxKind.GetAccessor]: Diagnostics.Add_a_return_type_to_the_get_accessor_declaration,
|
||||
[SyntaxKind.SetAccessor]: Diagnostics.Add_a_type_to_parameter_of_the_set_accessor_declaration,
|
||||
[SyntaxKind.FunctionDeclaration]: Diagnostics.Add_a_return_type_to_the_function_declaration,
|
||||
[SyntaxKind.ConstructSignature]: Diagnostics.Add_a_return_type_to_the_function_declaration,
|
||||
[SyntaxKind.Parameter]: Diagnostics.Add_a_type_annotation_to_the_parameter_0,
|
||||
[SyntaxKind.VariableDeclaration]: Diagnostics.Add_a_type_annotation_to_the_variable_0,
|
||||
[SyntaxKind.PropertyDeclaration]: Diagnostics.Add_a_type_annotation_to_the_property_0,
|
||||
[SyntaxKind.PropertySignature]: Diagnostics.Add_a_type_annotation_to_the_property_0,
|
||||
[SyntaxKind.ExportAssignment]: Diagnostics.Move_the_expression_in_default_export_to_a_variable_and_add_a_type_annotation_to_it,
|
||||
} satisfies Partial<Record<SyntaxKind, DiagnosticMessage>>;
|
||||
|
||||
const errorByDeclarationKind = {
|
||||
[SyntaxKind.FunctionExpression]: Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.FunctionDeclaration]: Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.ArrowFunction]: Diagnostics.Function_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.MethodDeclaration]: Diagnostics.Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.ConstructSignature]: Diagnostics.Method_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.GetAccessor]: Diagnostics.At_least_one_accessor_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.SetAccessor]: Diagnostics.At_least_one_accessor_must_have_an_explicit_return_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.Parameter]: Diagnostics.Parameter_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.VariableDeclaration]: Diagnostics.Variable_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.PropertyDeclaration]: Diagnostics.Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.PropertySignature]: Diagnostics.Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations,
|
||||
[SyntaxKind.ComputedPropertyName]: Diagnostics.Computed_properties_must_be_number_or_string_literals_variables_or_dotted_expressions_with_isolatedDeclarations,
|
||||
[SyntaxKind.SpreadAssignment]: Diagnostics.Objects_that_contain_spread_assignments_can_t_be_inferred_with_isolatedDeclarations,
|
||||
[SyntaxKind.ShorthandPropertyAssignment]: Diagnostics.Objects_that_contain_shorthand_properties_can_t_be_inferred_with_isolatedDeclarations,
|
||||
[SyntaxKind.ArrayLiteralExpression]: Diagnostics.Only_const_arrays_can_be_inferred_with_isolatedDeclarations,
|
||||
[SyntaxKind.ExportAssignment]: Diagnostics.Default_exports_can_t_be_inferred_with_isolatedDeclarations,
|
||||
[SyntaxKind.SpreadElement]: Diagnostics.Arrays_with_spread_elements_can_t_inferred_with_isolatedDeclarations,
|
||||
} satisfies Partial<Record<SyntaxKind, DiagnosticMessage>>;
|
||||
|
||||
return getDiagnostic;
|
||||
|
||||
type WithIsolatedDeclarationDiagnostic =
|
||||
| GetAccessorDeclaration
|
||||
| SetAccessorDeclaration
|
||||
| ShorthandPropertyAssignment
|
||||
| SpreadAssignment
|
||||
| ComputedPropertyName
|
||||
| ArrayLiteralExpression
|
||||
| SpreadElement
|
||||
| FunctionDeclaration
|
||||
| FunctionExpression
|
||||
| ArrowFunction
|
||||
| MethodDeclaration
|
||||
| ConstructSignatureDeclaration
|
||||
| BindingElement
|
||||
| VariableDeclaration
|
||||
| PropertyDeclaration
|
||||
| ParameterDeclaration
|
||||
| PropertyAssignment
|
||||
| ClassExpression;
|
||||
|
||||
function getDiagnostic(node: Node) {
|
||||
const heritageClause = findAncestor(node, isHeritageClause);
|
||||
if (heritageClause) {
|
||||
return createDiagnosticForNode(node, Diagnostics.Extends_clause_can_t_contain_an_expression_with_isolatedDeclarations);
|
||||
}
|
||||
Debug.type<WithIsolatedDeclarationDiagnostic>(node);
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
return createAccessorTypeError(node);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
case SyntaxKind.SpreadAssignment:
|
||||
return createObjectLiteralError(node);
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.SpreadElement:
|
||||
return createArrayLiteralError(node);
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return createReturnTypeError(node);
|
||||
case SyntaxKind.BindingElement:
|
||||
return createBindingElementError(node);
|
||||
case SyntaxKind.PropertyDeclaration:
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return createVariableOrPropertyError(node);
|
||||
case SyntaxKind.Parameter:
|
||||
return createParameterError(node);
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
return createExpressionError(node.initializer);
|
||||
case SyntaxKind.ClassExpression:
|
||||
return createClassExpressionError(node);
|
||||
default:
|
||||
assertType<never>(node);
|
||||
return createExpressionError(node as Expression);
|
||||
}
|
||||
}
|
||||
|
||||
function findNearestDeclaration(node: Node) {
|
||||
const result = findAncestor(node, n => isExportAssignment(n) || (isStatement(n) ? "quit" : isVariableDeclaration(n) || isPropertyDeclaration(n) || isParameter(n)));
|
||||
return result as VariableDeclaration | PropertyDeclaration | ParameterDeclaration | ExportAssignment | undefined;
|
||||
}
|
||||
|
||||
function createAccessorTypeError(node: GetAccessorDeclaration | SetAccessorDeclaration) {
|
||||
const { getAccessor, setAccessor } = getAllAccessorDeclarations(node.symbol.declarations, node);
|
||||
|
||||
const targetNode = (isSetAccessor(node) ? node.parameters[0] : node) ?? node;
|
||||
const diag = createDiagnosticForNode(targetNode, errorByDeclarationKind[node.kind]);
|
||||
|
||||
if (setAccessor) {
|
||||
addRelatedInfo(diag, createDiagnosticForNode(setAccessor, relatedSuggestionByDeclarationKind[setAccessor.kind]));
|
||||
}
|
||||
if (getAccessor) {
|
||||
addRelatedInfo(diag, createDiagnosticForNode(getAccessor, relatedSuggestionByDeclarationKind[getAccessor.kind]));
|
||||
}
|
||||
return diag;
|
||||
}
|
||||
function createObjectLiteralError(node: ShorthandPropertyAssignment | SpreadAssignment | ComputedPropertyName) {
|
||||
const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
|
||||
const parentDeclaration = findNearestDeclaration(node);
|
||||
if (parentDeclaration) {
|
||||
const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
|
||||
}
|
||||
return diag;
|
||||
}
|
||||
function createArrayLiteralError(node: ArrayLiteralExpression | SpreadElement) {
|
||||
const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
|
||||
const parentDeclaration = findNearestDeclaration(node);
|
||||
if (parentDeclaration) {
|
||||
const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
|
||||
}
|
||||
return diag;
|
||||
}
|
||||
function createReturnTypeError(node: FunctionDeclaration | FunctionExpression | ArrowFunction | MethodDeclaration | ConstructSignatureDeclaration) {
|
||||
const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
|
||||
const parentDeclaration = findNearestDeclaration(node);
|
||||
if (parentDeclaration) {
|
||||
const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
|
||||
}
|
||||
addRelatedInfo(diag, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind]));
|
||||
return diag;
|
||||
}
|
||||
function createBindingElementError(node: BindingElement) {
|
||||
return createDiagnosticForNode(node, Diagnostics.Binding_elements_can_t_be_exported_directly_with_isolatedDeclarations);
|
||||
}
|
||||
function createVariableOrPropertyError(node: VariableDeclaration | PropertyDeclaration) {
|
||||
const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
|
||||
const targetStr = getTextOfNode(node.name, /*includeTrivia*/ false);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind], targetStr));
|
||||
return diag;
|
||||
}
|
||||
function createParameterError(node: ParameterDeclaration) {
|
||||
if (isSetAccessor(node.parent)) {
|
||||
return createAccessorTypeError(node.parent);
|
||||
}
|
||||
const addUndefined = resolver.requiresAddingImplicitUndefined(node);
|
||||
if (!addUndefined && node.initializer) {
|
||||
return createExpressionError(node.initializer);
|
||||
}
|
||||
const message = addUndefined ?
|
||||
Diagnostics.Declaration_emit_for_this_parameter_requires_implicitly_adding_undefined_to_it_s_type_This_is_not_supported_with_isolatedDeclarations :
|
||||
errorByDeclarationKind[node.kind];
|
||||
const diag = createDiagnosticForNode(node, message);
|
||||
const targetStr = getTextOfNode(node.name, /*includeTrivia*/ false);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind], targetStr));
|
||||
return diag;
|
||||
}
|
||||
function createClassExpressionError(node: Expression) {
|
||||
return createExpressionError(node, Diagnostics.Inference_from_class_expressions_is_not_supported_with_isolatedDeclarations);
|
||||
}
|
||||
function createExpressionError(node: Expression, diagnosticMessage?: DiagnosticMessage) {
|
||||
const parentDeclaration = findNearestDeclaration(node);
|
||||
let diag: DiagnosticWithLocation;
|
||||
if (parentDeclaration) {
|
||||
const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
|
||||
const parent = findAncestor(node.parent, n => isExportAssignment(n) || (isStatement(n) ? "quit" : !isParenthesizedExpression(n) && !isTypeAssertionExpression(n) && !isAsExpression(n)));
|
||||
if (parentDeclaration === parent) {
|
||||
diag = createDiagnosticForNode(node, diagnosticMessage ?? errorByDeclarationKind[parentDeclaration.kind]);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
|
||||
}
|
||||
else {
|
||||
diag = createDiagnosticForNode(node, diagnosticMessage ?? Diagnostics.Expression_type_can_t_be_inferred_with_isolatedDeclarations);
|
||||
addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
|
||||
addRelatedInfo(diag, createDiagnosticForNode(node, Diagnostics.Add_satisfies_and_a_type_assertion_to_this_expression_satisfies_T_as_T_to_make_the_type_explicit));
|
||||
}
|
||||
}
|
||||
else {
|
||||
diag = createDiagnosticForNode(node, diagnosticMessage ?? Diagnostics.Expression_type_can_t_be_inferred_with_isolatedDeclarations);
|
||||
}
|
||||
return diag;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -14,7 +14,7 @@ import {
|
||||
} from "../../_namespaces/ts";
|
||||
|
||||
/** @internal */
|
||||
export function transformNodeModule(context: TransformationContext) {
|
||||
export function transformImpliedNodeFormatDependentModule(context: TransformationContext) {
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
const previousOnEmitNode = context.onEmitNode;
|
||||
|
||||
@@ -30,6 +30,7 @@ export function transformNodeModule(context: TransformationContext) {
|
||||
|
||||
const cjsOnSubstituteNode = context.onSubstituteNode;
|
||||
const cjsOnEmitNode = context.onEmitNode;
|
||||
const getEmitModuleFormatOfFile = (file: SourceFile) => context.getEmitHost().getEmitModuleFormatOfFile(file);
|
||||
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
context.onEmitNode = onEmitNode;
|
||||
@@ -51,7 +52,7 @@ export function transformNodeModule(context: TransformationContext) {
|
||||
if (!currentSourceFile) {
|
||||
return previousOnSubstituteNode(hint, node);
|
||||
}
|
||||
if (currentSourceFile.impliedNodeFormat === ModuleKind.ESNext) {
|
||||
if (getEmitModuleFormatOfFile(currentSourceFile) >= ModuleKind.ES2015) {
|
||||
return esmOnSubstituteNode(hint, node);
|
||||
}
|
||||
return cjsOnSubstituteNode(hint, node);
|
||||
@@ -65,14 +66,14 @@ export function transformNodeModule(context: TransformationContext) {
|
||||
if (!currentSourceFile) {
|
||||
return previousOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
if (currentSourceFile.impliedNodeFormat === ModuleKind.ESNext) {
|
||||
if (getEmitModuleFormatOfFile(currentSourceFile) >= ModuleKind.ES2015) {
|
||||
return esmOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
return cjsOnEmitNode(hint, node, emitCallback);
|
||||
}
|
||||
|
||||
function getModuleTransformForFile(file: SourceFile): typeof esmTransform {
|
||||
return file.impliedNodeFormat === ModuleKind.ESNext ? esmTransform : cjsTransform;
|
||||
return getEmitModuleFormatOfFile(file) >= ModuleKind.ES2015 ? esmTransform : cjsTransform;
|
||||
}
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
@@ -56,6 +56,7 @@ import {
|
||||
getOriginalNodeId,
|
||||
getStrictOptionValue,
|
||||
getTextOfIdentifierOrLiteral,
|
||||
hasJSFileExtension,
|
||||
hasJsonModuleEmitEnabled,
|
||||
hasSyntacticModifier,
|
||||
Identifier,
|
||||
@@ -243,6 +244,9 @@ export function transformModule(context: TransformationContext): (x: SourceFile
|
||||
}
|
||||
|
||||
function shouldEmitUnderscoreUnderscoreESModule() {
|
||||
if (hasJSFileExtension(currentSourceFile.fileName) && currentSourceFile.commonJsModuleIndicator && (!currentSourceFile.externalModuleIndicator || currentSourceFile.externalModuleIndicator === true)) {
|
||||
return false;
|
||||
}
|
||||
if (!currentModuleInfo.exportEquals && isExternalModule(currentSourceFile)) {
|
||||
return true;
|
||||
}
|
||||
@@ -785,7 +789,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile
|
||||
case SyntaxKind.PartiallyEmittedExpression:
|
||||
return visitPartiallyEmittedExpression(node as PartiallyEmittedExpression, valueIsDiscarded);
|
||||
case SyntaxKind.CallExpression:
|
||||
if (isImportCall(node) && currentSourceFile.impliedNodeFormat === undefined) {
|
||||
if (isImportCall(node) && host.shouldTransformImportCall(currentSourceFile)) {
|
||||
return visitImportCallExpression(node);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -118,6 +118,7 @@ import {
|
||||
isPrivateIdentifier,
|
||||
isPropertyAccessExpression,
|
||||
isPropertyName,
|
||||
isSatisfiesExpression,
|
||||
isShorthandPropertyAssignment,
|
||||
isSimpleInlineableExpression,
|
||||
isSourceFile,
|
||||
@@ -1689,7 +1690,7 @@ export function transformTypeScript(context: TransformationContext) {
|
||||
|
||||
function visitParenthesizedExpression(node: ParenthesizedExpression): Expression {
|
||||
const innerExpression = skipOuterExpressions(node.expression, ~OuterExpressionKinds.Assertions);
|
||||
if (isAssertionExpression(innerExpression)) {
|
||||
if (isAssertionExpression(innerExpression) || isSatisfiesExpression(innerExpression)) {
|
||||
// Make sure we consider all nested cast expressions, e.g.:
|
||||
// (<any><number><any>-A).x;
|
||||
const expression = visitNode(node.expression, visitor, isExpression);
|
||||
|
||||
+173
-20
@@ -1380,6 +1380,16 @@ export type HasIllegalModifiers =
|
||||
| MissingDeclaration
|
||||
| NamespaceExportDeclaration;
|
||||
|
||||
/** @internal */
|
||||
export type PrimitiveLiteral =
|
||||
| BooleanLiteral
|
||||
| NumericLiteral
|
||||
| StringLiteral
|
||||
| NoSubstitutionTemplateLiteral
|
||||
| BigIntLiteral
|
||||
| PrefixUnaryExpression & { operator: SyntaxKind.PlusToken; operand: NumericLiteral; }
|
||||
| PrefixUnaryExpression & { operator: SyntaxKind.MinusToken; operand: NumericLiteral | BigIntLiteral; };
|
||||
|
||||
/**
|
||||
* Declarations that can contain other declarations. Corresponds with `ContainerFlags.IsContainer` in binder.ts.
|
||||
*
|
||||
@@ -2752,6 +2762,22 @@ export interface RegularExpressionLiteral extends LiteralExpression {
|
||||
readonly kind: SyntaxKind.RegularExpressionLiteral;
|
||||
}
|
||||
|
||||
// dprint-ignore
|
||||
/** @internal */
|
||||
export const enum RegularExpressionFlags {
|
||||
None = 0,
|
||||
HasIndices = 1 << 0, // d
|
||||
Global = 1 << 1, // g
|
||||
IgnoreCase = 1 << 2, // i
|
||||
Multiline = 1 << 3, // m
|
||||
DotAll = 1 << 4, // s
|
||||
Unicode = 1 << 5, // u
|
||||
UnicodeSets = 1 << 6, // v
|
||||
Sticky = 1 << 7, // y
|
||||
UnicodeMode = Unicode | UnicodeSets,
|
||||
Modifiers = IgnoreCase | Multiline | DotAll,
|
||||
}
|
||||
|
||||
export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode, Declaration {
|
||||
readonly kind: SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||
/** @internal */
|
||||
@@ -4217,6 +4243,18 @@ export interface SourceFileLike {
|
||||
getPositionOfLineAndCharacter?(line: number, character: number, allowEdits?: true): number;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface FutureSourceFile {
|
||||
readonly path: Path;
|
||||
readonly fileName: string;
|
||||
readonly impliedNodeFormat?: ResolutionMode;
|
||||
readonly packageJsonScope?: PackageJsonInfo;
|
||||
readonly externalModuleIndicator?: true | undefined;
|
||||
readonly commonJsModuleIndicator?: true | undefined;
|
||||
readonly statements: readonly never[];
|
||||
readonly imports: readonly never[];
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface RedirectInfo {
|
||||
/** Source file this redirects to. */
|
||||
@@ -4708,21 +4746,79 @@ export interface Program extends ScriptReferenceHost {
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
isSourceFileDefaultLibrary(file: SourceFile): boolean;
|
||||
/**
|
||||
* Calculates the final resolution mode for a given module reference node. This is the resolution mode explicitly provided via import
|
||||
* attributes, if present, or the syntax the usage would have if emitted to JavaScript. In `--module node16` or `nodenext`, this may
|
||||
* depend on the file's `impliedNodeFormat`. In `--module preserve`, it depends only on the input syntax of the reference. In other
|
||||
* `module` modes, when overriding import attributes are not provided, this function returns `undefined`, as the result would have no
|
||||
* impact on module resolution, emit, or type checking.
|
||||
* Calculates the final resolution mode for a given module reference node. This function only returns a result when module resolution
|
||||
* settings allow differing resolution between ESM imports and CJS requires, or when a mode is explicitly provided via import attributes,
|
||||
* which cause an `import` or `require` condition to be used during resolution regardless of module resolution settings. In absence of
|
||||
* overriding attributes, and in modes that support differing resolution, the result indicates the syntax the usage would emit to JavaScript.
|
||||
* Some examples:
|
||||
*
|
||||
* ```ts
|
||||
* // tsc foo.mts --module nodenext
|
||||
* import {} from "mod";
|
||||
* // Result: ESNext - the import emits as ESM due to `impliedNodeFormat` set by .mts file extension
|
||||
*
|
||||
* // tsc foo.cts --module nodenext
|
||||
* import {} from "mod";
|
||||
* // Result: CommonJS - the import emits as CJS due to `impliedNodeFormat` set by .cts file extension
|
||||
*
|
||||
* // tsc foo.ts --module preserve --moduleResolution bundler
|
||||
* import {} from "mod";
|
||||
* // Result: ESNext - the import emits as ESM due to `--module preserve` and `--moduleResolution bundler`
|
||||
* // supports conditional imports/exports
|
||||
*
|
||||
* // tsc foo.ts --module preserve --moduleResolution node10
|
||||
* import {} from "mod";
|
||||
* // Result: undefined - the import emits as ESM due to `--module preserve`, but `--moduleResolution node10`
|
||||
* // does not support conditional imports/exports
|
||||
*
|
||||
* // tsc foo.ts --module commonjs --moduleResolution node10
|
||||
* import type {} from "mod" with { "resolution-mode": "import" };
|
||||
* // Result: ESNext - conditional imports/exports always supported with "resolution-mode" attribute
|
||||
* ```
|
||||
*/
|
||||
getModeForUsageLocation(file: SourceFile, usage: StringLiteralLike): ResolutionMode;
|
||||
/**
|
||||
* Calculates the final resolution mode for an import at some index within a file's `imports` list. This is the resolution mode
|
||||
* explicitly provided via import attributes, if present, or the syntax the usage would have if emitted to JavaScript. In
|
||||
* `--module node16` or `nodenext`, this may depend on the file's `impliedNodeFormat`. In `--module preserve`, it depends only on the
|
||||
* input syntax of the reference. In other `module` modes, when overriding import attributes are not provided, this function returns
|
||||
* `undefined`, as the result would have no impact on module resolution, emit, or type checking.
|
||||
* Calculates the final resolution mode for an import at some index within a file's `imports` list. This function only returns a result
|
||||
* when module resolution settings allow differing resolution between ESM imports and CJS requires, or when a mode is explicitly provided
|
||||
* via import attributes, which cause an `import` or `require` condition to be used during resolution regardless of module resolution
|
||||
* settings. In absence of overriding attributes, and in modes that support differing resolution, the result indicates the syntax the
|
||||
* usage would emit to JavaScript. Some examples:
|
||||
*
|
||||
* ```ts
|
||||
* // tsc foo.mts --module nodenext
|
||||
* import {} from "mod";
|
||||
* // Result: ESNext - the import emits as ESM due to `impliedNodeFormat` set by .mts file extension
|
||||
*
|
||||
* // tsc foo.cts --module nodenext
|
||||
* import {} from "mod";
|
||||
* // Result: CommonJS - the import emits as CJS due to `impliedNodeFormat` set by .cts file extension
|
||||
*
|
||||
* // tsc foo.ts --module preserve --moduleResolution bundler
|
||||
* import {} from "mod";
|
||||
* // Result: ESNext - the import emits as ESM due to `--module preserve` and `--moduleResolution bundler`
|
||||
* // supports conditional imports/exports
|
||||
*
|
||||
* // tsc foo.ts --module preserve --moduleResolution node10
|
||||
* import {} from "mod";
|
||||
* // Result: undefined - the import emits as ESM due to `--module preserve`, but `--moduleResolution node10`
|
||||
* // does not support conditional imports/exports
|
||||
*
|
||||
* // tsc foo.ts --module commonjs --moduleResolution node10
|
||||
* import type {} from "mod" with { "resolution-mode": "import" };
|
||||
* // Result: ESNext - conditional imports/exports always supported with "resolution-mode" attribute
|
||||
* ```
|
||||
*/
|
||||
getModeForResolutionAtIndex(file: SourceFile, index: number): ResolutionMode;
|
||||
/**
|
||||
* @internal
|
||||
* The resolution mode to use for module resolution or module specifier resolution
|
||||
* outside the context of an existing module reference, where
|
||||
* `program.getModeForUsageLocation` should be used instead.
|
||||
*/
|
||||
getDefaultResolutionModeForFile(sourceFile: SourceFile): ResolutionMode;
|
||||
/** @internal */ getImpliedNodeFormatForEmit(sourceFile: SourceFile): ResolutionMode;
|
||||
/** @internal */ getEmitModuleFormatOfFile(sourceFile: SourceFile): ModuleKind;
|
||||
/** @internal */ shouldTransformImportCall(sourceFile: SourceFile): boolean;
|
||||
|
||||
// For testing purposes only.
|
||||
// This is set on created program to let us know how the program was created using old program
|
||||
@@ -4777,6 +4873,7 @@ export interface Program extends ScriptReferenceHost {
|
||||
/** @internal */ getResolvedProjectReferenceByPath(projectReferencePath: Path): ResolvedProjectReference | undefined;
|
||||
/** @internal */ getRedirectReferenceForResolutionFromSourceOfProject(filePath: Path): ResolvedProjectReference | undefined;
|
||||
/** @internal */ isSourceOfProjectReferenceRedirect(fileName: string): boolean;
|
||||
/** @internal */ getCompilerOptionsForFile(file: SourceFile): CompilerOptions;
|
||||
/** @internal */ getBuildInfo?(): BuildInfo;
|
||||
/** @internal */ emitBuildInfo(writeFile?: WriteFileCallback, cancellationToken?: CancellationToken): EmitResult;
|
||||
/**
|
||||
@@ -4892,8 +4989,12 @@ export interface TypeCheckerHost extends ModuleSpecifierResolutionHost {
|
||||
getSourceFile(fileName: string): SourceFile | undefined;
|
||||
getProjectReferenceRedirect(fileName: string): string | undefined;
|
||||
isSourceOfProjectReferenceRedirect(fileName: string): boolean;
|
||||
getEmitSyntaxForUsageLocation(file: SourceFile, usage: StringLiteralLike): ResolutionMode;
|
||||
getRedirectReferenceForResolutionFromSourceOfProject(filePath: Path): ResolvedProjectReference | undefined;
|
||||
getModeForUsageLocation(file: SourceFile, usage: StringLiteralLike): ResolutionMode;
|
||||
getDefaultResolutionModeForFile(sourceFile: SourceFile): ResolutionMode;
|
||||
getImpliedNodeFormatForEmit(sourceFile: SourceFile): ResolutionMode;
|
||||
getEmitModuleFormatOfFile(sourceFile: SourceFile): ModuleKind;
|
||||
|
||||
getResolvedModule(f: SourceFile, moduleName: string, mode: ResolutionMode): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
|
||||
@@ -5319,7 +5420,7 @@ export const enum NodeBuilderFlags {
|
||||
AllowUniqueESSymbolType = 1 << 20,
|
||||
AllowEmptyIndexInfoType = 1 << 21,
|
||||
/** @internal */ WriteComputedProps = 1 << 30, // { [E.A]: 1 }
|
||||
|
||||
/** @internal */ NoSyntacticPrinter = 1 << 31,
|
||||
// Errors (cont.)
|
||||
AllowNodeModulesRelativePaths = 1 << 26,
|
||||
/** @internal */ DoNotIncludeSymbolChain = 1 << 27, // Skip looking up and printing an accessible symbol chain
|
||||
@@ -5548,6 +5649,9 @@ export interface RequireVariableDeclarationList extends VariableDeclarationList
|
||||
readonly declarations: NodeArray<VariableDeclarationInitializedTo<RequireOrImportCall>>;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export type CanHaveModuleSpecifier = AnyImportOrBareOrAccessedRequire | AliasDeclarationNode | ExportDeclaration | ImportTypeNode;
|
||||
|
||||
/** @internal */
|
||||
export type LateVisibilityPaintedStatement =
|
||||
| AnyImportOrJsDocImport
|
||||
@@ -5637,6 +5741,7 @@ export enum TypeReferenceSerializationKind {
|
||||
|
||||
/** @internal */
|
||||
export interface EmitResolver {
|
||||
isNonNarrowedBindableName(node: ComputedPropertyName): boolean;
|
||||
hasGlobalName(name: string): boolean;
|
||||
getReferencedExportContainer(node: Identifier, prefixLocals?: boolean): SourceFile | ModuleDeclaration | EnumDeclaration | undefined;
|
||||
getReferencedImportDeclaration(node: Identifier): Declaration | undefined;
|
||||
@@ -5651,9 +5756,9 @@ export interface EmitResolver {
|
||||
collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined;
|
||||
isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined;
|
||||
requiresAddingImplicitUndefined(node: ParameterDeclaration): boolean;
|
||||
isExpandoFunctionDeclaration(node: FunctionDeclaration): boolean;
|
||||
isExpandoFunctionDeclaration(node: FunctionDeclaration | VariableDeclaration): boolean;
|
||||
getPropertiesOfContainerFunction(node: Declaration): Symbol[];
|
||||
createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression | ElementAccessExpression | BinaryExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean): TypeNode | undefined;
|
||||
createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression | ElementAccessExpression | BinaryExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
|
||||
createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
|
||||
createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
|
||||
createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker): Expression;
|
||||
@@ -5998,6 +6103,7 @@ export interface EvaluatorResult<T extends string | number | undefined = string
|
||||
value: T;
|
||||
isSyntacticallyString: boolean;
|
||||
resolvedOtherFiles: boolean;
|
||||
hasExternalReferences: boolean;
|
||||
}
|
||||
|
||||
// dprint-ignore
|
||||
@@ -7088,7 +7194,7 @@ export enum PollingWatchKind {
|
||||
FixedChunkSize,
|
||||
}
|
||||
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[] | ProjectReference[] | null | undefined;
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[] | ProjectReference[] | null | undefined; // eslint-disable-line no-restricted-syntax
|
||||
|
||||
export interface CompilerOptions {
|
||||
/** @internal */ all?: boolean;
|
||||
@@ -7147,6 +7253,7 @@ export interface CompilerOptions {
|
||||
inlineSourceMap?: boolean;
|
||||
inlineSources?: boolean;
|
||||
isolatedModules?: boolean;
|
||||
isolatedDeclarations?: boolean;
|
||||
jsx?: JsxEmit;
|
||||
/** @deprecated */
|
||||
keyofStringsOnly?: boolean;
|
||||
@@ -7351,6 +7458,7 @@ export const enum ScriptTarget {
|
||||
ES2020 = 7,
|
||||
ES2021 = 8,
|
||||
ES2022 = 9,
|
||||
ES2023 = 10,
|
||||
ESNext = 99,
|
||||
JSON = 100,
|
||||
Latest = ESNext,
|
||||
@@ -7393,6 +7501,9 @@ export interface ConfigFileSpecs {
|
||||
validatedFilesSpec: readonly string[] | undefined;
|
||||
validatedIncludeSpecs: readonly string[] | undefined;
|
||||
validatedExcludeSpecs: readonly string[] | undefined;
|
||||
validatedFilesSpecBeforeSubstitution: readonly string[] | undefined;
|
||||
validatedIncludeSpecsBeforeSubstitution: readonly string[] | undefined;
|
||||
validatedExcludeSpecsBeforeSubstitution: readonly string[] | undefined;
|
||||
pathPatterns: readonly (string | Pattern)[] | undefined;
|
||||
isDefaultIncludeSpec: boolean;
|
||||
}
|
||||
@@ -7439,7 +7550,8 @@ export interface CommandLineOptionBase {
|
||||
affectsBuildInfo?: true; // true if this options should be emitted in buildInfo
|
||||
transpileOptionValue?: boolean | undefined; // If set this means that the option should be set to this value when transpiling
|
||||
extraValidation?: (value: CompilerOptionsValue) => [DiagnosticMessage, ...string[]] | undefined; // Additional validation to be performed for the value to be valid
|
||||
disallowNullOrUndefined?: true; // If set option does not allow setting null
|
||||
disallowNullOrUndefined?: true; // If set option does not allow setting null
|
||||
allowConfigDirTemplateSubstitution?: true; // If set option allows substitution of `${configDir}` in the value
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -7530,6 +7642,9 @@ export const enum CharacterCodes {
|
||||
mathematicalSpace = 0x205F,
|
||||
ogham = 0x1680,
|
||||
|
||||
// Unicode replacement character produced when a byte sequence is invalid
|
||||
replacementCharacter = 0xFFFD,
|
||||
|
||||
_ = 0x5F,
|
||||
$ = 0x24,
|
||||
|
||||
@@ -8244,6 +8359,8 @@ export interface EmitHost extends ScriptReferenceHost, ModuleSpecifierResolution
|
||||
getCanonicalFileName(fileName: string): string;
|
||||
|
||||
isEmitBlocked(emitFileName: string): boolean;
|
||||
shouldTransformImportCall(sourceFile: SourceFile): boolean;
|
||||
getEmitModuleFormatOfFile(sourceFile: SourceFile): ModuleKind;
|
||||
|
||||
writeFile: WriteFileCallback;
|
||||
getBuildInfo(): BuildInfo | undefined;
|
||||
@@ -8919,7 +9036,7 @@ export interface NodeFactory {
|
||||
// Synthetic Nodes
|
||||
//
|
||||
/** @internal */ createSyntheticExpression(type: Type, isSpread?: boolean, tupleNameSource?: ParameterDeclaration | NamedTupleMember): SyntheticExpression;
|
||||
/** @internal */ createSyntaxList(children: Node[]): SyntaxList;
|
||||
/** @internal */ createSyntaxList(children: readonly Node[]): SyntaxList;
|
||||
|
||||
//
|
||||
// Transformation nodes
|
||||
@@ -9485,6 +9602,7 @@ export interface PrinterOptions {
|
||||
omitTrailingSemicolon?: boolean;
|
||||
noEmitHelpers?: boolean;
|
||||
/** @internal */ module?: CompilerOptions["module"];
|
||||
/** @internal */ moduleResolution?: CompilerOptions["moduleResolution"];
|
||||
/** @internal */ target?: CompilerOptions["target"];
|
||||
/** @internal */ sourceMap?: boolean;
|
||||
/** @internal */ inlineSourceMap?: boolean;
|
||||
@@ -9502,11 +9620,11 @@ export interface PrinterOptions {
|
||||
export interface RawSourceMap {
|
||||
version: 3;
|
||||
file: string;
|
||||
sourceRoot?: string | null;
|
||||
sourceRoot?: string | null; // eslint-disable-line no-restricted-syntax
|
||||
sources: string[];
|
||||
sourcesContent?: (string | null)[] | null;
|
||||
sourcesContent?: (string | null)[] | null; // eslint-disable-line no-restricted-syntax
|
||||
mappings: string;
|
||||
names?: string[] | null;
|
||||
names?: string[] | null; // eslint-disable-line no-restricted-syntax
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -9523,7 +9641,7 @@ export interface SourceMapGenerator {
|
||||
/**
|
||||
* Set the content for a source.
|
||||
*/
|
||||
setSourceContent(sourceIndex: number, content: string | null): void;
|
||||
setSourceContent(sourceIndex: number, content: string | null): void; // eslint-disable-line no-restricted-syntax
|
||||
/**
|
||||
* Adds a name.
|
||||
*/
|
||||
@@ -9619,6 +9737,11 @@ export interface ModuleSpecifierResolutionHost {
|
||||
isSourceOfProjectReferenceRedirect(fileName: string): boolean;
|
||||
getFileIncludeReasons(): MultiMap<Path, FileIncludeReason>;
|
||||
getCommonSourceDirectory(): string;
|
||||
getDefaultResolutionModeForFile(sourceFile: SourceFile): ResolutionMode;
|
||||
getModeForResolutionAtIndex(file: SourceFile, index: number): ResolutionMode;
|
||||
|
||||
getModuleResolutionCache?(): ModuleResolutionCache | undefined;
|
||||
trace?(s: string): void;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -9666,6 +9789,7 @@ export interface SymbolTracker {
|
||||
moduleResolverHost?: ModuleSpecifierResolutionHost & { getCommonSourceDirectory(): string; };
|
||||
reportNonlocalAugmentation?(containingFile: SourceFile, parentSymbol: Symbol, augmentingSymbol: Symbol): void;
|
||||
reportNonSerializableProperty?(propertyName: string): void;
|
||||
reportInferenceFallback?(node: Node): void;
|
||||
}
|
||||
|
||||
export interface TextSpan {
|
||||
@@ -10120,3 +10244,32 @@ export interface EvaluationResolver {
|
||||
evaluateEntityNameExpression(expr: EntityNameExpression, location: Declaration | undefined): EvaluatorResult;
|
||||
evaluateElementAccessExpression(expr: ElementAccessExpression, location: Declaration | undefined): EvaluatorResult;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export type HasInferredType =
|
||||
| PropertyAssignment
|
||||
| PropertyAccessExpression
|
||||
| BinaryExpression
|
||||
| ElementAccessExpression
|
||||
| VariableDeclaration
|
||||
| ParameterDeclaration
|
||||
| BindingElement
|
||||
| PropertyDeclaration
|
||||
| PropertySignature
|
||||
| ExportAssignment;
|
||||
|
||||
/** @internal */
|
||||
export interface SyntacticTypeNodeBuilderContext {
|
||||
tracker: Required<Pick<SymbolTracker, "reportInferenceFallback">>;
|
||||
enclosingDeclaration: Node | undefined;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export interface SyntacticTypeNodeBuilderResolver {
|
||||
isUndefinedIdentifierExpression(name: Identifier): boolean;
|
||||
isNonNarrowedBindableName(name: ComputedPropertyName): boolean;
|
||||
isExpandoFunctionDeclaration(name: FunctionDeclaration | VariableDeclaration): boolean;
|
||||
getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations;
|
||||
isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node, shouldComputeAliasToMakeVisible?: boolean): SymbolVisibilityResult;
|
||||
requiresAddingImplicitUndefined(parameter: ParameterDeclaration | JSDocParameterTag): boolean;
|
||||
}
|
||||
|
||||
+765
-36
File diff suppressed because it is too large
Load Diff
@@ -311,6 +311,8 @@ export function getDefaultLibFileName(options: CompilerOptions): string {
|
||||
switch (getEmitScriptTarget(options)) {
|
||||
case ScriptTarget.ESNext:
|
||||
return "lib.esnext.full.d.ts";
|
||||
case ScriptTarget.ES2023:
|
||||
return "lib.es2023.full.d.ts";
|
||||
case ScriptTarget.ES2022:
|
||||
return "lib.es2022.full.d.ts";
|
||||
case ScriptTarget.ES2021:
|
||||
|
||||
+11
-7
@@ -44,9 +44,9 @@ import {
|
||||
FileWatcher,
|
||||
filter,
|
||||
find,
|
||||
findIndex,
|
||||
flattenDiagnosticMessageText,
|
||||
forEach,
|
||||
forEachEntry,
|
||||
ForegroundColorEscapeSequences,
|
||||
formatColorAndReset,
|
||||
formatDiagnostic,
|
||||
@@ -56,7 +56,9 @@ import {
|
||||
getDefaultLibFileName,
|
||||
getDirectoryPath,
|
||||
getEmitScriptTarget,
|
||||
getImpliedNodeFormatForEmitWorker,
|
||||
getLineAndCharacterOfPosition,
|
||||
getNameOfScriptTarget,
|
||||
getNewLineCharacter,
|
||||
getNormalizedAbsolutePath,
|
||||
getParsedCommandLineOfConfigFile,
|
||||
@@ -93,7 +95,6 @@ import {
|
||||
sourceMapCommentRegExpDontCareLineStart,
|
||||
sys,
|
||||
System,
|
||||
targetOptionDeclaration,
|
||||
WatchCompilerHost,
|
||||
WatchCompilerHostOfConfigFile,
|
||||
WatchCompilerHostOfFilesAndCompilerOptions,
|
||||
@@ -352,13 +353,14 @@ export function explainFiles(program: Program, write: (s: string) => void) {
|
||||
for (const file of program.getSourceFiles()) {
|
||||
write(`${toFileName(file, relativeFileName)}`);
|
||||
reasons.get(file.path)?.forEach(reason => write(` ${fileIncludeReasonToDiagnostics(program, reason, relativeFileName).messageText}`));
|
||||
explainIfFileIsRedirectAndImpliedFormat(file, relativeFileName)?.forEach(d => write(` ${d.messageText}`));
|
||||
explainIfFileIsRedirectAndImpliedFormat(file, program.getCompilerOptionsForFile(file), relativeFileName)?.forEach(d => write(` ${d.messageText}`));
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function explainIfFileIsRedirectAndImpliedFormat(
|
||||
file: SourceFile,
|
||||
options: CompilerOptions,
|
||||
fileNameConvertor?: (fileName: string) => string,
|
||||
): DiagnosticMessageChain[] | undefined {
|
||||
let result: DiagnosticMessageChain[] | undefined;
|
||||
@@ -377,7 +379,7 @@ export function explainIfFileIsRedirectAndImpliedFormat(
|
||||
));
|
||||
}
|
||||
if (isExternalOrCommonJsModule(file)) {
|
||||
switch (file.impliedNodeFormat) {
|
||||
switch (getImpliedNodeFormatForEmitWorker(file, options)) {
|
||||
case ModuleKind.ESNext:
|
||||
if (file.packageJsonScope) {
|
||||
(result ??= []).push(chainDiagnosticMessages(
|
||||
@@ -416,7 +418,8 @@ export function getMatchedFileSpec(program: Program, fileName: string) {
|
||||
|
||||
const filePath = program.getCanonicalFileName(fileName);
|
||||
const basePath = getDirectoryPath(getNormalizedAbsolutePath(configFile.fileName, program.getCurrentDirectory()));
|
||||
return find(configFile.configFileSpecs.validatedFilesSpec, fileSpec => program.getCanonicalFileName(getNormalizedAbsolutePath(fileSpec, basePath)) === filePath);
|
||||
const index = findIndex(configFile.configFileSpecs.validatedFilesSpec, fileSpec => program.getCanonicalFileName(getNormalizedAbsolutePath(fileSpec, basePath)) === filePath);
|
||||
return index !== -1 ? configFile.configFileSpecs.validatedFilesSpecBeforeSubstitution![index] : undefined;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -430,11 +433,12 @@ export function getMatchedIncludeSpec(program: Program, fileName: string) {
|
||||
const isJsonFile = fileExtensionIs(fileName, Extension.Json);
|
||||
const basePath = getDirectoryPath(getNormalizedAbsolutePath(configFile.fileName, program.getCurrentDirectory()));
|
||||
const useCaseSensitiveFileNames = program.useCaseSensitiveFileNames();
|
||||
return find(configFile?.configFileSpecs?.validatedIncludeSpecs, includeSpec => {
|
||||
const index = findIndex(configFile?.configFileSpecs?.validatedIncludeSpecs, includeSpec => {
|
||||
if (isJsonFile && !endsWith(includeSpec, Extension.Json)) return false;
|
||||
const pattern = getPatternFromSpec(includeSpec, basePath, "files");
|
||||
return !!pattern && getRegexFromPattern(`(${pattern})$`, useCaseSensitiveFileNames).test(fileName);
|
||||
});
|
||||
return index !== -1 ? configFile.configFileSpecs.validatedIncludeSpecsBeforeSubstitution![index] : undefined;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -537,7 +541,7 @@ export function fileIncludeReasonToDiagnostics(program: Program, reason: FileInc
|
||||
}
|
||||
case FileIncludeKind.LibFile: {
|
||||
if (reason.index !== undefined) return chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Library_0_specified_in_compilerOptions, options.lib![reason.index]);
|
||||
const target = forEachEntry(targetOptionDeclaration.type, (value, key) => value === getEmitScriptTarget(options) ? key : undefined);
|
||||
const target = getNameOfScriptTarget(getEmitScriptTarget(options));
|
||||
const messageAndArgs: DiagnosticAndArguments = target ? [Diagnostics.Default_library_for_target_0, target] : [Diagnostics.Default_library];
|
||||
return chainDiagnosticMessages(/*details*/ undefined, ...messageAndArgs);
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import {
|
||||
addObjectAllocatorPatcher,
|
||||
hasProperty,
|
||||
Identifier,
|
||||
identifierToKeywordKind,
|
||||
NodeFlags,
|
||||
} from "../_namespaces/ts";
|
||||
import { deprecate } from "../deprecate";
|
||||
|
||||
declare module "../../compiler/types" {
|
||||
export interface Identifier {
|
||||
/** @deprecated Use `idKeyword(identifier)` instead. */
|
||||
readonly originalKeywordKind?: SyntaxKind;
|
||||
|
||||
/** @deprecated Use `.parent` or the surrounding context to determine this instead. */
|
||||
readonly isInJSDocNamespace?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
addObjectAllocatorPatcher(objectAllocator => {
|
||||
const Identifier = objectAllocator.getIdentifierConstructor();
|
||||
|
||||
if (!hasProperty(Identifier.prototype, "originalKeywordKind")) {
|
||||
Object.defineProperty(Identifier.prototype, "originalKeywordKind", {
|
||||
get: deprecate(function (this: Identifier) {
|
||||
return identifierToKeywordKind(this);
|
||||
}, {
|
||||
name: "originalKeywordKind",
|
||||
since: "5.0",
|
||||
warnAfter: "5.1",
|
||||
errorAfter: "5.2",
|
||||
message: "Use 'identifierToKeywordKind(identifier)' instead.",
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
if (!hasProperty(Identifier.prototype, "isInJSDocNamespace")) {
|
||||
Object.defineProperty(Identifier.prototype, "isInJSDocNamespace", {
|
||||
get: deprecate(function (this: Identifier) {
|
||||
// NOTE: Returns `true` or `undefined` to match previous possible values.
|
||||
return this.flags & NodeFlags.IdentifierIsInJSDocNamespace ? true : undefined;
|
||||
}, {
|
||||
name: "isInJSDocNamespace",
|
||||
since: "5.0",
|
||||
warnAfter: "5.1",
|
||||
errorAfter: "5.2",
|
||||
message: "Use '.parent' or the surrounding context to determine this instead.",
|
||||
}),
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -2,4 +2,3 @@
|
||||
|
||||
export * from "../../compiler/_namespaces/ts";
|
||||
export * from "../deprecations";
|
||||
export * from "../5.0/identifierProperties";
|
||||
|
||||
@@ -237,7 +237,7 @@ export class Metadata {
|
||||
|
||||
constructor(parent?: Metadata) {
|
||||
this._parent = parent;
|
||||
this._map = Object.create(parent ? parent._map : null); // eslint-disable-line no-null/no-null
|
||||
this._map = Object.create(parent ? parent._map : null); // eslint-disable-line no-restricted-syntax
|
||||
}
|
||||
|
||||
public get size(): number {
|
||||
@@ -284,7 +284,7 @@ export class Metadata {
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this._map = Object.create(this._parent ? this._parent._map : null); // eslint-disable-line no-null/no-null
|
||||
this._map = Object.create(this._parent ? this._parent._map : null); // eslint-disable-line no-restricted-syntax
|
||||
this._size = -1;
|
||||
this._version++;
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ export class SourceMap {
|
||||
let sourceLine = 0;
|
||||
let sourceColumn = 0;
|
||||
let nameIndex = 0;
|
||||
let match: RegExpExecArray | null;
|
||||
let match: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax
|
||||
while (match = SourceMap._mappingRegExp.exec(this.raw.mappings)) {
|
||||
if (match[1]) {
|
||||
const segment = SourceMap._decodeVLQ(match[1]);
|
||||
@@ -141,7 +141,7 @@ export class SourceMap {
|
||||
}
|
||||
|
||||
public static getUrl(text: string) {
|
||||
let match: RegExpExecArray | null;
|
||||
let match: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax
|
||||
let lastMatch: RegExpExecArray | undefined;
|
||||
while (match = SourceMap._sourceMappingURLRegExp.exec(text)) {
|
||||
lastMatch = match;
|
||||
|
||||
@@ -253,7 +253,7 @@ class SystemLoader extends Loader<SystemModule> {
|
||||
protected createModule(file: string): SystemModule {
|
||||
return {
|
||||
file,
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
exports: Object.create(/*o*/ null),
|
||||
dependencies: [],
|
||||
dependers: [],
|
||||
|
||||
+49
-29
@@ -703,7 +703,7 @@ export namespace Compiler {
|
||||
}
|
||||
|
||||
export function doErrorBaseline(baselinePath: string, inputFiles: readonly TestFile[], errors: readonly ts.Diagnostic[], pretty?: boolean) {
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), !errors || (errors.length === 0) ? null : getErrorBaseline(inputFiles, errors, pretty)); // eslint-disable-line no-null/no-null
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), !errors || (errors.length === 0) ? null : getErrorBaseline(inputFiles, errors, pretty)); // eslint-disable-line no-restricted-syntax
|
||||
}
|
||||
|
||||
export function doTypeAndSymbolBaseline(baselinePath: string, header: string, program: ts.Program, allFiles: { unitName: string; content: string; }[], opts?: Baseline.BaselineOptions, multifile?: boolean, skipTypeBaselines?: boolean, skipSymbolBaselines?: boolean, hasErrorBaseline?: boolean) {
|
||||
@@ -774,7 +774,7 @@ export namespace Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
function generateBaseLine(isSymbolBaseline: boolean, skipBaseline?: boolean): string | null {
|
||||
function generateBaseLine(isSymbolBaseline: boolean, skipBaseline?: boolean): string | null { // eslint-disable-line no-restricted-syntax
|
||||
let result = "";
|
||||
const perfLines: string[] = [];
|
||||
const prePerformanceValues = getPerformanceBaselineValues();
|
||||
@@ -786,21 +786,27 @@ export namespace Compiler {
|
||||
const postPerformanceValues = getPerformanceBaselineValues();
|
||||
|
||||
if (!isSymbolBaseline) {
|
||||
const perfStats: [name: string, reportThreshold: number, rounding: number, beforeValue: number, afterValue: number][] = [];
|
||||
perfStats.push(["Strict subtype cache", 1000, 100, prePerformanceValues.strictSubtype, postPerformanceValues.strictSubtype]);
|
||||
perfStats.push(["Subtype cache", 1000, 100, prePerformanceValues.subtype, postPerformanceValues.subtype]);
|
||||
perfStats.push(["Identity cache", 1000, 100, prePerformanceValues.identity, postPerformanceValues.identity]);
|
||||
perfStats.push(["Assignability cache", 1000, 100, prePerformanceValues.assignability, postPerformanceValues.assignability]);
|
||||
perfStats.push(["Type Count", 1000, 100, prePerformanceValues.typeCount, postPerformanceValues.typeCount]);
|
||||
perfStats.push(["Instantiation count", 1500, 500, prePerformanceValues.instantiation, postPerformanceValues.instantiation]);
|
||||
perfStats.push(["Symbol count", 45000, 500, prePerformanceValues.symbol, postPerformanceValues.symbol]);
|
||||
const perfStats: [name: string, reportThreshold: number, beforeValue: number, afterValue: number][] = [];
|
||||
perfStats.push(["Strict subtype cache", 1000, prePerformanceValues.strictSubtype, postPerformanceValues.strictSubtype]);
|
||||
perfStats.push(["Subtype cache", 1000, prePerformanceValues.subtype, postPerformanceValues.subtype]);
|
||||
perfStats.push(["Identity cache", 1000, prePerformanceValues.identity, postPerformanceValues.identity]);
|
||||
perfStats.push(["Assignability cache", 1000, prePerformanceValues.assignability, postPerformanceValues.assignability]);
|
||||
perfStats.push(["Type Count", 1000, prePerformanceValues.typeCount, postPerformanceValues.typeCount]);
|
||||
perfStats.push(["Instantiation count", 1500, prePerformanceValues.instantiation, postPerformanceValues.instantiation]);
|
||||
perfStats.push(["Symbol count", 45000, prePerformanceValues.symbol, postPerformanceValues.symbol]);
|
||||
|
||||
if (perfStats.some(([, threshold, , , postValue]) => postValue >= threshold)) {
|
||||
if (perfStats.some(([, threshold, , postValue]) => postValue >= threshold)) {
|
||||
perfLines.push(`=== Performance Stats ===`);
|
||||
for (const [name, _, rounding, preValue, postValue] of perfStats) {
|
||||
const preDisplay = valueToString(preValue, rounding);
|
||||
if (preDisplay !== "0") {
|
||||
perfLines.push(`${name}: ${preDisplay} / ${valueToString(postValue, rounding)} (nearest ${rounding})`);
|
||||
for (const [name, threshold, preValue, postValue] of perfStats) {
|
||||
if (postValue >= threshold) {
|
||||
const preString = valueToString(preValue);
|
||||
const postString = valueToString(postValue);
|
||||
if (preString === postString) {
|
||||
perfLines.push(`${name}: ${preString}`);
|
||||
}
|
||||
else {
|
||||
perfLines.push(`${name}: ${preString} -> ${postString}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
perfLines.push("");
|
||||
@@ -808,11 +814,25 @@ export namespace Compiler {
|
||||
}
|
||||
}
|
||||
|
||||
return result ? (`//// [${header}] ////\r\n\r\n${perfLines.join("\n")}${result}`) : null; // eslint-disable-line no-null/no-null
|
||||
return result ? (`//// [${header}] ////\r\n\r\n${perfLines.join("\n")}${result}`) : null; // eslint-disable-line no-restricted-syntax
|
||||
|
||||
function valueToString(value: number) {
|
||||
return roundToHumanLogarithm(value).toLocaleString("en-US");
|
||||
}
|
||||
}
|
||||
|
||||
function valueToString(value: number, rounding: number) {
|
||||
return (Math.round(value / rounding) * rounding).toLocaleString("en-US");
|
||||
/**
|
||||
* Rounds to a number like 10, 25, 50, 100, 250, 500, 1000, etc
|
||||
*/
|
||||
function roundToHumanLogarithm(n: number) {
|
||||
if (n < 10) return 0;
|
||||
const powerOfTen = Math.floor(Math.log10(n));
|
||||
const basePowerOfTen = Math.pow(10, powerOfTen);
|
||||
const multipliers = [1, 2.5, 5, 10];
|
||||
const closestMultiplier = multipliers.reduce((prev, curr) => {
|
||||
return Math.abs(curr * basePowerOfTen - n) < Math.abs(prev * basePowerOfTen - n) ? curr : prev;
|
||||
});
|
||||
return closestMultiplier * basePowerOfTen;
|
||||
}
|
||||
|
||||
function getPerformanceBaselineValues() {
|
||||
@@ -890,11 +910,11 @@ export namespace Compiler {
|
||||
throw new Error("Number of sourcemap files should be same as js files.");
|
||||
}
|
||||
|
||||
let sourceMapCode: string | null;
|
||||
let sourceMapCode: string | null; // eslint-disable-line no-restricted-syntax
|
||||
if ((options.noEmitOnError && result.diagnostics.length !== 0) || result.maps.size === 0) {
|
||||
// We need to return null here or the runBaseLine will actually create a empty file.
|
||||
// Baselining isn't required here because there is no output.
|
||||
sourceMapCode = null; // eslint-disable-line no-null/no-null
|
||||
sourceMapCode = null; // eslint-disable-line no-restricted-syntax
|
||||
}
|
||||
else {
|
||||
sourceMapCode = "";
|
||||
@@ -976,7 +996,7 @@ export namespace Compiler {
|
||||
jsCode += getErrorBaseline(tsConfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.diagnostics);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
Baseline.runBaseline(baselinePath.replace(/\.tsx?/, ts.Extension.Js), jsCode.length > 0 ? tsCode + "\r\n\r\n" + jsCode : null);
|
||||
}
|
||||
|
||||
@@ -1215,8 +1235,8 @@ export namespace TestCaseParser {
|
||||
export function extractCompilerSettings(content: string): CompilerSettings {
|
||||
const opts: CompilerSettings = {};
|
||||
|
||||
let match: RegExpExecArray | null;
|
||||
while ((match = optionRegex.exec(content)) !== null) { // eslint-disable-line no-null/no-null
|
||||
let match: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax
|
||||
while ((match = optionRegex.exec(content)) !== null) { // eslint-disable-line no-restricted-syntax
|
||||
opts[match[1]] = match[2].trim();
|
||||
}
|
||||
|
||||
@@ -1246,7 +1266,7 @@ export namespace TestCaseParser {
|
||||
let symlinks: vfs.FileSet | undefined;
|
||||
|
||||
for (const line of lines) {
|
||||
let testMetaData: RegExpExecArray | null;
|
||||
let testMetaData: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax
|
||||
const possiblySymlinks = parseSymlinkFromTest(line, symlinks, vfs.srcFolder);
|
||||
if (possiblySymlinks) {
|
||||
symlinks = possiblySymlinks;
|
||||
@@ -1406,7 +1426,7 @@ export namespace Baseline {
|
||||
|
||||
const fileCache: { [idx: string]: boolean; } = {};
|
||||
|
||||
function compareToBaseline(actual: string | null, relativeFileName: string, opts: BaselineOptions | undefined) {
|
||||
function compareToBaseline(actual: string | null, relativeFileName: string, opts: BaselineOptions | undefined) { // eslint-disable-line no-restricted-syntax
|
||||
// actual is now either undefined (the generator had an error), null (no file requested),
|
||||
// or some real output of the function
|
||||
if (actual === undefined) {
|
||||
@@ -1416,7 +1436,7 @@ export namespace Baseline {
|
||||
|
||||
const refFileName = referencePath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
if (actual === null) {
|
||||
actual = noContent;
|
||||
}
|
||||
@@ -1484,7 +1504,7 @@ export namespace Baseline {
|
||||
return `The baseline file ${relativeFileName} has changed. (Run "hereby baseline-accept" if the new baseline is correct.)`;
|
||||
}
|
||||
|
||||
export function runBaseline(relativeFileName: string, actual: string | null, opts?: BaselineOptions): void {
|
||||
export function runBaseline(relativeFileName: string, actual: string | null, opts?: BaselineOptions): void { // eslint-disable-line no-restricted-syntax
|
||||
const actualFileName = localPath(relativeFileName, opts && opts.Baselinefolder, opts && opts.Subfolder);
|
||||
if (actual === undefined) {
|
||||
throw new Error('The generated content was "undefined". Return "null" if no baselining is required."');
|
||||
@@ -1493,12 +1513,12 @@ export namespace Baseline {
|
||||
writeComparison(comparison.expected, comparison.actual, relativeFileName, actualFileName, opts);
|
||||
}
|
||||
|
||||
export function runMultifileBaseline(relativeFileBase: string, extension: string, generateContent: () => IterableIterator<[string, string, number]> | IterableIterator<[string, string]> | null, opts?: BaselineOptions, referencedExtensions?: string[]): void {
|
||||
export function runMultifileBaseline(relativeFileBase: string, extension: string, generateContent: () => IterableIterator<[string, string, number]> | IterableIterator<[string, string]> | null, opts?: BaselineOptions, referencedExtensions?: string[]): void { // eslint-disable-line no-restricted-syntax
|
||||
const gen = generateContent();
|
||||
const writtenFiles = new Map<string, true>();
|
||||
const errors: Error[] = [];
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
if (gen !== null) {
|
||||
for (const value of gen) {
|
||||
const [name, content, count] = value as [string, string, number | undefined];
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
import { createWatchUtils } from "./watchUtils";
|
||||
|
||||
export function makeDefaultProxy(info: ts.server.PluginCreateInfo): ts.LanguageService {
|
||||
const proxy = Object.create(/*o*/ null); // eslint-disable-line no-null/no-null
|
||||
const proxy = Object.create(/*o*/ null); // eslint-disable-line no-restricted-syntax
|
||||
const langSvc: any = info.languageService;
|
||||
for (const k of Object.keys(langSvc)) {
|
||||
// eslint-disable-next-line local/only-arrow-functions
|
||||
|
||||
@@ -205,10 +205,6 @@ export function sourceFileToJSON(file: ts.Node): string {
|
||||
}
|
||||
break;
|
||||
|
||||
case "originalKeywordKind":
|
||||
o[propertyName] = getKindName((n as any)[propertyName]);
|
||||
break;
|
||||
|
||||
case "flags":
|
||||
// Clear the flags that are produced by aggregating child values. That is ephemeral
|
||||
// data we don't care about in the dump. We only care what the parser set directly
|
||||
|
||||
@@ -271,6 +271,8 @@ export function verifyResolutionCache(
|
||||
verifyResolutionSet(expected.resolutionsWithOnlyAffectingLocations, actual.resolutionsWithOnlyAffectingLocations, `resolutionsWithOnlyAffectingLocations`);
|
||||
verifyDirectoryWatchesOfFailedLookups(expected.directoryWatchesOfFailedLookups, actual.directoryWatchesOfFailedLookups);
|
||||
verifyFileWatchesOfAffectingLocations(expected.fileWatchesOfAffectingLocations, actual.fileWatchesOfAffectingLocations);
|
||||
verifyPackageDirWatchers(expected.packageDirWatchers, actual.packageDirWatchers);
|
||||
verifyDirPathToSymlinkPackageRefCount(expected.dirPathToSymlinkPackageRefCount, actual.dirPathToSymlinkPackageRefCount);
|
||||
|
||||
// Stop watching resolutions to verify everything gets closed.
|
||||
expected.startCachingPerDirectoryResolution();
|
||||
@@ -368,11 +370,17 @@ export function verifyResolutionCache(
|
||||
}
|
||||
|
||||
function verifyDirectoryWatchesOfFailedLookups(expected: Map<string, ts.DirectoryWatchesOfFailedLookup>, actual: Map<string, ts.DirectoryWatchesOfFailedLookup>) {
|
||||
verifyMap(expected, actual, (expected, actual, caption) => {
|
||||
ts.Debug.assert(expected?.refCount === actual?.refCount, `${projectName}:: ${caption}:: refCount`);
|
||||
ts.Debug.assert(!!expected?.refCount, `${projectName}:: ${caption}:: expected refCount to be non zero`);
|
||||
ts.Debug.assert(expected?.nonRecursive === actual?.nonRecursive, `${projectName}:: ${caption}:: nonRecursive`);
|
||||
}, "directoryWatchesOfFailedLookups");
|
||||
verifyMap(expected, actual, verifyDirectoryWatchesOfFailedLookup, "directoryWatchesOfFailedLookups");
|
||||
}
|
||||
|
||||
function verifyDirectoryWatchesOfFailedLookup(
|
||||
expected: ts.DirectoryWatchesOfFailedLookup | undefined,
|
||||
actual: ts.DirectoryWatchesOfFailedLookup | undefined,
|
||||
caption: string,
|
||||
) {
|
||||
ts.Debug.assert(expected?.refCount === actual?.refCount, `${projectName}:: ${caption}:: refCount`);
|
||||
ts.Debug.assert(!!expected?.refCount, `${projectName}:: ${caption}:: expected refCount to be non zero`);
|
||||
ts.Debug.assert(expected?.nonRecursive === actual?.nonRecursive, `${projectName}:: ${caption}:: nonRecursive`);
|
||||
}
|
||||
|
||||
function verifyFileWatchesOfAffectingLocations(
|
||||
@@ -391,6 +399,40 @@ export function verifyResolutionCache(
|
||||
ts.Debug.assert(expected?.files === actual?.files, `${projectName}:: ${caption}:: files`);
|
||||
verifySet(expected?.symlinks, actual?.symlinks, `${projectName}:: ${caption}:: symlinks`);
|
||||
}
|
||||
|
||||
function verifyPackageDirWatchers(
|
||||
expected: Map<ts.Path, ts.PackageDirWatcher>,
|
||||
actual: Map<ts.Path, ts.PackageDirWatcher>,
|
||||
) {
|
||||
verifyMap(expected, actual, verifyPackageDirWatcher, "packageDirWatchers");
|
||||
}
|
||||
|
||||
function verifyPackageDirWatcher(
|
||||
expected: ts.PackageDirWatcher | undefined,
|
||||
actual: ts.PackageDirWatcher | undefined,
|
||||
caption: string,
|
||||
) {
|
||||
ts.Debug.assert(expected?.isSymlink === actual?.isSymlink, `${projectName}:: ${caption}:: isSymlink`);
|
||||
verifyMap(expected?.dirPathToWatcher, actual?.dirPathToWatcher, verfiyDirPathToWatcherOfPackageDirWatcher, `${projectName}:: ${caption}:: dirPathToWatcher`);
|
||||
}
|
||||
|
||||
function verfiyDirPathToWatcherOfPackageDirWatcher(
|
||||
expected: ts.DirPathToWatcherOfPackageDirWatcher | undefined,
|
||||
actual: ts.DirPathToWatcherOfPackageDirWatcher | undefined,
|
||||
caption: string,
|
||||
) {
|
||||
ts.Debug.assert(expected?.refCount === actual?.refCount, `${projectName}:: ${caption}:: refCount`);
|
||||
verifyDirectoryWatchesOfFailedLookup(expected?.watcher, actual?.watcher, `${projectName}:: ${caption}:: directoryWatchesOfFailedLookup`);
|
||||
}
|
||||
|
||||
function verifyDirPathToSymlinkPackageRefCount(
|
||||
expected: Map<ts.Path, number>,
|
||||
actual: Map<ts.Path, number>,
|
||||
) {
|
||||
verifyMap(expected, actual, (expected, actual, caption) => {
|
||||
ts.Debug.assert(expected === actual, `${projectName}:: ${caption}`);
|
||||
}, "dirPathToSymlinkPackageRefCount");
|
||||
}
|
||||
}
|
||||
|
||||
function verifyMap<Key extends string, Expected, Actual>(
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import {
|
||||
AutoImportProviderProject,
|
||||
AuxiliaryProject,
|
||||
ConfiguredProject,
|
||||
isBackgroundProject,
|
||||
isConfiguredProject,
|
||||
LogLevel,
|
||||
@@ -32,6 +33,7 @@ interface ProjectData {
|
||||
isClosed: ReturnType<Project["isClosed"]>;
|
||||
isOrphan: ReturnType<Project["isOrphan"]>;
|
||||
noOpenRef: boolean;
|
||||
deferredClose: ConfiguredProject["deferredClose"];
|
||||
documentPositionMappers: SourceMapper["documentPositionMappers"];
|
||||
autoImportProviderHost: Project["autoImportProviderHost"];
|
||||
noDtsResolutionProject: Project["noDtsResolutionProject"];
|
||||
@@ -46,6 +48,7 @@ interface ScriptInfoData {
|
||||
open: ReturnType<ScriptInfo["isScriptOpen"]>;
|
||||
version: ReturnType<TextStorage["getVersion"]>;
|
||||
pendingReloadFromDisk: TextStorage["pendingReloadFromDisk"];
|
||||
deferredDelete: ScriptInfo["deferredDelete"];
|
||||
sourceMapFilePath: Exclude<ScriptInfo["sourceMapFilePath"], SourceMapFileWatcher> | SourceMapFileWatcherData | undefined;
|
||||
declarationInfoPath: ScriptInfo["declarationInfoPath"];
|
||||
sourceInfos: ScriptInfo["sourceInfos"];
|
||||
@@ -101,6 +104,8 @@ export function patchServiceForStateBaseline(service: ProjectService) {
|
||||
function baselineProjects(currentMappers: Set<DocumentPositionMapper>) {
|
||||
const autoImportProviderProjects = [] as AutoImportProviderProject[];
|
||||
const auxiliaryProjects = [] as AuxiliaryProject[];
|
||||
const orphanConfiguredProjects = service.getOrphanConfiguredProjects(/*toRetainConfiguredProjects*/ undefined);
|
||||
const noOpenRef = (project: Project) => isConfiguredProject(project) && (project.isClosed() || orphanConfiguredProjects.has(project));
|
||||
return baselineState(
|
||||
[service.externalProjects, service.configuredProjects, service.inferredProjects, autoImportProviderProjects, auxiliaryProjects],
|
||||
projects,
|
||||
@@ -115,7 +120,8 @@ export function patchServiceForStateBaseline(service: ProjectService) {
|
||||
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.TruthyOrChangedOrNew, data, "noOpenRef", noOpenRef(project), projectDiff, projectPropertyLogs);
|
||||
projectDiff = printProperty(PrintPropertyWhen.TruthyOrChangedOrNew, data, "deferredClose", isConfiguredProject(project) && project.deferredClose, projectDiff, projectPropertyLogs);
|
||||
projectDiff = printMapPropertyValue(
|
||||
PrintPropertyWhen.Changed,
|
||||
data?.documentPositionMappers,
|
||||
@@ -145,7 +151,8 @@ export function patchServiceForStateBaseline(service: ProjectService) {
|
||||
dirty: project.dirty,
|
||||
isClosed: project.isClosed(),
|
||||
isOrphan: !isBackgroundProject(project) && project.isOrphan(),
|
||||
noOpenRef: isConfiguredProject(project) && !project.hasOpenRef(),
|
||||
noOpenRef: noOpenRef(project),
|
||||
deferredClose: isConfiguredProject(project) && project.deferredClose,
|
||||
autoImportProviderHost: project.autoImportProviderHost,
|
||||
noDtsResolutionProject: project.noDtsResolutionProject,
|
||||
originalConfiguredProjects: project.originalConfiguredProjects && new Set(project.originalConfiguredProjects),
|
||||
@@ -166,6 +173,7 @@ export function patchServiceForStateBaseline(service: ProjectService) {
|
||||
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 = printProperty(PrintPropertyWhen.TruthyOrChangedOrNew, data, "deferredDelete", info.deferredDelete, 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);
|
||||
@@ -200,6 +208,7 @@ export function patchServiceForStateBaseline(service: ProjectService) {
|
||||
sourceInfos: info.sourceInfos && new Set(info.sourceInfos),
|
||||
documentPositionMapper: info.documentPositionMapper,
|
||||
containingProjects: new Set(info.containingProjects),
|
||||
deferredDelete: info.deferredDelete,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace SourceMapDecoder {
|
||||
namespace SourceMapSpanWriter {
|
||||
let sourceMapRecorder: Compiler.WriterAggregator;
|
||||
let sourceMapSources: string[];
|
||||
let sourceMapNames: string[] | null | undefined;
|
||||
let sourceMapNames: string[] | null | undefined; // eslint-disable-line no-restricted-syntax
|
||||
|
||||
let jsFile: documents.TextDocument;
|
||||
let jsLineMap: readonly number[];
|
||||
|
||||
@@ -123,7 +123,7 @@ export function sanitizeLog(s: string): string {
|
||||
s = s.replace(/getExportInfoMap: done in \d+(?:\.\d+)?/g, `getExportInfoMap: done in *`);
|
||||
s = s.replace(/collectAutoImports: \d+(?:\.\d+)?/g, `collectAutoImports: *`);
|
||||
s = s.replace(/continuePreviousIncompleteResponse: \d+(?:\.\d+)?/g, `continuePreviousIncompleteResponse: *`);
|
||||
s = s.replace(/dependencies in \d+(?:\.\d+)?/g, `dependencies in *`);
|
||||
s = s.replace(/referenced projects in \d+(?:\.\d+)?/g, `referenced projects in *`);
|
||||
s = s.replace(/"exportMapKey":\s*"\d+ \d+ /g, match => match.replace(/ \d+ /, ` * `));
|
||||
s = s.replace(/getIndentationAtPosition: getCurrentSourceFile: \d+(?:\.\d+)?/, `getIndentationAtPosition: getCurrentSourceFile: *`);
|
||||
s = s.replace(/getIndentationAtPosition: computeIndentation\s*: \d+(?:\.\d+)?/, `getIndentationAtPosition: computeIndentation: *`);
|
||||
|
||||
@@ -45,7 +45,7 @@ function* forEachASTNode(node: ts.Node) {
|
||||
}
|
||||
|
||||
function nodeIsFullySynthetic(node: ts.Node) {
|
||||
return ts.nodeIsSynthesized(node) && !node.original;
|
||||
return ts.nodeIsSynthesized(node) && !ts.getParseTreeNode(node);
|
||||
}
|
||||
|
||||
const createSyntheticNodeUnderliningPrinter = memoize((): { printer: ts.Printer; writer: ts.EmitTextWriter; underliner: ts.EmitTextWriter; reset(): void; } => {
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ export function dedent(array: TemplateStringsArray, ...args: any[]) {
|
||||
const lineTerminatorRegExp = /\r\n?|\n/g;
|
||||
const lines: string[] = [];
|
||||
const lineTerminators: string[] = [];
|
||||
let match: RegExpExecArray | null;
|
||||
let match: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax
|
||||
let lineStart = 0;
|
||||
while (match = lineTerminatorRegExp.exec(text)) {
|
||||
if (lineStart !== match.index || lines.length > 0) {
|
||||
|
||||
+11
-11
@@ -637,7 +637,7 @@ export class FileSystem {
|
||||
*
|
||||
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
||||
*/
|
||||
public readFileSync(path: string, encoding?: null): Buffer;
|
||||
public readFileSync(path: string, encoding?: null): Buffer; // eslint-disable-line no-restricted-syntax
|
||||
/**
|
||||
* Read from a file.
|
||||
*
|
||||
@@ -649,8 +649,8 @@ export class FileSystem {
|
||||
*
|
||||
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
||||
*/
|
||||
public readFileSync(path: string, encoding?: BufferEncoding | null): string | Buffer;
|
||||
public readFileSync(path: string, encoding: BufferEncoding | null = null) { // eslint-disable-line no-null/no-null
|
||||
public readFileSync(path: string, encoding?: BufferEncoding | null): string | Buffer; // eslint-disable-line no-restricted-syntax
|
||||
public readFileSync(path: string, encoding: BufferEncoding | null = null) { // eslint-disable-line no-restricted-syntax
|
||||
const { node } = this._walk(this._resolve(path));
|
||||
if (!node) throw createIOError("ENOENT");
|
||||
if (isDirectory(node)) throw createIOError("EISDIR");
|
||||
@@ -665,7 +665,7 @@ export class FileSystem {
|
||||
*
|
||||
* NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module.
|
||||
*/
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
public writeFileSync(path: string, data: string | Buffer, encoding: string | null = null) {
|
||||
if (this.isReadonly) throw createIOError("EROFS");
|
||||
|
||||
@@ -1141,7 +1141,7 @@ export class FileSystem {
|
||||
const path = dirname ? vpath.resolve(dirname, key) : key;
|
||||
vpath.validate(path, vpath.ValidationFlags.Absolute);
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
if (value === null || value === undefined || value instanceof Rmdir || value instanceof Unlink) {
|
||||
if (this.stringComparer(vpath.dirname(path), path) === 0) {
|
||||
throw new TypeError("Roots cannot be deleted.");
|
||||
@@ -1371,7 +1371,7 @@ export function createIOError(code: keyof typeof IOErrorMessages, details = "")
|
||||
* A template used to populate files, directories, links, etc. in a virtual file system.
|
||||
*/
|
||||
export interface FileSet {
|
||||
[name: string]: DirectoryLike | FileLike | Link | Symlink | Mount | Rmdir | Unlink | null | undefined;
|
||||
[name: string]: DirectoryLike | FileLike | Link | Symlink | Mount | Rmdir | Unlink | null | undefined; // eslint-disable-line no-restricted-syntax
|
||||
}
|
||||
|
||||
export type DirectoryLike = FileSet | Directory;
|
||||
@@ -1572,7 +1572,7 @@ function getBuiltLocal(host: FileSystemResolverHost, ignoreCase: boolean): FileS
|
||||
return builtLocalCS;
|
||||
}
|
||||
|
||||
/* eslint-disable no-null/no-null */
|
||||
/* eslint-disable no-restricted-syntax */
|
||||
function normalizeFileSetEntry(value: FileSet[string]) {
|
||||
if (
|
||||
value === undefined ||
|
||||
@@ -1595,14 +1595,14 @@ export function formatPatch(patch: FileSet | undefined): string | null;
|
||||
export function formatPatch(patch: FileSet | undefined) {
|
||||
return patch ? formatPatchWorker("", patch) : null;
|
||||
}
|
||||
/* eslint-enable no-null/no-null */
|
||||
/* eslint-enable no-restricted-syntax */
|
||||
|
||||
function formatPatchWorker(dirname: string, container: FileSet): string {
|
||||
let text = "";
|
||||
for (const name of Object.keys(container)) {
|
||||
const entry = normalizeFileSetEntry(container[name]);
|
||||
const file = dirname ? vpath.combine(dirname, name) : name;
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
if (entry === null || entry === undefined || entry instanceof Unlink) {
|
||||
text += `//// [${file}] unlink\r\n`;
|
||||
}
|
||||
@@ -1635,8 +1635,8 @@ function formatPatchWorker(dirname: string, container: FileSet): string {
|
||||
return text;
|
||||
}
|
||||
|
||||
export function iteratePatch(patch: FileSet | undefined): IterableIterator<[string, string]> | null {
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
export function iteratePatch(patch: FileSet | undefined): IterableIterator<[string, string]> | null { // eslint-disable-line no-restricted-syntax
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
return patch ? Harness.Compiler.iterateOutputs(iteratePatchWorker("", patch)) : null;
|
||||
}
|
||||
|
||||
|
||||
+5
@@ -8,3 +8,8 @@ interface FileSystemDirectoryHandle {
|
||||
keys(): AsyncIterableIterator<string>;
|
||||
values(): AsyncIterableIterator<FileSystemHandle>;
|
||||
}
|
||||
|
||||
interface ReadableStream<R = any> {
|
||||
[Symbol.asyncIterator](options?: ReadableStreamIteratorOptions): AsyncIterableIterator<R>;
|
||||
values(options?: ReadableStreamIteratorOptions): AsyncIterableIterator<R>;
|
||||
}
|
||||
|
||||
Vendored
+211
-33
@@ -201,6 +201,9 @@ interface ChannelSplitterOptions extends AudioNodeOptions {
|
||||
interface CheckVisibilityOptions {
|
||||
checkOpacity?: boolean;
|
||||
checkVisibilityCSS?: boolean;
|
||||
contentVisibilityAuto?: boolean;
|
||||
opacityProperty?: boolean;
|
||||
visibilityProperty?: boolean;
|
||||
}
|
||||
|
||||
interface ClientQueryOptions {
|
||||
@@ -267,6 +270,10 @@ interface ConstrainULongRange extends ULongRange {
|
||||
ideal?: number;
|
||||
}
|
||||
|
||||
interface ContentVisibilityAutoStateChangeEventInit extends EventInit {
|
||||
skipped?: boolean;
|
||||
}
|
||||
|
||||
interface ConvolverOptions extends AudioNodeOptions {
|
||||
buffer?: AudioBuffer | null;
|
||||
disableNormalization?: boolean;
|
||||
@@ -556,6 +563,8 @@ interface GainOptions extends AudioNodeOptions {
|
||||
|
||||
interface GamepadEffectParameters {
|
||||
duration?: number;
|
||||
leftTrigger?: number;
|
||||
rightTrigger?: number;
|
||||
startDelay?: number;
|
||||
strongMagnitude?: number;
|
||||
weakMagnitude?: number;
|
||||
@@ -1358,8 +1367,8 @@ interface RTCIceCandidateInit {
|
||||
}
|
||||
|
||||
interface RTCIceCandidatePair {
|
||||
local?: RTCIceCandidate;
|
||||
remote?: RTCIceCandidate;
|
||||
local: RTCIceCandidate;
|
||||
remote: RTCIceCandidate;
|
||||
}
|
||||
|
||||
interface RTCIceCandidatePairStats extends RTCStats {
|
||||
@@ -1619,6 +1628,17 @@ interface ReadableStreamGetReaderOptions {
|
||||
mode?: ReadableStreamReaderMode;
|
||||
}
|
||||
|
||||
interface ReadableStreamIteratorOptions {
|
||||
/**
|
||||
* Asynchronously iterates over the chunks in the stream's internal queue.
|
||||
*
|
||||
* Asynchronously iterating over the stream will lock it, preventing any other consumer from acquiring a reader. The lock will be released if the async iterator's return() method is called, e.g. by breaking out of the loop.
|
||||
*
|
||||
* By default, calling the async iterator's return() method will also cancel the stream. To prevent this, use the stream's values() method, passing true for the preventCancel option.
|
||||
*/
|
||||
preventCancel?: boolean;
|
||||
}
|
||||
|
||||
interface ReadableStreamReadDoneResult<T> {
|
||||
done: true;
|
||||
value?: T;
|
||||
@@ -1750,21 +1770,22 @@ interface ScrollToOptions extends ScrollOptions {
|
||||
interface SecurityPolicyViolationEventInit extends EventInit {
|
||||
blockedURI?: string;
|
||||
columnNumber?: number;
|
||||
disposition: SecurityPolicyViolationEventDisposition;
|
||||
documentURI: string;
|
||||
effectiveDirective: string;
|
||||
disposition?: SecurityPolicyViolationEventDisposition;
|
||||
documentURI?: string;
|
||||
effectiveDirective?: string;
|
||||
lineNumber?: number;
|
||||
originalPolicy: string;
|
||||
originalPolicy?: string;
|
||||
referrer?: string;
|
||||
sample?: string;
|
||||
sourceFile?: string;
|
||||
statusCode: number;
|
||||
violatedDirective: string;
|
||||
statusCode?: number;
|
||||
violatedDirective?: string;
|
||||
}
|
||||
|
||||
interface ShadowRootInit {
|
||||
delegatesFocus?: boolean;
|
||||
mode: ShadowRootMode;
|
||||
serializable?: boolean;
|
||||
slotAssignment?: SlotAssignmentMode;
|
||||
}
|
||||
|
||||
@@ -2189,6 +2210,8 @@ interface ARIAMixin {
|
||||
ariaAtomic: string | null;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaAutoComplete) */
|
||||
ariaAutoComplete: string | null;
|
||||
ariaBrailleLabel: string | null;
|
||||
ariaBrailleRoleDescription: string | null;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaBusy) */
|
||||
ariaBusy: string | null;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/ariaChecked) */
|
||||
@@ -2321,6 +2344,8 @@ declare var AbortSignal: {
|
||||
new(): AbortSignal;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/abort_static) */
|
||||
abort(reason?: any): AbortSignal;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/any_static) */
|
||||
any(signals: AbortSignal[]): AbortSignal;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/timeout_static) */
|
||||
timeout(milliseconds: number): AbortSignal;
|
||||
};
|
||||
@@ -3770,6 +3795,16 @@ declare var CSSScale: {
|
||||
new(x: CSSNumberish, y: CSSNumberish, z?: CSSNumberish): CSSScale;
|
||||
};
|
||||
|
||||
interface CSSScopeRule extends CSSGroupingRule {
|
||||
readonly end: string | null;
|
||||
readonly start: string | null;
|
||||
}
|
||||
|
||||
declare var CSSScopeRule: {
|
||||
prototype: CSSScopeRule;
|
||||
new(): CSSScopeRule;
|
||||
};
|
||||
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkew) */
|
||||
interface CSSSkew extends CSSTransformComponent {
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSSkew/ax) */
|
||||
@@ -3805,6 +3840,15 @@ declare var CSSSkewY: {
|
||||
new(ay: CSSNumericValue): CSSSkewY;
|
||||
};
|
||||
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStartingStyleRule) */
|
||||
interface CSSStartingStyleRule extends CSSGroupingRule {
|
||||
}
|
||||
|
||||
declare var CSSStartingStyleRule: {
|
||||
prototype: CSSStartingStyleRule;
|
||||
new(): CSSStartingStyleRule;
|
||||
};
|
||||
|
||||
/**
|
||||
* An object that is a CSS declaration block, and exposes style information and various style-related methods and properties.
|
||||
*
|
||||
@@ -4030,6 +4074,7 @@ interface CSSStyleDeclaration {
|
||||
clipRule: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/color) */
|
||||
color: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/color-interpolation) */
|
||||
colorInterpolation: string;
|
||||
colorInterpolationFilters: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/color-scheme) */
|
||||
@@ -4074,6 +4119,8 @@ interface CSSStyleDeclaration {
|
||||
containerType: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/content) */
|
||||
content: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/content-visibility) */
|
||||
contentVisibility: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/counter-increment) */
|
||||
counterIncrement: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/counter-reset) */
|
||||
@@ -4575,6 +4622,8 @@ interface CSSStyleDeclaration {
|
||||
textUnderlinePosition: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/text-wrap) */
|
||||
textWrap: string;
|
||||
textWrapMode: string;
|
||||
textWrapStyle: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/top) */
|
||||
top: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/touch-action) */
|
||||
@@ -4589,6 +4638,8 @@ interface CSSStyleDeclaration {
|
||||
transformStyle: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition) */
|
||||
transition: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-behavior) */
|
||||
transitionBehavior: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-delay) */
|
||||
transitionDelay: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/transition-duration) */
|
||||
@@ -5010,6 +5061,8 @@ interface CSSStyleDeclaration {
|
||||
webkitUserSelect: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/white-space) */
|
||||
whiteSpace: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/white-space-collapse) */
|
||||
whiteSpaceCollapse: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/widows) */
|
||||
widows: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/width) */
|
||||
@@ -5028,6 +5081,8 @@ interface CSSStyleDeclaration {
|
||||
y: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/z-index) */
|
||||
zIndex: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/CSS/zoom) */
|
||||
zoom: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/getPropertyPriority) */
|
||||
getPropertyPriority(property: string): string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CSSStyleDeclaration/getPropertyValue) */
|
||||
@@ -5791,6 +5846,17 @@ declare var ConstantSourceNode: {
|
||||
new(context: BaseAudioContext, options?: ConstantSourceOptions): ConstantSourceNode;
|
||||
};
|
||||
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ContentVisibilityAutoStateChangeEvent) */
|
||||
interface ContentVisibilityAutoStateChangeEvent extends Event {
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ContentVisibilityAutoStateChangeEvent/skipped) */
|
||||
readonly skipped: boolean;
|
||||
}
|
||||
|
||||
declare var ContentVisibilityAutoStateChangeEvent: {
|
||||
prototype: ContentVisibilityAutoStateChangeEvent;
|
||||
new(type: string, eventInitDict?: ContentVisibilityAutoStateChangeEventInit): ContentVisibilityAutoStateChangeEvent;
|
||||
};
|
||||
|
||||
/**
|
||||
* An AudioNode that performs a Linear Convolution on a given AudioBuffer, often used to achieve a reverb effect. A ConvolverNode always has exactly one input and one output.
|
||||
*
|
||||
@@ -5952,6 +6018,16 @@ declare var CustomEvent: {
|
||||
new<T>(type: string, eventInitDict?: CustomEventInit<T>): CustomEvent<T>;
|
||||
};
|
||||
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/CustomStateSet) */
|
||||
interface CustomStateSet {
|
||||
forEach(callbackfn: (value: string, key: string, parent: CustomStateSet) => void, thisArg?: any): void;
|
||||
}
|
||||
|
||||
declare var CustomStateSet: {
|
||||
prototype: CustomStateSet;
|
||||
new(): CustomStateSet;
|
||||
};
|
||||
|
||||
/**
|
||||
* An abnormal event (called an exception) which occurs as a result of calling a method or accessing a property of a web API.
|
||||
*
|
||||
@@ -7140,6 +7216,7 @@ interface Document extends Node, DocumentOrShadowRoot, FontFaceSource, GlobalEve
|
||||
createEvent(eventInterface: "ClipboardEvent"): ClipboardEvent;
|
||||
createEvent(eventInterface: "CloseEvent"): CloseEvent;
|
||||
createEvent(eventInterface: "CompositionEvent"): CompositionEvent;
|
||||
createEvent(eventInterface: "ContentVisibilityAutoStateChangeEvent"): ContentVisibilityAutoStateChangeEvent;
|
||||
createEvent(eventInterface: "CustomEvent"): CustomEvent;
|
||||
createEvent(eventInterface: "DeviceMotionEvent"): DeviceMotionEvent;
|
||||
createEvent(eventInterface: "DeviceOrientationEvent"): DeviceOrientationEvent;
|
||||
@@ -7401,6 +7478,7 @@ interface Document extends Node, DocumentOrShadowRoot, FontFaceSource, GlobalEve
|
||||
declare var Document: {
|
||||
prototype: Document;
|
||||
new(): Document;
|
||||
parseHTMLUnsafe(html: string): Document;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -7851,6 +7929,7 @@ interface Element extends Node, ARIAMixin, Animatable, ChildNode, InnerHTML, Non
|
||||
setAttributeNode(attr: Attr): Attr | null;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setAttributeNodeNS) */
|
||||
setAttributeNodeNS(attr: Attr): Attr | null;
|
||||
setHTMLUnsafe(html: string): void;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Element/setPointerCapture) */
|
||||
setPointerCapture(pointerId: number): void;
|
||||
/**
|
||||
@@ -7915,6 +7994,8 @@ interface ElementInternals extends ARIAMixin {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/shadowRoot)
|
||||
*/
|
||||
readonly shadowRoot: ShadowRoot | null;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ElementInternals/states) */
|
||||
readonly states: CustomStateSet;
|
||||
/**
|
||||
* Returns the error message that would be shown to the user if internals's target element was to be checked for validity.
|
||||
*
|
||||
@@ -8693,7 +8774,6 @@ declare var GainNode: {
|
||||
|
||||
/**
|
||||
* This Gamepad API interface defines an individual gamepad or other controller, allowing access to information such as button presses, axis positions, and id.
|
||||
* Available only in secure contexts.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad)
|
||||
*/
|
||||
@@ -8712,7 +8792,7 @@ interface Gamepad {
|
||||
readonly mapping: GamepadMappingType;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Gamepad/timestamp) */
|
||||
readonly timestamp: DOMHighResTimeStamp;
|
||||
readonly vibrationActuator: GamepadHapticActuator | null;
|
||||
readonly vibrationActuator: GamepadHapticActuator;
|
||||
}
|
||||
|
||||
declare var Gamepad: {
|
||||
@@ -8722,7 +8802,6 @@ declare var Gamepad: {
|
||||
|
||||
/**
|
||||
* An individual button of a gamepad or other controller, allowing access to the current state of different types of buttons available on the control device.
|
||||
* Available only in secure contexts.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadButton)
|
||||
*/
|
||||
@@ -8742,7 +8821,6 @@ declare var GamepadButton: {
|
||||
|
||||
/**
|
||||
* This Gamepad API interface contains references to gamepads connected to the system, which is what the gamepad events Window.gamepadconnected and Window.gamepaddisconnected are fired in response to.
|
||||
* Available only in secure contexts.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadEvent)
|
||||
*/
|
||||
@@ -8762,8 +8840,6 @@ declare var GamepadEvent: {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadHapticActuator)
|
||||
*/
|
||||
interface GamepadHapticActuator {
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/GamepadHapticActuator/type) */
|
||||
readonly type: GamepadHapticActuatorType;
|
||||
playEffect(type: GamepadHapticEffectType, params?: GamepadEffectParameters): Promise<GamepadHapticsResult>;
|
||||
reset(): Promise<GamepadHapticsResult>;
|
||||
}
|
||||
@@ -9474,6 +9550,7 @@ interface HTMLAnchorElement extends HTMLElement, HTMLHyperlinkElementUtils {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/name)
|
||||
*/
|
||||
name: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/ping) */
|
||||
ping: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAnchorElement/referrerPolicy) */
|
||||
referrerPolicy: string;
|
||||
@@ -9551,6 +9628,7 @@ interface HTMLAreaElement extends HTMLElement, HTMLHyperlinkElementUtils {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/noHref)
|
||||
*/
|
||||
noHref: boolean;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/ping) */
|
||||
ping: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLAreaElement/referrerPolicy) */
|
||||
referrerPolicy: string;
|
||||
@@ -10146,7 +10224,11 @@ declare var HTMLElement: {
|
||||
interface HTMLEmbedElement extends HTMLElement {
|
||||
/** @deprecated */
|
||||
align: string;
|
||||
/** Sets or retrieves the height of the object. */
|
||||
/**
|
||||
* Sets or retrieves the height of the object.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLEmbedElement/height)
|
||||
*/
|
||||
height: string;
|
||||
/**
|
||||
* Sets or retrieves the name of the object.
|
||||
@@ -10156,7 +10238,11 @@ interface HTMLEmbedElement extends HTMLElement {
|
||||
/** Sets or retrieves a URL to be loaded by the object. */
|
||||
src: string;
|
||||
type: string;
|
||||
/** Sets or retrieves the width of the object. */
|
||||
/**
|
||||
* Sets or retrieves the width of the object.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLEmbedElement/width)
|
||||
*/
|
||||
width: string;
|
||||
getSVGDocument(): Document | null;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLEmbedElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
@@ -10729,6 +10815,7 @@ interface HTMLIFrameElement extends HTMLElement {
|
||||
*/
|
||||
align: string;
|
||||
allow: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/allowFullscreen) */
|
||||
allowFullscreen: boolean;
|
||||
/**
|
||||
* Retrieves the document object of the page or frame.
|
||||
@@ -10755,6 +10842,7 @@ interface HTMLIFrameElement extends HTMLElement {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/height)
|
||||
*/
|
||||
height: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLIFrameElement/loading) */
|
||||
loading: string;
|
||||
/**
|
||||
* Sets or retrieves a URI to a long description of the object.
|
||||
@@ -10994,7 +11082,11 @@ interface HTMLInputElement extends HTMLElement, PopoverInvokerElement {
|
||||
checked: boolean;
|
||||
/** Sets or retrieves the state of the check box or radio button. */
|
||||
defaultChecked: boolean;
|
||||
/** Sets or retrieves the initial contents of the object. */
|
||||
/**
|
||||
* Sets or retrieves the initial contents of the object.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/defaultValue)
|
||||
*/
|
||||
defaultValue: string;
|
||||
dirName: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/disabled) */
|
||||
@@ -11053,12 +11145,25 @@ interface HTMLInputElement extends HTMLElement, PopoverInvokerElement {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/list)
|
||||
*/
|
||||
readonly list: HTMLDataListElement | null;
|
||||
/** Defines the maximum acceptable value for an input element with type="number".When used with the min and step attributes, lets you control the range and increment (such as only even numbers) that the user can enter into an input field. */
|
||||
/**
|
||||
* Defines the maximum acceptable value for an input element with type="number".When used with the min and step attributes, lets you control the range and increment (such as only even numbers) that the user can enter into an input field.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/max)
|
||||
*/
|
||||
max: string;
|
||||
/** Sets or retrieves the maximum number of characters that the user can enter in a text control. */
|
||||
/**
|
||||
* Sets or retrieves the maximum number of characters that the user can enter in a text control.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/maxLength)
|
||||
*/
|
||||
maxLength: number;
|
||||
/** Defines the minimum acceptable value for an input element with type="number". When used with the max and step attributes, lets you control the range and increment (such as even numbers only) that the user can enter into an input field. */
|
||||
/**
|
||||
* Defines the minimum acceptable value for an input element with type="number". When used with the max and step attributes, lets you control the range and increment (such as even numbers only) that the user can enter into an input field.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/min)
|
||||
*/
|
||||
min: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/minLength) */
|
||||
minLength: number;
|
||||
/**
|
||||
* Sets or retrieves the Boolean value indicating whether multiple items can be selected from a list.
|
||||
@@ -11089,16 +11194,28 @@ interface HTMLInputElement extends HTMLElement, PopoverInvokerElement {
|
||||
required: boolean;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/selectionDirection) */
|
||||
selectionDirection: "forward" | "backward" | "none" | null;
|
||||
/** Gets or sets the end position or offset of a text selection. */
|
||||
/**
|
||||
* Gets or sets the end position or offset of a text selection.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/selectionEnd)
|
||||
*/
|
||||
selectionEnd: number | null;
|
||||
/** Gets or sets the starting position or offset of a text selection. */
|
||||
/**
|
||||
* Gets or sets the starting position or offset of a text selection.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/selectionStart)
|
||||
*/
|
||||
selectionStart: number | null;
|
||||
size: number;
|
||||
/** The address or URL of the a media resource that is to be considered. */
|
||||
src: string;
|
||||
/** Defines an increment or jump between values that you want to allow the user to enter. When used with the max and min attributes, lets you control the range and increment (for example, allow only even numbers) that the user can enter into an input field. */
|
||||
step: string;
|
||||
/** Returns the content type of the object. */
|
||||
/**
|
||||
* Returns the content type of the object.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/type)
|
||||
*/
|
||||
type: string;
|
||||
/**
|
||||
* Sets or retrieves the URL, often with a bookmark extension (#name), to use as a client-side image map.
|
||||
@@ -11117,7 +11234,11 @@ interface HTMLInputElement extends HTMLElement, PopoverInvokerElement {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/validity)
|
||||
*/
|
||||
readonly validity: ValidityState;
|
||||
/** Returns the value of the data at the cursor's current position. */
|
||||
/**
|
||||
* Returns the value of the data at the cursor's current position.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLInputElement/value)
|
||||
*/
|
||||
value: string;
|
||||
/** Returns a Date object representing the form control's value, if applicable; otherwise, returns null. Can be set, to change the value. Throws an "InvalidStateError" DOMException if the control isn't date- or time-based. */
|
||||
valueAsDate: Date | null;
|
||||
@@ -11677,16 +11798,31 @@ declare var HTMLMenuElement: {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMetaElement)
|
||||
*/
|
||||
interface HTMLMetaElement extends HTMLElement {
|
||||
/** Gets or sets meta-information to associate with httpEquiv or name. */
|
||||
/**
|
||||
* Gets or sets meta-information to associate with httpEquiv or name.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMetaElement/content)
|
||||
*/
|
||||
content: string;
|
||||
/** Gets or sets information used to bind the value of a content attribute of a meta element to an HTTP response header. */
|
||||
/**
|
||||
* Gets or sets information used to bind the value of a content attribute of a meta element to an HTTP response header.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMetaElement/httpEquiv)
|
||||
*/
|
||||
httpEquiv: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMetaElement/media) */
|
||||
media: string;
|
||||
/** Sets or retrieves the value specified in the content attribute of the meta object. */
|
||||
/**
|
||||
* Sets or retrieves the value specified in the content attribute of the meta object.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMetaElement/name)
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Sets or retrieves a scheme to be used in interpreting the value of a property specified for the object.
|
||||
* @deprecated
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLMetaElement/scheme)
|
||||
*/
|
||||
scheme: string;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
@@ -11898,6 +12034,7 @@ interface HTMLObjectElement extends HTMLElement {
|
||||
type: string;
|
||||
/**
|
||||
* Sets or retrieves the URL, often with a bookmark extension (#name), to use as a client-side image map.
|
||||
* @deprecated
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLObjectElement/useMap)
|
||||
*/
|
||||
@@ -12452,7 +12589,7 @@ interface HTMLSelectElement extends HTMLElement {
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSelectElement/type)
|
||||
*/
|
||||
readonly type: string;
|
||||
readonly type: "select-one" | "select-multiple";
|
||||
/**
|
||||
* Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation messages without actually submitting.
|
||||
*
|
||||
@@ -12564,6 +12701,7 @@ declare var HTMLSlotElement: {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSourceElement)
|
||||
*/
|
||||
interface HTMLSourceElement extends HTMLElement {
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSourceElement/height) */
|
||||
height: number;
|
||||
/**
|
||||
* Gets or sets the intended media type of the media source.
|
||||
@@ -12587,6 +12725,7 @@ interface HTMLSourceElement extends HTMLElement {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSourceElement/type)
|
||||
*/
|
||||
type: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLSourceElement/width) */
|
||||
width: number;
|
||||
addEventListener<K extends keyof HTMLElementEventMap>(type: K, listener: (this: HTMLSourceElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
@@ -13228,7 +13367,11 @@ interface HTMLTextAreaElement extends HTMLElement {
|
||||
selectionStart: number;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTextAreaElement/textLength) */
|
||||
readonly textLength: number;
|
||||
/** Retrieves the type of control. */
|
||||
/**
|
||||
* Retrieves the type of control.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLTextAreaElement/type)
|
||||
*/
|
||||
readonly type: string;
|
||||
/** Returns the error message that would be displayed if the user submits the form, or an empty string if no error message. It also triggers the standard error message, such as "this is a required field". The result is that the user sees validation messages without actually submitting. */
|
||||
readonly validationMessage: string;
|
||||
@@ -13451,11 +13594,13 @@ interface HTMLVideoElement extends HTMLMediaElement {
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/width)
|
||||
*/
|
||||
width: number;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/cancelVideoFrameCallback) */
|
||||
cancelVideoFrameCallback(handle: number): void;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/getVideoPlaybackQuality) */
|
||||
getVideoPlaybackQuality(): VideoPlaybackQuality;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/requestPictureInPicture) */
|
||||
requestPictureInPicture(): Promise<PictureInPictureWindow>;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement/requestVideoFrameCallback) */
|
||||
requestVideoFrameCallback(callback: VideoFrameRequestCallback): number;
|
||||
addEventListener<K extends keyof HTMLVideoElementEventMap>(type: K, listener: (this: HTMLVideoElement, ev: HTMLVideoElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
@@ -14537,6 +14682,29 @@ declare var KeyframeEffect: {
|
||||
new(source: KeyframeEffect): KeyframeEffect;
|
||||
};
|
||||
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LargestContentfulPaint) */
|
||||
interface LargestContentfulPaint extends PerformanceEntry {
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LargestContentfulPaint/element) */
|
||||
readonly element: Element | null;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LargestContentfulPaint/id) */
|
||||
readonly id: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LargestContentfulPaint/loadTime) */
|
||||
readonly loadTime: DOMHighResTimeStamp;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LargestContentfulPaint/renderTime) */
|
||||
readonly renderTime: DOMHighResTimeStamp;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LargestContentfulPaint/size) */
|
||||
readonly size: number;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LargestContentfulPaint/url) */
|
||||
readonly url: string;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/LargestContentfulPaint/toJSON) */
|
||||
toJSON(): any;
|
||||
}
|
||||
|
||||
declare var LargestContentfulPaint: {
|
||||
prototype: LargestContentfulPaint;
|
||||
new(): LargestContentfulPaint;
|
||||
};
|
||||
|
||||
interface LinkStyle {
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLLinkElement/sheet) */
|
||||
readonly sheet: CSSStyleSheet | null;
|
||||
@@ -21374,6 +21542,8 @@ interface ShadowRootEventMap {
|
||||
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ShadowRoot) */
|
||||
interface ShadowRoot extends DocumentFragment, DocumentOrShadowRoot, InnerHTML {
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ShadowRoot/clonable) */
|
||||
readonly clonable: boolean;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ShadowRoot/delegatesFocus) */
|
||||
readonly delegatesFocus: boolean;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ShadowRoot/host) */
|
||||
@@ -21383,6 +21553,7 @@ interface ShadowRoot extends DocumentFragment, DocumentOrShadowRoot, InnerHTML {
|
||||
onslotchange: ((this: ShadowRoot, ev: Event) => any) | null;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/ShadowRoot/slotAssignment) */
|
||||
readonly slotAssignment: SlotAssignmentMode;
|
||||
setHTMLUnsafe(html: string): void;
|
||||
/** Throws a "NotSupportedError" DOMException if context object is a shadow root. */
|
||||
addEventListener<K extends keyof ShadowRootEventMap>(type: K, listener: (this: ShadowRoot, ev: ShadowRootEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
|
||||
@@ -25903,7 +26074,11 @@ interface Window extends EventTarget, AnimationFrameProvider, GlobalEventHandler
|
||||
readonly window: Window & typeof globalThis;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/alert) */
|
||||
alert(message?: any): void;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/blur) */
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/blur)
|
||||
*/
|
||||
blur(): void;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/cancelIdleCallback) */
|
||||
cancelIdleCallback(handle: number): void;
|
||||
@@ -27528,7 +27703,11 @@ declare var visualViewport: VisualViewport | null;
|
||||
declare var window: Window & typeof globalThis;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/alert) */
|
||||
declare function alert(message?: any): void;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/blur) */
|
||||
/**
|
||||
* @deprecated
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/blur)
|
||||
*/
|
||||
declare function blur(): void;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/cancelIdleCallback) */
|
||||
declare function cancelIdleCallback(handle: number): void;
|
||||
@@ -28275,8 +28454,7 @@ type FontDisplay = "auto" | "block" | "fallback" | "optional" | "swap";
|
||||
type FontFaceLoadStatus = "error" | "loaded" | "loading" | "unloaded";
|
||||
type FontFaceSetLoadStatus = "loaded" | "loading";
|
||||
type FullscreenNavigationUI = "auto" | "hide" | "show";
|
||||
type GamepadHapticActuatorType = "vibration";
|
||||
type GamepadHapticEffectType = "dual-rumble";
|
||||
type GamepadHapticEffectType = "dual-rumble" | "trigger-rumble";
|
||||
type GamepadHapticsResult = "complete" | "preempted";
|
||||
type GamepadMappingType = "" | "standard" | "xr-standard";
|
||||
type GlobalCompositeOperation = "color" | "color-burn" | "color-dodge" | "copy" | "darken" | "destination-atop" | "destination-in" | "destination-out" | "destination-over" | "difference" | "exclusion" | "hard-light" | "hue" | "lighten" | "lighter" | "luminosity" | "multiply" | "overlay" | "saturation" | "screen" | "soft-light" | "source-atop" | "source-in" | "source-out" | "source-over" | "xor";
|
||||
|
||||
Vendored
+8
@@ -2,6 +2,11 @@
|
||||
/// Window Iterable APIs
|
||||
/////////////////////////////
|
||||
|
||||
interface AbortSignal {
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/any_static) */
|
||||
any(signals: Iterable<AbortSignal>): AbortSignal;
|
||||
}
|
||||
|
||||
interface AudioParam {
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AudioParam/setValueCurveAtTime) */
|
||||
setValueCurveAtTime(values: Iterable<number>, startTime: number, duration: number): AudioParam;
|
||||
@@ -65,6 +70,9 @@ interface CanvasPathDrawingStyles {
|
||||
setLineDash(segments: Iterable<number>): void;
|
||||
}
|
||||
|
||||
interface CustomStateSet extends Set<string> {
|
||||
}
|
||||
|
||||
interface DOMRectList {
|
||||
[Symbol.iterator](): IterableIterator<DOMRect>;
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -42,7 +42,7 @@ interface FinalizationRegistry<T> {
|
||||
* @param unregisterToken The token that was used as the unregisterToken argument when calling
|
||||
* register to register the target value.
|
||||
*/
|
||||
unregister(unregisterToken: WeakKey): void;
|
||||
unregister(unregisterToken: WeakKey): boolean;
|
||||
}
|
||||
|
||||
interface FinalizationRegistryConstructor {
|
||||
|
||||
Vendored
+1
@@ -7,3 +7,4 @@
|
||||
/// <reference lib="esnext.collection" />
|
||||
/// <reference lib="esnext.array" />
|
||||
/// <reference lib="esnext.regexp" />
|
||||
/// <reference lib="esnext.string" />
|
||||
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
interface String {
|
||||
/**
|
||||
* Returns true if all leading surrogates and trailing surrogates appear paired and in order.
|
||||
*/
|
||||
isWellFormed(): boolean;
|
||||
|
||||
/**
|
||||
* Returns a string where all lone or out-of-order surrogates have been replaced by the Unicode replacement character (U+FFFD).
|
||||
*/
|
||||
toWellFormed(): string;
|
||||
}
|
||||
@@ -79,6 +79,7 @@
|
||||
"esnext.collection",
|
||||
"esnext.array",
|
||||
"esnext.regexp",
|
||||
"esnext.string",
|
||||
"decorators",
|
||||
"decorators.legacy",
|
||||
// Default libraries
|
||||
|
||||
@@ -8,3 +8,8 @@ interface FileSystemDirectoryHandle {
|
||||
keys(): AsyncIterableIterator<string>;
|
||||
values(): AsyncIterableIterator<FileSystemHandle>;
|
||||
}
|
||||
|
||||
interface ReadableStream<R = any> {
|
||||
[Symbol.asyncIterator](options?: ReadableStreamIteratorOptions): AsyncIterableIterator<R>;
|
||||
values(options?: ReadableStreamIteratorOptions): AsyncIterableIterator<R>;
|
||||
}
|
||||
|
||||
Vendored
+20
-6
@@ -532,6 +532,17 @@ interface ReadableStreamGetReaderOptions {
|
||||
mode?: ReadableStreamReaderMode;
|
||||
}
|
||||
|
||||
interface ReadableStreamIteratorOptions {
|
||||
/**
|
||||
* Asynchronously iterates over the chunks in the stream's internal queue.
|
||||
*
|
||||
* Asynchronously iterating over the stream will lock it, preventing any other consumer from acquiring a reader. The lock will be released if the async iterator's return() method is called, e.g. by breaking out of the loop.
|
||||
*
|
||||
* By default, calling the async iterator's return() method will also cancel the stream. To prevent this, use the stream's values() method, passing true for the preventCancel option.
|
||||
*/
|
||||
preventCancel?: boolean;
|
||||
}
|
||||
|
||||
interface ReadableStreamReadDoneResult<T> {
|
||||
done: true;
|
||||
value?: T;
|
||||
@@ -629,16 +640,16 @@ interface RsaPssParams extends Algorithm {
|
||||
interface SecurityPolicyViolationEventInit extends EventInit {
|
||||
blockedURI?: string;
|
||||
columnNumber?: number;
|
||||
disposition: SecurityPolicyViolationEventDisposition;
|
||||
documentURI: string;
|
||||
effectiveDirective: string;
|
||||
disposition?: SecurityPolicyViolationEventDisposition;
|
||||
documentURI?: string;
|
||||
effectiveDirective?: string;
|
||||
lineNumber?: number;
|
||||
originalPolicy: string;
|
||||
originalPolicy?: string;
|
||||
referrer?: string;
|
||||
sample?: string;
|
||||
sourceFile?: string;
|
||||
statusCode: number;
|
||||
violatedDirective: string;
|
||||
statusCode?: number;
|
||||
violatedDirective?: string;
|
||||
}
|
||||
|
||||
interface StorageEstimate {
|
||||
@@ -953,6 +964,8 @@ declare var AbortSignal: {
|
||||
new(): AbortSignal;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/abort_static) */
|
||||
abort(reason?: any): AbortSignal;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/any_static) */
|
||||
any(signals: AbortSignal[]): AbortSignal;
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/timeout_static) */
|
||||
timeout(milliseconds: number): AbortSignal;
|
||||
};
|
||||
@@ -5203,6 +5216,7 @@ interface ServiceWorkerGlobalScopeEventMap extends WorkerGlobalScopeEventMap {
|
||||
|
||||
/**
|
||||
* This ServiceWorker API interface represents the global execution context of a service worker.
|
||||
* Available only in secure contexts.
|
||||
*
|
||||
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/ServiceWorkerGlobalScope)
|
||||
*/
|
||||
|
||||
+5
@@ -2,6 +2,11 @@
|
||||
/// Worker Iterable APIs
|
||||
/////////////////////////////
|
||||
|
||||
interface AbortSignal {
|
||||
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/AbortSignal/any_static) */
|
||||
any(signals: Iterable<AbortSignal>): AbortSignal;
|
||||
}
|
||||
|
||||
interface CSSNumericArray {
|
||||
[Symbol.iterator](): IterableIterator<CSSNumericValue>;
|
||||
entries(): IterableIterator<[number, CSSNumericValue]>;
|
||||
|
||||
+376
-208
File diff suppressed because it is too large
Load Diff
+120
-22
@@ -7,6 +7,7 @@ import {
|
||||
arrayToMap,
|
||||
BuilderState,
|
||||
CachedDirectoryStructureHost,
|
||||
changeExtension,
|
||||
changesAffectModuleResolution,
|
||||
clearMap,
|
||||
cloneCompilerOptions,
|
||||
@@ -16,7 +17,6 @@ import {
|
||||
comparePaths,
|
||||
CompilerHost,
|
||||
CompilerOptions,
|
||||
concatenate,
|
||||
containsPath,
|
||||
createCacheableExportInfoMap,
|
||||
createLanguageService,
|
||||
@@ -50,6 +50,7 @@ import {
|
||||
getAutomaticTypeDirectiveNames,
|
||||
getBaseFileName,
|
||||
GetCanonicalFileName,
|
||||
getCommonSourceDirectoryOfConfig,
|
||||
getDeclarationEmitOutputFilePathWorker,
|
||||
getDefaultCompilerOptions,
|
||||
getDefaultLibFileName,
|
||||
@@ -60,6 +61,7 @@ import {
|
||||
getEntrypointsFromPackageJsonInfo,
|
||||
getNormalizedAbsolutePath,
|
||||
getOrUpdate,
|
||||
getOutputDeclarationFileName,
|
||||
GetPackageJsonEntrypointsHost,
|
||||
getStringComparer,
|
||||
HasInvalidatedLibResolutions,
|
||||
@@ -79,6 +81,7 @@ import {
|
||||
map,
|
||||
mapDefined,
|
||||
maybeBind,
|
||||
memoize,
|
||||
ModuleResolutionCache,
|
||||
ModuleResolutionHost,
|
||||
noop,
|
||||
@@ -657,7 +660,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
}
|
||||
|
||||
private getOrCreateScriptInfoAndAttachToProject(fileName: string) {
|
||||
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.currentDirectory, this.directoryStructureHost);
|
||||
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(
|
||||
fileName,
|
||||
this.currentDirectory,
|
||||
this.directoryStructureHost,
|
||||
/*deferredDeleteOk*/ false,
|
||||
);
|
||||
if (scriptInfo) {
|
||||
const existingValue = this.rootFilesMap.get(scriptInfo.path);
|
||||
if (existingValue && existingValue.info !== scriptInfo) {
|
||||
@@ -678,7 +686,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
getScriptVersion(filename: string) {
|
||||
// Don't attach to the project if version is asked
|
||||
|
||||
const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient(filename, this.currentDirectory, this.directoryStructureHost);
|
||||
const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient(
|
||||
filename,
|
||||
this.currentDirectory,
|
||||
this.directoryStructureHost,
|
||||
/*deferredDeleteOk*/ false,
|
||||
);
|
||||
return (info && info.getLatestVersion())!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
@@ -1298,6 +1311,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
markAsDirty() {
|
||||
if (!this.dirty) {
|
||||
this.projectStateVersion++;
|
||||
@@ -1305,6 +1319,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
markAutoImportProviderAsDirty() {
|
||||
if (!this.autoImportProviderHost) this.autoImportProviderHost = undefined;
|
||||
this.autoImportProviderHost?.markAsDirty();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
onAutoImportProviderSettingsChanged() {
|
||||
if (this.autoImportProviderHost === false) {
|
||||
@@ -1389,8 +1409,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
this.projectProgramVersion++;
|
||||
}
|
||||
if (hasAddedorRemovedFiles) {
|
||||
if (!this.autoImportProviderHost) this.autoImportProviderHost = undefined;
|
||||
this.autoImportProviderHost?.markAsDirty();
|
||||
this.markAutoImportProviderAsDirty();
|
||||
}
|
||||
if (isFirstProgramLoad) {
|
||||
// Preload auto import provider so it's not created during completions request
|
||||
@@ -1658,7 +1677,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
|
||||
// by the host for files in the program when the program is retrieved above but
|
||||
// the program doesn't contain external files so this must be done explicitly.
|
||||
inserted => {
|
||||
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, this.currentDirectory, this.directoryStructureHost);
|
||||
const scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(
|
||||
inserted,
|
||||
this.currentDirectory,
|
||||
this.directoryStructureHost,
|
||||
/*deferredDeleteOk*/ false,
|
||||
);
|
||||
scriptInfo?.attachToProject(this);
|
||||
},
|
||||
removed => this.detachScriptInfoFromProject(removed),
|
||||
@@ -2423,7 +2447,7 @@ export class AutoImportProviderProject extends Project {
|
||||
|
||||
const start = timestamp();
|
||||
let dependencyNames: Set<string> | undefined;
|
||||
let rootNames: string[] | undefined;
|
||||
let rootNames: Set<string> | undefined;
|
||||
const rootFileName = combinePaths(hostProject.currentDirectory, inferredTypesContainingFile);
|
||||
const packageJsons = hostProject.getPackageJsonsForAutoImport(combinePaths(hostProject.currentDirectory, rootFileName));
|
||||
for (const packageJson of packageJsons) {
|
||||
@@ -2455,8 +2479,7 @@ export class AutoImportProviderProject extends Project {
|
||||
if (packageJson) {
|
||||
const entrypoints = getRootNamesFromPackageJson(packageJson, program, symlinkCache);
|
||||
if (entrypoints) {
|
||||
rootNames = concatenate(rootNames, entrypoints);
|
||||
dependenciesAdded += entrypoints.length ? 1 : 0;
|
||||
dependenciesAdded += addRootNames(entrypoints);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -2474,8 +2497,7 @@ export class AutoImportProviderProject extends Project {
|
||||
);
|
||||
if (typesPackageJson) {
|
||||
const entrypoints = getRootNamesFromPackageJson(typesPackageJson, program, symlinkCache);
|
||||
rootNames = concatenate(rootNames, entrypoints);
|
||||
dependenciesAdded += entrypoints?.length ? 1 : 0;
|
||||
dependenciesAdded += addRootNames(entrypoints);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2488,16 +2510,56 @@ export class AutoImportProviderProject extends Project {
|
||||
// package and load the JS.
|
||||
if (packageJson && compilerOptions.allowJs && compilerOptions.maxNodeModuleJsDepth) {
|
||||
const entrypoints = getRootNamesFromPackageJson(packageJson, program, symlinkCache, /*resolveJs*/ true);
|
||||
rootNames = concatenate(rootNames, entrypoints);
|
||||
dependenciesAdded += entrypoints?.length ? 1 : 0;
|
||||
dependenciesAdded += addRootNames(entrypoints);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rootNames?.length) {
|
||||
hostProject.log(`AutoImportProviderProject: found ${rootNames.length} root files in ${dependenciesAdded} dependencies in ${timestamp() - start} ms`);
|
||||
const references = program.getResolvedProjectReferences();
|
||||
let referencesAddded = 0;
|
||||
if (references?.length && hostProject.projectService.getHostPreferences().includeCompletionsForModuleExports) {
|
||||
// Add direct referenced projects to rootFiles names
|
||||
references.forEach(ref => {
|
||||
if (ref?.commandLine.options.outFile) {
|
||||
referencesAddded += addRootNames(filterEntrypoints([
|
||||
changeExtension(ref.commandLine.options.outFile, ".d.ts"),
|
||||
]));
|
||||
}
|
||||
else if (ref) {
|
||||
const getCommonSourceDirectory = memoize(() =>
|
||||
getCommonSourceDirectoryOfConfig(
|
||||
ref.commandLine,
|
||||
!hostProject.useCaseSensitiveFileNames(),
|
||||
)
|
||||
);
|
||||
referencesAddded += addRootNames(filterEntrypoints(mapDefined(
|
||||
ref.commandLine.fileNames,
|
||||
fileName =>
|
||||
!isDeclarationFileName(fileName) &&
|
||||
!fileExtensionIs(fileName, Extension.Json) &&
|
||||
!program.getSourceFile(fileName) ?
|
||||
getOutputDeclarationFileName(
|
||||
fileName,
|
||||
ref.commandLine,
|
||||
!hostProject.useCaseSensitiveFileNames(),
|
||||
getCommonSourceDirectory,
|
||||
) : undefined,
|
||||
)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (rootNames?.size) {
|
||||
hostProject.log(`AutoImportProviderProject: found ${rootNames.size} root files in ${dependenciesAdded} dependencies ${referencesAddded} referenced projects in ${timestamp() - start} ms`);
|
||||
}
|
||||
return rootNames ? arrayFrom(rootNames.values()) : ts.emptyArray;
|
||||
|
||||
function addRootNames(entrypoints: readonly string[] | undefined) {
|
||||
if (!entrypoints?.length) return 0;
|
||||
rootNames ??= new Set();
|
||||
entrypoints.forEach(entry => rootNames!.add(entry));
|
||||
return 1;
|
||||
}
|
||||
return rootNames || ts.emptyArray;
|
||||
|
||||
function addDependency(dependency: string) {
|
||||
if (!startsWith(dependency, "@types/")) {
|
||||
@@ -2524,14 +2586,18 @@ export class AutoImportProviderProject extends Project {
|
||||
});
|
||||
}
|
||||
|
||||
return mapDefined(entrypoints, entrypoint => {
|
||||
const resolvedFileName = isSymlink ? entrypoint.replace(packageJson.packageDirectory, real!) : entrypoint;
|
||||
if (!program.getSourceFile(resolvedFileName) && !(isSymlink && program.getSourceFile(entrypoint))) {
|
||||
return resolvedFileName;
|
||||
}
|
||||
});
|
||||
return filterEntrypoints(entrypoints, isSymlink ? entrypoint => entrypoint.replace(packageJson.packageDirectory, real!) : undefined);
|
||||
}
|
||||
}
|
||||
|
||||
function filterEntrypoints(entrypoints: readonly string[] | undefined, symlinkName?: (entrypoint: string) => string) {
|
||||
return mapDefined(entrypoints, entrypoint => {
|
||||
const resolvedFileName = symlinkName ? symlinkName(entrypoint) : entrypoint;
|
||||
if (!program!.getSourceFile(resolvedFileName) && !(symlinkName && program!.getSourceFile(entrypoint))) {
|
||||
return resolvedFileName;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -2584,6 +2650,7 @@ export class AutoImportProviderProject extends Project {
|
||||
return !some(this.rootFileNames);
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
override isOrphan() {
|
||||
return true;
|
||||
}
|
||||
@@ -2619,6 +2686,7 @@ export class AutoImportProviderProject extends Project {
|
||||
return !!this.rootFileNames?.length;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
override markAsDirty() {
|
||||
this.rootFileNames = undefined;
|
||||
super.markAsDirty();
|
||||
@@ -2707,6 +2775,15 @@ export class ConfiguredProject extends Project {
|
||||
/** @internal */
|
||||
private compilerHost?: CompilerHost;
|
||||
|
||||
/** @internal */
|
||||
hasConfigFileDiagnostics?: boolean;
|
||||
|
||||
/** @internal */
|
||||
skipConfigDiagEvent?: true;
|
||||
|
||||
/** @internal */
|
||||
deferredClose?: boolean;
|
||||
|
||||
/** @internal */
|
||||
constructor(
|
||||
configFileName: NormalizedPath,
|
||||
@@ -2767,6 +2844,7 @@ export class ConfiguredProject extends Project {
|
||||
* @returns: true if set of files in the project stays the same and false - otherwise.
|
||||
*/
|
||||
override updateGraph(): boolean {
|
||||
if (this.deferredClose) return false;
|
||||
const isInitialLoad = this.isInitialLoadPending();
|
||||
this.isInitialLoadPending = returnFalse;
|
||||
const updateLevel = this.pendingUpdateLevel;
|
||||
@@ -2790,6 +2868,9 @@ export class ConfiguredProject extends Project {
|
||||
this.compilerHost = undefined;
|
||||
this.projectService.sendProjectLoadingFinishEvent(this);
|
||||
this.projectService.sendProjectTelemetry(this);
|
||||
if (!this.skipConfigDiagEvent && !result) { // If new program, send event if diagnostics presence has changed
|
||||
this.projectService.sendConfigFileDiagEvent(this, /*triggerFile*/ undefined);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2883,6 +2964,12 @@ export class ConfiguredProject extends Project {
|
||||
super.close();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
override markAsDirty() {
|
||||
if (this.deferredClose) return;
|
||||
super.markAsDirty();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
addExternalProjectReference() {
|
||||
this.externalProjectRefCount++;
|
||||
@@ -2932,6 +3019,7 @@ export class ConfiguredProject extends Project {
|
||||
}
|
||||
|
||||
const configFileExistenceInfo = this.projectService.configFileExistenceInfoCache.get(this.canonicalConfigFilePath)!;
|
||||
if (this.deferredClose) return !!configFileExistenceInfo.openFilesImpactedByConfigFile?.size;
|
||||
if (this.projectService.hasPendingProjectUpdate(this)) {
|
||||
// If there is pending update for this project,
|
||||
// we dont know if this project would be needed by any of the open files impacted by this config file
|
||||
@@ -2957,6 +3045,11 @@ export class ConfiguredProject extends Project {
|
||||
) || false;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
override isOrphan(): boolean {
|
||||
return !!this.deferredClose;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
hasExternalProjectRef() {
|
||||
return !!this.externalProjectRefCount;
|
||||
@@ -3014,3 +3107,8 @@ export function isExternalProject(project: Project): project is ExternalProject
|
||||
export function isBackgroundProject(project: Project): project is AutoImportProviderProject | AuxiliaryProject {
|
||||
return project.projectKind === ProjectKind.AutoImportProvider || project.projectKind === ProjectKind.Auxiliary;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function isProjectDeferredClose(project: Project): project is ConfiguredProject {
|
||||
return isConfiguredProject(project) && !!project.deferredClose;
|
||||
}
|
||||
|
||||
@@ -3142,6 +3142,7 @@ export const enum ScriptTarget {
|
||||
ES2020 = "es2020",
|
||||
ES2021 = "es2021",
|
||||
ES2022 = "es2022",
|
||||
ES2023 = "es2023",
|
||||
ESNext = "esnext",
|
||||
JSON = "json",
|
||||
Latest = ESNext,
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
IScriptSnapshot,
|
||||
isString,
|
||||
LineInfo,
|
||||
missingFileModifiedTime,
|
||||
orderedRemoveItem,
|
||||
Path,
|
||||
ScriptKind,
|
||||
@@ -44,6 +45,7 @@ import {
|
||||
isConfiguredProject,
|
||||
isExternalProject,
|
||||
isInferredProject,
|
||||
isProjectDeferredClose,
|
||||
maxFileSize,
|
||||
NormalizedPath,
|
||||
Project,
|
||||
@@ -180,6 +182,14 @@ export class TextStorage {
|
||||
const reloaded = this.reload(newText);
|
||||
this.fileSize = fileSize; // NB: after reload since reload clears it
|
||||
this.ownFileText = !tempFileName || tempFileName === this.info.fileName;
|
||||
// In case we update this text before mTime gets updated to present file modified time
|
||||
// because its schedule to do that later, update the mTime so we dont re-update the text
|
||||
// Eg. with npm ci where file gets created and editor calls say get error request before
|
||||
// the timeout to update the file stamps in node_modules is run
|
||||
// Test:: watching npm install in codespaces where workspaces folder is hosted at root
|
||||
if (this.ownFileText && this.info.mTime === missingFileModifiedTime.getTime()) {
|
||||
this.info.mTime = (this.host.getModifiedTime!(this.info.fileName) || missingFileModifiedTime).getTime();
|
||||
}
|
||||
return reloaded;
|
||||
}
|
||||
|
||||
@@ -398,6 +408,9 @@ export class ScriptInfo {
|
||||
/** @internal */
|
||||
documentPositionMapper?: DocumentPositionMapper | false;
|
||||
|
||||
/** @internal */
|
||||
deferredDelete?: boolean;
|
||||
|
||||
constructor(
|
||||
private readonly host: ServerHost,
|
||||
readonly fileName: NormalizedPath,
|
||||
@@ -567,7 +580,10 @@ export class ScriptInfo {
|
||||
case 0:
|
||||
return Errors.ThrowNoProject();
|
||||
case 1:
|
||||
return ensurePrimaryProjectKind(this.containingProjects[0]);
|
||||
return ensurePrimaryProjectKind(
|
||||
!isProjectDeferredClose(this.containingProjects[0]) ?
|
||||
this.containingProjects[0] : undefined,
|
||||
);
|
||||
default:
|
||||
// If this file belongs to multiple projects, below is the order in which default project is used
|
||||
// - for open script info, its default configured project during opening is default if info is part of it
|
||||
@@ -583,6 +599,7 @@ export class ScriptInfo {
|
||||
for (let index = 0; index < this.containingProjects.length; index++) {
|
||||
const project = this.containingProjects[index];
|
||||
if (isConfiguredProject(project)) {
|
||||
if (project.deferredClose) continue;
|
||||
if (!project.isSourceOfProjectReferenceRedirect(this.fileName)) {
|
||||
// If we havent found default configuredProject and
|
||||
// its not the last one, find it and use that one if there
|
||||
@@ -676,7 +693,7 @@ export class ScriptInfo {
|
||||
}
|
||||
|
||||
isOrphan() {
|
||||
return !forEach(this.containingProjects, p => !p.isOrphan());
|
||||
return this.deferredDelete || !forEach(this.containingProjects, p => !p.isOrphan());
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
|
||||
@@ -591,7 +591,7 @@ export class LineNode implements LineCollection {
|
||||
if (children.length) this.updateCounts();
|
||||
}
|
||||
|
||||
isLeaf() {
|
||||
isLeaf(): this is LineLeaf {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -839,7 +839,7 @@ export class LineLeaf implements LineCollection {
|
||||
constructor(public text: string) {
|
||||
}
|
||||
|
||||
isLeaf() {
|
||||
isLeaf(): this is LineLeaf {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1575,6 +1575,7 @@ export class Session<TMessage = string> implements EventSender {
|
||||
fileNameToSearch,
|
||||
noDtsProject.currentDirectory,
|
||||
noDtsProject.directoryStructureHost,
|
||||
/*deferredDeleteOk*/ false,
|
||||
);
|
||||
if (!info) continue;
|
||||
if (!noDtsProject.containsScriptInfo(info)) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
isComputedPropertyName,
|
||||
isDeclarationWithTypeParameterChildren,
|
||||
isExpressionStatement,
|
||||
isFunctionDeclaration,
|
||||
isIdentifier,
|
||||
isImportClause,
|
||||
isImportDeclaration,
|
||||
@@ -129,6 +130,10 @@ registerCodeFix({
|
||||
];
|
||||
}
|
||||
|
||||
if (isIdentifier(token) && isFunctionDeclaration(token.parent)) {
|
||||
return [createDeleteFix(textChanges.ChangeTracker.with(context, t => deleteFunctionLikeDeclaration(t, sourceFile, token.parent as FunctionLikeDeclaration)), [Diagnostics.Remove_unused_declaration_for_Colon_0, token.getText(sourceFile)])];
|
||||
}
|
||||
|
||||
const result: CodeFixAction[] = [];
|
||||
if (token.kind === SyntaxKind.InferKeyword) {
|
||||
const changes = textChanges.ChangeTracker.with(context, t => changeInferToUnknown(t, sourceFile, token));
|
||||
@@ -431,3 +436,12 @@ function mayDeleteExpression(node: Node) {
|
||||
return ((isBinaryExpression(node.parent) && node.parent.left === node) ||
|
||||
((isPostfixUnaryExpression(node.parent) || isPrefixUnaryExpression(node.parent)) && node.parent.operand === node)) && isExpressionStatement(node.parent.parent);
|
||||
}
|
||||
|
||||
function deleteFunctionLikeDeclaration(changes: textChanges.ChangeTracker, sourceFile: SourceFile, node: FunctionLikeDeclaration) {
|
||||
const declarations = node.symbol.declarations;
|
||||
if (declarations) {
|
||||
for (const declaration of declarations) {
|
||||
changes.delete(sourceFile, declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
AnyImportOrRequireStatement,
|
||||
AnyImportSyntax,
|
||||
arrayFrom,
|
||||
BindingElement,
|
||||
CancellationToken,
|
||||
cast,
|
||||
changeAnyExtension,
|
||||
@@ -15,6 +16,7 @@ import {
|
||||
compareValues,
|
||||
Comparison,
|
||||
CompilerOptions,
|
||||
createFutureSourceFile,
|
||||
createModuleSpecifierResolutionHost,
|
||||
createMultiMap,
|
||||
createPackageJsonImportFilter,
|
||||
@@ -27,50 +29,57 @@ import {
|
||||
ExportKind,
|
||||
ExportMapInfoKey,
|
||||
factory,
|
||||
findAncestor,
|
||||
first,
|
||||
firstDefined,
|
||||
flatMap,
|
||||
flatMapIterator,
|
||||
forEachExternalModuleToImportFrom,
|
||||
formatting,
|
||||
FutureSourceFile,
|
||||
FutureSymbolExportInfo,
|
||||
getAllowSyntheticDefaultImports,
|
||||
getBaseFileName,
|
||||
getDefaultExportInfoWorker,
|
||||
getDefaultLikeExportInfo,
|
||||
getDirectoryPath,
|
||||
getEmitModuleFormatOfFileWorker,
|
||||
getEmitModuleKind,
|
||||
getEmitModuleResolutionKind,
|
||||
getEmitScriptTarget,
|
||||
getExportInfoMap,
|
||||
getImpliedNodeFormatForEmitWorker,
|
||||
getMeaningFromDeclaration,
|
||||
getMeaningFromLocation,
|
||||
getNameForExportedSymbol,
|
||||
getNodeId,
|
||||
getOutputExtension,
|
||||
getQuoteFromPreference,
|
||||
getQuotePreference,
|
||||
getSourceFileOfNode,
|
||||
getSymbolId,
|
||||
getSynthesizedDeepClone,
|
||||
getTokenAtPosition,
|
||||
getTokenPosOfNode,
|
||||
getTypeKeywordOfTypeOnlyImport,
|
||||
getUniqueSymbolId,
|
||||
hasJSFileExtension,
|
||||
hostGetCanonicalFileName,
|
||||
Identifier,
|
||||
ImportClause,
|
||||
ImportEqualsDeclaration,
|
||||
importFromModuleSpecifier,
|
||||
ImportKind,
|
||||
ImportSpecifier,
|
||||
insertImports,
|
||||
InternalSymbolName,
|
||||
isExternalModule,
|
||||
isExternalModuleReference,
|
||||
isFullSourceFile,
|
||||
isIdentifier,
|
||||
isIdentifierPart,
|
||||
isIdentifierStart,
|
||||
isImportableFile,
|
||||
isImportDeclaration,
|
||||
isImportEqualsDeclaration,
|
||||
isInJSFile,
|
||||
isIntrinsicJsxName,
|
||||
isJSDocImportTag,
|
||||
isJsxClosingElement,
|
||||
@@ -79,6 +88,7 @@ import {
|
||||
isJSXTagName,
|
||||
isNamedImports,
|
||||
isNamespaceImport,
|
||||
isRequireVariableStatement,
|
||||
isSourceFileJS,
|
||||
isStringANonContextualKeyword,
|
||||
isStringLiteral,
|
||||
@@ -101,6 +111,7 @@ import {
|
||||
MultiMap,
|
||||
Mutable,
|
||||
NamedImports,
|
||||
NamespaceImport,
|
||||
Node,
|
||||
NodeFlags,
|
||||
nodeIsMissing,
|
||||
@@ -114,6 +125,7 @@ import {
|
||||
QuotePreference,
|
||||
removeFileExtension,
|
||||
removeSuffix,
|
||||
RequireOrImportCall,
|
||||
RequireVariableStatement,
|
||||
sameMap,
|
||||
ScriptTarget,
|
||||
@@ -140,6 +152,7 @@ import {
|
||||
TypeChecker,
|
||||
TypeOnlyAliasDeclaration,
|
||||
UserPreferences,
|
||||
VariableDeclarationInitializedTo,
|
||||
} from "../_namespaces/ts";
|
||||
import {
|
||||
createCodeFixAction,
|
||||
@@ -200,6 +213,14 @@ registerCodeFix({
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* The node kinds that may be the declaration of an alias symbol imported/required from an external module.
|
||||
* `ImportClause` is the declaration for a syntactic default import. `VariableDeclaration` is the declaration
|
||||
* for a non-destructured `require` call.
|
||||
* @internal
|
||||
*/
|
||||
export type ImportOrRequireAliasDeclaration = ImportEqualsDeclaration | ImportClause | ImportSpecifier | NamespaceImport | VariableDeclarationInitializedTo<RequireOrImportCall> | BindingElement;
|
||||
|
||||
/**
|
||||
* Computes multiple import additions to a file and writes them to a ChangeTracker.
|
||||
*
|
||||
@@ -208,12 +229,16 @@ registerCodeFix({
|
||||
export interface ImportAdder {
|
||||
hasFixes(): boolean;
|
||||
addImportFromDiagnostic: (diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) => void;
|
||||
addImportFromExportedSymbol: (exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean) => void;
|
||||
addImportFromExportedSymbol: (exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean, referenceImport?: ImportOrRequireAliasDeclaration) => void;
|
||||
addImportForNonExistentExport: (exportName: string, exportingFileName: string, exportKind: ExportKind, exportedMeanings: SymbolFlags, isImportUsageValidAsTypeOnly: boolean) => void;
|
||||
addImportForUnresolvedIdentifier: (context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) => void;
|
||||
addVerbatimImport: (declaration: AnyImportOrRequireStatement | ImportOrRequireAliasDeclaration) => void;
|
||||
removeExistingImport: (declaration: ImportOrRequireAliasDeclaration) => void;
|
||||
writeFixes: (changeTracker: textChanges.ChangeTracker, oldFileQuotePreference?: QuotePreference) => void;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function createImportAdder(sourceFile: SourceFile, program: Program, preferences: UserPreferences, host: LanguageServiceHost, cancellationToken?: CancellationToken): ImportAdder {
|
||||
export function createImportAdder(sourceFile: SourceFile | FutureSourceFile, program: Program, preferences: UserPreferences, host: LanguageServiceHost, cancellationToken?: CancellationToken): ImportAdder {
|
||||
return createImportAdderWorker(sourceFile, program, /*useAutoImportProvider*/ false, preferences, host, cancellationToken);
|
||||
}
|
||||
|
||||
@@ -223,18 +248,29 @@ interface AddToExistingState {
|
||||
readonly namedImports: Map<string, AddAsTypeOnly>;
|
||||
}
|
||||
|
||||
function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAutoImportProvider: boolean, preferences: UserPreferences, host: LanguageServiceHost, cancellationToken: CancellationToken | undefined): ImportAdder {
|
||||
function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, program: Program, useAutoImportProvider: boolean, preferences: UserPreferences, host: LanguageServiceHost, cancellationToken: CancellationToken | undefined): ImportAdder {
|
||||
const compilerOptions = program.getCompilerOptions();
|
||||
// Namespace fixes don't conflict, so just build a list.
|
||||
const addToNamespace: FixUseNamespaceImport[] = [];
|
||||
const importType: FixAddJsdocTypeImport[] = [];
|
||||
/** Keys are import clause node IDs. */
|
||||
const addToExisting = new Map<string, AddToExistingState>();
|
||||
const addToExisting = new Map<ImportClause | ObjectBindingPattern, AddToExistingState>();
|
||||
const removeExisting = new Set<ImportOrRequireAliasDeclaration>();
|
||||
const verbatimImports = new Set<AnyImportOrRequireStatement | ImportOrRequireAliasDeclaration>();
|
||||
|
||||
type NewImportsKey = `${0 | 1}|${string}`;
|
||||
/** Use `getNewImportEntry` for access */
|
||||
const newImports = new Map<NewImportsKey, Mutable<ImportsCollection & { useRequire: boolean; }>>();
|
||||
return { addImportFromDiagnostic, addImportFromExportedSymbol, writeFixes, hasFixes };
|
||||
return { addImportFromDiagnostic, addImportFromExportedSymbol, writeFixes, hasFixes, addImportForUnresolvedIdentifier, addImportForNonExistentExport, removeExistingImport, addVerbatimImport };
|
||||
|
||||
function addVerbatimImport(declaration: AnyImportOrRequireStatement | ImportOrRequireAliasDeclaration) {
|
||||
verbatimImports.add(declaration);
|
||||
}
|
||||
|
||||
function addImportForUnresolvedIdentifier(context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) {
|
||||
const info = getFixInfosWithoutDiagnostic(context, symbolToken, useAutoImportProvider);
|
||||
if (!info || !info.length) return;
|
||||
addImport(first(info));
|
||||
}
|
||||
|
||||
function addImportFromDiagnostic(diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) {
|
||||
const info = getFixInfos(context, diagnostic.code, diagnostic.start, useAutoImportProvider);
|
||||
@@ -242,19 +278,89 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu
|
||||
addImport(first(info));
|
||||
}
|
||||
|
||||
function addImportFromExportedSymbol(exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean) {
|
||||
function addImportFromExportedSymbol(exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean, referenceImport?: ImportOrRequireAliasDeclaration) {
|
||||
const moduleSymbol = Debug.checkDefined(exportedSymbol.parent);
|
||||
const symbolName = getNameForExportedSymbol(exportedSymbol, getEmitScriptTarget(compilerOptions));
|
||||
const checker = program.getTypeChecker();
|
||||
const symbol = checker.getMergedSymbol(skipAlias(exportedSymbol, checker));
|
||||
const exportInfo = getAllExportInfoForSymbol(sourceFile, symbol, symbolName, moduleSymbol, /*preferCapitalized*/ false, program, host, preferences, cancellationToken);
|
||||
const useRequire = shouldUseRequire(sourceFile, program);
|
||||
const fix = getImportFixForSymbol(sourceFile, Debug.checkDefined(exportInfo), program, /*position*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences);
|
||||
let fix = getImportFixForSymbol(sourceFile, Debug.checkDefined(exportInfo), program, /*position*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences);
|
||||
if (fix) {
|
||||
addImport({ fix, symbolName, errorIdentifierText: undefined });
|
||||
const localName = tryCast(referenceImport?.name, isIdentifier)?.text ?? symbolName;
|
||||
if (
|
||||
referenceImport
|
||||
&& isTypeOnlyImportDeclaration(referenceImport)
|
||||
&& (fix.kind === ImportFixKind.AddNew || fix.kind === ImportFixKind.AddToExisting)
|
||||
&& fix.addAsTypeOnly === AddAsTypeOnly.Allowed
|
||||
) {
|
||||
// Copy the type-only status from the reference import
|
||||
fix = { ...fix, addAsTypeOnly: AddAsTypeOnly.Required };
|
||||
}
|
||||
addImport({ fix, symbolName: localName ?? symbolName, errorIdentifierText: undefined });
|
||||
}
|
||||
}
|
||||
|
||||
function addImportForNonExistentExport(exportName: string, exportingFileName: string, exportKind: ExportKind, exportedMeanings: SymbolFlags, isImportUsageValidAsTypeOnly: boolean) {
|
||||
const exportingSourceFile = program.getSourceFile(exportingFileName);
|
||||
const useRequire = shouldUseRequire(sourceFile, program);
|
||||
if (exportingSourceFile && exportingSourceFile.symbol) {
|
||||
const { fixes } = getImportFixes(
|
||||
[{
|
||||
exportKind,
|
||||
isFromPackageJson: false,
|
||||
moduleFileName: exportingFileName,
|
||||
moduleSymbol: exportingSourceFile.symbol,
|
||||
targetFlags: exportedMeanings,
|
||||
}],
|
||||
/*usagePosition*/ undefined,
|
||||
isImportUsageValidAsTypeOnly,
|
||||
useRequire,
|
||||
program,
|
||||
sourceFile,
|
||||
host,
|
||||
preferences,
|
||||
);
|
||||
if (fixes.length) {
|
||||
addImport({ fix: fixes[0], symbolName: exportName, errorIdentifierText: exportName });
|
||||
}
|
||||
}
|
||||
else {
|
||||
// File does not exist yet or has no exports, so all imports added will be "new"
|
||||
const futureExportingSourceFile = createFutureSourceFile(exportingFileName, ModuleKind.ESNext, program, host);
|
||||
const moduleSpecifier = moduleSpecifiers.getLocalModuleSpecifierBetweenFileNames(
|
||||
sourceFile,
|
||||
exportingFileName,
|
||||
compilerOptions,
|
||||
createModuleSpecifierResolutionHost(program, host),
|
||||
);
|
||||
const importKind = getImportKind(futureExportingSourceFile, exportKind, program);
|
||||
const addAsTypeOnly = getAddAsTypeOnly(
|
||||
isImportUsageValidAsTypeOnly,
|
||||
/*isForNewImportDeclaration*/ true,
|
||||
/*symbol*/ undefined,
|
||||
exportedMeanings,
|
||||
program.getTypeChecker(),
|
||||
compilerOptions,
|
||||
);
|
||||
const fix: FixAddNewImport = {
|
||||
kind: ImportFixKind.AddNew,
|
||||
moduleSpecifier,
|
||||
importKind,
|
||||
addAsTypeOnly,
|
||||
useRequire,
|
||||
};
|
||||
addImport({ fix, symbolName: exportName, errorIdentifierText: exportName });
|
||||
}
|
||||
}
|
||||
|
||||
function removeExistingImport(declaration: ImportOrRequireAliasDeclaration) {
|
||||
if (declaration.kind === SyntaxKind.ImportClause) {
|
||||
Debug.assertIsDefined(declaration.name, "ImportClause should have a name if it's being removed");
|
||||
}
|
||||
removeExisting.add(declaration);
|
||||
}
|
||||
|
||||
function addImport(info: FixInfo) {
|
||||
const { fix, symbolName } = info;
|
||||
switch (fix.kind) {
|
||||
@@ -266,10 +372,9 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu
|
||||
break;
|
||||
case ImportFixKind.AddToExisting: {
|
||||
const { importClauseOrBindingPattern, importKind, addAsTypeOnly } = fix;
|
||||
const key = String(getNodeId(importClauseOrBindingPattern));
|
||||
let entry = addToExisting.get(key);
|
||||
let entry = addToExisting.get(importClauseOrBindingPattern);
|
||||
if (!entry) {
|
||||
addToExisting.set(key, entry = { importClauseOrBindingPattern, defaultImport: undefined, namedImports: new Map() });
|
||||
addToExisting.set(importClauseOrBindingPattern, entry = { importClauseOrBindingPattern, defaultImport: undefined, namedImports: new Map() });
|
||||
}
|
||||
if (importKind === ImportKind.Named) {
|
||||
const prevValue = entry?.namedImports.get(symbolName);
|
||||
@@ -362,7 +467,7 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu
|
||||
|
||||
function writeFixes(changeTracker: textChanges.ChangeTracker, oldFileQuotePreference?: QuotePreference) {
|
||||
let quotePreference: QuotePreference;
|
||||
if (sourceFile.imports.length === 0 && oldFileQuotePreference !== undefined) {
|
||||
if (isFullSourceFile(sourceFile) && sourceFile.imports.length === 0 && oldFileQuotePreference !== undefined) {
|
||||
// If the target file has no imports, we must use the same quote preference as the file we are importing from.
|
||||
quotePreference = oldFileQuotePreference;
|
||||
}
|
||||
@@ -370,18 +475,102 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu
|
||||
quotePreference = getQuotePreference(sourceFile, preferences);
|
||||
}
|
||||
for (const fix of addToNamespace) {
|
||||
addNamespaceQualifier(changeTracker, sourceFile, fix);
|
||||
// Any modifications to existing syntax imply SourceFile already exists
|
||||
addNamespaceQualifier(changeTracker, sourceFile as SourceFile, fix);
|
||||
}
|
||||
for (const fix of importType) {
|
||||
addImportType(changeTracker, sourceFile, fix, quotePreference);
|
||||
// Any modifications to existing syntax imply SourceFile already exists
|
||||
addImportType(changeTracker, sourceFile as SourceFile, fix, quotePreference);
|
||||
}
|
||||
let importSpecifiersToRemoveWhileAdding: Set<ImportSpecifier | BindingElement> | undefined;
|
||||
if (removeExisting.size) {
|
||||
Debug.assert(isFullSourceFile(sourceFile), "Cannot remove imports from a future source file");
|
||||
const importDeclarationsWithRemovals = new Set(mapDefined([...removeExisting], d => findAncestor(d, isImportDeclaration)!));
|
||||
const variableDeclarationsWithRemovals = new Set(mapDefined([...removeExisting], d => findAncestor(d, isVariableDeclarationInitializedToRequire)!));
|
||||
const emptyImportDeclarations = [...importDeclarationsWithRemovals].filter(d =>
|
||||
// nothing added to the import declaration
|
||||
!addToExisting.has(d.importClause!) &&
|
||||
// no default, or default is being removed
|
||||
(!d.importClause?.name || removeExisting.has(d.importClause)) &&
|
||||
// no namespace import, or namespace import is being removed
|
||||
(!tryCast(d.importClause?.namedBindings, isNamespaceImport) || removeExisting.has(d.importClause!.namedBindings as NamespaceImport)) &&
|
||||
// no named imports, or all named imports are being removed
|
||||
(!tryCast(d.importClause?.namedBindings, isNamedImports) || every((d.importClause!.namedBindings as NamedImports).elements, e => removeExisting.has(e)))
|
||||
);
|
||||
const emptyVariableDeclarations = [...variableDeclarationsWithRemovals].filter(d =>
|
||||
// no binding elements being added to the variable declaration
|
||||
(d.name.kind !== SyntaxKind.ObjectBindingPattern || !addToExisting.has(d.name)) &&
|
||||
// no binding elements, or all binding elements are being removed
|
||||
(d.name.kind !== SyntaxKind.ObjectBindingPattern || every(d.name.elements, e => removeExisting.has(e)))
|
||||
);
|
||||
const namedBindingsToDelete = [...importDeclarationsWithRemovals].filter(d =>
|
||||
// has named bindings
|
||||
d.importClause?.namedBindings &&
|
||||
// is not being fully removed
|
||||
emptyImportDeclarations.indexOf(d) === -1 &&
|
||||
// is not gaining named imports
|
||||
!addToExisting.get(d.importClause)?.namedImports &&
|
||||
// all named imports are being removed
|
||||
(d.importClause.namedBindings.kind === SyntaxKind.NamespaceImport || every(d.importClause.namedBindings.elements, e => removeExisting.has(e)))
|
||||
);
|
||||
for (const declaration of [...emptyImportDeclarations, ...emptyVariableDeclarations]) {
|
||||
changeTracker.delete(sourceFile, declaration);
|
||||
}
|
||||
for (const declaration of namedBindingsToDelete) {
|
||||
changeTracker.replaceNode(
|
||||
sourceFile,
|
||||
declaration.importClause!,
|
||||
factory.updateImportClause(
|
||||
declaration.importClause!,
|
||||
declaration.importClause!.isTypeOnly,
|
||||
declaration.importClause!.name,
|
||||
/*namedBindings*/ undefined,
|
||||
),
|
||||
);
|
||||
}
|
||||
for (const declaration of removeExisting) {
|
||||
const importDeclaration = findAncestor(declaration, isImportDeclaration);
|
||||
if (
|
||||
importDeclaration &&
|
||||
emptyImportDeclarations.indexOf(importDeclaration) === -1 &&
|
||||
namedBindingsToDelete.indexOf(importDeclaration) === -1
|
||||
) {
|
||||
if (declaration.kind === SyntaxKind.ImportClause) {
|
||||
changeTracker.delete(sourceFile, declaration.name!);
|
||||
}
|
||||
else {
|
||||
Debug.assert(declaration.kind === SyntaxKind.ImportSpecifier, "NamespaceImport should have been handled earlier");
|
||||
if (addToExisting.get(importDeclaration.importClause!)?.namedImports) {
|
||||
// Handle combined inserts/deletes in `doAddExistingFix`
|
||||
(importSpecifiersToRemoveWhileAdding ??= new Set()).add(declaration);
|
||||
}
|
||||
else {
|
||||
changeTracker.delete(sourceFile, declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.BindingElement) {
|
||||
if (addToExisting.get(declaration.parent as ObjectBindingPattern)?.namedImports) {
|
||||
// Handle combined inserts/deletes in `doAddExistingFix`
|
||||
(importSpecifiersToRemoveWhileAdding ??= new Set()).add(declaration);
|
||||
}
|
||||
else {
|
||||
changeTracker.delete(sourceFile, declaration);
|
||||
}
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.ImportEqualsDeclaration) {
|
||||
changeTracker.delete(sourceFile, declaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
addToExisting.forEach(({ importClauseOrBindingPattern, defaultImport, namedImports }) => {
|
||||
doAddExistingFix(
|
||||
changeTracker,
|
||||
sourceFile,
|
||||
sourceFile as SourceFile,
|
||||
importClauseOrBindingPattern,
|
||||
defaultImport,
|
||||
arrayFrom(namedImports.entries(), ([name, addAsTypeOnly]) => ({ addAsTypeOnly, name })),
|
||||
importSpecifiersToRemoveWhileAdding,
|
||||
preferences,
|
||||
);
|
||||
});
|
||||
@@ -401,13 +590,84 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu
|
||||
);
|
||||
newDeclarations = combine(newDeclarations, declarations);
|
||||
});
|
||||
newDeclarations = combine(newDeclarations, getCombinedVerbatimImports());
|
||||
if (newDeclarations) {
|
||||
insertImports(changeTracker, sourceFile, newDeclarations, /*blankLineBetween*/ true, preferences);
|
||||
}
|
||||
}
|
||||
|
||||
function getCombinedVerbatimImports(): AnyImportOrRequireStatement[] | undefined {
|
||||
if (!verbatimImports.size) return undefined;
|
||||
const importDeclarations = new Set(mapDefined([...verbatimImports], d => findAncestor(d, isImportDeclaration)));
|
||||
const requireStatements = new Set(mapDefined([...verbatimImports], d => findAncestor(d, isRequireVariableStatement)));
|
||||
return [
|
||||
...mapDefined([...verbatimImports], d =>
|
||||
d.kind === SyntaxKind.ImportEqualsDeclaration
|
||||
? getSynthesizedDeepClone(d, /*includeTrivia*/ true)
|
||||
: undefined),
|
||||
...[...importDeclarations].map(d => {
|
||||
if (verbatimImports.has(d)) {
|
||||
return getSynthesizedDeepClone(d, /*includeTrivia*/ true);
|
||||
}
|
||||
return getSynthesizedDeepClone(
|
||||
factory.updateImportDeclaration(
|
||||
d,
|
||||
d.modifiers,
|
||||
d.importClause && factory.updateImportClause(
|
||||
d.importClause,
|
||||
d.importClause.isTypeOnly,
|
||||
verbatimImports.has(d.importClause) ? d.importClause.name : undefined,
|
||||
verbatimImports.has(d.importClause.namedBindings as NamespaceImport)
|
||||
? d.importClause.namedBindings as NamespaceImport :
|
||||
tryCast(d.importClause.namedBindings, isNamedImports)?.elements.some(e => verbatimImports.has(e))
|
||||
? factory.updateNamedImports(
|
||||
d.importClause.namedBindings as NamedImports,
|
||||
(d.importClause.namedBindings as NamedImports).elements.filter(e => verbatimImports.has(e)),
|
||||
)
|
||||
: undefined,
|
||||
),
|
||||
d.moduleSpecifier,
|
||||
d.attributes,
|
||||
),
|
||||
/*includeTrivia*/ true,
|
||||
);
|
||||
}),
|
||||
...[...requireStatements].map(s => {
|
||||
if (verbatimImports.has(s)) {
|
||||
return getSynthesizedDeepClone(s, /*includeTrivia*/ true);
|
||||
}
|
||||
return getSynthesizedDeepClone(
|
||||
factory.updateVariableStatement(
|
||||
s,
|
||||
s.modifiers,
|
||||
factory.updateVariableDeclarationList(
|
||||
s.declarationList,
|
||||
mapDefined(s.declarationList.declarations, d => {
|
||||
if (verbatimImports.has(d)) {
|
||||
return d;
|
||||
}
|
||||
return factory.updateVariableDeclaration(
|
||||
d,
|
||||
d.name.kind === SyntaxKind.ObjectBindingPattern
|
||||
? factory.updateObjectBindingPattern(
|
||||
d.name,
|
||||
d.name.elements.filter(e => verbatimImports.has(e)),
|
||||
) : d.name,
|
||||
d.exclamationToken,
|
||||
d.type,
|
||||
d.initializer,
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
/*includeTrivia*/ true,
|
||||
) as RequireVariableStatement;
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
function hasFixes() {
|
||||
return addToNamespace.length > 0 || importType.length > 0 || addToExisting.size > 0 || newImports.size > 0;
|
||||
return addToNamespace.length > 0 || importType.length > 0 || addToExisting.size > 0 || newImports.size > 0 || verbatimImports.size > 0 || removeExisting.size > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,13 +682,13 @@ export interface ImportSpecifierResolver {
|
||||
position: number,
|
||||
isValidTypeOnlyUseSite: boolean,
|
||||
fromCacheOnly?: boolean,
|
||||
): { exportInfo?: SymbolExportInfo; moduleSpecifier: string; computedWithoutCacheCount: number; } | undefined;
|
||||
): { exportInfo?: SymbolExportInfo | FutureSymbolExportInfo; moduleSpecifier: string; computedWithoutCacheCount: number; } | undefined;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function createImportSpecifierResolver(importingFile: SourceFile, program: Program, host: LanguageServiceHost, preferences: UserPreferences): ImportSpecifierResolver {
|
||||
const packageJsonImportFilter = createPackageJsonImportFilter(importingFile, preferences, host);
|
||||
const importMap = createExistingImportMap(program.getTypeChecker(), importingFile, program.getCompilerOptions());
|
||||
const importMap = createExistingImportMap(importingFile, program);
|
||||
return { getModuleSpecifierForBestExportInfo };
|
||||
|
||||
function getModuleSpecifierForBestExportInfo(
|
||||
@@ -436,7 +696,7 @@ export function createImportSpecifierResolver(importingFile: SourceFile, program
|
||||
position: number,
|
||||
isValidTypeOnlyUseSite: boolean,
|
||||
fromCacheOnly?: boolean,
|
||||
): { exportInfo?: SymbolExportInfo; moduleSpecifier: string; computedWithoutCacheCount: number; } | undefined {
|
||||
): { exportInfo?: SymbolExportInfo | FutureSymbolExportInfo; moduleSpecifier: string; computedWithoutCacheCount: number; } | undefined {
|
||||
const { fixes, computedWithoutCacheCount } = getImportFixes(
|
||||
exportInfo,
|
||||
position,
|
||||
@@ -477,7 +737,7 @@ type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImpor
|
||||
// Properties are be undefined if fix is derived from an existing import
|
||||
interface ImportFixBase {
|
||||
readonly isReExport?: boolean;
|
||||
readonly exportInfo?: SymbolExportInfo;
|
||||
readonly exportInfo?: SymbolExportInfo | FutureSymbolExportInfo;
|
||||
readonly moduleSpecifier: string;
|
||||
}
|
||||
interface Qualification {
|
||||
@@ -491,7 +751,7 @@ interface FixAddJsdocTypeImport extends ImportFixBase {
|
||||
readonly kind: ImportFixKind.JsdocTypeImport;
|
||||
readonly usagePosition: number;
|
||||
readonly isReExport: boolean;
|
||||
readonly exportInfo: SymbolExportInfo;
|
||||
readonly exportInfo: SymbolExportInfo | FutureSymbolExportInfo;
|
||||
}
|
||||
interface FixAddToExistingImport extends ImportFixBase {
|
||||
readonly kind: ImportFixKind.AddToExisting;
|
||||
@@ -516,7 +776,7 @@ interface FixAddToExistingImportInfo {
|
||||
readonly declaration: AnyImportOrRequire;
|
||||
readonly importKind: ImportKind;
|
||||
readonly targetFlags: SymbolFlags;
|
||||
readonly symbol: Symbol;
|
||||
readonly symbol?: Symbol;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
@@ -584,7 +844,7 @@ export function getPromoteTypeOnlyCompletionAction(sourceFile: SourceFile, symbo
|
||||
));
|
||||
}
|
||||
|
||||
function getImportFixForSymbol(sourceFile: SourceFile, exportInfos: readonly SymbolExportInfo[], program: Program, position: number | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, host: LanguageServiceHost, preferences: UserPreferences) {
|
||||
function getImportFixForSymbol(sourceFile: SourceFile | FutureSourceFile, exportInfos: readonly SymbolExportInfo[], program: Program, position: number | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, host: LanguageServiceHost, preferences: UserPreferences) {
|
||||
const packageJsonImportFilter = createPackageJsonImportFilter(sourceFile, preferences, host);
|
||||
return getBestFix(getImportFixes(exportInfos, position, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes, sourceFile, program, packageJsonImportFilter, host);
|
||||
}
|
||||
@@ -593,7 +853,7 @@ function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAc
|
||||
return { description, changes, commands };
|
||||
}
|
||||
|
||||
function getAllExportInfoForSymbol(importingFile: SourceFile, symbol: Symbol, symbolName: string, moduleSymbol: Symbol, preferCapitalized: boolean, program: Program, host: LanguageServiceHost, preferences: UserPreferences, cancellationToken: CancellationToken | undefined): readonly SymbolExportInfo[] | undefined {
|
||||
function getAllExportInfoForSymbol(importingFile: SourceFile | FutureSourceFile, symbol: Symbol, symbolName: string, moduleSymbol: Symbol, preferCapitalized: boolean, program: Program, host: LanguageServiceHost, preferences: UserPreferences, cancellationToken: CancellationToken | undefined): readonly SymbolExportInfo[] | undefined {
|
||||
const getChecker = createGetChecker(program, host);
|
||||
return getExportInfoMap(importingFile, host, program, preferences, cancellationToken)
|
||||
.search(importingFile.path, preferCapitalized, name => name === symbolName, info => {
|
||||
@@ -624,20 +884,24 @@ function getSingleExportInfoForSymbol(symbol: Symbol, symbolName: string, module
|
||||
}
|
||||
}
|
||||
|
||||
function isFutureSymbolExportInfoArray(info: readonly SymbolExportInfo[] | readonly FutureSymbolExportInfo[]): info is readonly FutureSymbolExportInfo[] {
|
||||
return info[0].symbol === undefined;
|
||||
}
|
||||
|
||||
function getImportFixes(
|
||||
exportInfos: readonly SymbolExportInfo[],
|
||||
exportInfos: readonly SymbolExportInfo[] | readonly FutureSymbolExportInfo[],
|
||||
usagePosition: number | undefined,
|
||||
isValidTypeOnlyUseSite: boolean,
|
||||
useRequire: boolean,
|
||||
program: Program,
|
||||
sourceFile: SourceFile,
|
||||
sourceFile: SourceFile | FutureSourceFile,
|
||||
host: LanguageServiceHost,
|
||||
preferences: UserPreferences,
|
||||
importMap = createExistingImportMap(program.getTypeChecker(), sourceFile, program.getCompilerOptions()),
|
||||
importMap = isFullSourceFile(sourceFile) ? createExistingImportMap(sourceFile, program) : undefined,
|
||||
fromCacheOnly?: boolean,
|
||||
): { computedWithoutCacheCount: number; fixes: readonly ImportFixWithModuleSpecifier[]; } {
|
||||
const checker = program.getTypeChecker();
|
||||
const existingImports = flatMap(exportInfos, importMap.getImportsForExportInfo);
|
||||
const existingImports = importMap && !isFutureSymbolExportInfoArray(exportInfos) ? flatMap(exportInfos, importMap.getImportsForExportInfo) : emptyArray;
|
||||
const useNamespace = usagePosition !== undefined && tryUseExistingNamespaceImport(existingImports, usagePosition);
|
||||
const addToExisting = tryAddToExistingImport(existingImports, isValidTypeOnlyUseSite, checker, program.getCompilerOptions());
|
||||
if (addToExisting) {
|
||||
@@ -706,7 +970,7 @@ function getNamespaceLikeImportText(declaration: AnyImportOrRequire) {
|
||||
function getAddAsTypeOnly(
|
||||
isValidTypeOnlyUseSite: boolean,
|
||||
isForNewImportDeclaration: boolean,
|
||||
symbol: Symbol,
|
||||
symbol: Symbol | undefined,
|
||||
targetFlags: SymbolFlags,
|
||||
checker: TypeChecker,
|
||||
compilerOptions: CompilerOptions,
|
||||
@@ -716,6 +980,7 @@ function getAddAsTypeOnly(
|
||||
return AddAsTypeOnly.NotAllowed;
|
||||
}
|
||||
if (
|
||||
symbol &&
|
||||
compilerOptions.verbatimModuleSyntax &&
|
||||
(!(targetFlags & SymbolFlags.Value) || !!checker.getTypeOnlyAliasDeclaration(symbol))
|
||||
) {
|
||||
@@ -798,7 +1063,8 @@ function tryAddToExistingImport(existingImports: readonly FixAddToExistingImport
|
||||
}
|
||||
}
|
||||
|
||||
function createExistingImportMap(checker: TypeChecker, importingFile: SourceFile, compilerOptions: CompilerOptions) {
|
||||
function createExistingImportMap(importingFile: SourceFile, program: Program) {
|
||||
const checker = program.getTypeChecker();
|
||||
let importMap: MultiMap<SymbolId, AnyImportOrRequire> | undefined;
|
||||
for (const moduleSpecifier of importingFile.imports) {
|
||||
const i = importFromModuleSpecifier(moduleSpecifier);
|
||||
@@ -828,15 +1094,15 @@ function createExistingImportMap(checker: TypeChecker, importingFile: SourceFile
|
||||
&& !every(matchingDeclarations, isJSDocImportTag)
|
||||
) return emptyArray;
|
||||
|
||||
const importKind = getImportKind(importingFile, exportKind, compilerOptions);
|
||||
const importKind = getImportKind(importingFile, exportKind, program);
|
||||
return matchingDeclarations.map(declaration => ({ declaration, importKind, symbol, targetFlags }));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function shouldUseRequire(sourceFile: SourceFile, program: Program): boolean {
|
||||
function shouldUseRequire(sourceFile: SourceFile | FutureSourceFile, program: Program): boolean {
|
||||
// 1. TypeScript files don't use require variable declarations
|
||||
if (!isSourceFileJS(sourceFile)) {
|
||||
if (!hasJSFileExtension(sourceFile.fileName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -852,8 +1118,9 @@ function shouldUseRequire(sourceFile: SourceFile, program: Program): boolean {
|
||||
|
||||
// 4. In --module nodenext, assume we're not emitting JS -> JS, so use
|
||||
// whatever syntax Node expects based on the detected module kind
|
||||
if (sourceFile.impliedNodeFormat === ModuleKind.CommonJS) return true;
|
||||
if (sourceFile.impliedNodeFormat === ModuleKind.ESNext) return false;
|
||||
// TODO: consider removing `impliedNodeFormatForEmit`
|
||||
if (getImpliedNodeFormatForEmit(sourceFile, program) === ModuleKind.CommonJS) return true;
|
||||
if (getImpliedNodeFormatForEmit(sourceFile, program) === ModuleKind.ESNext) return false;
|
||||
|
||||
// 5. Match the first other JS file in the program that's unambiguously CJS or ESM
|
||||
for (const otherFile of program.getSourceFiles()) {
|
||||
@@ -872,29 +1139,29 @@ function createGetChecker(program: Program, host: LanguageServiceHost) {
|
||||
|
||||
function getNewImportFixes(
|
||||
program: Program,
|
||||
sourceFile: SourceFile,
|
||||
sourceFile: SourceFile | FutureSourceFile,
|
||||
usagePosition: number | undefined,
|
||||
isValidTypeOnlyUseSite: boolean,
|
||||
useRequire: boolean,
|
||||
exportInfo: readonly SymbolExportInfo[],
|
||||
exportInfo: readonly (SymbolExportInfo | FutureSymbolExportInfo)[],
|
||||
host: LanguageServiceHost,
|
||||
preferences: UserPreferences,
|
||||
fromCacheOnly?: boolean,
|
||||
): { computedWithoutCacheCount: number; fixes: readonly (FixAddNewImport | FixAddJsdocTypeImport)[]; } {
|
||||
const isJs = isSourceFileJS(sourceFile);
|
||||
const isJs = hasJSFileExtension(sourceFile.fileName);
|
||||
const compilerOptions = program.getCompilerOptions();
|
||||
const moduleSpecifierResolutionHost = createModuleSpecifierResolutionHost(program, host);
|
||||
const getChecker = createGetChecker(program, host);
|
||||
const moduleResolution = getEmitModuleResolutionKind(compilerOptions);
|
||||
const rejectNodeModulesRelativePaths = moduleResolutionUsesNodeModules(moduleResolution);
|
||||
const getModuleSpecifiers = fromCacheOnly
|
||||
? (moduleSymbol: Symbol) => ({ moduleSpecifiers: moduleSpecifiers.tryGetModuleSpecifiersFromCache(moduleSymbol, sourceFile, moduleSpecifierResolutionHost, preferences), computedWithoutCache: false })
|
||||
: (moduleSymbol: Symbol, checker: TypeChecker) => moduleSpecifiers.getModuleSpecifiersWithCacheInfo(moduleSymbol, checker, compilerOptions, sourceFile, moduleSpecifierResolutionHost, preferences, /*options*/ undefined, /*forAutoImport*/ true);
|
||||
? (exportInfo: SymbolExportInfo | FutureSymbolExportInfo) => ({ moduleSpecifiers: moduleSpecifiers.tryGetModuleSpecifiersFromCache(exportInfo.moduleSymbol, sourceFile, moduleSpecifierResolutionHost, preferences), computedWithoutCache: false })
|
||||
: (exportInfo: SymbolExportInfo | FutureSymbolExportInfo, checker: TypeChecker) => moduleSpecifiers.getModuleSpecifiersWithCacheInfo(exportInfo.moduleSymbol, checker, compilerOptions, sourceFile, moduleSpecifierResolutionHost, preferences, /*options*/ undefined, /*forAutoImport*/ true);
|
||||
|
||||
let computedWithoutCacheCount = 0;
|
||||
const fixes = flatMap(exportInfo, (exportInfo, i) => {
|
||||
const checker = getChecker(exportInfo.isFromPackageJson);
|
||||
const { computedWithoutCache, moduleSpecifiers } = getModuleSpecifiers(exportInfo.moduleSymbol, checker);
|
||||
const { computedWithoutCache, moduleSpecifiers } = getModuleSpecifiers(exportInfo, checker);
|
||||
const importedSymbolHasValueMeaning = !!(exportInfo.targetFlags & SymbolFlags.Value);
|
||||
const addAsTypeOnly = getAddAsTypeOnly(isValidTypeOnlyUseSite, /*isForNewImportDeclaration*/ true, exportInfo.symbol, exportInfo.targetFlags, checker, compilerOptions);
|
||||
computedWithoutCacheCount += computedWithoutCache ? 1 : 0;
|
||||
@@ -906,7 +1173,7 @@ function getNewImportFixes(
|
||||
// `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types.
|
||||
return { kind: ImportFixKind.JsdocTypeImport, moduleSpecifier, usagePosition, exportInfo, isReExport: i > 0 };
|
||||
}
|
||||
const importKind = getImportKind(sourceFile, exportInfo.exportKind, compilerOptions);
|
||||
const importKind = getImportKind(sourceFile, exportInfo.exportKind, program);
|
||||
let qualification: Qualification | undefined;
|
||||
if (usagePosition !== undefined && importKind === ImportKind.CommonJS && exportInfo.exportKind === ExportKind.Named) {
|
||||
// Compiler options are restricting our import options to a require, but we need to access
|
||||
@@ -944,10 +1211,10 @@ function getNewImportFixes(
|
||||
}
|
||||
|
||||
function getFixesForAddImport(
|
||||
exportInfos: readonly SymbolExportInfo[],
|
||||
exportInfos: readonly SymbolExportInfo[] | readonly FutureSymbolExportInfo[],
|
||||
existingImports: readonly FixAddToExistingImportInfo[],
|
||||
program: Program,
|
||||
sourceFile: SourceFile,
|
||||
sourceFile: SourceFile | FutureSourceFile,
|
||||
usagePosition: number | undefined,
|
||||
isValidTypeOnlyUseSite: boolean,
|
||||
useRequire: boolean,
|
||||
@@ -1011,7 +1278,13 @@ function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModuleSpecif
|
||||
compareModuleSpecifiers(a.fix, b.fix, sourceFile, program, packageJsonImportFilter.allowsImportingSpecifier, _toPath));
|
||||
}
|
||||
|
||||
function getBestFix(fixes: readonly ImportFixWithModuleSpecifier[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): ImportFixWithModuleSpecifier | undefined {
|
||||
function getFixInfosWithoutDiagnostic(context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly FixInfo[] | undefined {
|
||||
const info = getFixesInfoForNonUMDImport(context, symbolToken, useAutoImportProvider);
|
||||
const packageJsonImportFilter = createPackageJsonImportFilter(context.sourceFile, context.preferences, context.host);
|
||||
return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host);
|
||||
}
|
||||
|
||||
function getBestFix(fixes: readonly ImportFixWithModuleSpecifier[], sourceFile: SourceFile | FutureSourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): ImportFixWithModuleSpecifier | undefined {
|
||||
if (!some(fixes)) return;
|
||||
// These will always be placed first if available, and are better than other kinds
|
||||
if (fixes[0].kind === ImportFixKind.UseNamespace || fixes[0].kind === ImportFixKind.AddToExisting) {
|
||||
@@ -1035,7 +1308,7 @@ function getBestFix(fixes: readonly ImportFixWithModuleSpecifier[], sourceFile:
|
||||
function compareModuleSpecifiers(
|
||||
a: ImportFixWithModuleSpecifier,
|
||||
b: ImportFixWithModuleSpecifier,
|
||||
importingFile: SourceFile,
|
||||
importingFile: SourceFile | FutureSourceFile,
|
||||
program: Program,
|
||||
allowsImportingSpecifier: (specifier: string) => boolean,
|
||||
toPath: (fileName: string) => Path,
|
||||
@@ -1044,8 +1317,8 @@ function compareModuleSpecifiers(
|
||||
return compareBooleans(allowsImportingSpecifier(b.moduleSpecifier), allowsImportingSpecifier(a.moduleSpecifier))
|
||||
|| compareNodeCoreModuleSpecifiers(a.moduleSpecifier, b.moduleSpecifier, importingFile, program)
|
||||
|| compareBooleans(
|
||||
isFixPossiblyReExportingImportingFile(a, importingFile, program.getCompilerOptions(), toPath),
|
||||
isFixPossiblyReExportingImportingFile(b, importingFile, program.getCompilerOptions(), toPath),
|
||||
isFixPossiblyReExportingImportingFile(a, importingFile.path, toPath),
|
||||
isFixPossiblyReExportingImportingFile(b, importingFile.path, toPath),
|
||||
)
|
||||
|| compareNumberOfDirectorySeparators(a.moduleSpecifier, b.moduleSpecifier);
|
||||
}
|
||||
@@ -1056,14 +1329,14 @@ function compareModuleSpecifiers(
|
||||
// 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".
|
||||
function isFixPossiblyReExportingImportingFile(fix: ImportFixWithModuleSpecifier, importingFile: SourceFile, compilerOptions: CompilerOptions, toPath: (fileName: string) => Path): boolean {
|
||||
function isFixPossiblyReExportingImportingFile(fix: ImportFixWithModuleSpecifier, importingFilePath: Path, toPath: (fileName: string) => Path): boolean {
|
||||
if (
|
||||
fix.isReExport &&
|
||||
fix.exportInfo?.moduleFileName &&
|
||||
isIndexFileName(fix.exportInfo.moduleFileName)
|
||||
) {
|
||||
const reExportDir = toPath(getDirectoryPath(fix.exportInfo.moduleFileName));
|
||||
return startsWith(importingFile.path, reExportDir);
|
||||
return startsWith(importingFilePath, reExportDir);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -1072,7 +1345,7 @@ function isIndexFileName(fileName: string) {
|
||||
return getBaseFileName(fileName, [".js", ".jsx", ".d.ts", ".ts", ".tsx"], /*ignoreCase*/ true) === "index";
|
||||
}
|
||||
|
||||
function compareNodeCoreModuleSpecifiers(a: string, b: string, importingFile: SourceFile, program: Program): Comparison {
|
||||
function compareNodeCoreModuleSpecifiers(a: string, b: string, importingFile: SourceFile | FutureSourceFile, program: Program): Comparison {
|
||||
if (startsWith(a, "node:") && !startsWith(b, "node:")) return shouldUseUriStyleNodeCoreModules(importingFile, program) ? Comparison.LessThan : Comparison.GreaterThan;
|
||||
if (startsWith(b, "node:") && !startsWith(a, "node:")) return shouldUseUriStyleNodeCoreModules(importingFile, program) ? Comparison.GreaterThan : Comparison.LessThan;
|
||||
return Comparison.EqualTo;
|
||||
@@ -1117,8 +1390,8 @@ function getUmdSymbol(token: Node, checker: TypeChecker): Symbol | undefined {
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export function getImportKind(importingFile: SourceFile, exportKind: ExportKind, compilerOptions: CompilerOptions, forceImportKeyword?: boolean): ImportKind {
|
||||
if (compilerOptions.verbatimModuleSyntax && (getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS || importingFile.impliedNodeFormat === ModuleKind.CommonJS)) {
|
||||
export function getImportKind(importingFile: SourceFile | FutureSourceFile, exportKind: ExportKind, program: Program, forceImportKeyword?: boolean): ImportKind {
|
||||
if (program.getCompilerOptions().verbatimModuleSyntax && getEmitModuleFormatOfFile(importingFile, program) === ModuleKind.CommonJS) {
|
||||
// TODO: if the exporting file is ESM under nodenext, or `forceImport` is given in a JS file, this is impossible
|
||||
return ImportKind.CommonJS;
|
||||
}
|
||||
@@ -1128,28 +1401,28 @@ export function getImportKind(importingFile: SourceFile, exportKind: ExportKind,
|
||||
case ExportKind.Default:
|
||||
return ImportKind.Default;
|
||||
case ExportKind.ExportEquals:
|
||||
return getExportEqualsImportKind(importingFile, compilerOptions, !!forceImportKeyword);
|
||||
return getExportEqualsImportKind(importingFile, program.getCompilerOptions(), !!forceImportKeyword);
|
||||
case ExportKind.UMD:
|
||||
return getUmdImportKind(importingFile, compilerOptions, !!forceImportKeyword);
|
||||
return getUmdImportKind(importingFile, program, !!forceImportKeyword);
|
||||
default:
|
||||
return Debug.assertNever(exportKind);
|
||||
}
|
||||
}
|
||||
|
||||
function getUmdImportKind(importingFile: SourceFile, compilerOptions: CompilerOptions, forceImportKeyword: boolean): ImportKind {
|
||||
function getUmdImportKind(importingFile: SourceFile | FutureSourceFile, program: Program, forceImportKeyword: boolean): ImportKind {
|
||||
// Import a synthetic `default` if enabled.
|
||||
if (getAllowSyntheticDefaultImports(compilerOptions)) {
|
||||
if (getAllowSyntheticDefaultImports(program.getCompilerOptions())) {
|
||||
return ImportKind.Default;
|
||||
}
|
||||
|
||||
// When a synthetic `default` is unavailable, use `import..require` if the module kind supports it.
|
||||
const moduleKind = getEmitModuleKind(compilerOptions);
|
||||
const moduleKind = getEmitModuleKind(program.getCompilerOptions());
|
||||
switch (moduleKind) {
|
||||
case ModuleKind.AMD:
|
||||
case ModuleKind.CommonJS:
|
||||
case ModuleKind.UMD:
|
||||
if (isInJSFile(importingFile)) {
|
||||
return isExternalModule(importingFile) || forceImportKeyword ? ImportKind.Namespace : ImportKind.CommonJS;
|
||||
if (hasJSFileExtension(importingFile.fileName)) {
|
||||
return importingFile.externalModuleIndicator || forceImportKeyword ? ImportKind.Namespace : ImportKind.CommonJS;
|
||||
}
|
||||
return ImportKind.CommonJS;
|
||||
case ModuleKind.System:
|
||||
@@ -1163,7 +1436,7 @@ function getUmdImportKind(importingFile: SourceFile, compilerOptions: CompilerOp
|
||||
return ImportKind.Namespace;
|
||||
case ModuleKind.Node16:
|
||||
case ModuleKind.NodeNext:
|
||||
return importingFile.impliedNodeFormat === ModuleKind.ESNext ? ImportKind.Namespace : ImportKind.CommonJS;
|
||||
return getImpliedNodeFormatForEmit(importingFile, program) === ModuleKind.ESNext ? ImportKind.Namespace : ImportKind.CommonJS;
|
||||
default:
|
||||
return Debug.assertNever(moduleKind, `Unexpected moduleKind ${moduleKind}`);
|
||||
}
|
||||
@@ -1265,9 +1538,9 @@ function getExportInfos(
|
||||
return originalSymbolToExportInfos;
|
||||
}
|
||||
|
||||
function getExportEqualsImportKind(importingFile: SourceFile, compilerOptions: CompilerOptions, forceImportKeyword: boolean): ImportKind {
|
||||
function getExportEqualsImportKind(importingFile: SourceFile | FutureSourceFile, compilerOptions: CompilerOptions, forceImportKeyword: boolean): ImportKind {
|
||||
const allowSyntheticDefaults = getAllowSyntheticDefaultImports(compilerOptions);
|
||||
const isJS = isInJSFile(importingFile);
|
||||
const isJS = hasJSFileExtension(importingFile.fileName);
|
||||
// 1. 'import =' will not work in es2015+ TS files, so the decision is between a default
|
||||
// and a namespace import, based on allowSyntheticDefaultImports/esModuleInterop.
|
||||
if (!isJS && getEmitModuleKind(compilerOptions) >= ModuleKind.ES2015) {
|
||||
@@ -1276,14 +1549,14 @@ function getExportEqualsImportKind(importingFile: SourceFile, compilerOptions: C
|
||||
// 2. 'import =' will not work in JavaScript, so the decision is between a default import,
|
||||
// a namespace import, and const/require.
|
||||
if (isJS) {
|
||||
return isExternalModule(importingFile) || forceImportKeyword
|
||||
return importingFile.externalModuleIndicator || forceImportKeyword
|
||||
? allowSyntheticDefaults ? ImportKind.Default : ImportKind.Namespace
|
||||
: ImportKind.CommonJS;
|
||||
}
|
||||
// 3. At this point the most correct choice is probably 'import =', but people
|
||||
// really hate that, so look to see if the importing file has any precedent
|
||||
// on how to handle it.
|
||||
for (const statement of importingFile.statements) {
|
||||
for (const statement of importingFile.statements ?? emptyArray) {
|
||||
// `import foo` parses as an ImportEqualsDeclaration even though it could be an ImportDeclaration
|
||||
if (isImportEqualsDeclaration(statement) && !nodeIsMissing(statement.moduleReference)) {
|
||||
return ImportKind.CommonJS;
|
||||
@@ -1334,6 +1607,7 @@ function codeActionForFixWorker(
|
||||
importClauseOrBindingPattern,
|
||||
importKind === ImportKind.Default ? { name: symbolName, addAsTypeOnly } : undefined,
|
||||
importKind === ImportKind.Named ? [{ name: symbolName, addAsTypeOnly }] : emptyArray,
|
||||
/*removeExistingImportSpecifiers*/ undefined,
|
||||
preferences,
|
||||
);
|
||||
const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier);
|
||||
@@ -1474,9 +1748,25 @@ function doAddExistingFix(
|
||||
clause: ImportClause | ObjectBindingPattern,
|
||||
defaultImport: Import | undefined,
|
||||
namedImports: readonly Import[],
|
||||
removeExistingImportSpecifiers: Set<ImportSpecifier | BindingElement> | undefined,
|
||||
preferences: UserPreferences,
|
||||
): void {
|
||||
if (clause.kind === SyntaxKind.ObjectBindingPattern) {
|
||||
if (removeExistingImportSpecifiers && clause.elements.some(e => removeExistingImportSpecifiers.has(e))) {
|
||||
// If we're both adding and removing elements, just replace and reprint the whole
|
||||
// node. The change tracker doesn't understand all the operations and can insert or
|
||||
// leave behind stray commas.
|
||||
changes.replaceNode(
|
||||
sourceFile,
|
||||
clause,
|
||||
factory.createObjectBindingPattern([
|
||||
...clause.elements.filter(e => !removeExistingImportSpecifiers.has(e)),
|
||||
...defaultImport ? [factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ "default", defaultImport.name)] : emptyArray,
|
||||
...namedImports.map(i => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i.name)),
|
||||
]),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (defaultImport) {
|
||||
addElementToBindingPattern(clause, defaultImport.name, "default");
|
||||
}
|
||||
@@ -1508,6 +1798,19 @@ function doAddExistingFix(
|
||||
specifierComparer,
|
||||
);
|
||||
|
||||
if (removeExistingImportSpecifiers) {
|
||||
// If we're both adding and removing specifiers, just replace and reprint the whole
|
||||
// node. The change tracker doesn't understand all the operations and can insert or
|
||||
// leave behind stray commas.
|
||||
changes.replaceNode(
|
||||
sourceFile,
|
||||
clause.namedBindings!,
|
||||
factory.updateNamedImports(
|
||||
clause.namedBindings as NamedImports,
|
||||
stableSort([...existingSpecifiers!.filter(s => !removeExistingImportSpecifiers.has(s)), ...newSpecifiers], specifierComparer),
|
||||
),
|
||||
);
|
||||
}
|
||||
// The sorting preference computed earlier may or may not have validated that these particular
|
||||
// import specifiers are sorted. If they aren't, `getImportSpecifierInsertionIndex` will return
|
||||
// nonsense. So if there are existing specifiers, even if we know the sorting preference, we
|
||||
@@ -1515,7 +1818,7 @@ function doAddExistingFix(
|
||||
// to do a sorted insertion.
|
||||
|
||||
// changed to check if existing specifiers are sorted
|
||||
if (existingSpecifiers?.length && isSorted !== false) {
|
||||
else if (existingSpecifiers?.length && isSorted !== false) {
|
||||
// if we're promoting the clause from type-only, we need to transform the existing imports before attempting to insert the new named imports
|
||||
const transformedExistingSpecifiers = (promoteFromTypeOnly && existingSpecifiers) ? factory.updateNamedImports(
|
||||
clause.namedBindings as NamedImports,
|
||||
@@ -1736,3 +2039,11 @@ export function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target
|
||||
// Need `|| "_"` to ensure result isn't empty.
|
||||
return !isStringANonContextualKeyword(res) ? res || "_" : `_${res}`;
|
||||
}
|
||||
|
||||
function getImpliedNodeFormatForEmit(file: SourceFile | FutureSourceFile, program: Program) {
|
||||
return isFullSourceFile(file) ? program.getImpliedNodeFormatForEmit(file) : getImpliedNodeFormatForEmitWorker(file, program.getCompilerOptions());
|
||||
}
|
||||
|
||||
function getEmitModuleFormatOfFile(file: SourceFile | FutureSourceFile, program: Program) {
|
||||
return isFullSourceFile(file) ? program.getEmitModuleFormatOfFile(file) : getEmitModuleFormatOfFileWorker(file, program.getCompilerOptions());
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ import {
|
||||
forEach,
|
||||
formatting,
|
||||
FunctionLikeDeclaration,
|
||||
FutureSymbolExportInfo,
|
||||
getAllSuperTypeNodes,
|
||||
getAncestor,
|
||||
getCombinedLocalAndExportSymbolFlags,
|
||||
@@ -609,7 +610,7 @@ interface ModuleSpecifierResolutionContext {
|
||||
}
|
||||
|
||||
type ModuleSpecifierResolutionResult = "skipped" | "failed" | {
|
||||
exportInfo?: SymbolExportInfo;
|
||||
exportInfo?: SymbolExportInfo | FutureSymbolExportInfo;
|
||||
moduleSpecifier: string;
|
||||
};
|
||||
|
||||
@@ -1157,11 +1158,13 @@ function getJSDocParamAnnotation(
|
||||
? createSnippetPrinter({
|
||||
removeComments: true,
|
||||
module: options.module,
|
||||
moduleResolution: options.moduleResolution,
|
||||
target: options.target,
|
||||
})
|
||||
: createPrinter({
|
||||
removeComments: true,
|
||||
module: options.module,
|
||||
moduleResolution: options.moduleResolution,
|
||||
target: options.target,
|
||||
});
|
||||
setEmitFlags(typeNode, EmitFlags.SingleLine);
|
||||
@@ -1455,6 +1458,7 @@ function getExhaustiveCaseSnippets(
|
||||
const printer = createSnippetPrinter({
|
||||
removeComments: true,
|
||||
module: options.module,
|
||||
moduleResolution: options.moduleResolution,
|
||||
target: options.target,
|
||||
newLine: getNewLineKind(newLineChar),
|
||||
});
|
||||
@@ -1716,7 +1720,7 @@ function createCompletionEntry(
|
||||
if (originIsResolvedExport(origin)) {
|
||||
sourceDisplay = [textPart(origin.moduleSpecifier)];
|
||||
if (importStatementCompletion) {
|
||||
({ insertText, replacementSpan } = getInsertTextAndReplacementSpanForImportCompletion(name, importStatementCompletion, origin, useSemicolons, sourceFile, options, preferences));
|
||||
({ insertText, replacementSpan } = getInsertTextAndReplacementSpanForImportCompletion(name, importStatementCompletion, origin, useSemicolons, sourceFile, program, preferences));
|
||||
isSnippet = preferences.includeCompletionsWithSnippetText ? true : undefined;
|
||||
}
|
||||
}
|
||||
@@ -1942,6 +1946,7 @@ function getEntryForMemberCompletion(
|
||||
const printer = createSnippetPrinter({
|
||||
removeComments: true,
|
||||
module: options.module,
|
||||
moduleResolution: options.moduleResolution,
|
||||
target: options.target,
|
||||
omitTrailingSemicolon: false,
|
||||
newLine: getNewLineKind(getNewLineOrDefaultFromHost(host, formatContext?.options)),
|
||||
@@ -2168,6 +2173,7 @@ function getEntryForObjectLiteralMethodCompletion(
|
||||
const printer = createSnippetPrinter({
|
||||
removeComments: true,
|
||||
module: options.module,
|
||||
moduleResolution: options.moduleResolution,
|
||||
target: options.target,
|
||||
omitTrailingSemicolon: false,
|
||||
newLine: getNewLineKind(getNewLineOrDefaultFromHost(host, formatContext?.options)),
|
||||
@@ -2182,6 +2188,7 @@ function getEntryForObjectLiteralMethodCompletion(
|
||||
const signaturePrinter = createPrinter({
|
||||
removeComments: true,
|
||||
module: options.module,
|
||||
moduleResolution: options.moduleResolution,
|
||||
target: options.target,
|
||||
omitTrailingSemicolon: true,
|
||||
});
|
||||
@@ -2484,14 +2491,14 @@ function completionEntryDataToSymbolOriginInfo(data: CompletionEntryData, comple
|
||||
return unresolvedOrigin;
|
||||
}
|
||||
|
||||
function getInsertTextAndReplacementSpanForImportCompletion(name: string, importStatementCompletion: ImportStatementCompletionInfo, origin: SymbolOriginInfoResolvedExport, useSemicolons: boolean, sourceFile: SourceFile, options: CompilerOptions, preferences: UserPreferences) {
|
||||
function getInsertTextAndReplacementSpanForImportCompletion(name: string, importStatementCompletion: ImportStatementCompletionInfo, origin: SymbolOriginInfoResolvedExport, useSemicolons: boolean, sourceFile: SourceFile, program: Program, preferences: UserPreferences) {
|
||||
const replacementSpan = importStatementCompletion.replacementSpan;
|
||||
const quotedModuleSpecifier = escapeSnippetText(quote(sourceFile, preferences, origin.moduleSpecifier));
|
||||
const exportKind = origin.isDefaultExport ? ExportKind.Default :
|
||||
origin.exportName === InternalSymbolName.ExportEquals ? ExportKind.ExportEquals :
|
||||
ExportKind.Named;
|
||||
const tabStop = preferences.includeCompletionsWithSnippetText ? "$1" : "";
|
||||
const importKind = codefix.getImportKind(sourceFile, exportKind, options, /*forceImportKeyword*/ true);
|
||||
const importKind = codefix.getImportKind(sourceFile, exportKind, program, /*forceImportKeyword*/ true);
|
||||
const isImportSpecifierTypeOnly = importStatementCompletion.couldBeTypeOnlyImportSpecifier;
|
||||
const topLevelTypeOnlyText = importStatementCompletion.isTopLevelTypeOnly ? ` ${tokenToString(SyntaxKind.TypeKeyword)} ` : " ";
|
||||
const importSpecifierTypeOnlyText = isImportSpecifierTypeOnly ? `${tokenToString(SyntaxKind.TypeKeyword)} ` : "";
|
||||
@@ -3941,7 +3948,9 @@ function getCompletionData(
|
||||
// If module transpilation is enabled or we're targeting es6 or above, or not emitting, OK.
|
||||
if (compilerOptionsIndicateEsModules(program.getCompilerOptions())) return true;
|
||||
// If some file is using ES6 modules, assume that it's OK to add more.
|
||||
return programContainsModules(program);
|
||||
return program.getSymlinkCache?.().hasAnySymlinks() ||
|
||||
!!program.getCompilerOptions().paths ||
|
||||
programContainsModules(program);
|
||||
}
|
||||
|
||||
function isSnippetScope(scopeNode: Node): boolean {
|
||||
@@ -4079,20 +4088,20 @@ function getCompletionData(
|
||||
// it should be identical regardless of which one is used. During the subsequent
|
||||
// `CompletionEntryDetails` request, we'll get all the ExportInfos again and pick
|
||||
// the best one based on the module specifier it produces.
|
||||
let exportInfo = info[0], moduleSpecifier;
|
||||
let exportInfo: SymbolExportInfo | FutureSymbolExportInfo = info[0], moduleSpecifier;
|
||||
if (result !== "skipped") {
|
||||
({ exportInfo = info[0], moduleSpecifier } = result);
|
||||
}
|
||||
|
||||
const isDefaultExport = exportInfo.exportKind === ExportKind.Default;
|
||||
const symbol = isDefaultExport && getLocalSymbolForExportDefault(exportInfo.symbol) || exportInfo.symbol;
|
||||
const symbol = isDefaultExport && getLocalSymbolForExportDefault(Debug.checkDefined(exportInfo.symbol)) || Debug.checkDefined(exportInfo.symbol);
|
||||
|
||||
pushAutoImportSymbol(symbol, {
|
||||
kind: moduleSpecifier ? SymbolOriginInfoKind.ResolvedExport : SymbolOriginInfoKind.Export,
|
||||
moduleSpecifier,
|
||||
symbolName,
|
||||
exportMapKey,
|
||||
exportName: exportInfo.exportKind === ExportKind.ExportEquals ? InternalSymbolName.ExportEquals : exportInfo.symbol.name,
|
||||
exportName: exportInfo.exportKind === ExportKind.ExportEquals ? InternalSymbolName.ExportEquals : Debug.checkDefined(exportInfo.symbol).name,
|
||||
fileName: exportInfo.moduleFileName,
|
||||
isDefaultExport,
|
||||
moduleSymbol: exportInfo.moduleSymbol,
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
firstDefined,
|
||||
forEachAncestorDirectory,
|
||||
forEachEntry,
|
||||
FutureSourceFile,
|
||||
getBaseFileName,
|
||||
GetCanonicalFileName,
|
||||
getDirectoryPath,
|
||||
@@ -90,6 +91,12 @@ export interface SymbolExportInfo {
|
||||
isFromPackageJson: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* ExportInfo for an export that does not exist yet, so does not have a symbol.
|
||||
*/
|
||||
export type FutureSymbolExportInfo = Omit<SymbolExportInfo, "symbol"> & { readonly symbol?: undefined; };
|
||||
|
||||
interface CachedSymbolExportInfo {
|
||||
// Used to rehydrate `symbol` and `moduleSymbol` when transient
|
||||
id: number;
|
||||
@@ -477,7 +484,7 @@ function forEachExternalModule(checker: TypeChecker, allSourceFiles: readonly So
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function getExportInfoMap(importingFile: SourceFile, host: LanguageServiceHost, program: Program, preferences: UserPreferences, cancellationToken: CancellationToken | undefined): ExportInfoMap {
|
||||
export function getExportInfoMap(importingFile: SourceFile | FutureSourceFile, host: LanguageServiceHost, program: Program, preferences: UserPreferences, cancellationToken: CancellationToken | undefined): ExportInfoMap {
|
||||
const start = timestamp();
|
||||
// Pulling the AutoImportProvider project will trigger its updateGraph if pending,
|
||||
// which will invalidate the export map cache if things change, so pull it before
|
||||
|
||||
@@ -1376,7 +1376,7 @@ const enum LineAction {
|
||||
export function getRangeOfEnclosingComment(
|
||||
sourceFile: SourceFile,
|
||||
position: number,
|
||||
precedingToken?: Node | null,
|
||||
precedingToken?: Node | null, // eslint-disable-line no-restricted-syntax
|
||||
tokenAtPosition = getTokenAtPosition(sourceFile, position),
|
||||
): CommentRange | undefined {
|
||||
const jsdoc = findAncestor(tokenAtPosition, isJSDoc);
|
||||
@@ -1386,7 +1386,7 @@ export function getRangeOfEnclosingComment(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
precedingToken = precedingToken === null ? undefined : precedingToken === undefined ? findPrecedingToken(position, sourceFile) : precedingToken;
|
||||
|
||||
// Between two consecutive tokens, all comments are either trailing on the former
|
||||
|
||||
@@ -92,7 +92,7 @@ export namespace SmartIndenter {
|
||||
|
||||
const precedingToken = findPrecedingToken(position, sourceFile, /*startNode*/ undefined, /*excludeJsdoc*/ true);
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
const enclosingCommentRange = getRangeOfEnclosingComment(sourceFile, position, precedingToken || null);
|
||||
if (enclosingCommentRange && enclosingCommentRange.kind === SyntaxKind.MultiLineCommentTrivia) {
|
||||
return getCommentIndent(sourceFile, position, options, enclosingCommentRange);
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
createTextSpanFromBounds,
|
||||
createTextSpanFromNode,
|
||||
createTextSpanFromRange,
|
||||
Debug,
|
||||
Declaration,
|
||||
DefinitionInfo,
|
||||
DefinitionInfoAndBoundSpan,
|
||||
@@ -342,7 +341,7 @@ export function getReferenceAtPosition(sourceFile: SourceFile, position: number,
|
||||
|
||||
const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position);
|
||||
if (typeReferenceDirective) {
|
||||
const reference = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName, typeReferenceDirective.resolutionMode || sourceFile.impliedNodeFormat)?.resolvedTypeReferenceDirective;
|
||||
const reference = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName, typeReferenceDirective.resolutionMode || program.getDefaultResolutionModeForFile(sourceFile))?.resolvedTypeReferenceDirective;
|
||||
const file = reference && program.getSourceFile(reference.resolvedFileName!); // TODO:GH#18217
|
||||
return file && { reference: typeReferenceDirective, fileName: file.fileName, file, unverified: false };
|
||||
}
|
||||
@@ -581,16 +580,20 @@ function isExpandoDeclaration(node: Declaration): boolean {
|
||||
|
||||
function getDefinitionFromSymbol(typeChecker: TypeChecker, symbol: Symbol, node: Node, failedAliasResolution?: boolean, excludeDeclaration?: Node): DefinitionInfo[] | undefined {
|
||||
const filteredDeclarations = filter(symbol.declarations, d => d !== excludeDeclaration);
|
||||
const signatureDefinition = getConstructSignatureDefinition() || getCallSignatureDefinition();
|
||||
if (signatureDefinition) {
|
||||
return signatureDefinition;
|
||||
}
|
||||
const withoutExpandos = filter(filteredDeclarations, d => !isExpandoDeclaration(d));
|
||||
const results = some(withoutExpandos) ? withoutExpandos : filteredDeclarations;
|
||||
return getConstructSignatureDefinition() || getCallSignatureDefinition() || map(results, declaration => createDefinitionInfo(declaration, typeChecker, symbol, node, /*unverified*/ false, failedAliasResolution));
|
||||
return map(results, declaration => createDefinitionInfo(declaration, typeChecker, symbol, node, /*unverified*/ false, failedAliasResolution));
|
||||
|
||||
function getConstructSignatureDefinition(): DefinitionInfo[] | undefined {
|
||||
// Applicable only if we are in a new expression, or we are on a constructor declaration
|
||||
// and in either case the symbol has a construct signature definition, i.e. class
|
||||
if (symbol.flags & SymbolFlags.Class && !(symbol.flags & (SymbolFlags.Function | SymbolFlags.Variable)) && (isNewExpressionTarget(node) || node.kind === SyntaxKind.ConstructorKeyword)) {
|
||||
const cls = find(filteredDeclarations, isClassLike) || Debug.fail("Expected declaration to have at least one class-like declaration");
|
||||
return getSignatureDefinition(cls.members, /*selectConstructors*/ true);
|
||||
const cls = find(filteredDeclarations, isClassLike);
|
||||
return cls && getSignatureDefinition(cls.members, /*selectConstructors*/ true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -480,7 +480,7 @@ export function findModuleReferences(program: Program, sourceFiles: readonly Sou
|
||||
}
|
||||
}
|
||||
for (const ref of referencingFile.typeReferenceDirectives) {
|
||||
const referenced = program.getResolvedTypeReferenceDirectives().get(ref.fileName, ref.resolutionMode || referencingFile.impliedNodeFormat)?.resolvedTypeReferenceDirective;
|
||||
const referenced = program.getResolvedTypeReferenceDirectives().get(ref.fileName, ref.resolutionMode || program.getDefaultResolutionModeForFile(referencingFile))?.resolvedTypeReferenceDirective;
|
||||
if (referenced !== undefined && referenced.resolvedFileName === (searchSourceFile as SourceFile).fileName) {
|
||||
refs.push({ kind: "reference", referencingFile, ref });
|
||||
}
|
||||
|
||||
@@ -70,8 +70,8 @@ import {
|
||||
isObjectLiteralExpression,
|
||||
isOptionalTypeNode,
|
||||
isParameter,
|
||||
isParameterDeclaration,
|
||||
isParenthesizedTypeNode,
|
||||
isPartOfParameterDeclaration,
|
||||
isPrefixUnaryExpression,
|
||||
isPropertyAccessExpression,
|
||||
isPropertyDeclaration,
|
||||
@@ -899,7 +899,7 @@ export function provideInlayHints(context: InlayHintsContext): InlayHint[] {
|
||||
}
|
||||
|
||||
function isHintableDeclaration(node: VariableDeclaration | ParameterDeclaration) {
|
||||
if ((isParameterDeclaration(node) || isVariableDeclaration(node) && isVarConst(node)) && node.initializer) {
|
||||
if ((isPartOfParameterDeclaration(node) || isVariableDeclaration(node) && isVarConst(node)) && node.initializer) {
|
||||
const initializer = skipParentheses(node.initializer);
|
||||
return !(isHintableLiteral(initializer) || isNewExpression(initializer) || isObjectLiteralExpression(initializer) || isAssertionExpression(initializer));
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ function isRegionDelimiter(lineText: string) {
|
||||
// multiple potential whitespace matches can make for some gnarly backtracking behavior
|
||||
lineText = lineText.trimStart();
|
||||
if (!startsWith(lineText, "//")) {
|
||||
return null; // eslint-disable-line no-null/no-null
|
||||
return null; // eslint-disable-line no-restricted-syntax
|
||||
}
|
||||
lineText = lineText.slice(2).trim();
|
||||
return regionDelimiterRegExp.exec(lineText);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user