diff --git a/.dprint.jsonc b/.dprint.jsonc
index 945a51ab237e9..a5b46620d6465 100644
--- a/.dprint.jsonc
+++ b/.dprint.jsonc
@@ -1,4 +1,5 @@
{
+ // If updating this, also update the config in dtsBundler.mjs.
"indentWidth": 4,
"lineWidth": 1000,
"newLineKind": "auto",
@@ -56,9 +57,10 @@
"**/_namespaces/**"
],
// Note: if adding new languages, make sure settings.template.json is updated too.
+ // Also, if updating typescript, update the one in package.json.
"plugins": [
- "https://plugins.dprint.dev/typescript-0.90.0.wasm",
- "https://plugins.dprint.dev/json-0.19.2.wasm",
- "https://plugins.dprint.dev/prettier-0.39.0.json@896b70f29ef8213c1b0ba81a93cee9c2d4f39ac2194040313cd433906db7bc7c"
+ "https://plugins.dprint.dev/typescript-0.91.0.wasm",
+ "https://plugins.dprint.dev/json-0.19.3.wasm",
+ "https://plugins.dprint.dev/prettier-0.40.0.json@68c668863ec834d4be0f6f5ccaab415df75336a992aceb7eeeb14fdf096a9e9c"
]
}
diff --git a/.eslintrc.json b/.eslintrc.json
index 668bbad52298f..1c2de33bec6c9 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -144,7 +144,8 @@
"local/no-in-operator": "error",
"local/debug-assert": "error",
"local/no-keywords": "error",
- "local/jsdoc-format": "error"
+ "local/jsdoc-format": "error",
+ "local/js-extensions": "error"
},
"overrides": [
// By default, the ESLint CLI only looks at .js files. But, it will also look at
diff --git a/.github/workflows/accept-baselines-fix-lints.yaml b/.github/workflows/accept-baselines-fix-lints.yaml
index e0e458f2c065a..6b9480874288f 100644
--- a/.github/workflows/accept-baselines-fix-lints.yaml
+++ b/.github/workflows/accept-baselines-fix-lints.yaml
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index edb7a14820c51..b5d1897e216f3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -49,7 +49,7 @@ jobs:
name: Test Node ${{ matrix.node-version }} on ${{ matrix.os }}${{ (!matrix.bundle && ' with --no-bundle') || '' }}
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Use node version ${{ matrix.node-version }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
@@ -73,7 +73,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -87,7 +87,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -108,7 +108,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -125,7 +125,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -139,7 +139,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
@@ -181,11 +181,11 @@ jobs:
if: github.event_name == 'pull_request'
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
path: pr
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
path: base
ref: ${{ github.base_ref }}
@@ -223,7 +223,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -240,7 +240,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -260,7 +260,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index f696653c70f7f..9367758462749 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -42,11 +42,11 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3
+ uses: github/codeql-action/init@ccf74c947955fd1cf117aef6a0e4e66191ef6f61 # v3.25.4
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@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3
+ uses: github/codeql-action/autobuild@ccf74c947955fd1cf117aef6a0e4e66191ef6f61 # v3.25.4
# âšī¸ 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@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3
+ uses: github/codeql-action/analyze@ccf74c947955fd1cf117aef6a0e4e66191ef6f61 # v3.25.4
diff --git a/.github/workflows/create-cherry-pick-pr.yml b/.github/workflows/create-cherry-pick-pr.yml
index 1024070708f4b..73a199291872e 100644
--- a/.github/workflows/create-cherry-pick-pr.yml
+++ b/.github/workflows/create-cherry-pick-pr.yml
@@ -47,7 +47,7 @@ jobs:
if: github.repository == 'microsoft/TypeScript'
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
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.
diff --git a/.github/workflows/insiders.yaml b/.github/workflows/insiders.yaml
index 0b24d11baa0e7..c5ebda6349150 100644
--- a/.github/workflows/insiders.yaml
+++ b/.github/workflows/insiders.yaml
@@ -20,7 +20,7 @@ jobs:
if: github.repository == 'microsoft/TypeScript'
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
@@ -42,7 +42,7 @@ jobs:
if: github.repository == 'microsoft/TypeScript'
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
diff --git a/.github/workflows/lkg.yml b/.github/workflows/lkg.yml
index 72cd27b7c062b..d79d96790556a 100644
--- a/.github/workflows/lkg.yml
+++ b/.github/workflows/lkg.yml
@@ -27,7 +27,7 @@ jobs:
exit 1
fi
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
ref: ${{ inputs.branch_name }}
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
diff --git a/.github/workflows/new-release-branch.yaml b/.github/workflows/new-release-branch.yaml
index 68ef5bcda76b5..5f485067b8343 100644
--- a/.github/workflows/new-release-branch.yaml
+++ b/.github/workflows/new-release-branch.yaml
@@ -50,7 +50,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
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.
diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml
index 8aa7b7a97ae8d..e6cd366e14558 100644
--- a/.github/workflows/nightly.yaml
+++ b/.github/workflows/nightly.yaml
@@ -21,7 +21,7 @@ jobs:
if: github.repository == 'microsoft/TypeScript'
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
@@ -42,7 +42,7 @@ jobs:
if: github.repository == 'microsoft/TypeScript'
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
diff --git a/.github/workflows/release-branch-artifact.yaml b/.github/workflows/release-branch-artifact.yaml
index c097bf46abd78..08a79bfabd9c9 100644
--- a/.github/workflows/release-branch-artifact.yaml
+++ b/.github/workflows/release-branch-artifact.yaml
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
index bad1aa47aaceb..4df7ed4df43d5 100644
--- a/.github/workflows/scorecard.yml
+++ b/.github/workflows/scorecard.yml
@@ -29,12 +29,12 @@ jobs:
steps:
- name: 'Checkout code'
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
persist-credentials: false
- name: 'Run analysis'
- uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
+ uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
with:
results_file: results.sarif
results_format: sarif
@@ -55,6 +55,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: 'Upload to code-scanning'
- uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3
+ uses: github/codeql-action/upload-sarif@ccf74c947955fd1cf117aef6a0e4e66191ef6f61 # v3.25.4
with:
sarif_file: results.sarif
diff --git a/.github/workflows/set-version.yaml b/.github/workflows/set-version.yaml
index 6a7fd02f88834..4837a7775a54f 100644
--- a/.github/workflows/set-version.yaml
+++ b/.github/workflows/set-version.yaml
@@ -49,7 +49,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
ref: ${{ inputs.branch_name }}
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
diff --git a/.github/workflows/sync-branch.yaml b/.github/workflows/sync-branch.yaml
index 753f93b77d8e7..6b343119a105b 100644
--- a/.github/workflows/sync-branch.yaml
+++ b/.github/workflows/sync-branch.yaml
@@ -45,7 +45,7 @@ jobs:
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
ref: ${{ inputs.branch_name }}
filter: blob:none # https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/
diff --git a/.github/workflows/sync-wiki.yml b/.github/workflows/sync-wiki.yml
index efa7cd7d375ea..c5cc842efa914 100644
--- a/.github/workflows/sync-wiki.yml
+++ b/.github/workflows/sync-wiki.yml
@@ -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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
repository: '${{ GITHUB.repository_owner }}/${{ env.BASENAME }}-wiki'
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
diff --git a/.github/workflows/twoslash-repros.yaml b/.github/workflows/twoslash-repros.yaml
index 211c41e502b10..972c431606da9 100644
--- a/.github/workflows/twoslash-repros.yaml
+++ b/.github/workflows/twoslash-repros.yaml
@@ -49,12 +49,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- if: ${{ github.event.inputs.bisect }}
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
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@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
diff --git a/.github/workflows/update-package-lock.yaml b/.github/workflows/update-package-lock.yaml
index dc016ee2652b5..a6897956604fb 100644
--- a/.github/workflows/update-package-lock.yaml
+++ b/.github/workflows/update-package-lock.yaml
@@ -22,7 +22,7 @@ jobs:
if: github.repository == 'microsoft/TypeScript'
steps:
- - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
+ - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
with:
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
diff --git a/.vscode/settings.template.json b/.vscode/settings.template.json
index e918fd9577867..82315167674d9 100644
--- a/.vscode/settings.template.json
+++ b/.vscode/settings.template.json
@@ -18,6 +18,9 @@
".git-blame-ignore-revs"
],
+ "javascript.preferences.importModuleSpecifierEnding": "js",
+ "typescript.preferences.importModuleSpecifierEnding": "js",
+
// Match dprint in organize/auto-imports.
"typescript.unstable": {
"organizeImportsCollation": "unicode",
diff --git a/package-lock.json b/package-lock.json
index 90a05842f36e2..75d6c9fad24d6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,9 +13,11 @@
"tsserver": "bin/tsserver"
},
"devDependencies": {
+ "@dprint/formatter": "^0.3.0",
+ "@dprint/typescript": "0.91.0",
"@esfx/canceltoken": "^1.0.0",
- "@octokit/rest": "^20.0.2",
- "@types/chai": "^4.3.14",
+ "@octokit/rest": "^20.1.1",
+ "@types/chai": "^4.3.16",
"@types/microsoft__typescript-etw": "^0.1.3",
"@types/minimist": "^1.2.5",
"@types/mocha": "^10.0.6",
@@ -23,48 +25,39 @@
"@types/node": "latest",
"@types/source-map-support": "^0.5.10",
"@types/which": "^3.0.3",
- "@typescript-eslint/eslint-plugin": "^7.3.1",
- "@typescript-eslint/parser": "^7.3.1",
- "@typescript-eslint/utils": "^7.3.1",
- "azure-devops-node-api": "^12.5.0",
+ "@typescript-eslint/eslint-plugin": "^7.11.0",
+ "@typescript-eslint/parser": "^7.11.0",
+ "@typescript-eslint/utils": "^7.11.0",
+ "azure-devops-node-api": "^13.0.0",
"c8": "^9.1.0",
"chai": "^4.4.1",
"chalk": "^4.1.2",
"chokidar": "^3.6.0",
"diff": "^5.2.0",
- "dprint": "^0.45.0",
- "esbuild": "^0.20.2",
+ "dprint": "^0.46.1",
+ "esbuild": "^0.21.4",
"eslint": "^8.57.0",
"eslint-formatter-autolinkable-stylish": "^1.3.0",
- "eslint-plugin-local": "^4.2.1",
- "fast-xml-parser": "^4.3.6",
- "glob": "^10.3.10",
+ "eslint-plugin-local": "^4.2.2",
+ "fast-xml-parser": "^4.4.0",
+ "glob": "^10.4.1",
"hereby": "^1.8.9",
"jsonc-parser": "^3.2.1",
"minimist": "^1.2.8",
- "mocha": "^10.3.0",
+ "mocha": "^10.4.0",
"mocha-fivemat-progress-reporter": "^0.1.0",
"ms": "^2.1.3",
"node-fetch": "^3.3.2",
- "playwright": "^1.42.1",
+ "playwright": "^1.44.1",
"source-map-support": "^0.5.21",
"tslib": "^2.6.2",
- "typescript": "^5.4.3",
+ "typescript": "^5.4.5",
"which": "^3.0.1"
},
"engines": {
"node": ">=14.17"
}
},
- "node_modules/@aashutoshrathi/word-wrap": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
- "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/@bcoe/v8-coverage": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
@@ -72,9 +65,9 @@
"dev": true
},
"node_modules/@dprint/darwin-arm64": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.45.1.tgz",
- "integrity": "sha512-pH0/uKLJ5SJPoHhOwLWFMhCmL0BY3FzWQbull8OGMK/FRkIPgOl2adZSovtUZpUMGWyDOzIWH1fW9X2DuMhnEg==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.1.tgz",
+ "integrity": "sha512-dycE/uE++NGKYhKwSOrm1EculcD48GM12A1BF0f3Q2OW1ZNUqvlui/99lrohjPulJaIYX/QZQJ4hzTnaa6EDUA==",
"cpu": [
"arm64"
],
@@ -85,9 +78,9 @@
]
},
"node_modules/@dprint/darwin-x64": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.45.1.tgz",
- "integrity": "sha512-YUj421LmBLDlxpIER3pORKfQmpmXD50n5mClHjpZrnl17WTiHtQ+jHvDJdJoxH2eS66W0mQyxLoGo5SfFfiM7A==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.1.tgz",
+ "integrity": "sha512-q4Q8TQj51OU+SXhHCzP6jxUtwyCR6Vsmla7yyJVZKryA5l2WUqsSPimkq7Tt4K6ciDficTNxi5aaN/DMXBND2w==",
"cpu": [
"x64"
],
@@ -97,10 +90,16 @@
"darwin"
]
},
+ "node_modules/@dprint/formatter": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@dprint/formatter/-/formatter-0.3.0.tgz",
+ "integrity": "sha512-N9fxCxbaBOrDkteSOzaCqwWjso5iAe+WJPsHC021JfHNj2ThInPNEF13ORDKta3llq5D1TlclODCvOvipH7bWQ==",
+ "dev": true
+ },
"node_modules/@dprint/linux-arm64-glibc": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.45.1.tgz",
- "integrity": "sha512-lJ7s/pOQWRJ0mstjZQnVyX2/3QRXZ9cpFHJDZ7e81Y8QSn/iqxTrnK0DPgxUrDG8hYKQmWQdQLU4sP5DKBz0Jg==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.1.tgz",
+ "integrity": "sha512-kT6UHU8nN516nfk42IpxvQ9yRHg+lVcWyaGU6Pk/Wn0t/9UDqS2SWXfNNYFvq3A+IVsOAEY6ZvD40D1uXey0Pg==",
"cpu": [
"arm64"
],
@@ -111,9 +110,9 @@
]
},
"node_modules/@dprint/linux-arm64-musl": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.45.1.tgz",
- "integrity": "sha512-un2awe1L1sAJLsCPSEUrE0/cgupdzbYFoyBOutyU1zHR9KQn47AtIDw+chvuinU4xleHDuEGyXGuJ6NE+Ky6vw==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.1.tgz",
+ "integrity": "sha512-Qo71XzmL7GWEKPKKTFDf27WUO8mO+eXEvKY4gRiFuV2lOPw0VCfadc4iqlTCPj8Wp9qIKK7z/NgQXkVjPMbx5Q==",
"cpu": [
"arm64"
],
@@ -124,9 +123,9 @@
]
},
"node_modules/@dprint/linux-x64-glibc": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.45.1.tgz",
- "integrity": "sha512-5Civht90S/g8zlyYB7n4oH78p+sLbNqeFCFuImJRK7uRxZwCRya7lji6RwlB6DQ7qngVqovTHj9RLOYfZzfVlg==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.1.tgz",
+ "integrity": "sha512-ZDgJaCTY8Cb9F2FUlBgpN++stVamGKvy7MfdkKvvahAdkCQvba7kJg91aLGHNhDilDTo1IPgLcXLEP4xPhXMyA==",
"cpu": [
"x64"
],
@@ -137,9 +136,9 @@
]
},
"node_modules/@dprint/linux-x64-musl": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.45.1.tgz",
- "integrity": "sha512-p2/gjnHDd8GRCvtey5HZO4o/He6pSmY/zpcCuIXprFW9P0vNlEj3DFhz4FPpOKXM+csrsVWWs2E0T/xr5QZtVg==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.1.tgz",
+ "integrity": "sha512-6I+ubsGL89k9Vezo6AwWoLDHMoyGdBiHvVvfopF3GwDW1y4jRFXqSeVt3IGoeNa2PXZBEzhGzgiNl1YFFjao/A==",
"cpu": [
"x64"
],
@@ -149,10 +148,16 @@
"linux"
]
},
+ "node_modules/@dprint/typescript": {
+ "version": "0.91.0",
+ "resolved": "https://registry.npmjs.org/@dprint/typescript/-/typescript-0.91.0.tgz",
+ "integrity": "sha512-NUKkNbuSnaEHONhiKhyn+V+wMzuLFXMZB7ACtyqKcdTJCXajmzkb6oSeaTAgTeNgRlua1zKgUOzKVAc/cp5Qwg==",
+ "dev": true
+ },
"node_modules/@dprint/win32-x64": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.45.1.tgz",
- "integrity": "sha512-2l78XM7KsW46P2Yv6uPB3fE+y92EsBlrCxi+RVQ0pbznPFdMdkLyGgaCuh683zdld14jHlaADpIQ7YchGAEMAg==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.1.tgz",
+ "integrity": "sha512-ugdhmL3Lo9n6Si/7eBtj1Rgo3Hbmf+9G0JxsWvuZBRA7Y+Xa9vtxbU4XqpUfG8rict5wR3b0i2X0iexVUgMYxA==",
"cpu": [
"x64"
],
@@ -163,9 +168,9 @@
]
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
- "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.4.tgz",
+ "integrity": "sha512-Zrm+B33R4LWPLjDEVnEqt2+SLTATlru1q/xYKVn8oVTbiRBGmK2VIMoIYGJDGyftnGaC788IuzGFAlb7IQ0Y8A==",
"cpu": [
"ppc64"
],
@@ -179,9 +184,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
- "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.4.tgz",
+ "integrity": "sha512-E7H/yTd8kGQfY4z9t3nRPk/hrhaCajfA3YSQSBrst8B+3uTcgsi8N+ZWYCaeIDsiVs6m65JPCaQN/DxBRclF3A==",
"cpu": [
"arm"
],
@@ -195,9 +200,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
- "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.4.tgz",
+ "integrity": "sha512-fYFnz+ObClJ3dNiITySBUx+oNalYUT18/AryMxfovLkYWbutXsct3Wz2ZWAcGGppp+RVVX5FiXeLYGi97umisA==",
"cpu": [
"arm64"
],
@@ -211,9 +216,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
- "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.4.tgz",
+ "integrity": "sha512-mDqmlge3hFbEPbCWxp4fM6hqq7aZfLEHZAKGP9viq9wMUBVQx202aDIfc3l+d2cKhUJM741VrCXEzRFhPDKH3Q==",
"cpu": [
"x64"
],
@@ -227,9 +232,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
- "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.4.tgz",
+ "integrity": "sha512-72eaIrDZDSiWqpmCzVaBD58c8ea8cw/U0fq/PPOTqE3c53D0xVMRt2ooIABZ6/wj99Y+h4ksT/+I+srCDLU9TA==",
"cpu": [
"arm64"
],
@@ -243,9 +248,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
- "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.4.tgz",
+ "integrity": "sha512-uBsuwRMehGmw1JC7Vecu/upOjTsMhgahmDkWhGLWxIgUn2x/Y4tIwUZngsmVb6XyPSTXJYS4YiASKPcm9Zitag==",
"cpu": [
"x64"
],
@@ -259,9 +264,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
- "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.4.tgz",
+ "integrity": "sha512-8JfuSC6YMSAEIZIWNL3GtdUT5NhUA/CMUCpZdDRolUXNAXEE/Vbpe6qlGLpfThtY5NwXq8Hi4nJy4YfPh+TwAg==",
"cpu": [
"arm64"
],
@@ -275,9 +280,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
- "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.4.tgz",
+ "integrity": "sha512-8d9y9eQhxv4ef7JmXny7591P/PYsDFc4+STaxC1GBv0tMyCdyWfXu2jBuqRsyhY8uL2HU8uPyscgE2KxCY9imQ==",
"cpu": [
"x64"
],
@@ -291,9 +296,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
- "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.4.tgz",
+ "integrity": "sha512-2rqFFefpYmpMs+FWjkzSgXg5vViocqpq5a1PSRgT0AvSgxoXmGF17qfGAzKedg6wAwyM7UltrKVo9kxaJLMF/g==",
"cpu": [
"arm"
],
@@ -307,9 +312,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
- "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.4.tgz",
+ "integrity": "sha512-/GLD2orjNU50v9PcxNpYZi+y8dJ7e7/LhQukN3S4jNDXCKkyyiyAz9zDw3siZ7Eh1tRcnCHAo/WcqKMzmi4eMQ==",
"cpu": [
"arm64"
],
@@ -323,9 +328,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
- "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.4.tgz",
+ "integrity": "sha512-pNftBl7m/tFG3t2m/tSjuYeWIffzwAZT9m08+9DPLizxVOsUl8DdFzn9HvJrTQwe3wvJnwTdl92AonY36w/25g==",
"cpu": [
"ia32"
],
@@ -339,9 +344,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
- "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.4.tgz",
+ "integrity": "sha512-cSD2gzCK5LuVX+hszzXQzlWya6c7hilO71L9h4KHwqI4qeqZ57bAtkgcC2YioXjsbfAv4lPn3qe3b00Zt+jIfQ==",
"cpu": [
"loong64"
],
@@ -355,9 +360,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
- "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.4.tgz",
+ "integrity": "sha512-qtzAd3BJh7UdbiXCrg6npWLYU0YpufsV9XlufKhMhYMJGJCdfX/G6+PNd0+v877X1JG5VmjBLUiFB0o8EUSicA==",
"cpu": [
"mips64el"
],
@@ -371,9 +376,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
- "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.4.tgz",
+ "integrity": "sha512-yB8AYzOTaL0D5+2a4xEy7OVvbcypvDR05MsB/VVPVA7nL4hc5w5Dyd/ddnayStDgJE59fAgNEOdLhBxjfx5+dg==",
"cpu": [
"ppc64"
],
@@ -387,9 +392,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
- "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.4.tgz",
+ "integrity": "sha512-Y5AgOuVzPjQdgU59ramLoqSSiXddu7F3F+LI5hYy/d1UHN7K5oLzYBDZe23QmQJ9PIVUXwOdKJ/jZahPdxzm9w==",
"cpu": [
"riscv64"
],
@@ -403,9 +408,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
- "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.4.tgz",
+ "integrity": "sha512-Iqc/l/FFwtt8FoTK9riYv9zQNms7B8u+vAI/rxKuN10HgQIXaPzKZc479lZ0x6+vKVQbu55GdpYpeNWzjOhgbA==",
"cpu": [
"s390x"
],
@@ -419,9 +424,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
- "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.4.tgz",
+ "integrity": "sha512-Td9jv782UMAFsuLZINfUpoF5mZIbAj+jv1YVtE58rFtfvoKRiKSkRGQfHTgKamLVT/fO7203bHa3wU122V/Bdg==",
"cpu": [
"x64"
],
@@ -435,9 +440,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
- "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.4.tgz",
+ "integrity": "sha512-Awn38oSXxsPMQxaV0Ipb7W/gxZtk5Tx3+W+rAPdZkyEhQ6968r9NvtkjhnhbEgWXYbgV+JEONJ6PcdBS+nlcpA==",
"cpu": [
"x64"
],
@@ -451,9 +456,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
- "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.4.tgz",
+ "integrity": "sha512-IsUmQeCY0aU374R82fxIPu6vkOybWIMc3hVGZ3ChRwL9hA1TwY+tS0lgFWV5+F1+1ssuvvXt3HFqe8roCip8Hg==",
"cpu": [
"x64"
],
@@ -467,9 +472,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
- "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.4.tgz",
+ "integrity": "sha512-hsKhgZ4teLUaDA6FG/QIu2q0rI6I36tZVfM4DBZv3BG0mkMIdEnMbhc4xwLvLJSS22uWmaVkFkqWgIS0gPIm+A==",
"cpu": [
"x64"
],
@@ -483,9 +488,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
- "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.4.tgz",
+ "integrity": "sha512-UUfMgMoXPoA/bvGUNfUBFLCh0gt9dxZYIx9W4rfJr7+hKe5jxxHmfOK8YSH4qsHLLN4Ck8JZ+v7Q5fIm1huErg==",
"cpu": [
"arm64"
],
@@ -499,9 +504,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
- "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.4.tgz",
+ "integrity": "sha512-yIxbspZb5kGCAHWm8dexALQ9en1IYDfErzjSEq1KzXFniHv019VT3mNtTK7t8qdy4TwT6QYHI9sEZabONHg+aw==",
"cpu": [
"ia32"
],
@@ -515,9 +520,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
- "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.4.tgz",
+ "integrity": "sha512-sywLRD3UK/qRJt0oBwdpYLBibk7KiRfbswmWRDabuncQYSlf8aLEEUor/oP6KRz8KEG+HoiVLBhPRD5JWjS8Sg==",
"cpu": [
"x64"
],
@@ -857,18 +862,18 @@
}
},
"node_modules/@octokit/openapi-types": {
- "version": "22.1.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.1.0.tgz",
- "integrity": "sha512-pGUdSP+eEPfZiQHNkZI0U01HLipxncisdJQB4G//OAmfeO8sqTQ9KRa0KF03TUPCziNsoXUrTg4B2Q1EX++T0Q==",
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
+ "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==",
"dev": true
},
"node_modules/@octokit/plugin-paginate-rest": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz",
- "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==",
+ "version": "11.3.1",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.1.tgz",
+ "integrity": "sha512-ryqobs26cLtM1kQxqeZui4v8FeznirUsksiA+RYemMPJ7Micju0WSkv50dBksTuZks9O5cg4wp+t8fZ/cLY56g==",
"dev": true,
"dependencies": {
- "@octokit/types": "^12.6.0"
+ "@octokit/types": "^13.5.0"
},
"engines": {
"node": ">= 18"
@@ -877,21 +882,6 @@
"@octokit/core": "5"
}
},
- "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": {
- "version": "20.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
- "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
- "dev": true
- },
- "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": {
- "version": "12.6.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
- "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
- "dev": true,
- "dependencies": {
- "@octokit/openapi-types": "^20.0.0"
- }
- },
"node_modules/@octokit/plugin-request-log": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.1.tgz",
@@ -905,33 +895,18 @@
}
},
"node_modules/@octokit/plugin-rest-endpoint-methods": {
- "version": "10.4.1",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
- "integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
+ "version": "13.2.2",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.2.2.tgz",
+ "integrity": "sha512-EI7kXWidkt3Xlok5uN43suK99VWqc8OaIMktY9d9+RNKl69juoTyxmLoWPIZgJYzi41qj/9zU7G/ljnNOJ5AFA==",
"dev": true,
"dependencies": {
- "@octokit/types": "^12.6.0"
+ "@octokit/types": "^13.5.0"
},
"engines": {
"node": ">= 18"
},
"peerDependencies": {
- "@octokit/core": "5"
- }
- },
- "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": {
- "version": "20.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
- "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
- "dev": true
- },
- "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
- "version": "12.6.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
- "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
- "dev": true,
- "dependencies": {
- "@octokit/openapi-types": "^20.0.0"
+ "@octokit/core": "^5"
}
},
"node_modules/@octokit/request": {
@@ -964,27 +939,27 @@
}
},
"node_modules/@octokit/rest": {
- "version": "20.1.0",
- "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.0.tgz",
- "integrity": "sha512-STVO3itHQLrp80lvcYB2UIKoeil5Ctsgd2s1AM+du3HqZIR35ZH7WE9HLwUOLXH0myA0y3AGNPo8gZtcgIbw0g==",
+ "version": "20.1.1",
+ "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.1.tgz",
+ "integrity": "sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw==",
"dev": true,
"dependencies": {
"@octokit/core": "^5.0.2",
- "@octokit/plugin-paginate-rest": "^9.1.5",
+ "@octokit/plugin-paginate-rest": "11.3.1",
"@octokit/plugin-request-log": "^4.0.0",
- "@octokit/plugin-rest-endpoint-methods": "^10.2.0"
+ "@octokit/plugin-rest-endpoint-methods": "13.2.2"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/@octokit/types": {
- "version": "13.4.1",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.4.1.tgz",
- "integrity": "sha512-Y73oOAzRBAUzR/iRAbGULzpNkX8vaxKCqEtg6K74Ff3w9f5apFnWtE/2nade7dMWWW3bS5Kkd6DJS4HF04xreg==",
+ "version": "13.5.0",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz",
+ "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==",
"dev": true,
"dependencies": {
- "@octokit/openapi-types": "^22.1.0"
+ "@octokit/openapi-types": "^22.2.0"
}
},
"node_modules/@pkgjs/parseargs": {
@@ -1010,9 +985,9 @@
}
},
"node_modules/@types/chai": {
- "version": "4.3.14",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz",
- "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==",
+ "version": "4.3.16",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz",
+ "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==",
"dev": true
},
"node_modules/@types/istanbul-lib-coverage": {
@@ -1021,12 +996,6 @@
"integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
"dev": true
},
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true
- },
"node_modules/@types/microsoft__typescript-etw": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@types/microsoft__typescript-etw/-/microsoft__typescript-etw-0.1.3.tgz",
@@ -1052,20 +1021,14 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "20.12.7",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
- "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
+ "version": "20.12.13",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.13.tgz",
+ "integrity": "sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA==",
"dev": true,
"dependencies": {
"undici-types": "~5.26.4"
}
},
- "node_modules/@types/semver": {
- "version": "7.5.8",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
- "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
- "dev": true
- },
"node_modules/@types/source-map-support": {
"version": "0.5.10",
"resolved": "https://registry.npmjs.org/@types/source-map-support/-/source-map-support-0.5.10.tgz",
@@ -1082,21 +1045,19 @@
"dev": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "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==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz",
+ "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==",
"dev": true,
"dependencies": {
"@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",
+ "@typescript-eslint/scope-manager": "7.11.0",
+ "@typescript-eslint/type-utils": "7.11.0",
+ "@typescript-eslint/utils": "7.11.0",
+ "@typescript-eslint/visitor-keys": "7.11.0",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
- "semver": "^7.6.0",
"ts-api-utils": "^1.3.0"
},
"engines": {
@@ -1117,15 +1078,15 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz",
- "integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz",
+ "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==",
"dev": true,
"dependencies": {
- "@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",
+ "@typescript-eslint/scope-manager": "7.11.0",
+ "@typescript-eslint/types": "7.11.0",
+ "@typescript-eslint/typescript-estree": "7.11.0",
+ "@typescript-eslint/visitor-keys": "7.11.0",
"debug": "^4.3.4"
},
"engines": {
@@ -1145,13 +1106,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "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==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz",
+ "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.7.0",
- "@typescript-eslint/visitor-keys": "7.7.0"
+ "@typescript-eslint/types": "7.11.0",
+ "@typescript-eslint/visitor-keys": "7.11.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -1162,13 +1123,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz",
- "integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz",
+ "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "7.7.0",
- "@typescript-eslint/utils": "7.7.0",
+ "@typescript-eslint/typescript-estree": "7.11.0",
+ "@typescript-eslint/utils": "7.11.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.3.0"
},
@@ -1189,9 +1150,9 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz",
- "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz",
+ "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==",
"dev": true,
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -1202,13 +1163,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz",
- "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz",
+ "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.7.0",
- "@typescript-eslint/visitor-keys": "7.7.0",
+ "@typescript-eslint/types": "7.11.0",
+ "@typescript-eslint/visitor-keys": "7.11.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -1230,18 +1191,15 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz",
- "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz",
+ "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@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/scope-manager": "7.11.0",
+ "@typescript-eslint/types": "7.11.0",
+ "@typescript-eslint/typescript-estree": "7.11.0"
},
"engines": {
"node": "^18.18.0 || >=20.0.0"
@@ -1255,12 +1213,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz",
- "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz",
+ "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.7.0",
+ "@typescript-eslint/types": "7.11.0",
"eslint-visitor-keys": "^3.4.3"
},
"engines": {
@@ -1394,9 +1352,9 @@
}
},
"node_modules/azure-devops-node-api": {
- "version": "12.5.0",
- "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz",
- "integrity": "sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==",
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-13.0.0.tgz",
+ "integrity": "sha512-T/i3pt2Dxb2//1+TJT05Ff5heUmQEWKwa8sdguIhdRYT3Zge9FYw98zpfFvCD7CZsz6AN74SKGgqF3ISVN2TGg==",
"dev": true,
"dependencies": {
"tunnel": "0.0.6",
@@ -1437,12 +1395,12 @@
}
},
"node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"dependencies": {
- "fill-range": "^7.0.1"
+ "fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
@@ -1919,22 +1877,22 @@
}
},
"node_modules/dprint": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.45.1.tgz",
- "integrity": "sha512-OYefcDgxd6jSdig/Cfkw1vdvyiOIRruCPnqGBbXpc95buDt9kvwL+Lic1OHc+SaQSsQub0BUZMd5+TNgy8Sh3A==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.1.tgz",
+ "integrity": "sha512-OdILoUitGxbykCYcTijUOtY7bD4kNoSSzm4kHd5sYNh6f64P8Zfcr+e/Dh4oEn89wHIl10TTrrUs7ny5MELKkQ==",
"dev": true,
"hasInstallScript": true,
"bin": {
"dprint": "bin.js"
},
"optionalDependencies": {
- "@dprint/darwin-arm64": "0.45.1",
- "@dprint/darwin-x64": "0.45.1",
- "@dprint/linux-arm64-glibc": "0.45.1",
- "@dprint/linux-arm64-musl": "0.45.1",
- "@dprint/linux-x64-glibc": "0.45.1",
- "@dprint/linux-x64-musl": "0.45.1",
- "@dprint/win32-x64": "0.45.1"
+ "@dprint/darwin-arm64": "0.46.1",
+ "@dprint/darwin-x64": "0.46.1",
+ "@dprint/linux-arm64-glibc": "0.46.1",
+ "@dprint/linux-arm64-musl": "0.46.1",
+ "@dprint/linux-x64-glibc": "0.46.1",
+ "@dprint/linux-x64-musl": "0.46.1",
+ "@dprint/win32-x64": "0.46.1"
}
},
"node_modules/eastasianwidth": {
@@ -1971,9 +1929,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
- "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.4.tgz",
+ "integrity": "sha512-sFMcNNrj+Q0ZDolrp5pDhH0nRPN9hLIM3fRPwgbLYJeSHHgnXSnbV3xYgSVuOeLWH9c73VwmEverVzupIv5xuA==",
"dev": true,
"hasInstallScript": true,
"bin": {
@@ -1983,29 +1941,29 @@
"node": ">=12"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.20.2",
- "@esbuild/android-arm": "0.20.2",
- "@esbuild/android-arm64": "0.20.2",
- "@esbuild/android-x64": "0.20.2",
- "@esbuild/darwin-arm64": "0.20.2",
- "@esbuild/darwin-x64": "0.20.2",
- "@esbuild/freebsd-arm64": "0.20.2",
- "@esbuild/freebsd-x64": "0.20.2",
- "@esbuild/linux-arm": "0.20.2",
- "@esbuild/linux-arm64": "0.20.2",
- "@esbuild/linux-ia32": "0.20.2",
- "@esbuild/linux-loong64": "0.20.2",
- "@esbuild/linux-mips64el": "0.20.2",
- "@esbuild/linux-ppc64": "0.20.2",
- "@esbuild/linux-riscv64": "0.20.2",
- "@esbuild/linux-s390x": "0.20.2",
- "@esbuild/linux-x64": "0.20.2",
- "@esbuild/netbsd-x64": "0.20.2",
- "@esbuild/openbsd-x64": "0.20.2",
- "@esbuild/sunos-x64": "0.20.2",
- "@esbuild/win32-arm64": "0.20.2",
- "@esbuild/win32-ia32": "0.20.2",
- "@esbuild/win32-x64": "0.20.2"
+ "@esbuild/aix-ppc64": "0.21.4",
+ "@esbuild/android-arm": "0.21.4",
+ "@esbuild/android-arm64": "0.21.4",
+ "@esbuild/android-x64": "0.21.4",
+ "@esbuild/darwin-arm64": "0.21.4",
+ "@esbuild/darwin-x64": "0.21.4",
+ "@esbuild/freebsd-arm64": "0.21.4",
+ "@esbuild/freebsd-x64": "0.21.4",
+ "@esbuild/linux-arm": "0.21.4",
+ "@esbuild/linux-arm64": "0.21.4",
+ "@esbuild/linux-ia32": "0.21.4",
+ "@esbuild/linux-loong64": "0.21.4",
+ "@esbuild/linux-mips64el": "0.21.4",
+ "@esbuild/linux-ppc64": "0.21.4",
+ "@esbuild/linux-riscv64": "0.21.4",
+ "@esbuild/linux-s390x": "0.21.4",
+ "@esbuild/linux-x64": "0.21.4",
+ "@esbuild/netbsd-x64": "0.21.4",
+ "@esbuild/openbsd-x64": "0.21.4",
+ "@esbuild/sunos-x64": "0.21.4",
+ "@esbuild/win32-arm64": "0.21.4",
+ "@esbuild/win32-ia32": "0.21.4",
+ "@esbuild/win32-x64": "0.21.4"
}
},
"node_modules/escalade": {
@@ -2101,9 +2059,9 @@
}
},
"node_modules/eslint-plugin-local": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-local/-/eslint-plugin-local-4.2.1.tgz",
- "integrity": "sha512-ucwGuCldrHVF7ei/El3H+TVH7BjTB78EmyCdQgqMk3cVdoapXshfxpsuIDHsFQwxashycB+/I8Z50xO9pQOo4A==",
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-local/-/eslint-plugin-local-4.2.2.tgz",
+ "integrity": "sha512-9yNacxuEAVw2nYGCAj+ofx74cWODq7N7jcajlq1tzz6xuJS0WFhp72s/WSvIyJG6b/75+n63SKxUFVrt1UHmfQ==",
"dev": true,
"dependencies": {
"@thisismanta/pessimist": "^1.2.0",
@@ -2272,9 +2230,9 @@
"dev": true
},
"node_modules/fast-xml-parser": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz",
- "integrity": "sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz",
+ "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==",
"dev": true,
"funding": [
{
@@ -2347,9 +2305,9 @@
}
},
"node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"dependencies": {
"to-regex-range": "^5.0.1"
@@ -2498,22 +2456,22 @@
}
},
"node_modules/glob": {
- "version": "10.3.12",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz",
- "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==",
+ "version": "10.4.1",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz",
+ "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==",
"dev": true,
"dependencies": {
"foreground-child": "^3.1.0",
- "jackspeak": "^2.3.6",
- "minimatch": "^9.0.1",
- "minipass": "^7.0.4",
- "path-scurry": "^1.10.2"
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"engines": {
- "node": ">=16 || 14 >=14.17"
+ "node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -2724,6 +2682,7 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
"dev": true,
"dependencies": {
"once": "^1.3.0",
@@ -2869,9 +2828,9 @@
}
},
"node_modules/jackspeak": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
- "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz",
+ "integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==",
"dev": true,
"dependencies": {
"@isaacs/cliui": "^8.0.2"
@@ -2997,9 +2956,9 @@
}
},
"node_modules/lru-cache": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
- "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
+ "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
"dev": true,
"engines": {
"node": "14 || >=16.14"
@@ -3030,12 +2989,12 @@
}
},
"node_modules/micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
+ "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
"dev": true,
"dependencies": {
- "braces": "^3.0.2",
+ "braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
@@ -3067,9 +3026,9 @@
}
},
"node_modules/minipass": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
- "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true,
"engines": {
"node": ">=16 || 14 >=14.17"
@@ -3173,6 +3132,7 @@
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
@@ -3350,17 +3310,17 @@
}
},
"node_modules/optionator": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
- "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
"dependencies": {
- "@aashutoshrathi/word-wrap": "^1.2.3",
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
- "type-check": "^0.4.0"
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
},
"engines": {
"node": ">= 0.8.0"
@@ -3448,16 +3408,16 @@
}
},
"node_modules/path-scurry": {
- "version": "1.10.2",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
- "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
"dependencies": {
"lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
- "node": ">=16 || 14 >=14.17"
+ "node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -3482,9 +3442,9 @@
}
},
"node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+ "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
"dev": true
},
"node_modules/picomatch": {
@@ -3500,12 +3460,12 @@
}
},
"node_modules/playwright": {
- "version": "1.43.1",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.1.tgz",
- "integrity": "sha512-V7SoH0ai2kNt1Md9E3Gwas5B9m8KR2GVvwZnAI6Pg0m3sh7UvgiYhRrhsziCmqMJNouPckiOhk8T+9bSAK0VIA==",
+ "version": "1.44.1",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz",
+ "integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==",
"dev": true,
"dependencies": {
- "playwright-core": "1.43.1"
+ "playwright-core": "1.44.1"
},
"bin": {
"playwright": "cli.js"
@@ -3518,9 +3478,9 @@
}
},
"node_modules/playwright-core": {
- "version": "1.43.1",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.1.tgz",
- "integrity": "sha512-EI36Mto2Vrx6VF7rm708qSnesVQKbxEWvPrfA1IPY6HgczBplDx7ENtx+K2n4kJ41sLLkuGfmb0ZLSSXlDhqPg==",
+ "version": "1.44.1",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz",
+ "integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==",
"dev": true,
"bin": {
"playwright-core": "cli.js"
@@ -3688,6 +3648,7 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
"dev": true,
"dependencies": {
"glob": "^7.1.3"
@@ -3713,6 +3674,7 @@
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
@@ -3785,13 +3747,10 @@
]
},
"node_modules/semver": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
- "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
"dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
"bin": {
"semver": "bin/semver.js"
},
@@ -3799,18 +3758,6 @@
"node": ">=10"
}
},
- "node_modules/semver/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/serialize-javascript": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
@@ -4079,6 +4026,7 @@
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
"dev": true,
"dependencies": {
"fs.realpath": "^1.0.0",
@@ -4283,6 +4231,15 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/wordwrapjs": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz",
@@ -4411,12 +4368,6 @@
"node": ">=10"
}
},
- "node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"node_modules/yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
@@ -4493,12 +4444,6 @@
}
},
"dependencies": {
- "@aashutoshrathi/word-wrap": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
- "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
- "dev": true
- },
"@bcoe/v8-coverage": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
@@ -4506,212 +4451,224 @@
"dev": true
},
"@dprint/darwin-arm64": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.45.1.tgz",
- "integrity": "sha512-pH0/uKLJ5SJPoHhOwLWFMhCmL0BY3FzWQbull8OGMK/FRkIPgOl2adZSovtUZpUMGWyDOzIWH1fW9X2DuMhnEg==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/darwin-arm64/-/darwin-arm64-0.46.1.tgz",
+ "integrity": "sha512-dycE/uE++NGKYhKwSOrm1EculcD48GM12A1BF0f3Q2OW1ZNUqvlui/99lrohjPulJaIYX/QZQJ4hzTnaa6EDUA==",
"dev": true,
"optional": true
},
"@dprint/darwin-x64": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.45.1.tgz",
- "integrity": "sha512-YUj421LmBLDlxpIER3pORKfQmpmXD50n5mClHjpZrnl17WTiHtQ+jHvDJdJoxH2eS66W0mQyxLoGo5SfFfiM7A==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/darwin-x64/-/darwin-x64-0.46.1.tgz",
+ "integrity": "sha512-q4Q8TQj51OU+SXhHCzP6jxUtwyCR6Vsmla7yyJVZKryA5l2WUqsSPimkq7Tt4K6ciDficTNxi5aaN/DMXBND2w==",
"dev": true,
"optional": true
},
+ "@dprint/formatter": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@dprint/formatter/-/formatter-0.3.0.tgz",
+ "integrity": "sha512-N9fxCxbaBOrDkteSOzaCqwWjso5iAe+WJPsHC021JfHNj2ThInPNEF13ORDKta3llq5D1TlclODCvOvipH7bWQ==",
+ "dev": true
+ },
"@dprint/linux-arm64-glibc": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.45.1.tgz",
- "integrity": "sha512-lJ7s/pOQWRJ0mstjZQnVyX2/3QRXZ9cpFHJDZ7e81Y8QSn/iqxTrnK0DPgxUrDG8hYKQmWQdQLU4sP5DKBz0Jg==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-glibc/-/linux-arm64-glibc-0.46.1.tgz",
+ "integrity": "sha512-kT6UHU8nN516nfk42IpxvQ9yRHg+lVcWyaGU6Pk/Wn0t/9UDqS2SWXfNNYFvq3A+IVsOAEY6ZvD40D1uXey0Pg==",
"dev": true,
"optional": true
},
"@dprint/linux-arm64-musl": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.45.1.tgz",
- "integrity": "sha512-un2awe1L1sAJLsCPSEUrE0/cgupdzbYFoyBOutyU1zHR9KQn47AtIDw+chvuinU4xleHDuEGyXGuJ6NE+Ky6vw==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/linux-arm64-musl/-/linux-arm64-musl-0.46.1.tgz",
+ "integrity": "sha512-Qo71XzmL7GWEKPKKTFDf27WUO8mO+eXEvKY4gRiFuV2lOPw0VCfadc4iqlTCPj8Wp9qIKK7z/NgQXkVjPMbx5Q==",
"dev": true,
"optional": true
},
"@dprint/linux-x64-glibc": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.45.1.tgz",
- "integrity": "sha512-5Civht90S/g8zlyYB7n4oH78p+sLbNqeFCFuImJRK7uRxZwCRya7lji6RwlB6DQ7qngVqovTHj9RLOYfZzfVlg==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/linux-x64-glibc/-/linux-x64-glibc-0.46.1.tgz",
+ "integrity": "sha512-ZDgJaCTY8Cb9F2FUlBgpN++stVamGKvy7MfdkKvvahAdkCQvba7kJg91aLGHNhDilDTo1IPgLcXLEP4xPhXMyA==",
"dev": true,
"optional": true
},
"@dprint/linux-x64-musl": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.45.1.tgz",
- "integrity": "sha512-p2/gjnHDd8GRCvtey5HZO4o/He6pSmY/zpcCuIXprFW9P0vNlEj3DFhz4FPpOKXM+csrsVWWs2E0T/xr5QZtVg==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/linux-x64-musl/-/linux-x64-musl-0.46.1.tgz",
+ "integrity": "sha512-6I+ubsGL89k9Vezo6AwWoLDHMoyGdBiHvVvfopF3GwDW1y4jRFXqSeVt3IGoeNa2PXZBEzhGzgiNl1YFFjao/A==",
"dev": true,
"optional": true
},
+ "@dprint/typescript": {
+ "version": "0.91.0",
+ "resolved": "https://registry.npmjs.org/@dprint/typescript/-/typescript-0.91.0.tgz",
+ "integrity": "sha512-NUKkNbuSnaEHONhiKhyn+V+wMzuLFXMZB7ACtyqKcdTJCXajmzkb6oSeaTAgTeNgRlua1zKgUOzKVAc/cp5Qwg==",
+ "dev": true
+ },
"@dprint/win32-x64": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.45.1.tgz",
- "integrity": "sha512-2l78XM7KsW46P2Yv6uPB3fE+y92EsBlrCxi+RVQ0pbznPFdMdkLyGgaCuh683zdld14jHlaADpIQ7YchGAEMAg==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/@dprint/win32-x64/-/win32-x64-0.46.1.tgz",
+ "integrity": "sha512-ugdhmL3Lo9n6Si/7eBtj1Rgo3Hbmf+9G0JxsWvuZBRA7Y+Xa9vtxbU4XqpUfG8rict5wR3b0i2X0iexVUgMYxA==",
"dev": true,
"optional": true
},
"@esbuild/aix-ppc64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
- "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.4.tgz",
+ "integrity": "sha512-Zrm+B33R4LWPLjDEVnEqt2+SLTATlru1q/xYKVn8oVTbiRBGmK2VIMoIYGJDGyftnGaC788IuzGFAlb7IQ0Y8A==",
"dev": true,
"optional": true
},
"@esbuild/android-arm": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
- "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.4.tgz",
+ "integrity": "sha512-E7H/yTd8kGQfY4z9t3nRPk/hrhaCajfA3YSQSBrst8B+3uTcgsi8N+ZWYCaeIDsiVs6m65JPCaQN/DxBRclF3A==",
"dev": true,
"optional": true
},
"@esbuild/android-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
- "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.4.tgz",
+ "integrity": "sha512-fYFnz+ObClJ3dNiITySBUx+oNalYUT18/AryMxfovLkYWbutXsct3Wz2ZWAcGGppp+RVVX5FiXeLYGi97umisA==",
"dev": true,
"optional": true
},
"@esbuild/android-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
- "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.4.tgz",
+ "integrity": "sha512-mDqmlge3hFbEPbCWxp4fM6hqq7aZfLEHZAKGP9viq9wMUBVQx202aDIfc3l+d2cKhUJM741VrCXEzRFhPDKH3Q==",
"dev": true,
"optional": true
},
"@esbuild/darwin-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
- "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.4.tgz",
+ "integrity": "sha512-72eaIrDZDSiWqpmCzVaBD58c8ea8cw/U0fq/PPOTqE3c53D0xVMRt2ooIABZ6/wj99Y+h4ksT/+I+srCDLU9TA==",
"dev": true,
"optional": true
},
"@esbuild/darwin-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
- "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.4.tgz",
+ "integrity": "sha512-uBsuwRMehGmw1JC7Vecu/upOjTsMhgahmDkWhGLWxIgUn2x/Y4tIwUZngsmVb6XyPSTXJYS4YiASKPcm9Zitag==",
"dev": true,
"optional": true
},
"@esbuild/freebsd-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
- "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.4.tgz",
+ "integrity": "sha512-8JfuSC6YMSAEIZIWNL3GtdUT5NhUA/CMUCpZdDRolUXNAXEE/Vbpe6qlGLpfThtY5NwXq8Hi4nJy4YfPh+TwAg==",
"dev": true,
"optional": true
},
"@esbuild/freebsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
- "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.4.tgz",
+ "integrity": "sha512-8d9y9eQhxv4ef7JmXny7591P/PYsDFc4+STaxC1GBv0tMyCdyWfXu2jBuqRsyhY8uL2HU8uPyscgE2KxCY9imQ==",
"dev": true,
"optional": true
},
"@esbuild/linux-arm": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
- "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.4.tgz",
+ "integrity": "sha512-2rqFFefpYmpMs+FWjkzSgXg5vViocqpq5a1PSRgT0AvSgxoXmGF17qfGAzKedg6wAwyM7UltrKVo9kxaJLMF/g==",
"dev": true,
"optional": true
},
"@esbuild/linux-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
- "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.4.tgz",
+ "integrity": "sha512-/GLD2orjNU50v9PcxNpYZi+y8dJ7e7/LhQukN3S4jNDXCKkyyiyAz9zDw3siZ7Eh1tRcnCHAo/WcqKMzmi4eMQ==",
"dev": true,
"optional": true
},
"@esbuild/linux-ia32": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
- "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.4.tgz",
+ "integrity": "sha512-pNftBl7m/tFG3t2m/tSjuYeWIffzwAZT9m08+9DPLizxVOsUl8DdFzn9HvJrTQwe3wvJnwTdl92AonY36w/25g==",
"dev": true,
"optional": true
},
"@esbuild/linux-loong64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
- "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.4.tgz",
+ "integrity": "sha512-cSD2gzCK5LuVX+hszzXQzlWya6c7hilO71L9h4KHwqI4qeqZ57bAtkgcC2YioXjsbfAv4lPn3qe3b00Zt+jIfQ==",
"dev": true,
"optional": true
},
"@esbuild/linux-mips64el": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
- "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.4.tgz",
+ "integrity": "sha512-qtzAd3BJh7UdbiXCrg6npWLYU0YpufsV9XlufKhMhYMJGJCdfX/G6+PNd0+v877X1JG5VmjBLUiFB0o8EUSicA==",
"dev": true,
"optional": true
},
"@esbuild/linux-ppc64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
- "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.4.tgz",
+ "integrity": "sha512-yB8AYzOTaL0D5+2a4xEy7OVvbcypvDR05MsB/VVPVA7nL4hc5w5Dyd/ddnayStDgJE59fAgNEOdLhBxjfx5+dg==",
"dev": true,
"optional": true
},
"@esbuild/linux-riscv64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
- "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.4.tgz",
+ "integrity": "sha512-Y5AgOuVzPjQdgU59ramLoqSSiXddu7F3F+LI5hYy/d1UHN7K5oLzYBDZe23QmQJ9PIVUXwOdKJ/jZahPdxzm9w==",
"dev": true,
"optional": true
},
"@esbuild/linux-s390x": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
- "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.4.tgz",
+ "integrity": "sha512-Iqc/l/FFwtt8FoTK9riYv9zQNms7B8u+vAI/rxKuN10HgQIXaPzKZc479lZ0x6+vKVQbu55GdpYpeNWzjOhgbA==",
"dev": true,
"optional": true
},
"@esbuild/linux-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
- "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.4.tgz",
+ "integrity": "sha512-Td9jv782UMAFsuLZINfUpoF5mZIbAj+jv1YVtE58rFtfvoKRiKSkRGQfHTgKamLVT/fO7203bHa3wU122V/Bdg==",
"dev": true,
"optional": true
},
"@esbuild/netbsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
- "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.4.tgz",
+ "integrity": "sha512-Awn38oSXxsPMQxaV0Ipb7W/gxZtk5Tx3+W+rAPdZkyEhQ6968r9NvtkjhnhbEgWXYbgV+JEONJ6PcdBS+nlcpA==",
"dev": true,
"optional": true
},
"@esbuild/openbsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
- "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.4.tgz",
+ "integrity": "sha512-IsUmQeCY0aU374R82fxIPu6vkOybWIMc3hVGZ3ChRwL9hA1TwY+tS0lgFWV5+F1+1ssuvvXt3HFqe8roCip8Hg==",
"dev": true,
"optional": true
},
"@esbuild/sunos-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
- "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.4.tgz",
+ "integrity": "sha512-hsKhgZ4teLUaDA6FG/QIu2q0rI6I36tZVfM4DBZv3BG0mkMIdEnMbhc4xwLvLJSS22uWmaVkFkqWgIS0gPIm+A==",
"dev": true,
"optional": true
},
"@esbuild/win32-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
- "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.4.tgz",
+ "integrity": "sha512-UUfMgMoXPoA/bvGUNfUBFLCh0gt9dxZYIx9W4rfJr7+hKe5jxxHmfOK8YSH4qsHLLN4Ck8JZ+v7Q5fIm1huErg==",
"dev": true,
"optional": true
},
"@esbuild/win32-ia32": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
- "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.4.tgz",
+ "integrity": "sha512-yIxbspZb5kGCAHWm8dexALQ9en1IYDfErzjSEq1KzXFniHv019VT3mNtTK7t8qdy4TwT6QYHI9sEZabONHg+aw==",
"dev": true,
"optional": true
},
"@esbuild/win32-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
- "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.4.tgz",
+ "integrity": "sha512-sywLRD3UK/qRJt0oBwdpYLBibk7KiRfbswmWRDabuncQYSlf8aLEEUor/oP6KRz8KEG+HoiVLBhPRD5JWjS8Sg==",
"dev": true,
"optional": true
},
@@ -4972,35 +4929,18 @@
}
},
"@octokit/openapi-types": {
- "version": "22.1.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.1.0.tgz",
- "integrity": "sha512-pGUdSP+eEPfZiQHNkZI0U01HLipxncisdJQB4G//OAmfeO8sqTQ9KRa0KF03TUPCziNsoXUrTg4B2Q1EX++T0Q==",
+ "version": "22.2.0",
+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-22.2.0.tgz",
+ "integrity": "sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==",
"dev": true
},
"@octokit/plugin-paginate-rest": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz",
- "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==",
+ "version": "11.3.1",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-11.3.1.tgz",
+ "integrity": "sha512-ryqobs26cLtM1kQxqeZui4v8FeznirUsksiA+RYemMPJ7Micju0WSkv50dBksTuZks9O5cg4wp+t8fZ/cLY56g==",
"dev": true,
"requires": {
- "@octokit/types": "^12.6.0"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "20.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
- "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
- "dev": true
- },
- "@octokit/types": {
- "version": "12.6.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
- "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
- "dev": true,
- "requires": {
- "@octokit/openapi-types": "^20.0.0"
- }
- }
+ "@octokit/types": "^13.5.0"
}
},
"@octokit/plugin-request-log": {
@@ -5011,29 +4951,12 @@
"requires": {}
},
"@octokit/plugin-rest-endpoint-methods": {
- "version": "10.4.1",
- "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz",
- "integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==",
+ "version": "13.2.2",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-13.2.2.tgz",
+ "integrity": "sha512-EI7kXWidkt3Xlok5uN43suK99VWqc8OaIMktY9d9+RNKl69juoTyxmLoWPIZgJYzi41qj/9zU7G/ljnNOJ5AFA==",
"dev": true,
"requires": {
- "@octokit/types": "^12.6.0"
- },
- "dependencies": {
- "@octokit/openapi-types": {
- "version": "20.0.0",
- "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz",
- "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==",
- "dev": true
- },
- "@octokit/types": {
- "version": "12.6.0",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz",
- "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==",
- "dev": true,
- "requires": {
- "@octokit/openapi-types": "^20.0.0"
- }
- }
+ "@octokit/types": "^13.5.0"
}
},
"@octokit/request": {
@@ -5060,24 +4983,24 @@
}
},
"@octokit/rest": {
- "version": "20.1.0",
- "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.0.tgz",
- "integrity": "sha512-STVO3itHQLrp80lvcYB2UIKoeil5Ctsgd2s1AM+du3HqZIR35ZH7WE9HLwUOLXH0myA0y3AGNPo8gZtcgIbw0g==",
+ "version": "20.1.1",
+ "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.1.1.tgz",
+ "integrity": "sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw==",
"dev": true,
"requires": {
"@octokit/core": "^5.0.2",
- "@octokit/plugin-paginate-rest": "^9.1.5",
+ "@octokit/plugin-paginate-rest": "11.3.1",
"@octokit/plugin-request-log": "^4.0.0",
- "@octokit/plugin-rest-endpoint-methods": "^10.2.0"
+ "@octokit/plugin-rest-endpoint-methods": "13.2.2"
}
},
"@octokit/types": {
- "version": "13.4.1",
- "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.4.1.tgz",
- "integrity": "sha512-Y73oOAzRBAUzR/iRAbGULzpNkX8vaxKCqEtg6K74Ff3w9f5apFnWtE/2nade7dMWWW3bS5Kkd6DJS4HF04xreg==",
+ "version": "13.5.0",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-13.5.0.tgz",
+ "integrity": "sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==",
"dev": true,
"requires": {
- "@octokit/openapi-types": "^22.1.0"
+ "@octokit/openapi-types": "^22.2.0"
}
},
"@pkgjs/parseargs": {
@@ -5097,9 +5020,9 @@
}
},
"@types/chai": {
- "version": "4.3.14",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz",
- "integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w==",
+ "version": "4.3.16",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.16.tgz",
+ "integrity": "sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==",
"dev": true
},
"@types/istanbul-lib-coverage": {
@@ -5108,12 +5031,6 @@
"integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
"dev": true
},
- "@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true
- },
"@types/microsoft__typescript-etw": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@types/microsoft__typescript-etw/-/microsoft__typescript-etw-0.1.3.tgz",
@@ -5139,20 +5056,14 @@
"dev": true
},
"@types/node": {
- "version": "20.12.7",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
- "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
+ "version": "20.12.13",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.13.tgz",
+ "integrity": "sha512-gBGeanV41c1L171rR7wjbMiEpEI/l5XFQdLLfhr/REwpgDy/4U8y89+i8kRiLzDyZdOkXh+cRaTetUnCYutoXA==",
"dev": true,
"requires": {
"undici-types": "~5.26.4"
}
},
- "@types/semver": {
- "version": "7.5.8",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
- "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
- "dev": true
- },
"@types/source-map-support": {
"version": "0.5.10",
"resolved": "https://registry.npmjs.org/@types/source-map-support/-/source-map-support-0.5.10.tgz",
@@ -5169,73 +5080,71 @@
"dev": true
},
"@typescript-eslint/eslint-plugin": {
- "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==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz",
+ "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==",
"dev": true,
"requires": {
"@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",
+ "@typescript-eslint/scope-manager": "7.11.0",
+ "@typescript-eslint/type-utils": "7.11.0",
+ "@typescript-eslint/utils": "7.11.0",
+ "@typescript-eslint/visitor-keys": "7.11.0",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
- "semver": "^7.6.0",
"ts-api-utils": "^1.3.0"
}
},
"@typescript-eslint/parser": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.0.tgz",
- "integrity": "sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz",
+ "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==",
"dev": true,
"requires": {
- "@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",
+ "@typescript-eslint/scope-manager": "7.11.0",
+ "@typescript-eslint/types": "7.11.0",
+ "@typescript-eslint/typescript-estree": "7.11.0",
+ "@typescript-eslint/visitor-keys": "7.11.0",
"debug": "^4.3.4"
}
},
"@typescript-eslint/scope-manager": {
- "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==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz",
+ "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "7.7.0",
- "@typescript-eslint/visitor-keys": "7.7.0"
+ "@typescript-eslint/types": "7.11.0",
+ "@typescript-eslint/visitor-keys": "7.11.0"
}
},
"@typescript-eslint/type-utils": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.0.tgz",
- "integrity": "sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz",
+ "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==",
"dev": true,
"requires": {
- "@typescript-eslint/typescript-estree": "7.7.0",
- "@typescript-eslint/utils": "7.7.0",
+ "@typescript-eslint/typescript-estree": "7.11.0",
+ "@typescript-eslint/utils": "7.11.0",
"debug": "^4.3.4",
"ts-api-utils": "^1.3.0"
}
},
"@typescript-eslint/types": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.0.tgz",
- "integrity": "sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz",
+ "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.0.tgz",
- "integrity": "sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz",
+ "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "7.7.0",
- "@typescript-eslint/visitor-keys": "7.7.0",
+ "@typescript-eslint/types": "7.11.0",
+ "@typescript-eslint/visitor-keys": "7.11.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -5245,27 +5154,24 @@
}
},
"@typescript-eslint/utils": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.0.tgz",
- "integrity": "sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz",
+ "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@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/scope-manager": "7.11.0",
+ "@typescript-eslint/types": "7.11.0",
+ "@typescript-eslint/typescript-estree": "7.11.0"
}
},
"@typescript-eslint/visitor-keys": {
- "version": "7.7.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.0.tgz",
- "integrity": "sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==",
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz",
+ "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "7.7.0",
+ "@typescript-eslint/types": "7.11.0",
"eslint-visitor-keys": "^3.4.3"
}
},
@@ -5356,9 +5262,9 @@
"dev": true
},
"azure-devops-node-api": {
- "version": "12.5.0",
- "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-12.5.0.tgz",
- "integrity": "sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og==",
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-13.0.0.tgz",
+ "integrity": "sha512-T/i3pt2Dxb2//1+TJT05Ff5heUmQEWKwa8sdguIhdRYT3Zge9FYw98zpfFvCD7CZsz6AN74SKGgqF3ISVN2TGg==",
"dev": true,
"requires": {
"tunnel": "0.0.6",
@@ -5393,12 +5299,12 @@
}
},
"braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"requires": {
- "fill-range": "^7.0.1"
+ "fill-range": "^7.1.1"
}
},
"browser-stdout": {
@@ -5759,18 +5665,18 @@
}
},
"dprint": {
- "version": "0.45.1",
- "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.45.1.tgz",
- "integrity": "sha512-OYefcDgxd6jSdig/Cfkw1vdvyiOIRruCPnqGBbXpc95buDt9kvwL+Lic1OHc+SaQSsQub0BUZMd5+TNgy8Sh3A==",
+ "version": "0.46.1",
+ "resolved": "https://registry.npmjs.org/dprint/-/dprint-0.46.1.tgz",
+ "integrity": "sha512-OdILoUitGxbykCYcTijUOtY7bD4kNoSSzm4kHd5sYNh6f64P8Zfcr+e/Dh4oEn89wHIl10TTrrUs7ny5MELKkQ==",
"dev": true,
"requires": {
- "@dprint/darwin-arm64": "0.45.1",
- "@dprint/darwin-x64": "0.45.1",
- "@dprint/linux-arm64-glibc": "0.45.1",
- "@dprint/linux-arm64-musl": "0.45.1",
- "@dprint/linux-x64-glibc": "0.45.1",
- "@dprint/linux-x64-musl": "0.45.1",
- "@dprint/win32-x64": "0.45.1"
+ "@dprint/darwin-arm64": "0.46.1",
+ "@dprint/darwin-x64": "0.46.1",
+ "@dprint/linux-arm64-glibc": "0.46.1",
+ "@dprint/linux-arm64-musl": "0.46.1",
+ "@dprint/linux-x64-glibc": "0.46.1",
+ "@dprint/linux-x64-musl": "0.46.1",
+ "@dprint/win32-x64": "0.46.1"
}
},
"eastasianwidth": {
@@ -5801,34 +5707,34 @@
"dev": true
},
"esbuild": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
- "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
- "dev": true,
- "requires": {
- "@esbuild/aix-ppc64": "0.20.2",
- "@esbuild/android-arm": "0.20.2",
- "@esbuild/android-arm64": "0.20.2",
- "@esbuild/android-x64": "0.20.2",
- "@esbuild/darwin-arm64": "0.20.2",
- "@esbuild/darwin-x64": "0.20.2",
- "@esbuild/freebsd-arm64": "0.20.2",
- "@esbuild/freebsd-x64": "0.20.2",
- "@esbuild/linux-arm": "0.20.2",
- "@esbuild/linux-arm64": "0.20.2",
- "@esbuild/linux-ia32": "0.20.2",
- "@esbuild/linux-loong64": "0.20.2",
- "@esbuild/linux-mips64el": "0.20.2",
- "@esbuild/linux-ppc64": "0.20.2",
- "@esbuild/linux-riscv64": "0.20.2",
- "@esbuild/linux-s390x": "0.20.2",
- "@esbuild/linux-x64": "0.20.2",
- "@esbuild/netbsd-x64": "0.20.2",
- "@esbuild/openbsd-x64": "0.20.2",
- "@esbuild/sunos-x64": "0.20.2",
- "@esbuild/win32-arm64": "0.20.2",
- "@esbuild/win32-ia32": "0.20.2",
- "@esbuild/win32-x64": "0.20.2"
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.4.tgz",
+ "integrity": "sha512-sFMcNNrj+Q0ZDolrp5pDhH0nRPN9hLIM3fRPwgbLYJeSHHgnXSnbV3xYgSVuOeLWH9c73VwmEverVzupIv5xuA==",
+ "dev": true,
+ "requires": {
+ "@esbuild/aix-ppc64": "0.21.4",
+ "@esbuild/android-arm": "0.21.4",
+ "@esbuild/android-arm64": "0.21.4",
+ "@esbuild/android-x64": "0.21.4",
+ "@esbuild/darwin-arm64": "0.21.4",
+ "@esbuild/darwin-x64": "0.21.4",
+ "@esbuild/freebsd-arm64": "0.21.4",
+ "@esbuild/freebsd-x64": "0.21.4",
+ "@esbuild/linux-arm": "0.21.4",
+ "@esbuild/linux-arm64": "0.21.4",
+ "@esbuild/linux-ia32": "0.21.4",
+ "@esbuild/linux-loong64": "0.21.4",
+ "@esbuild/linux-mips64el": "0.21.4",
+ "@esbuild/linux-ppc64": "0.21.4",
+ "@esbuild/linux-riscv64": "0.21.4",
+ "@esbuild/linux-s390x": "0.21.4",
+ "@esbuild/linux-x64": "0.21.4",
+ "@esbuild/netbsd-x64": "0.21.4",
+ "@esbuild/openbsd-x64": "0.21.4",
+ "@esbuild/sunos-x64": "0.21.4",
+ "@esbuild/win32-arm64": "0.21.4",
+ "@esbuild/win32-ia32": "0.21.4",
+ "@esbuild/win32-x64": "0.21.4"
}
},
"escalade": {
@@ -5930,9 +5836,9 @@
}
},
"eslint-plugin-local": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-local/-/eslint-plugin-local-4.2.1.tgz",
- "integrity": "sha512-ucwGuCldrHVF7ei/El3H+TVH7BjTB78EmyCdQgqMk3cVdoapXshfxpsuIDHsFQwxashycB+/I8Z50xO9pQOo4A==",
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-local/-/eslint-plugin-local-4.2.2.tgz",
+ "integrity": "sha512-9yNacxuEAVw2nYGCAj+ofx74cWODq7N7jcajlq1tzz6xuJS0WFhp72s/WSvIyJG6b/75+n63SKxUFVrt1UHmfQ==",
"dev": true,
"requires": {
"@thisismanta/pessimist": "^1.2.0",
@@ -6028,9 +5934,9 @@
"dev": true
},
"fast-xml-parser": {
- "version": "4.3.6",
- "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.6.tgz",
- "integrity": "sha512-M2SovcRxD4+vC493Uc2GZVcZaj66CCJhWurC4viynVSTvrpErCShNcDz1lAho6n9REQKvL/ll4A4/fw6Y9z8nw==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.0.tgz",
+ "integrity": "sha512-kLY3jFlwIYwBNDojclKsNAC12sfD6NwW74QB2CoNGPvtVxjliYehVunB3HYyNi+n4Tt1dAcgwYvmKF/Z18flqg==",
"dev": true,
"requires": {
"strnum": "^1.0.5"
@@ -6071,9 +5977,9 @@
}
},
"fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
@@ -6176,16 +6082,16 @@
}
},
"glob": {
- "version": "10.3.12",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz",
- "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==",
+ "version": "10.4.1",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.1.tgz",
+ "integrity": "sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==",
"dev": true,
"requires": {
"foreground-child": "^3.1.0",
- "jackspeak": "^2.3.6",
- "minimatch": "^9.0.1",
- "minipass": "^7.0.4",
- "path-scurry": "^1.10.2"
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "path-scurry": "^1.11.1"
}
},
"glob-parent": {
@@ -6435,9 +6341,9 @@
}
},
"jackspeak": {
- "version": "2.3.6",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
- "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.1.2.tgz",
+ "integrity": "sha512-kWmLKn2tRtfYMF/BakihVVRzBKOxz4gJMiL2Rj91WnAB5TPZumSH99R/Yf1qE1u4uRimvCSJfm6hnxohXeEXjQ==",
"dev": true,
"requires": {
"@isaacs/cliui": "^8.0.2",
@@ -6537,9 +6443,9 @@
}
},
"lru-cache": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
- "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
+ "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
"dev": true
},
"make-dir": {
@@ -6558,12 +6464,12 @@
"dev": true
},
"micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
+ "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
"dev": true,
"requires": {
- "braces": "^3.0.2",
+ "braces": "^3.0.3",
"picomatch": "^2.3.1"
}
},
@@ -6583,9 +6489,9 @@
"dev": true
},
"minipass": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
- "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true
},
"mocha": {
@@ -6788,17 +6694,17 @@
}
},
"optionator": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
- "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
"dev": true,
"requires": {
- "@aashutoshrathi/word-wrap": "^1.2.3",
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
- "type-check": "^0.4.0"
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
}
},
"p-limit": {
@@ -6853,9 +6759,9 @@
"dev": true
},
"path-scurry": {
- "version": "1.10.2",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
- "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
"requires": {
"lru-cache": "^10.2.0",
@@ -6875,9 +6781,9 @@
"dev": true
},
"picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+ "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
"dev": true
},
"picomatch": {
@@ -6887,13 +6793,13 @@
"dev": true
},
"playwright": {
- "version": "1.43.1",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.43.1.tgz",
- "integrity": "sha512-V7SoH0ai2kNt1Md9E3Gwas5B9m8KR2GVvwZnAI6Pg0m3sh7UvgiYhRrhsziCmqMJNouPckiOhk8T+9bSAK0VIA==",
+ "version": "1.44.1",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz",
+ "integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==",
"dev": true,
"requires": {
"fsevents": "2.3.2",
- "playwright-core": "1.43.1"
+ "playwright-core": "1.44.1"
},
"dependencies": {
"fsevents": {
@@ -6906,9 +6812,9 @@
}
},
"playwright-core": {
- "version": "1.43.1",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.43.1.tgz",
- "integrity": "sha512-EI36Mto2Vrx6VF7rm708qSnesVQKbxEWvPrfA1IPY6HgczBplDx7ENtx+K2n4kJ41sLLkuGfmb0ZLSSXlDhqPg==",
+ "version": "1.44.1",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz",
+ "integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==",
"dev": true
},
"plur": {
@@ -7058,24 +6964,10 @@
"dev": true
},
"semver": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
- "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
- "dev": true,
- "requires": {
- "lru-cache": "^6.0.0"
- },
- "dependencies": {
- "lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "requires": {
- "yallist": "^4.0.0"
- }
- }
- }
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+ "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "dev": true
},
"serialize-javascript": {
"version": "6.0.0",
@@ -7430,6 +7322,12 @@
"isexe": "^2.0.0"
}
},
+ "word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true
+ },
"wordwrapjs": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.1.tgz",
@@ -7522,12 +7420,6 @@
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true
},
- "yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
- },
"yargs": {
"version": "17.7.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
diff --git a/package.json b/package.json
index 1e143ca3f23ce..0db39bd81b327 100644
--- a/package.json
+++ b/package.json
@@ -39,9 +39,11 @@
"!**/.gitattributes"
],
"devDependencies": {
+ "@dprint/formatter": "^0.3.0",
+ "@dprint/typescript": "0.91.0",
"@esfx/canceltoken": "^1.0.0",
- "@octokit/rest": "^20.0.2",
- "@types/chai": "^4.3.14",
+ "@octokit/rest": "^20.1.1",
+ "@types/chai": "^4.3.16",
"@types/microsoft__typescript-etw": "^0.1.3",
"@types/minimist": "^1.2.5",
"@types/mocha": "^10.0.6",
@@ -49,33 +51,33 @@
"@types/node": "latest",
"@types/source-map-support": "^0.5.10",
"@types/which": "^3.0.3",
- "@typescript-eslint/eslint-plugin": "^7.3.1",
- "@typescript-eslint/parser": "^7.3.1",
- "@typescript-eslint/utils": "^7.3.1",
- "azure-devops-node-api": "^12.5.0",
+ "@typescript-eslint/eslint-plugin": "^7.11.0",
+ "@typescript-eslint/parser": "^7.11.0",
+ "@typescript-eslint/utils": "^7.11.0",
+ "azure-devops-node-api": "^13.0.0",
"c8": "^9.1.0",
"chai": "^4.4.1",
"chalk": "^4.1.2",
"chokidar": "^3.6.0",
"diff": "^5.2.0",
- "dprint": "^0.45.0",
- "esbuild": "^0.20.2",
+ "dprint": "^0.46.1",
+ "esbuild": "^0.21.4",
"eslint": "^8.57.0",
"eslint-formatter-autolinkable-stylish": "^1.3.0",
- "eslint-plugin-local": "^4.2.1",
- "fast-xml-parser": "^4.3.6",
- "glob": "^10.3.10",
+ "eslint-plugin-local": "^4.2.2",
+ "fast-xml-parser": "^4.4.0",
+ "glob": "^10.4.1",
"hereby": "^1.8.9",
"jsonc-parser": "^3.2.1",
"minimist": "^1.2.8",
- "mocha": "^10.3.0",
+ "mocha": "^10.4.0",
"mocha-fivemat-progress-reporter": "^0.1.0",
"ms": "^2.1.3",
"node-fetch": "^3.3.2",
- "playwright": "^1.42.1",
+ "playwright": "^1.44.1",
"source-map-support": "^0.5.21",
"tslib": "^2.6.2",
- "typescript": "^5.4.3",
+ "typescript": "^5.4.5",
"which": "^3.0.1"
},
"overrides": {
diff --git a/scripts/dtsBundler.mjs b/scripts/dtsBundler.mjs
index e7ace12303e1d..7323c77c1c1ca 100644
--- a/scripts/dtsBundler.mjs
+++ b/scripts/dtsBundler.mjs
@@ -5,8 +5,9 @@
* bundle as namespaces again, even though the project is modules.
*/
+import * as dprintFormatter from "@dprint/formatter";
+import * as dprintTypeScript from "@dprint/typescript";
import assert, { fail } from "assert";
-import cp from "child_process";
import fs from "fs";
import minimist from "minimist";
import path from "path";
@@ -475,23 +476,23 @@ if (publicContents.includes("@internal")) {
console.error("Output includes untrimmed @internal nodes!");
}
-const dprintPath = path.resolve(__dirname, "..", "node_modules", "dprint", "bin.js");
+const buffer = fs.readFileSync(dprintTypeScript.getPath());
+const formatter = dprintFormatter.createFromBuffer(buffer);
+formatter.setConfig({
+ indentWidth: 4,
+ lineWidth: 1000,
+ newLineKind: "auto",
+ useTabs: false,
+}, {
+ quoteStyle: "preferDouble",
+});
/**
* @param {string} contents
* @returns {string}
*/
function dprint(contents) {
- const result = cp.execFileSync(
- process.execPath,
- [dprintPath, "fmt", "--stdin", "ts"],
- {
- stdio: ["pipe", "pipe", "inherit"],
- encoding: "utf-8",
- input: contents,
- maxBuffer: 100 * 1024 * 1024, // 100 MB "ought to be enough for anyone"; https://github.com/nodejs/node/issues/9829
- },
- );
+ const result = formatter.formatText("dummy.d.ts", contents);
return result.replace(/\r\n/g, "\n");
}
diff --git a/scripts/eslint/rules/js-extensions.cjs b/scripts/eslint/rules/js-extensions.cjs
new file mode 100644
index 0000000000000..7e435d1ada8ce
--- /dev/null
+++ b/scripts/eslint/rules/js-extensions.cjs
@@ -0,0 +1,70 @@
+const { createRule } = require("./utils.cjs");
+
+module.exports = createRule({
+ name: "js-extensions",
+ meta: {
+ docs: {
+ description: ``,
+ },
+ messages: {
+ missingJsExtension: `This relative module reference is missing a '.js' extension`,
+ },
+ schema: [],
+ type: "suggestion",
+ fixable: "code",
+ },
+ defaultOptions: [],
+
+ create(context) {
+ /** @type {(
+ * node:
+ * | import("@typescript-eslint/utils").TSESTree.ImportDeclaration
+ * | import("@typescript-eslint/utils").TSESTree.ExportAllDeclaration
+ * | import("@typescript-eslint/utils").TSESTree.ExportNamedDeclaration
+ * | import("@typescript-eslint/utils").TSESTree.TSImportEqualsDeclaration
+ * | import("@typescript-eslint/utils").TSESTree.TSModuleDeclaration
+ * ) => void}
+ */
+ const check = node => {
+ let source;
+ if (node.type === "TSImportEqualsDeclaration") {
+ const moduleReference = node.moduleReference;
+ if (
+ moduleReference.type === "TSExternalModuleReference"
+ && moduleReference.expression.type === "Literal"
+ && typeof moduleReference.expression.value === "string"
+ ) {
+ source = moduleReference.expression;
+ }
+ }
+ else if (node.type === "TSModuleDeclaration") {
+ if (node.kind === "module" && node.id.type === "Literal") {
+ source = node.id;
+ }
+ }
+ else {
+ source = node.source;
+ }
+
+ // This is not 100% accurate; this could point to a nested package, or to a directory
+ // containing an index.js file. But we don't have anything like that in our repo,
+ // so this check is good enough. Replicate this logic at your own risk.
+ if (source?.value.startsWith(".") && !/\.[cm]?js$/.test(source.value)) {
+ const quote = source.raw[0];
+ context.report({
+ messageId: "missingJsExtension",
+ node: source,
+ fix: fixer => fixer.replaceText(source, `${quote}${source.value}.js${quote}`),
+ });
+ }
+ };
+
+ return {
+ ImportDeclaration: check,
+ ExportAllDeclaration: check,
+ ExportNamedDeclaration: check,
+ TSImportEqualsDeclaration: check,
+ TSModuleDeclaration: check,
+ };
+ },
+});
diff --git a/scripts/eslint/tests/js-extensions.cjs b/scripts/eslint/tests/js-extensions.cjs
new file mode 100644
index 0000000000000..177070ab5f520
--- /dev/null
+++ b/scripts/eslint/tests/js-extensions.cjs
@@ -0,0 +1,149 @@
+const { RuleTester } = require("./support/RuleTester.cjs");
+const rule = require("../rules/js-extensions.cjs");
+
+const ruleTester = new RuleTester({
+ parserOptions: {
+ warnOnUnsupportedTypeScriptVersion: false,
+ },
+ parser: require.resolve("@typescript-eslint/parser"),
+});
+
+ruleTester.run("js-extensions", rule, {
+ valid: [
+ {
+ code: `
+import "some-library";
+import "./a.js";
+import "./a.mjs";
+import "./a.cjs";
+import "../foo/a.js";
+import "../foo/a.mjs";
+import "../foo/a.cjs";
+ `,
+ },
+ {
+ code: `
+import * as blah from "some-library";
+import * as blah from "./a.js";
+import * as blah from "./a.mjs";
+import * as blah from "./a.cjs";
+import * as blah from "../foo/a.js";
+import * as blah from "../foo/a.mjs";
+import * as blah from "../foo/a.cjs";
+ `,
+ },
+ {
+ code: `
+export * from "some-library";
+export * from "./a.js";
+export * from "./a.mjs";
+export * from "./a.cjs";
+export * from "../foo/a.js";
+export * from "../foo/a.mjs";
+export * from "../foo/a.cjs";
+ `,
+ },
+ {
+ code: `
+import blah = require("some-library");
+import blah = require("./a.js");
+import blah = require("./a.mjs");
+import blah = require("./a.cjs");
+import blah = require("../foo/a.js");
+import blah = require("../foo/a.mjs");
+import blah = require("../foo/a.cjs");
+ `,
+ },
+ ],
+
+ invalid: [
+ {
+ code: `
+import "./a";
+import "../foo/a";
+ `,
+ errors: [
+ {
+ messageId: "missingJsExtension",
+ line: 2,
+ column: 8,
+ },
+ {
+ messageId: "missingJsExtension",
+ line: 3,
+ column: 8,
+ },
+ ],
+ output: `
+import "./a.js";
+import "../foo/a.js";
+ `,
+ },
+ {
+ code: `
+import * as blah from "./a";
+import * as blah from "../foo/a";
+ `,
+ errors: [
+ {
+ messageId: "missingJsExtension",
+ line: 2,
+ column: 23,
+ },
+ {
+ messageId: "missingJsExtension",
+ line: 3,
+ column: 23,
+ },
+ ],
+ output: `
+import * as blah from "./a.js";
+import * as blah from "../foo/a.js";
+ `,
+ },
+ {
+ code: `
+export * from "./a";
+export * from "../foo/a";
+ `,
+ errors: [
+ {
+ messageId: "missingJsExtension",
+ line: 2,
+ column: 15,
+ },
+ {
+ messageId: "missingJsExtension",
+ line: 3,
+ column: 15,
+ },
+ ],
+ output: `
+export * from "./a.js";
+export * from "../foo/a.js";
+ `,
+ },
+ {
+ code: `
+import blah = require("./a");
+import blah = require("../foo/a");
+ `,
+ errors: [
+ {
+ messageId: "missingJsExtension",
+ line: 2,
+ column: 23,
+ },
+ {
+ messageId: "missingJsExtension",
+ line: 3,
+ column: 23,
+ },
+ ],
+ output: `
+import blah = require("./a.js");
+import blah = require("../foo/a.js");
+ `,
+ },
+ ],
+});
diff --git a/scripts/processDiagnosticMessages.mjs b/scripts/processDiagnosticMessages.mjs
index 069bd95aa4308..b3f398b802c18 100644
--- a/scripts/processDiagnosticMessages.mjs
+++ b/scripts/processDiagnosticMessages.mjs
@@ -86,7 +86,7 @@ function buildInfoFileOutput(messageTable, inputFilePathRel) {
"// ",
`// generated from '${inputFilePathRel}'`,
"",
- 'import { DiagnosticCategory, DiagnosticMessage } from "./types";',
+ 'import { DiagnosticCategory, DiagnosticMessage } from "./types.js";',
"",
"function diag(code: number, category: DiagnosticCategory, key: string, message: string, reportsUnnecessary?: {}, elidedInCompatabilityPyramid?: boolean, reportsDeprecated?: {}): DiagnosticMessage {",
" return { code, category, key, message, reportsUnnecessary, elidedInCompatabilityPyramid, reportsDeprecated };",
diff --git a/scripts/regenerate-unicode-identifier-parts.mjs b/scripts/regenerate-unicode-identifier-parts.mjs
index e993a40e7a8d9..4dbc0354ebe87 100644
--- a/scripts/regenerate-unicode-identifier-parts.mjs
+++ b/scripts/regenerate-unicode-identifier-parts.mjs
@@ -20,10 +20,12 @@ for (let i = 0; i < MAX_UNICODE_CODEPOINT; i++) {
}
console.log(`/**
-* Generated by scripts/regenerate-unicode-identifier-parts.js on node ${process.version} with unicode ${process.versions.unicode}
-* based on http://www.unicode.org/reports/tr31/ and https://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords
-* unicodeESNextIdentifierStart corresponds to the ID_Start and Other_ID_Start property, and
-* unicodeESNextIdentifierPart corresponds to ID_Continue, Other_ID_Continue, plus ID_Start and Other_ID_Start
-*/`);
+ * Generated by scripts/regenerate-unicode-identifier-parts.mjs on node ${process.version} with unicode ${process.versions.unicode}
+ * based on http://www.unicode.org/reports/tr31/ and https://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords
+ * unicodeESNextIdentifierStart corresponds to the ID_Start and Other_ID_Start property, and
+ * unicodeESNextIdentifierPart corresponds to ID_Continue, Other_ID_Continue, plus ID_Start and Other_ID_Start
+ */`);
+console.log(`// dprint-ignore`);
console.log(`const unicodeESNextIdentifierStart = [${starts.join(", ")}];`);
+console.log(`// dprint-ignore`);
console.log(`const unicodeESNextIdentifierPart = [${parts.join(", ")}];`);
diff --git a/src/compiler/_namespaces/ts.moduleSpecifiers.ts b/src/compiler/_namespaces/ts.moduleSpecifiers.ts
index 47a204d4a72b9..445d749e07810 100644
--- a/src/compiler/_namespaces/ts.moduleSpecifiers.ts
+++ b/src/compiler/_namespaces/ts.moduleSpecifiers.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.moduleSpecifiers namespace. */
-export * from "../moduleSpecifiers";
+export * from "../moduleSpecifiers.js";
diff --git a/src/compiler/_namespaces/ts.performance.ts b/src/compiler/_namespaces/ts.performance.ts
index 707f8f85ef697..58639cdda87ad 100644
--- a/src/compiler/_namespaces/ts.performance.ts
+++ b/src/compiler/_namespaces/ts.performance.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.performance namespace. */
-export * from "../performance";
+export * from "../performance.js";
diff --git a/src/compiler/_namespaces/ts.ts b/src/compiler/_namespaces/ts.ts
index 61f836b427b37..17b7bd7841238 100644
--- a/src/compiler/_namespaces/ts.ts
+++ b/src/compiler/_namespaces/ts.ts
@@ -1,79 +1,79 @@
/* Generated file to emulate the ts namespace. */
-export * from "../corePublic";
-export * from "../core";
-export * from "../debug";
-export * from "../semver";
-export * from "../performanceCore";
-export * from "../perfLogger";
-export * from "../tracing";
-export * from "../types";
-export * from "../sys";
-export * from "../path";
-export * from "../diagnosticInformationMap.generated";
-export * from "../scanner";
-export * from "../utilitiesPublic";
-export * from "../utilities";
-export * from "../factory/baseNodeFactory";
-export * from "../factory/parenthesizerRules";
-export * from "../factory/nodeConverters";
-export * from "../factory/nodeFactory";
-export * from "../factory/emitNode";
-export * from "../factory/emitHelpers";
-export * from "../factory/nodeTests";
-export * from "../factory/nodeChildren";
-export * from "../factory/utilities";
-export * from "../factory/utilitiesPublic";
-export * from "../parser";
-export * from "../commandLineParser";
-export * from "../moduleNameResolver";
-export * from "../binder";
-export * from "../symbolWalker";
-export * from "../checker";
-export * from "../visitorPublic";
-export * from "../sourcemap";
-export * from "../transformers/utilities";
-export * from "../transformers/destructuring";
-export * from "../transformers/classThis";
-export * from "../transformers/namedEvaluation";
-export * from "../transformers/taggedTemplate";
-export * from "../transformers/ts";
-export * from "../transformers/classFields";
-export * from "../transformers/typeSerializer";
-export * from "../transformers/legacyDecorators";
-export * from "../transformers/esDecorators";
-export * from "../transformers/es2017";
-export * from "../transformers/es2018";
-export * from "../transformers/es2019";
-export * from "../transformers/es2020";
-export * from "../transformers/es2021";
-export * from "../transformers/esnext";
-export * from "../transformers/jsx";
-export * from "../transformers/es2016";
-export * from "../transformers/es2015";
-export * from "../transformers/generators";
-export * from "../transformers/module/module";
-export * from "../transformers/module/system";
-export * from "../transformers/module/esnextAnd2015";
-export * from "../transformers/module/impliedNodeFormatDependent";
-export * from "../transformers/declarations/diagnostics";
-export * from "../transformers/declarations";
-export * from "../transformer";
-export * from "../emitter";
-export * from "../watchUtilities";
-export * from "../program";
-export * from "../builderStatePublic";
-export * from "../builderState";
-export * from "../builder";
-export * from "../builderPublic";
-export * from "../resolutionCache";
-export * from "../watch";
-export * from "../watchPublic";
-export * from "../tsbuild";
-export * from "../tsbuildPublic";
-export * from "../executeCommandLine";
-export * from "../expressionToTypeNode";
-import * as moduleSpecifiers from "./ts.moduleSpecifiers";
+export * from "../corePublic.js";
+export * from "../core.js";
+export * from "../debug.js";
+export * from "../semver.js";
+export * from "../performanceCore.js";
+export * from "../perfLogger.js";
+export * from "../tracing.js";
+export * from "../types.js";
+export * from "../sys.js";
+export * from "../path.js";
+export * from "../diagnosticInformationMap.generated.js";
+export * from "../scanner.js";
+export * from "../utilitiesPublic.js";
+export * from "../utilities.js";
+export * from "../factory/baseNodeFactory.js";
+export * from "../factory/parenthesizerRules.js";
+export * from "../factory/nodeConverters.js";
+export * from "../factory/nodeFactory.js";
+export * from "../factory/emitNode.js";
+export * from "../factory/emitHelpers.js";
+export * from "../factory/nodeTests.js";
+export * from "../factory/nodeChildren.js";
+export * from "../factory/utilities.js";
+export * from "../factory/utilitiesPublic.js";
+export * from "../parser.js";
+export * from "../commandLineParser.js";
+export * from "../moduleNameResolver.js";
+export * from "../binder.js";
+export * from "../symbolWalker.js";
+export * from "../checker.js";
+export * from "../visitorPublic.js";
+export * from "../sourcemap.js";
+export * from "../transformers/utilities.js";
+export * from "../transformers/destructuring.js";
+export * from "../transformers/classThis.js";
+export * from "../transformers/namedEvaluation.js";
+export * from "../transformers/taggedTemplate.js";
+export * from "../transformers/ts.js";
+export * from "../transformers/classFields.js";
+export * from "../transformers/typeSerializer.js";
+export * from "../transformers/legacyDecorators.js";
+export * from "../transformers/esDecorators.js";
+export * from "../transformers/es2017.js";
+export * from "../transformers/es2018.js";
+export * from "../transformers/es2019.js";
+export * from "../transformers/es2020.js";
+export * from "../transformers/es2021.js";
+export * from "../transformers/esnext.js";
+export * from "../transformers/jsx.js";
+export * from "../transformers/es2016.js";
+export * from "../transformers/es2015.js";
+export * from "../transformers/generators.js";
+export * from "../transformers/module/module.js";
+export * from "../transformers/module/system.js";
+export * from "../transformers/module/esnextAnd2015.js";
+export * from "../transformers/module/impliedNodeFormatDependent.js";
+export * from "../transformers/declarations/diagnostics.js";
+export * from "../transformers/declarations.js";
+export * from "../transformer.js";
+export * from "../emitter.js";
+export * from "../watchUtilities.js";
+export * from "../program.js";
+export * from "../builderStatePublic.js";
+export * from "../builderState.js";
+export * from "../builder.js";
+export * from "../builderPublic.js";
+export * from "../resolutionCache.js";
+export * from "../watch.js";
+export * from "../watchPublic.js";
+export * from "../tsbuild.js";
+export * from "../tsbuildPublic.js";
+export * from "../executeCommandLine.js";
+export * from "../expressionToTypeNode.js";
+import * as moduleSpecifiers from "./ts.moduleSpecifiers.js";
export { moduleSpecifiers };
-import * as performance from "./ts.performance";
+import * as performance from "./ts.performance.js";
export { performance };
diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts
index 59b1eb19d7323..ea263f471cbdc 100644
--- a/src/compiler/binder.ts
+++ b/src/compiler/binder.ts
@@ -320,8 +320,8 @@ import {
VariableDeclaration,
WhileStatement,
WithStatement,
-} from "./_namespaces/ts";
-import * as performance from "./_namespaces/ts.performance";
+} from "./_namespaces/ts.js";
+import * as performance from "./_namespaces/ts.performance.js";
/** @internal */
export const enum ModuleInstanceState {
diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts
index d2f7b376ddd5b..3b75cb86732c0 100644
--- a/src/compiler/builder.ts
+++ b/src/compiler/builder.ts
@@ -1,6 +1,7 @@
import {
addRange,
AffectedFileResult,
+ append,
arrayFrom,
arrayToMap,
BuilderProgram,
@@ -49,6 +50,7 @@ import {
getOptionsNameMap,
getOwnKeys,
getRelativePathFromDirectory,
+ getSourceFileOfNode,
getTsBuildInfoEmitOutputFilePath,
handleNoEmitOptions,
HostForComputeHash,
@@ -58,6 +60,7 @@ import {
isNumber,
isString,
map,
+ mapDefinedIterator,
maybeBind,
noop,
notImplemented,
@@ -73,15 +76,18 @@ import {
sameMap,
SemanticDiagnosticsBuilderProgram,
SignatureInfo,
+ skipAlias,
skipTypeChecking,
+ some,
SourceFile,
sourceFileMayBeEmitted,
SourceMapEmitResult,
+ SymbolFlags,
toPath,
tryAddToSet,
WriteFileCallback,
WriteFileCallbackData,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export interface ReusableDiagnostic extends ReusableDiagnosticRelatedInformation {
@@ -97,7 +103,7 @@ export interface ReusableDiagnostic extends ReusableDiagnosticRelatedInformation
export interface ReusableDiagnosticRelatedInformation {
category: DiagnosticCategory;
code: number;
- file: string | undefined;
+ file: string | undefined | false;
start: number | undefined;
length: number | undefined;
messageText: string | ReusableDiagnosticMessageChain;
@@ -379,7 +385,7 @@ function createBuilderProgramState(newProgram: Program, oldState: Readonly convertOrRepopulateDiagnosticMessageChain(chain, sourceFile, newProgram, repopulateInfo));
}
-function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newProgram: Program): readonly Diagnostic[] {
+function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], diagnosticFilePath: Path, newProgram: Program): readonly Diagnostic[] {
if (!diagnostics.length) return emptyArray;
let buildInfoDirectory: string | undefined;
return diagnostics.map(diagnostic => {
- const result: Diagnostic = convertToDiagnosticRelatedInformation(diagnostic, newProgram, toPathInBuildInfoDirectory);
+ const result: Diagnostic = convertToDiagnosticRelatedInformation(diagnostic, diagnosticFilePath, newProgram, toPathInBuildInfoDirectory);
result.reportsUnnecessary = diagnostic.reportsUnnecessary;
result.reportsDeprecated = diagnostic.reportDeprecated;
result.source = diagnostic.source;
@@ -523,7 +529,7 @@ function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newPro
const { relatedInformation } = diagnostic;
result.relatedInformation = relatedInformation ?
relatedInformation.length ?
- relatedInformation.map(r => convertToDiagnosticRelatedInformation(r, newProgram, toPathInBuildInfoDirectory)) :
+ relatedInformation.map(r => convertToDiagnosticRelatedInformation(r, diagnosticFilePath, newProgram, toPathInBuildInfoDirectory)) :
[] :
undefined;
return result;
@@ -535,9 +541,11 @@ function convertToDiagnostics(diagnostics: readonly ReusableDiagnostic[], newPro
}
}
-function convertToDiagnosticRelatedInformation(diagnostic: ReusableDiagnosticRelatedInformation, newProgram: Program, toPath: (path: string) => Path): DiagnosticRelatedInformation {
+function convertToDiagnosticRelatedInformation(diagnostic: ReusableDiagnosticRelatedInformation, diagnosticFilePath: Path, newProgram: Program, toPath: (path: string) => Path): DiagnosticRelatedInformation {
const { file } = diagnostic;
- const sourceFile = file ? newProgram.getSourceFileByPath(toPath(file)) : undefined;
+ const sourceFile = file !== false ?
+ newProgram.getSourceFileByPath(file ? toPath(file) : diagnosticFilePath) :
+ undefined;
return {
...diagnostic,
file: sourceFile,
@@ -761,6 +769,7 @@ function handleDtsMayChangeOfAffectedFile(
function handleDtsMayChangeOf(
state: BuilderProgramState,
path: Path,
+ invalidateJsFiles: boolean,
cancellationToken: CancellationToken | undefined,
host: BuilderProgramHost,
): void {
@@ -784,7 +793,10 @@ function handleDtsMayChangeOf(
/*useFileVersionAsSignature*/ true,
);
// If not dts emit, nothing more to do
- if (getEmitDeclarations(state.compilerOptions)) {
+ if (invalidateJsFiles) {
+ addToAffectedFilesPendingEmit(state, path, getBuilderFileEmit(state.compilerOptions));
+ }
+ else if (getEmitDeclarations(state.compilerOptions)) {
addToAffectedFilesPendingEmit(state, path, state.compilerOptions.declarationMap ? BuilderFileEmit.AllDts : BuilderFileEmit.Dts);
}
}
@@ -813,6 +825,7 @@ function isChangedSignature(state: BuilderProgramState, path: Path) {
function handleDtsMayChangeOfGlobalScope(
state: BuilderProgramState,
filePath: Path,
+ invalidateJsFiles: boolean,
cancellationToken: CancellationToken | undefined,
host: BuilderProgramHost,
): boolean {
@@ -823,6 +836,7 @@ function handleDtsMayChangeOfGlobalScope(
handleDtsMayChangeOf(
state,
file.resolvedPath,
+ invalidateJsFiles,
cancellationToken,
host,
)
@@ -855,8 +869,16 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
const currentPath = queue.pop()!;
if (!seenFileNamesMap.has(currentPath)) {
seenFileNamesMap.set(currentPath, true);
- if (handleDtsMayChangeOfGlobalScope(state, currentPath, cancellationToken, host)) return;
- handleDtsMayChangeOf(state, currentPath, cancellationToken, host);
+ if (
+ handleDtsMayChangeOfGlobalScope(
+ state,
+ currentPath,
+ /*invalidateJsFiles*/ false,
+ cancellationToken,
+ host,
+ )
+ ) return;
+ handleDtsMayChangeOf(state, currentPath, /*invalidateJsFiles*/ false, cancellationToken, host);
if (isChangedSignature(state, currentPath)) {
const currentSourceFile = Debug.checkDefined(state.program).getSourceFileByPath(currentPath)!;
queue.push(...BuilderState.getReferencedByPaths(state, currentSourceFile.resolvedPath));
@@ -866,14 +888,26 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
}
const seenFileAndExportsOfFile = new Set();
+ // If exported const enum, we need to ensure that js files are emitted as well since the const enum value changed
+ const invalidateJsFiles = !!affectedFile.symbol?.exports && !!forEachEntry(
+ affectedFile.symbol.exports,
+ exported => {
+ if ((exported.flags & SymbolFlags.ConstEnum) !== 0) return true;
+ const aliased = skipAlias(exported, state.program!.getTypeChecker());
+ if (aliased === exported) return false;
+ return (aliased.flags & SymbolFlags.ConstEnum) !== 0 &&
+ some(aliased.declarations, d => getSourceFileOfNode(d) === affectedFile);
+ },
+ );
// Go through files that reference affected file and handle dts emit and semantic diagnostics for them and their references
state.referencedMap.getKeys(affectedFile.resolvedPath)?.forEach(exportedFromPath => {
- if (handleDtsMayChangeOfGlobalScope(state, exportedFromPath, cancellationToken, host)) return true;
+ if (handleDtsMayChangeOfGlobalScope(state, exportedFromPath, invalidateJsFiles, cancellationToken, host)) return true;
const references = state.referencedMap!.getKeys(exportedFromPath);
return references && forEachKey(references, filePath =>
handleDtsMayChangeOfFileAndExportsOfFile(
state,
filePath,
+ invalidateJsFiles,
seenFileAndExportsOfFile,
cancellationToken,
host,
@@ -888,20 +922,22 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
function handleDtsMayChangeOfFileAndExportsOfFile(
state: BuilderProgramState,
filePath: Path,
+ invalidateJsFiles: boolean,
seenFileAndExportsOfFile: Set,
cancellationToken: CancellationToken | undefined,
host: BuilderProgramHost,
): boolean | undefined {
if (!tryAddToSet(seenFileAndExportsOfFile, filePath)) return undefined;
- if (handleDtsMayChangeOfGlobalScope(state, filePath, cancellationToken, host)) return true;
- handleDtsMayChangeOf(state, filePath, cancellationToken, host);
+ if (handleDtsMayChangeOfGlobalScope(state, filePath, invalidateJsFiles, cancellationToken, host)) return true;
+ handleDtsMayChangeOf(state, filePath, invalidateJsFiles, cancellationToken, host);
// Remove the diagnostics of files that import this file and handle all its exports too
state.referencedMap!.getKeys(filePath)?.forEach(referencingFilePath =>
handleDtsMayChangeOfFileAndExportsOfFile(
state,
referencingFilePath,
+ invalidateJsFiles,
seenFileAndExportsOfFile,
cancellationToken,
host,
@@ -948,7 +984,14 @@ export type ProgramBuildInfoFileId = number & { __programBuildInfoFileIdBrand: a
/** @internal */
export type ProgramBuildInfoFileIdListId = number & { __programBuildInfoFileIdListIdBrand: any; };
/** @internal */
-export type ProgramBuildInfoDiagnostic = ProgramBuildInfoFileId | [fileId: ProgramBuildInfoFileId, diagnostics: readonly ReusableDiagnostic[]];
+export type ProgramBuildInfoDiagnosticOfFile = [fileId: ProgramBuildInfoFileId, diagnostics: readonly ReusableDiagnostic[]];
+/** @internal */
+export type ProgramBuildInfoDiagnostic =
+ | ProgramBuildInfoFileId // File is not in changedSet and still doesnt have cached diagnostics
+ | ProgramBuildInfoDiagnosticOfFile; // Diagnostics for file
+/** @internal */
+export type ProgramBuildInfoEmitDiagnostic = ProgramBuildInfoDiagnosticOfFile; // Diagnostics for the file
+
/**
* fileId if pending emit is same as what compilerOptions suggest
* [fileId] if pending emit is only dts file emit
@@ -990,15 +1033,18 @@ export type ProgramBuildInfoRootStartEnd = [start: ProgramBuildInfoFileId, end:
*/
export type ProgramBuildInfoRoot = ProgramBuildInfoRootStartEnd | ProgramBuildInfoFileId;
/** @internal */
+export type ProgramBuildInfoResolvedRoot = [resolved: ProgramBuildInfoFileId, root: ProgramBuildInfoFileId];
+/** @internal */
export interface ProgramMultiFileEmitBuildInfo {
fileNames: readonly string[];
fileInfos: readonly ProgramMultiFileEmitBuildInfoFileInfo[];
root: readonly ProgramBuildInfoRoot[];
+ resolvedRoot: readonly ProgramBuildInfoResolvedRoot[] | undefined;
options: CompilerOptions | undefined;
fileIdsList: readonly (readonly ProgramBuildInfoFileId[])[] | undefined;
referencedMap: ProgramBuildInfoReferencedMap | undefined;
semanticDiagnosticsPerFile: ProgramBuildInfoDiagnostic[] | undefined;
- emitDiagnosticsPerFile: ProgramBuildInfoDiagnostic[] | undefined;
+ emitDiagnosticsPerFile: ProgramBuildInfoEmitDiagnostic[] | undefined;
affectedFilesPendingEmit: ProgramBuilderInfoFilePendingEmit[] | undefined;
changeFileSet: readonly ProgramBuildInfoFileId[] | undefined;
emitSignatures: readonly ProgramBuildInfoEmitSignature[] | undefined;
@@ -1023,6 +1069,7 @@ export interface ProgramBundleEmitBuildInfo {
fileNames: readonly string[];
fileInfos: readonly ProgramBundleEmitBuildInfoFileInfo[];
root: readonly ProgramBuildInfoRoot[];
+ resolvedRoot: readonly ProgramBuildInfoResolvedRoot[] | undefined;
options: CompilerOptions | undefined;
outSignature: EmitSignature | undefined;
latestChangedDtsFile: string | undefined;
@@ -1047,6 +1094,7 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
const latestChangedDtsFile = state.latestChangedDtsFile ? relativeToBuildInfoEnsuringAbsolutePath(state.latestChangedDtsFile) : undefined;
const fileNames: string[] = [];
const fileNameToFileId = new Map();
+ const rootFileNames = new Set(state.program!.getRootFileNames().map(f => toPath(f, currentDirectory, state.program!.getCanonicalFileName)));
const root: ProgramBuildInfoRoot[] = [];
if (state.compilerOptions.outFile) {
// Copy all fileInfo, version and impliedFormat
@@ -1063,6 +1111,7 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
fileNames,
fileInfos,
root,
+ resolvedRoot: toResolvedRoot(),
options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions),
outSignature: state.outSignature,
latestChangedDtsFile,
@@ -1090,7 +1139,8 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
if (!isJsonSourceFile(file) && sourceFileMayBeEmitted(file, state.program!)) {
const emitSignature = state.emitSignatures?.get(key);
if (emitSignature !== actualSignature) {
- (emitSignatures ||= []).push(
+ emitSignatures = append(
+ emitSignatures,
emitSignature === undefined ?
fileId : // There is no emit, encode as false
// fileId, signature: emptyArray if signature only differs in dtsMap option than our own compilerOptions otherwise EmitSignature
@@ -1116,14 +1166,14 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
});
let referencedMap: ProgramBuildInfoReferencedMap | undefined;
- if (state.referencedMap) {
+ if (state.referencedMap?.size()) {
referencedMap = arrayFrom(state.referencedMap.keys()).sort(compareStringsCaseSensitive).map(key => [
toFileId(key),
toFileIdListId(state.referencedMap!.getValues(key)!),
]);
}
- const semanticDiagnosticsPerFile = convertToProgramBuildInfoDiagnostics(state.semanticDiagnosticsPerFile);
+ const semanticDiagnosticsPerFile = convertToProgramBuildInfoDiagnostics();
let affectedFilesPendingEmit: ProgramBuilderInfoFilePendingEmit[] | undefined;
if (state.affectedFilesPendingEmit?.size) {
const fullEmitForOptions = getBuilderFileEmit(state.compilerOptions);
@@ -1133,7 +1183,8 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
const file = state.program!.getSourceFileByPath(path);
if (!file || !sourceFileMayBeEmitted(file, state.program!)) continue;
const fileId = toFileId(path), pendingEmit = state.affectedFilesPendingEmit.get(path)!;
- (affectedFilesPendingEmit ||= []).push(
+ affectedFilesPendingEmit = append(
+ affectedFilesPendingEmit,
pendingEmit === fullEmitForOptions ?
fileId : // Pending full emit per options
pendingEmit === BuilderFileEmit.Dts ?
@@ -1147,14 +1198,15 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
let changeFileSet: ProgramBuildInfoFileId[] | undefined;
if (state.changedFilesSet.size) {
for (const path of arrayFrom(state.changedFilesSet.keys()).sort(compareStringsCaseSensitive)) {
- (changeFileSet ||= []).push(toFileId(path));
+ changeFileSet = append(changeFileSet, toFileId(path));
}
}
- const emitDiagnosticsPerFile = convertToProgramBuildInfoDiagnostics(state.emitDiagnosticsPerFile);
+ const emitDiagnosticsPerFile = convertToProgramBuildInfoEmitDiagnostics();
const program: ProgramMultiFileEmitBuildInfo = {
fileNames,
fileInfos,
root,
+ resolvedRoot: toResolvedRoot(),
options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions),
fileIdsList,
referencedMap,
@@ -1189,8 +1241,8 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
const key = fileIds.join();
let fileIdListId = fileNamesToFileIdListId?.get(key);
if (fileIdListId === undefined) {
- (fileIdsList ||= []).push(fileIds);
- (fileNamesToFileIdListId ||= new Map()).set(key, fileIdListId = fileIdsList.length as ProgramBuildInfoFileIdListId);
+ fileIdsList = append(fileIdsList, fileIds);
+ (fileNamesToFileIdListId ??= new Map()).set(key, fileIdListId = fileIdsList.length as ProgramBuildInfoFileIdListId);
}
return fileIdListId;
}
@@ -1214,6 +1266,17 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
return root.length = root.length - 1;
}
+ function toResolvedRoot(): ProgramBuildInfoResolvedRoot[] | undefined {
+ let result: ProgramBuildInfoResolvedRoot[] | undefined;
+ rootFileNames.forEach(path => {
+ const file = state.program!.getSourceFileByPath(path);
+ if (file && path !== file.resolvedPath) {
+ result = append(result, [toFileId(file.resolvedPath), toFileId(path)]);
+ }
+ });
+ return result;
+ }
+
/**
* @param optionKey key of CommandLineOption to use to determine if the option should be serialized in tsbuildinfo
*/
@@ -1248,28 +1311,40 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
return value;
}
- function convertToProgramBuildInfoDiagnostics(diagnostics: Map | undefined) {
+ function convertToProgramBuildInfoDiagnostics() {
let result: ProgramBuildInfoDiagnostic[] | undefined;
- if (diagnostics) {
- for (const key of arrayFrom(diagnostics.keys()).sort(compareStringsCaseSensitive)) {
- const value = diagnostics.get(key)!;
- (result ||= []).push(
- value.length ?
- [
- toFileId(key),
- convertToReusableDiagnostics(value),
- ] :
- toFileId(key),
- );
+ state.fileInfos.forEach((_value, key) => {
+ const value = state.semanticDiagnosticsPerFile?.get(key);
+ if (!value) {
+ if (!state.changedFilesSet.has(key)) result = append(result, toFileId(key));
+ }
+ else if (value.length) {
+ result = append(result, [
+ toFileId(key),
+ convertToReusableDiagnostics(value, key),
+ ]);
}
+ });
+ return result;
+ }
+
+ function convertToProgramBuildInfoEmitDiagnostics() {
+ let result: ProgramBuildInfoEmitDiagnostic[] | undefined;
+ if (!state.emitDiagnosticsPerFile?.size) return result;
+ for (const key of arrayFrom(state.emitDiagnosticsPerFile.keys()).sort(compareStringsCaseSensitive)) {
+ const value = state.emitDiagnosticsPerFile.get(key)!;
+ result = append(result, [
+ toFileId(key),
+ convertToReusableDiagnostics(value, key),
+ ]);
}
return result;
}
- function convertToReusableDiagnostics(diagnostics: readonly Diagnostic[]): readonly ReusableDiagnostic[] {
+ function convertToReusableDiagnostics(diagnostics: readonly Diagnostic[], diagnosticFilePath: Path): readonly ReusableDiagnostic[] {
Debug.assert(!!diagnostics.length);
return diagnostics.map(diagnostic => {
- const result: ReusableDiagnostic = convertToReusableDiagnosticRelatedInformation(diagnostic);
+ const result: ReusableDiagnostic = convertToReusableDiagnosticRelatedInformation(diagnostic, diagnosticFilePath);
result.reportsUnnecessary = diagnostic.reportsUnnecessary;
result.reportDeprecated = diagnostic.reportsDeprecated;
result.source = diagnostic.source;
@@ -1277,18 +1352,22 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
const { relatedInformation } = diagnostic;
result.relatedInformation = relatedInformation ?
relatedInformation.length ?
- relatedInformation.map(r => convertToReusableDiagnosticRelatedInformation(r)) :
+ relatedInformation.map(r => convertToReusableDiagnosticRelatedInformation(r, diagnosticFilePath)) :
[] :
undefined;
return result;
});
}
- function convertToReusableDiagnosticRelatedInformation(diagnostic: DiagnosticRelatedInformation): ReusableDiagnosticRelatedInformation {
+ function convertToReusableDiagnosticRelatedInformation(diagnostic: DiagnosticRelatedInformation, diagnosticFilePath: Path): ReusableDiagnosticRelatedInformation {
const { file } = diagnostic;
return {
...diagnostic,
- file: file ? relativeToBuildInfo(file.resolvedPath) : undefined,
+ file: file ?
+ file.resolvedPath === diagnosticFilePath ?
+ undefined :
+ relativeToBuildInfo(file.resolvedPath) :
+ false,
messageText: isString(diagnostic.messageText) ? diagnostic.messageText : convertToReusableDiagnosticMessageChain(diagnostic.messageText),
};
}
@@ -1827,16 +1906,17 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo,
);
}
});
+ const changedFilesSet = new Set(map(program.changeFileSet, toFilePath));
const fullEmitForOptions = program.affectedFilesPendingEmit ? getBuilderFileEmit(program.options || {}) : undefined;
state = {
fileInfos,
compilerOptions: program.options ? convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {},
- referencedMap: toManyToManyPathMap(program.referencedMap),
- semanticDiagnosticsPerFile: toPerFileDiagnostics(program.semanticDiagnosticsPerFile),
- emitDiagnosticsPerFile: toPerFileDiagnostics(program.emitDiagnosticsPerFile),
+ referencedMap: toManyToManyPathMap(program.referencedMap, program.options ?? {}),
+ semanticDiagnosticsPerFile: toPerFileSemanticDiagnostics(program.semanticDiagnosticsPerFile, fileInfos, changedFilesSet),
+ emitDiagnosticsPerFile: toPerFileEmitDiagnostics(program.emitDiagnosticsPerFile),
hasReusableDiagnostic: true,
affectedFilesPendingEmit: program.affectedFilesPendingEmit && arrayToMap(program.affectedFilesPendingEmit, value => toFilePath(isNumber(value) ? value : value[0]), value => toBuilderFileEmit(value, fullEmitForOptions!)),
- changedFilesSet: new Set(map(program.changeFileSet, toFilePath)),
+ changedFilesSet,
latestChangedDtsFile,
emitSignatures: emitSignatures?.size ? emitSignatures : undefined,
};
@@ -1884,18 +1964,33 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo,
return filePathsSetList![fileIdsListId - 1];
}
- function toManyToManyPathMap(referenceMap: ProgramBuildInfoReferencedMap | undefined): BuilderState.ManyToManyPathMap | undefined {
- if (!referenceMap) {
- return undefined;
- }
-
- const map = BuilderState.createManyToManyPathMap();
+ function toManyToManyPathMap(referenceMap: ProgramBuildInfoReferencedMap | undefined, options: CompilerOptions): BuilderState.ManyToManyPathMap | undefined {
+ const map = BuilderState.createReferencedMap(options);
+ if (!map || !referenceMap) return map;
referenceMap.forEach(([fileId, fileIdListId]) => map.set(toFilePath(fileId), toFilePathsSet(fileIdListId)));
return map;
}
- function toPerFileDiagnostics(diagnostics: readonly ProgramBuildInfoDiagnostic[] | undefined): Map | undefined {
- return diagnostics && arrayToMap(diagnostics, value => toFilePath(isNumber(value) ? value : value[0]), value => isNumber(value) ? emptyArray : value[1]);
+ function toPerFileSemanticDiagnostics(
+ diagnostics: readonly ProgramBuildInfoDiagnostic[] | undefined,
+ fileInfos: Map,
+ changedFilesSet: Set,
+ ): Map | undefined {
+ const semanticDiagnostics = new Map(
+ mapDefinedIterator(
+ fileInfos.keys(),
+ key => !changedFilesSet.has(key) ? [key, emptyArray] : undefined,
+ ),
+ );
+ diagnostics?.forEach(value => {
+ if (isNumber(value)) semanticDiagnostics.delete(toFilePath(value));
+ else semanticDiagnostics.set(toFilePath(value[0]), value[1]);
+ });
+ return semanticDiagnostics.size ? semanticDiagnostics : undefined;
+ }
+
+ function toPerFileEmitDiagnostics(diagnostics: readonly ProgramBuildInfoEmitDiagnostic[] | undefined): Map | undefined {
+ return diagnostics && arrayToMap(diagnostics, value => toFilePath(value[0]), value => value[1]);
}
}
@@ -1909,7 +2004,9 @@ export function getBuildInfoFileVersionMap(
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
const fileInfos = new Map();
let rootIndex = 0;
- const roots: Path[] = [];
+ // Root name to resolved
+ const roots = new Map();
+ const resolvedRoots = new Map(program.resolvedRoot);
program.fileInfos.forEach((fileInfo, index) => {
const path = toPath(program.fileNames[index], buildInfoDirectory, getCanonicalFileName);
const version = isString(fileInfo) ? fileInfo : fileInfo.version;
@@ -1919,17 +2016,27 @@ export function getBuildInfoFileVersionMap(
const fileId = (index + 1) as ProgramBuildInfoFileId;
if (isArray(current)) {
if (current[0] <= fileId && fileId <= current[1]) {
- roots.push(path);
+ addRoot(fileId, path);
if (current[1] === fileId) rootIndex++;
}
}
else if (current === fileId) {
- roots.push(path);
+ addRoot(fileId, path);
rootIndex++;
}
}
});
return { fileInfos, roots };
+
+ function addRoot(fileId: ProgramBuildInfoFileId, path: Path) {
+ const root = resolvedRoots.get(fileId);
+ if (root) {
+ roots.set(toPath(program.fileNames[root - 1], buildInfoDirectory, getCanonicalFileName), path);
+ }
+ else {
+ roots.set(path, undefined);
+ }
+ }
}
/** @internal */
diff --git a/src/compiler/builderPublic.ts b/src/compiler/builderPublic.ts
index 57f2124c9997f..eb2b9b9f4f6dc 100644
--- a/src/compiler/builderPublic.ts
+++ b/src/compiler/builderPublic.ts
@@ -16,7 +16,7 @@ import {
SavedBuildProgramEmitState,
SourceFile,
WriteFileCallback,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export type AffectedFileResult = { result: T; affected: SourceFile | Program; } | undefined;
diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts
index ded9436a279bd..6e23eaddc3741 100644
--- a/src/compiler/builderState.ts
+++ b/src/compiler/builderState.ts
@@ -1,6 +1,7 @@
import {
arrayFrom,
CancellationToken,
+ CompilerOptions,
computeSignatureWithDiagnostics,
CustomTransformers,
Debug,
@@ -31,7 +32,7 @@ import {
Symbol,
toPath,
TypeChecker,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export function getFileEmitOutput(
@@ -110,6 +111,7 @@ export namespace BuilderState {
getKeys(v: Path): ReadonlySet | undefined;
getValues(k: Path): ReadonlySet | undefined;
keys(): IterableIterator;
+ size(): number;
}
export interface ManyToManyPathMap extends ReadonlyManyToManyPathMap {
@@ -123,6 +125,7 @@ export namespace BuilderState {
getKeys: v => reverse.get(v),
getValues: k => forward.get(k),
keys: () => forward.keys(),
+ size: () => forward.size,
deleteKey: k => {
(deleted ||= new Set()).add(k);
@@ -292,15 +295,19 @@ export namespace BuilderState {
return oldState && !oldState.referencedMap === !newReferencedMap;
}
+ export function createReferencedMap(options: CompilerOptions) {
+ return options.module !== ModuleKind.None && !options.outFile ?
+ createManyToManyPathMap() :
+ undefined;
+ }
+
/**
* Creates the state of file references and signature for the new program from oldState if it is safe
*/
export function create(newProgram: Program, oldState: Readonly | undefined, disableUseFileVersionAsSignature: boolean): BuilderState {
const fileInfos = new Map();
const options = newProgram.getCompilerOptions();
- const isOutFile = options.outFile;
- const referencedMap = options.module !== ModuleKind.None && !isOutFile ?
- createManyToManyPathMap() : undefined;
+ const referencedMap = createReferencedMap(options);
const useOldState = canReuseOldState(referencedMap, oldState);
// Ensure source files have parent pointers set
@@ -323,7 +330,7 @@ export namespace BuilderState {
version,
signature,
// No need to calculate affectsGlobalScope with --out since its not used at all
- affectsGlobalScope: !isOutFile ? isFileAffectingGlobalScope(sourceFile) || undefined : undefined,
+ affectsGlobalScope: !options.outFile ? isFileAffectingGlobalScope(sourceFile) || undefined : undefined,
impliedFormat: sourceFile.impliedNodeFormat,
});
}
diff --git a/src/compiler/builderStatePublic.ts b/src/compiler/builderStatePublic.ts
index 9b3a302d2e547..50d08838d0f38 100644
--- a/src/compiler/builderStatePublic.ts
+++ b/src/compiler/builderStatePublic.ts
@@ -1,7 +1,7 @@
import {
Diagnostic,
WriteFileCallbackData,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export interface EmitOutput {
outputFiles: OutputFile[];
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 027007fb15b62..b9579872bd3f0 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -446,6 +446,7 @@ import {
InterfaceType,
InterfaceTypeWithDeclaredMembers,
InternalSymbolName,
+ IntersectionFlags,
IntersectionType,
IntersectionTypeNode,
intrinsicTagNameToString,
@@ -489,6 +490,7 @@ import {
isCatchClauseVariableDeclarationOrBindingElement,
isCheckJsEnabledForFile,
isClassDeclaration,
+ isClassElement,
isClassExpression,
isClassInstanceProperty,
isClassLike,
@@ -692,6 +694,7 @@ import {
isPrivateIdentifierPropertyAccessExpression,
isPropertyAccessEntityNameExpression,
isPropertyAccessExpression,
+ isPropertyAccessOrQualifiedName,
isPropertyAccessOrQualifiedNameOrImportTypeNode,
isPropertyAssignment,
isPropertyDeclaration,
@@ -738,6 +741,7 @@ import {
isThisInitializedObjectBindingExpression,
isThisInTypeQuery,
isThisProperty,
+ isThisTypeNode,
isThisTypeParameter,
isThisTypePredicate,
isTransientSymbol,
@@ -778,7 +782,6 @@ import {
JSDocAugmentsTag,
JSDocCallbackTag,
JSDocComment,
- JSDocEnumTag,
JSDocFunctionType,
JSDocImplementsTag,
JSDocImportTag,
@@ -835,6 +838,7 @@ import {
LateBoundDeclaration,
LateBoundName,
LateVisibilityPaintedStatement,
+ LazyNodeCheckFlags,
length,
LiteralExpression,
LiteralType,
@@ -1104,13 +1108,25 @@ import {
WideningContext,
WithStatement,
YieldExpression,
-} from "./_namespaces/ts";
-import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers";
-import * as performance from "./_namespaces/ts.performance";
+} from "./_namespaces/ts.js";
+import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers.js";
+import * as performance from "./_namespaces/ts.performance.js";
const ambientModuleSymbolRegex = /^".+"$/;
const anon = "(anonymous)" as __String & string;
+const enum ReferenceHint {
+ Unspecified,
+ Identifier,
+ Property,
+ ExportAssignment,
+ Jsx,
+ AsyncFunction,
+ ExportImportEquals,
+ ExportSpecifier,
+ Decorator,
+}
+
let nextSymbolId = 1;
let nextNodeId = 1;
let nextMergeId = 1;
@@ -1272,7 +1288,6 @@ const enum TypeSystemPropertyName {
DeclaredType,
ResolvedReturnType,
ImmediateBaseConstraint,
- EnumTagType,
ResolvedTypeArguments,
ResolvedBaseTypes,
WriteType,
@@ -1448,9 +1463,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// they no longer need the information (for example, if the user started editing again).
var cancellationToken: CancellationToken | undefined;
- var requestedExternalEmitHelperNames = new Set();
- var requestedExternalEmitHelpers: ExternalEmitHelpers;
- var externalHelpersModule: Symbol;
var scanner: Scanner | undefined;
var Symbol = objectAllocator.getSymbolConstructor();
@@ -1492,7 +1504,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
var syntacticNodeBuilder = createSyntacticTypeNodeBuilder(compilerOptions, {
isEntityNameVisible,
isExpandoFunctionDeclaration,
- isNonNarrowedBindableName,
getAllAccessorDeclarations: getAllAccessorDeclarationsForDeclaration,
requiresAddingImplicitUndefined,
isUndefinedIdentifierExpression(node: Identifier) {
@@ -1752,6 +1763,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
getImmediateAliasedSymbol,
getAliasedSymbol: resolveAlias,
getEmitResolver,
+ requiresAddingImplicitUndefined,
getExportsOfModule: getExportsOfModuleAsArray,
getExportsAndPropertiesOfModule,
forEachExportAndPropertyOfModule,
@@ -1899,6 +1911,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
getMemberOverrideModifierStatus,
isTypeParameterPossiblyReferenced,
typeHasCallOrConstructSignatures,
+ getSymbolFlags,
};
function getCandidateSignaturesForStringLiteralCompletions(call: CallLikeExpression, editingArgument: Node) {
@@ -2415,10 +2428,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return visitEachChild(node, markAsSynthetic, /*context*/ undefined);
}
- function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) {
+ function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken, skipDiagnostics?: boolean) {
// Ensure we have all the type information in place for this file so that all the
// emitter questions of this resolver will return the right information.
- getDiagnostics(sourceFile, cancellationToken);
+ if (!skipDiagnostics) getDiagnostics(sourceFile, cancellationToken);
return emitResolver;
}
@@ -2608,7 +2621,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (resolvedTarget === unknownSymbol) {
return source;
}
- target = cloneSymbol(resolvedTarget);
+ if (
+ !(resolvedTarget.flags & getExcludedSymbolFlags(source.flags)) ||
+ (source.flags | resolvedTarget.flags) & SymbolFlags.Assignment
+ ) {
+ target = cloneSymbol(resolvedTarget);
+ }
+ else {
+ reportMergeSymbolError(target, source);
+ return source;
+ }
}
// Javascript static-property-assignment declarations always merge, even though they are also values
if (source.flags & SymbolFlags.ValueModule && target.flags & SymbolFlags.ValueModule && target.constEnumOnlyModule && !source.constEnumOnlyModule) {
@@ -2644,7 +2666,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
);
}
}
- else { // error
+ else {
+ reportMergeSymbolError(target, source);
+ }
+ return target;
+
+ function reportMergeSymbolError(target: Symbol, source: Symbol) {
const isEitherEnum = !!(target.flags & SymbolFlags.Enum || source.flags & SymbolFlags.Enum);
const isEitherBlockScoped = !!(target.flags & SymbolFlags.BlockScopedVariable || source.flags & SymbolFlags.BlockScopedVariable);
const message = isEitherEnum ? Diagnostics.Enum_declarations_can_only_merge_with_namespace_or_other_enum_declarations
@@ -2671,7 +2698,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (!isTargetPlainJs) addDuplicateDeclarationErrorsForSymbols(target, message, symbolName, source);
}
}
- return target;
function addDuplicateLocations(locs: Declaration[], symbol: Symbol): void {
if (symbol.declarations) {
@@ -2808,7 +2834,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (meaning) {
const symbol = getMergedSymbol(symbols.get(name));
if (symbol) {
- Debug.assert((getCheckFlags(symbol) & CheckFlags.Instantiated) === 0, "Should never get an instantiated symbol here.");
if (symbol.flags & meaning) {
return symbol;
}
@@ -4242,6 +4267,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return undefined;
}
const links = getSymbolLinks(symbol);
+ if (links.typeOnlyDeclaration === undefined) {
+ // We need to set a WIP value here to prevent reentrancy during `getImmediateAliasedSymbol` which, paradoxically, can depend on this
+ links.typeOnlyDeclaration = false;
+ const resolved = resolveSymbol(symbol); // do this before the `resolveImmediate` below, as it uses a different circularity cache and we might hide a circularity error if we blindly get the immediate alias first
+ // While usually the alias will have been marked during the pass by the full typecheck, we may still need to calculate the alias declaration now
+ markSymbolOfAliasDeclarationIfTypeOnly(symbol.declarations?.[0], getDeclarationOfAliasSymbol(symbol) && getImmediateAliasedSymbol(symbol), resolved, /*overwriteEmpty*/ true);
+ }
if (include === undefined) {
return links.typeOnlyDeclaration || undefined;
}
@@ -4254,44 +4286,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return undefined;
}
- function markExportAsReferenced(node: ImportEqualsDeclaration | ExportSpecifier) {
- if (!canCollectSymbolAliasAccessabilityData) {
- return;
- }
- const symbol = getSymbolOfDeclaration(node);
- const target = resolveAlias(symbol);
- if (target) {
- const markAlias = target === unknownSymbol ||
- ((getSymbolFlags(symbol, /*excludeTypeOnlyMeanings*/ true) & SymbolFlags.Value) && !isConstEnumOrConstEnumOnlyModule(target));
-
- if (markAlias) {
- markAliasSymbolAsReferenced(symbol);
- }
- }
- }
-
- // When an alias symbol is referenced, we need to mark the entity it references as referenced and in turn repeat that until
- // we reach a non-alias or an exported entity (which is always considered referenced). We do this by checking the target of
- // the alias as an expression (which recursively takes us back here if the target references another alias).
- function markAliasSymbolAsReferenced(symbol: Symbol) {
- Debug.assert(canCollectSymbolAliasAccessabilityData);
- const links = getSymbolLinks(symbol);
- if (!links.referenced) {
- links.referenced = true;
- const node = getDeclarationOfAliasSymbol(symbol);
- if (!node) return Debug.fail();
- // We defer checking of the reference of an `import =` until the import itself is referenced,
- // This way a chain of imports can be elided if ultimately the final input is only used in a type
- // position.
- if (isInternalModuleImportEqualsDeclaration(node)) {
- if (getSymbolFlags(resolveSymbol(symbol)) & SymbolFlags.Value) {
- // import foo =
- checkExpressionCached(node.moduleReference as Expression);
- }
- }
- }
- }
-
// This function is only for imports with entity names
function getSymbolOfPartOfRightHandSideOfImportEquals(entityName: EntityName, dontResolveAlias?: boolean): Symbol | undefined {
// There are three things we might try to look for. In the following examples,
@@ -4439,7 +4433,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
else {
Debug.assertNever(name, "Unknown entity name kind.");
}
- Debug.assert((getCheckFlags(symbol) & CheckFlags.Instantiated) === 0, "Should never get an instantiated symbol here.");
if (!nodeIsSynthesized(name) && isEntityName(name) && (symbol.flags & SymbolFlags.Alias || name.parent.kind === SyntaxKind.ExportAssignment)) {
markSymbolOfAliasDeclarationIfTypeOnly(getAliasDeclarationFromName(name), symbol, /*finalTarget*/ undefined, /*overwriteEmpty*/ true);
}
@@ -5889,8 +5882,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return { accessibility: SymbolAccessibility.Accessible };
}
+ if (!symbol) {
+ return {
+ accessibility: SymbolAccessibility.NotResolved,
+ errorSymbolName: getTextOfNode(firstIdentifier),
+ errorNode: firstIdentifier,
+ };
+ }
// Verify if the symbol is accessible
- return (symbol && hasVisibleDeclarations(symbol, shouldComputeAliasToMakeVisible)) || {
+ return hasVisibleDeclarations(symbol, shouldComputeAliasToMakeVisible) || {
accessibility: SymbolAccessibility.NotAccessible,
errorSymbolName: getTextOfNode(firstIdentifier),
errorNode: firstIdentifier,
@@ -5991,7 +5991,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function isClassInstanceSide(type: Type) {
return !!type.symbol && !!(type.symbol.flags & SymbolFlags.Class) && (type === getDeclaredTypeOfClassOrInterface(type.symbol) || (!!(type.flags & TypeFlags.Object) && !!(getObjectFlags(type) & ObjectFlags.IsClassInstanceClone)));
}
-
+ /**
+ * Same as getTypeFromTypeNode, but for use in createNodeBuilder
+ * Inside createNodeBuilder we shadow getTypeFromTypeNode to make sure anyone using this function will call the local version that does type mapping if appropriate
+ * This function is used to still be able to call the original getTypeFromTypeNode from the local scope version of getTypeFromTypeNode
+ */
+ function getTypeFromTypeNodeWithoutContext(node: TypeNode) {
+ return getTypeFromTypeNode(node);
+ }
function createNodeBuilder() {
return {
typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => typeToTypeNodeHelper(type, context)),
@@ -6010,6 +6017,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
symbolToNode: (symbol: Symbol, meaning: SymbolFlags, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => withContext(enclosingDeclaration, flags, tracker, context => symbolToNode(symbol, context, meaning)),
};
+ function getTypeFromTypeNode(context: NodeBuilderContext, node: TypeNode, noMappedTypes?: false): Type;
+ function getTypeFromTypeNode(context: NodeBuilderContext, node: TypeNode, noMappedTypes: true): Type | undefined;
+ function getTypeFromTypeNode(context: NodeBuilderContext, node: TypeNode, noMappedTypes?: boolean): Type | undefined {
+ const type = getTypeFromTypeNodeWithoutContext(node);
+ if (!context.mapper) return type;
+
+ const mappedType = instantiateType(type, context.mapper);
+ return noMappedTypes && mappedType !== type ? undefined : mappedType;
+ }
+
/**
* Unlike the utilities `setTextRange`, this checks if the `location` we're trying to set on `range` is within the
* same file as the active context. If not, the range is not applied. This prevents us from copying ranges across files,
@@ -6023,6 +6040,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (!nodeIsSynthesized(range) && !(range.flags & NodeFlags.Synthesized) && (!context.enclosingFile || context.enclosingFile !== getSourceFileOfNode(range))) {
range = factory.cloneNode(range);
}
+ if (range === location) return range;
if (!location) {
return range;
}
@@ -6078,7 +6096,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
const clone = tryReuseExistingNonParameterTypeNode(context, typeNode, type, host);
if (clone) {
- if (addUndefined && !someType(getTypeFromTypeNode(typeNode), t => !!(t.flags & TypeFlags.Undefined))) {
+ if (addUndefined && !someType(getTypeFromTypeNode(context, typeNode), t => !!(t.flags & TypeFlags.Undefined))) {
return factory.createUnionTypeNode([clone, factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]);
}
return clone;
@@ -6097,9 +6115,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
existing: TypeNode,
type: Type,
host = context.enclosingDeclaration,
- annotationType?: Type,
+ annotationType = getTypeFromTypeNode(context, existing, /*noMappedTypes*/ true),
) {
- if (typeNodeIsEquivalentToType(existing, host, type, annotationType) && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type)) {
+ if (annotationType && typeNodeIsEquivalentToType(host, type, annotationType) && existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type)) {
const result = tryReuseExistingTypeNodeHelper(context, existing);
if (result) {
return result;
@@ -6124,7 +6142,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function withContext(enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined, tracker: SymbolTracker | undefined, cb: (context: NodeBuilderContext) => T): T | undefined {
- Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & NodeFlags.Synthesized) === 0);
const moduleResolverHost = tracker?.trackSymbol ? tracker.moduleResolverHost :
flags! & NodeBuilderFlags.DoNotIncludeSymbolChain ? createBasicNodeBuilderModuleSpecifierResolutionHost(host) :
undefined;
@@ -6141,6 +6158,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
approximateLength: 0,
trackedSymbols: undefined,
bundled: !!compilerOptions.outFile && !!enclosingDeclaration && isExternalOrCommonJsModule(getSourceFileOfNode(enclosingDeclaration)),
+ truncating: false,
+ usedSymbolNames: undefined,
+ remappedSymbolNames: undefined,
+ remappedSymbolReferences: undefined,
+ reverseMappedStack: undefined,
+ mustCreateTypeParameterSymbolList: true,
+ typeParameterSymbolList: undefined,
+ mustCreateTypeParametersNamesLookups: true,
+ typeParameterNames: undefined,
+ typeParameterNamesByText: undefined,
+ typeParameterNamesByTextNextNameCount: undefined,
+ mapper: undefined,
};
context.tracker = new SymbolTrackerImpl(context, tracker, moduleResolverHost);
const resultingNode = cb(context);
@@ -6430,8 +6459,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
context.inferTypeParameters = type.root.inferTypeParameters;
const extendsTypeNode = typeToTypeNodeHelper(instantiateType(type.root.extendsType, newMapper), context);
context.inferTypeParameters = saveInferTypeParameters;
- const trueTypeNode = typeToTypeNodeOrCircularityElision(instantiateType(getTypeFromTypeNode(type.root.node.trueType), newMapper));
- const falseTypeNode = typeToTypeNodeOrCircularityElision(instantiateType(getTypeFromTypeNode(type.root.node.falseType), newMapper));
+ const trueTypeNode = typeToTypeNodeOrCircularityElision(instantiateType(getTypeFromTypeNode(context, type.root.node.trueType), newMapper));
+ const falseTypeNode = typeToTypeNodeOrCircularityElision(instantiateType(getTypeFromTypeNode(context, type.root.node.falseType), newMapper));
// outermost conditional makes `T` a type parameter, allowing the inner conditionals to be distributive
// second conditional makes `T` have `T & checkType` substitution, so it is correctly usable as the checkType
@@ -6528,7 +6557,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// homomorphic mapped type with a non-homomorphic naive inlining
// wrap it with a conditional like `SomeModifiersType extends infer U ? {..the mapped type...} : never` to ensure the resulting
// type stays homomorphic
- const originalConstraint = instantiateType(getConstraintOfTypeParameter(getTypeFromTypeNode((type.declaration.typeParameter.constraint! as TypeOperatorNode).type) as TypeParameter) || unknownType, type.mapper);
+ const originalConstraint = instantiateType(getConstraintOfTypeParameter(getTypeFromTypeNode(context, (type.declaration.typeParameter.constraint! as TypeOperatorNode).type) as TypeParameter) || unknownType, type.mapper);
return factory.createConditionalTypeNode(
typeToTypeNodeHelper(getModifiersTypeFromMappedType(type), context),
factory.createInferTypeNode(factory.createTypeParameterDeclaration(/*modifiers*/ undefined, factory.cloneNode(newTypeVariable!.typeName) as Identifier, originalConstraint.flags & TypeFlags.Unknown ? undefined : typeToTypeNodeHelper(originalConstraint, context))),
@@ -7210,11 +7239,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function signatureToSignatureDeclarationHelper(signature: Signature, kind: SignatureDeclaration["kind"], context: NodeBuilderContext, options?: SignatureToSignatureDeclarationOptions): SignatureDeclaration {
- const flags = context.flags;
- context.flags &= ~NodeBuilderFlags.SuppressAnyReturnType; // SuppressAnyReturnType should only apply to the signature `return` position
- context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum
let typeParameters: TypeParameterDeclaration[] | undefined;
let typeArguments: TypeNode[] | undefined;
+
+ const expandedParams = getExpandedParameters(signature, /*skipUnionExpanding*/ true)[0];
+ const cleanup = enterNewScope(context, signature.declaration, expandedParams, signature.typeParameters, signature.parameters, signature.mapper);
+ context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum
+
if (context.flags & NodeBuilderFlags.WriteTypeArgumentsOfSignature && signature.target && signature.mapper && signature.target.typeParameters) {
typeArguments = signature.target.typeParameters.map(parameter => typeToTypeNodeHelper(instantiateType(parameter, signature.mapper), context));
}
@@ -7222,9 +7253,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter, context));
}
- const expandedParams = getExpandedParameters(signature, /*skipUnionExpanding*/ true)[0];
- const cleanup = enterNewScope(context, signature.declaration, expandedParams, signature.typeParameters);
-
+ const flags = context.flags;
+ context.flags &= ~NodeBuilderFlags.SuppressAnyReturnType; // SuppressAnyReturnType should only apply to the signature `return` position
// If the expanded parameter list had a variadic in a non-trailing position, don't expand it
const parameters = (some(expandedParams, p => p !== expandedParams[expandedParams.length - 1] && !!(getCheckFlags(p) & CheckFlags.RestParameter)) ? signature.parameters : expandedParams).map(parameter => symbolToParameterDeclaration(parameter, context, kind === SyntaxKind.Constructor));
const thisParameter = context.flags & NodeBuilderFlags.OmitThisParameter ? undefined : tryGetThisParameterDeclaration(signature, context);
@@ -7284,10 +7314,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function getParametersInScope(node: IntroducesNewScopeNode | ConditionalTypeNode) {
- return isFunctionLike(node) || isJSDocSignature(node) ? getExpandedParameters(getSignatureFromDeclaration(node), /*skipUnionExpanding*/ true)[0] : undefined;
+ return isFunctionLike(node) || isJSDocSignature(node) ? getSignatureFromDeclaration(node).parameters : undefined;
}
- function enterNewScope(context: NodeBuilderContext, declaration: IntroducesNewScopeNode | ConditionalTypeNode | undefined, expandedParams: readonly Symbol[] | undefined, typeParameters: readonly TypeParameter[] | undefined) {
+ function enterNewScope(
+ context: NodeBuilderContext,
+ declaration: IntroducesNewScopeNode | ConditionalTypeNode | undefined,
+ expandedParams: readonly Symbol[] | undefined,
+ typeParameters: readonly TypeParameter[] | undefined,
+ originalParameters?: readonly Symbol[] | undefined,
+ mapper?: TypeMapper,
+ ) {
+ const cleanupContext = cloneNodeBuilderContext(context);
// For regular function/method declarations, the enclosing declaration will already be signature.declaration,
// so this is a no-op, but for arrow functions and function expressions, the enclosing declaration will be
// the declaration that the arrow function / function expression is assigned to.
@@ -7300,17 +7338,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// accessible to the current enclosing declaration, or gain access to symbols not accessible to the current
// enclosing declaration. To keep this chain accurate, insert a fake scope into the chain which makes the
// function's parameters visible.
- //
- // If the declaration is in a JS file, then we don't need to do this at all, as there are no annotations besides
- // JSDoc, which are always outside the function declaration, so are not in the parameter scope.
- let cleanup: (() => void) | undefined;
- if (
- context.enclosingDeclaration
- && declaration
- && declaration !== context.enclosingDeclaration
- && !isInJSFile(declaration)
- && (some(expandedParams) || some(typeParameters))
- ) {
+ let cleanupParams: (() => void) | undefined;
+ let cleanupTypeParams: (() => void) | undefined;
+ const oldEnclosingDecl = context.enclosingDeclaration;
+ const oldMapper = context.mapper;
+ if (mapper) {
+ context.mapper = mapper;
+ }
+ if (context.enclosingDeclaration && declaration) {
// As a performance optimization, reuse the same fake scope within this chain.
// This is especially needed when we are working on an excessively deep type;
// if we don't do this, then we spend all of our time adding more and more
@@ -7327,11 +7362,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// Note that we only check the most immediate enclosingDeclaration; the only place we
// could potentially add another fake scope into the chain is right here, so we don't
// traverse all ancestors.
- pushFakeScope(
+ cleanupParams = !some(expandedParams) ? undefined : pushFakeScope(
"params",
add => {
- for (const param of expandedParams ?? emptyArray) {
- if (
+ if (!expandedParams) return;
+ for (let pIndex = 0; pIndex < expandedParams.length; pIndex++) {
+ const param = expandedParams[pIndex];
+ const originalParam = originalParameters?.[pIndex];
+ if (originalParameters && originalParam !== param) {
+ // Can't reference parameters that come from an expansion
+ add(param.escapedName, unknownSymbol);
+ // Can't reference the original expanded parameter either
+ if (originalParam) {
+ add(originalParam.escapedName, unknownSymbol);
+ }
+ }
+ else if (
!forEach(param.declarations, d => {
if (isParameter(d) && isBindingPattern(d.name)) {
bindPattern(d.name);
@@ -7365,9 +7411,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
},
);
- if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams) {
- // TODO(jakebailey): should this instead be done before walking type parameters?
- pushFakeScope(
+ if (context.flags & NodeBuilderFlags.GenerateNamesForShadowedTypeParams && some(typeParameters)) {
+ cleanupTypeParams = pushFakeScope(
"typeParams",
add => {
for (const typeParam of typeParameters ?? emptyArray) {
@@ -7378,8 +7423,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
);
}
- return cleanup;
-
function pushFakeScope(kind: "params" | "typeParams", addAll: (addSymbol: (name: __String, symbol: Symbol) => void) => void) {
// We only ever need to look two declarations upward.
Debug.assert(context.enclosingDeclaration);
@@ -7394,41 +7437,48 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const locals = existingFakeScope?.locals ?? createSymbolTable();
let newLocals: __String[] | undefined;
+ let oldLocals: { name: __String; oldSymbol: Symbol; }[] | undefined;
addAll((name, symbol) => {
- if (!locals.has(name)) {
- newLocals = append(newLocals, name);
- locals.set(name, symbol);
+ // Add cleanup information only if we don't own the fake scope
+ if (existingFakeScope) {
+ const oldSymbol = locals.get(name);
+ if (!oldSymbol) {
+ newLocals = append(newLocals, name);
+ }
+ else {
+ oldLocals = append(oldLocals, { name, oldSymbol });
+ }
}
+ locals.set(name, symbol);
});
- if (!newLocals) return;
- const oldCleanup = cleanup;
- function undo() {
- forEach(newLocals, s => locals.delete(s));
- oldCleanup?.();
- }
-
- if (existingFakeScope) {
- cleanup = undo;
- }
- else {
+ if (!existingFakeScope) {
// Use a Block for this; the type of the node doesn't matter so long as it
// has locals, and this is cheaper/easier than using a function-ish Node.
- const fakeScope = parseNodeFactory.createBlock(emptyArray);
+ const fakeScope = factory.createBlock(emptyArray);
getNodeLinks(fakeScope).fakeScopeForSignatureDeclaration = kind;
fakeScope.locals = locals;
- const saveEnclosingDeclaration = context.enclosingDeclaration;
- setParent(fakeScope, saveEnclosingDeclaration);
+ setParent(fakeScope, context.enclosingDeclaration);
context.enclosingDeclaration = fakeScope;
-
- cleanup = () => {
- context.enclosingDeclaration = saveEnclosingDeclaration;
- undo();
+ }
+ else {
+ // We did not create the current scope, so we have to clean it up
+ return function undo() {
+ forEach(newLocals, s => locals.delete(s));
+ forEach(oldLocals, s => locals.set(s.name, s.oldSymbol));
};
}
}
}
+
+ return () => {
+ cleanupParams?.();
+ cleanupTypeParams?.();
+ cleanupContext();
+ context.enclosingDeclaration = oldEnclosingDecl;
+ context.mapper = oldMapper;
+ };
}
function tryGetThisParameterDeclaration(signature: Signature, context: NodeBuilderContext) {
@@ -7443,7 +7493,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
/*dotDotDotToken*/ undefined,
"this",
/*questionToken*/ undefined,
- typeToTypeNodeHelper(getTypeFromTypeNode(thisTag.typeExpression), context),
+ typeToTypeNodeHelper(getTypeFromTypeNode(context, thisTag.typeExpression), context),
);
}
}
@@ -7460,8 +7510,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return factory.createTypeParameterDeclaration(modifiers, name, constraintNode, defaultParameterNode);
}
+ function typeToTypeNodeHelperWithPossibleReusableTypeNode(type: Type, typeNode: TypeNode | undefined, context: NodeBuilderContext) {
+ return typeNode && tryReuseExistingNonParameterTypeNode(context, typeNode, type) || typeToTypeNodeHelper(type, context);
+ }
+
function typeParameterToDeclaration(type: TypeParameter, context: NodeBuilderContext, constraint = getConstraintOfTypeParameter(type)): TypeParameterDeclaration {
- const constraintNode = constraint && typeToTypeNodeHelper(constraint, context);
+ const constraintNode = constraint && typeToTypeNodeHelperWithPossibleReusableTypeNode(constraint, getConstraintDeclaration(type), context);
return typeParameterToDeclarationWithConstraint(type, context, constraintNode);
}
@@ -7661,7 +7715,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (context.typeParameterSymbolList?.has(symbolId)) {
return undefined;
}
- (context.typeParameterSymbolList || (context.typeParameterSymbolList = new Set())).add(symbolId);
+ if (context.mustCreateTypeParameterSymbolList) {
+ context.mustCreateTypeParameterSymbolList = false;
+ context.typeParameterSymbolList = new Set(context.typeParameterSymbolList);
+ }
+ context.typeParameterSymbolList!.add(symbolId);
let typeParameterNodes: readonly TypeNode[] | readonly TypeParameterDeclaration[] | undefined;
if (context.flags & NodeBuilderFlags.WriteTypeParametersInQualifiedName && index < (chain.length - 1)) {
const parentSymbol = symbol;
@@ -7946,11 +8004,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
result = factory.createIdentifier(text);
setIdentifierTypeArguments(result, typeArguments);
}
+ if (context.mustCreateTypeParametersNamesLookups) {
+ context.mustCreateTypeParametersNamesLookups = false;
+ context.typeParameterNames = new Map(context.typeParameterNames);
+ context.typeParameterNamesByTextNextNameCount = new Map(context.typeParameterNamesByTextNextNameCount);
+ context.typeParameterNamesByText = new Set(context.typeParameterNamesByText);
+ }
// avoiding iterations of the above loop turns out to be worth it when `i` starts to get large, so we cache the max
// `i` we've used thus far, to save work later
- (context.typeParameterNamesByTextNextNameCount ||= new Map()).set(rawtext, i);
- (context.typeParameterNames ||= new Map()).set(getTypeId(type), result);
- (context.typeParameterNamesByText ||= new Set()).add(text);
+ context.typeParameterNamesByTextNextNameCount!.set(rawtext, i);
+ context.typeParameterNames!.set(getTypeId(type), result);
+ context.typeParameterNamesByText!.add(text);
}
return result;
}
@@ -8093,8 +8157,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
- function cloneNodeBuilderContext(context: NodeBuilderContext): NodeBuilderContext {
- const initial: NodeBuilderContext = { ...context };
+ function cloneNodeBuilderContext(context: NodeBuilderContext) {
// Make type parameters created within this context not consume the name outside this context
// The symbol serializer ends up creating many sibling scopes that all need "separate" contexts when
// it comes to naming things - within a normal `typeToTypeNode` call, the node builder only ever descends
@@ -8107,23 +8170,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// we write it out like that, rather than as
// export const x: (x: T) => T
// export const y: (x: T_1) => T_1
- if (initial.typeParameterNames) {
- initial.typeParameterNames = new Map(initial.typeParameterNames);
- }
- if (initial.typeParameterNamesByText) {
- initial.typeParameterNamesByText = new Set(initial.typeParameterNamesByText);
- }
- if (initial.typeParameterSymbolList) {
- initial.typeParameterSymbolList = new Set(initial.typeParameterSymbolList);
- }
- if (initial.typeParameterNamesByTextNextNameCount) {
- initial.typeParameterNamesByTextNextNameCount = new Map(initial.typeParameterNamesByTextNextNameCount);
- }
- initial.tracker = new SymbolTrackerImpl(initial, initial.tracker.inner, initial.tracker.moduleResolverHost);
- return initial;
+ const oldMustCreateTypeParameterSymbolList = context.mustCreateTypeParameterSymbolList;
+ const oldMustCreateTypeParametersNamesLookups = context.mustCreateTypeParametersNamesLookups;
+ context.mustCreateTypeParameterSymbolList = true;
+ context.mustCreateTypeParametersNamesLookups = true;
+ const oldTypeParameterNames = context.typeParameterNames;
+ const oldTypeParameterNamesByText = context.typeParameterNamesByText;
+ const oldTypeParameterNamesByTextNextNameCount = context.typeParameterNamesByTextNextNameCount;
+ const oldTypeParameterSymbolList = context.typeParameterSymbolList;
+ return () => {
+ context.typeParameterNames = oldTypeParameterNames;
+ context.typeParameterNamesByText = oldTypeParameterNamesByText;
+ context.typeParameterNamesByTextNextNameCount = oldTypeParameterNamesByTextNextNameCount;
+ context.typeParameterSymbolList = oldTypeParameterSymbolList;
+ context.mustCreateTypeParameterSymbolList = oldMustCreateTypeParameterSymbolList;
+ context.mustCreateTypeParametersNamesLookups = oldMustCreateTypeParametersNamesLookups;
+ };
}
- function getDeclarationWithTypeAnnotation(symbol: Symbol, enclosingDeclaration: Node | undefined) {
+ function getDeclarationWithTypeAnnotation(symbol: Symbol, enclosingDeclaration?: Node | undefined) {
return symbol.declarations && find(symbol.declarations, s => !!getNonlocalEffectiveTypeAnnotationNode(s) && (!enclosingDeclaration || !!findAncestor(s, n => n === enclosingDeclaration)));
}
@@ -8158,20 +8223,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function serializeTypeForDeclaration(context: NodeBuilderContext, declaration: Declaration | undefined, type: Type, symbol: Symbol) {
const addUndefined = declaration && (isParameter(declaration) || isJSDocParameterTag(declaration)) && requiresAddingImplicitUndefined(declaration);
const enclosingDeclaration = context.enclosingDeclaration;
- if (!isErrorType(type) && enclosingDeclaration) {
+ const oldFlags = context.flags;
+ if (declaration && hasInferredType(declaration) && !(context.flags & NodeBuilderFlags.NoSyntacticPrinter)) {
+ syntacticNodeBuilder.serializeTypeOfDeclaration(declaration, context);
+ }
+ context.flags |= NodeBuilderFlags.NoSyntacticPrinter;
+ if (enclosingDeclaration && (!isErrorType(type) || (context.flags & NodeBuilderFlags.AllowUnresolvedNames))) {
const declWithExistingAnnotation = declaration && getNonlocalEffectiveTypeAnnotationNode(declaration)
? declaration
- : getDeclarationWithTypeAnnotation(symbol, getEnclosingDeclarationIgnoringFakeScope(enclosingDeclaration));
+ : getDeclarationWithTypeAnnotation(symbol);
if (declWithExistingAnnotation && !isFunctionLikeDeclaration(declWithExistingAnnotation) && !isGetAccessorDeclaration(declWithExistingAnnotation)) {
// try to reuse the existing annotation
const existing = getNonlocalEffectiveTypeAnnotationNode(declWithExistingAnnotation)!;
- const result = tryReuseExistingTypeNode(context, existing, type, declWithExistingAnnotation, addUndefined);
+ const result = !isTypePredicateNode(existing) && tryReuseExistingTypeNode(context, existing, type, declWithExistingAnnotation, addUndefined);
if (result) {
+ context.flags = oldFlags;
return result;
}
}
}
- const oldFlags = context.flags;
if (
type.flags & TypeFlags.UniqueESSymbol &&
type.symbol === symbol && (!context.enclosingDeclaration || some(symbol.declarations, d => getSourceFileOfNode(d) === getSourceFileOfNode(context.enclosingDeclaration!)))
@@ -8182,16 +8252,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const decl = declaration ?? symbol.valueDeclaration ?? symbol.declarations?.[0];
const expr = decl && isDeclarationWithPossibleInnerTypeNodeReuse(decl) ? getPossibleTypeNodeReuseExpression(decl) : undefined;
- if (decl && hasInferredType(decl) && !(context.flags & NodeBuilderFlags.NoSyntacticPrinter)) {
- syntacticNodeBuilder.serializeTypeOfDeclaration(decl, context);
- }
- context.flags |= NodeBuilderFlags.NoSyntacticPrinter;
const result = expressionOrTypeToTypeNode(context, expr, type, addUndefined);
context.flags = oldFlags;
return result;
}
- function typeNodeIsEquivalentToType(typeNode: TypeNode, annotatedDeclaration: Node | undefined, type: Type, typeFromTypeNode = getTypeFromTypeNode(typeNode)) {
+ function typeNodeIsEquivalentToType(annotatedDeclaration: Node | undefined, type: Type, typeFromTypeNode: Type) {
if (typeFromTypeNode === type) {
return true;
}
@@ -8224,13 +8290,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function serializeReturnTypeForSignatureWorker(context: NodeBuilderContext, signature: Signature) {
const typePredicate = getTypePredicateOfSignature(signature);
const type = getReturnTypeOfSignature(signature);
- if (!isErrorType(type) && context.enclosingDeclaration) {
+ if (context.enclosingDeclaration && (!isErrorType(type) || (context.flags & NodeBuilderFlags.AllowUnresolvedNames)) && signature.declaration && !nodeIsSynthesized(signature.declaration)) {
const annotation = signature.declaration && getNonlocalEffectiveReturnTypeAnnotationNode(signature.declaration);
- const enclosingDeclarationIgnoringFakeScope = getEnclosingDeclarationIgnoringFakeScope(context.enclosingDeclaration);
- if (!!findAncestor(annotation, n => n === enclosingDeclarationIgnoringFakeScope) && annotation) {
- const annotated = getTypeFromTypeNode(annotation);
- const thisInstantiated = annotated.flags & TypeFlags.TypeParameter && (annotated as TypeParameter).isThisType ? instantiateType(annotated, signature.mapper) : annotated;
- const result = tryReuseExistingNonParameterTypeNode(context, annotation, type, signature.declaration, thisInstantiated);
+ // Default constructor signatures inherited from base classes return the derived class but have the base class declaration
+ // To ensure we don't serialize the wrong type we check that that return type of the signature corresponds to the declaration return type signature
+ if (annotation && getTypeFromTypeNode(context, annotation) === type) {
+ const result = tryReuseExistingTypeNodeHelper(context, annotation);
if (result) {
return result;
}
@@ -8262,21 +8327,50 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return { introducesError, node: attachSymbolToLeftmostIdentifier(node) as T };
}
sym = resolveEntityName(leftmost, meaning, /*ignoreErrors*/ true, /*dontResolveAlias*/ true);
+ if (
+ context.enclosingDeclaration &&
+ !(sym && sym.flags & SymbolFlags.TypeParameter)
+ ) {
+ sym = getExportSymbolOfValueSymbolIfExported(sym);
+ // Some declarations may be transplanted to a new location.
+ // When this happens we need to make sure that the name has the same meaning at both locations
+ // We also check for the unknownSymbol because when we create a fake scope some parameters may actually not be usable
+ // either because they are the expanded rest parameter,
+ // or because they are the newly added parameters from the tuple, which might have different meanings in the original context
+ const symAtLocation = resolveEntityName(leftmost, meaning, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, context.enclosingDeclaration);
+ if (
+ // Check for unusable parameters symbols
+ symAtLocation === unknownSymbol ||
+ // If the symbol is not found, but was not found in the original scope either we probably have an error, don't reuse the node
+ (symAtLocation === undefined && sym !== undefined) ||
+ // If the symbol is found both in declaration scope and in current scope then it shoudl point to the same reference
+ (symAtLocation && sym && !getSymbolIfSameReference(getExportSymbolOfValueSymbolIfExported(symAtLocation), sym))
+ ) {
+ // In isolated declaration we will not do rest parameter expansion so there is no need to report on these.
+ if (symAtLocation !== unknownSymbol) {
+ context.tracker.reportInferenceFallback(node);
+ }
+ introducesError = true;
+ return { introducesError, node, sym };
+ }
+ }
+
if (sym) {
// If a parameter is resolvable in the current context it is also visible, so no need to go to symbol accesibility
if (
sym.flags & SymbolFlags.FunctionScopedVariable
&& sym.valueDeclaration
) {
- if (isPartOfParameterDeclaration(sym.valueDeclaration)) {
+ if (isPartOfParameterDeclaration(sym.valueDeclaration) || isJSDocParameterTag(sym.valueDeclaration)) {
return { introducesError, node: attachSymbolToLeftmostIdentifier(node) as T };
}
}
if (
- !(sym.flags & SymbolFlags.TypeParameter) && // Type parameters are visible in the curent context if they are are resolvable
+ !(sym.flags & SymbolFlags.TypeParameter) && // Type parameters are visible in the current context if they are are resolvable
!isDeclarationName(node) &&
isSymbolAccessible(sym, context.enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== SymbolAccessibility.Accessible
) {
+ context.tracker.reportInferenceFallback(node);
introducesError = true;
}
else {
@@ -8306,6 +8400,70 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
+ function serializeTypeName(context: NodeBuilderContext, node: EntityName, isTypeOf?: boolean, typeArguments?: readonly TypeNode[]) {
+ const meaning = isTypeOf ? SymbolFlags.Value : SymbolFlags.Type;
+ const symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true);
+ if (!symbol) return undefined;
+ const resolvedSymbol = symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol;
+ if (isSymbolAccessible(symbol, context.enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ false).accessibility !== SymbolAccessibility.Accessible) return undefined;
+ return symbolToTypeNode(resolvedSymbol, context, meaning, typeArguments);
+ }
+
+ function canReuseTypeNode(context: NodeBuilderContext, existing: TypeNode) {
+ if (isInJSFile(existing)) {
+ if (isLiteralImportTypeNode(existing)) {
+ // Ensure resolvedSymbol is present
+ void getTypeFromImportTypeNode(existing);
+ const nodeSymbol = getNodeLinks(existing).resolvedSymbol;
+ return (
+ !nodeSymbol ||
+ !(
+ // The import type resolved using jsdoc fallback logic
+ (!existing.isTypeOf && !(nodeSymbol.flags & SymbolFlags.Type)) ||
+ // The import type had type arguments autofilled by js fallback logic
+ !(length(existing.typeArguments) >= getMinTypeArgumentCount(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(nodeSymbol)))
+ )
+ );
+ }
+ }
+ if (isThisTypeNode(existing)) {
+ if (context.mapper === undefined) return true;
+ const type = getTypeFromTypeNode(context, existing, /*noMappedTypes*/ true);
+ return !!type;
+ }
+ if (isTypeReferenceNode(existing)) {
+ if (isConstTypeReference(existing)) return false;
+ const type = getTypeFromTypeReference(existing);
+ const symbol = getNodeLinks(existing).resolvedSymbol;
+ if (!symbol) return false;
+ if (symbol.flags & SymbolFlags.TypeParameter) {
+ const type = getDeclaredTypeOfSymbol(symbol);
+ if (context.mapper && getMappedType(type, context.mapper) !== type) {
+ return false;
+ }
+ }
+ if (isInJSDoc(existing)) {
+ return existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing, type)
+ && !getIntendedTypeFromJSDocTypeReference(existing) // We should probably allow the reuse of JSDoc reference types such as String Number etc
+ && (symbol.flags & SymbolFlags.Type); // JSDoc type annotations can reference values (meaning typeof value) as well as types. We only reuse type nodes
+ }
+ }
+ if (
+ isTypeOperatorNode(existing) &&
+ existing.operator === SyntaxKind.UniqueKeyword &&
+ existing.type.kind === SyntaxKind.SymbolKeyword
+ ) {
+ const effectiveEnclosingContext = context.enclosingDeclaration && getEnclosingDeclarationIgnoringFakeScope(context.enclosingDeclaration);
+ return !!findAncestor(existing, n => n === effectiveEnclosingContext);
+ }
+ return true;
+ }
+
+ function serializeExistingTypeNode(context: NodeBuilderContext, typeNode: TypeNode) {
+ const type = getTypeFromTypeNode(context, typeNode);
+ return typeToTypeNodeHelper(type, context);
+ }
+
/**
* Do you mean to call this directly? You probably should use `tryReuseExistingTypeNode` instead,
* which performs sanity checking on the type before doing this.
@@ -8315,16 +8473,30 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
cancellationToken.throwIfCancellationRequested();
}
let hadError = false;
+ const { finalizeBoundary, startRecoveryScope } = createRecoveryBoundary();
const transformed = visitNode(existing, visitExistingNodeTreeSymbols, isTypeNode);
- if (hadError) {
+ if (!finalizeBoundary()) {
return undefined;
}
+ context.approximateLength += existing.end - existing.pos;
return transformed;
function visitExistingNodeTreeSymbols(node: Node): Node | undefined {
+ // If there was an error in a sibling node bail early, the result will be discarded anyway
+ if (hadError) return node;
+ const recover = startRecoveryScope();
const onExitNewScope = isNewScopeNode(node) ? onEnterNewScope(node) : undefined;
const result = visitExistingNodeTreeSymbolsWorker(node);
onExitNewScope?.();
+
+ // If there was an error, maybe we can recover by serializing the actual type of the node
+ if (hadError) {
+ if (isTypeNode(node) && !isTypePredicateNode(node)) {
+ recover();
+ return serializeExistingTypeNode(context, node);
+ }
+ return node;
+ }
// We want to clone the subtree, so when we mark it up with __pos and __end in quickfixes,
// we don't get odd behavior because of reused nodes. We also need to clone to _remove_
// the position information if the node comes from a different file than the one the node builder
@@ -8334,20 +8506,117 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return result === node ? setTextRange(context, factory.cloneNode(result), node) : result;
}
+ function createRecoveryBoundary() {
+ let unreportedErrors: (() => void)[];
+ const oldTracker = context.tracker;
+ const oldTrackedSymbols = context.trackedSymbols;
+ context.trackedSymbols = [];
+ const oldEncounteredError = context.encounteredError;
+ context.tracker = new SymbolTrackerImpl(context, {
+ ...oldTracker.inner,
+ reportCyclicStructureError() {
+ markError(() => oldTracker.reportCyclicStructureError());
+ },
+ reportInaccessibleThisError() {
+ markError(() => oldTracker.reportInaccessibleThisError());
+ },
+ reportInaccessibleUniqueSymbolError() {
+ markError(() => oldTracker.reportInaccessibleUniqueSymbolError());
+ },
+ reportLikelyUnsafeImportRequiredError(specifier) {
+ markError(() => oldTracker.reportLikelyUnsafeImportRequiredError(specifier));
+ },
+ reportNonSerializableProperty(name) {
+ markError(() => oldTracker.reportNonSerializableProperty(name));
+ },
+ trackSymbol(sym, decl, meaning) {
+ const accessibility = isSymbolAccessible(sym, decl, meaning, /*shouldComputeAliasesToMakeVisible*/ false);
+ if (accessibility.accessibility !== SymbolAccessibility.Accessible) {
+ (context.trackedSymbols ??= []).push([sym, decl, meaning]);
+ return true;
+ }
+ return false;
+ },
+ moduleResolverHost: context.tracker.moduleResolverHost,
+ }, context.tracker.moduleResolverHost);
+
+ return {
+ startRecoveryScope,
+ finalizeBoundary,
+ };
+
+ function markError(unreportedError: () => void) {
+ hadError = true;
+ (unreportedErrors ??= []).push(unreportedError);
+ }
+
+ function startRecoveryScope() {
+ const initialTrackedSymbolsTop = context.trackedSymbols?.length ?? 0;
+ const unreportedErrorsTop = unreportedErrors?.length ?? 0;
+ return () => {
+ hadError = false;
+ // Reset the tracked symbols to before the error
+ if (context.trackedSymbols) {
+ context.trackedSymbols.length = initialTrackedSymbolsTop;
+ }
+ if (unreportedErrors) {
+ unreportedErrors.length = unreportedErrorsTop;
+ }
+ };
+ }
+
+ function finalizeBoundary() {
+ context.tracker = oldTracker;
+ const newTrackedSymbols = context.trackedSymbols;
+ context.trackedSymbols = oldTrackedSymbols;
+ context.encounteredError = oldEncounteredError;
+
+ unreportedErrors?.forEach(fn => fn());
+ if (hadError) {
+ return false;
+ }
+ newTrackedSymbols?.forEach(
+ ([symbol, enclosingDeclaration, meaning]) =>
+ context.tracker.trackSymbol(
+ symbol,
+ enclosingDeclaration,
+ meaning,
+ ),
+ );
+ return true;
+ }
+ }
function onEnterNewScope(node: IntroducesNewScopeNode | ConditionalTypeNode) {
- const oldContex = context;
- context = cloneNodeBuilderContext(context);
- const cleanup = enterNewScope(context, node, getParametersInScope(node), getTypeParametersInScope(node));
+ return enterNewScope(context, node, getParametersInScope(node), getTypeParametersInScope(node));
+ }
- return onExitNewScope;
+ function tryVisitTypeReference(node: TypeReferenceNode) {
+ if (canReuseTypeNode(context, node)) {
+ const { introducesError, node: newName } = trackExistingEntityName(node.typeName, context);
+ const typeArguments = visitNodes(node.typeArguments, visitExistingNodeTreeSymbols, isTypeNode);
- function onExitNewScope() {
- cleanup?.();
- context = oldContex;
+ if (!introducesError) {
+ const updated = factory.updateTypeReferenceNode(
+ node,
+ newName,
+ typeArguments,
+ );
+ return setTextRange(context, updated, node);
+ }
+ else {
+ const serializedName = serializeTypeName(context, node.typeName, /*isTypeOf*/ false, typeArguments);
+ if (serializedName) {
+ return setTextRange(context, serializedName, node.typeName);
+ }
+ }
}
}
function visitExistingNodeTreeSymbolsWorker(node: Node): Node | undefined {
+ if (isJSDocTypeExpression(node)) {
+ // Unwrap JSDocTypeExpressions
+ return visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode);
+ }
// We don't _actually_ support jsdoc namepath types, emit `any` instead
if (isJSDocAllType(node) || node.kind === SyntaxKind.JSDocNamepathType) {
return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
@@ -8370,8 +8639,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (isJSDocTypeLiteral(node)) {
return factory.createTypeLiteralNode(map(node.jsDocPropertyTags, t => {
const name = isIdentifier(t.name) ? t.name : t.name.right;
- const typeViaParent = getTypeOfPropertyOfType(getTypeFromTypeNode(node), name.escapedText);
- const overrideTypeNode = typeViaParent && t.typeExpression && getTypeFromTypeNode(t.typeExpression.type) !== typeViaParent ? typeToTypeNodeHelper(typeViaParent, context) : undefined;
+ const typeViaParent = getTypeOfPropertyOfType(getTypeFromTypeNode(context, node), name.escapedText);
+ const overrideTypeNode = typeViaParent && t.typeExpression && getTypeFromTypeNode(context, t.typeExpression.type) !== typeViaParent ? typeToTypeNodeHelper(typeViaParent, context) : undefined;
return factory.createPropertySignature(
/*modifiers*/ undefined,
@@ -8407,7 +8676,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
p.name && isIdentifier(p.name) && p.name.escapedText === "new" ? (newTypeNode = p.type, undefined) : factory.createParameterDeclaration(
/*modifiers*/ undefined,
getEffectiveDotDotDotForParameter(p),
- getNameForJSDocFunctionParameter(p, i),
+ setTextRange(context, factory.createIdentifier(getNameForJSDocFunctionParameter(p, i)), p),
p.questionToken,
visitNode(p.type, visitExistingNodeTreeSymbols, isTypeNode),
/*initializer*/ undefined,
@@ -8422,7 +8691,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
factory.createParameterDeclaration(
/*modifiers*/ undefined,
getEffectiveDotDotDotForParameter(p),
- getNameForJSDocFunctionParameter(p, i),
+ setTextRange(context, factory.createIdentifier(getNameForJSDocFunctionParameter(p, i)), p),
p.questionToken,
visitNode(p.type, visitExistingNodeTreeSymbols, isTypeNode),
/*initializer*/ undefined,
@@ -8431,8 +8700,39 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
);
}
}
- if (isTypeReferenceNode(node) && isInJSDoc(node) && (!existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(node, getTypeFromTypeNode(node)) || getIntendedTypeFromJSDocTypeReference(node) || unknownSymbol === resolveTypeReferenceName(node, SymbolFlags.Type, /*ignoreErrors*/ true))) {
- return setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node);
+ if (isThisTypeNode(node)) {
+ if (canReuseTypeNode(context, node)) {
+ return node;
+ }
+ hadError = true;
+ return node;
+ }
+ if (isTypeParameterDeclaration(node)) {
+ return factory.updateTypeParameterDeclaration(
+ node,
+ node.modifiers,
+ setTextRange(context, typeParameterToName(getDeclaredTypeOfSymbol(getSymbolOfDeclaration(node)), context), node),
+ visitNode(node.constraint, visitExistingNodeTreeSymbols, isTypeNode),
+ visitNode(node.default, visitExistingNodeTreeSymbols, isTypeNode),
+ );
+ }
+
+ if (isIndexedAccessTypeNode(node) && isTypeReferenceNode(node.objectType)) {
+ const objectType = tryVisitTypeReference(node.objectType);
+ if (!objectType) {
+ hadError = true;
+ return node;
+ }
+ return factory.updateIndexedAccessTypeNode(node, objectType, visitNode(node.indexType, visitExistingNodeTreeSymbols, isTypeNode)!);
+ }
+
+ if (isTypeReferenceNode(node)) {
+ const result = tryVisitTypeReference(node);
+ if (result) {
+ return result;
+ }
+ hadError = true;
+ return node;
}
if (isLiteralImportTypeNode(node)) {
const nodeSymbol = getNodeLinks(node).resolvedSymbol;
@@ -8446,7 +8746,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
!(length(node.typeArguments) >= getMinTypeArgumentCount(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(nodeSymbol)))
)
) {
- return setOriginalNode(typeToTypeNodeHelper(getTypeFromTypeNode(node), context), node);
+ return setTextRange(context, typeToTypeNodeHelper(getTypeFromTypeNode(context, node), context), node);
}
return factory.updateImportTypeNode(
node,
@@ -8458,7 +8758,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
);
}
if (isNamedDeclaration(node) && node.name.kind === SyntaxKind.ComputedPropertyName && !isLateBindableName(node.name)) {
- return undefined;
+ if (!(context.flags & NodeBuilderFlags.AllowUnresolvedNames && hasDynamicName(node) && isEntityNameExpression(node.name.expression) && checkComputedPropertyName(node.name).flags & TypeFlags.Any)) {
+ return undefined;
+ }
}
if (
(isFunctionLike(node) && !node.type)
@@ -8476,15 +8778,55 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
return visited;
}
-
- if (isEntityName(node) || isEntityNameExpression(node)) {
- if (isDeclarationName(node)) {
+ if (isTypeQueryNode(node)) {
+ const { introducesError, node: exprName } = trackExistingEntityName(node.exprName, context);
+ if (introducesError) {
+ const serializedName = serializeTypeName(context, node.exprName, /*isTypeOf*/ true);
+ if (serializedName) {
+ return setTextRange(context, serializedName, node.exprName);
+ }
+ hadError = true;
return node;
}
- const { introducesError, node: result } = trackExistingEntityName(node, context);
- hadError = hadError || introducesError;
- // We should not go to child nodes of the entity name, they will not be accessible
- return result;
+ return factory.updateTypeQueryNode(
+ node,
+ exprName,
+ visitNodes(node.typeArguments, visitExistingNodeTreeSymbols, isTypeNode),
+ );
+ }
+ if (isComputedPropertyName(node) && isEntityNameExpression(node.expression)) {
+ const { node: result, introducesError } = trackExistingEntityName(node.expression, context);
+ if (!introducesError) {
+ return factory.updateComputedPropertyName(node, result);
+ }
+ else {
+ const type = getWidenedType(getRegularTypeOfExpression(node.expression));
+ const computedPropertyNameType = typeToTypeNodeHelper(type, context);
+ Debug.assertNode(computedPropertyNameType, isLiteralTypeNode);
+ const literal = computedPropertyNameType.literal;
+ if (literal.kind === SyntaxKind.StringLiteral && isIdentifierText(literal.text, getEmitScriptTarget(compilerOptions))) {
+ return factory.createIdentifier(literal.text);
+ }
+ if (literal.kind === SyntaxKind.NumericLiteral && !literal.text.startsWith("-")) {
+ return literal;
+ }
+ return factory.updateComputedPropertyName(node, literal);
+ }
+ }
+ if (isTypePredicateNode(node)) {
+ let parameterName;
+ if (isIdentifier(node.parameterName)) {
+ const { node: result, introducesError } = trackExistingEntityName(node.parameterName, context);
+ // Should not usually happen the only case is when a type predicate comes from a JSDoc type annotation with it's own parameter symbol definition.
+ // /** @type {(v: unknown) => v is undefined} */
+ // const isUndef = v => v === undefined;
+ hadError = hadError || introducesError;
+ parameterName = result;
+ }
+ else {
+ parameterName = node.parameterName;
+ }
+ return factory.updateTypePredicateNode(node, node.assertsModifier, parameterName, visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode));
}
if (isTupleTypeNode(node) || isTypeLiteralNode(node) || isMappedTypeNode(node)) {
@@ -8516,6 +8858,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
);
}
+ if (isTypeOperatorNode(node)) {
+ if (node.operator === SyntaxKind.UniqueKeyword && node.type.kind === SyntaxKind.SymbolKeyword) {
+ if (!canReuseTypeNode(context, node)) {
+ hadError = true;
+ return node;
+ }
+ }
+ else if (node.operator === SyntaxKind.KeyOfKeyword) {
+ if (isTypeReferenceNode(node.type)) {
+ const type = tryVisitTypeReference(node.type);
+ if (!type) {
+ hadError = true;
+ return node;
+ }
+ return factory.updateTypeOperatorNode(node, type);
+ }
+ }
+ }
+
return visitEachChild(node, visitExistingNodeTreeSymbols, /*context*/ undefined);
function getEffectiveDotDotDotForParameter(p: ParameterDeclaration) {
@@ -8531,13 +8892,30 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function rewriteModuleSpecifier(parent: ImportTypeNode, lit: StringLiteral) {
if (context.bundled || context.enclosingFile !== getSourceFileOfNode(lit)) {
- const targetFile = getExternalModuleFileFromDeclaration(parent);
- if (targetFile) {
- const newName = getSpecifierForModuleSymbol(targetFile.symbol, context);
- if (newName !== lit.text) {
- return setOriginalNode(factory.createStringLiteral(newName), lit);
+ let name = lit.text;
+ const nodeSymbol = getNodeLinks(node).resolvedSymbol;
+ const meaning = parent.isTypeOf ? SymbolFlags.Value : SymbolFlags.Type;
+ const parentSymbol = nodeSymbol
+ && isSymbolAccessible(nodeSymbol, context.enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible
+ && lookupSymbolChain(nodeSymbol, context, meaning, /*yieldModuleSymbol*/ true)[0];
+ if (parentSymbol && parentSymbol.flags & SymbolFlags.Module) {
+ name = getSpecifierForModuleSymbol(parentSymbol, context);
+ }
+ else {
+ const targetFile = getExternalModuleFileFromDeclaration(parent);
+ if (targetFile) {
+ name = getSpecifierForModuleSymbol(targetFile.symbol, context);
+ }
+ }
+ if (name.includes("/node_modules/")) {
+ context.encounteredError = true;
+ if (context.tracker.reportLikelyUnsafeImportRequiredError) {
+ context.tracker.reportLikelyUnsafeImportRequiredError(name);
}
}
+ if (name !== lit.text) {
+ return setOriginalNode(factory.createStringLiteral(name), lit);
+ }
}
return visitNode(lit, visitExistingNodeTreeSymbols, isStringLiteral)!;
}
@@ -8804,17 +9182,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// Only actually serialize symbols within the correct enclosing declaration, otherwise do nothing with the out-of-context symbol
const skipMembershipCheck = !isPrivate; // We only call this on exported symbols when we know they're in the correct scope
if (skipMembershipCheck || (!!length(symbol.declarations) && some(symbol.declarations, d => !!findAncestor(d, n => n === enclosingDeclaration)))) {
- const oldContext = context;
- context = cloneNodeBuilderContext(context);
+ const scopeCleanup = cloneNodeBuilderContext(context);
serializeSymbolWorker(symbol, isPrivate, propertyAsAlias);
- if (context.reportedDiagnostic) {
- oldcontext.reportedDiagnostic = context.reportedDiagnostic; // hoist diagnostic result into outer context
- }
- if (context.trackedSymbols) {
- if (!oldContext.trackedSymbols) oldContext.trackedSymbols = context.trackedSymbols;
- else Debug.assert(context.trackedSymbols === oldContext.trackedSymbols);
- }
- context = oldContext;
+ scopeCleanup();
}
}
@@ -9325,8 +9695,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return cleanup(factory.createExpressionWithTypeArguments(
expr,
map(e.typeArguments, a =>
- tryReuseExistingNonParameterTypeNode(context, a, getTypeFromTypeNode(a))
- || typeToTypeNodeHelper(getTypeFromTypeNode(a), context)),
+ tryReuseExistingNonParameterTypeNode(context, a, getTypeFromTypeNode(context, a))
+ || typeToTypeNodeHelper(getTypeFromTypeNode(context, a), context)),
));
function cleanup(result: T): T {
@@ -10486,8 +10856,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
switch (propertyName) {
case TypeSystemPropertyName.Type:
return !!getSymbolLinks(target as Symbol).type;
- case TypeSystemPropertyName.EnumTagType:
- return !!(getNodeLinks(target as JSDocEnumTag).resolvedEnumType);
case TypeSystemPropertyName.DeclaredType:
return !!getSymbolLinks(target as Symbol).declaredType;
case TypeSystemPropertyName.ResolvedBaseConstructorType:
@@ -14196,7 +14564,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
// The source types were normalized; ensure the result is normalized too.
- return getNormalizedType(getIntersectionType(constraints), /*writing*/ false);
+ return getNormalizedType(getIntersectionType(constraints, IntersectionFlags.NoConstraintReduction), /*writing*/ false);
}
return undefined;
}
@@ -16906,6 +17274,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (flags & TypeFlags.Instantiable) includes |= TypeFlags.IncludesInstantiable;
if (flags & TypeFlags.Intersection && getObjectFlags(type) & ObjectFlags.IsConstrainedTypeVariable) includes |= TypeFlags.IncludesConstrainedTypeVariable;
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
+ if (isErrorType(type)) includes |= TypeFlags.IncludesError;
if (!strictNullChecks && flags & TypeFlags.Nullable) {
if (!(getObjectFlags(type) & ObjectFlags.ContainsWideningType)) includes |= TypeFlags.IncludesNonWideningType;
}
@@ -17157,7 +17526,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (unionReduction !== UnionReduction.None) {
if (includes & TypeFlags.AnyOrUnknown) {
return includes & TypeFlags.Any ?
- includes & TypeFlags.IncludesWildcard ? wildcardType : anyType :
+ includes & TypeFlags.IncludesWildcard ? wildcardType :
+ includes & TypeFlags.IncludesError ? errorType : anyType :
unknownType;
}
if (includes & TypeFlags.Undefined) {
@@ -17299,6 +17669,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
else {
if (flags & TypeFlags.AnyOrUnknown) {
if (type === wildcardType) includes |= TypeFlags.IncludesWildcard;
+ if (isErrorType(type)) includes |= TypeFlags.IncludesError;
}
else if (strictNullChecks || !(flags & TypeFlags.Nullable)) {
if (type === missingType) {
@@ -17459,7 +17830,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// a type alias of the form "type List = T & { next: List }" cannot be reduced during its declaration.
// Also, unlike union types, the order of the constituent types is preserved in order that overload resolution
// for intersections of types with signatures can be deterministic.
- function getIntersectionType(types: readonly Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[], noSupertypeReduction?: boolean): Type {
+ function getIntersectionType(types: readonly Type[], flags = IntersectionFlags.None, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type {
const typeMembershipMap = new Map();
const includes = addTypesToIntersection(typeMembershipMap, 0 as TypeFlags, types);
const typeSet: Type[] = arrayFrom(typeMembershipMap.values());
@@ -17491,7 +17862,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return neverType;
}
if (includes & TypeFlags.Any) {
- return includes & TypeFlags.IncludesWildcard ? wildcardType : anyType;
+ return includes & TypeFlags.IncludesWildcard ? wildcardType : includes & TypeFlags.IncludesError ? errorType : anyType;
}
if (!strictNullChecks && includes & TypeFlags.Nullable) {
return includes & TypeFlags.IncludesEmptyObject ? neverType : includes & TypeFlags.Undefined ? undefinedType : nullType;
@@ -17504,7 +17875,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
includes & TypeFlags.Void && includes & TypeFlags.Undefined ||
includes & TypeFlags.IncludesEmptyObject && includes & TypeFlags.DefinitelyNonNullable
) {
- if (!noSupertypeReduction) removeRedundantSupertypes(typeSet, includes);
+ if (!(flags & IntersectionFlags.NoSupertypeReduction)) removeRedundantSupertypes(typeSet, includes);
}
if (includes & TypeFlags.IncludesMissingType) {
typeSet[typeSet.indexOf(undefinedType)] = missingType;
@@ -17515,7 +17886,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (typeSet.length === 1) {
return typeSet[0];
}
- if (typeSet.length === 2) {
+ if (typeSet.length === 2 && !(flags & IntersectionFlags.NoConstraintReduction)) {
const typeVarIndex = typeSet[0].flags & TypeFlags.TypeVariable ? 0 : 1;
const typeVariable = typeSet[typeVarIndex];
const primitiveType = typeSet[1 - typeVarIndex];
@@ -17548,7 +17919,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
}
- const id = getTypeListId(typeSet) + getAliasId(aliasSymbol, aliasTypeArguments);
+ const id = getTypeListId(typeSet) + (flags & IntersectionFlags.NoConstraintReduction ? "*" : getAliasId(aliasSymbol, aliasTypeArguments));
let result = intersectionTypes.get(id);
if (!result) {
if (includes & TypeFlags.Union) {
@@ -17556,16 +17927,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// When the intersection creates a reduced set (which might mean that *all* union types have
// disappeared), we restart the operation to get a new set of combined flags. Once we have
// reduced we'll never reduce again, so this occurs at most once.
- result = getIntersectionType(typeSet, aliasSymbol, aliasTypeArguments);
+ result = getIntersectionType(typeSet, flags, aliasSymbol, aliasTypeArguments);
}
else if (every(typeSet, t => !!(t.flags & TypeFlags.Union && (t as UnionType).types[0].flags & TypeFlags.Undefined))) {
const containedUndefinedType = some(typeSet, containsMissingType) ? missingType : undefinedType;
removeFromEach(typeSet, TypeFlags.Undefined);
- result = getUnionType([getIntersectionType(typeSet), containedUndefinedType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
+ result = getUnionType([getIntersectionType(typeSet, flags), containedUndefinedType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
}
else if (every(typeSet, t => !!(t.flags & TypeFlags.Union && ((t as UnionType).types[0].flags & TypeFlags.Null || (t as UnionType).types[1].flags & TypeFlags.Null)))) {
removeFromEach(typeSet, TypeFlags.Null);
- result = getUnionType([getIntersectionType(typeSet), nullType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
+ result = getUnionType([getIntersectionType(typeSet, flags), nullType], UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
}
else if (typeSet.length >= 4) {
// When we have four or more constituents, some of which are unions, we employ a "divide and conquer" strategy
@@ -17573,7 +17944,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// unions of intersections than the full cartesian product (due to some intersections becoming `never`), this can
// dramatically reduce the overall work.
const middle = Math.floor(typeSet.length / 2);
- result = getIntersectionType([getIntersectionType(typeSet.slice(0, middle)), getIntersectionType(typeSet.slice(middle))], aliasSymbol, aliasTypeArguments);
+ result = getIntersectionType([getIntersectionType(typeSet.slice(0, middle), flags), getIntersectionType(typeSet.slice(middle), flags)], flags, aliasSymbol, aliasTypeArguments);
}
else {
// We are attempting to construct a type of the form X & (A | B) & (C | D). Transform this into a type of
@@ -17582,7 +17953,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (!checkCrossProductUnion(typeSet)) {
return errorType;
}
- const constituents = getCrossProductIntersections(typeSet);
+ const constituents = getCrossProductIntersections(typeSet, flags);
// We attach a denormalized origin type when at least one constituent of the cross-product union is an
// intersection (i.e. when the intersection didn't just reduce one or more unions to smaller unions) and
// the denormalized origin has fewer constituents than the union itself.
@@ -17612,7 +17983,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return true;
}
- function getCrossProductIntersections(types: readonly Type[]) {
+ function getCrossProductIntersections(types: readonly Type[], flags: IntersectionFlags) {
const count = getCrossProductUnionSize(types);
const intersections: Type[] = [];
for (let i = 0; i < count; i++) {
@@ -17626,7 +17997,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
n = Math.floor(n / length);
}
}
- const t = getIntersectionType(constituents);
+ const t = getIntersectionType(constituents, flags);
if (!(t.flags & TypeFlags.Never)) intersections.push(t);
}
return intersections;
@@ -17653,7 +18024,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const emptyIndex = types.length === 2 ? types.indexOf(emptyTypeLiteralType) : -1;
const t = emptyIndex >= 0 ? types[1 - emptyIndex] : unknownType;
const noSupertypeReduction = !!(t.flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.BigInt) || t.flags & TypeFlags.TemplateLiteral && isPatternLiteralType(t));
- links.resolvedType = getIntersectionType(types, aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol), noSupertypeReduction);
+ links.resolvedType = getIntersectionType(types, noSupertypeReduction ? IntersectionFlags.NoSupertypeReduction : 0, aliasSymbol, getTypeArgumentsForAliasSymbol(aliasSymbol));
}
return links.resolvedType;
}
@@ -17869,16 +18240,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (contains(types, wildcardType)) {
return wildcardType;
}
- if (
- texts.length === 2 && texts[0] === "" && texts[1] === ""
- // literals (including string enums) are stringified below
- && !(types[0].flags & TypeFlags.Literal)
- // infer T extends StringLike can't be unwrapped eagerly
- && !types[0].symbol?.declarations?.some(d => d.parent.kind === SyntaxKind.InferType)
- && isTypeAssignableTo(types[0], stringType)
- ) {
- return types[0];
- }
const newTypes: Type[] = [];
const newTexts: string[] = [];
let text = texts[0];
@@ -18533,7 +18894,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return undefined;
}
return accessFlags & AccessFlags.Writing
- ? getIntersectionType(propTypes, aliasSymbol, aliasTypeArguments)
+ ? getIntersectionType(propTypes, IntersectionFlags.None, aliasSymbol, aliasTypeArguments)
: getUnionType(propTypes, UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
}
return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, accessNode, accessFlags | AccessFlags.CacheSymbol | AccessFlags.ReportDeprecated);
@@ -19884,7 +20245,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const newAliasSymbol = aliasSymbol || type.aliasSymbol;
const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper);
return flags & TypeFlags.Intersection || origin && origin.flags & TypeFlags.Intersection ?
- getIntersectionType(newTypes, newAliasSymbol, newAliasTypeArguments) :
+ getIntersectionType(newTypes, IntersectionFlags.None, newAliasSymbol, newAliasTypeArguments) :
getUnionType(newTypes, UnionReduction.Literal, newAliasSymbol, newAliasTypeArguments);
}
if (flags & TypeFlags.Index) {
@@ -20769,7 +21130,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
for (let i = 0; i < paramCount; i++) {
const sourceType = i === restIndex ? getRestOrAnyTypeAtPosition(source, i) : tryGetTypeAtPosition(source, i);
const targetType = i === restIndex ? getRestOrAnyTypeAtPosition(target, i) : tryGetTypeAtPosition(target, i);
- if (sourceType && targetType) {
+ if (sourceType && targetType && (sourceType !== targetType || checkMode & SignatureCheckMode.StrictArity)) {
// In order to ensure that any generic type Foo is at least co-variant with respect to T no matter
// how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions,
// they naturally relate only contra-variantly). However, if the source and target parameters both have
@@ -24951,13 +25312,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function applyToReturnTypes(source: Signature, target: Signature, callback: (s: Type, t: Type) => void) {
- const sourceTypePredicate = getTypePredicateOfSignature(source);
const targetTypePredicate = getTypePredicateOfSignature(target);
- if (sourceTypePredicate && targetTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) {
- callback(sourceTypePredicate.type, targetTypePredicate.type);
+ if (targetTypePredicate) {
+ const sourceTypePredicate = getTypePredicateOfSignature(source);
+ if (sourceTypePredicate && typePredicateKindsMatch(sourceTypePredicate, targetTypePredicate) && sourceTypePredicate.type && targetTypePredicate.type) {
+ callback(sourceTypePredicate.type, targetTypePredicate.type);
+ return;
+ }
}
- else {
- callback(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target));
+ const targetReturnType = getReturnTypeOfSignature(target);
+ if (couldContainTypeVariables(targetReturnType)) {
+ callback(getReturnTypeOfSignature(source), targetReturnType);
}
}
@@ -29148,6 +29513,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function getNarrowableTypeForReference(type: Type, reference: Node, checkMode?: CheckMode) {
+ if (isNoInferType(type)) {
+ type = (type as SubstitutionType).baseType;
+ }
// When the type of a reference is or contains an instantiable type with a union type constraint, and
// when the reference is in a constraint position (where it is known we'll obtain the apparent type) or
// has a contextual type containing no top-level instantiables (meaning constraints will determine
@@ -29177,6 +29545,286 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
});
}
+ /**
+ * This function marks all the imports the given location refers to as `.referenced` in `NodeLinks` (transitively through local import aliases).
+ * (This corresponds to not getting elided in JS emit.)
+ * It can be called on *most* nodes in the AST with `ReferenceHint.Unspecified` and will filter its inputs, but care should be taken to avoid calling it on the RHS of an `import =` or specifiers in a `import {} from "..."`,
+ * unless you *really* want to *definitely* mark those as referenced.
+ * These shouldn't be directly marked, and should only get marked transitively by the internals of this function.
+ *
+ * @param location The location to mark js import refernces for
+ * @param hint The kind of reference `location` has already been checked to be
+ * @param propSymbol The optional symbol of the property we're looking up - this is used for property accesses when `const enum`s do not count as references (no `isolatedModules`, no `preserveConstEnums` + export). It will be calculated if not provided.
+ * @param parentType The optional type of the parent of the LHS of the property access - this will be recalculated if not provided (but is costly).
+ */
+ function markLinkedReferences(location: PropertyAccessExpression | QualifiedName, hint: ReferenceHint.Property, propSymbol: Symbol | undefined, parentType: Type): void;
+ function markLinkedReferences(location: Identifier, hint: ReferenceHint.Identifier): void;
+ function markLinkedReferences(location: ExportAssignment, hint: ReferenceHint.ExportAssignment): void;
+ function markLinkedReferences(location: JsxOpeningLikeElement | JsxOpeningFragment, hint: ReferenceHint.Jsx): void;
+ function markLinkedReferences(location: FunctionLikeDeclaration | MethodSignature, hint: ReferenceHint.AsyncFunction): void;
+ function markLinkedReferences(location: ImportEqualsDeclaration, hint: ReferenceHint.ExportImportEquals): void;
+ function markLinkedReferences(location: ExportSpecifier, hint: ReferenceHint.ExportSpecifier): void;
+ function markLinkedReferences(location: HasDecorators, hint: ReferenceHint.Decorator): void;
+ function markLinkedReferences(location: Node, hint: ReferenceHint.Unspecified, propSymbol?: Symbol, parentType?: Type): void;
+ function markLinkedReferences(location: Node, hint: ReferenceHint, propSymbol?: Symbol, parentType?: Type) {
+ if (!canCollectSymbolAliasAccessabilityData) {
+ return;
+ }
+ if (location.flags & NodeFlags.Ambient) {
+ return; // References within types and declaration files are never going to contribute to retaining a JS import
+ }
+ switch (hint) {
+ case ReferenceHint.Identifier:
+ return markIdentifierAliasReferenced(location as Identifier);
+ case ReferenceHint.Property:
+ return markPropertyAliasReferenced(location as PropertyAccessExpression | QualifiedName, propSymbol, parentType);
+ case ReferenceHint.ExportAssignment:
+ return markExportAssignmentAliasReferenced(location as ExportAssignment);
+ case ReferenceHint.Jsx:
+ return markJsxAliasReferenced(location as JsxOpeningLikeElement | JsxOpeningFragment);
+ case ReferenceHint.AsyncFunction:
+ return markAsyncFunctionAliasReferenced(location as FunctionLikeDeclaration | MethodSignature);
+ case ReferenceHint.ExportImportEquals:
+ return markImportEqualsAliasReferenced(location as ImportEqualsDeclaration);
+ case ReferenceHint.ExportSpecifier:
+ return markExportSpecifierAliasReferenced(location as ExportSpecifier);
+ case ReferenceHint.Decorator:
+ return markDecoratorAliasReferenced(location as HasDecorators);
+ case ReferenceHint.Unspecified: {
+ // Identifiers in expression contexts are emitted, so we need to follow their referenced aliases and mark them as used
+ // Some non-expression identifiers are also treated as expression identifiers for this purpose, eg, `a` in `b = {a}` or `q` in `import r = q`
+ // This is the exception, rather than the rule - most non-expression identifiers are declaration names.
+ if (isIdentifier(location) && (isExpressionNode(location) || isShorthandPropertyAssignment(location.parent) || (isImportEqualsDeclaration(location.parent) && location.parent.moduleReference === location)) && shouldMarkIdentifierAliasReferenced(location)) {
+ if (isPropertyAccessOrQualifiedName(location.parent)) {
+ const left = isPropertyAccessExpression(location.parent) ? location.parent.expression : location.parent.left;
+ if (left !== location) return; // Only mark the LHS (the RHS is a property lookup)
+ }
+ markIdentifierAliasReferenced(location);
+ return;
+ }
+ if (isPropertyAccessOrQualifiedName(location)) {
+ let topProp: Node | undefined = location;
+ while (isPropertyAccessOrQualifiedName(topProp)) {
+ if (isPartOfTypeNode(topProp)) return;
+ topProp = topProp.parent;
+ }
+ return markPropertyAliasReferenced(location);
+ }
+ if (isExportAssignment(location)) {
+ return markExportAssignmentAliasReferenced(location);
+ }
+ if (isJsxOpeningLikeElement(location) || isJsxOpeningFragment(location)) {
+ return markJsxAliasReferenced(location);
+ }
+ if (isImportEqualsDeclaration(location)) {
+ if (isInternalModuleImportEqualsDeclaration(location) || checkExternalImportOrExportDeclaration(location)) {
+ return markImportEqualsAliasReferenced(location);
+ }
+ return;
+ }
+ if (isExportSpecifier(location)) {
+ return markExportSpecifierAliasReferenced(location);
+ }
+ if (isFunctionLikeDeclaration(location) || isMethodSignature(location)) {
+ markAsyncFunctionAliasReferenced(location);
+ // Might be decorated, fall through to decorator final case
+ }
+ if (!compilerOptions.emitDecoratorMetadata) {
+ return;
+ }
+ if (!canHaveDecorators(location) || !hasDecorators(location) || !location.modifiers || !nodeCanBeDecorated(legacyDecorators, location, location.parent, location.parent.parent)) {
+ return;
+ }
+
+ return markDecoratorAliasReferenced(location);
+ }
+ default:
+ Debug.assertNever(hint, `Unhandled reference hint: ${hint}`);
+ }
+ }
+
+ function markIdentifierAliasReferenced(location: Identifier) {
+ const symbol = getResolvedSymbol(location);
+ if (symbol && symbol !== argumentsSymbol && symbol !== unknownSymbol && !isThisInTypeQuery(location)) {
+ markAliasReferenced(symbol, location);
+ }
+ }
+
+ function markPropertyAliasReferenced(location: PropertyAccessExpression | QualifiedName, propSymbol?: Symbol, parentType?: Type) {
+ const left = isPropertyAccessExpression(location) ? location.expression : location.left;
+ if (isThisIdentifier(left) || !isIdentifier(left)) {
+ return;
+ }
+ const parentSymbol = getResolvedSymbol(left);
+ if (!parentSymbol || parentSymbol === unknownSymbol) {
+ return;
+ }
+ // In `Foo.Bar.Baz`, 'Foo' is not referenced if 'Bar' is a const enum or a module containing only const enums.
+ // `Foo` is also not referenced in `enum FooCopy { Bar = Foo.Bar }`, because the enum member value gets inlined
+ // here even if `Foo` is not a const enum.
+ //
+ // The exceptions are:
+ // 1. if 'isolatedModules' is enabled, because the const enum value will not be inlined, and
+ // 2. if 'preserveConstEnums' is enabled and the expression is itself an export, e.g. `export = Foo.Bar.Baz`.
+ //
+ // The property lookup is deferred as much as possible, in as many situations as possible, to avoid alias marking
+ // pulling on types/symbols it doesn't strictly need to.
+ if (getIsolatedModules(compilerOptions) || (shouldPreserveConstEnums(compilerOptions) && isExportOrExportExpression(location))) {
+ markAliasReferenced(parentSymbol, location);
+ return;
+ }
+ // Hereafter, this relies on type checking - but every check prior to this only used symbol information
+ const leftType = parentType || checkExpressionCached(left);
+ if (isTypeAny(leftType) || leftType === silentNeverType) {
+ markAliasReferenced(parentSymbol, location);
+ return;
+ }
+ let prop = propSymbol;
+ if (!prop && !parentType) {
+ const right = isPropertyAccessExpression(location) ? location.name : location.right;
+ const lexicallyScopedSymbol = isPrivateIdentifier(right) && lookupSymbolForPrivateIdentifierDeclaration(right.escapedText, right);
+ const assignmentKind = getAssignmentTargetKind(location);
+ const apparentType = getApparentType(assignmentKind !== AssignmentKind.None || isMethodAccessForCall(location) ? getWidenedType(leftType) : leftType);
+ prop = isPrivateIdentifier(right) ? lexicallyScopedSymbol && getPrivateIdentifierPropertyOfType(apparentType, lexicallyScopedSymbol) || undefined : getPropertyOfType(apparentType, right.escapedText);
+ }
+ if (
+ !(prop && (isConstEnumOrConstEnumOnlyModule(prop) || prop.flags & SymbolFlags.EnumMember && location.parent.kind === SyntaxKind.EnumMember))
+ ) {
+ markAliasReferenced(parentSymbol, location);
+ }
+ return;
+ }
+
+ function markExportAssignmentAliasReferenced(location: ExportAssignment) {
+ if (isIdentifier(location.expression)) {
+ const id = location.expression;
+ const sym = getExportSymbolOfValueSymbolIfExported(resolveEntityName(id, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, location));
+ if (sym) {
+ markAliasReferenced(sym, id);
+ }
+ }
+ }
+
+ function markJsxAliasReferenced(node: JsxOpeningLikeElement | JsxOpeningFragment) {
+ if (!getJsxNamespaceContainerForImplicitImport(node)) {
+ // The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
+ // And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
+ const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
+ const jsxFactoryNamespace = getJsxNamespace(node);
+ const jsxFactoryLocation = isJsxOpeningLikeElement(node) ? node.tagName : node;
+
+ // allow null as jsxFragmentFactory
+ let jsxFactorySym: Symbol | undefined;
+ if (!(isJsxOpeningFragment(node) && jsxFactoryNamespace === "null")) {
+ jsxFactorySym = resolveName(jsxFactoryLocation, jsxFactoryNamespace, SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
+ }
+
+ if (jsxFactorySym) {
+ // Mark local symbol as referenced here because it might not have been marked
+ // if jsx emit was not jsxFactory as there wont be error being emitted
+ jsxFactorySym.isReferenced = SymbolFlags.All;
+
+ // If react/jsxFactory symbol is alias, mark it as refereced
+ if (canCollectSymbolAliasAccessabilityData && jsxFactorySym.flags & SymbolFlags.Alias && !getTypeOnlyAliasDeclaration(jsxFactorySym)) {
+ markAliasSymbolAsReferenced(jsxFactorySym);
+ }
+ }
+
+ // For JsxFragment, mark jsx pragma as referenced via resolveName
+ if (isJsxOpeningFragment(node)) {
+ const file = getSourceFileOfNode(node);
+ const localJsxNamespace = getLocalJsxNamespace(file);
+ if (localJsxNamespace) {
+ resolveName(jsxFactoryLocation, localJsxNamespace, SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
+ }
+ }
+ }
+ return;
+ }
+
+ function markAsyncFunctionAliasReferenced(location: FunctionLikeDeclaration | MethodSignature) {
+ if (languageVersion < ScriptTarget.ES2015) {
+ if (getFunctionFlags(location) & FunctionFlags.Async) {
+ const returnTypeNode = getEffectiveReturnTypeNode(location);
+ markTypeNodeAsReferenced(returnTypeNode);
+ }
+ }
+ }
+
+ function markImportEqualsAliasReferenced(location: ImportEqualsDeclaration) {
+ if (hasSyntacticModifier(location, ModifierFlags.Export)) {
+ markExportAsReferenced(location);
+ }
+ }
+
+ function markExportSpecifierAliasReferenced(location: ExportSpecifier) {
+ if (!location.parent.parent.moduleSpecifier && !location.isTypeOnly && !location.parent.parent.isTypeOnly) {
+ const exportedName = location.propertyName || location.name;
+ const symbol = resolveName(exportedName, exportedName.escapedText, SymbolFlags.Value | SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias, /*nameNotFoundMessage*/ undefined, /*isUse*/ true);
+ if (symbol && (symbol === undefinedSymbol || symbol === globalThisSymbol || symbol.declarations && isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) {
+ // Do nothing, non-local symbol
+ }
+ else {
+ const target = symbol && (symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol);
+ if (!target || getSymbolFlags(target) & SymbolFlags.Value) {
+ markExportAsReferenced(location); // marks export as used
+ markIdentifierAliasReferenced(location.propertyName || location.name); // marks target of export as used
+ }
+ }
+ return;
+ }
+ }
+
+ function markDecoratorAliasReferenced(node: HasDecorators) {
+ if (compilerOptions.emitDecoratorMetadata) {
+ const firstDecorator = find(node.modifiers, isDecorator);
+ if (!firstDecorator) {
+ return;
+ }
+
+ checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Metadata);
+
+ // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
+ switch (node.kind) {
+ case SyntaxKind.ClassDeclaration:
+ const constructor = getFirstConstructorWithBody(node);
+ if (constructor) {
+ for (const parameter of constructor.parameters) {
+ markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
+ }
+ }
+ break;
+
+ case SyntaxKind.GetAccessor:
+ case SyntaxKind.SetAccessor:
+ const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
+ const otherAccessor = getDeclarationOfKind(getSymbolOfDeclaration(node), otherKind);
+ markDecoratorMedataDataTypeNodeAsReferenced(getAnnotatedAccessorTypeNode(node) || otherAccessor && getAnnotatedAccessorTypeNode(otherAccessor));
+ break;
+ case SyntaxKind.MethodDeclaration:
+ for (const parameter of node.parameters) {
+ markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
+ }
+
+ markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveReturnTypeNode(node));
+ break;
+
+ case SyntaxKind.PropertyDeclaration:
+ markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveTypeAnnotationNode(node));
+ break;
+
+ case SyntaxKind.Parameter:
+ markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node));
+ const containingSignature = node.parent;
+ for (const parameter of containingSignature.parameters) {
+ markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
+ }
+ markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveReturnTypeNode(containingSignature));
+ break;
+ }
+ }
+ }
+
function markAliasReferenced(symbol: Symbol, location: Node) {
if (!canCollectSymbolAliasAccessabilityData) {
return;
@@ -29198,6 +29846,95 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
+ // When an alias symbol is referenced, we need to mark the entity it references as referenced and in turn repeat that until
+ // we reach a non-alias or an exported entity (which is always considered referenced). We do this by checking the target of
+ // the alias as an expression (which recursively takes us back here if the target references another alias).
+ function markAliasSymbolAsReferenced(symbol: Symbol) {
+ Debug.assert(canCollectSymbolAliasAccessabilityData);
+ const links = getSymbolLinks(symbol);
+ if (!links.referenced) {
+ links.referenced = true;
+ const node = getDeclarationOfAliasSymbol(symbol);
+ if (!node) return Debug.fail();
+ // We defer checking of the reference of an `import =` until the import itself is referenced,
+ // This way a chain of imports can be elided if ultimately the final input is only used in a type
+ // position.
+ if (isInternalModuleImportEqualsDeclaration(node)) {
+ if (getSymbolFlags(resolveSymbol(symbol)) & SymbolFlags.Value) {
+ // import foo =
+ const left = getFirstIdentifier(node.moduleReference as EntityNameExpression);
+ markIdentifierAliasReferenced(left);
+ }
+ }
+ }
+ }
+
+ function markExportAsReferenced(node: ImportEqualsDeclaration | ExportSpecifier) {
+ const symbol = getSymbolOfDeclaration(node);
+ const target = resolveAlias(symbol);
+ if (target) {
+ const markAlias = target === unknownSymbol ||
+ ((getSymbolFlags(symbol, /*excludeTypeOnlyMeanings*/ true) & SymbolFlags.Value) && !isConstEnumOrConstEnumOnlyModule(target));
+
+ if (markAlias) {
+ markAliasSymbolAsReferenced(symbol);
+ }
+ }
+ }
+
+ function markEntityNameOrEntityExpressionAsReference(typeName: EntityNameOrEntityNameExpression | undefined, forDecoratorMetadata: boolean) {
+ if (!typeName) return;
+
+ const rootName = getFirstIdentifier(typeName);
+ const meaning = (typeName.kind === SyntaxKind.Identifier ? SymbolFlags.Type : SymbolFlags.Namespace) | SymbolFlags.Alias;
+ const rootSymbol = resolveName(rootName, rootName.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*isUse*/ true);
+ if (rootSymbol && rootSymbol.flags & SymbolFlags.Alias) {
+ if (
+ canCollectSymbolAliasAccessabilityData
+ && symbolIsValue(rootSymbol)
+ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))
+ && !getTypeOnlyAliasDeclaration(rootSymbol)
+ ) {
+ markAliasSymbolAsReferenced(rootSymbol);
+ }
+ else if (
+ forDecoratorMetadata
+ && getIsolatedModules(compilerOptions)
+ && getEmitModuleKind(compilerOptions) >= ModuleKind.ES2015
+ && !symbolIsValue(rootSymbol)
+ && !some(rootSymbol.declarations, isTypeOnlyImportOrExportDeclaration)
+ ) {
+ const diag = error(typeName, Diagnostics.A_type_referenced_in_a_decorated_signature_must_be_imported_with_import_type_or_a_namespace_import_when_isolatedModules_and_emitDecoratorMetadata_are_enabled);
+ const aliasDeclaration = find(rootSymbol.declarations || emptyArray, isAliasSymbolDeclaration);
+ if (aliasDeclaration) {
+ addRelatedInfo(diag, createDiagnosticForNode(aliasDeclaration, Diagnostics._0_was_imported_here, idText(rootName)));
+ }
+ }
+ }
+ }
+
+ /**
+ * If a TypeNode can be resolved to a value symbol imported from an external module, it is
+ * marked as referenced to prevent import elision.
+ */
+ function markTypeNodeAsReferenced(node: TypeNode | undefined) {
+ markEntityNameOrEntityExpressionAsReference(node && getEntityNameFromTypeNode(node), /*forDecoratorMetadata*/ false);
+ }
+
+ /**
+ * This function marks the type used for metadata decorator as referenced if it is import
+ * from external module.
+ * This is different from markTypeNodeAsReferenced because it tries to simplify type nodes in
+ * union and intersection type
+ * @param node
+ */
+ function markDecoratorMedataDataTypeNodeAsReferenced(node: TypeNode | undefined): void {
+ const entityName = getEntityNameForDecoratorMetadata(node);
+ if (entityName && isEntityName(entityName)) {
+ markEntityNameOrEntityExpressionAsReference(entityName, /*forDecoratorMetadata*/ true);
+ }
+ }
+
function getNarrowedTypeOfSymbol(symbol: Symbol, location: Identifier, checkMode?: CheckMode) {
const type = getTypeOfSymbol(symbol, checkMode);
const declaration = symbol.valueDeclaration;
@@ -29287,15 +30024,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return type;
}
- function checkIdentifier(node: Identifier, checkMode: CheckMode | undefined): Type {
- if (isThisInTypeQuery(node)) {
- return checkThisExpression(node);
- }
-
- const symbol = getResolvedSymbol(node);
- if (symbol === unknownSymbol) {
- return errorType;
- }
+ /**
+ * This part of `checkIdentifier` is kept seperate from the rest, so `NodeCheckFlags` (and related diagnostics) can be lazily calculated
+ * without calculating the flow type of the identifier.
+ */
+ function checkIdentifierCalculateNodeCheckFlags(node: Identifier, symbol: Symbol) {
+ if (isThisInTypeQuery(node)) return;
// As noted in ECMAScript 6 language spec, arrow functions never have an arguments objects.
// Although in down-level emit of arrow function, we emit it using function expression which means that
@@ -29306,7 +30040,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (symbol === argumentsSymbol) {
if (isInPropertyInitializerOrClassStaticBlock(node)) {
error(node, Diagnostics.arguments_cannot_be_referenced_in_property_initializers);
- return errorType;
+ return;
}
let container = getContainingFunction(node);
@@ -29328,11 +30062,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
}
- return getTypeOfSymbol(symbol);
- }
-
- if (shouldMarkIdentifierAliasReferenced(node)) {
- markAliasReferenced(symbol, node);
+ return;
}
const localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
@@ -29341,7 +30071,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
addDeprecatedSuggestion(node, targetSymbol.declarations, node.escapedText as string);
}
- let declaration = localOrExportSymbol.valueDeclaration;
+ const declaration = localOrExportSymbol.valueDeclaration;
if (declaration && localOrExportSymbol.flags & SymbolFlags.Class) {
// When we downlevel classes we may emit some code outside of the class body. Due to the fact the
// class name is double-bound, we must ensure we mark references to the class name so that we can
@@ -29361,6 +30091,33 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
checkNestedBlockScopedBinding(node, symbol);
+ }
+
+ function checkIdentifier(node: Identifier, checkMode: CheckMode | undefined): Type {
+ if (isThisInTypeQuery(node)) {
+ return checkThisExpression(node);
+ }
+
+ const symbol = getResolvedSymbol(node);
+ if (symbol === unknownSymbol) {
+ return errorType;
+ }
+
+ checkIdentifierCalculateNodeCheckFlags(node, symbol);
+
+ if (symbol === argumentsSymbol) {
+ if (isInPropertyInitializerOrClassStaticBlock(node)) {
+ return errorType;
+ }
+ return getTypeOfSymbol(symbol);
+ }
+
+ if (shouldMarkIdentifierAliasReferenced(node)) {
+ markLinkedReferences(node, ReferenceHint.Identifier);
+ }
+
+ const localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol);
+ let declaration = localOrExportSymbol.valueDeclaration;
let type = getNarrowedTypeOfSymbol(localOrExportSymbol, node, checkMode);
const assignmentKind = getAssignmentTargetKind(node);
@@ -30325,9 +31082,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (!node.asteriskToken && contextualReturnType.flags & TypeFlags.Union) {
contextualReturnType = filterType(contextualReturnType, type => !!getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, type, isAsyncGenerator));
}
- return node.asteriskToken
- ? contextualReturnType
- : getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, contextualReturnType, isAsyncGenerator);
+ if (node.asteriskToken) {
+ const iterationTypes = getIterationTypesOfGeneratorFunctionReturnType(contextualReturnType, isAsyncGenerator);
+ const yieldType = iterationTypes?.yieldType ?? silentNeverType;
+ const returnType = getContextualType(node, contextFlags) ?? silentNeverType;
+ const nextType = iterationTypes?.nextType ?? unknownType;
+ const generatorType = createGeneratorType(yieldType, returnType, nextType, /*isAsyncGenerator*/ false);
+ if (isAsyncGenerator) {
+ const asyncGeneratorType = createGeneratorType(yieldType, returnType, nextType, /*isAsyncGenerator*/ true);
+ return getUnionType([generatorType, asyncGeneratorType]);
+ }
+ return generatorType;
+ }
+ return getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, contextualReturnType, isAsyncGenerator);
}
}
@@ -31385,7 +32152,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
scanner.setScriptTarget(sourceFile.languageVersion);
scanner.setLanguageVariant(sourceFile.languageVariant);
scanner.setOnError((message, length, arg0) => {
- // emulate `parseErrorAtPosition` from parser.ts
+ // For providing spelling suggestions
const start = scanner!.getTokenEnd();
if (message.category === DiagnosticCategory.Message && lastError && start === lastError.start && length === lastError.length) {
const error = createDetachedDiagnostic(sourceFile.fileName, sourceFile.text, start, length, message, arg0);
@@ -32191,12 +32958,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const errorMessage = isClassic
? Diagnostics.Cannot_find_module_0_Did_you_mean_to_set_the_moduleResolution_option_to_nodenext_or_to_add_aliases_to_the_paths_option
: Diagnostics.Cannot_find_module_0_or_its_corresponding_type_declarations;
- // Synthesized JSX import is either first or after tslib
- const jsxImportIndex = compilerOptions.importHelpers ? 1 : 0;
- const specifier = file?.imports[jsxImportIndex];
- if (specifier) {
- Debug.assert(nodeIsSynthesized(specifier) && specifier.text === runtimeImportSpecifier, `Expected sourceFile.imports[${jsxImportIndex}] to be the synthesized JSX runtime import`);
- }
+ const specifier = getJSXRuntimeImportSpecifier(file, runtimeImportSpecifier);
const mod = resolveExternalModule(specifier || location!, runtimeImportSpecifier, errorMessage, location!);
const result = mod && mod !== unknownSymbol ? getMergedSymbol(resolveSymbol(mod)) : undefined;
if (links) {
@@ -32472,39 +33234,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
checkJsxPreconditions(node);
- if (!getJsxNamespaceContainerForImplicitImport(node)) {
- // The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
- // And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
- const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
- const jsxFactoryNamespace = getJsxNamespace(node);
- const jsxFactoryLocation = isNodeOpeningLikeElement ? node.tagName : node;
-
- // allow null as jsxFragmentFactory
- let jsxFactorySym: Symbol | undefined;
- if (!(isJsxOpeningFragment(node) && jsxFactoryNamespace === "null")) {
- jsxFactorySym = resolveName(jsxFactoryLocation, jsxFactoryNamespace, SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
- }
-
- if (jsxFactorySym) {
- // Mark local symbol as referenced here because it might not have been marked
- // if jsx emit was not jsxFactory as there wont be error being emitted
- jsxFactorySym.isReferenced = SymbolFlags.All;
-
- // If react/jsxFactory symbol is alias, mark it as refereced
- if (canCollectSymbolAliasAccessabilityData && jsxFactorySym.flags & SymbolFlags.Alias && !getTypeOnlyAliasDeclaration(jsxFactorySym)) {
- markAliasSymbolAsReferenced(jsxFactorySym);
- }
- }
-
- // For JsxFragment, mark jsx pragma as referenced via resolveName
- if (isJsxOpeningFragment(node)) {
- const file = getSourceFileOfNode(node);
- const localJsxNamespace = getLocalJsxNamespace(file);
- if (localJsxNamespace) {
- resolveName(jsxFactoryLocation, localJsxNamespace, SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
- }
- }
- }
+ markLinkedReferences(node, ReferenceHint.Jsx);
if (isNodeOpeningLikeElement) {
const jsxOpeningLikeNode = node;
@@ -33081,28 +33811,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
else {
if (isAnyLike) {
if (isIdentifier(left) && parentSymbol) {
- markAliasReferenced(parentSymbol, node);
+ markLinkedReferences(node, ReferenceHint.Property, /*propSymbol*/ undefined, leftType);
}
return isErrorType(apparentType) ? errorType : apparentType;
}
prop = getPropertyOfType(apparentType, right.escapedText, /*skipObjectFunctionPropertyAugment*/ isConstEnumObjectType(apparentType), /*includeTypeOnlyMembers*/ node.kind === SyntaxKind.QualifiedName);
}
- // In `Foo.Bar.Baz`, 'Foo' is not referenced if 'Bar' is a const enum or a module containing only const enums.
- // `Foo` is also not referenced in `enum FooCopy { Bar = Foo.Bar }`, because the enum member value gets inlined
- // here even if `Foo` is not a const enum.
- //
- // The exceptions are:
- // 1. if 'isolatedModules' is enabled, because the const enum value will not be inlined, and
- // 2. if 'preserveConstEnums' is enabled and the expression is itself an export, e.g. `export = Foo.Bar.Baz`.
- if (
- isIdentifier(left) && parentSymbol && (
- getIsolatedModules(compilerOptions) ||
- !(prop && (isConstEnumOrConstEnumOnlyModule(prop) || prop.flags & SymbolFlags.EnumMember && node.parent.kind === SyntaxKind.EnumMember)) ||
- shouldPreserveConstEnums(compilerOptions) && isExportOrExportExpression(node)
- )
- ) {
- markAliasReferenced(parentSymbol, node);
- }
+ markLinkedReferences(node, ReferenceHint.Property, prop, leftType);
let propType: Type;
if (!prop) {
@@ -37291,7 +38006,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
if (isGenerator) {
- return createGeneratorReturnType(
+ return createGeneratorType(
yieldType || neverType,
returnType || fallbackReturnType,
nextType || getContextualIterationType(IterationTypeKind.Next, func) || unknownType,
@@ -37308,7 +38023,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
- function createGeneratorReturnType(yieldType: Type, returnType: Type, nextType: Type, isAsyncGenerator: boolean) {
+ function createGeneratorType(yieldType: Type, returnType: Type, nextType: Type, isAsyncGenerator: boolean) {
const resolver = isAsyncGenerator ? asyncIterationTypesResolver : syncIterationTypesResolver;
const globalGeneratorType = resolver.getGlobalGeneratorType(/*reportErrors*/ false);
yieldType = resolver.resolveIterationType(yieldType, /*errorNode*/ undefined) || unknownType;
@@ -39227,11 +39942,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
texts.push(span.literal.text);
types.push(isTypeAssignableTo(type, templateConstraintType) ? type : stringType);
}
+ const evaluated = node.parent.kind !== SyntaxKind.TaggedTemplateExpression && evaluate(node).value;
+ if (evaluated) {
+ return getFreshTypeOfLiteralType(getStringLiteralType(evaluated));
+ }
if (isConstContext(node) || isTemplateLiteralContext(node) || someType(getContextualType(node, /*contextFlags*/ undefined) || unknownType, isTemplateLiteralContextualType)) {
return getTemplateLiteralType(texts, types);
}
- const evaluated = node.parent.kind !== SyntaxKind.TaggedTemplateExpression && evaluate(node).value;
- return evaluated ? getFreshTypeOfLiteralType(getStringLiteralType(evaluated)) : stringType;
+ return stringType;
}
function isTemplateLiteralContextualType(type: Type): boolean {
@@ -40107,7 +40825,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const generatorYieldType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Yield, returnType, (functionFlags & FunctionFlags.Async) !== 0) || anyType;
const generatorReturnType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Return, returnType, (functionFlags & FunctionFlags.Async) !== 0) || generatorYieldType;
const generatorNextType = getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, returnType, (functionFlags & FunctionFlags.Async) !== 0) || unknownType;
- const generatorInstantiation = createGeneratorReturnType(generatorYieldType, generatorReturnType, generatorNextType, !!(functionFlags & FunctionFlags.Async));
+ const generatorInstantiation = createGeneratorType(generatorYieldType, generatorReturnType, generatorNextType, !!(functionFlags & FunctionFlags.Async));
return checkTypeAssignableTo(generatorInstantiation, returnType, errorNode);
}
@@ -41438,10 +42156,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// - The base constraint of `T` is an object type with a callable `then` method.
if (isAwaitedTypeNeeded(type)) {
- const awaitedType = tryCreateAwaitedType(type);
- if (awaitedType) {
- return awaitedType;
- }
+ return tryCreateAwaitedType(type) ?? type;
}
Debug.assert(isAwaitedTypeInstantiation(type) || getPromisedTypeOfPromise(type) === undefined, "type provided should not be a non-generic 'promise'-like.");
@@ -41646,8 +42361,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
else {
// Always mark the type node as referenced if it points to a value
- markTypeNodeAsReferenced(returnTypeNode);
-
+ markLinkedReferences(node, ReferenceHint.AsyncFunction);
if (isErrorType(returnType)) {
return;
}
@@ -41866,59 +42580,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return createFunctionType(/*typeParameters*/ undefined, /*thisParameter*/ undefined, [valueParam], voidType);
}
- /**
- * If a TypeNode can be resolved to a value symbol imported from an external module, it is
- * marked as referenced to prevent import elision.
- */
- function markTypeNodeAsReferenced(node: TypeNode) {
- markEntityNameOrEntityExpressionAsReference(node && getEntityNameFromTypeNode(node), /*forDecoratorMetadata*/ false);
- }
-
- function markEntityNameOrEntityExpressionAsReference(typeName: EntityNameOrEntityNameExpression | undefined, forDecoratorMetadata: boolean) {
- if (!typeName) return;
-
- const rootName = getFirstIdentifier(typeName);
- const meaning = (typeName.kind === SyntaxKind.Identifier ? SymbolFlags.Type : SymbolFlags.Namespace) | SymbolFlags.Alias;
- const rootSymbol = resolveName(rootName, rootName.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*isUse*/ true);
- if (rootSymbol && rootSymbol.flags & SymbolFlags.Alias) {
- if (
- canCollectSymbolAliasAccessabilityData
- && symbolIsValue(rootSymbol)
- && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))
- && !getTypeOnlyAliasDeclaration(rootSymbol)
- ) {
- markAliasSymbolAsReferenced(rootSymbol);
- }
- else if (
- forDecoratorMetadata
- && getIsolatedModules(compilerOptions)
- && getEmitModuleKind(compilerOptions) >= ModuleKind.ES2015
- && !symbolIsValue(rootSymbol)
- && !some(rootSymbol.declarations, isTypeOnlyImportOrExportDeclaration)
- ) {
- const diag = error(typeName, Diagnostics.A_type_referenced_in_a_decorated_signature_must_be_imported_with_import_type_or_a_namespace_import_when_isolatedModules_and_emitDecoratorMetadata_are_enabled);
- const aliasDeclaration = find(rootSymbol.declarations || emptyArray, isAliasSymbolDeclaration);
- if (aliasDeclaration) {
- addRelatedInfo(diag, createDiagnosticForNode(aliasDeclaration, Diagnostics._0_was_imported_here, idText(rootName)));
- }
- }
- }
- }
-
- /**
- * This function marks the type used for metadata decorator as referenced if it is import
- * from external module.
- * This is different from markTypeNodeAsReferenced because it tries to simplify type nodes in
- * union and intersection type
- * @param node
- */
- function markDecoratorMedataDataTypeNodeAsReferenced(node: TypeNode | undefined): void {
- const entityName = getEntityNameForDecoratorMetadata(node);
- if (entityName && isEntityName(entityName)) {
- markEntityNameOrEntityExpressionAsReference(entityName, /*forDecoratorMetadata*/ true);
- }
- }
-
function getEntityNameForDecoratorMetadata(node: TypeNode | undefined): EntityName | undefined {
if (node) {
switch (node.kind) {
@@ -42026,48 +42687,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
- if (compilerOptions.emitDecoratorMetadata) {
- checkExternalEmitHelpers(firstDecorator, ExternalEmitHelpers.Metadata);
-
- // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator.
- switch (node.kind) {
- case SyntaxKind.ClassDeclaration:
- const constructor = getFirstConstructorWithBody(node);
- if (constructor) {
- for (const parameter of constructor.parameters) {
- markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
- }
- }
- break;
-
- case SyntaxKind.GetAccessor:
- case SyntaxKind.SetAccessor:
- const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
- const otherAccessor = getDeclarationOfKind(getSymbolOfDeclaration(node), otherKind);
- markDecoratorMedataDataTypeNodeAsReferenced(getAnnotatedAccessorTypeNode(node) || otherAccessor && getAnnotatedAccessorTypeNode(otherAccessor));
- break;
- case SyntaxKind.MethodDeclaration:
- for (const parameter of node.parameters) {
- markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
- }
-
- markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveReturnTypeNode(node));
- break;
-
- case SyntaxKind.PropertyDeclaration:
- markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveTypeAnnotationNode(node));
- break;
-
- case SyntaxKind.Parameter:
- markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node));
- const containingSignature = node.parent;
- for (const parameter of containingSignature.parameters) {
- markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter));
- }
- markDecoratorMedataDataTypeNodeAsReferenced(getEffectiveReturnTypeNode(containingSignature));
- break;
- }
- }
+ markLinkedReferences(node, ReferenceHint.Decorator);
for (const modifier of node.modifiers) {
if (isDecorator(modifier)) {
@@ -46399,9 +47019,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
checkGrammarModifiers(node);
if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
checkImportBinding(node);
- if (hasSyntacticModifier(node, ModifierFlags.Export)) {
- markExportAsReferenced(node);
- }
+ markLinkedReferences(node, ReferenceHint.ExportImportEquals);
if (node.moduleReference.kind !== SyntaxKind.ExternalModuleReference) {
const target = resolveAlias(getSymbolOfDeclaration(node));
if (target !== unknownSymbol) {
@@ -46510,13 +47128,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
error(exportedName, Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, idText(exportedName));
}
else {
- if (!node.isTypeOnly && !node.parent.parent.isTypeOnly) {
- markExportAsReferenced(node);
- }
- const target = symbol && (symbol.flags & SymbolFlags.Alias ? resolveAlias(symbol) : symbol);
- if (!target || getSymbolFlags(target) & SymbolFlags.Value) {
- checkExpressionCached(node.propertyName || node.name);
- }
+ markLinkedReferences(node, ReferenceHint.ExportSpecifier);
}
}
else {
@@ -46569,8 +47181,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const id = node.expression as Identifier;
const sym = getExportSymbolOfValueSymbolIfExported(resolveEntityName(id, SymbolFlags.All, /*ignoreErrors*/ true, /*dontResolveAlias*/ true, node));
if (sym) {
+ markLinkedReferences(node, ReferenceHint.ExportAssignment);
const typeOnlyDeclaration = getTypeOnlyAliasDeclaration(sym, SymbolFlags.Value);
- markAliasReferenced(sym, id);
// If not a value, we're interpreting the identifier as a type export, along the lines of (`export { Id as default }`)
if (getSymbolFlags(sym) & SymbolFlags.Value) {
// However if it is a value, we need to check it's being used correctly
@@ -48209,12 +48821,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (links.isDeclarationWithCollidingName === undefined) {
const container = getEnclosingBlockScopeContainer(symbol.valueDeclaration);
if (isStatementWithLocals(container) || isSymbolOfDestructuredElementOfCatchBinding(symbol)) {
- const nodeLinks = getNodeLinks(symbol.valueDeclaration);
if (resolveName(container.parent, symbol.escapedName, SymbolFlags.Value, /*nameNotFoundMessage*/ undefined, /*isUse*/ false)) {
// redeclaration - always should be renamed
links.isDeclarationWithCollidingName = true;
}
- else if (nodeLinks.flags & NodeCheckFlags.CapturedBlockScopedBinding) {
+ else if (hasNodeCheckFlag(symbol.valueDeclaration, NodeCheckFlags.CapturedBlockScopedBinding)) {
// binding is captured in the function
// should be renamed if:
// - binding is not top level - top level bindings never collide with anything
@@ -48230,7 +48841,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// * variables from initializer are passed to rewritten loop body as parameters so they are not captured directly
// * variables that are declared immediately in loop body will become top level variable after loop is rewritten and thus
// they will not collide with anything
- const isDeclaredInLoop = nodeLinks.flags & NodeCheckFlags.BlockScopedBindingInLoop;
+ const isDeclaredInLoop = hasNodeCheckFlag(symbol.valueDeclaration, NodeCheckFlags.BlockScopedBindingInLoop);
const inLoopInitializer = isIterationStatement(container, /*lookInLabeledStatements*/ false);
const inLoopBodyBlock = container.kind === SyntaxKind.Block && isIterationStatement(container.parent, /*lookInLabeledStatements*/ false);
@@ -48317,6 +48928,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (!symbol) {
return false;
}
+ const container = getSourceFileOfNode(symbol.valueDeclaration);
+ const fileSymbol = container && getSymbolOfDeclaration(container);
+ // Ensures cjs export assignment is setup, since this symbol may point at, and merge with, the file itself.
+ // If we don't, the merge may not have yet occured, and the flags check below will be missing flags that
+ // are added as a result of the merge.
+ void resolveExternalModuleSymbol(fileSymbol);
const target = getExportSymbolOfValueSymbolIfExported(resolveAlias(symbol));
if (target === unknownSymbol) {
return !excludeTypeOnlyValues || !getTypeOnlyAliasDeclaration(symbol);
@@ -48443,6 +49060,129 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return nodeLinks[nodeId]?.flags || 0;
}
+ function hasNodeCheckFlag(node: Node, flag: LazyNodeCheckFlags) {
+ calculateNodeCheckFlagWorker(node, flag);
+ return !!(getNodeCheckFlags(node) & flag);
+ }
+
+ function calculateNodeCheckFlagWorker(node: Node, flag: LazyNodeCheckFlags) {
+ if (!compilerOptions.noCheck) {
+ // Unless noCheck is passed, assume calculation of node check flags has been done eagerly.
+ // This saves needing to mark up where in the eager traversal certain results are "done",
+ // just to reconcile the eager and lazy results. This wouldn't be hard if an eager typecheck
+ // was actually an in-order traversal, but it isn't - some nodes are deferred, and so don't
+ // have these node check flags calculated until that deferral is completed. As an example,
+ // in concept, we could consider a class that we've called `checkSourceElement` on as having had
+ // these flags calculated, but since the method bodies are deferred, we actually can't set the
+ // flags as having been calculated until that deferral is completed.
+ // The downside to this either/or approach to eager or lazy calculation is that we can't combine
+ // a partial eager traversal and lazy calculation for the missing bits, and there's a bit of
+ // overlap in functionality. This isn't a huge loss for any usecases today, but would be nice
+ // alongside language service partial file checking and editor-triggered emit.
+ return;
+ }
+ const links = getNodeLinks(node);
+ if (links.calculatedFlags & flag) {
+ return;
+ }
+ // This is only the set of `NodeCheckFlags` our emitter actually looks for, not all of them
+ switch (flag) {
+ case NodeCheckFlags.SuperInstance:
+ case NodeCheckFlags.SuperStatic:
+ return checkSingleSuperExpression(node);
+ case NodeCheckFlags.MethodWithSuperPropertyAccessInAsync:
+ case NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync:
+ case NodeCheckFlags.ContainsSuperPropertyInStaticInitializer:
+ return checkChildSuperExpressions(node);
+ case NodeCheckFlags.CaptureArguments:
+ case NodeCheckFlags.ContainsCapturedBlockScopeBinding:
+ case NodeCheckFlags.NeedsLoopOutParameter:
+ case NodeCheckFlags.ContainsConstructorReference:
+ return checkChildIdentifiers(node);
+ case NodeCheckFlags.ConstructorReference:
+ return checkSingleIdentifier(node);
+ case NodeCheckFlags.LoopWithCapturedBlockScopedBinding:
+ case NodeCheckFlags.BlockScopedBindingInLoop:
+ case NodeCheckFlags.CapturedBlockScopedBinding:
+ return checkContainingBlockScopeBindingUses(node);
+ default:
+ return Debug.assertNever(flag, `Unhandled node check flag calculation: ${Debug.formatNodeCheckFlags(flag)}`);
+ }
+
+ function forEachNodeRecursively(root: Node, cb: (node: Node, parent: Node) => T | "skip" | undefined): T | undefined {
+ const rootResult = cb(root, root.parent);
+ if (rootResult === "skip") return undefined;
+ if (rootResult) return rootResult;
+ return forEachChildRecursively(root, cb);
+ }
+
+ function checkSuperExpressions(node: Node) {
+ const links = getNodeLinks(node);
+ if (links.calculatedFlags & flag) return "skip";
+ links.calculatedFlags |= NodeCheckFlags.MethodWithSuperPropertyAccessInAsync | NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync | NodeCheckFlags.ContainsSuperPropertyInStaticInitializer;
+ checkSingleSuperExpression(node);
+ return undefined;
+ }
+
+ function checkChildSuperExpressions(node: Node) {
+ forEachNodeRecursively(node, checkSuperExpressions);
+ }
+
+ function checkSingleSuperExpression(node: Node) {
+ const nodeLinks = getNodeLinks(node); // This is called on sub-nodes of the original input, make sure we set `calculatedFlags` on the correct node
+ nodeLinks.calculatedFlags |= NodeCheckFlags.SuperInstance | NodeCheckFlags.SuperStatic; // Yes, we set this on non-applicable nodes, so we can entirely skip the traversal on future calls
+ if (node.kind === SyntaxKind.SuperKeyword) {
+ checkSuperExpression(node);
+ }
+ }
+
+ function checkIdentifiers(node: Node) {
+ const links = getNodeLinks(node);
+ if (links.calculatedFlags & flag) return "skip";
+ links.calculatedFlags |= NodeCheckFlags.CaptureArguments | NodeCheckFlags.ContainsCapturedBlockScopeBinding | NodeCheckFlags.NeedsLoopOutParameter | NodeCheckFlags.ContainsConstructorReference;
+ checkSingleIdentifier(node);
+ return undefined;
+ }
+
+ function checkChildIdentifiers(node: Node) {
+ forEachNodeRecursively(node, checkIdentifiers);
+ }
+
+ function checkSingleIdentifier(node: Node) {
+ const nodeLinks = getNodeLinks(node);
+ nodeLinks.calculatedFlags |= NodeCheckFlags.ConstructorReference | NodeCheckFlags.CapturedBlockScopedBinding | NodeCheckFlags.BlockScopedBindingInLoop;
+ if (isIdentifier(node) && isExpressionNode(node) && !(isPropertyAccessExpression(node.parent) && node.parent.name === node)) {
+ const s = getSymbolAtLocation(node, /*ignoreErrors*/ true);
+ if (s && s !== unknownSymbol) {
+ checkIdentifierCalculateNodeCheckFlags(node, s);
+ }
+ }
+ }
+
+ function checkBlockScopeBindings(node: Node) {
+ const links = getNodeLinks(node);
+ if (links.calculatedFlags & flag) return "skip";
+ links.calculatedFlags |= NodeCheckFlags.LoopWithCapturedBlockScopedBinding | NodeCheckFlags.BlockScopedBindingInLoop | NodeCheckFlags.CapturedBlockScopedBinding;
+ checkSingleBlockScopeBinding(node);
+ return undefined;
+ }
+
+ function checkContainingBlockScopeBindingUses(node: Node) {
+ const scope = getEnclosingBlockScopeContainer(isDeclarationName(node) ? node.parent : node);
+ forEachNodeRecursively(scope, checkBlockScopeBindings);
+ }
+
+ function checkSingleBlockScopeBinding(node: Node) {
+ checkSingleIdentifier(node);
+ if (isComputedPropertyName(node)) {
+ checkComputedPropertyName(node);
+ }
+ if (isPrivateIdentifier(node) && isClassElement(node.parent)) {
+ setNodeLinksForPrivateIdentifierScope(node.parent as PropertyDeclaration | PropertySignature | MethodDeclaration | MethodSignature | AccessorDeclaration);
+ }
+ }
+ }
+
function getEnumMemberValue(node: EnumMember): EvaluatorResult {
computeEnumMemberValues(node.parent);
return getNodeLinks(node).enumMemberValue ?? evaluatorResult(/*value*/ undefined);
@@ -48463,7 +49203,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return getEnumMemberValue(node).value;
}
- const symbol = getNodeLinks(node).resolvedSymbol;
+ if (!getNodeLinks(node).resolvedSymbol) {
+ void checkExpressionCached(node); // ensure cached resolved symbol is set
+ }
+ const symbol = getNodeLinks(node).resolvedSymbol || (isEntityNameExpression(node) ? resolveEntityName(node, SymbolFlags.Value, /*ignoreErrors*/ true) : undefined);
if (symbol && (symbol.flags & SymbolFlags.EnumMember)) {
// inline property\index accesses only for const enums
const member = symbol.valueDeclaration as EnumMember;
@@ -48620,6 +49363,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
function getSingleReturnExpression(declaration: SignatureDeclaration | undefined): Expression | undefined {
let candidateExpr: Expression | undefined;
if (declaration && !nodeIsMissing((declaration as FunctionLikeDeclaration).body)) {
+ if (getFunctionFlags(declaration) & FunctionFlags.AsyncGenerator) return undefined;
const body = (declaration as FunctionLikeDeclaration).body;
if (body && isBlock(body)) {
forEachReturnStatement(body, s => {
@@ -48759,25 +49503,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
return false;
}
- function isNonNarrowedBindableName(node: ComputedPropertyName) {
- if (!hasBindableName(node.parent)) {
- return false;
- }
-
- const expression = node.expression;
- if (!isEntityNameExpression(expression)) {
- return true;
- }
-
- const type = getTypeOfExpression(expression);
- const symbol = getSymbolAtLocation(expression);
- if (!symbol) {
- return false;
- }
- // Ensure not type narrowing
- const declaredType = getTypeOfSymbol(symbol);
- return declaredType === type;
- }
function literalTypeToNode(type: FreshableType, enclosing: Node, tracker: SymbolTracker): Expression {
const enumResult = type.flags & TypeFlags.EnumLike ? nodeBuilder.symbolToExpression(type.symbol, SymbolFlags.Value, enclosing, /*flags*/ undefined, tracker)
@@ -48868,9 +49593,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// Synthesized nodes are always treated as referenced.
return node && canCollectSymbolAliasAccessabilityData ? isReferencedAliasDeclaration(node, checkChildren) : true;
},
- getNodeCheckFlags: nodeIn => {
+ hasNodeCheckFlag: (nodeIn, flag) => {
const node = getParseTreeNode(nodeIn);
- return node ? getNodeCheckFlags(node) : 0;
+ if (!node) return false;
+ return hasNodeCheckFlag(node, flag);
},
isTopLevelValueImportEqualsWithEntityName,
isDeclarationVisible,
@@ -48893,6 +49619,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return node ? getEnumMemberValue(node) : undefined;
},
collectLinkedAliases,
+ markLinkedReferences: nodeIn => {
+ const node = getParseTreeNode(nodeIn);
+ return node && markLinkedReferences(node, ReferenceHint.Unspecified);
+ },
getReferencedValueDeclaration,
getReferencedValueDeclarations,
getTypeReferenceSerializationKind,
@@ -48903,7 +49633,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return node && getExternalModuleFileFromDeclaration(node);
},
isLiteralConstDeclaration,
- isNonNarrowedBindableName,
isLateBound: (nodeIn: Declaration): nodeIn is LateBoundDeclaration => {
const node = getParseTreeNode(nodeIn, isDeclaration);
const symbol = node && getSymbolOfDeclaration(node);
@@ -49093,42 +49822,43 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function checkExternalEmitHelpers(location: Node, helpers: ExternalEmitHelpers) {
- if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) {
+ if (compilerOptions.importHelpers) {
const sourceFile = getSourceFileOfNode(location);
if (isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & NodeFlags.Ambient)) {
const helpersModule = resolveHelpersModule(sourceFile, location);
if (helpersModule !== unknownSymbol) {
- const uncheckedHelpers = helpers & ~requestedExternalEmitHelpers;
- for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) {
- if (uncheckedHelpers & helper) {
- for (const name of getHelperNames(helper)) {
- if (requestedExternalEmitHelperNames.has(name)) continue;
- requestedExternalEmitHelperNames.add(name);
-
- const symbol = resolveSymbol(getSymbol(getExportsOfModule(helpersModule), escapeLeadingUnderscores(name), SymbolFlags.Value));
- if (!symbol) {
- error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name);
- }
- else if (helper & ExternalEmitHelpers.ClassPrivateFieldGet) {
- if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 3)) {
- error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 4);
+ const links = getSymbolLinks(helpersModule);
+ links.requestedExternalEmitHelpers ??= 0 as ExternalEmitHelpers;
+ if ((links.requestedExternalEmitHelpers & helpers) !== helpers) {
+ const uncheckedHelpers = helpers & ~links.requestedExternalEmitHelpers;
+ for (let helper = ExternalEmitHelpers.FirstEmitHelper; helper <= ExternalEmitHelpers.LastEmitHelper; helper <<= 1) {
+ if (uncheckedHelpers & helper) {
+ for (const name of getHelperNames(helper)) {
+ const symbol = resolveSymbol(getSymbol(getExportsOfModule(helpersModule), escapeLeadingUnderscores(name), SymbolFlags.Value));
+ if (!symbol) {
+ error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_which_does_not_exist_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name);
}
- }
- else if (helper & ExternalEmitHelpers.ClassPrivateFieldSet) {
- if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 4)) {
- error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 5);
+ else if (helper & ExternalEmitHelpers.ClassPrivateFieldGet) {
+ if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 3)) {
+ error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 4);
+ }
}
- }
- else if (helper & ExternalEmitHelpers.SpreadArray) {
- if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 2)) {
- error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 3);
+ else if (helper & ExternalEmitHelpers.ClassPrivateFieldSet) {
+ if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 4)) {
+ error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 5);
+ }
+ }
+ else if (helper & ExternalEmitHelpers.SpreadArray) {
+ if (!some(getSignaturesOfSymbol(symbol), signature => getParameterCount(signature) > 2)) {
+ error(location, Diagnostics.This_syntax_requires_an_imported_helper_named_1_with_2_parameters_which_is_not_compatible_with_the_one_in_0_Consider_upgrading_your_version_of_0, externalHelpersModuleNameText, name, 3);
+ }
}
}
}
}
}
+ links.requestedExternalEmitHelpers |= helpers;
}
- requestedExternalEmitHelpers |= helpers;
}
}
}
@@ -49190,11 +49920,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
- function resolveHelpersModule(node: SourceFile, errorNode: Node) {
- if (!externalHelpersModule) {
- externalHelpersModule = resolveExternalModule(node, externalHelpersModuleNameText, Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
+ function resolveHelpersModule(file: SourceFile, errorNode: Node) {
+ const links = getNodeLinks(file);
+ if (!links.externalHelpersModule) {
+ links.externalHelpersModule = resolveExternalModule(getImportHelpersImportSpecifier(file), externalHelpersModuleNameText, Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol;
}
- return externalHelpersModule;
+ return links.externalHelpersModule;
}
// GRAMMAR CHECKING
@@ -50204,7 +50935,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return true;
}
}
- return false;
}
}
@@ -51142,6 +51872,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
blockScopeKind === NodeFlags.Using ||
blockScopeKind === NodeFlags.AwaitUsing;
}
+
+ function getJSXRuntimeImportSpecifier(file: SourceFile | undefined, specifierText: string) {
+ // Synthesized JSX import is either first or after tslib
+ const jsxImportIndex = compilerOptions.importHelpers ? 1 : 0;
+ const specifier = file?.imports[jsxImportIndex];
+ if (specifier) {
+ Debug.assert(nodeIsSynthesized(specifier) && specifier.text === specifierText, `Expected sourceFile.imports[${jsxImportIndex}] to be the synthesized JSX runtime import`);
+ }
+ return specifier;
+ }
+
+ function getImportHelpersImportSpecifier(file: SourceFile) {
+ Debug.assert(compilerOptions.importHelpers, "Expected importHelpers to be enabled");
+ const specifier = file.imports[0];
+ Debug.assert(specifier && nodeIsSynthesized(specifier) && specifier.text === "tslib", `Expected sourceFile.imports[0] to be the synthesized tslib import`);
+ return specifier;
+ }
}
function isNotAccessor(declaration: Declaration): boolean {
@@ -51239,16 +51986,19 @@ interface NodeBuilderContext {
symbolDepth: Map | undefined;
inferTypeParameters: TypeParameter[] | undefined;
approximateLength: number;
- truncating?: boolean;
- typeParameterSymbolList?: Set;
- typeParameterNames?: Map;
- typeParameterNamesByText?: Set;
- typeParameterNamesByTextNextNameCount?: Map;
- usedSymbolNames?: Set;
- remappedSymbolNames?: Map;
- remappedSymbolReferences?: Map;
- reverseMappedStack?: ReverseMappedSymbol[];
- bundled?: boolean;
+ truncating: boolean;
+ mustCreateTypeParameterSymbolList: boolean;
+ typeParameterSymbolList: Set | undefined;
+ mustCreateTypeParametersNamesLookups: boolean;
+ typeParameterNames: Map | undefined;
+ typeParameterNamesByText: Set | undefined;
+ typeParameterNamesByTextNextNameCount: Map | undefined;
+ usedSymbolNames: Set | undefined;
+ remappedSymbolNames: Map | undefined;
+ remappedSymbolReferences: Map | undefined;
+ reverseMappedStack: ReverseMappedSymbol[] | undefined;
+ bundled: boolean;
+ mapper: TypeMapper | undefined;
}
class SymbolTrackerImpl implements SymbolTracker {
diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts
index 9e103d0a90dce..4a9918c9671e9 100644
--- a/src/compiler/commandLineParser.ts
+++ b/src/compiler/commandLineParser.ts
@@ -121,7 +121,7 @@ import {
WatchDirectoryKind,
WatchFileKind,
WatchOptions,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export const compileOnSaveCommandLineOption: CommandLineOption = {
@@ -778,7 +778,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
showInSimplifiedHelpView: false,
category: Diagnostics.Compiler_Diagnostics,
description: Diagnostics.Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported,
- transpileOptionValue: undefined,
+ transpileOptionValue: true,
defaultValueDescription: false,
affectsSemanticDiagnostics: true,
affectsBuildInfo: true,
@@ -1639,6 +1639,12 @@ export const configDirTemplateSubstitutionWatchOptions: readonly CommandLineOpti
option => option.allowConfigDirTemplateSubstitution || (!option.isCommandLineOnly && option.isFilePath),
);
+/** @internal */
+export const commandLineOptionOfCustomType: readonly CommandLineOptionOfCustomType[] = optionDeclarations.filter(isCommandLineOptionOfCustomType);
+function isCommandLineOptionOfCustomType(option: CommandLineOption): option is CommandLineOptionOfCustomType {
+ return !isString(option.type);
+}
+
// Build related options
/** @internal */
export const optionsForBuild: CommandLineOption[] = [
diff --git a/src/compiler/core.ts b/src/compiler/core.ts
index 93772d05b2721..d7f6fe0580d5f 100644
--- a/src/compiler/core.ts
+++ b/src/compiler/core.ts
@@ -9,7 +9,7 @@ import {
SortedArray,
SortedReadonlyArray,
TextSpan,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export const emptyArray: never[] = [] as never[];
diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts
index 98fcde9847420..baa8ce61a90f2 100644
--- a/src/compiler/debug.ts
+++ b/src/compiler/debug.ts
@@ -1,4 +1,4 @@
-import * as ts from "./_namespaces/ts";
+import * as ts from "./_namespaces/ts.js";
import {
AnyFunction,
AssertionLevel,
@@ -64,6 +64,7 @@ import {
ModifierFlags,
Node,
NodeArray,
+ NodeCheckFlags,
NodeFlags,
nodeIsSynthesized,
noop,
@@ -91,7 +92,7 @@ import {
unescapeLeadingUnderscores,
VarianceFlags,
zipWith,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export enum LogLevel {
@@ -455,6 +456,10 @@ export namespace Debug {
return formatEnum(flags, (ts as any).NodeFlags, /*isFlags*/ true);
}
+ export function formatNodeCheckFlags(flags: NodeCheckFlags | undefined): string {
+ return formatEnum(flags, (ts as any).NodeCheckFlags, /*isFlags*/ true);
+ }
+
export function formatModifierFlags(flags: ModifierFlags | undefined): string {
return formatEnum(flags, (ts as any).ModifierFlags, /*isFlags*/ true);
}
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 1db3b8c70bc30..e74033719b5b8 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -1789,7 +1789,7 @@
"category": "Error",
"code": 1533
},
- "This backreference is invalid because the containing regular expression contains no capturing groups.": {
+ "This backreference refers to a group that does not exist. There are no capturing groups in this regular expression.": {
"category": "Error",
"code": 1534
},
@@ -1797,6 +1797,14 @@
"category": "Error",
"code": 1535
},
+ "Octal escape sequences and backreferences are not allowed in a character class. If this was intended as an escape sequence, use the syntax '{0}' instead.": {
+ "category": "Error",
+ "code": 1536
+ },
+ "Decimal escape sequences and backreferences are not allowed in a character class.": {
+ "category": "Error",
+ "code": 1537
+ },
"The types of '{0}' are incompatible between these types.": {
"category": "Error",
@@ -4200,10 +4208,6 @@
"category": "Error",
"code": 4085
},
- "Conflicting definitions for '{0}' found at '{1}' and '{2}'. Consider installing a specific version of this library to resolve the conflict.": {
- "category": "Error",
- "code": 4090
- },
"Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'.": {
"category": "Error",
"code": 4091
@@ -7018,6 +7022,14 @@
"category": "Error",
"code": 9037
},
+ "Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.": {
+ "category": "Error",
+ "code": 9038
+ },
+ "Type containing private name '{0}' can't be used with --isolatedDeclarations.": {
+ "category": "Error",
+ "code": 9039
+ },
"JSX attributes must only be assigned a non-empty 'expression'.": {
"category": "Error",
"code": 17000
diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts
index 2b95abb5db68c..539190c63c336 100644
--- a/src/compiler/emitter.ts
+++ b/src/compiler/emitter.ts
@@ -1,4 +1,4 @@
-import * as ts from "./_namespaces/ts";
+import * as ts from "./_namespaces/ts.js";
import {
AccessorDeclaration,
ArrayBindingPattern,
@@ -207,6 +207,7 @@ import {
isGeneratedPrivateIdentifier,
isIdentifier,
isImportAttributes,
+ isImportEqualsDeclaration,
isIncrementalCompilation,
isInJsonFile,
isJSDocLikeText,
@@ -420,8 +421,8 @@ import {
writeCommentRange,
writeFile,
YieldExpression,
-} from "./_namespaces/ts";
-import * as performance from "./_namespaces/ts.performance";
+} from "./_namespaces/ts.js";
+import * as performance from "./_namespaces/ts.performance.js";
const brackets = createBracketsMap();
@@ -717,6 +718,11 @@ export function getFirstProjectOutput(configFile: ParsedCommandLine, ignoreCase:
return Debug.fail(`project ${configFile.options.configFilePath} expected to have at least one output`);
}
+/** @internal */
+export function emitResolverSkipsTypeChecking(emitOnly: boolean | EmitOnly | undefined, forceDtsEmit: boolean | undefined) {
+ return !!forceDtsEmit && !!emitOnly;
+}
+
/** @internal */
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile | undefined, { scriptTransformers, declarationTransformers }: EmitTransformers, emitOnly?: boolean | EmitOnly, onlyBuildInfo?: boolean, forceDtsEmit?: boolean): EmitResult {
@@ -793,6 +799,11 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
emitSkipped = true;
return;
}
+
+ if (compilerOptions.noCheck) {
+ (isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : filter(sourceFileOrBundle.sourceFiles, isSourceFileNotJson)).forEach(markLinkedReferences);
+ }
+
// Transform the source files
const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
@@ -848,7 +859,11 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
const filesForEmit = forceDtsEmit ? sourceFiles : filter(sourceFiles, isSourceFileNotJson);
// Setup and perform the transformation to retrieve declarations from the input files
const inputListOrBundle = compilerOptions.outFile ? [factory.createBundle(filesForEmit)] : filesForEmit;
- if ((emitOnly && !getEmitDeclarations(compilerOptions)) || compilerOptions.noCheck) {
+ if (
+ (emitOnly && !getEmitDeclarations(compilerOptions)) ||
+ compilerOptions.noCheck ||
+ emitResolverSkipsTypeChecking(emitOnly, forceDtsEmit)
+ ) {
// Checker wont collect the linked aliases since thats only done when declaration is enabled and checking is performed.
// Do that here when emitting only dts files
filesForEmit.forEach(collectLinkedAliases);
@@ -924,6 +939,14 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
forEachChild(node, collectLinkedAliases);
}
+ function markLinkedReferences(file: SourceFile) {
+ ts.forEachChildRecursively(file, n => {
+ if (isImportEqualsDeclaration(n) && !(ts.getSyntacticModifierFlags(n) & ts.ModifierFlags.Export)) return "skip"; // These are deferred and marked in a chain when referenced
+ if (ts.isImportDeclaration(n)) return "skip"; // likewise, these are ultimately what get marked by calls on other nodes - we want to skip them
+ resolver.markLinkedReferences(n);
+ });
+ }
+
function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, transform: TransformationResult, printer: Printer, mapOptions: SourceMapOptions) {
const sourceFileOrBundle = transform.transformed[0];
const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined;
@@ -1090,10 +1113,11 @@ export const notImplementedResolver: EmitResolver = {
isValueAliasDeclaration: notImplemented,
isReferencedAliasDeclaration: notImplemented,
isTopLevelValueImportEqualsWithEntityName: notImplemented,
- getNodeCheckFlags: notImplemented,
+ hasNodeCheckFlag: notImplemented,
isDeclarationVisible: notImplemented,
isLateBound: (_node): _node is LateBoundDeclaration => false,
collectLinkedAliases: notImplemented,
+ markLinkedReferences: notImplemented,
isImplementationOfOverload: notImplemented,
requiresAddingImplicitUndefined: notImplemented,
isExpandoFunctionDeclaration: notImplemented,
@@ -1114,7 +1138,6 @@ export const notImplementedResolver: EmitResolver = {
isArgumentsLocalBinding: notImplemented,
getExternalModuleFileFromDeclaration: notImplemented,
isLiteralConstDeclaration: notImplemented,
- isNonNarrowedBindableName: notImplemented,
getJsxFactoryEntity: notImplemented,
getJsxFragmentFactoryEntity: notImplemented,
isBindingCapturedByNode: notImplemented,
@@ -2125,13 +2148,9 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function emitComputedPropertyName(node: ComputedPropertyName) {
- const savedPrivateNameTempFlags = privateNameTempFlags;
- const savedReservedMemberNames = reservedPrivateNames;
- popPrivateNameGenerationScope();
writePunctuation("[");
emitExpression(node.expression, parenthesizer.parenthesizeExpressionOfComputedPropertyName);
writePunctuation("]");
- pushPrivateNameGenerationScope(savedPrivateNameTempFlags, savedReservedMemberNames);
}
//
@@ -2198,15 +2217,10 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function emitMethodSignature(node: MethodSignature) {
- pushNameGenerationScope(node);
emitModifierList(node, node.modifiers);
emit(node.name);
emit(node.questionToken);
- emitTypeParameters(node, node.typeParameters);
- emitParameters(node, node.parameters);
- emitTypeAnnotation(node.type);
- writeTrailingSemicolon();
- popNameGenerationScope(node);
+ emitSignatureAndBody(node, emitSignatureHead, emitEmptyFunctionBody);
}
function emitMethodDeclaration(node: MethodDeclaration) {
@@ -2214,18 +2228,20 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emit(node.asteriskToken);
emit(node.name);
emit(node.questionToken);
- emitSignatureAndBody(node, emitSignatureHead);
+ emitSignatureAndBody(node, emitSignatureHead, emitFunctionBody);
}
function emitClassStaticBlockDeclaration(node: ClassStaticBlockDeclaration) {
writeKeyword("static");
+ pushNameGenerationScope(node);
emitBlockFunctionBody(node.body);
+ popNameGenerationScope(node);
}
function emitConstructor(node: ConstructorDeclaration) {
emitDecoratorsAndModifiers(node, node.modifiers, /*allowDecorators*/ false);
writeKeyword("constructor");
- emitSignatureAndBody(node, emitSignatureHead);
+ emitSignatureAndBody(node, emitSignatureHead, emitFunctionBody);
}
function emitAccessorDeclaration(node: AccessorDeclaration) {
@@ -2234,27 +2250,17 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emitTokenWithComment(token, pos, writeKeyword, node);
writeSpace();
emit(node.name);
- emitSignatureAndBody(node, emitSignatureHead);
+ emitSignatureAndBody(node, emitSignatureHead, emitFunctionBody);
}
function emitCallSignature(node: CallSignatureDeclaration) {
- pushNameGenerationScope(node);
- emitTypeParameters(node, node.typeParameters);
- emitParameters(node, node.parameters);
- emitTypeAnnotation(node.type);
- writeTrailingSemicolon();
- popNameGenerationScope(node);
+ emitSignatureAndBody(node, emitSignatureHead, emitEmptyFunctionBody);
}
function emitConstructSignature(node: ConstructSignatureDeclaration) {
- pushNameGenerationScope(node);
writeKeyword("new");
writeSpace();
- emitTypeParameters(node, node.typeParameters);
- emitParameters(node, node.parameters);
- emitTypeAnnotation(node.type);
- writeTrailingSemicolon();
- popNameGenerationScope(node);
+ emitSignatureAndBody(node, emitSignatureHead, emitEmptyFunctionBody);
}
function emitIndexSignature(node: IndexSignatureDeclaration) {
@@ -2297,14 +2303,19 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function emitFunctionType(node: FunctionTypeNode) {
- pushNameGenerationScope(node);
+ emitSignatureAndBody(node, emitFunctionTypeHead, emitFunctionTypeBody);
+ }
+
+ function emitFunctionTypeHead(node: FunctionTypeNode | ConstructorTypeNode) {
emitTypeParameters(node, node.typeParameters);
emitParametersForArrow(node, node.parameters);
writeSpace();
writePunctuation("=>");
+ }
+
+ function emitFunctionTypeBody(node: FunctionTypeNode | ConstructorTypeNode) {
writeSpace();
emit(node.type);
- popNameGenerationScope(node);
}
function emitJSDocFunctionType(node: JSDocFunctionType) {
@@ -2330,17 +2341,10 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function emitConstructorType(node: ConstructorTypeNode) {
- pushNameGenerationScope(node);
emitModifierList(node, node.modifiers);
writeKeyword("new");
writeSpace();
- emitTypeParameters(node, node.typeParameters);
- emitParameters(node, node.parameters);
- writeSpace();
- writePunctuation("=>");
- writeSpace();
- emit(node.type);
- popNameGenerationScope(node);
+ emitSignatureAndBody(node, emitFunctionTypeHead, emitFunctionTypeBody);
}
function emitTypeQuery(node: TypeQueryNode) {
@@ -2351,16 +2355,15 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function emitTypeLiteral(node: TypeLiteralNode) {
- // Type literals don't have private names, but we need to push a new scope so that
- // we can step out of it when emitting a computed property.
- pushPrivateNameGenerationScope(TempFlags.Auto, /*newReservedMemberNames*/ undefined);
+ pushNameGenerationScope(node);
+ forEach(node.members, generateMemberNames);
writePunctuation("{");
const flags = getEmitFlags(node) & EmitFlags.SingleLine ? ListFormat.SingleLineTypeLiteralMembers : ListFormat.MultiLineTypeLiteralMembers;
emitList(node, node.members, flags | ListFormat.NoSpaceIfEmpty);
writePunctuation("}");
- popPrivateNameGenerationScope();
+ popNameGenerationScope(node);
}
function emitArrayType(node: ArrayTypeNode) {
@@ -2569,9 +2572,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function emitObjectLiteralExpression(node: ObjectLiteralExpression) {
- // Object literals don't have private names, but we need to push a new scope so that
- // we can step out of it when emitting a computed property.
- pushPrivateNameGenerationScope(TempFlags.Auto, /*newReservedMemberNames*/ undefined);
+ pushNameGenerationScope(node);
forEach(node.properties, generateMemberNames);
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
@@ -2587,7 +2588,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
decreaseIndent();
}
- popPrivateNameGenerationScope();
+ popNameGenerationScope(node);
}
function emitPropertyAccessExpression(node: PropertyAccessExpression) {
@@ -2714,7 +2715,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
function emitArrowFunction(node: ArrowFunction) {
emitModifierList(node, node.modifiers);
- emitSignatureAndBody(node, emitArrowFunctionHead);
+ emitSignatureAndBody(node, emitArrowFunctionHead, emitArrowFunctionBody);
}
function emitArrowFunctionHead(node: ArrowFunction) {
@@ -2725,6 +2726,16 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emit(node.equalsGreaterThanToken);
}
+ function emitArrowFunctionBody(node: ArrowFunction) {
+ if (isBlock(node.body)) {
+ emitBlockFunctionBody(node.body);
+ }
+ else {
+ writeSpace();
+ emitExpression(node.body, parenthesizer.parenthesizeConciseBodyOfArrowFunction);
+ }
+ }
+
function emitDeleteExpression(node: DeleteExpression) {
emitTokenWithComment(SyntaxKind.DeleteKeyword, node.pos, writeKeyword, node);
writeSpace();
@@ -3305,42 +3316,40 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emit(node.asteriskToken);
writeSpace();
emitIdentifierName(node.name);
- emitSignatureAndBody(node, emitSignatureHead);
+ emitSignatureAndBody(node, emitSignatureHead, emitFunctionBody);
}
- function emitSignatureAndBody(node: T, emitSignatureHead: (node: T) => void) {
- const body = node.body;
- if (body) {
- if (isBlock(body)) {
- const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
- if (indentedFlag) {
- increaseIndent();
- }
+ function emitSignatureAndBody(node: T, emitSignatureHead: (node: T) => void, emitBody: (node: T) => void) {
+ const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
+ if (indentedFlag) {
+ increaseIndent();
+ }
- pushNameGenerationScope(node);
- forEach(node.parameters, generateNames);
- generateNames(node.body);
+ pushNameGenerationScope(node);
+ forEach(node.parameters, generateNames);
+ emitSignatureHead(node);
+ emitBody(node);
+ popNameGenerationScope(node);
- emitSignatureHead(node);
- emitBlockFunctionBody(body);
- popNameGenerationScope(node);
+ if (indentedFlag) {
+ decreaseIndent();
+ }
+ }
- if (indentedFlag) {
- decreaseIndent();
- }
- }
- else {
- emitSignatureHead(node);
- writeSpace();
- emitExpression(body, parenthesizer.parenthesizeConciseBodyOfArrowFunction);
- }
+ function emitFunctionBody>(node: T) {
+ const body = node.body;
+ if (body) {
+ emitBlockFunctionBody(body);
}
else {
- emitSignatureHead(node);
writeTrailingSemicolon();
}
}
+ function emitEmptyFunctionBody(_node: SignatureDeclaration) {
+ writeTrailingSemicolon();
+ }
+
function emitSignatureHead(node: SignatureDeclaration) {
emitTypeParameters(node, node.typeParameters);
emitParameters(node, node.parameters);
@@ -3388,6 +3397,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function emitBlockFunctionBody(body: Block) {
+ generateNames(body);
onBeforeEmitNode?.(body);
writeSpace();
writePunctuation("{");
@@ -3428,10 +3438,6 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function emitClassDeclarationOrExpression(node: ClassDeclaration | ClassExpression) {
- pushPrivateNameGenerationScope(TempFlags.Auto, /*newReservedMemberNames*/ undefined);
-
- forEach(node.members, generateMemberNames);
-
emitDecoratorsAndModifiers(node, node.modifiers, /*allowDecorators*/ true);
emitTokenWithComment(SyntaxKind.ClassKeyword, moveRangePastModifiers(node).pos, writeKeyword, node);
if (node.name) {
@@ -3446,24 +3452,22 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emitTypeParameters(node, node.typeParameters);
emitList(node, node.heritageClauses, ListFormat.ClassHeritageClauses);
-
writeSpace();
writePunctuation("{");
+
+ pushNameGenerationScope(node);
+ forEach(node.members, generateMemberNames);
emitList(node, node.members, ListFormat.ClassMembers);
+ popNameGenerationScope(node);
+
writePunctuation("}");
if (indentedFlag) {
decreaseIndent();
}
-
- popPrivateNameGenerationScope();
}
function emitInterfaceDeclaration(node: InterfaceDeclaration) {
- // Interfaces don't have private names, but we need to push a new scope so that
- // we can step out of it when emitting a computed property.
- pushPrivateNameGenerationScope(TempFlags.Auto, /*newReservedMemberNames*/ undefined);
-
emitDecoratorsAndModifiers(node, node.modifiers, /*allowDecorators*/ false);
writeKeyword("interface");
writeSpace();
@@ -3472,10 +3476,13 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emitList(node, node.heritageClauses, ListFormat.HeritageClauses);
writeSpace();
writePunctuation("{");
+
+ pushNameGenerationScope(node);
+ forEach(node.members, generateMemberNames);
emitList(node, node.members, ListFormat.InterfaceMembers);
- writePunctuation("}");
+ popNameGenerationScope(node);
- popPrivateNameGenerationScope();
+ writePunctuation("}");
}
function emitTypeAliasDeclaration(node: TypeAliasDeclaration) {
@@ -4488,7 +4495,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emitList(parentNode, parameters, ListFormat.Parameters);
}
- function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) {
+ function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ConstructorTypeNode | ArrowFunction, parameters: NodeArray) {
const parameter = singleOrUndefined(parameters);
return parameter
&& parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter
@@ -4504,7 +4511,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
&& isIdentifier(parameter.name); // parameter name must be identifier
}
- function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray) {
+ function emitParametersForArrow(parentNode: FunctionTypeNode | ConstructorTypeNode | ArrowFunction, parameters: NodeArray) {
if (canEmitSimpleArrowHead(parentNode, parameters)) {
emitList(parentNode, parameters, ListFormat.Parameters & ~ListFormat.Parenthesis);
}
@@ -5172,9 +5179,14 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
* Push a new name generation scope.
*/
function pushNameGenerationScope(node: Node | undefined) {
+ privateNameTempFlagsStack.push(privateNameTempFlags);
+ privateNameTempFlags = TempFlags.Auto;
+ reservedPrivateNamesStack.push(reservedPrivateNames);
+
if (node && getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) {
return;
}
+
tempFlagsStack.push(tempFlags);
tempFlags = TempFlags.Auto;
formattedNameTempFlagsStack.push(formattedNameTempFlags);
@@ -5186,9 +5198,13 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
* Pop the current name generation scope.
*/
function popNameGenerationScope(node: Node | undefined) {
+ privateNameTempFlags = privateNameTempFlagsStack.pop()!;
+ reservedPrivateNames = reservedPrivateNamesStack.pop();
+
if (node && getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) {
return;
}
+
tempFlags = tempFlagsStack.pop()!;
formattedNameTempFlags = formattedNameTempFlagsStack.pop();
reservedNames = reservedNamesStack.pop();
@@ -5201,24 +5217,6 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
reservedNames.add(name);
}
- /**
- * Push a new member name generation scope.
- */
- function pushPrivateNameGenerationScope(newPrivateNameTempFlags: TempFlags, newReservedMemberNames: Set | undefined) {
- privateNameTempFlagsStack.push(privateNameTempFlags);
- privateNameTempFlags = newPrivateNameTempFlags;
- reservedPrivateNamesStack.push(reservedNames);
- reservedPrivateNames = newReservedMemberNames;
- }
-
- /**
- * Pop the current member name generation scope.
- */
- function popPrivateNameGenerationScope() {
- privateNameTempFlags = privateNameTempFlagsStack.pop()!;
- reservedPrivateNames = reservedPrivateNamesStack.pop();
- }
-
function reservePrivateNameInNestedScopes(name: string) {
if (!reservedPrivateNames || reservedPrivateNames === lastOrUndefined(reservedPrivateNamesStack)) {
reservedPrivateNames = new Set();
@@ -5318,7 +5316,9 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
case SyntaxKind.PropertyAssignment:
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.PropertyDeclaration:
+ case SyntaxKind.PropertySignature:
case SyntaxKind.MethodDeclaration:
+ case SyntaxKind.MethodSignature:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
generateNameIfNeeded((node as NamedDeclaration).name);
@@ -5372,7 +5372,30 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function isReservedName(name: string, privateName: boolean): boolean {
- return privateName ? !!reservedPrivateNames?.has(name) : !!reservedNames?.has(name);
+ let set: Set | undefined;
+ let stack: (Set | undefined)[];
+ if (privateName) {
+ set = reservedPrivateNames;
+ stack = reservedPrivateNamesStack;
+ }
+ else {
+ set = reservedNames;
+ stack = reservedNamesStack;
+ }
+
+ if (set?.has(name)) {
+ return true;
+ }
+ for (let i = stack.length - 1; i >= 0; i--) {
+ if (set === stack[i]) {
+ continue;
+ }
+ set = stack[i];
+ if (set?.has(name)) {
+ return true;
+ }
+ }
+ return false;
}
/**
diff --git a/src/compiler/executeCommandLine.ts b/src/compiler/executeCommandLine.ts
index 4053523f3565b..f9b1400b4daad 100644
--- a/src/compiler/executeCommandLine.ts
+++ b/src/compiler/executeCommandLine.ts
@@ -86,8 +86,8 @@ import {
WatchCompilerHost,
WatchOfConfigFile,
WatchOptions,
-} from "./_namespaces/ts";
-import * as performance from "./performance";
+} from "./_namespaces/ts.js";
+import * as performance from "./performance.js";
interface Statistic {
name: string;
diff --git a/src/compiler/expressionToTypeNode.ts b/src/compiler/expressionToTypeNode.ts
index a9f64a4919bc8..e1a9c0548a77e 100644
--- a/src/compiler/expressionToTypeNode.ts
+++ b/src/compiler/expressionToTypeNode.ts
@@ -14,10 +14,12 @@ import {
Expression,
forEachReturnStatement,
FunctionExpression,
+ FunctionFlags,
FunctionLikeDeclaration,
GetAccessorDeclaration,
getEffectiveReturnTypeNode,
getEffectiveTypeAnnotationNode,
+ getFunctionFlags,
getJSDocTypeAssertionType,
getStrictOptionValue,
HasInferredType,
@@ -26,12 +28,10 @@ import {
isBlock,
isConstTypeReference,
isDeclarationReadonly,
- isEntityNameExpression,
isGetAccessor,
isIdentifier,
isJSDocTypeAssertion,
isKeyword,
- isParameter,
isPrimitiveLiteralValue,
isShorthandPropertyAssignment,
isSpreadAssignment,
@@ -55,7 +55,6 @@ import {
PropertySignature,
SetAccessorDeclaration,
SignatureDeclaration,
- SymbolAccessibility,
SyntacticTypeNodeBuilderContext,
SyntacticTypeNodeBuilderResolver,
SyntaxKind,
@@ -64,7 +63,7 @@ import {
TypeParameterDeclaration,
UnionTypeNode,
VariableDeclaration,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolver: SyntacticTypeNodeBuilderResolver) {
@@ -76,8 +75,8 @@ export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolve
serializeReturnTypeForSignature,
serializeTypeOfExpression,
};
- function serializeExistingTypeAnnotation(type: TypeNode | undefined) {
- return type === undefined ? undefined : !type.parent || !isParameter(type.parent) || !resolver.requiresAddingImplicitUndefined(type.parent) || canAddUndefined(type);
+ function serializeExistingTypeAnnotation(type: TypeNode | undefined, addUndefined?: boolean) {
+ return type !== undefined && (!addUndefined || (type && canAddUndefined(type))) ? true : undefined;
}
function serializeTypeOfExpression(expr: Expression, context: SyntacticTypeNodeBuilderContext, addUndefined?: boolean, preserveLiterals?: boolean) {
return typeFromExpression(expr, context, /*isConstContext*/ false, addUndefined, preserveLiterals) ?? inferExpressionType(expr, context);
@@ -181,12 +180,12 @@ export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolve
const declaredType = getEffectiveTypeAnnotationNode(node);
const addUndefined = resolver.requiresAddingImplicitUndefined(node);
let resultType;
- if (!addUndefined) {
- if (declaredType) {
- return serializeExistingTypeAnnotation(declaredType);
- }
+ if (declaredType) {
+ resultType = serializeExistingTypeAnnotation(declaredType, addUndefined);
+ }
+ else {
if (node.initializer && isIdentifier(node.name)) {
- resultType = typeFromExpression(node.initializer, context);
+ resultType = typeFromExpression(node.initializer, context, /*isConstContext*/ undefined, addUndefined);
}
}
return resultType ?? inferTypeOfDeclaration(node, context);
@@ -351,7 +350,7 @@ export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolve
}
else if (prop.name.kind === SyntaxKind.ComputedPropertyName) {
const expression = prop.name.expression;
- if (!isPrimitiveLiteralValue(expression, /*includeBigInt*/ false) && !isEntityNameExpression(expression)) {
+ if (!isPrimitiveLiteralValue(expression, /*includeBigInt*/ false)) {
context.tracker.reportInferenceFallback(prop.name);
result = false;
}
@@ -367,17 +366,6 @@ export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolve
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;
@@ -482,6 +470,8 @@ export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolve
function typeFromSingleReturnExpression(declaration: FunctionLikeDeclaration | undefined, context: SyntacticTypeNodeBuilderContext): boolean | undefined {
let candidateExpr: Expression | undefined;
if (declaration && !nodeIsMissing(declaration.body)) {
+ if (getFunctionFlags(declaration) & FunctionFlags.AsyncGenerator) return undefined;
+
const body = declaration.body;
if (body && isBlock(body)) {
forEachReturnStatement(body, s => {
diff --git a/src/compiler/factory/baseNodeFactory.ts b/src/compiler/factory/baseNodeFactory.ts
index 9ea81cdf5632b..4043f1a8931a1 100644
--- a/src/compiler/factory/baseNodeFactory.ts
+++ b/src/compiler/factory/baseNodeFactory.ts
@@ -2,7 +2,7 @@ import {
Node,
objectAllocator,
SyntaxKind,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/**
* A `BaseNodeFactory` is an abstraction over an `ObjectAllocator` that handles caching `Node` constructors
diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts
index 0937915e75b16..365dc03925d07 100644
--- a/src/compiler/factory/emitHelpers.ts
+++ b/src/compiler/factory/emitHelpers.ts
@@ -35,7 +35,7 @@ import {
TextRange,
TransformationContext,
UnscopedEmitHelper,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export const enum PrivateIdentifierKind {
@@ -1395,7 +1395,7 @@ export const addDisposableResourceHelper: UnscopedEmitHelper = {
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
if (value !== null && value !== void 0) {
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
- var dispose;
+ var dispose, inner;
if (async) {
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
dispose = value[Symbol.asyncDispose];
@@ -1403,8 +1403,10 @@ export const addDisposableResourceHelper: UnscopedEmitHelper = {
if (dispose === void 0) {
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
dispose = value[Symbol.dispose];
+ if (async) inner = dispose;
}
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
env.stack.push({ value: value, dispose: dispose, async: async });
}
else if (async) {
diff --git a/src/compiler/factory/emitNode.ts b/src/compiler/factory/emitNode.ts
index fba507d899ea7..9d649979b8f24 100644
--- a/src/compiler/factory/emitNode.ts
+++ b/src/compiler/factory/emitNode.ts
@@ -26,7 +26,7 @@ import {
TextRange,
TypeNode,
TypeParameterDeclaration,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/**
* Associates a node with the current transformation, initializing
diff --git a/src/compiler/factory/nodeChildren.ts b/src/compiler/factory/nodeChildren.ts
index aa41f5955fb69..79e8563f6f593 100644
--- a/src/compiler/factory/nodeChildren.ts
+++ b/src/compiler/factory/nodeChildren.ts
@@ -2,7 +2,7 @@ import {
emptyArray,
isNodeKind,
Node,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
const nodeChildren = new WeakMap();
diff --git a/src/compiler/factory/nodeConverters.ts b/src/compiler/factory/nodeConverters.ts
index 33ab7b4b598ad..14ef80f2ae379 100644
--- a/src/compiler/factory/nodeConverters.ts
+++ b/src/compiler/factory/nodeConverters.ts
@@ -35,7 +35,7 @@ import {
setStartsOnNewLine,
setTextRange,
SyntaxKind,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export function createNodeConverters(factory: NodeFactory): NodeConverters {
diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts
index 78e3e3e5fd5ef..9fcd2a4acf7c1 100644
--- a/src/compiler/factory/nodeFactory.ts
+++ b/src/compiler/factory/nodeFactory.ts
@@ -456,7 +456,7 @@ import {
WhileStatement,
WithStatement,
YieldExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
let nextAutoGenerateId = 0;
diff --git a/src/compiler/factory/nodeTests.ts b/src/compiler/factory/nodeTests.ts
index 012616ac5dc70..cd31b63f81843 100644
--- a/src/compiler/factory/nodeTests.ts
+++ b/src/compiler/factory/nodeTests.ts
@@ -227,7 +227,7 @@ import {
WhileStatement,
WithStatement,
YieldExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
// Literals
diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts
index b90cc220fb616..3a67604847438 100644
--- a/src/compiler/factory/parenthesizerRules.ts
+++ b/src/compiler/factory/parenthesizerRules.ts
@@ -48,7 +48,7 @@ import {
SyntaxKind,
TypeNode,
UnaryExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export function createParenthesizerRules(factory: NodeFactory): ParenthesizerRules {
diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts
index 731c13d78ec60..502ffd17db5e0 100644
--- a/src/compiler/factory/utilities.ts
+++ b/src/compiler/factory/utilities.ts
@@ -180,7 +180,7 @@ import {
TransformFlags,
TypeNode,
WrappedExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
// Compound nodes
diff --git a/src/compiler/factory/utilitiesPublic.ts b/src/compiler/factory/utilitiesPublic.ts
index 5380a4a1604e0..be395a64523a4 100644
--- a/src/compiler/factory/utilitiesPublic.ts
+++ b/src/compiler/factory/utilitiesPublic.ts
@@ -5,7 +5,7 @@ import {
setTextRangePosEnd,
SyntaxKind,
TextRange,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
export function setTextRange(range: T, location: TextRange | undefined): T {
return location ? setTextRangePosEnd(range, location.pos, location.end) : range;
diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts
index 699e902dab5a6..9ede133aae270 100644
--- a/src/compiler/moduleNameResolver.ts
+++ b/src/compiler/moduleNameResolver.ts
@@ -108,7 +108,7 @@ import {
version,
versionMajorMinor,
VersionRange,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void {
diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts
index cf3eeca0488f8..6e21b0678a9c1 100644
--- a/src/compiler/moduleSpecifiers.ts
+++ b/src/compiler/moduleSpecifiers.ts
@@ -107,6 +107,7 @@ import {
removeTrailingDirectorySeparator,
replaceFirstStar,
ResolutionMode,
+ ResolvedModuleSpecifierInfo,
resolveModuleName,
resolvePath,
ScriptKind,
@@ -124,7 +125,7 @@ import {
tryParsePatterns,
TypeChecker,
UserPreferences,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
// Used by importFixes, getEditsForFileRename, and declaration emit to synthesize import module specifiers.
@@ -287,14 +288,15 @@ export function tryGetModuleSpecifiersFromCache(
host: ModuleSpecifierResolutionHost,
userPreferences: UserPreferences,
options: ModuleSpecifierOptions = {},
-): readonly string[] | undefined {
- return tryGetModuleSpecifiersFromCacheWorker(
+): ModuleSpecifierResult | undefined {
+ const result = tryGetModuleSpecifiersFromCacheWorker(
moduleSymbol,
importingSourceFile,
host,
userPreferences,
options,
- )[0];
+ );
+ return result[1] && { kind: result[0], moduleSpecifiers: result[1], computedWithoutCache: false };
}
function tryGetModuleSpecifiersFromCacheWorker(
@@ -303,7 +305,7 @@ function tryGetModuleSpecifiersFromCacheWorker(
host: ModuleSpecifierResolutionHost,
userPreferences: UserPreferences,
options: ModuleSpecifierOptions = {},
-): readonly [specifiers?: readonly string[], moduleFile?: SourceFile, modulePaths?: readonly ModulePath[], cache?: ModuleSpecifierCache] {
+): readonly [kind?: ModuleSpecifierResult["kind"], specifiers?: readonly string[], moduleFile?: SourceFile, modulePaths?: readonly ModulePath[], cache?: ModuleSpecifierCache] {
const moduleSourceFile = getSourceFileOfModule(moduleSymbol);
if (!moduleSourceFile) {
return emptyArray as [];
@@ -311,7 +313,7 @@ function tryGetModuleSpecifiersFromCacheWorker(
const cache = host.getModuleSpecifierCache?.();
const cached = cache?.get(importingSourceFile.path, moduleSourceFile.path, userPreferences, options);
- return [cached?.moduleSpecifiers, moduleSourceFile, cached?.modulePaths, cache];
+ return [cached?.kind, cached?.moduleSpecifiers, moduleSourceFile, cached?.modulePaths, cache];
}
/**
@@ -340,6 +342,13 @@ export function getModuleSpecifiers(
).moduleSpecifiers;
}
+/** @internal */
+export interface ModuleSpecifierResult {
+ kind: ResolvedModuleSpecifierInfo["kind"];
+ moduleSpecifiers: readonly string[];
+ computedWithoutCache: boolean;
+}
+
/** @internal */
export function getModuleSpecifiersWithCacheInfo(
moduleSymbol: Symbol,
@@ -350,21 +359,21 @@ export function getModuleSpecifiersWithCacheInfo(
userPreferences: UserPreferences,
options: ModuleSpecifierOptions = {},
forAutoImport: boolean,
-): { moduleSpecifiers: readonly string[]; computedWithoutCache: boolean; } {
+): ModuleSpecifierResult {
let computedWithoutCache = false;
const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol, checker);
- if (ambient) return { moduleSpecifiers: [ambient], computedWithoutCache };
+ if (ambient) return { kind: "ambient", moduleSpecifiers: [ambient], computedWithoutCache };
// eslint-disable-next-line prefer-const
- let [specifiers, moduleSourceFile, modulePaths, cache] = tryGetModuleSpecifiersFromCacheWorker(
+ let [kind, specifiers, moduleSourceFile, modulePaths, cache] = tryGetModuleSpecifiersFromCacheWorker(
moduleSymbol,
importingSourceFile,
host,
userPreferences,
options,
);
- if (specifiers) return { moduleSpecifiers: specifiers, computedWithoutCache };
- if (!moduleSourceFile) return { moduleSpecifiers: emptyArray, computedWithoutCache };
+ if (specifiers) return { kind, moduleSpecifiers: specifiers, computedWithoutCache };
+ if (!moduleSourceFile) return { kind: undefined, moduleSpecifiers: emptyArray, computedWithoutCache };
computedWithoutCache = true;
modulePaths ||= getAllModulePathsWorker(getInfo(importingSourceFile.fileName, host), moduleSourceFile.originalFileName, host, compilerOptions, options);
@@ -377,8 +386,8 @@ export function getModuleSpecifiersWithCacheInfo(
options,
forAutoImport,
);
- cache?.set(importingSourceFile.path, moduleSourceFile.path, userPreferences, options, modulePaths, result);
- return { moduleSpecifiers: result, computedWithoutCache };
+ cache?.set(importingSourceFile.path, moduleSourceFile.path, userPreferences, options, result.kind, modulePaths, result.moduleSpecifiers);
+ return result;
}
/** @internal */
@@ -409,7 +418,7 @@ function computeModuleSpecifiers(
userPreferences: UserPreferences,
options: ModuleSpecifierOptions = {},
forAutoImport: boolean,
-): readonly string[] {
+): ModuleSpecifierResult {
const info = getInfo(importingSourceFile.fileName, host);
const preferences = getModuleSpecifierPreferences(userPreferences, host, compilerOptions, importingSourceFile);
const existingSpecifier = isFullSourceFile(importingSourceFile) && forEach(modulePaths, modulePath =>
@@ -432,8 +441,7 @@ function computeModuleSpecifiers(
},
));
if (existingSpecifier) {
- const moduleSpecifiers = [existingSpecifier];
- return moduleSpecifiers;
+ return { kind: undefined, moduleSpecifiers: [existingSpecifier], computedWithoutCache: true };
}
const importedFileIsInNodeModules = some(modulePaths, p => p.isInNodeModules);
@@ -455,7 +463,7 @@ function computeModuleSpecifiers(
if (specifier && modulePath.isRedirect) {
// If we got a specifier for a redirect, it was a bare package specifier (e.g. "@foo/bar",
// not "@foo/bar/path/to/file"). No other specifier will be this good, so stop looking.
- return nodeModulesSpecifiers!;
+ return { kind: "node_modules", moduleSpecifiers: nodeModulesSpecifiers!, computedWithoutCache: true };
}
if (!specifier) {
@@ -501,10 +509,10 @@ function computeModuleSpecifiers(
}
}
- return pathsSpecifiers?.length ? pathsSpecifiers :
- redirectPathsSpecifiers?.length ? redirectPathsSpecifiers :
- nodeModulesSpecifiers?.length ? nodeModulesSpecifiers :
- Debug.checkDefined(relativeSpecifiers);
+ return pathsSpecifiers?.length ? { kind: "paths", moduleSpecifiers: pathsSpecifiers, computedWithoutCache: true } :
+ redirectPathsSpecifiers?.length ? { kind: "redirect", moduleSpecifiers: redirectPathsSpecifiers, computedWithoutCache: true } :
+ nodeModulesSpecifiers?.length ? { kind: "node_modules", moduleSpecifiers: nodeModulesSpecifiers, computedWithoutCache: true } :
+ { kind: "relative", moduleSpecifiers: Debug.checkDefined(relativeSpecifiers), computedWithoutCache: true };
}
interface Info {
diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts
index 80c63bbe58964..56b958bcf3b74 100644
--- a/src/compiler/parser.ts
+++ b/src/compiler/parser.ts
@@ -62,7 +62,6 @@ import {
DeleteExpression,
Diagnostic,
DiagnosticArguments,
- DiagnosticCategory,
DiagnosticMessage,
Diagnostics,
DiagnosticWithDetachedLocation,
@@ -397,8 +396,8 @@ import {
WhileStatement,
WithStatement,
YieldExpression,
-} from "./_namespaces/ts";
-import * as performance from "./_namespaces/ts.performance";
+} from "./_namespaces/ts.js";
+import * as performance from "./_namespaces/ts.performance.js";
const enum SignatureFlags {
None = 0,
@@ -2144,11 +2143,7 @@ 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 (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) {
+ if (!lastError || start !== lastError.start) {
result = createDetachedDiagnostic(fileName, sourceText, start, length, message, ...args);
parseDiagnostics.push(result);
}
diff --git a/src/compiler/path.ts b/src/compiler/path.ts
index 8c7f75f816a8b..cbafbb785147f 100644
--- a/src/compiler/path.ts
+++ b/src/compiler/path.ts
@@ -16,7 +16,7 @@ import {
Path,
some,
startsWith,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/**
* Internally, we represent paths as strings with '/' as the directory separator.
diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts
index 40b333041e636..6784d1d0f7dce 100644
--- a/src/compiler/performance.ts
+++ b/src/compiler/performance.ts
@@ -7,7 +7,7 @@ import {
System,
timestamp,
tryGetNativePerformanceHooks,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** Performance measurements for the compiler. */
diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts
index 9493115ea1ed3..abff50eb8aae6 100644
--- a/src/compiler/performanceCore.ts
+++ b/src/compiler/performanceCore.ts
@@ -1,4 +1,4 @@
-import { isNodeLikeSystem } from "./_namespaces/ts";
+import { isNodeLikeSystem } from "./_namespaces/ts.js";
// The following definitions provide the minimum compatible support for the Web Performance User Timings API
// between browsers and NodeJS:
diff --git a/src/compiler/program.ts b/src/compiler/program.ts
index a89ae1f365f1d..0402c1bba985d 100644
--- a/src/compiler/program.ts
+++ b/src/compiler/program.ts
@@ -15,6 +15,7 @@ import {
changesAffectingProgramStructure,
changesAffectModuleResolution,
combinePaths,
+ commandLineOptionOfCustomType,
CommentDirective,
CommentDirectivesMap,
compareDataObjects,
@@ -67,6 +68,7 @@ import {
EmitHost,
emitModuleKindIsNonNodeESM,
EmitOnly,
+ emitResolverSkipsTypeChecking,
EmitResult,
emptyArray,
ensureTrailingDirectorySeparator,
@@ -86,6 +88,7 @@ import {
fileIncludeReasonToDiagnostics,
FilePreprocessingDiagnostics,
FilePreprocessingDiagnosticsKind,
+ FilePreprocessingLibReferenceDiagnostic,
FileReference,
filter,
find,
@@ -326,8 +329,8 @@ import {
WriteFileCallback,
WriteFileCallbackData,
writeFileEnsuringDirectories,
-} from "./_namespaces/ts";
-import * as performance from "./_namespaces/ts.performance";
+} from "./_namespaces/ts.js";
+import * as performance from "./_namespaces/ts.performance.js";
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string | undefined {
return forEachAncestorDirectory(searchPath, ancestor => {
@@ -1056,8 +1059,7 @@ export function createModuleResolutionLoader(
}
function getTypeReferenceResolutionName(entry: T) {
- // We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
- return !isString(entry) ? toFileNameLowerCase(entry.fileName) : entry;
+ return !isString(entry) ? entry.fileName : entry;
}
const typeReferenceResolutionNameAndModeGetter: ResolutionNameAndModeGetter = {
@@ -1190,10 +1192,13 @@ export function getLibraryNameFromLibFileName(libFileName: string) {
return "@typescript/lib-" + path;
}
+function getLibNameFromLibReference(libReference: FileReference) {
+ return toFileNameLowerCase(libReference.fileName);
+}
+
function getLibFileNameFromLibReference(libReference: FileReference) {
- const libName = toFileNameLowerCase(libReference.fileName);
- const libFileName = libMap.get(libName);
- return { libName, libFileName };
+ const libName = getLibNameFromLibReference(libReference);
+ return libMap.get(libName);
}
interface DiagnosticCache {
@@ -1238,11 +1243,11 @@ export function isReferenceFileLocation(location: ReferenceFileLocation | Synthe
export function getReferencedFileLocation(program: Program, ref: ReferencedFile): ReferenceFileLocation | SyntheticReferenceFileLocation {
const file = Debug.checkDefined(program.getSourceFileByPath(ref.file));
const { kind, index } = ref;
- let pos: number | undefined, end: number | undefined, packageId: PackageId | undefined, resolutionMode: FileReference["resolutionMode"] | undefined;
+ let pos: number | undefined, end: number | undefined, packageId: PackageId | undefined;
switch (kind) {
case FileIncludeKind.Import:
const importLiteral = getModuleNameStringLiteralAt(file, index);
- packageId = program.getResolvedModule(file, importLiteral.text, program.getModeForUsageLocation(file, importLiteral))?.resolvedModule?.packageId;
+ packageId = program.getResolvedModuleFromModuleSpecifier(importLiteral, file)?.resolvedModule?.packageId;
if (importLiteral.pos === -1) return { file, packageId, text: importLiteral.text };
pos = skipTrivia(file.text, importLiteral.pos);
end = importLiteral.end;
@@ -1251,8 +1256,8 @@ export function getReferencedFileLocation(program: Program, ref: ReferencedFile)
({ pos, end } = file.referencedFiles[index]);
break;
case FileIncludeKind.TypeReferenceDirective:
- ({ pos, end, resolutionMode } = file.typeReferenceDirectives[index]);
- packageId = program.getResolvedTypeReferenceDirective(file, toFileNameLowerCase(file.typeReferenceDirectives[index].fileName), resolutionMode || file.impliedNodeFormat)?.resolvedTypeReferenceDirective?.packageId;
+ ({ pos, end } = file.typeReferenceDirectives[index]);
+ packageId = program.getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(file.typeReferenceDirectives[index], file)?.resolvedTypeReferenceDirective?.packageId;
break;
case FileIncludeKind.LibReferenceDirective:
({ pos, end } = file.libReferenceDirectives[index]);
@@ -1499,6 +1504,16 @@ export const plainJSErrors = new Set([
Diagnostics.This_condition_will_always_return_0_since_JavaScript_compares_objects_by_reference_not_value.code,
]);
+interface LazyProgramDiagnosticExplainingFile {
+ file: SourceFile;
+ diagnostic: DiagnosticMessage;
+ args: DiagnosticArguments;
+}
+interface FileReasonToChainCache {
+ fileIncludeReasonDetails: DiagnosticMessageChain | undefined;
+ redirectInfo: DiagnosticMessageChain[] | undefined;
+ details?: DiagnosticMessageChain[];
+}
/**
* Determine if source file needs to be re-created even if its text hasn't changed
*/
@@ -1550,6 +1565,13 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options!, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#18217
const { rootNames, options, configFileParsingDiagnostics, projectReferences, typeScriptVersion } = createProgramOptions;
let { oldProgram } = createProgramOptions;
+ for (const option of commandLineOptionOfCustomType) {
+ if (hasProperty(options, option.name)) {
+ if (typeof options[option.name] === "string") {
+ throw new Error(`${option.name} is a string value; tsconfig JSON must be parsed with parseJsonSourceFileConfigFileContent or getParsedCommandLineOfConfigFile before passing to createProgram`);
+ }
+ }
+ }
const reportInvalidIgnoreDeprecations = memoize(() => createOptionValueDiagnostic("ignoreDeprecations", Diagnostics.Invalid_value_for_ignoreDeprecations));
@@ -1562,10 +1584,12 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
let classifiableNames: Set<__String>;
const ambientModuleNameToUnmodifiedFileName = new Map();
let fileReasons = createMultiMap();
+ let filesWithReferencesProcessed: Set | undefined;
+ let fileReasonsToChain: Map | undefined;
+ let reasonToRelatedInfo: Map | undefined;
const cachedBindAndCheckDiagnosticsForFile: DiagnosticCache = {};
const cachedDeclarationDiagnosticsForFile: DiagnosticCache = {};
- let resolvedTypeReferenceDirectives = createModeAwareCache();
let fileProcessingDiagnostics: FilePreprocessingDiagnostics[] | undefined;
let automaticTypeDirectiveNames: string[] | undefined;
let automaticTypeDirectiveResolutions: ModeAwareCache;
@@ -1612,6 +1636,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
* Otherwise fileProcessingDiagnostics is correct locations so that the diagnostics can be reported in all structure use scenarios
*/
const programDiagnostics = createDiagnosticCollection();
+ let lazyProgramDiagnosticExplainingFile: LazyProgramDiagnosticExplainingFile[] | undefined = [];
const currentDirectory = host.getCurrentDirectory();
const supportedExtensions = getSupportedExtensions(options);
const supportedExtensionsWithJsonIfResolveJsonModule = getSupportedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
@@ -1858,6 +1883,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
files = stableSort(processingDefaultLibFiles, compareDefaultLibFiles).concat(processingOtherFiles);
processingDefaultLibFiles = undefined;
processingOtherFiles = undefined;
+ filesWithReferencesProcessed = undefined;
}
// Release any files we have acquired in the old program but are
@@ -1934,7 +1960,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
getInstantiationCount: () => getTypeChecker().getInstantiationCount(),
getRelationCacheSizes: () => getTypeChecker().getRelationCacheSizes(),
getFileProcessingDiagnostics: () => fileProcessingDiagnostics,
- getResolvedTypeReferenceDirectives: () => resolvedTypeReferenceDirectives,
getAutomaticTypeDirectiveNames: () => automaticTypeDirectiveNames!,
getAutomaticTypeDirectiveResolutions: () => automaticTypeDirectiveResolutions,
isSourceFileFromExternalLibrary,
@@ -1953,6 +1978,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
getResolvedModule,
getResolvedModuleFromModuleSpecifier,
getResolvedTypeReferenceDirective,
+ getResolvedTypeReferenceDirectiveFromTypeReferenceDirective,
forEachResolvedModule,
forEachResolvedTypeReferenceDirective,
getCurrentPackagesMap: () => packageMap,
@@ -1988,21 +2014,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
onProgramCreateComplete();
- // Add file processingDiagnostics
- fileProcessingDiagnostics?.forEach(diagnostic => {
- switch (diagnostic.kind) {
- case FilePreprocessingDiagnosticsKind.FilePreprocessingFileExplainingDiagnostic:
- return programDiagnostics.add(createDiagnosticExplainingFile(diagnostic.file && getSourceFileByPath(diagnostic.file), diagnostic.fileProcessingReason, diagnostic.diagnostic, diagnostic.args || emptyArray));
- case FilePreprocessingDiagnosticsKind.FilePreprocessingReferencedDiagnostic:
- const { file, pos, end } = getReferencedFileLocation(program, diagnostic.reason) as ReferenceFileLocation;
- return programDiagnostics.add(createFileDiagnostic(file, Debug.checkDefined(pos), Debug.checkDefined(end) - pos, diagnostic.diagnostic, ...diagnostic.args || emptyArray));
- case FilePreprocessingDiagnosticsKind.ResolutionDiagnostics:
- return diagnostic.diagnostics.forEach(d => programDiagnostics.add(d));
- default:
- Debug.assertNever(diagnostic);
- }
- });
-
verifyCompilerOptions();
performance.mark("afterProgram");
performance.measure("Program", "beforeProgram", "afterProgram");
@@ -2010,12 +2021,62 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
return program;
+ function updateAndGetProgramDiagnostics() {
+ if (lazyProgramDiagnosticExplainingFile) {
+ // Add file processingDiagnostics
+ fileProcessingDiagnostics?.forEach(diagnostic => {
+ switch (diagnostic.kind) {
+ case FilePreprocessingDiagnosticsKind.FilePreprocessingFileExplainingDiagnostic:
+ return programDiagnostics.add(
+ createDiagnosticExplainingFile(
+ diagnostic.file && getSourceFileByPath(diagnostic.file),
+ diagnostic.fileProcessingReason,
+ diagnostic.diagnostic,
+ diagnostic.args || emptyArray,
+ ),
+ );
+ case FilePreprocessingDiagnosticsKind.FilePreprocessingLibReferenceDiagnostic:
+ return programDiagnostics.add(filePreprocessingLibreferenceDiagnostic(diagnostic));
+ case FilePreprocessingDiagnosticsKind.ResolutionDiagnostics:
+ return diagnostic.diagnostics.forEach(d => programDiagnostics.add(d));
+ default:
+ Debug.assertNever(diagnostic);
+ }
+ });
+ lazyProgramDiagnosticExplainingFile.forEach(({ file, diagnostic, args }) =>
+ programDiagnostics.add(
+ createDiagnosticExplainingFile(file, /*fileProcessingReason*/ undefined, diagnostic, args),
+ )
+ );
+ lazyProgramDiagnosticExplainingFile = undefined;
+ fileReasonsToChain = undefined;
+ reasonToRelatedInfo = undefined;
+ }
+ return programDiagnostics;
+ }
+
+ function filePreprocessingLibreferenceDiagnostic({ reason }: FilePreprocessingLibReferenceDiagnostic) {
+ const { file, pos, end } = getReferencedFileLocation(program, reason) as ReferenceFileLocation;
+ const libReference = file.libReferenceDirectives[reason.index];
+ const libName = getLibNameFromLibReference(libReference);
+ const unqualifiedLibName = removeSuffix(removePrefix(libName, "lib."), ".d.ts");
+ const suggestion = getSpellingSuggestion(unqualifiedLibName, libs, identity);
+ return createFileDiagnostic(
+ file,
+ Debug.checkDefined(pos),
+ Debug.checkDefined(end) - pos,
+ suggestion ? Diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1 : Diagnostics.Cannot_find_lib_definition_for_0,
+ libName,
+ suggestion!,
+ );
+ }
+
function getResolvedModule(file: SourceFile, moduleName: string, mode: ResolutionMode) {
return resolvedModules?.get(file.path)?.get(moduleName, mode);
}
- function getResolvedModuleFromModuleSpecifier(moduleSpecifier: StringLiteralLike): ResolvedModuleWithFailedLookupLocations | undefined {
- const sourceFile = getSourceFileOfNode(moduleSpecifier);
+ function getResolvedModuleFromModuleSpecifier(moduleSpecifier: StringLiteralLike, sourceFile?: SourceFile): ResolvedModuleWithFailedLookupLocations | undefined {
+ sourceFile ??= getSourceFileOfNode(moduleSpecifier);
Debug.assertIsDefined(sourceFile, "`moduleSpecifier` must have a `SourceFile` ancestor. Use `program.getResolvedModule` instead to provide the containing file and resolution mode.");
return getResolvedModule(sourceFile, moduleSpecifier.text, getModeForUsageLocation(sourceFile, moduleSpecifier));
}
@@ -2024,6 +2085,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
return resolvedTypeReferenceDirectiveNames?.get(file.path)?.get(typeDirectiveName, mode);
}
+ function getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(typeRef: FileReference, sourceFile: SourceFile) {
+ return getResolvedTypeReferenceDirective(sourceFile, typeRef.fileName, typeRef.resolutionMode || sourceFile.impliedNodeFormat);
+ }
+
function forEachResolvedModule(
callback: (resolution: ResolvedModuleWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
file?: SourceFile,
@@ -2656,7 +2721,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
files = newSourceFiles;
fileReasons = oldProgram.getFileIncludeReasons();
fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
- resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
automaticTypeDirectiveNames = oldProgram.getAutomaticTypeDirectiveNames();
automaticTypeDirectiveResolutions = oldProgram.getAutomaticTypeDirectiveResolutions();
@@ -2807,18 +2871,27 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
// This is because in the -out scenario all files need to be emitted, and therefore all
// files need to be type checked. And the way to specify that all files need to be type
// checked is to not pass the file to getEmitResolver.
- const emitResolver = getTypeChecker().getEmitResolver(options.outFile ? undefined : sourceFile, cancellationToken);
+ const typeChecker = getTypeChecker();
+ const emitResolver = typeChecker.getEmitResolver(
+ options.outFile ? undefined : sourceFile,
+ cancellationToken,
+ emitResolverSkipsTypeChecking(emitOnly, forceDtsEmit),
+ );
performance.mark("beforeEmit");
- const emitResult = emitFiles(
- emitResolver,
- getEmitHost(writeFileCallback),
- sourceFile,
- getTransformers(options, customTransformers, emitOnly),
- emitOnly,
- /*onlyBuildInfo*/ false,
- forceDtsEmit,
+ const emitResult = typeChecker.runWithCancellationToken(
+ cancellationToken,
+ () =>
+ emitFiles(
+ emitResolver,
+ getEmitHost(writeFileCallback),
+ sourceFile,
+ getTransformers(options, customTransformers, emitOnly),
+ emitOnly,
+ /*onlyBuildInfo*/ false,
+ forceDtsEmit,
+ ),
);
performance.mark("afterEmit");
@@ -2873,7 +2946,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
return emptyArray;
}
- const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
+ const programDiagnosticsInFile = updateAndGetProgramDiagnostics().getDiagnostics(sourceFile.fileName);
if (!sourceFile.commentDirectives?.length) {
return programDiagnosticsInFile;
}
@@ -3319,16 +3392,16 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
function getOptionsDiagnostics(): SortedReadonlyArray {
return sortAndDeduplicateDiagnostics(concatenate(
- programDiagnostics.getGlobalDiagnostics(),
+ updateAndGetProgramDiagnostics().getGlobalDiagnostics(),
getOptionsDiagnosticsOfConfigFile(),
));
}
function getOptionsDiagnosticsOfConfigFile() {
if (!options.configFile) return emptyArray;
- let diagnostics = programDiagnostics.getDiagnostics(options.configFile.fileName);
+ let diagnostics = updateAndGetProgramDiagnostics().getDiagnostics(options.configFile.fileName);
forEachResolvedProjectReference(resolvedRef => {
- diagnostics = concatenate(diagnostics, programDiagnostics.getDiagnostics(resolvedRef.sourceFile.fileName));
+ diagnostics = concatenate(diagnostics, updateAndGetProgramDiagnostics().getDiagnostics(resolvedRef.sourceFile.fileName));
});
return diagnostics;
}
@@ -3357,7 +3430,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
function createSyntheticImport(text: string, file: SourceFile) {
const externalHelpersModuleReference = factory.createStringLiteral(text);
- const importDecl = factory.createImportDeclaration(/*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference, /*attributes*/ undefined);
+ const importDecl = factory.createImportDeclaration(/*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference);
addInternalEmitFlags(importDecl, InternalEmitFlags.NeverApplyImportHelper);
setParent(externalHelpersModuleReference, importDecl);
setParent(importDecl, file);
@@ -3382,11 +3455,11 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
let ambientModules: string[] | undefined;
// If we are importing helpers, we need to add a synthetic reference to resolve the
- // helpers library.
- if (
- (getIsolatedModules(options) || isExternalModuleFile)
- && !file.isDeclarationFile
- ) {
+ // helpers library. (A JavaScript file without `externalModuleIndicator` set might be
+ // a CommonJS module; `commonJsModuleIndicator` doesn't get set until the binder has
+ // run. We synthesize a helpers import for it just in case; it will never be used if
+ // the binder doesn't find and set a `commonJsModuleIndicator`.)
+ if (isJavaScriptFile || (!file.isDeclarationFile && (getIsolatedModules(options) || isExternalModule(file)))) {
if (options.importHelpers) {
// synthesize 'import "tslib"' declaration
imports = [createSyntheticImport(externalHelpersModuleNameText, file)];
@@ -3506,7 +3579,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
}
function getLibFileFromReference(ref: FileReference) {
- const { libFileName } = getLibFileNameFromLibReference(ref);
+ const libFileName = getLibFileNameFromLibReference(ref);
const actualFileName = libFileName && resolvedLibReferences?.get(libFileName)?.actual;
return actualFileName !== undefined ? getSourceFile(actualFileName) : undefined;
}
@@ -3658,10 +3731,10 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
const originalFileName = fileName;
if (filesByName.has(path)) {
const file = filesByName.get(path);
- addFileIncludeReason(file || undefined, reason);
+ const addedReason = addFileIncludeReason(file || undefined, reason, /*checkExisting*/ true);
// try to check if we've already seen this file but with a different casing in path
// NOTE: this only makes sense for case-insensitive file systems, and only on files which are not redirected
- if (file && !(options.forceConsistentCasingInFileNames === false)) {
+ if (file && addedReason && !(options.forceConsistentCasingInFileNames === false)) {
const checkedName = file.fileName;
const isRedirect = toPath(checkedName) !== toPath(fileName);
if (isRedirect) {
@@ -3702,7 +3775,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
}
let redirectedPath: Path | undefined;
- if (isReferencedFile(reason) && !useSourceOfProjectReferenceRedirect) {
+ if (!useSourceOfProjectReferenceRedirect) {
const redirectProject = getProjectReferenceRedirectProject(fileName);
if (redirectProject) {
if (redirectProject.commandLine.options.outFile) {
@@ -3738,7 +3811,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
const dupFile = createRedirectedSourceFile(fileFromPackageId, file!, fileName, path, toPath(fileName), originalFileName, sourceFileOptions);
redirectTargetsMap.add(fileFromPackageId.path, fileName);
addFileToFilesByName(dupFile, path, fileName, redirectedPath);
- addFileIncludeReason(dupFile, reason);
+ addFileIncludeReason(dupFile, reason, /*checkExisting*/ false);
sourceFileToPackageName.set(path, packageIdToPackageName(packageId));
processingOtherFiles!.push(dupFile);
return dupFile;
@@ -3759,7 +3832,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
file.originalFileName = originalFileName;
file.packageJsonLocations = sourceFileOptions.packageJsonLocations?.length ? sourceFileOptions.packageJsonLocations : undefined;
file.packageJsonScope = sourceFileOptions.packageJsonScope;
- addFileIncludeReason(file, reason);
+ addFileIncludeReason(file, reason, /*checkExisting*/ false);
if (host.useCaseSensitiveFileNames()) {
const pathLowerCase = toFileNameLowerCase(path);
@@ -3792,12 +3865,17 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
else {
processingOtherFiles!.push(file);
}
+ (filesWithReferencesProcessed ??= new Set()).add(file.path);
}
return file;
}
- function addFileIncludeReason(file: SourceFile | undefined, reason: FileIncludeReason) {
- if (file) fileReasons.add(file.path, reason);
+ function addFileIncludeReason(file: SourceFile | undefined, reason: FileIncludeReason, checkExisting: boolean) {
+ if (file && (!checkExisting || !isReferencedFile(reason) || !filesWithReferencesProcessed?.has(reason.file))) {
+ fileReasons.add(file.path, reason);
+ return true;
+ }
+ return false;
}
function addFileToFilesByName(file: SourceFile | undefined, path: Path, fileName: string, redirectedPath: Path | undefined) {
@@ -3923,7 +4001,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
const ref = file.typeReferenceDirectives[index];
const resolvedTypeReferenceDirective = resolutions[index];
// store resolved type directive on the file
- const fileName = toFileNameLowerCase(ref.fileName);
+ const fileName = ref.fileName;
resolutionsInFile.set(fileName, getModeForFileReference(ref, file.impliedNodeFormat), resolvedTypeReferenceDirective);
const mode = ref.resolutionMode || getDefaultResolutionModeForFile(file);
processTypeReferenceDirective(fileName, mode, resolvedTypeReferenceDirective, { kind: FileIncludeKind.TypeReferenceDirective, file: file.path, index });
@@ -3952,55 +4030,18 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
reason: FileIncludeReason,
): void {
addResolutionDiagnostics(resolution);
- // If we already found this library as a primary reference - nothing to do
- const previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective, mode)?.resolvedTypeReferenceDirective;
- if (previousResolution && previousResolution.primary) {
- return;
- }
- let saveResolution = true;
const { resolvedTypeReferenceDirective } = resolution;
if (resolvedTypeReferenceDirective) {
if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth++;
- if (resolvedTypeReferenceDirective.primary) {
- // resolved from the primary path
- processSourceFile(resolvedTypeReferenceDirective.resolvedFileName!, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, reason); // TODO: GH#18217
- }
- else {
- // If we already resolved to this file, it must have been a secondary reference. Check file contents
- // for sameness and possibly issue an error
- if (previousResolution) {
- // Don't bother reading the file again if it's the same file.
- if (resolvedTypeReferenceDirective.resolvedFileName !== previousResolution.resolvedFileName) {
- const otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName!);
- const existingFile = getSourceFile(previousResolution.resolvedFileName!)!;
- if (otherFileText !== existingFile.text) {
- addFilePreprocessingFileExplainingDiagnostic(
- existingFile,
- reason,
- Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict,
- [typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName!, previousResolution.resolvedFileName!],
- );
- }
- }
- // don't overwrite previous resolution result
- saveResolution = false;
- }
- else {
- // First resolution of this library
- processSourceFile(resolvedTypeReferenceDirective.resolvedFileName!, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, reason);
- }
- }
+ // resolved from the primary path
+ processSourceFile(resolvedTypeReferenceDirective.resolvedFileName!, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, reason); // TODO: GH#18217
if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth--;
}
else {
addFilePreprocessingFileExplainingDiagnostic(/*file*/ undefined, reason, Diagnostics.Cannot_find_type_definition_file_for_0, [typeReferenceDirective]);
}
-
- if (saveResolution) {
- resolvedTypeReferenceDirectives.set(typeReferenceDirective, mode, resolution);
- }
}
function pathForLibFile(libFileName: string): string {
@@ -4059,21 +4100,15 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
function processLibReferenceDirectives(file: SourceFile) {
forEach(file.libReferenceDirectives, (libReference, index) => {
- const { libName, libFileName } = getLibFileNameFromLibReference(libReference);
+ const libFileName = getLibFileNameFromLibReference(libReference);
if (libFileName) {
// we ignore any 'no-default-lib' reference set on this file.
processRootFile(pathForLibFile(libFileName), /*isDefaultLib*/ true, /*ignoreNoDefaultLib*/ true, { kind: FileIncludeKind.LibReferenceDirective, file: file.path, index });
}
else {
- const unqualifiedLibName = removeSuffix(removePrefix(libName, "lib."), ".d.ts");
- const suggestion = getSpellingSuggestion(unqualifiedLibName, libs, identity);
- const diagnostic = suggestion ? Diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1 : Diagnostics.Cannot_find_lib_definition_for_0;
- const args = suggestion ? [libName, suggestion] : [libName];
(fileProcessingDiagnostics ||= []).push({
- kind: FilePreprocessingDiagnosticsKind.FilePreprocessingReferencedDiagnostic,
+ kind: FilePreprocessingDiagnosticsKind.FilePreprocessingLibReferenceDiagnostic,
reason: { kind: FileIncludeKind.LibReferenceDirective, file: file.path, index },
- diagnostic,
- args,
});
}
});
@@ -4158,7 +4193,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
if (!sourceFile.isDeclarationFile) {
const absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
- addProgramDiagnosticExplainingFile(
+ addLazyProgramDiagnosticExplainingFile(
sourceFile,
Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files,
[sourceFile.fileName, rootDirectory],
@@ -4281,7 +4316,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
for (const file of files) {
// Ignore file that is not emitted
if (sourceFileMayBeEmitted(file, program) && !rootPaths.has(file.path)) {
- addProgramDiagnosticExplainingFile(
+ addLazyProgramDiagnosticExplainingFile(
file,
Diagnostics.File_0_is_not_listed_within_the_file_list_of_project_1_Projects_must_list_all_files_or_use_an_include_pattern,
[file.fileName, options.configFilePath || ""],
@@ -4429,9 +4464,6 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
if (options.noEmit) {
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noCheck", "noEmit");
}
- if (!options.emitDeclarationOnly) {
- createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "noCheck", "emitDeclarationOnly");
- }
}
if (
@@ -4671,38 +4703,122 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
});
}
- function createDiagnosticExplainingFile(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason | undefined, diagnostic: DiagnosticMessage, args: DiagnosticArguments | undefined): Diagnostic {
+ function createDiagnosticExplainingFile(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason | undefined, diagnostic: DiagnosticMessage, args: DiagnosticArguments): Diagnostic {
+ let seenReasons: Set | undefined;
+ const reasons = file && fileReasons.get(file.path);
let fileIncludeReasons: DiagnosticMessageChain[] | undefined;
- let relatedInfo: Diagnostic[] | undefined;
+ let relatedInfo: DiagnosticWithLocation[] | undefined;
let locationReason = isReferencedFile(fileProcessingReason) ? fileProcessingReason : undefined;
- if (file) fileReasons.get(file.path)?.forEach(processReason);
+ let fileIncludeReasonDetails: DiagnosticMessageChain | undefined;
+ let redirectInfo: DiagnosticMessageChain[] | undefined;
+ let cachedChain = file && fileReasonsToChain?.get(file.path);
+ let chain: DiagnosticMessageChain | undefined;
+ if (cachedChain) {
+ if (cachedChain.fileIncludeReasonDetails) {
+ seenReasons = new Set(reasons);
+ reasons?.forEach(populateRelatedInfo);
+ }
+ else {
+ reasons?.forEach(processReason);
+ }
+ redirectInfo = cachedChain.redirectInfo;
+ }
+ else {
+ reasons?.forEach(processReason);
+ redirectInfo = file && explainIfFileIsRedirectAndImpliedFormat(file, getCompilerOptionsForFile(file));
+ }
+
if (fileProcessingReason) processReason(fileProcessingReason);
+ const processedExtraReason = seenReasons?.size !== reasons?.length;
+
// If we have location and there is only one reason file is in which is the location, dont add details for file include
- if (locationReason && fileIncludeReasons?.length === 1) fileIncludeReasons = undefined;
+ if (locationReason && seenReasons?.size === 1) seenReasons = undefined;
+
+ if (seenReasons && cachedChain) {
+ if (cachedChain.details && !processedExtraReason) {
+ chain = chainDiagnosticMessages(cachedChain.details, diagnostic, ...args || emptyArray);
+ }
+ else if (cachedChain.fileIncludeReasonDetails) {
+ if (!processedExtraReason) {
+ if (!cachedFileIncludeDetailsHasProcessedExtraReason()) {
+ fileIncludeReasonDetails = cachedChain.fileIncludeReasonDetails;
+ }
+ else {
+ fileIncludeReasons = cachedChain.fileIncludeReasonDetails.next!.slice(0, reasons!.length);
+ }
+ }
+ else {
+ if (!cachedFileIncludeDetailsHasProcessedExtraReason()) {
+ fileIncludeReasons = [...cachedChain.fileIncludeReasonDetails.next!, fileIncludeReasons![0]];
+ }
+ else {
+ fileIncludeReasons = append(cachedChain.fileIncludeReasonDetails.next!.slice(0, reasons!.length), fileIncludeReasons![0]);
+ }
+ }
+ }
+ }
+
+ if (!chain) {
+ if (!fileIncludeReasonDetails) fileIncludeReasonDetails = seenReasons && chainDiagnosticMessages(fileIncludeReasons, Diagnostics.The_file_is_in_the_program_because_Colon);
+ chain = chainDiagnosticMessages(
+ redirectInfo ?
+ fileIncludeReasonDetails ? [fileIncludeReasonDetails, ...redirectInfo] : redirectInfo :
+ fileIncludeReasonDetails,
+ diagnostic,
+ ...args || emptyArray,
+ );
+ }
+
+ // This is chain's next contains:
+ // - File is in program because:
+ // - Files reasons listed
+ // - extra reason if its not already processed - this happens in case sensitive file system where files differ in casing and we are giving reasons for two files so reason is not in file's reason
+ // fyi above whole secton is ommited if we have single reason and we are reporting at that reason's location
+ // - redirect and additional information about file
+ // So cache result if we havent ommited file include reasons
+ if (file) {
+ if (cachedChain) {
+ // Cache new fileIncludeDetails if we have update
+ // Or if we had cached with more details than the reasons
+ if (!cachedChain.fileIncludeReasonDetails || (!processedExtraReason && fileIncludeReasonDetails)) {
+ cachedChain.fileIncludeReasonDetails = fileIncludeReasonDetails;
+ }
+ }
+ else {
+ (fileReasonsToChain ??= new Map()).set(file.path, cachedChain = { fileIncludeReasonDetails, redirectInfo });
+ }
+ // If we didnt compute extra file include reason , cache the details to use directly
+ if (!cachedChain.details && !processedExtraReason) cachedChain.details = chain.next;
+ }
+
const location = locationReason && getReferencedFileLocation(program, locationReason);
- const fileIncludeReasonDetails = fileIncludeReasons && chainDiagnosticMessages(fileIncludeReasons, Diagnostics.The_file_is_in_the_program_because_Colon);
- 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) :
createCompilerDiagnosticFromMessageChain(chain, relatedInfo);
function processReason(reason: FileIncludeReason) {
- (fileIncludeReasons ||= []).push(fileIncludeReasonToDiagnostics(program, reason));
+ if (seenReasons?.has(reason)) return;
+ (seenReasons ??= new Set()).add(reason);
+ (fileIncludeReasons ??= []).push(fileIncludeReasonToDiagnostics(program, reason));
+ populateRelatedInfo(reason);
+ }
+
+ function populateRelatedInfo(reason: FileIncludeReason) {
if (!locationReason && isReferencedFile(reason)) {
// Report error at first reference file or file currently in processing and dont report in related information
locationReason = reason;
}
else if (locationReason !== reason) {
- relatedInfo = append(relatedInfo, fileIncludeReasonToRelatedInformation(reason));
+ relatedInfo = append(relatedInfo, getFileIncludeReasonToRelatedInformation(reason));
}
- // Remove fileProcessingReason if its already included in fileReasons of the program
- if (reason === fileProcessingReason) fileProcessingReason = undefined;
+ }
+
+ function cachedFileIncludeDetailsHasProcessedExtraReason() {
+ return cachedChain!.fileIncludeReasonDetails!.next?.length !== reasons?.length;
}
}
- function addFilePreprocessingFileExplainingDiagnostic(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason, diagnostic: DiagnosticMessage, args?: DiagnosticArguments) {
+ function addFilePreprocessingFileExplainingDiagnostic(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason, diagnostic: DiagnosticMessage, args: DiagnosticArguments) {
(fileProcessingDiagnostics ||= []).push({
kind: FilePreprocessingDiagnosticsKind.FilePreprocessingFileExplainingDiagnostic,
file: file && file.path,
@@ -4712,8 +4828,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
});
}
- function addProgramDiagnosticExplainingFile(file: SourceFile, diagnostic: DiagnosticMessage, args?: DiagnosticArguments) {
- programDiagnostics.add(createDiagnosticExplainingFile(file, /*fileProcessingReason*/ undefined, diagnostic, args));
+ function addLazyProgramDiagnosticExplainingFile(file: SourceFile, diagnostic: DiagnosticMessage, args: DiagnosticArguments) {
+ lazyProgramDiagnosticExplainingFile!.push({ file, diagnostic, args });
+ }
+
+ function getFileIncludeReasonToRelatedInformation(reason: FileIncludeReason) {
+ let relatedInfo = reasonToRelatedInfo?.get(reason);
+ if (relatedInfo === undefined) (reasonToRelatedInfo ??= new Map()).set(reason, relatedInfo = fileIncludeReasonToRelatedInformation(reason) ?? false);
+ return relatedInfo || undefined;
}
function fileIncludeReasonToRelatedInformation(reason: FileIncludeReason): DiagnosticWithLocation | undefined {
diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts
index 5fd381cf84c39..cbfa95b27d537 100644
--- a/src/compiler/resolutionCache.ts
+++ b/src/compiler/resolutionCache.ts
@@ -76,7 +76,7 @@ import {
trace,
updateResolutionField,
WatchDirectoryFlags,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export interface HasInvalidatedFromResolutionCache {
diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts
index 7b7e8875c6711..ad6928331f26d 100644
--- a/src/compiler/scanner.ts
+++ b/src/compiler/scanner.ts
@@ -33,7 +33,7 @@ import {
SyntaxKind,
TextRange,
TokenFlags,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export type ErrorCallback = (message: DiagnosticMessage, length: number, arg0?: any) => void;
@@ -329,15 +329,15 @@ const unicodeES5IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216,
const unicodeES5IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2048, 2093, 2112, 2139, 2208, 2208, 2210, 2220, 2276, 2302, 2304, 2403, 2406, 2415, 2417, 2423, 2425, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3396, 3398, 3400, 3402, 3406, 3415, 3415, 3424, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6263, 6272, 6314, 6320, 6389, 6400, 6428, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6617, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7376, 7378, 7380, 7414, 7424, 7654, 7676, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12442, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42647, 42655, 42737, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43047, 43072, 43123, 43136, 43204, 43216, 43225, 43232, 43255, 43259, 43259, 43264, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43643, 43648, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65062, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500 ];
/**
- * Generated by scripts/regenerate-unicode-identifier-parts.js on node v12.4.0 with unicode 12.1
+ * Generated by scripts/regenerate-unicode-identifier-parts.mjs on node v22.1.0 with unicode 15.1
* based on http://www.unicode.org/reports/tr31/ and https://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords
* unicodeESNextIdentifierStart corresponds to the ID_Start and Other_ID_Start property, and
* unicodeESNextIdentifierPart corresponds to ID_Continue, Other_ID_Continue, plus ID_Start and Other_ID_Start
*/
// dprint-ignore
-const unicodeESNextIdentifierStart = [65, 90, 97, 122, 170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 895, 895, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1488, 1514, 1519, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2144, 2154, 2208, 2228, 2230, 2237, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2432, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2556, 2556, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2809, 2809, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3133, 3160, 3162, 3168, 3169, 3200, 3200, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3412, 3414, 3423, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6264, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6430, 6480, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7401, 7404, 7406, 7411, 7413, 7414, 7418, 7418, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12443, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40943, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42653, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42943, 42946, 42950, 42999, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43261, 43262, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43488, 43492, 43494, 43503, 43514, 43518, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43646, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43879, 43888, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66335, 66349, 66378, 66384, 66421, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 67072, 67382, 67392, 67413, 67424, 67431, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68096, 68112, 68115, 68117, 68119, 68121, 68149, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68324, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68899, 69376, 69404, 69415, 69415, 69424, 69445, 69600, 69622, 69635, 69687, 69763, 69807, 69840, 69864, 69891, 69926, 69956, 69956, 69968, 70002, 70006, 70006, 70019, 70066, 70081, 70084, 70106, 70106, 70108, 70108, 70144, 70161, 70163, 70187, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70366, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70461, 70461, 70480, 70480, 70493, 70497, 70656, 70708, 70727, 70730, 70751, 70751, 70784, 70831, 70852, 70853, 70855, 70855, 71040, 71086, 71128, 71131, 71168, 71215, 71236, 71236, 71296, 71338, 71352, 71352, 71424, 71450, 71680, 71723, 71840, 71903, 71935, 71935, 72096, 72103, 72106, 72144, 72161, 72161, 72163, 72163, 72192, 72192, 72203, 72242, 72250, 72250, 72272, 72272, 72284, 72329, 72349, 72349, 72384, 72440, 72704, 72712, 72714, 72750, 72768, 72768, 72818, 72847, 72960, 72966, 72968, 72969, 72971, 73008, 73030, 73030, 73056, 73061, 73063, 73064, 73066, 73097, 73112, 73112, 73440, 73458, 73728, 74649, 74752, 74862, 74880, 75075, 77824, 78894, 82944, 83526, 92160, 92728, 92736, 92766, 92880, 92909, 92928, 92975, 92992, 92995, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94032, 94032, 94099, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101106, 110592, 110878, 110928, 110930, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 123136, 123180, 123191, 123197, 123214, 123214, 123584, 123627, 124928, 125124, 125184, 125251, 125259, 125259, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173782, 173824, 177972, 177984, 178205, 178208, 183969, 183984, 191456, 194560, 195101];
+const unicodeESNextIdentifierStart = [65, 90, 97, 122, 170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 895, 895, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1488, 1514, 1519, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2144, 2154, 2160, 2183, 2185, 2190, 2208, 2249, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2432, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2556, 2556, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2809, 2809, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3133, 3160, 3162, 3165, 3165, 3168, 3169, 3200, 3200, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3293, 3294, 3296, 3297, 3313, 3314, 3332, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3412, 3414, 3423, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5905, 5919, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6264, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6430, 6480, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6988, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7401, 7404, 7406, 7411, 7413, 7414, 7418, 7418, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12443, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12735, 12784, 12799, 13312, 19903, 19968, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42653, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42954, 42960, 42961, 42963, 42963, 42965, 42969, 42994, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43261, 43262, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43488, 43492, 43494, 43503, 43514, 43518, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43646, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43881, 43888, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66176, 66204, 66208, 66256, 66304, 66335, 66349, 66378, 66384, 66421, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 66928, 66938, 66940, 66954, 66956, 66962, 66964, 66965, 66967, 66977, 66979, 66993, 66995, 67001, 67003, 67004, 67072, 67382, 67392, 67413, 67424, 67431, 67456, 67461, 67463, 67504, 67506, 67514, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68096, 68112, 68115, 68117, 68119, 68121, 68149, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68324, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68899, 69248, 69289, 69296, 69297, 69376, 69404, 69415, 69415, 69424, 69445, 69488, 69505, 69552, 69572, 69600, 69622, 69635, 69687, 69745, 69746, 69749, 69749, 69763, 69807, 69840, 69864, 69891, 69926, 69956, 69956, 69959, 69959, 69968, 70002, 70006, 70006, 70019, 70066, 70081, 70084, 70106, 70106, 70108, 70108, 70144, 70161, 70163, 70187, 70207, 70208, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70366, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70461, 70461, 70480, 70480, 70493, 70497, 70656, 70708, 70727, 70730, 70751, 70753, 70784, 70831, 70852, 70853, 70855, 70855, 71040, 71086, 71128, 71131, 71168, 71215, 71236, 71236, 71296, 71338, 71352, 71352, 71424, 71450, 71488, 71494, 71680, 71723, 71840, 71903, 71935, 71942, 71945, 71945, 71948, 71955, 71957, 71958, 71960, 71983, 71999, 71999, 72001, 72001, 72096, 72103, 72106, 72144, 72161, 72161, 72163, 72163, 72192, 72192, 72203, 72242, 72250, 72250, 72272, 72272, 72284, 72329, 72349, 72349, 72368, 72440, 72704, 72712, 72714, 72750, 72768, 72768, 72818, 72847, 72960, 72966, 72968, 72969, 72971, 73008, 73030, 73030, 73056, 73061, 73063, 73064, 73066, 73097, 73112, 73112, 73440, 73458, 73474, 73474, 73476, 73488, 73490, 73523, 73648, 73648, 73728, 74649, 74752, 74862, 74880, 75075, 77712, 77808, 77824, 78895, 78913, 78918, 82944, 83526, 92160, 92728, 92736, 92766, 92784, 92862, 92880, 92909, 92928, 92975, 92992, 92995, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94032, 94032, 94099, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101589, 101632, 101640, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 122624, 122654, 122661, 122666, 122928, 122989, 123136, 123180, 123191, 123197, 123214, 123214, 123536, 123565, 123584, 123627, 124112, 124139, 124896, 124902, 124904, 124907, 124909, 124910, 124912, 124926, 124928, 125124, 125184, 125251, 125259, 125259, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173791, 173824, 177977, 177984, 178205, 178208, 183969, 183984, 191456, 191472, 192093, 194560, 195101, 196608, 201546, 201552, 205743];
// dprint-ignore
-const unicodeESNextIdentifierPart = [48, 57, 65, 90, 95, 95, 97, 122, 170, 170, 181, 181, 183, 183, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 895, 895, 902, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1519, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2045, 2045, 2048, 2093, 2112, 2139, 2144, 2154, 2208, 2228, 2230, 2237, 2259, 2273, 2275, 2403, 2406, 2415, 2417, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2556, 2556, 2558, 2558, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2809, 2815, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3072, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3162, 3168, 3171, 3174, 3183, 3200, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3328, 3331, 3333, 3340, 3342, 3344, 3346, 3396, 3398, 3400, 3402, 3406, 3412, 3415, 3423, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3558, 3567, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4969, 4977, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6264, 6272, 6314, 6320, 6389, 6400, 6430, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6618, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6832, 6845, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7376, 7378, 7380, 7418, 7424, 7673, 7675, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12447, 12449, 12538, 12540, 12543, 12549, 12591, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40943, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42737, 42775, 42783, 42786, 42888, 42891, 42943, 42946, 42950, 42999, 43047, 43072, 43123, 43136, 43205, 43216, 43225, 43232, 43255, 43259, 43259, 43261, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43488, 43518, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43879, 43888, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65071, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66045, 66045, 66176, 66204, 66208, 66256, 66272, 66272, 66304, 66335, 66349, 66378, 66384, 66426, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66720, 66729, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 67072, 67382, 67392, 67413, 67424, 67431, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68099, 68101, 68102, 68108, 68115, 68117, 68119, 68121, 68149, 68152, 68154, 68159, 68159, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68326, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68903, 68912, 68921, 69376, 69404, 69415, 69415, 69424, 69456, 69600, 69622, 69632, 69702, 69734, 69743, 69759, 69818, 69840, 69864, 69872, 69881, 69888, 69940, 69942, 69951, 69956, 69958, 69968, 70003, 70006, 70006, 70016, 70084, 70089, 70092, 70096, 70106, 70108, 70108, 70144, 70161, 70163, 70199, 70206, 70206, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70378, 70384, 70393, 70400, 70403, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70459, 70468, 70471, 70472, 70475, 70477, 70480, 70480, 70487, 70487, 70493, 70499, 70502, 70508, 70512, 70516, 70656, 70730, 70736, 70745, 70750, 70751, 70784, 70853, 70855, 70855, 70864, 70873, 71040, 71093, 71096, 71104, 71128, 71133, 71168, 71232, 71236, 71236, 71248, 71257, 71296, 71352, 71360, 71369, 71424, 71450, 71453, 71467, 71472, 71481, 71680, 71738, 71840, 71913, 71935, 71935, 72096, 72103, 72106, 72151, 72154, 72161, 72163, 72164, 72192, 72254, 72263, 72263, 72272, 72345, 72349, 72349, 72384, 72440, 72704, 72712, 72714, 72758, 72760, 72768, 72784, 72793, 72818, 72847, 72850, 72871, 72873, 72886, 72960, 72966, 72968, 72969, 72971, 73014, 73018, 73018, 73020, 73021, 73023, 73031, 73040, 73049, 73056, 73061, 73063, 73064, 73066, 73102, 73104, 73105, 73107, 73112, 73120, 73129, 73440, 73462, 73728, 74649, 74752, 74862, 74880, 75075, 77824, 78894, 82944, 83526, 92160, 92728, 92736, 92766, 92768, 92777, 92880, 92909, 92912, 92916, 92928, 92982, 92992, 92995, 93008, 93017, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94031, 94087, 94095, 94111, 94176, 94177, 94179, 94179, 94208, 100343, 100352, 101106, 110592, 110878, 110928, 110930, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 113821, 113822, 119141, 119145, 119149, 119154, 119163, 119170, 119173, 119179, 119210, 119213, 119362, 119364, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 120782, 120831, 121344, 121398, 121403, 121452, 121461, 121461, 121476, 121476, 121499, 121503, 121505, 121519, 122880, 122886, 122888, 122904, 122907, 122913, 122915, 122916, 122918, 122922, 123136, 123180, 123184, 123197, 123200, 123209, 123214, 123214, 123584, 123641, 124928, 125124, 125136, 125142, 125184, 125259, 125264, 125273, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173782, 173824, 177972, 177984, 178205, 178208, 183969, 183984, 191456, 194560, 195101, 917760, 917999];
+const unicodeESNextIdentifierPart = [48, 57, 65, 90, 95, 95, 97, 122, 170, 170, 181, 181, 183, 183, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 895, 895, 902, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1327, 1329, 1366, 1369, 1369, 1376, 1416, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1519, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2045, 2045, 2048, 2093, 2112, 2139, 2144, 2154, 2160, 2183, 2185, 2190, 2200, 2273, 2275, 2403, 2406, 2415, 2417, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2556, 2556, 2558, 2558, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2809, 2815, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2901, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3072, 3084, 3086, 3088, 3090, 3112, 3114, 3129, 3132, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3162, 3165, 3165, 3168, 3171, 3174, 3183, 3200, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3293, 3294, 3296, 3299, 3302, 3311, 3313, 3315, 3328, 3340, 3342, 3344, 3346, 3396, 3398, 3400, 3402, 3406, 3412, 3415, 3423, 3427, 3430, 3439, 3450, 3455, 3457, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3558, 3567, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3718, 3722, 3724, 3747, 3749, 3749, 3751, 3773, 3776, 3780, 3782, 3782, 3784, 3790, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4969, 4977, 4992, 5007, 5024, 5109, 5112, 5117, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5880, 5888, 5909, 5919, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6159, 6169, 6176, 6264, 6272, 6314, 6320, 6389, 6400, 6430, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6618, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6832, 6845, 6847, 6862, 6912, 6988, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7296, 7304, 7312, 7354, 7357, 7359, 7376, 7378, 7380, 7418, 7424, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8472, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12447, 12449, 12543, 12549, 12591, 12593, 12686, 12704, 12735, 12784, 12799, 13312, 19903, 19968, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42737, 42775, 42783, 42786, 42888, 42891, 42954, 42960, 42961, 42963, 42963, 42965, 42969, 42994, 43047, 43052, 43052, 43072, 43123, 43136, 43205, 43216, 43225, 43232, 43255, 43259, 43259, 43261, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43488, 43518, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43824, 43866, 43868, 43881, 43888, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65071, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65536, 65547, 65549, 65574, 65576, 65594, 65596, 65597, 65599, 65613, 65616, 65629, 65664, 65786, 65856, 65908, 66045, 66045, 66176, 66204, 66208, 66256, 66272, 66272, 66304, 66335, 66349, 66378, 66384, 66426, 66432, 66461, 66464, 66499, 66504, 66511, 66513, 66517, 66560, 66717, 66720, 66729, 66736, 66771, 66776, 66811, 66816, 66855, 66864, 66915, 66928, 66938, 66940, 66954, 66956, 66962, 66964, 66965, 66967, 66977, 66979, 66993, 66995, 67001, 67003, 67004, 67072, 67382, 67392, 67413, 67424, 67431, 67456, 67461, 67463, 67504, 67506, 67514, 67584, 67589, 67592, 67592, 67594, 67637, 67639, 67640, 67644, 67644, 67647, 67669, 67680, 67702, 67712, 67742, 67808, 67826, 67828, 67829, 67840, 67861, 67872, 67897, 67968, 68023, 68030, 68031, 68096, 68099, 68101, 68102, 68108, 68115, 68117, 68119, 68121, 68149, 68152, 68154, 68159, 68159, 68192, 68220, 68224, 68252, 68288, 68295, 68297, 68326, 68352, 68405, 68416, 68437, 68448, 68466, 68480, 68497, 68608, 68680, 68736, 68786, 68800, 68850, 68864, 68903, 68912, 68921, 69248, 69289, 69291, 69292, 69296, 69297, 69373, 69404, 69415, 69415, 69424, 69456, 69488, 69509, 69552, 69572, 69600, 69622, 69632, 69702, 69734, 69749, 69759, 69818, 69826, 69826, 69840, 69864, 69872, 69881, 69888, 69940, 69942, 69951, 69956, 69959, 69968, 70003, 70006, 70006, 70016, 70084, 70089, 70092, 70094, 70106, 70108, 70108, 70144, 70161, 70163, 70199, 70206, 70209, 70272, 70278, 70280, 70280, 70282, 70285, 70287, 70301, 70303, 70312, 70320, 70378, 70384, 70393, 70400, 70403, 70405, 70412, 70415, 70416, 70419, 70440, 70442, 70448, 70450, 70451, 70453, 70457, 70459, 70468, 70471, 70472, 70475, 70477, 70480, 70480, 70487, 70487, 70493, 70499, 70502, 70508, 70512, 70516, 70656, 70730, 70736, 70745, 70750, 70753, 70784, 70853, 70855, 70855, 70864, 70873, 71040, 71093, 71096, 71104, 71128, 71133, 71168, 71232, 71236, 71236, 71248, 71257, 71296, 71352, 71360, 71369, 71424, 71450, 71453, 71467, 71472, 71481, 71488, 71494, 71680, 71738, 71840, 71913, 71935, 71942, 71945, 71945, 71948, 71955, 71957, 71958, 71960, 71989, 71991, 71992, 71995, 72003, 72016, 72025, 72096, 72103, 72106, 72151, 72154, 72161, 72163, 72164, 72192, 72254, 72263, 72263, 72272, 72345, 72349, 72349, 72368, 72440, 72704, 72712, 72714, 72758, 72760, 72768, 72784, 72793, 72818, 72847, 72850, 72871, 72873, 72886, 72960, 72966, 72968, 72969, 72971, 73014, 73018, 73018, 73020, 73021, 73023, 73031, 73040, 73049, 73056, 73061, 73063, 73064, 73066, 73102, 73104, 73105, 73107, 73112, 73120, 73129, 73440, 73462, 73472, 73488, 73490, 73530, 73534, 73538, 73552, 73561, 73648, 73648, 73728, 74649, 74752, 74862, 74880, 75075, 77712, 77808, 77824, 78895, 78912, 78933, 82944, 83526, 92160, 92728, 92736, 92766, 92768, 92777, 92784, 92862, 92864, 92873, 92880, 92909, 92912, 92916, 92928, 92982, 92992, 92995, 93008, 93017, 93027, 93047, 93053, 93071, 93760, 93823, 93952, 94026, 94031, 94087, 94095, 94111, 94176, 94177, 94179, 94180, 94192, 94193, 94208, 100343, 100352, 101589, 101632, 101640, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817, 113821, 113822, 118528, 118573, 118576, 118598, 119141, 119145, 119149, 119154, 119163, 119170, 119173, 119179, 119210, 119213, 119362, 119364, 119808, 119892, 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770, 120772, 120779, 120782, 120831, 121344, 121398, 121403, 121452, 121461, 121461, 121476, 121476, 121499, 121503, 121505, 121519, 122624, 122654, 122661, 122666, 122880, 122886, 122888, 122904, 122907, 122913, 122915, 122916, 122918, 122922, 122928, 122989, 123023, 123023, 123136, 123180, 123184, 123197, 123200, 123209, 123214, 123214, 123536, 123566, 123584, 123641, 124112, 124153, 124896, 124902, 124904, 124907, 124909, 124910, 124912, 124926, 124928, 125124, 125136, 125142, 125184, 125259, 125264, 125273, 126464, 126467, 126469, 126495, 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514, 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530, 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543, 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553, 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562, 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583, 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619, 126625, 126627, 126629, 126633, 126635, 126651, 130032, 130041, 131072, 173791, 173824, 177977, 177984, 178205, 178208, 183969, 183984, 191456, 191472, 192093, 194560, 195101, 196608, 201546, 201552, 205743, 917760, 917999];
/**
* Test for whether a single line comment with leading whitespace trimmed's text contains a directive.
@@ -997,6 +997,19 @@ export function isIdentifierText(name: string, languageVersion: ScriptTarget | u
return true;
}
+const enum EscapeSequenceScanningFlags {
+ String = 1 << 0,
+ ReportErrors = 1 << 1,
+
+ RegularExpression = 1 << 2,
+ AnnexB = 1 << 3,
+ AnyUnicodeMode = 1 << 4,
+ AtomEscape = 1 << 5,
+
+ ReportInvalidEscapeErrors = RegularExpression | ReportErrors,
+ ScanExtendedUnicodeEscape = String | AnyUnicodeMode,
+}
+
const enum ClassSetExpressionType {
Unknown,
ClassUnion,
@@ -1416,7 +1429,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
}
if (ch === CharacterCodes.backslash && !jsxAttributeString) {
result += text.substring(start, pos);
- result += scanEscapeSequence(/*shouldEmitInvalidEscapeError*/ true, /*isRegularExpression*/ false);
+ result += scanEscapeSequence(EscapeSequenceScanningFlags.String | EscapeSequenceScanningFlags.ReportErrors);
start = pos;
continue;
}
@@ -1474,7 +1487,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
// Escape character
if (currChar === CharacterCodes.backslash) {
contents += text.substring(start, pos);
- contents += scanEscapeSequence(shouldEmitInvalidEscapeError, /*isRegularExpression*/ false);
+ contents += scanEscapeSequence(EscapeSequenceScanningFlags.String | (shouldEmitInvalidEscapeError ? EscapeSequenceScanningFlags.ReportErrors : 0));
start = pos;
continue;
}
@@ -1517,7 +1530,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
// | [0-3] [0-7] [0-7]?
// | [4-7] [0-7]
// NonOctalDecimalEscapeSequence ::= [89]
- function scanEscapeSequence(shouldEmitInvalidEscapeError: boolean, isRegularExpression: boolean | "annex-b"): string {
+ function scanEscapeSequence(flags: EscapeSequenceScanningFlags): string {
const start = pos;
pos++;
if (pos >= end) {
@@ -1554,9 +1567,12 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
}
// '\47'
tokenFlags |= TokenFlags.ContainsInvalidEscape;
- if (isRegularExpression || shouldEmitInvalidEscapeError) {
+ if (flags & EscapeSequenceScanningFlags.ReportInvalidEscapeErrors) {
const code = parseInt(text.substring(start + 1, pos), 8);
- if (isRegularExpression !== "annex-b") {
+ if (flags & EscapeSequenceScanningFlags.RegularExpression && !(flags & EscapeSequenceScanningFlags.AtomEscape) && ch !== CharacterCodes._0) {
+ error(Diagnostics.Octal_escape_sequences_and_backreferences_are_not_allowed_in_a_character_class_If_this_was_intended_as_an_escape_sequence_use_the_syntax_0_instead, start, pos - start, "\\x" + code.toString(16).padStart(2, "0"));
+ }
+ else {
error(Diagnostics.Octal_escape_sequences_are_not_allowed_Use_the_syntax_0, start, pos - start, "\\x" + code.toString(16).padStart(2, "0"));
}
return String.fromCharCode(code);
@@ -1566,8 +1582,13 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
case CharacterCodes._9:
// the invalid '\8' and '\9'
tokenFlags |= TokenFlags.ContainsInvalidEscape;
- if (isRegularExpression || shouldEmitInvalidEscapeError) {
- error(Diagnostics.Escape_sequence_0_is_not_allowed, start, pos - start, text.substring(start, pos));
+ if (flags & EscapeSequenceScanningFlags.ReportInvalidEscapeErrors) {
+ if (flags & EscapeSequenceScanningFlags.RegularExpression && !(flags & EscapeSequenceScanningFlags.AtomEscape)) {
+ error(Diagnostics.Decimal_escape_sequences_and_backreferences_are_not_allowed_in_a_character_class, start, pos - start);
+ }
+ else {
+ error(Diagnostics.Escape_sequence_0_is_not_allowed, start, pos - start, text.substring(start, pos));
+ }
return String.fromCharCode(ch);
}
return text.substring(start, pos);
@@ -1589,18 +1610,18 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
return '"';
case CharacterCodes.u:
if (
- (!isRegularExpression || shouldEmitInvalidEscapeError) &&
+ flags & EscapeSequenceScanningFlags.ScanExtendedUnicodeEscape &&
pos < end && charCodeUnchecked(pos) === CharacterCodes.openBrace
) {
// '\u{DDDDDD}'
pos -= 2;
- return scanExtendedUnicodeEscape(!!isRegularExpression || shouldEmitInvalidEscapeError);
+ return scanExtendedUnicodeEscape(!!(flags & EscapeSequenceScanningFlags.ReportInvalidEscapeErrors));
}
// '\uDDDD'
for (; pos < start + 6; pos++) {
if (!(pos < end && isHexDigit(charCodeUnchecked(pos)))) {
tokenFlags |= TokenFlags.ContainsInvalidEscape;
- if (isRegularExpression || shouldEmitInvalidEscapeError) {
+ if (flags & EscapeSequenceScanningFlags.ReportInvalidEscapeErrors) {
error(Diagnostics.Hexadecimal_digit_expected);
}
return text.substring(start, pos);
@@ -1610,10 +1631,10 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
const escapedValue = parseInt(text.substring(start + 2, pos), 16);
const escapedValueString = String.fromCharCode(escapedValue);
if (
- isRegularExpression && shouldEmitInvalidEscapeError && escapedValue >= 0xD800 && escapedValue <= 0xDBFF &&
+ flags & EscapeSequenceScanningFlags.AnyUnicodeMode && escapedValue >= 0xD800 && escapedValue <= 0xDBFF &&
pos + 6 < end && text.substring(pos, pos + 2) === "\\u" && charCodeUnchecked(pos + 2) !== CharacterCodes.openBrace
) {
- // For regular expressions in Unicode mode, \u HexLeadSurrogate \u HexTrailSurrogate is treated as a single character
+ // For regular expressions in any Unicode mode, \u HexLeadSurrogate \u HexTrailSurrogate is treated as a single character
// for the purpose of determining whether a character class range is out of order
// https://tc39.es/ecma262/#prod-RegExpUnicodeEscapeSequence
const nextStart = pos;
@@ -1637,7 +1658,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
for (; pos < start + 4; pos++) {
if (!(pos < end && isHexDigit(charCodeUnchecked(pos)))) {
tokenFlags |= TokenFlags.ContainsInvalidEscape;
- if (isRegularExpression || shouldEmitInvalidEscapeError) {
+ if (flags & EscapeSequenceScanningFlags.ReportInvalidEscapeErrors) {
error(Diagnostics.Hexadecimal_digit_expected);
}
return text.substring(start, pos);
@@ -1658,7 +1679,12 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
case CharacterCodes.paragraphSeparator:
return "";
default:
- if (isRegularExpression === true && (shouldEmitInvalidEscapeError || isIdentifierPart(ch, languageVersion))) {
+ if (
+ flags & EscapeSequenceScanningFlags.AnyUnicodeMode
+ || flags & EscapeSequenceScanningFlags.RegularExpression
+ && !(flags & EscapeSequenceScanningFlags.AnnexB)
+ && isIdentifierPart(ch, languageVersion)
+ ) {
error(Diagnostics.This_character_cannot_be_escaped_in_a_regular_expression, pos - 2, 2);
}
return String.fromCharCode(ch);
@@ -2424,10 +2450,15 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
function reScanSlashToken(reportErrors?: boolean): SyntaxKind {
if (token === SyntaxKind.SlashToken || token === SyntaxKind.SlashEqualsToken) {
// Quickly get to the end of regex such that we know the flags
- let p = tokenStart + 1;
+ const startOfRegExpBody = tokenStart + 1;
+ pos = startOfRegExpBody;
let inEscape = false;
+ let namedCaptureGroups = false;
// Although nested character classes are allowed in Unicode Sets mode,
- // an unescaped slash is nevertheless invalid even in a character class in Unicode mode.
+ // an unescaped slash is nevertheless invalid even in a character class in any Unicode mode.
+ // This is indicated by Section 12.9.5 Regular Expression Literals of the specification,
+ // where nested character classes are not considered at all. (A `[` RegularExpressionClassChar
+ // does nothing in a RegularExpressionClass, and a `]` always closes the class.)
// Additionally, parsing nested character classes will misinterpret regexes like `/[[]/`
// as unterminated, consuming characters beyond the slash. (This even applies to `/[[]/v`,
// which should be parsed as a well-terminated regex with an incomplete character class.)
@@ -2436,16 +2467,9 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
while (true) {
// If we reach the end of a file, or hit a newline, then this is an unterminated
// regex. Report error and return what we have so far.
- if (p >= end) {
- tokenFlags |= TokenFlags.Unterminated;
- error(Diagnostics.Unterminated_regular_expression_literal);
- break;
- }
-
- const ch = charCodeUnchecked(p);
- if (isLineBreak(ch)) {
+ const ch = charCodeChecked(pos);
+ if (ch === CharacterCodes.EOF || isLineBreak(ch)) {
tokenFlags |= TokenFlags.Unterminated;
- error(Diagnostics.Unterminated_regular_expression_literal);
break;
}
@@ -2457,7 +2481,6 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
else if (ch === CharacterCodes.slash && !inCharacterClass) {
// A slash within a character class is permissible,
// but in general it signals the end of the regexp literal.
- p++;
break;
}
else if (ch === CharacterCodes.openBracket) {
@@ -2469,47 +2492,99 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
else if (ch === CharacterCodes.closeBracket) {
inCharacterClass = false;
}
- p++;
- }
- const isUnterminated = !!(tokenFlags & TokenFlags.Unterminated);
- const endOfBody = p - (isUnterminated ? 0 : 1);
- let regExpFlags = RegularExpressionFlags.None;
- while (p < end) {
- const ch = charCodeUnchecked(p);
- if (!isIdentifierPart(ch, languageVersion)) {
- break;
+ else if (
+ !inCharacterClass
+ && ch === CharacterCodes.openParen
+ && charCodeChecked(pos + 1) === CharacterCodes.question
+ && charCodeChecked(pos + 2) === CharacterCodes.lessThan
+ && charCodeChecked(pos + 3) !== CharacterCodes.equals
+ && charCodeChecked(pos + 3) !== CharacterCodes.exclamation
+ ) {
+ namedCaptureGroups = true;
}
- if (reportErrors) {
- const flag = characterToRegularExpressionFlag(String.fromCharCode(ch));
- if (flag === undefined) {
- error(Diagnostics.Unknown_regular_expression_flag, p, 1);
+ pos++;
+ }
+ const endOfRegExpBody = pos;
+ if (tokenFlags & TokenFlags.Unterminated) {
+ // Search for the nearest unbalanced bracket for better recovery. Since the expression is
+ // invalid anyways, we take nested square brackets into consideration for the best guess.
+ pos = startOfRegExpBody;
+ inEscape = false;
+ let characterClassDepth = 0;
+ let inDecimalQuantifier = false;
+ let groupDepth = 0;
+ while (pos < endOfRegExpBody) {
+ const ch = charCodeUnchecked(pos);
+ if (inEscape) {
+ inEscape = false;
+ }
+ else if (ch === CharacterCodes.backslash) {
+ inEscape = true;
+ }
+ else if (ch === CharacterCodes.openBracket) {
+ characterClassDepth++;
+ }
+ else if (ch === CharacterCodes.closeBracket && characterClassDepth) {
+ characterClassDepth--;
+ }
+ else if (!characterClassDepth) {
+ if (ch === CharacterCodes.openBrace) {
+ inDecimalQuantifier = true;
+ }
+ else if (ch === CharacterCodes.closeBrace && inDecimalQuantifier) {
+ inDecimalQuantifier = false;
+ }
+ else if (!inDecimalQuantifier) {
+ if (ch === CharacterCodes.openParen) {
+ groupDepth++;
+ }
+ else if (ch === CharacterCodes.closeParen && groupDepth) {
+ groupDepth--;
+ }
+ else if (ch === CharacterCodes.closeParen || ch === CharacterCodes.closeBracket || ch === CharacterCodes.closeBrace) {
+ // We encountered an unbalanced bracket outside a character class. Treat this position as the end of regex.
+ break;
+ }
+ }
}
- else if (regExpFlags & flag) {
- error(Diagnostics.Duplicate_regular_expression_flag, p, 1);
+ pos++;
+ }
+ // Whitespaces and semicolons at the end are not likely to be part of the regex
+ while (isWhiteSpaceLike(charCodeChecked(pos - 1)) || charCodeChecked(pos - 1) === CharacterCodes.semicolon) pos--;
+ error(Diagnostics.Unterminated_regular_expression_literal, tokenStart, pos - tokenStart);
+ }
+ else {
+ // Consume the slash character
+ pos++;
+ let regExpFlags = RegularExpressionFlags.None;
+ while (true) {
+ const ch = codePointChecked(pos);
+ if (ch === CharacterCodes.EOF || !isIdentifierPart(ch, languageVersion)) {
+ break;
}
- else if (((regExpFlags | flag) & RegularExpressionFlags.UnicodeMode) === RegularExpressionFlags.UnicodeMode) {
- error(Diagnostics.The_Unicode_u_flag_and_the_Unicode_Sets_v_flag_cannot_be_set_simultaneously, p, 1);
+ if (reportErrors) {
+ const flag = characterToRegularExpressionFlag(String.fromCharCode(ch));
+ if (flag === undefined) {
+ error(Diagnostics.Unknown_regular_expression_flag, pos, 1);
+ }
+ else if (regExpFlags & flag) {
+ error(Diagnostics.Duplicate_regular_expression_flag, pos, 1);
+ }
+ else if (((regExpFlags | flag) & RegularExpressionFlags.AnyUnicodeMode) === RegularExpressionFlags.AnyUnicodeMode) {
+ error(Diagnostics.The_Unicode_u_flag_and_the_Unicode_Sets_v_flag_cannot_be_set_simultaneously, pos, 1);
+ }
+ else {
+ regExpFlags |= flag;
+ checkRegularExpressionFlagAvailable(flag, pos);
+ }
}
- else {
- regExpFlags |= flag;
- checkRegularExpressionFlagAvailable(flag, p);
- }
- }
- p++;
- }
- pos = p;
- if (reportErrors) {
- const saveTokenStart = tokenStart;
- const saveTokenFlags = tokenFlags;
- const savePos = pos;
- const saveEnd = end;
- pos = tokenStart + 1;
- end = endOfBody;
- scanRegularExpressionWorker(regExpFlags, isUnterminated, /*annexB*/ true);
- tokenStart = saveTokenStart;
- tokenFlags = saveTokenFlags;
- pos = savePos;
- end = saveEnd;
+ pos++;
+ }
+ if (reportErrors) {
+ scanRange(startOfRegExpBody, endOfRegExpBody - startOfRegExpBody, () => {
+ scanRegularExpressionWorker(regExpFlags, /*annexB*/ true, namedCaptureGroups);
+ });
+ }
}
tokenValue = text.substring(tokenStart, pos);
token = SyntaxKind.RegularExpressionLiteral;
@@ -2517,7 +2592,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
return token;
}
- function scanRegularExpressionWorker(regExpFlags: RegularExpressionFlags, isUnterminated: boolean, annexB: boolean) {
+ function scanRegularExpressionWorker(regExpFlags: RegularExpressionFlags, annexB: boolean, namedCaptureGroups: boolean) {
// Why var? It avoids TDZ checks in the runtime which can be costly.
// See: https://github.com/microsoft/TypeScript/issues/52924
/* eslint-disable no-var */
@@ -2525,17 +2600,16 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
/** Grammar parameter */
var unicodeSetsMode = !!(regExpFlags & RegularExpressionFlags.UnicodeSets);
/** Grammar parameter */
- var unicodeMode = !!(regExpFlags & RegularExpressionFlags.UnicodeMode);
+ var anyUnicodeMode = !!(regExpFlags & RegularExpressionFlags.AnyUnicodeMode);
- if (unicodeMode) {
- // Annex B treats any unicode mode as the strict syntax.
- annexB = false;
- }
+ // Regular expressions are checked more strictly when either in 'u' or 'v' mode, or
+ // when not using the looser interpretation of the syntax from ECMA-262 Annex B.
+ var anyUnicodeModeOrNonAnnexB = anyUnicodeMode || !annexB;
/** @see {scanClassSetExpression} */
var mayContainStrings = false;
- /** The number of numeric (anonymous) capturing groups defined in the regex. */
+ /** The number of all (named and unnamed) capturing groups defined in the regex. */
var numberOfCapturingGroups = 0;
/** All named capturing groups defined in the regex. */
var groupSpecifiers: Set | undefined;
@@ -2626,7 +2700,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
case CharacterCodes.exclamation:
pos++;
// In Annex B, `(?=Disjunction)` and `(?!Disjunction)` are quantifiable
- isPreviousTermQuantifiable = annexB;
+ isPreviousTermQuantifiable = !anyUnicodeModeOrNonAnnexB;
break;
case CharacterCodes.lessThan:
const groupNameStart = pos;
@@ -2675,6 +2749,10 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
const digitsStart = pos;
scanDigits();
const min = tokenValue;
+ if (!anyUnicodeModeOrNonAnnexB && !min) {
+ isPreviousTermQuantifiable = true;
+ break;
+ }
if (charCodeChecked(pos) === CharacterCodes.comma) {
pos++;
scanDigits();
@@ -2684,26 +2762,32 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
error(Diagnostics.Incomplete_quantifier_Digit_expected, digitsStart, 0);
}
else {
- if (unicodeMode) {
- error(Diagnostics.Unexpected_0_Did_you_mean_to_escape_it_with_backslash, start, 1, String.fromCharCode(ch));
- }
+ error(Diagnostics.Unexpected_0_Did_you_mean_to_escape_it_with_backslash, start, 1, String.fromCharCode(ch));
isPreviousTermQuantifiable = true;
break;
}
}
- if (max && Number.parseInt(min) > Number.parseInt(max)) {
+ else if (max && Number.parseInt(min) > Number.parseInt(max) && (anyUnicodeModeOrNonAnnexB || charCodeChecked(pos) === CharacterCodes.closeBrace)) {
error(Diagnostics.Numbers_out_of_order_in_quantifier, digitsStart, pos - digitsStart);
}
}
else if (!min) {
- if (unicodeMode) {
+ if (anyUnicodeModeOrNonAnnexB) {
error(Diagnostics.Unexpected_0_Did_you_mean_to_escape_it_with_backslash, start, 1, String.fromCharCode(ch));
}
isPreviousTermQuantifiable = true;
break;
}
- scanExpectedChar(CharacterCodes.closeBrace);
- pos--;
+ if (charCodeChecked(pos) !== CharacterCodes.closeBrace) {
+ if (anyUnicodeModeOrNonAnnexB) {
+ error(Diagnostics._0_expected, pos, 0, String.fromCharCode(CharacterCodes.closeBrace));
+ pos--;
+ }
+ else {
+ isPreviousTermQuantifiable = true;
+ break;
+ }
+ }
// falls through
case CharacterCodes.asterisk:
case CharacterCodes.plus:
@@ -2740,11 +2824,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
// falls through
case CharacterCodes.closeBracket:
case CharacterCodes.closeBrace:
- if (isUnterminated && !isInGroup) {
- // Assume what starting from the character to be outside of the regex
- return;
- }
- if (unicodeMode || ch === CharacterCodes.closeParen) {
+ if (anyUnicodeModeOrNonAnnexB || ch === CharacterCodes.closeParen) {
error(Diagnostics.Unexpected_0_Did_you_mean_to_escape_it_with_backslash, pos, 1, String.fromCharCode(ch));
}
pos++;
@@ -2801,7 +2881,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
scanGroupName(/*isReference*/ true);
scanExpectedChar(CharacterCodes.greaterThan);
}
- else if (unicodeMode) {
+ else if (anyUnicodeModeOrNonAnnexB || namedCaptureGroups) {
error(Diagnostics.k_must_be_followed_by_a_capturing_group_name_enclosed_in_angle_brackets, pos - 2, 2);
}
break;
@@ -2844,6 +2924,9 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
Debug.assertEqual(charCodeUnchecked(pos - 1), CharacterCodes.backslash);
let ch = charCodeChecked(pos);
switch (ch) {
+ case CharacterCodes.EOF:
+ error(Diagnostics.Undetermined_character_escape, pos - 1, 1);
+ return "\\";
case CharacterCodes.c:
pos++;
ch = charCodeChecked(pos);
@@ -2851,10 +2934,10 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
pos++;
return String.fromCharCode(ch & 0x1f);
}
- if (unicodeMode) {
+ if (anyUnicodeModeOrNonAnnexB) {
error(Diagnostics.c_must_be_followed_by_an_ASCII_letter, pos - 2, 2);
}
- else if (atomEscape && annexB) {
+ else if (atomEscape) {
// Annex B treats
//
// ExtendedAtom : `\` [lookahead = `c`]
@@ -2882,12 +2965,13 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
pos++;
return String.fromCharCode(ch);
default:
- if (pos >= end) {
- error(Diagnostics.Undetermined_character_escape, pos - 1, 1);
- return "\\";
- }
pos--;
- return scanEscapeSequence(/*shouldEmitInvalidEscapeError*/ unicodeMode, /*isRegularExpression*/ annexB ? "annex-b" : true);
+ return scanEscapeSequence(
+ EscapeSequenceScanningFlags.RegularExpression
+ | (annexB ? EscapeSequenceScanningFlags.AnnexB : 0)
+ | (anyUnicodeMode ? EscapeSequenceScanningFlags.AnyUnicodeMode : 0)
+ | (atomEscape ? EscapeSequenceScanningFlags.AtomEscape : 0),
+ );
}
}
@@ -2936,12 +3020,12 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
if (isClassContentExit(ch)) {
return;
}
- if (!minCharacter && !annexB) {
+ if (!minCharacter && anyUnicodeModeOrNonAnnexB) {
error(Diagnostics.A_character_class_range_must_not_be_bounded_by_another_character_class, minStart, pos - 1 - minStart);
}
const maxStart = pos;
const maxCharacter = scanClassAtom();
- if (!maxCharacter && !annexB) {
+ if (!maxCharacter && anyUnicodeModeOrNonAnnexB) {
error(Diagnostics.A_character_class_range_must_not_be_bounded_by_another_character_class, maxStart, pos - maxStart);
continue;
}
@@ -3433,13 +3517,17 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
}
}
scanExpectedChar(CharacterCodes.closeBrace);
- if (!unicodeMode) {
+ if (!anyUnicodeMode) {
error(Diagnostics.Unicode_property_value_expressions_are_only_available_when_the_Unicode_u_flag_or_the_Unicode_Sets_v_flag_is_set, start, pos - start);
}
}
- else if (unicodeMode) {
+ else if (anyUnicodeModeOrNonAnnexB) {
error(Diagnostics._0_must_be_followed_by_a_Unicode_property_value_expression_enclosed_in_braces, pos - 2, 2, String.fromCharCode(ch));
}
+ else {
+ pos--;
+ return false;
+ }
return true;
}
return false;
@@ -3459,7 +3547,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
}
function scanSourceCharacter(): string {
- const size = unicodeMode ? charSize(charCodeChecked(pos)) : 1;
+ const size = anyUnicodeMode ? charSize(charCodeChecked(pos)) : 1;
pos += size;
return size > 0 ? text.substring(pos - size, pos) : "";
}
@@ -3481,14 +3569,15 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean
}
});
forEach(decimalEscapes, escape => {
- // in AnnexB, if a DecimalEscape is greater than the number of capturing groups then it is treated as
- // either a LegacyOctalEscapeSequence or IdentityEscape
- if (!annexB && escape.value > numberOfCapturingGroups) {
+ // Although a DecimalEscape with a value greater than the number of capturing groups
+ // is treated as either a LegacyOctalEscapeSequence or an IdentityEscape in Annex B,
+ // an error is nevertheless reported since it's most likely a mistake.
+ if (escape.value > numberOfCapturingGroups) {
if (numberOfCapturingGroups) {
error(Diagnostics.This_backreference_refers_to_a_group_that_does_not_exist_There_are_only_0_capturing_groups_in_this_regular_expression, escape.pos, escape.end - escape.pos, numberOfCapturingGroups);
}
else {
- error(Diagnostics.This_backreference_is_invalid_because_the_containing_regular_expression_contains_no_capturing_groups, escape.pos, escape.end - escape.pos);
+ error(Diagnostics.This_backreference_refers_to_a_group_that_does_not_exist_There_are_no_capturing_groups_in_this_regular_expression, escape.pos, escape.end - escape.pos);
}
}
});
diff --git a/src/compiler/semver.ts b/src/compiler/semver.ts
index 23573253459d5..2e472e3af5af1 100644
--- a/src/compiler/semver.ts
+++ b/src/compiler/semver.ts
@@ -8,7 +8,7 @@ import {
isArray,
map,
some,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
// https://semver.org/#spec-item-2
// > A normal version number MUST take the form X.Y.Z where X, Y, and Z are non-negative
diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts
index d6240cf0aa2bf..fbc30ba0c6ddd 100644
--- a/src/compiler/sourcemap.ts
+++ b/src/compiler/sourcemap.ts
@@ -24,8 +24,8 @@ import {
sortAndDeduplicate,
SortedReadonlyArray,
SourceMapGenerator,
-} from "./_namespaces/ts";
-import * as performance from "./_namespaces/ts.performance";
+} from "./_namespaces/ts.js";
+import * as performance from "./_namespaces/ts.performance.js";
/** @internal */
export interface SourceMapGeneratorOptions {
diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts
index 3adeee07406e4..6942028d9af79 100644
--- a/src/compiler/symbolWalker.ts
+++ b/src/compiler/symbolWalker.ts
@@ -24,7 +24,7 @@ import {
TypeQueryNode,
TypeReference,
UnionOrIntersectionType,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export function createGetSymbolWalker(
diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts
index 86e029c799494..a8fdd4d156822 100644
--- a/src/compiler/sys.ts
+++ b/src/compiler/sys.ts
@@ -46,7 +46,7 @@ import {
WatchFileKind,
WatchOptions,
writeFileEnsuringDirectories,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
declare function setTimeout(handler: (...args: any[]) => void, timeout: number): any;
declare function clearTimeout(handle: any): void;
diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts
index a1431b5749ee2..94e9bd57c83b6 100644
--- a/src/compiler/tracing.ts
+++ b/src/compiler/tracing.ts
@@ -20,8 +20,8 @@ import {
TypeReference,
unescapeLeadingUnderscores,
UnionType,
-} from "./_namespaces/ts";
-import * as performance from "./_namespaces/ts.performance";
+} from "./_namespaces/ts.js";
+import * as performance from "./_namespaces/ts.performance.js";
/* Tracing events for the compiler. */
diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts
index 607cf01e63deb..bd181e5f3c028 100644
--- a/src/compiler/transformer.ts
+++ b/src/compiler/transformer.ts
@@ -72,8 +72,8 @@ import {
transformSystemModule,
transformTypeScript,
VariableDeclaration,
-} from "./_namespaces/ts";
-import * as performance from "./_namespaces/ts.performance";
+} from "./_namespaces/ts.js";
+import * as performance from "./_namespaces/ts.performance.js";
function getModuleTransformer(moduleKind: ModuleKind): TransformerFactory {
switch (moduleKind) {
diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts
index ede44357f242d..b75468adc642f 100644
--- a/src/compiler/transformers/classFields.ts
+++ b/src/compiler/transformers/classFields.ts
@@ -86,9 +86,9 @@ import {
isCallChain,
isCallToHelper,
isCatchClause,
- isClassDeclaration,
isClassElement,
isClassExpression,
+ isClassLike,
isClassNamedEvaluationHelperBlock,
isClassStaticBlockDeclaration,
isClassThisAssignmentBlock,
@@ -225,7 +225,7 @@ import {
Visitor,
visitParameterList,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
const enum ClassPropertySubstitutionFlags {
/**
@@ -901,10 +901,9 @@ export function transformClassFields(context: TransformationContext): (x: Source
}
}
- function getClassThis() {
+ function tryGetClassThis() {
const lex = getClassLexicalEnvironment();
- const classThis = lex.classThis ?? lex.classConstructor ?? currentClassContainer?.name;
- return Debug.checkDefined(classThis);
+ return lex.classThis ?? lex.classConstructor ?? currentClassContainer?.name;
}
function transformAutoAccessor(node: AutoAccessorPropertyDeclaration): VisitResult {
@@ -946,7 +945,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
setEmitFlags(backingField, EmitFlags.NoComments);
setSourceMapRange(backingField, sourceMapRange);
- const receiver = isStatic(node) ? getClassThis() : factory.createThis();
+ const receiver = isStatic(node) ? tryGetClassThis() ?? factory.createThis() : factory.createThis();
const getter = createAccessorPropertyGetRedirector(factory, node, modifiers, getterName, receiver);
setOriginalNode(getter, node);
setCommentRange(getter, commentRange);
@@ -1713,7 +1712,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
function getClassFacts(node: ClassLikeDeclaration) {
let facts = ClassFacts.None;
const original = getOriginalNode(node);
- if (isClassDeclaration(original) && classOrConstructorParameterIsDecorated(legacyDecorators, original)) {
+ if (isClassLike(original) && classOrConstructorParameterIsDecorated(legacyDecorators, original)) {
facts |= ClassFacts.ClassWasDecorated;
}
if (shouldTransformPrivateElementsOrClassStaticBlocks && (classHasClassThisAssignment(node) || classHasExplicitlyAssignedName(node))) {
@@ -1755,7 +1754,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
}
else if (isPrivateIdentifierClassElementDeclaration(member)) {
containsInstancePrivateElements = true;
- if (resolver.getNodeCheckFlags(member) & NodeCheckFlags.ContainsConstructorReference) {
+ if (resolver.hasNodeCheckFlag(member, NodeCheckFlags.ContainsConstructorReference)) {
facts |= ClassFacts.NeedsClassConstructorReference;
}
}
@@ -1889,7 +1888,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
getClassLexicalEnvironment().classThis = node.emitNode.classThis;
}
- const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ContainsConstructorReference;
+ const isClassWithConstructorReference = resolver.hasNodeCheckFlag(node, NodeCheckFlags.ContainsConstructorReference);
const isExport = hasSyntacticModifier(node, ModifierFlags.Export);
const isDefault = hasSyntacticModifier(node, ModifierFlags.Default);
let modifiers = visitNodes(node.modifiers, modifierVisitor, isModifier);
@@ -1965,8 +1964,8 @@ export function transformClassFields(context: TransformationContext): (x: Source
// these statements after the class expression variable statement.
const isDecoratedClassDeclaration = !!(facts & ClassFacts.ClassWasDecorated);
const staticPropertiesOrClassStaticBlocks = getStaticPropertiesAndClassStaticBlock(node);
- const classCheckFlags = resolver.getNodeCheckFlags(node);
- const isClassWithConstructorReference = classCheckFlags & NodeCheckFlags.ContainsConstructorReference;
+ const isClassWithConstructorReference = resolver.hasNodeCheckFlag(node, NodeCheckFlags.ContainsConstructorReference);
+ const requiresBlockScopedVar = resolver.hasNodeCheckFlag(node, NodeCheckFlags.BlockScopedBindingInLoop);
let temp: Identifier | undefined;
function createClassTempVar() {
@@ -1983,7 +1982,6 @@ export function transformClassFields(context: TransformationContext): (x: Source
return getClassLexicalEnvironment().classConstructor = node.emitNode.classThis;
}
- const requiresBlockScopedVar = classCheckFlags & NodeCheckFlags.BlockScopedBindingInLoop;
const temp = factory.createTempVariable(requiresBlockScopedVar ? addBlockScopedVariable : hoistVariableDeclaration, /*reservedInNestedScopes*/ true);
getClassLexicalEnvironment().classConstructor = factory.cloneNode(temp);
return temp;
@@ -2712,7 +2710,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
const alreadyTransformed = !!cacheAssignment || isAssignmentExpression(innerExpression) && isGeneratedIdentifier(innerExpression.left);
if (!alreadyTransformed && !inlinable && shouldHoist) {
const generatedName = factory.getGeneratedNameForNode(name);
- if (resolver.getNodeCheckFlags(name) & NodeCheckFlags.BlockScopedBindingInLoop) {
+ if (resolver.hasNodeCheckFlag(name, NodeCheckFlags.BlockScopedBindingInLoop)) {
addBlockScopedVariable(generatedName);
}
else {
@@ -2960,7 +2958,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
typeof name === "string" ? factory.createUniqueName(name, GeneratedIdentifierFlags.Optimistic, prefix, suffix) :
factory.createTempVariable(/*recordTempVariable*/ undefined, /*reservedInNestedScopes*/ true, prefix, suffix);
- if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.BlockScopedBindingInLoop) {
+ if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.BlockScopedBindingInLoop)) {
addBlockScopedVariable(identifier);
}
else {
@@ -3295,7 +3293,7 @@ export function transformClassFields(context: TransformationContext): (x: Source
function trySubstituteClassAlias(node: Identifier): Expression | undefined {
if (enabledSubstitutions & ClassPropertySubstitutionFlags.ClassAliases) {
- if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ConstructorReference) {
+ if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.ConstructorReference)) {
// Due to the emit for class decorators, any reference to the class from inside of the class body
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
// behavior of class names in ES6.
diff --git a/src/compiler/transformers/classThis.ts b/src/compiler/transformers/classThis.ts
index 48f51ea8477c4..d6678e6c082a2 100644
--- a/src/compiler/transformers/classThis.ts
+++ b/src/compiler/transformers/classThis.ts
@@ -21,7 +21,7 @@ import {
Statement,
SyntaxKind,
ThisExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/**
* Creates a class `static {}` block used to assign the static `this` to a `_classThis` (or similar) variable.
diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts
index c14408ad5ef7d..ab75abaad6e0e 100644
--- a/src/compiler/transformers/declarations.ts
+++ b/src/compiler/transformers/declarations.ts
@@ -139,6 +139,7 @@ import {
isTupleTypeNode,
isTypeAliasDeclaration,
isTypeElement,
+ isTypeLiteralNode,
isTypeNode,
isTypeParameterDeclaration,
isTypeQueryNode,
@@ -210,7 +211,7 @@ import {
visitNode,
visitNodes,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined {
@@ -233,6 +234,7 @@ const declarationEmitNodeBuilderFlags = NodeBuilderFlags.MultilineObjectLiterals
NodeBuilderFlags.UseTypeOfFunction |
NodeBuilderFlags.UseStructuralFallback |
NodeBuilderFlags.AllowEmptyTuple |
+ NodeBuilderFlags.AllowUnresolvedNames |
NodeBuilderFlags.GenerateNamesForShadowedTypeParams |
NodeBuilderFlags.NoTruncation;
@@ -323,7 +325,8 @@ export function transformDeclarations(context: TransformationContext) {
}
// TODO: Do all these accessibility checks inside/after the first pass in the checker when declarations are enabled, if possible
}
- else {
+ // The checker should issue errors on unresolvable names, skip the declaration emit error for using a private/unreachable name for those
+ else if (symbolAccessibilityResult.accessibility !== SymbolAccessibility.NotResolved) {
// Report error
const errorInfo = getSymbolAccessibilityDiagnostic(symbolAccessibilityResult);
if (errorInfo) {
@@ -993,20 +996,26 @@ export function transformDeclarations(context: TransformationContext) {
if (shouldStripInternal(input)) return;
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
+ if (hasDynamicName(input)) {
+ if (isolatedDeclarations) {
+ // Classes and object literals 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));
+ if (isClassDeclaration(input.parent) || isObjectLiteralExpression(input.parent)) {
+ context.addDiagnostic(createDiagnosticForNode(input, Diagnostics.Computed_property_names_on_class_or_object_literals_cannot_be_inferred_with_isolatedDeclarations));
+ return;
+ }
+ else if (
+ // Type declarations just need to double-check that the input computed name is an entity name expression
+ (isInterfaceDeclaration(input.parent) || isTypeLiteralNode(input.parent))
+ && !isEntityNameExpression(input.name.expression)
+ ) {
+ context.addDiagnostic(createDiagnosticForNode(input, Diagnostics.Computed_properties_must_be_number_or_string_literals_variables_or_dotted_expressions_with_isolatedDeclarations));
+ return;
+ }
+ }
+ else if (!resolver.isLateBound(getParseTreeNode(input) as Declaration) || !isEntityNameExpression(input.name.expression)) {
+ return;
}
- return;
}
}
@@ -1778,7 +1787,7 @@ export function transformDeclarations(context: TransformationContext) {
getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNodeName(node);
}
errorNameNode = (node as NamedDeclaration).name;
- Debug.assert(resolver.isLateBound(getParseTreeNode(node) as Declaration)); // Should only be called with dynamic names
+ Debug.assert(hasDynamicName(node as NamedDeclaration)); // Should only be called with dynamic names
const decl = node as NamedDeclaration as LateBoundDeclaration;
const entityName = decl.name.expression;
checkEntityNameVisibility(entityName, enclosingDeclaration);
diff --git a/src/compiler/transformers/declarations/diagnostics.ts b/src/compiler/transformers/declarations/diagnostics.ts
index 7d0c9551e61bb..22bb998ae60bf 100644
--- a/src/compiler/transformers/declarations/diagnostics.ts
+++ b/src/compiler/transformers/declarations/diagnostics.ts
@@ -19,12 +19,14 @@ import {
DiagnosticWithLocation,
ElementAccessExpression,
EmitResolver,
+ EntityNameOrEntityNameExpression,
ExportAssignment,
Expression,
ExpressionWithTypeArguments,
findAncestor,
FunctionDeclaration,
FunctionExpression,
+ FunctionLikeDeclaration,
GetAccessorDeclaration,
getAllAccessorDeclarations,
getNameOfDeclaration,
@@ -40,9 +42,12 @@ import {
isConstructorDeclaration,
isConstructSignatureDeclaration,
isElementAccessExpression,
+ isEntityName,
+ isEntityNameExpression,
isExportAssignment,
isExpressionWithTypeArguments,
isFunctionDeclaration,
+ isFunctionLikeDeclaration,
isGetAccessor,
isHeritageClause,
isImportEqualsDeclaration,
@@ -53,15 +58,18 @@ import {
isParameter,
isParameterPropertyDeclaration,
isParenthesizedExpression,
+ isPartOfTypeNode,
isPropertyAccessExpression,
isPropertyDeclaration,
isPropertySignature,
+ isReturnStatement,
isSetAccessor,
isStatement,
isStatic,
isTypeAliasDeclaration,
isTypeAssertionExpression,
isTypeParameterDeclaration,
+ isTypeQueryNode,
isVariableDeclaration,
JSDocCallbackTag,
JSDocEnumTag,
@@ -87,7 +95,7 @@ import {
TypeAliasDeclaration,
TypeParameterDeclaration,
VariableDeclaration,
-} from "../../_namespaces/ts";
+} from "../../_namespaces/ts.js";
/** @internal */
export type GetSymbolAccessibilityDiagnostic = (symbolAccessibilityResult: SymbolAccessibilityResult) => SymbolAccessibilityDiagnostic | undefined;
@@ -623,7 +631,7 @@ export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
[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.ComputedPropertyName]: Diagnostics.Computed_property_names_on_class_or_object_literals_cannot_be_inferred_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,
@@ -658,6 +666,9 @@ export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
if (heritageClause) {
return createDiagnosticForNode(node, Diagnostics.Extends_clause_can_t_contain_an_expression_with_isolatedDeclarations);
}
+ if ((isPartOfTypeNode(node) || isTypeQueryNode(node.parent)) && (isEntityName(node) || isEntityNameExpression(node))) {
+ return createEntityInTypeNodeError(node);
+ }
Debug.type(node);
switch (node.kind) {
case SyntaxKind.GetAccessor:
@@ -694,8 +705,15 @@ export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
}
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;
+ const result = findAncestor(node, n => isExportAssignment(n) || isStatement(n) || isVariableDeclaration(n) || isPropertyDeclaration(n) || isParameter(n));
+ if (!result) return undefined;
+
+ if (isExportAssignment(result)) return result;
+
+ if (isReturnStatement(result)) {
+ return findAncestor(result, (n): n is Exclude => isFunctionLikeDeclaration(n) && !isConstructorDeclaration(n));
+ }
+ return (isStatement(result) ? undefined : result) as VariableDeclaration | PropertyDeclaration | ParameterDeclaration | ExportAssignment | undefined;
}
function createAccessorTypeError(node: GetAccessorDeclaration | SetAccessorDeclaration) {
@@ -712,31 +730,27 @@ export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
}
return diag;
}
- function createObjectLiteralError(node: ShorthandPropertyAssignment | SpreadAssignment | ComputedPropertyName) {
- const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
+ function addParentDeclarationRelatedInfo(node: Node, diag: DiagnosticWithLocation) {
const parentDeclaration = findNearestDeclaration(node);
if (parentDeclaration) {
- const targetStr = isExportAssignment(parentDeclaration) ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
+ const targetStr = isExportAssignment(parentDeclaration) || !parentDeclaration.name ? "" : getTextOfNode(parentDeclaration.name, /*includeTrivia*/ false);
addRelatedInfo(diag, createDiagnosticForNode(parentDeclaration, relatedSuggestionByDeclarationKind[parentDeclaration.kind], targetStr));
}
return diag;
}
+ function createObjectLiteralError(node: ShorthandPropertyAssignment | SpreadAssignment | ComputedPropertyName) {
+ const diag = createDiagnosticForNode(node, errorByDeclarationKind[node.kind]);
+ addParentDeclarationRelatedInfo(node, diag);
+ 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));
- }
+ addParentDeclarationRelatedInfo(node, diag);
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));
- }
+ addParentDeclarationRelatedInfo(node, diag);
addRelatedInfo(diag, createDiagnosticForNode(node, relatedSuggestionByDeclarationKind[node.kind]));
return diag;
}
@@ -768,12 +782,18 @@ export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) {
function createClassExpressionError(node: Expression) {
return createExpressionError(node, Diagnostics.Inference_from_class_expressions_is_not_supported_with_isolatedDeclarations);
}
+ function createEntityInTypeNodeError(node: EntityNameOrEntityNameExpression) {
+ const diag = createDiagnosticForNode(node, Diagnostics.Type_containing_private_name_0_can_t_be_used_with_isolatedDeclarations, getTextOfNode(node, /*includeTrivia*/ false));
+ addParentDeclarationRelatedInfo(node, diag);
+ return diag;
+ }
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 targetStr = isExportAssignment(parentDeclaration) || !parentDeclaration.name ? "" : 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));
diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts
index 1a3b93e8b77fa..aa61d9f64787b 100644
--- a/src/compiler/transformers/destructuring.ts
+++ b/src/compiler/transformers/destructuring.ts
@@ -60,7 +60,7 @@ import {
VariableDeclaration,
visitNode,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
interface FlattenContext {
context: TransformationContext;
diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts
index f8849b8cb23f7..6973b1aef26e0 100644
--- a/src/compiler/transformers/es2015.ts
+++ b/src/compiler/transformers/es2015.ts
@@ -215,7 +215,7 @@ import {
VoidExpression,
WhileStatement,
YieldExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
const enum ES2015SubstitutionFlags {
/** Enables substitutions for captured `this` */
@@ -2867,9 +2867,8 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
// * Why loop initializer is excluded?
// - Since we've introduced a fresh name it already will be undefined.
- const flags = resolver.getNodeCheckFlags(node);
- const isCapturedInFunction = flags & NodeCheckFlags.CapturedBlockScopedBinding;
- const isDeclaredInLoop = flags & NodeCheckFlags.BlockScopedBindingInLoop;
+ const isCapturedInFunction = resolver.hasNodeCheckFlag(node, NodeCheckFlags.CapturedBlockScopedBinding);
+ const isDeclaredInLoop = resolver.hasNodeCheckFlag(node, NodeCheckFlags.BlockScopedBindingInLoop);
const emittedAsTopLevel = (hierarchyFacts & HierarchyFacts.TopLevel) !== 0
|| (isCapturedInFunction
&& isDeclaredInLoop
@@ -3373,7 +3372,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
}
function shouldConvertPartOfIterationStatement(node: Node) {
- return (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ContainsCapturedBlockScopeBinding) !== 0;
+ return resolver.hasNodeCheckFlag(node, NodeCheckFlags.ContainsCapturedBlockScopeBinding);
}
function shouldConvertInitializerOfForStatement(node: IterationStatement): node is ForStatementWithConvertibleInitializer {
@@ -3394,7 +3393,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
}
function shouldConvertBodyOfIterationStatement(node: IterationStatement): boolean {
- return (resolver.getNodeCheckFlags(node) & NodeCheckFlags.LoopWithCapturedBlockScopedBinding) !== 0;
+ return resolver.hasNodeCheckFlag(node, NodeCheckFlags.LoopWithCapturedBlockScopedBinding);
}
/**
@@ -4057,11 +4056,11 @@ export function transformES2015(context: TransformationContext): (x: SourceFile
}
else {
loopParameters.push(factory.createParameterDeclaration(/*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
- const checkFlags = resolver.getNodeCheckFlags(decl);
- if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter || hasCapturedBindingsInForHead) {
+ const needsOutParam = resolver.hasNodeCheckFlag(decl, NodeCheckFlags.NeedsLoopOutParameter);
+ if (needsOutParam || hasCapturedBindingsInForHead) {
const outParamName = factory.createUniqueName("out_" + idText(name));
let flags = LoopOutParameterFlags.None;
- if (checkFlags & NodeCheckFlags.NeedsLoopOutParameter) {
+ if (needsOutParam) {
flags |= LoopOutParameterFlags.Body;
}
if (isForStatement(container)) {
diff --git a/src/compiler/transformers/es2016.ts b/src/compiler/transformers/es2016.ts
index 39d3e05a27d65..27118ae2f1d9c 100644
--- a/src/compiler/transformers/es2016.ts
+++ b/src/compiler/transformers/es2016.ts
@@ -15,7 +15,7 @@ import {
visitEachChild,
visitNode,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export function transformES2016(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle {
diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts
index 7aeb18db18b54..e1f0c9756b242 100644
--- a/src/compiler/transformers/es2017.ts
+++ b/src/compiler/transformers/es2017.ts
@@ -99,7 +99,7 @@ import {
visitNodes,
visitParameterList,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
type SuperContainer = ClassDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration;
@@ -659,7 +659,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
// This step isn't needed if we eventually transform this to ES5.
const originalMethod = getOriginalNode(node, isFunctionLikeDeclaration);
const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 &&
- resolver.getNodeCheckFlags(node) & (NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync | NodeCheckFlags.MethodWithSuperPropertyAccessInAsync) &&
+ (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) || resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync)) &&
(getFunctionFlags(originalMethod) & FunctionFlags.AsyncGenerator) !== FunctionFlags.AsyncGenerator;
if (emitSuperHelpers) {
@@ -675,10 +675,10 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
if (hasSuperElementAccess) {
// Emit helpers for super element access expressions (`super[x]`).
- if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) {
+ if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync)) {
addEmitHelper(updated, advancedAsyncSuperHelper);
}
- else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAccessInAsync) {
+ else if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync)) {
addEmitHelper(updated, asyncSuperHelper);
}
}
@@ -743,7 +743,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
const promiseConstructor = languageVersion < ScriptTarget.ES2015 ? getPromiseConstructor(nodeType) : undefined;
const isArrowFunction = node.kind === SyntaxKind.ArrowFunction;
const savedLexicalArgumentsBinding = lexicalArgumentsBinding;
- const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0;
+ const hasLexicalArguments = resolver.hasNodeCheckFlag(node, NodeCheckFlags.CaptureArguments);
const captureLexicalArguments = hasLexicalArguments && !lexicalArgumentsBinding;
if (captureLexicalArguments) {
lexicalArgumentsBinding = factory.createUniqueName("arguments");
@@ -816,7 +816,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
// This step isn't needed if we eventually transform this to ES5.
- const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && resolver.getNodeCheckFlags(node) & (NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync | NodeCheckFlags.MethodWithSuperPropertyAccessInAsync);
+ const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) || resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync));
if (emitSuperHelpers) {
enableSubstitutionForAsyncMethodsWithSuper();
@@ -836,10 +836,10 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
if (emitSuperHelpers && hasSuperElementAccess) {
// Emit helpers for super element access expressions (`super[x]`).
- if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) {
+ if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync)) {
addEmitHelper(block, advancedAsyncSuperHelper);
}
- else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAccessInAsync) {
+ else if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync)) {
addEmitHelper(block, asyncSuperHelper);
}
}
@@ -926,7 +926,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
// If we need to support substitutions for `super` in an async method,
// we should track it here.
if (enabledSubstitutions & ES2017SubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
- const superContainerFlags = resolver.getNodeCheckFlags(node) & (NodeCheckFlags.MethodWithSuperPropertyAccessInAsync | NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync);
+ const superContainerFlags = (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync) ? NodeCheckFlags.MethodWithSuperPropertyAccessInAsync : 0) | (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) ? NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync : 0);
if (superContainerFlags !== enclosingSuperContainerFlags) {
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
enclosingSuperContainerFlags = superContainerFlags;
@@ -1058,7 +1058,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile
export function createSuperAccessVariableStatement(factory: NodeFactory, resolver: EmitResolver, node: FunctionLikeDeclaration, names: Set<__String>) {
// Create a variable declaration with a getter/setter (if binding) definition for each name:
// const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... });
- const hasBinding = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) !== 0;
+ const hasBinding = resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync);
const accessors: PropertyAssignment[] = [];
names.forEach((_, key) => {
const name = unescapeLeadingUnderscores(key);
diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts
index 421bb548bf26f..4eff61428d9fd 100644
--- a/src/compiler/transformers/es2018.ts
+++ b/src/compiler/transformers/es2018.ts
@@ -110,7 +110,7 @@ import {
VisitResult,
VoidExpression,
YieldExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
const enum ESNextSubstitutionFlags {
/** Enables substitutions for async methods with `super` calls. */
@@ -1190,7 +1190,7 @@ export function transformES2018(context: TransformationContext): (x: SourceFile
// Minor optimization, emit `_super` helper to capture `super` access in an arrow.
// This step isn't needed if we eventually transform this to ES5.
- const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && resolver.getNodeCheckFlags(node) & (NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync | NodeCheckFlags.MethodWithSuperPropertyAccessInAsync);
+ const emitSuperHelpers = languageVersion >= ScriptTarget.ES2015 && (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) || resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync));
if (emitSuperHelpers) {
enableSubstitutionForAsyncMethodsWithSuper();
const variableStatement = createSuperAccessVariableStatement(factory, resolver, node, capturedSuperProperties);
@@ -1202,10 +1202,10 @@ export function transformES2018(context: TransformationContext): (x: SourceFile
const block = factory.updateBlock(node.body!, outerStatements);
if (emitSuperHelpers && hasSuperElementAccess) {
- if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) {
+ if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync)) {
addEmitHelper(block, advancedAsyncSuperHelper);
}
- else if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.MethodWithSuperPropertyAccessInAsync) {
+ else if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync)) {
addEmitHelper(block, asyncSuperHelper);
}
}
@@ -1360,7 +1360,7 @@ export function transformES2018(context: TransformationContext): (x: SourceFile
// If we need to support substitutions for `super` in an async method,
// we should track it here.
if (enabledSubstitutions & ESNextSubstitutionFlags.AsyncMethodsWithSuper && isSuperContainer(node)) {
- const superContainerFlags = resolver.getNodeCheckFlags(node) & (NodeCheckFlags.MethodWithSuperPropertyAccessInAsync | NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync);
+ const superContainerFlags = (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAccessInAsync) ? NodeCheckFlags.MethodWithSuperPropertyAccessInAsync : 0) | (resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync) ? NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync : 0);
if (superContainerFlags !== enclosingSuperContainerFlags) {
const savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags;
enclosingSuperContainerFlags = superContainerFlags;
diff --git a/src/compiler/transformers/es2019.ts b/src/compiler/transformers/es2019.ts
index 0435e4c352707..15c139078efe4 100644
--- a/src/compiler/transformers/es2019.ts
+++ b/src/compiler/transformers/es2019.ts
@@ -11,7 +11,7 @@ import {
visitEachChild,
visitNode,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export function transformES2019(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle {
diff --git a/src/compiler/transformers/es2020.ts b/src/compiler/transformers/es2020.ts
index c3eb99351fde9..8d25281d799b7 100644
--- a/src/compiler/transformers/es2020.ts
+++ b/src/compiler/transformers/es2020.ts
@@ -36,7 +36,7 @@ import {
visitNode,
visitNodes,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export function transformES2020(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle {
diff --git a/src/compiler/transformers/es2021.ts b/src/compiler/transformers/es2021.ts
index 08ab7af2a239b..026083fd5f5be 100644
--- a/src/compiler/transformers/es2021.ts
+++ b/src/compiler/transformers/es2021.ts
@@ -19,7 +19,7 @@ import {
visitEachChild,
visitNode,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export function transformES2021(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle {
diff --git a/src/compiler/transformers/esDecorators.ts b/src/compiler/transformers/esDecorators.ts
index e164665379205..7609ab957a0c5 100644
--- a/src/compiler/transformers/esDecorators.ts
+++ b/src/compiler/transformers/esDecorators.ts
@@ -188,7 +188,7 @@ import {
Visitor,
VisitResult,
WrappedExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
// Class/Decorator evaluation order, as it pertains to this transformer:
//
diff --git a/src/compiler/transformers/esnext.ts b/src/compiler/transformers/esnext.ts
index 62d40e7831270..4deb7ecbd9a36 100644
--- a/src/compiler/transformers/esnext.ts
+++ b/src/compiler/transformers/esnext.ts
@@ -14,6 +14,7 @@ import {
ExportAssignment,
ExportSpecifier,
Expression,
+ firstOrUndefined,
ForOfStatement,
ForStatement,
GeneratedIdentifierFlags,
@@ -61,7 +62,7 @@ import {
visitNode,
visitNodes,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
const enum UsingKind {
None,
@@ -305,11 +306,7 @@ export function transformESNext(context: TransformationContext): (x: SourceFile
//
// before handing the shallow transformation back to the visitor for an in-depth transformation.
const forInitializer = node.initializer;
- Debug.assertNode(forInitializer, isUsingVariableDeclarationList);
- Debug.assert(forInitializer.declarations.length === 1, "ForInitializer may only have one declaration");
-
- const forDecl = forInitializer.declarations[0];
- Debug.assert(!forDecl.initializer, "ForInitializer may not have an initializer");
+ const forDecl = firstOrUndefined(forInitializer.declarations) || factory.createVariableDeclaration(factory.createTempVariable(/*recordTempVariable*/ undefined));
const isAwaitUsing = getUsingKindOfVariableDeclarationList(forInitializer) === UsingKind.Async;
const temp = factory.getGeneratedNameForNode(forDecl.name);
diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts
index 775075a6e8f6f..4031cb704665a 100644
--- a/src/compiler/transformers/generators.ts
+++ b/src/compiler/transformers/generators.ts
@@ -95,7 +95,7 @@ import {
WhileStatement,
WithStatement,
YieldExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
// Transforms generator functions into a compatible ES5 representation with similar runtime
// semantics. This is accomplished by first transforming the body of each generator
diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts
index 1044618351aef..49d04a2fd8280 100644
--- a/src/compiler/transformers/jsx.ts
+++ b/src/compiler/transformers/jsx.ts
@@ -84,7 +84,7 @@ import {
visitEachChild,
visitNode,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export function transformJsx(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle {
diff --git a/src/compiler/transformers/legacyDecorators.ts b/src/compiler/transformers/legacyDecorators.ts
index 69f955e39b9cd..6ef7745dfd301 100644
--- a/src/compiler/transformers/legacyDecorators.ts
+++ b/src/compiler/transformers/legacyDecorators.ts
@@ -82,7 +82,7 @@ import {
visitNode,
visitNodes,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export function transformLegacyDecorators(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle {
@@ -773,7 +773,7 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
* double-binding semantics for the class name.
*/
function getClassAliasIfNeeded(node: ClassDeclaration) {
- if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ContainsConstructorReference) {
+ if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.ContainsConstructorReference)) {
enableSubstitutionForClassAliases();
const classAlias = factory.createUniqueName(node.name && !isGeneratedIdentifier(node.name) ? idText(node.name) : "default");
classAliases[getOriginalNodeId(node)] = classAlias;
@@ -822,7 +822,7 @@ export function transformLegacyDecorators(context: TransformationContext): (x: S
function trySubstituteClassAlias(node: Identifier): Expression | undefined {
if (classAliases) {
- if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ConstructorReference) {
+ if (resolver.hasNodeCheckFlag(node, NodeCheckFlags.ConstructorReference)) {
// Due to the emit for class decorators, any reference to the class from inside of the class body
// must instead be rewritten to point to a temporary variable to avoid issues with the double-bind
// behavior of class names in ES6.
diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts
index 12c8fd87136ed..0c3bbc8129a2a 100644
--- a/src/compiler/transformers/module/esnextAnd2015.ts
+++ b/src/compiler/transformers/module/esnextAnd2015.ts
@@ -49,7 +49,7 @@ import {
visitEachChild,
visitNodes,
VisitResult,
-} from "../../_namespaces/ts";
+} from "../../_namespaces/ts.js";
/** @internal */
export function transformECMAScriptModule(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle {
diff --git a/src/compiler/transformers/module/impliedNodeFormatDependent.ts b/src/compiler/transformers/module/impliedNodeFormatDependent.ts
index c96ead5ebf753..7a5bf9e210fcd 100644
--- a/src/compiler/transformers/module/impliedNodeFormatDependent.ts
+++ b/src/compiler/transformers/module/impliedNodeFormatDependent.ts
@@ -11,7 +11,7 @@ import {
TransformationContext,
transformECMAScriptModule,
transformModule,
-} from "../../_namespaces/ts";
+} from "../../_namespaces/ts.js";
/** @internal */
export function transformImpliedNodeFormatDependentModule(context: TransformationContext) {
diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts
index 959c59f3e2952..92b214276e533 100644
--- a/src/compiler/transformers/module/module.ts
+++ b/src/compiler/transformers/module/module.ts
@@ -161,7 +161,7 @@ import {
VisitResult,
WhileStatement,
WithStatement,
-} from "../../_namespaces/ts";
+} from "../../_namespaces/ts.js";
/** @internal */
export function transformModule(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle {
@@ -283,10 +283,8 @@ export function transformModule(context: TransformationContext): (x: SourceFile
);
}
}
- if (some(currentModuleInfo.exportedFunctions)) {
- for (const f of currentModuleInfo.exportedFunctions) {
- appendExportsOfHoistedDeclaration(statements, f);
- }
+ for (const f of currentModuleInfo.exportedFunctions) {
+ appendExportsOfHoistedDeclaration(statements, f);
}
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, topLevelVisitor, isStatement));
@@ -613,10 +611,8 @@ export function transformModule(context: TransformationContext): (x: SourceFile
if (some(currentModuleInfo.exportedNames)) {
append(statements, factory.createExpressionStatement(reduceLeft(currentModuleInfo.exportedNames, (prev, nextId) => factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier("exports"), factory.createIdentifier(idText(nextId))), prev), factory.createVoidZero() as Expression)));
}
- if (some(currentModuleInfo.exportedFunctions)) {
- for (const f of currentModuleInfo.exportedFunctions) {
- appendExportsOfHoistedDeclaration(statements, f);
- }
+ for (const f of currentModuleInfo.exportedFunctions) {
+ appendExportsOfHoistedDeclaration(statements, f);
}
// Visit each statement of the module body.
diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts
index 10d6b7047ed74..f03ad63a1c0ca 100644
--- a/src/compiler/transformers/module/system.ts
+++ b/src/compiler/transformers/module/system.ts
@@ -128,7 +128,7 @@ import {
VisitResult,
WhileStatement,
WithStatement,
-} from "../../_namespaces/ts";
+} from "../../_namespaces/ts.js";
/** @internal */
export function transformSystemModule(context: TransformationContext): (x: SourceFile | Bundle) => SourceFile | Bundle {
@@ -433,7 +433,7 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
// this set is used to filter names brought by star expors.
// local names set should only be added if we have anything exported
- if (!some(moduleInfo.exportedNames) && !some(moduleInfo.exportedFunctions) && moduleInfo.exportSpecifiers.size === 0) {
+ if (!some(moduleInfo.exportedNames) && moduleInfo.exportedFunctions.size === 0 && moduleInfo.exportSpecifiers.size === 0) {
// no exported declarations (export var ...) or export specifiers (export {x})
// check if we have any non star export declarations.
let hasExportDeclarationWithExportClause = false;
@@ -469,21 +469,19 @@ export function transformSystemModule(context: TransformationContext): (x: Sourc
}
}
- if (moduleInfo.exportedFunctions) {
- for (const f of moduleInfo.exportedFunctions) {
- if (hasSyntacticModifier(f, ModifierFlags.Default)) {
- continue;
- }
- Debug.assert(!!f.name);
-
- // write name of exported declaration, i.e 'export var x...'
- exportedNames.push(
- factory.createPropertyAssignment(
- factory.createStringLiteralFromNode(f.name),
- factory.createTrue(),
- ),
- );
+ for (const f of moduleInfo.exportedFunctions) {
+ if (hasSyntacticModifier(f, ModifierFlags.Default)) {
+ continue;
}
+ Debug.assert(!!f.name);
+
+ // write name of exported declaration, i.e 'export var x...'
+ exportedNames.push(
+ factory.createPropertyAssignment(
+ factory.createStringLiteralFromNode(f.name),
+ factory.createTrue(),
+ ),
+ );
}
const exportedNamesStorageRef = factory.createUniqueName("exportedNames");
diff --git a/src/compiler/transformers/namedEvaluation.ts b/src/compiler/transformers/namedEvaluation.ts
index 34123cf560080..785ed280c4158 100644
--- a/src/compiler/transformers/namedEvaluation.ts
+++ b/src/compiler/transformers/namedEvaluation.ts
@@ -48,7 +48,7 @@ import {
TransformationContext,
VariableDeclaration,
WrappedExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/**
* Gets a string literal to use as the assigned name of an anonymous class or function declaration.
diff --git a/src/compiler/transformers/taggedTemplate.ts b/src/compiler/transformers/taggedTemplate.ts
index a905dcb26ecb8..94f01dec4ba5e 100644
--- a/src/compiler/transformers/taggedTemplate.ts
+++ b/src/compiler/transformers/taggedTemplate.ts
@@ -23,7 +23,7 @@ import {
visitEachChild,
visitNode,
Visitor,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export enum ProcessLevel {
diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts
index b4c7172cf05d2..668da90d8e696 100644
--- a/src/compiler/transformers/ts.ts
+++ b/src/compiler/transformers/ts.ts
@@ -201,7 +201,7 @@ import {
visitNodes,
visitParameterList,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/**
* Indicates whether to emit type metadata in the new format.
diff --git a/src/compiler/transformers/typeSerializer.ts b/src/compiler/transformers/typeSerializer.ts
index 2fcd9264e0b06..4c9d397b74385 100644
--- a/src/compiler/transformers/typeSerializer.ts
+++ b/src/compiler/transformers/typeSerializer.ts
@@ -67,7 +67,7 @@ import {
TypeReferenceSerializationKind,
UnionOrIntersectionTypeNode,
VoidExpression,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export type SerializedEntityName =
diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts
index ad86ded1cb6f2..8f5f2b257a004 100644
--- a/src/compiler/transformers/utilities.ts
+++ b/src/compiler/transformers/utilities.ts
@@ -90,7 +90,7 @@ import {
unorderedRemoveItem,
VariableDeclaration,
VariableStatement,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export function getOriginalNodeId(node: Node) {
@@ -105,7 +105,7 @@ export interface ExternalModuleInfo {
exportSpecifiers: IdentifierNameMap; // file-local export specifiers by name (no reexports)
exportedBindings: Identifier[][]; // exported names of local declarations
exportedNames: Identifier[] | undefined; // all exported names in the module, both local and reexported, excluding the names of locally exported function declarations
- exportedFunctions: FunctionDeclaration[] | undefined; // all of the top-level exported function declarations
+ exportedFunctions: Set; // all of the top-level exported function declarations
exportEquals: ExportAssignment | undefined; // an export= declaration if one was present
hasExportStarsToExportValues: boolean; // whether this module contains export*
}
@@ -174,8 +174,8 @@ export function collectExternalModuleInfo(context: TransformationContext, source
const exportSpecifiers = new IdentifierNameMultiMap();
const exportedBindings: Identifier[][] = [];
const uniqueExports = new Map();
+ const exportedFunctions = new Set();
let exportedNames: Identifier[] | undefined;
- let exportedFunctions: FunctionDeclaration[] | undefined;
let hasExportDefault = false;
let exportEquals: ExportAssignment | undefined;
let hasExportStarsToExportValues = false;
@@ -256,22 +256,7 @@ export function collectExternalModuleInfo(context: TransformationContext, source
case SyntaxKind.FunctionDeclaration:
if (hasSyntacticModifier(node, ModifierFlags.Export)) {
- exportedFunctions = append(exportedFunctions, node as FunctionDeclaration);
- if (hasSyntacticModifier(node, ModifierFlags.Default)) {
- // export default function() { }
- if (!hasExportDefault) {
- multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), context.factory.getDeclarationName(node as FunctionDeclaration));
- hasExportDefault = true;
- }
- }
- else {
- // export function x() { }
- const name = (node as FunctionDeclaration).name!;
- if (!uniqueExports.get(idText(name))) {
- multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
- uniqueExports.set(idText(name), true);
- }
- }
+ addExportedFunctionDeclaration(node as FunctionDeclaration, /*name*/ undefined, hasSyntacticModifier(node, ModifierFlags.Default));
}
break;
@@ -317,6 +302,11 @@ export function collectExternalModuleInfo(context: TransformationContext, source
|| resolver.getReferencedValueDeclaration(name);
if (decl) {
+ if (decl.kind === SyntaxKind.FunctionDeclaration) {
+ addExportedFunctionDeclaration(decl as FunctionDeclaration, specifier.name, specifier.name.escapedText === InternalSymbolName.Default);
+ continue;
+ }
+
multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
}
@@ -325,6 +315,27 @@ export function collectExternalModuleInfo(context: TransformationContext, source
}
}
}
+
+ function addExportedFunctionDeclaration(node: FunctionDeclaration, name: Identifier | undefined, isDefault: boolean) {
+ exportedFunctions.add(node);
+ if (isDefault) {
+ // export default function() { }
+ // function x() { } + export { x as default };
+ if (!hasExportDefault) {
+ multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name ?? context.factory.getDeclarationName(node));
+ hasExportDefault = true;
+ }
+ }
+ else {
+ // export function x() { }
+ // function x() { } + export { x }
+ name ??= node.name!;
+ if (!uniqueExports.get(idText(name))) {
+ multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name);
+ uniqueExports.set(idText(name), true);
+ }
+ }
+ }
}
function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map, exportedNames: Identifier[] | undefined, exportedBindings: Identifier[][]) {
diff --git a/src/compiler/tsbuild.ts b/src/compiler/tsbuild.ts
index cf902ea11c2f8..39a448fea9a15 100644
--- a/src/compiler/tsbuild.ts
+++ b/src/compiler/tsbuild.ts
@@ -4,7 +4,7 @@ import {
fileExtensionIs,
Path,
ResolvedConfigFileName,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export enum UpToDateStatusType {
diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts
index a44e6a6bc428d..a7ca5dad5bdbe 100644
--- a/src/compiler/tsbuildPublic.ts
+++ b/src/compiler/tsbuildPublic.ts
@@ -48,6 +48,7 @@ import {
findIndex,
flattenDiagnosticMessageText,
forEach,
+ forEachEntry,
forEachKey,
ForegroundColorEscapeSequences,
formatColorAndReset,
@@ -70,7 +71,6 @@ import {
getWatchErrorSummaryDiagnosticMessage,
hasProperty,
identity,
- isArray,
isIgnoredFileFromWildCardWatching,
isIncrementalCompilation,
isPackageJsonInfo,
@@ -104,7 +104,6 @@ import {
SemanticDiagnosticsBuilderProgram,
setGetSourceFileAsHashVersioned,
SharedExtendedConfigFileWatcher,
- some,
SourceFile,
Status,
sys,
@@ -126,8 +125,8 @@ import {
WildcardDirectoryWatcher,
writeFile,
WriteFileCallback,
-} from "./_namespaces/ts";
-import * as performance from "./_namespaces/ts.performance";
+} from "./_namespaces/ts.js";
+import * as performance from "./_namespaces/ts.performance.js";
const minimumDate = new Date(-8640000000000000);
const maximumDate = new Date(8640000000000000);
@@ -1697,7 +1696,7 @@ function getUpToDateStatusWorker(state: SolutionBuilde
(!project.options.noEmit ?
(buildInfo.program as ProgramMultiFileEmitBuildInfo).affectedFilesPendingEmit?.length ||
(buildInfo.program as ProgramMultiFileEmitBuildInfo).emitDiagnosticsPerFile?.length :
- some((buildInfo.program as ProgramMultiFileEmitBuildInfo).semanticDiagnosticsPerFile, isArray))
+ (buildInfo.program as ProgramMultiFileEmitBuildInfo).semanticDiagnosticsPerFile?.length)
) {
return {
type: UpToDateStatusType.OutOfDateBuildInfo,
@@ -1734,6 +1733,7 @@ function getUpToDateStatusWorker(state: SolutionBuilde
};
}
+ const inputPath = buildInfoProgram ? toPath(state, inputFile) : undefined;
// If an buildInfo is older than the newest input, we can stop checking
if (buildInfoTime && buildInfoTime < inputTime) {
let version: string | undefined;
@@ -1741,8 +1741,9 @@ function getUpToDateStatusWorker(state: SolutionBuilde
if (buildInfoProgram) {
// Read files and see if they are same, read is anyways cached
if (!buildInfoVersionMap) buildInfoVersionMap = getBuildInfoFileVersionMap(buildInfoProgram, buildInfoPath!, host);
- version = buildInfoVersionMap.fileInfos.get(toPath(state, inputFile));
- const text = version ? state.readFileWithCache(inputFile) : undefined;
+ const resolvedInputPath = buildInfoVersionMap.roots.get(inputPath!);
+ version = buildInfoVersionMap.fileInfos.get(resolvedInputPath ?? inputPath!);
+ const text = version ? state.readFileWithCache(resolvedInputPath ?? inputFile) : undefined;
currentVersion = text !== undefined ? getSourceFileVersionAsHashFromText(host, text) : undefined;
if (version && version === currentVersion) pseudoInputUpToDate = true;
}
@@ -1761,20 +1762,22 @@ function getUpToDateStatusWorker(state: SolutionBuilde
newestInputFileTime = inputTime;
}
- if (buildInfoProgram) seenRoots.add(toPath(state, inputFile));
+ if (buildInfoProgram) seenRoots.add(inputPath!);
}
if (buildInfoProgram) {
if (!buildInfoVersionMap) buildInfoVersionMap = getBuildInfoFileVersionMap(buildInfoProgram, buildInfoPath!, host);
- for (const existingRoot of buildInfoVersionMap.roots) {
- if (!seenRoots.has(existingRoot)) {
- // File was root file when project was built but its not any more
- return {
- type: UpToDateStatusType.OutOfDateRoots,
- buildInfoFile: buildInfoPath!,
- inputFile: existingRoot,
- };
- }
+ const existingRoot = forEachEntry(
+ buildInfoVersionMap.roots,
+ // File was root file when project was built but its not any more
+ (_resolved, existingRoot) => !seenRoots.has(existingRoot) ? existingRoot : undefined,
+ );
+ if (existingRoot) {
+ return {
+ type: UpToDateStatusType.OutOfDateRoots,
+ buildInfoFile: buildInfoPath!,
+ inputFile: existingRoot,
+ };
}
}
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 21339a7742bd9..9df1b4a8e7f31 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -16,7 +16,7 @@ import {
ProgramBuildInfo,
SymlinkCache,
ThisContainer,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
// branded string type used to store absolute, normalized and canonicalized paths
// arbitrary file name can be converted to Path via toPath function
@@ -2765,17 +2765,17 @@ export interface RegularExpressionLiteral extends LiteralExpression {
// 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,
+ 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
+ AnyUnicodeMode = Unicode | UnicodeSets,
+ Modifiers = IgnoreCase | Multiline | DotAll,
}
export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode, Declaration {
@@ -4608,26 +4608,24 @@ export type FileIncludeReason =
/** @internal */
export const enum FilePreprocessingDiagnosticsKind {
- FilePreprocessingReferencedDiagnostic,
+ FilePreprocessingLibReferenceDiagnostic,
FilePreprocessingFileExplainingDiagnostic,
ResolutionDiagnostics,
}
/** @internal */
-export interface FilePreprocessingReferencedDiagnostic {
- kind: FilePreprocessingDiagnosticsKind.FilePreprocessingReferencedDiagnostic;
- reason: ReferencedFile;
- diagnostic: DiagnosticMessage;
- args?: DiagnosticArguments;
+export interface FilePreprocessingLibReferenceDiagnostic {
+ kind: FilePreprocessingDiagnosticsKind.FilePreprocessingLibReferenceDiagnostic;
+ reason: ReferencedFile & { kind: FileIncludeKind.LibReferenceDirective; };
}
/** @internal */
export interface FilePreprocessingFileExplainingDiagnostic {
kind: FilePreprocessingDiagnosticsKind.FilePreprocessingFileExplainingDiagnostic;
- file?: Path;
+ file: Path | undefined;
fileProcessingReason: FileIncludeReason;
diagnostic: DiagnosticMessage;
- args?: DiagnosticArguments;
+ args: DiagnosticArguments;
}
/** @internal */
@@ -4637,7 +4635,7 @@ export interface ResolutionDiagnostics {
}
/** @internal */
-export type FilePreprocessingDiagnostics = FilePreprocessingReferencedDiagnostic | FilePreprocessingFileExplainingDiagnostic | ResolutionDiagnostics;
+export type FilePreprocessingDiagnostics = FilePreprocessingLibReferenceDiagnostic | FilePreprocessingFileExplainingDiagnostic | ResolutionDiagnostics;
/** @internal */
export const enum EmitOnly {
@@ -4681,10 +4679,12 @@ export interface Program extends ScriptReferenceHost {
/** @internal */
getResolvedModule(f: SourceFile, moduleName: string, mode: ResolutionMode): ResolvedModuleWithFailedLookupLocations | undefined;
/** @internal */
- getResolvedModuleFromModuleSpecifier(moduleSpecifier: StringLiteralLike): ResolvedModuleWithFailedLookupLocations | undefined;
+ getResolvedModuleFromModuleSpecifier(moduleSpecifier: StringLiteralLike, sourceFile?: SourceFile): ResolvedModuleWithFailedLookupLocations | undefined;
/** @internal */
getResolvedTypeReferenceDirective(f: SourceFile, typeDirectiveName: string, mode: ResolutionMode): ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined;
/** @internal */
+ getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(typedRef: FileReference, sourceFile: SourceFile): ResolvedTypeReferenceDirectiveWithFailedLookupLocations | undefined;
+ /** @internal */
forEachResolvedModule(
callback: (resolution: ResolvedModuleWithFailedLookupLocations, moduleName: string, mode: ResolutionMode, filePath: Path) => void,
file?: SourceFile,
@@ -4740,7 +4740,6 @@ export interface Program extends ScriptReferenceHost {
getRelationCacheSizes(): { assignable: number; identity: number; subtype: number; strictSubtype: number; };
/** @internal */ getFileProcessingDiagnostics(): FilePreprocessingDiagnostics[] | undefined;
- /** @internal */ getResolvedTypeReferenceDirectives(): ModeAwareCache;
/** @internal */ getAutomaticTypeDirectiveNames(): string[];
/** @internal */ getAutomaticTypeDirectiveResolutions(): ModeAwareCache;
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
@@ -5265,7 +5264,8 @@ export interface TypeChecker {
// Should not be called directly. Should only be accessed through the Program instance.
/** @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
/** @internal */ getGlobalDiagnostics(): Diagnostic[];
- /** @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken): EmitResolver;
+ /** @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken, forceDts?: boolean): EmitResolver;
+ /** @internal */ requiresAddingImplicitUndefined(parameter: ParameterDeclaration | JSDocParameterTag): boolean;
/** @internal */ getNodeCount(): number;
/** @internal */ getIdentifierCount(): number;
@@ -5355,6 +5355,8 @@ export interface TypeChecker {
* and the operation is cancelled, then it should be discarded, otherwise it is safe to keep.
*/
runWithCancellationToken(token: CancellationToken, cb: (checker: TypeChecker) => T): T;
+ /**@internal */
+ runWithCancellationToken(token: CancellationToken | undefined, cb: (checker: TypeChecker) => T): T; // eslint-disable-line @typescript-eslint/unified-signatures
/** @internal */ getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol: Symbol): readonly TypeParameter[] | undefined;
/** @internal */ isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean;
@@ -5363,6 +5365,7 @@ export interface TypeChecker {
/** @internal */ getMemberOverrideModifierStatus(node: ClassLikeDeclaration, member: ClassElement, memberSymbol: Symbol): MemberOverrideStatus;
/** @internal */ isTypeParameterPossiblyReferenced(tp: TypeParameter, node: Node): boolean;
/** @internal */ typeHasCallOrConstructSignatures(type: Type): boolean;
+ /** @internal */ getSymbolFlags(symbol: Symbol): SymbolFlags;
}
/** @internal */
@@ -5379,6 +5382,13 @@ export const enum UnionReduction {
Subtype,
}
+/** @internal */
+export const enum IntersectionFlags {
+ None = 0,
+ NoSupertypeReduction = 1 << 0,
+ NoConstraintReduction = 1 << 1,
+}
+
// dprint-ignore
/** @internal */
export const enum ContextFlags {
@@ -5426,6 +5436,7 @@ export const enum NodeBuilderFlags {
// Errors (cont.)
AllowNodeModulesRelativePaths = 1 << 26,
/** @internal */ DoNotIncludeSymbolChain = 1 << 27, // Skip looking up and printing an accessible symbol chain
+ /** @internal */ AllowUnresolvedNames = 1 << 32,
IgnoreErrors = AllowThisInObjectLiteral | AllowQualifiedNameInPlaceOfIdentifier | AllowAnonymousIdentifier | AllowEmptyUnionOrIntersection | AllowEmptyTuple | AllowEmptyIndexInfoType | AllowNodeModulesRelativePaths,
@@ -5536,6 +5547,7 @@ export const enum SymbolAccessibility {
Accessible,
NotAccessible,
CannotBeNamed,
+ NotResolved,
}
/** @internal */
@@ -5741,9 +5753,24 @@ export enum TypeReferenceSerializationKind {
ObjectType,
}
+/** @internal */
+export type LazyNodeCheckFlags =
+ | NodeCheckFlags.SuperInstance
+ | NodeCheckFlags.SuperStatic
+ | NodeCheckFlags.MethodWithSuperPropertyAccessInAsync
+ | NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync
+ | NodeCheckFlags.ContainsSuperPropertyInStaticInitializer
+ | NodeCheckFlags.CaptureArguments
+ | NodeCheckFlags.ContainsCapturedBlockScopeBinding
+ | NodeCheckFlags.NeedsLoopOutParameter
+ | NodeCheckFlags.ContainsConstructorReference
+ | NodeCheckFlags.ConstructorReference
+ | NodeCheckFlags.CapturedBlockScopedBinding
+ | NodeCheckFlags.BlockScopedBindingInLoop
+ | NodeCheckFlags.LoopWithCapturedBlockScopedBinding;
+
/** @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;
@@ -5752,10 +5779,11 @@ export interface EmitResolver {
isValueAliasDeclaration(node: Node): boolean;
isReferencedAliasDeclaration(node: Node, checkChildren?: boolean): boolean;
isTopLevelValueImportEqualsWithEntityName(node: ImportEqualsDeclaration): boolean;
- getNodeCheckFlags(node: Node): NodeCheckFlags;
+ hasNodeCheckFlag(node: Node, flags: LazyNodeCheckFlags): boolean;
isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean;
isLateBound(node: Declaration): node is LateBoundDeclaration;
collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined;
+ markLinkedReferences(node: Node): void;
isImplementationOfOverload(node: SignatureDeclaration): boolean | undefined;
requiresAddingImplicitUndefined(node: ParameterDeclaration): boolean;
isExpandoFunctionDeclaration(node: FunctionDeclaration | VariableDeclaration): boolean;
@@ -5911,10 +5939,7 @@ export interface SymbolLinks {
uniqueESSymbolType?: Type; // UniqueESSymbol type for a symbol
declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter
typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic)
- outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type
instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic)
- aliasSymbol?: Symbol; // Alias associated with generic type alias instantiation
- aliasTypeArguments?: readonly Type[] // Alias type arguments (if any)
inferredClassSymbol?: Map; // Symbol of an inferred ES5 constructor function
mapper?: TypeMapper; // Type mapper for instantiation alias
referenced?: boolean; // True if alias symbol has been referenced as a value that can be emitted
@@ -5929,8 +5954,6 @@ export interface SymbolLinks {
typeParametersChecked?: boolean; // True if type parameters of merged class and interface declarations have been checked.
isDeclarationWithCollidingName?: boolean; // True if symbol is block scoped redeclaration
bindingElement?: BindingElement; // Binding element associated with property symbol
- exportsSomeValue?: boolean; // True if module exports some value (not just types)
- enumKind?: EnumKind; // Enum declaration classification
originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol`
lateSymbol?: Symbol; // Late-bound symbol for a computed property
specifierCache?: Map; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings
@@ -5948,12 +5971,7 @@ export interface SymbolLinks {
tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label
accessibleChainCache?: Map;
filteredIndexSymbolCache?: Map //Symbol with applicable declarations
-}
-
-/** @internal */
-export const enum EnumKind {
- Numeric, // Numeric enum (each member has a TypeFlags.Enum type)
- Literal, // Literal enum (each member has a TypeFlags.EnumLiteral type)
+ requestedExternalEmitHelpers?: ExternalEmitHelpers; // External emit helpers already checked for this symbol.
}
// dprint-ignore
@@ -6097,6 +6115,21 @@ export const enum NodeCheckFlags {
ContainsClassWithPrivateIdentifiers = 1 << 20, // Marked on all block-scoped containers containing a class with private identifiers.
ContainsSuperPropertyInStaticInitializer = 1 << 21, // Marked on all block-scoped containers containing a static initializer with 'super.x' or 'super[x]'.
InCheckIdentifier = 1 << 22,
+
+ /** These flags are LazyNodeCheckFlags and can be calculated lazily by `hasNodeCheckFlag` */
+ LazyFlags = SuperInstance
+ | SuperStatic
+ | MethodWithSuperPropertyAccessInAsync
+ | MethodWithSuperPropertyAssignmentInAsync
+ | ContainsSuperPropertyInStaticInitializer
+ | CaptureArguments
+ | ContainsCapturedBlockScopeBinding
+ | NeedsLoopOutParameter
+ | ContainsConstructorReference
+ | ConstructorReference
+ | CapturedBlockScopedBinding
+ | BlockScopedBindingInLoop
+ | LoopWithCapturedBlockScopedBinding,
}
/** @internal */
@@ -6111,8 +6144,8 @@ export interface EvaluatorResult | undefined;
- set(fromFileName: Path, toFileName: Path, preferences: UserPreferences, options: ModuleSpecifierOptions, modulePaths: readonly ModulePath[], moduleSpecifiers: readonly string[]): void;
+ set(fromFileName: Path, toFileName: Path, preferences: UserPreferences, options: ModuleSpecifierOptions, kind: ResolvedModuleSpecifierInfo["kind"], modulePaths: readonly ModulePath[], moduleSpecifiers: readonly string[]): void;
setBlockedByPackageJsonDependencies(fromFileName: Path, toFileName: Path, preferences: UserPreferences, options: ModuleSpecifierOptions, isBlockedByPackageJsonDependencies: boolean): void;
setModulePaths(fromFileName: Path, toFileName: Path, preferences: UserPreferences, options: ModuleSpecifierOptions, modulePaths: readonly ModulePath[]): void;
clear(): void;
@@ -10291,7 +10330,6 @@ export interface SyntacticTypeNodeBuilderContext {
/** @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;
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index 3b67540ffcb8e..8f9238385deff 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -585,7 +585,7 @@ import {
WriteFileCallback,
WriteFileCallbackData,
YieldExpression,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export const resolvingEmptyArray: never[] = [];
@@ -2485,6 +2485,7 @@ export function getJSDocCommentRanges(node: Node, text: string) {
getLeadingCommentRanges(text, node.pos);
// True if the comment starts with '/**' but not if it is '/**/'
return filter(commentRanges, comment =>
+ comment.end <= node.end && // Due to parse errors sometime empty parameter may get comments assigned to it that end up not in parameter range
text.charCodeAt(comment.pos + 1) === CharacterCodes.asterisk &&
text.charCodeAt(comment.pos + 2) === CharacterCodes.asterisk &&
text.charCodeAt(comment.pos + 3) !== CharacterCodes.slash);
@@ -6679,6 +6680,7 @@ export function getAllAccessorDeclarations(declarations: readonly Declaration[]
*/
export function getEffectiveTypeAnnotationNode(node: Node): TypeNode | undefined {
if (!isInJSFile(node) && isFunctionDeclaration(node)) return undefined;
+ if (isTypeAliasDeclaration(node)) return undefined; // has a .type, is not a type annotation
const type = (node as HasType).type;
if (type || !isInJSFile(node)) return type;
return isJSDocPropertyLikeTag(node) ? node.typeExpression && node.typeExpression.type : getJSDocType(node);
@@ -11116,7 +11118,8 @@ export function createNameResolver({
if (meaning & result.flags & SymbolFlags.Type && lastLocation.kind !== SyntaxKind.JSDoc) {
useResult = result.flags & SymbolFlags.TypeParameter
// type parameters are visible in parameter list, return type and type parameter list
- ? lastLocation === (location as FunctionLikeDeclaration).type ||
+ ? !!(lastLocation.flags & NodeFlags.Synthesized) || // Synthetic fake scopes are added for signatures so type parameters are accessible from them
+ lastLocation === (location as FunctionLikeDeclaration).type ||
lastLocation.kind === SyntaxKind.Parameter ||
lastLocation.kind === SyntaxKind.JSDocParameterTag ||
lastLocation.kind === SyntaxKind.JSDocReturnTag ||
@@ -11135,6 +11138,7 @@ export function createNameResolver({
// however it is detected separately when checking initializers of parameters
// to make sure that they reference no variables declared after them.
useResult = lastLocation.kind === SyntaxKind.Parameter ||
+ !!(lastLocation.flags & NodeFlags.Synthesized) || // Synthetic fake scopes are added for signatures so parameters are accessible from them
(
lastLocation === (location as FunctionLikeDeclaration).type &&
!!findAncestor(result.valueDeclaration, isParameter)
diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts
index 35cabc9011aae..2ff6e7adaa867 100644
--- a/src/compiler/utilitiesPublic.ts
+++ b/src/compiler/utilitiesPublic.ts
@@ -295,7 +295,7 @@ import {
TypeReferenceType,
UnaryExpression,
VariableDeclaration,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export function isExternalModuleNameRelative(moduleName: string): boolean {
// TypeScript 1.0 spec (April 2014): 11.2.1
@@ -1253,7 +1253,7 @@ function formatJSDocLink(link: JSDocLink | JSDocLinkCode | JSDocLinkPlain) {
: link.kind === SyntaxKind.JSDocLinkCode ? "linkcode"
: "linkplain";
const name = link.name ? entityNameToString(link.name) : "";
- const space = link.name && link.text.startsWith("://") ? "" : " ";
+ const space = link.name && (link.text === "" || link.text.startsWith("://")) ? "" : " ";
return `{@${kind} ${name}${space}${link.text}}`;
}
@@ -2320,7 +2320,8 @@ function isDeclarationKind(kind: SyntaxKind) {
|| kind === SyntaxKind.VariableDeclaration
|| kind === SyntaxKind.JSDocTypedefTag
|| kind === SyntaxKind.JSDocCallbackTag
- || kind === SyntaxKind.JSDocPropertyTag;
+ || kind === SyntaxKind.JSDocPropertyTag
+ || kind === SyntaxKind.NamedTupleMember;
}
function isDeclarationStatementKind(kind: SyntaxKind) {
diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts
index 0a4c746c2e7c6..21e477329270e 100644
--- a/src/compiler/visitorPublic.ts
+++ b/src/compiler/visitorPublic.ts
@@ -102,7 +102,7 @@ import {
SyntaxKind,
TransformationContext,
Visitor,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/**
* Visits a Node using the supplied visitor, possibly returning a new Node in its place.
diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts
index 431156743f538..4b28e288a3442 100644
--- a/src/compiler/watch.ts
+++ b/src/compiler/watch.ts
@@ -106,7 +106,7 @@ import {
WatchStatusReporter,
whitespaceOrMapCommentRegExp,
WriteFileCallback,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
const sysFormatDiagnosticsHost: FormatDiagnosticsHost | undefined = sys ? {
getCurrentDirectory: () => sys.getCurrentDirectory(),
diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts
index ca3561747f636..7c29f9ec6a085 100644
--- a/src/compiler/watchPublic.ts
+++ b/src/compiler/watchPublic.ts
@@ -94,7 +94,7 @@ import {
WatchType,
WatchTypeRegistry,
WildcardDirectoryWatcher,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export interface ReadBuildProgramHost {
useCaseSensitiveFileNames(): boolean;
@@ -594,6 +594,7 @@ export function createWatchProgram(host: WatchCompiler
});
parsedConfigs = undefined;
}
+ builderProgram = undefined!;
}
function getResolutionCache() {
diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts
index 34794533ace12..425fedfdd6f22 100644
--- a/src/compiler/watchUtilities.ts
+++ b/src/compiler/watchUtilities.ts
@@ -56,7 +56,7 @@ import {
WatchDirectoryFlags,
WatchFileKind,
WatchOptions,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/**
* Partial interface of the System thats needed to support the caching of directory structure
diff --git a/src/deprecatedCompat/_namespaces/ts.ts b/src/deprecatedCompat/_namespaces/ts.ts
index cbfc88edbb648..0d062e9bc024d 100644
--- a/src/deprecatedCompat/_namespaces/ts.ts
+++ b/src/deprecatedCompat/_namespaces/ts.ts
@@ -1,4 +1,4 @@
/* Generated file to emulate the ts namespace. */
-export * from "../../compiler/_namespaces/ts";
-export * from "../deprecations";
+export * from "../../compiler/_namespaces/ts.js";
+export * from "../deprecations.js";
diff --git a/src/deprecatedCompat/deprecate.ts b/src/deprecatedCompat/deprecate.ts
index 0bb11bfd228ab..595376a5222d1 100644
--- a/src/deprecatedCompat/deprecate.ts
+++ b/src/deprecatedCompat/deprecate.ts
@@ -5,7 +5,7 @@ import {
noop,
Version,
version,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export let enableDeprecationWarnings = true;
diff --git a/src/deprecatedCompat/deprecations.ts b/src/deprecatedCompat/deprecations.ts
index 23dd903c44428..4f4ec88e957fb 100644
--- a/src/deprecatedCompat/deprecations.ts
+++ b/src/deprecatedCompat/deprecations.ts
@@ -2,8 +2,8 @@ import {
hasProperty,
UnionToIntersection,
Version,
-} from "./_namespaces/ts";
-import { deprecate } from "./deprecate";
+} from "./_namespaces/ts.js";
+import { deprecate } from "./deprecate.js";
/** @internal */
export interface DeprecationOptions {
diff --git a/src/harness/_namespaces/FourSlash.ts b/src/harness/_namespaces/FourSlash.ts
index c069ebaf784de..ff7722f62895b 100644
--- a/src/harness/_namespaces/FourSlash.ts
+++ b/src/harness/_namespaces/FourSlash.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the FourSlash namespace. */
-export * from "../fourslashImpl";
+export * from "../fourslashImpl.js";
diff --git a/src/harness/_namespaces/FourSlashInterface.ts b/src/harness/_namespaces/FourSlashInterface.ts
index 270be7300135f..88127d65a0ea0 100644
--- a/src/harness/_namespaces/FourSlashInterface.ts
+++ b/src/harness/_namespaces/FourSlashInterface.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the FourSlashInterface namespace. */
-export * from "../fourslashInterfaceImpl";
+export * from "../fourslashInterfaceImpl.js";
diff --git a/src/harness/_namespaces/Harness.LanguageService.ts b/src/harness/_namespaces/Harness.LanguageService.ts
index 53544477e279c..d485be2af0b73 100644
--- a/src/harness/_namespaces/Harness.LanguageService.ts
+++ b/src/harness/_namespaces/Harness.LanguageService.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the Harness.LanguageService namespace. */
-export * from "../harnessLanguageService";
+export * from "../harnessLanguageService.js";
diff --git a/src/harness/_namespaces/Harness.SourceMapRecorder.ts b/src/harness/_namespaces/Harness.SourceMapRecorder.ts
index 909654b08d165..8ae47bc803a6d 100644
--- a/src/harness/_namespaces/Harness.SourceMapRecorder.ts
+++ b/src/harness/_namespaces/Harness.SourceMapRecorder.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the Harness.SourceMapRecorder namespace. */
-export * from "../sourceMapRecorder";
+export * from "../sourceMapRecorder.js";
diff --git a/src/harness/_namespaces/Harness.ts b/src/harness/_namespaces/Harness.ts
index 3ff4b006555c1..964d64de66cb1 100644
--- a/src/harness/_namespaces/Harness.ts
+++ b/src/harness/_namespaces/Harness.ts
@@ -1,9 +1,9 @@
/* Generated file to emulate the Harness namespace. */
-export * from "../runnerbase";
-export * from "../harnessIO";
-export * from "../typeWriter";
-import * as LanguageService from "./Harness.LanguageService";
+export * from "../runnerbase.js";
+export * from "../harnessIO.js";
+export * from "../typeWriter.js";
+import * as LanguageService from "./Harness.LanguageService.js";
export { LanguageService };
-import * as SourceMapRecorder from "./Harness.SourceMapRecorder";
+import * as SourceMapRecorder from "./Harness.SourceMapRecorder.js";
export { SourceMapRecorder };
diff --git a/src/harness/_namespaces/Utils.ts b/src/harness/_namespaces/Utils.ts
index 3b958cd166789..d15b5cc7e3b72 100644
--- a/src/harness/_namespaces/Utils.ts
+++ b/src/harness/_namespaces/Utils.ts
@@ -1,5 +1,5 @@
/* Generated file to emulate the Utils namespace. */
-export * from "../util";
-export * from "../findUpDir";
-export * from "../harnessUtils";
+export * from "../util.js";
+export * from "../findUpDir.js";
+export * from "../harnessUtils.js";
diff --git a/src/harness/_namespaces/collections.ts b/src/harness/_namespaces/collections.ts
index 870e956769ebb..3445e7971ffeb 100644
--- a/src/harness/_namespaces/collections.ts
+++ b/src/harness/_namespaces/collections.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the collections namespace. */
-export * from "../collectionsImpl";
+export * from "../collectionsImpl.js";
diff --git a/src/harness/_namespaces/compiler.ts b/src/harness/_namespaces/compiler.ts
index 3ff645eca59d2..3b53847394748 100644
--- a/src/harness/_namespaces/compiler.ts
+++ b/src/harness/_namespaces/compiler.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the compiler namespace. */
-export * from "../compilerImpl";
+export * from "../compilerImpl.js";
diff --git a/src/harness/_namespaces/documents.ts b/src/harness/_namespaces/documents.ts
index 67dbd0e6c1c20..c1bba77a940a4 100644
--- a/src/harness/_namespaces/documents.ts
+++ b/src/harness/_namespaces/documents.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the documents namespace. */
-export * from "../documentsUtil";
+export * from "../documentsUtil.js";
diff --git a/src/harness/_namespaces/evaluator.ts b/src/harness/_namespaces/evaluator.ts
index e47f3eb0aeee2..d052b6c8fe4d3 100644
--- a/src/harness/_namespaces/evaluator.ts
+++ b/src/harness/_namespaces/evaluator.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the evaluator namespace. */
-export * from "../evaluatorImpl";
+export * from "../evaluatorImpl.js";
diff --git a/src/harness/_namespaces/fakes.ts b/src/harness/_namespaces/fakes.ts
index d2a68860bbb15..f5d19a8eeec15 100644
--- a/src/harness/_namespaces/fakes.ts
+++ b/src/harness/_namespaces/fakes.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the fakes namespace. */
-export * from "../fakesHosts";
+export * from "../fakesHosts.js";
diff --git a/src/harness/_namespaces/ts.server.ts b/src/harness/_namespaces/ts.server.ts
index 714986489e3d5..d808ae75c51c4 100644
--- a/src/harness/_namespaces/ts.server.ts
+++ b/src/harness/_namespaces/ts.server.ts
@@ -1,6 +1,6 @@
/* Generated file to emulate the ts.server namespace. */
-export * from "../../jsTyping/_namespaces/ts.server";
-export * from "../../server/_namespaces/ts.server";
-export * from "../../typingsInstallerCore/_namespaces/ts.server";
-export * from "../client";
+export * from "../../jsTyping/_namespaces/ts.server.js";
+export * from "../../server/_namespaces/ts.server.js";
+export * from "../../typingsInstallerCore/_namespaces/ts.server.js";
+export * from "../client.js";
diff --git a/src/harness/_namespaces/ts.ts b/src/harness/_namespaces/ts.ts
index 3f6ecdc8eeea5..a8d0cb3f723c2 100644
--- a/src/harness/_namespaces/ts.ts
+++ b/src/harness/_namespaces/ts.ts
@@ -1,11 +1,11 @@
/* Generated file to emulate the ts namespace. */
-export * from "../../compiler/_namespaces/ts";
-export * from "../../services/_namespaces/ts";
-export * from "../../jsTyping/_namespaces/ts";
-export * from "../../server/_namespaces/ts";
-export * from "../../typingsInstallerCore/_namespaces/ts";
-export * from "../../deprecatedCompat/_namespaces/ts";
-export * from "../harnessGlobals";
-import * as server from "./ts.server";
+export * from "../../compiler/_namespaces/ts.js";
+export * from "../../services/_namespaces/ts.js";
+export * from "../../jsTyping/_namespaces/ts.js";
+export * from "../../server/_namespaces/ts.js";
+export * from "../../typingsInstallerCore/_namespaces/ts.js";
+export * from "../../deprecatedCompat/_namespaces/ts.js";
+export * from "../harnessGlobals.js";
+import * as server from "./ts.server.js";
export { server };
diff --git a/src/harness/_namespaces/vfs.ts b/src/harness/_namespaces/vfs.ts
index 1eb82cd822103..ddd2347e4a99e 100644
--- a/src/harness/_namespaces/vfs.ts
+++ b/src/harness/_namespaces/vfs.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the vfs namespace. */
-export * from "../vfsUtil";
+export * from "../vfsUtil.js";
diff --git a/src/harness/_namespaces/vpath.ts b/src/harness/_namespaces/vpath.ts
index 7430c87d9b6ad..5c9c5ff5e95df 100644
--- a/src/harness/_namespaces/vpath.ts
+++ b/src/harness/_namespaces/vpath.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the vpath namespace. */
-export * from "../vpathUtil";
+export * from "../vpathUtil.js";
diff --git a/src/harness/client.ts b/src/harness/client.ts
index cc138546174e5..2d764ad15d9d6 100644
--- a/src/harness/client.ts
+++ b/src/harness/client.ts
@@ -48,6 +48,8 @@ import {
notImplemented,
OrganizeImportsArgs,
OutliningSpan,
+ PasteEdits,
+ PasteEditsArgs,
PatternMatchKind,
Program,
QuickInfo,
@@ -73,8 +75,8 @@ import {
TodoComment,
TodoCommentDescriptor,
UserPreferences,
-} from "./_namespaces/ts";
-import { protocol } from "./_namespaces/ts.server";
+} from "./_namespaces/ts.js";
+import { protocol } from "./_namespaces/ts.server.js";
export interface SessionClientHost extends LanguageServiceHost {
writeMessage(message: string): void;
@@ -787,6 +789,8 @@ export class SessionClient implements LanguageService {
});
}
+ mapCode = notImplemented;
+
private createFileLocationOrRangeRequestArgs(positionOrRange: number | TextRange, fileName: string): protocol.FileLocationOrRangeRequestArgs {
return typeof positionOrRange === "number"
? this.createFileLocationRequestArgs(fileName, positionOrRange)
@@ -1006,6 +1010,26 @@ export class SessionClient implements LanguageService {
return getSupportedCodeFixes();
}
+ getPasteEdits(
+ { targetFile, pastedText, pasteLocations, copiedFrom }: PasteEditsArgs,
+ formatOptions: FormatCodeSettings,
+ ): PasteEdits {
+ this.setFormattingOptions(formatOptions);
+ const args: protocol.GetPasteEditsRequestArgs = {
+ file: targetFile,
+ pastedText,
+ pasteLocations: pasteLocations.map(range => ({ start: this.positionToOneBasedLineOffset(targetFile, range.pos), end: this.positionToOneBasedLineOffset(targetFile, range.end) })),
+ copiedFrom: copiedFrom ? { file: copiedFrom.file, spans: copiedFrom.range.map(range => ({ start: this.positionToOneBasedLineOffset(copiedFrom.file, range.pos), end: this.positionToOneBasedLineOffset(copiedFrom.file, range.end) })) } : undefined,
+ };
+ const request = this.processRequest(protocol.CommandTypes.GetPasteEdits, args);
+ const response = this.processResponse(request);
+ if (!response.body) {
+ return { edits: [] };
+ }
+ const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body.edits);
+ return { edits, fixId: response.body.fixId };
+ }
+
getProgram(): Program {
throw new Error("Program objects are not serializable through the server protocol.");
}
diff --git a/src/harness/collectionsImpl.ts b/src/harness/collectionsImpl.ts
index 5e6b3d1fb4446..7b0a859d0fcbc 100644
--- a/src/harness/collectionsImpl.ts
+++ b/src/harness/collectionsImpl.ts
@@ -1,4 +1,4 @@
-import * as ts from "./_namespaces/ts";
+import * as ts from "./_namespaces/ts.js";
export interface SortOptions {
comparer: (a: T, b: T) => number;
diff --git a/src/harness/compilerImpl.ts b/src/harness/compilerImpl.ts
index f73e739e8b2d0..90393622d9308 100644
--- a/src/harness/compilerImpl.ts
+++ b/src/harness/compilerImpl.ts
@@ -1,10 +1,10 @@
-import * as collections from "./_namespaces/collections";
-import * as documents from "./_namespaces/documents";
-import * as fakes from "./_namespaces/fakes";
-import * as Harness from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import * as vfs from "./_namespaces/vfs";
-import * as vpath from "./_namespaces/vpath";
+import * as collections from "./_namespaces/collections.js";
+import * as documents from "./_namespaces/documents.js";
+import * as fakes from "./_namespaces/fakes.js";
+import * as Harness from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import * as vfs from "./_namespaces/vfs.js";
+import * as vpath from "./_namespaces/vpath.js";
/**
* Test harness compiler functionality.
diff --git a/src/harness/documentsUtil.ts b/src/harness/documentsUtil.ts
index 8699609ef5350..8a96d4d290f3e 100644
--- a/src/harness/documentsUtil.ts
+++ b/src/harness/documentsUtil.ts
@@ -1,5 +1,5 @@
-import * as Harness from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
+import * as Harness from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
// NOTE: The contents of this file are all exported from the namespace 'documents'. This is to
// support the eventual conversion of harness into a modular system.
diff --git a/src/harness/evaluatorImpl.ts b/src/harness/evaluatorImpl.ts
index b8decf789a1aa..9fdeed5b6cdc7 100644
--- a/src/harness/evaluatorImpl.ts
+++ b/src/harness/evaluatorImpl.ts
@@ -1,9 +1,9 @@
-import * as compiler from "./_namespaces/compiler";
-import * as fakes from "./_namespaces/fakes";
-import * as Harness from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import * as vfs from "./_namespaces/vfs";
-import * as vpath from "./_namespaces/vpath";
+import * as compiler from "./_namespaces/compiler.js";
+import * as fakes from "./_namespaces/fakes.js";
+import * as Harness from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import * as vfs from "./_namespaces/vfs.js";
+import * as vpath from "./_namespaces/vpath.js";
const sourceFile = vpath.combine(vfs.srcFolder, "source.ts");
const sourceFileJs = vpath.combine(vfs.srcFolder, "source.js");
diff --git a/src/harness/fakesHosts.ts b/src/harness/fakesHosts.ts
index 4388b77aa1ca5..b677d7248261d 100644
--- a/src/harness/fakesHosts.ts
+++ b/src/harness/fakesHosts.ts
@@ -1,10 +1,10 @@
-import * as collections from "./_namespaces/collections";
-import * as documents from "./_namespaces/documents";
-import * as Harness from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import * as Utils from "./_namespaces/Utils";
-import * as vfs from "./_namespaces/vfs";
-import * as vpath from "./_namespaces/vpath";
+import * as collections from "./_namespaces/collections.js";
+import * as documents from "./_namespaces/documents.js";
+import * as Harness from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import * as Utils from "./_namespaces/Utils.js";
+import * as vfs from "./_namespaces/vfs.js";
+import * as vpath from "./_namespaces/vpath.js";
/**
* Fake implementations of various compiler dependencies.
diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts
index fc544bc2e0e6d..ac44525404f5d 100644
--- a/src/harness/fourslashImpl.ts
+++ b/src/harness/fourslashImpl.ts
@@ -1,11 +1,11 @@
-import * as fakes from "./_namespaces/fakes";
-import * as FourSlashInterface from "./_namespaces/FourSlashInterface";
-import * as Harness from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import * as Utils from "./_namespaces/Utils";
-import * as vfs from "./_namespaces/vfs";
-import * as vpath from "./_namespaces/vpath";
-import { LoggerWithInMemoryLogs } from "./tsserverLogger";
+import * as fakes from "./_namespaces/fakes.js";
+import * as FourSlashInterface from "./_namespaces/FourSlashInterface.js";
+import * as Harness from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import * as Utils from "./_namespaces/Utils.js";
+import * as vfs from "./_namespaces/vfs.js";
+import * as vpath from "./_namespaces/vpath.js";
+import { LoggerWithInMemoryLogs } from "./tsserverLogger.js";
import ArrayOrSingle = FourSlashInterface.ArrayOrSingle;
@@ -3560,6 +3560,11 @@ export class TestState {
assert.deepEqual(actualModuleSpecifiers, moduleSpecifiers);
}
+ public verifyPasteEdits(options: FourSlashInterface.PasteEditsOptions): void {
+ const editInfo = this.languageService.getPasteEdits({ targetFile: this.activeFile.fileName, pastedText: options.args.pastedText, pasteLocations: options.args.pasteLocations, copiedFrom: options.args.copiedFrom, preferences: options.args.preferences }, this.formatCodeSettings);
+ this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits);
+ }
+
public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined, options?: ts.DocCommentTemplateOptions) {
const name = "verifyDocCommentTemplate";
const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition, options || { generateReturnInDocTemplate: true }, this.formatCodeSettings)!;
@@ -4505,6 +4510,57 @@ export class TestState {
this.verifyCurrentFileContent(newFileContent);
}
+
+ public baselineMapCode(
+ ranges: Range[][],
+ changes: string[] = [],
+ ): void {
+ const fileName = this.activeFile.fileName;
+ const focusLocations = ranges.map(r =>
+ r.map(({ pos, end }) => {
+ return { start: pos, length: end - pos };
+ })
+ );
+ let before = this.getFileContent(fileName);
+ const edits = this.languageService.mapCode(
+ fileName,
+ // We trim the leading whitespace stuff just so our test cases can be more readable.
+ changes,
+ focusLocations,
+ this.formatCodeSettings,
+ {},
+ );
+ this.applyChanges(edits);
+ focusLocations.forEach(r => {
+ r.sort((a, b) => a.start - b.start);
+ });
+ focusLocations.sort((a, b) => a[0].start - b[0].start);
+ for (const subLoc of focusLocations) {
+ for (const { start, length } of subLoc) {
+ let offset = 0;
+ for (const sl2 of focusLocations) {
+ for (const { start: s2, length: l2 } of sl2) {
+ if (s2 < start) {
+ offset += 4;
+ if ((s2 + l2) > start) {
+ offset -= 2;
+ }
+ }
+ }
+ }
+ before = before.slice(0, start + offset) + "[|" + before.slice(start + offset, start + offset + length) + "|]" + before.slice(start + offset + length);
+ }
+ }
+ const after = this.getFileContent(fileName);
+ const baseline = `
+// === ORIGINAL ===
+${before}
+// === INCOMING CHANGES ===
+${changes.join("\n// ---\n")}
+// === MAPPED ===
+${after}`;
+ this.baseline("mapCode", baseline, ".mapCode.ts");
+ }
}
function updateTextRangeForTextChanges({ pos, end }: ts.TextRange, textChanges: readonly ts.TextChange[]): ts.TextRange {
diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts
index 64577f69ced7c..f04ac4594f918 100644
--- a/src/harness/fourslashInterfaceImpl.ts
+++ b/src/harness/fourslashInterfaceImpl.ts
@@ -1,5 +1,5 @@
-import * as FourSlash from "./_namespaces/FourSlash";
-import * as ts from "./_namespaces/ts";
+import * as FourSlash from "./_namespaces/FourSlash.js";
+import * as ts from "./_namespaces/ts.js";
export class Test {
constructor(private state: FourSlash.TestState) {
@@ -239,6 +239,10 @@ export class VerifyNegatable {
public uncommentSelection(newFileContent: string) {
this.state.uncommentSelection(newFileContent);
}
+
+ public baselineMapCode(ranges: FourSlash.Range[][], changes: string[] = []): void {
+ this.state.baselineMapCode(ranges, changes);
+ }
}
export class Verify extends VerifyNegatable {
@@ -620,6 +624,10 @@ export class Verify extends VerifyNegatable {
public organizeImports(newContent: string, mode?: ts.OrganizeImportsMode, preferences?: ts.UserPreferences): void {
this.state.verifyOrganizeImports(newContent, mode, preferences);
}
+
+ public pasteEdits(options: PasteEditsOptions): void {
+ this.state.verifyPasteEdits(options);
+ }
}
export class Edit {
@@ -1923,6 +1931,12 @@ export interface MoveToFileOptions {
readonly preferences?: ts.UserPreferences;
}
+export interface PasteEditsOptions {
+ readonly newFileContents: { readonly [fileName: string]: string; };
+ args: ts.PasteEditsArgs;
+ readonly fixId: string;
+}
+
export type RenameLocationsOptions = readonly RenameLocationOptions[] | {
readonly findInStrings?: boolean;
readonly findInComments?: boolean;
diff --git a/src/harness/harnessGlobals.ts b/src/harness/harnessGlobals.ts
index a83bff41287ba..87831e80f66d5 100644
--- a/src/harness/harnessGlobals.ts
+++ b/src/harness/harnessGlobals.ts
@@ -1,6 +1,6 @@
import * as chai from "chai";
-import * as ts from "./_namespaces/ts";
+import * as ts from "./_namespaces/ts.js";
// this will work in the browser via browserify
declare global {
diff --git a/src/harness/harnessIO.ts b/src/harness/harnessIO.ts
index a9891d70921b0..ea8e988eb991b 100644
--- a/src/harness/harnessIO.ts
+++ b/src/harness/harnessIO.ts
@@ -1,15 +1,15 @@
-import * as compiler from "./_namespaces/compiler";
-import * as documents from "./_namespaces/documents";
-import * as fakes from "./_namespaces/fakes";
+import * as compiler from "./_namespaces/compiler.js";
+import * as documents from "./_namespaces/documents.js";
+import * as fakes from "./_namespaces/fakes.js";
import {
RunnerBase,
TypeWriterResult,
TypeWriterWalker,
-} from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import * as Utils from "./_namespaces/Utils";
-import * as vfs from "./_namespaces/vfs";
-import * as vpath from "./_namespaces/vpath";
+} from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import * as Utils from "./_namespaces/Utils.js";
+import * as vfs from "./_namespaces/vfs.js";
+import * as vpath from "./_namespaces/vpath.js";
export interface IO {
newLine(): string;
@@ -1001,9 +1001,10 @@ export namespace Compiler {
jsCode += "\r\n\r\n";
jsCode += getErrorBaseline(tsConfigFiles.concat(declFileCompilationResult.declInputFiles, declFileCompilationResult.declOtherFiles), declFileCompilationResult.declResult.diagnostics);
}
- else if (!options.noCheck && !options.noEmit && (options.composite || options.declaration || options.emitDeclarationOnly)) {
- const withoutChecking = result.repeat({ noCheck: "true", emitDeclarationOnly: "true" });
+ else if (!options.noCheck && !options.noEmit) {
+ const withoutChecking = result.repeat({ noCheck: "true" });
compareResultFileSets(withoutChecking.dts, result.dts);
+ compareResultFileSets(withoutChecking.js, result.js);
}
// eslint-disable-next-line no-restricted-syntax
diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts
index c890eadc37e75..4dfd58a297a96 100644
--- a/src/harness/harnessLanguageService.ts
+++ b/src/harness/harnessLanguageService.ts
@@ -1,22 +1,22 @@
-import * as collections from "./_namespaces/collections";
-import * as fakes from "./_namespaces/fakes";
+import * as collections from "./_namespaces/collections.js";
+import * as fakes from "./_namespaces/fakes.js";
import {
Compiler,
mockHash,
virtualFileSystemRoot,
-} from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import { getNewLineCharacter } from "./_namespaces/ts";
-import * as vfs from "./_namespaces/vfs";
-import * as vpath from "./_namespaces/vpath";
-import { incrementalVerifier } from "./incrementalUtils";
-import { patchServiceForStateBaseline } from "./projectServiceStateLogger";
+} from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import { getNewLineCharacter } from "./_namespaces/ts.js";
+import * as vfs from "./_namespaces/vfs.js";
+import * as vpath from "./_namespaces/vpath.js";
+import { incrementalVerifier } from "./incrementalUtils.js";
+import { patchServiceForStateBaseline } from "./projectServiceStateLogger.js";
import {
createLoggerWithInMemoryLogs,
HarnessLSCouldNotResolveModule,
LoggerWithInMemoryLogs,
-} from "./tsserverLogger";
-import { createWatchUtils } from "./watchUtils";
+} from "./tsserverLogger.js";
+import { createWatchUtils } from "./watchUtils.js";
export function makeDefaultProxy(info: ts.server.PluginCreateInfo): ts.LanguageService {
const proxy = Object.create(/*o*/ null); // eslint-disable-line no-restricted-syntax
diff --git a/src/harness/harnessUtils.ts b/src/harness/harnessUtils.ts
index cb335891e893b..d7989da8d6980 100644
--- a/src/harness/harnessUtils.ts
+++ b/src/harness/harnessUtils.ts
@@ -1,5 +1,5 @@
-import * as Harness from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
+import * as Harness from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
export function encodeString(s: string): string {
return Buffer.from(s).toString("utf8");
diff --git a/src/harness/incrementalUtils.ts b/src/harness/incrementalUtils.ts
index 0ac3c9da9d2d3..ae48d0bed6694 100644
--- a/src/harness/incrementalUtils.ts
+++ b/src/harness/incrementalUtils.ts
@@ -1,4 +1,4 @@
-import * as ts from "./_namespaces/ts";
+import * as ts from "./_namespaces/ts.js";
export function reportDocumentRegistryStats(documentRegistry: ts.DocumentRegistry) {
const str: string[] = [];
diff --git a/src/harness/projectServiceStateLogger.ts b/src/harness/projectServiceStateLogger.ts
index fd3f75853079d..599769b8e734b 100644
--- a/src/harness/projectServiceStateLogger.ts
+++ b/src/harness/projectServiceStateLogger.ts
@@ -9,7 +9,7 @@ import {
isString,
noop,
SourceMapper,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
AutoImportProviderProject,
AuxiliaryProject,
@@ -23,8 +23,8 @@ import {
ScriptInfo,
SourceMapFileWatcher,
TextStorage,
-} from "./_namespaces/ts.server";
-import { LoggerWithInMemoryLogs } from "./tsserverLogger";
+} from "./_namespaces/ts.server.js";
+import { LoggerWithInMemoryLogs } from "./tsserverLogger.js";
interface ProjectData {
projectStateVersion: Project["projectStateVersion"];
@@ -104,7 +104,11 @@ export function patchServiceForStateBaseline(service: ProjectService) {
function baselineProjects(currentMappers: Set) {
const autoImportProviderProjects = [] as AutoImportProviderProject[];
const auxiliaryProjects = [] as AuxiliaryProject[];
- const orphanConfiguredProjects = service.getOrphanConfiguredProjects(/*toRetainConfiguredProjects*/ undefined);
+ const orphanConfiguredProjects = service.getOrphanConfiguredProjects(
+ /*toRetainConfiguredProjects*/ undefined,
+ /*openFilesWithRetainedConfiguredProject*/ undefined,
+ /*externalProjectsRetainingConfiguredProjects*/ undefined,
+ );
const noOpenRef = (project: Project) => isConfiguredProject(project) && (project.isClosed() || orphanConfiguredProjects.has(project));
return baselineState(
[service.externalProjects, service.configuredProjects, service.inferredProjects, autoImportProviderProjects, auxiliaryProjects],
diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts
index cc341aa499e89..17c6e5cb556a2 100644
--- a/src/harness/runnerbase.ts
+++ b/src/harness/runnerbase.ts
@@ -1,8 +1,8 @@
import {
IO,
userSpecifiedRoot,
-} from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
+} from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
export type TestRunnerKind = CompilerTestKind | FourslashTestKind | "project" | "transpile";
export type CompilerTestKind = "conformance" | "compiler";
diff --git a/src/harness/sourceMapRecorder.ts b/src/harness/sourceMapRecorder.ts
index 6504f33877614..44a6c12edf935 100644
--- a/src/harness/sourceMapRecorder.ts
+++ b/src/harness/sourceMapRecorder.ts
@@ -1,7 +1,7 @@
-import * as documents from "./_namespaces/documents";
-import { Compiler } from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import * as Utils from "./_namespaces/Utils";
+import * as documents from "./_namespaces/documents.js";
+import { Compiler } from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import * as Utils from "./_namespaces/Utils.js";
interface SourceMapSpanWithDecodeErrors {
sourceMapSpan: ts.Mapping;
diff --git a/src/harness/tsserverLogger.ts b/src/harness/tsserverLogger.ts
index 605d478824d40..6e8d18be74c6e 100644
--- a/src/harness/tsserverLogger.ts
+++ b/src/harness/tsserverLogger.ts
@@ -1,5 +1,5 @@
-import * as ts from "./_namespaces/ts";
-import { Compiler } from "./harnessIO";
+import * as ts from "./_namespaces/ts.js";
+import { Compiler } from "./harnessIO.js";
export const HarnessLSCouldNotResolveModule = "HarnessLanguageService:: Could not resolve module";
diff --git a/src/harness/typeWriter.ts b/src/harness/typeWriter.ts
index d8dd2326ddbd2..e09f8bd56a272 100644
--- a/src/harness/typeWriter.ts
+++ b/src/harness/typeWriter.ts
@@ -1,9 +1,9 @@
-import * as ts from "./_namespaces/ts";
+import * as ts from "./_namespaces/ts.js";
import {
createPrinter,
createTextWriter,
memoize,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export interface TypeWriterTypeResult {
line: number;
diff --git a/src/harness/util.ts b/src/harness/util.ts
index 59bbbb0cec6af..4b0f7e28b9a09 100644
--- a/src/harness/util.ts
+++ b/src/harness/util.ts
@@ -1,4 +1,4 @@
-import * as ts from "./_namespaces/ts";
+import * as ts from "./_namespaces/ts.js";
/**
* Common utilities
diff --git a/src/harness/vfsUtil.ts b/src/harness/vfsUtil.ts
index 11ffcfb25a683..7e6e76d545d19 100644
--- a/src/harness/vfsUtil.ts
+++ b/src/harness/vfsUtil.ts
@@ -1,8 +1,8 @@
-import * as collections from "./_namespaces/collections";
-import * as documents from "./_namespaces/documents";
-import * as Harness from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import * as vpath from "./_namespaces/vpath";
+import * as collections from "./_namespaces/collections.js";
+import * as documents from "./_namespaces/documents.js";
+import * as Harness from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import * as vpath from "./_namespaces/vpath.js";
/**
* Posix-style path to the TypeScript compiler build outputs (including tsc.js, lib.d.ts, etc.)
@@ -788,8 +788,8 @@ export class FileSystem {
}
private static fileDiff(container: FileSet, basename: string, changed: FileSystem, changedNode: FileInode, base: FileSystem, baseNode: FileInode, options: DiffOptions) {
- while (!changedNode.buffer && changedNode.shadowRoot) changedNode = changedNode.shadowRoot;
- while (!baseNode.buffer && baseNode.shadowRoot) baseNode = baseNode.shadowRoot;
+ changedNode = walkSameNodes(changedNode);
+ baseNode = walkSameNodes(baseNode);
// no difference if the nodes are the same reference
if (changedNode === baseNode) return false;
@@ -827,6 +827,15 @@ export class FileSystem {
container[basename] = new File(changedBuffer.data, { encoding: changedBuffer.encoding });
return true;
+
+ function walkSameNodes(node: FileInode) {
+ while (
+ !node.buffer &&
+ node.shadowRoot &&
+ (!options.includeChangedFileWithSameContent || node.mtimeMs === node.shadowRoot.mtimeMs)
+ ) node = node.shadowRoot;
+ return node;
+ }
}
private static symlinkDiff(container: FileSet, basename: string, changedNode: SymlinkInode, baseNode: SymlinkInode) {
diff --git a/src/harness/vpathUtil.ts b/src/harness/vpathUtil.ts
index 9b9d5e79fdfe6..c7c1ef4ce47c8 100644
--- a/src/harness/vpathUtil.ts
+++ b/src/harness/vpathUtil.ts
@@ -1,5 +1,5 @@
-import * as ts from "./_namespaces/ts";
-import * as vfs from "./_namespaces/vfs";
+import * as ts from "./_namespaces/ts.js";
+import * as vfs from "./_namespaces/vfs.js";
export import sep = ts.directorySeparator;
export import normalizeSeparators = ts.normalizeSlashes;
diff --git a/src/harness/watchUtils.ts b/src/harness/watchUtils.ts
index fd0201f28b20f..194a4d3225b2d 100644
--- a/src/harness/watchUtils.ts
+++ b/src/harness/watchUtils.ts
@@ -10,7 +10,7 @@ import {
MultiMap,
PollingInterval,
System,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export interface TestFileWatcher {
cb: FileWatcherCallback;
diff --git a/src/jsTyping/_namespaces/ts.JsTyping.ts b/src/jsTyping/_namespaces/ts.JsTyping.ts
index 6b010af980713..92abff3bea4b5 100644
--- a/src/jsTyping/_namespaces/ts.JsTyping.ts
+++ b/src/jsTyping/_namespaces/ts.JsTyping.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.JsTyping namespace. */
-export * from "../jsTyping";
+export * from "../jsTyping.js";
diff --git a/src/jsTyping/_namespaces/ts.server.ts b/src/jsTyping/_namespaces/ts.server.ts
index fe67648d42d98..a378332035669 100644
--- a/src/jsTyping/_namespaces/ts.server.ts
+++ b/src/jsTyping/_namespaces/ts.server.ts
@@ -1,4 +1,4 @@
/* Generated file to emulate the ts.server namespace. */
-export * from "../shared";
-export * from "../types";
+export * from "../shared.js";
+export * from "../types.js";
diff --git a/src/jsTyping/_namespaces/ts.ts b/src/jsTyping/_namespaces/ts.ts
index adf9791f4d2b5..db60f5218cf19 100644
--- a/src/jsTyping/_namespaces/ts.ts
+++ b/src/jsTyping/_namespaces/ts.ts
@@ -1,7 +1,7 @@
/* Generated file to emulate the ts namespace. */
-export * from "../../compiler/_namespaces/ts";
-import * as JsTyping from "./ts.JsTyping";
+export * from "../../compiler/_namespaces/ts.js";
+import * as JsTyping from "./ts.JsTyping.js";
export { JsTyping };
-import * as server from "./ts.server";
+import * as server from "./ts.server.js";
export { server };
diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts
index 1f81cca4ad7ad..c1d2babeab10c 100644
--- a/src/jsTyping/jsTyping.ts
+++ b/src/jsTyping/jsTyping.ts
@@ -29,8 +29,8 @@ import {
TypeAcquisition,
Version,
versionMajorMinor,
-} from "./_namespaces/ts";
-import { stringifyIndented } from "./_namespaces/ts.server";
+} from "./_namespaces/ts.js";
+import { stringifyIndented } from "./_namespaces/ts.server.js";
export interface TypingResolutionHost {
directoryExists(path: string): boolean;
diff --git a/src/jsTyping/shared.ts b/src/jsTyping/shared.ts
index ab163bccbc34e..ddf13a4c9f9d7 100644
--- a/src/jsTyping/shared.ts
+++ b/src/jsTyping/shared.ts
@@ -1,4 +1,4 @@
-import { sys } from "./_namespaces/ts";
+import { sys } from "./_namespaces/ts.js";
export type ActionSet = "action::set";
export type ActionInvalidate = "action::invalidate";
diff --git a/src/jsTyping/types.ts b/src/jsTyping/types.ts
index 8d84a0d3bfdfb..0504a9344ca05 100644
--- a/src/jsTyping/types.ts
+++ b/src/jsTyping/types.ts
@@ -5,7 +5,7 @@ import {
Path,
SortedReadonlyArray,
TypeAcquisition,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
ActionInvalidate,
ActionPackageInstalled,
@@ -15,7 +15,7 @@ import {
EventEndInstallTypes,
EventInitializationFailed,
EventTypesRegistry,
-} from "./_namespaces/ts.server";
+} from "./_namespaces/ts.server.js";
export interface TypingInstallerResponse {
readonly kind: ActionSet | ActionInvalidate | EventTypesRegistry | ActionPackageInstalled | EventBeginInstallTypes | EventEndInstallTypes | EventInitializationFailed | ActionWatchTypingLocations;
diff --git a/src/lib/esnext.collection.d.ts b/src/lib/esnext.collection.d.ts
index 7a799f3c494e7..504ed6782d4bb 100644
--- a/src/lib/esnext.collection.d.ts
+++ b/src/lib/esnext.collection.d.ts
@@ -9,3 +9,80 @@ interface MapConstructor {
keySelector: (item: T, index: number) => K,
): Map;
}
+
+interface ReadonlySetLike {
+ /**
+ * Despite its name, returns an iterator of the values in the set-like.
+ */
+ keys(): Iterator;
+ /**
+ * @returns a boolean indicating whether an element with the specified value exists in the set-like or not.
+ */
+ has(value: T): boolean;
+ /**
+ * @returns the number of (unique) elements in the set-like.
+ */
+ readonly size: number;
+}
+
+interface Set {
+ /**
+ * @returns a new Set containing all the elements in this Set and also all the elements in the argument.
+ */
+ union(other: ReadonlySetLike): Set;
+ /**
+ * @returns a new Set containing all the elements which are both in this Set and in the argument.
+ */
+ intersection(other: ReadonlySetLike): Set;
+ /**
+ * @returns a new Set containing all the elements in this Set which are not also in the argument.
+ */
+ difference(other: ReadonlySetLike): Set;
+ /**
+ * @returns a new Set containing all the elements which are in either this Set or in the argument, but not in both.
+ */
+ symmetricDifference(other: ReadonlySetLike): Set;
+ /**
+ * @returns a boolean indicating whether all the elements in this Set are also in the argument.
+ */
+ isSubsetOf(other: ReadonlySetLike): boolean;
+ /**
+ * @returns a boolean indicating whether all the elements in the argument are also in this Set.
+ */
+ isSupersetOf(other: ReadonlySetLike): boolean;
+ /**
+ * @returns a boolean indicating whether this Set has no elements in common with the argument.
+ */
+ isDisjointFrom(other: ReadonlySetLike): boolean;
+}
+
+interface ReadonlySet {
+ /**
+ * @returns a new Set containing all the elements in this Set and also all the elements in the argument.
+ */
+ union(other: ReadonlySetLike): Set;
+ /**
+ * @returns a new Set containing all the elements which are both in this Set and in the argument.
+ */
+ intersection(other: ReadonlySetLike): Set;
+ /**
+ * @returns a new Set containing all the elements in this Set which are not also in the argument.
+ */
+ difference(other: ReadonlySetLike): Set;
+ /**
+ * @returns a new Set containing all the elements which are in either this Set or in the argument, but not in both.
+ */
+ symmetricDifference(other: ReadonlySetLike): Set;
+ /**
+ * @returns a boolean indicating whether all the elements in this Set are also in the argument.
+ */
+ isSubsetOf(other: ReadonlySetLike): boolean;
+ /**
+ * @returns a boolean indicating whether all the elements in the argument are also in this Set.
+ */
+ isSupersetOf(other: ReadonlySetLike): boolean;
+ /**
+ * @returns a boolean indicating whether this Set has no elements in common with the argument.
+ */
+ isDisjointFrom(other: ReadonlySetLike): boolean;
+}
diff --git a/src/server/_namespaces/ts.server.protocol.ts b/src/server/_namespaces/ts.server.protocol.ts
index 781f82d050732..09d3f3b43b855 100644
--- a/src/server/_namespaces/ts.server.protocol.ts
+++ b/src/server/_namespaces/ts.server.protocol.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.server.protocol namespace. */
-export * from "../protocol";
+export * from "../protocol.js";
diff --git a/src/server/_namespaces/ts.server.ts b/src/server/_namespaces/ts.server.ts
index deaf2e873c38d..cc95db272e9d9 100644
--- a/src/server/_namespaces/ts.server.ts
+++ b/src/server/_namespaces/ts.server.ts
@@ -1,18 +1,18 @@
/* Generated file to emulate the ts.server namespace. */
-export * from "../../jsTyping/_namespaces/ts.server";
-export * from "../../typingsInstallerCore/_namespaces/ts.server";
-export * from "../types";
-export * from "../utilitiesPublic";
-export * from "../utilities";
-import * as protocol from "./ts.server.protocol";
+export * from "../../jsTyping/_namespaces/ts.server.js";
+export * from "../../typingsInstallerCore/_namespaces/ts.server.js";
+export * from "../types.js";
+export * from "../utilitiesPublic.js";
+export * from "../utilities.js";
+import * as protocol from "./ts.server.protocol.js";
export { protocol };
-export * from "../scriptInfo";
-export * from "../typingsCache";
-export * from "../project";
-export * from "../editorServices";
-export * from "../moduleSpecifierCache";
-export * from "../packageJsonCache";
-export * from "../session";
-export * from "../scriptVersionCache";
-export * from "../typingInstallerAdapter";
+export * from "../scriptInfo.js";
+export * from "../typingsCache.js";
+export * from "../project.js";
+export * from "../editorServices.js";
+export * from "../moduleSpecifierCache.js";
+export * from "../packageJsonCache.js";
+export * from "../session.js";
+export * from "../scriptVersionCache.js";
+export * from "../typingInstallerAdapter.js";
diff --git a/src/server/_namespaces/ts.ts b/src/server/_namespaces/ts.ts
index 26e554e4cd973..59404d1b09eac 100644
--- a/src/server/_namespaces/ts.ts
+++ b/src/server/_namespaces/ts.ts
@@ -1,9 +1,9 @@
/* Generated file to emulate the ts namespace. */
-export * from "../../compiler/_namespaces/ts";
-export * from "../../jsTyping/_namespaces/ts";
-export * from "../../services/_namespaces/ts";
+export * from "../../compiler/_namespaces/ts.js";
+export * from "../../jsTyping/_namespaces/ts.js";
+export * from "../../services/_namespaces/ts.js";
// Pull this in here so that plugins loaded by the server see compat wrappers.
-export * from "../../deprecatedCompat/_namespaces/ts";
-import * as server from "./ts.server";
+export * from "../../deprecatedCompat/_namespaces/ts.js";
+import * as server from "./ts.server.js";
export { server };
diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts
index 389c879feb106..ae10458e5ad79 100644
--- a/src/server/editorServices.ts
+++ b/src/server/editorServices.ts
@@ -1,7 +1,6 @@
import {
addToSeen,
arrayFrom,
- arrayToMap,
AssertionLevel,
CachedDirectoryStructureHost,
canJsonReportNoInputFiles,
@@ -40,7 +39,6 @@ import {
FileWatcherCallback,
FileWatcherEventKind,
find,
- flatMap,
forEach,
forEachAncestorDirectory,
forEachEntry,
@@ -106,8 +104,8 @@ import {
removeMinAndVersionNumbers,
ResolvedProjectReference,
resolveProjectReferencePath,
+ returnFalse,
returnNoopFileWatcher,
- returnTrue,
ScriptKind,
SharedExtendedConfigFileWatcher,
some,
@@ -136,7 +134,7 @@ import {
WatchOptions,
WatchType,
WildcardDirectoryWatcher,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
ActionInvalidate,
ActionSet,
@@ -159,6 +157,7 @@ import {
isBackgroundProject,
isConfiguredProject,
isDynamicFileName,
+ isExternalProject,
isInferredProject,
isInferredProjectName,
isProjectDeferredClose,
@@ -186,8 +185,8 @@ import {
toNormalizedPath,
TypingsCache,
WatchTypingLocations,
-} from "./_namespaces/ts.server";
-import * as protocol from "./protocol";
+} from "./_namespaces/ts.server.js";
+import * as protocol from "./protocol.js";
export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024;
/** @internal */
@@ -526,7 +525,7 @@ export interface OpenConfiguredProjectResult {
}
interface AssignProjectResult extends OpenConfiguredProjectResult {
- retainProjects: readonly ConfiguredProject[] | ConfiguredProject | undefined;
+ retainProjects: Set | undefined;
}
interface FilePropertyReader {
@@ -582,14 +581,15 @@ export interface ConfigFileExistenceInfo {
* (config file may include the inferred project files after the change and hence may be wont need to be in inferred project)
*/
exists: boolean;
+ /**
+ * Tracks how many open files are impacted by this config file that are root of inferred project
+ */
+ inferredProjectRoots?: number;
/**
* openFilesImpactedByConfigFiles is a map of open files that would be impacted by this config file
* because these are the paths being looked up for their default configured project location
- * The value in the map is true if the open file is root of the inferred project
- * It is false when the open file that would still be impacted by existence of
- * this config file but it is not the root of inferred project
*/
- openFilesImpactedByConfigFile?: Map;
+ openFilesImpactedByConfigFile?: Set;
/**
* The file watcher watching the config file because there is open script info that is root of
* inferred project and will be impacted by change in the status of the config file
@@ -626,19 +626,36 @@ export interface ProjectServiceOptions {
jsDocParsingMode?: JSDocParsingMode;
}
-interface OriginalFileInfo {
+/**
+ * string if file name,
+ * false if no config file name
+ * @internal
+ */
+export type ConfigFileName = NormalizedPath | false;
+
+/** Gets cached value of config file name based on open script info or ancestor script info */
+function getConfigFileNameFromCache(info: OpenScriptInfoOrClosedOrConfigFileInfo, cache: Map | undefined): ConfigFileName | undefined {
+ if (!cache || isAncestorConfigFileInfo(info)) return undefined;
+ return cache.get(info.path);
+}
+
+/** @internal */
+export interface OriginalFileInfo {
fileName: NormalizedPath;
path: Path;
}
-interface AncestorConfigFileInfo {
+/** @internal */
+export interface AncestorConfigFileInfo {
/** config file name */
- fileName: string;
+ fileName: NormalizedPath;
/** path of open file so we can look at correct root */
path: Path;
configFileInfo: true;
}
-type OpenScriptInfoOrClosedFileInfo = ScriptInfo | OriginalFileInfo;
-type OpenScriptInfoOrClosedOrConfigFileInfo = OpenScriptInfoOrClosedFileInfo | AncestorConfigFileInfo;
+/** @internal */
+export type OpenScriptInfoOrClosedFileInfo = ScriptInfo | OriginalFileInfo;
+/** @internal */
+export type OpenScriptInfoOrClosedOrConfigFileInfo = OpenScriptInfoOrClosedFileInfo | AncestorConfigFileInfo;
function isOpenScriptInfo(infoOrFileNameOrConfig: OpenScriptInfoOrClosedOrConfigFileInfo): infoOrFileNameOrConfig is ScriptInfo {
return !!(infoOrFileNameOrConfig as ScriptInfo).containingProjects;
@@ -648,68 +665,136 @@ function isAncestorConfigFileInfo(infoOrFileNameOrConfig: OpenScriptInfoOrClosed
return !!(infoOrFileNameOrConfig as AncestorConfigFileInfo).configFileInfo;
}
-/**
- * Kind of operation to perform to get project reference project
- *
- * @internal
- */
-export enum ProjectReferenceProjectLoadKind {
- /** Find existing project for project reference */
+/** @internal */
+export enum ConfiguredProjectLoadKind {
Find,
- /** Find existing project or create one for the project reference */
- FindCreate,
- /** Find existing project or create and load it for the project reference */
- FindCreateLoad,
+ Create,
+ Reload,
}
/** @internal */
-export function forEachResolvedProjectReferenceProject(
- project: ConfiguredProject,
- fileName: string | undefined,
- cb: (child: ConfiguredProject) => T | undefined,
- projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind.Find | ProjectReferenceProjectLoadKind.FindCreate,
-): T | undefined;
+export interface DefaultConfiguredProjectResult {
+ defaultProject: ConfiguredProject | undefined;
+ sentConfigDiag: Set;
+ seenProjects: Set;
+}
+
/** @internal */
-export function forEachResolvedProjectReferenceProject(
+export interface FindCreateOrLoadConfiguredProjectResult {
+ project: ConfiguredProject;
+ sentConfigFileDiag: boolean;
+}
+
+/**
+ * Goes through each tsconfig from project till project root of open script info and finds, creates or reloads project per kind
+ */
+function forEachAncestorProject(
+ info: ScriptInfo,
project: ConfiguredProject,
- fileName: string | undefined,
- cb: (child: ConfiguredProject) => T | undefined,
- projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind,
+ cb: (ancestor: ConfiguredProject) => T | undefined,
+ kind: ConfiguredProjectLoadKind,
+ /** Used with ConfiguredProjectLoadKind.Create or ConfiguredProjectLoadKind.Reload for new projects or reload updates */
reason: string,
-): T | undefined;
+ /** Used with ConfiguredProjectLoadKind.Find to get deferredClosed projects as well */
+ allowDeferredClosed: boolean | undefined,
+ /** Used with ConfiguredProjectLoadKind.Reload to check if this project was already reloaded */
+ reloadedProjects: Set | undefined,
+ /** Used with ConfiguredProjectLoadKind.Reload to specify delay reload, and also a set of configured projects already marked for delay load */
+ delayReloadedConfiguredProjects?: Set,
+): T | undefined {
+ // Create configured project till project root
+ while (true) {
+ // Skip if project is not composite and we are only looking for solution
+ if (
+ !project.isInitialLoadPending() &&
+ (
+ !project.getCompilerOptions().composite ||
+ project.getCompilerOptions().disableSolutionSearching
+ )
+ ) return;
+
+ // Get config file name
+ const configFileName = project.projectService.getConfigFileNameForFile({
+ fileName: project.getConfigFilePath(),
+ path: info.path,
+ configFileInfo: true,
+ }, kind === ConfiguredProjectLoadKind.Find);
+ if (!configFileName) return;
+
+ // find or delay load the project
+ const ancestor = project.projectService.findCreateOrReloadConfiguredProject(
+ configFileName,
+ kind,
+ reason,
+ allowDeferredClosed,
+ /*triggerFile*/ undefined,
+ reloadedProjects,
+ /*delayLoad*/ true,
+ delayReloadedConfiguredProjects,
+ );
+ if (!ancestor) return;
+
+ // If this ancestor is new and was delay loaded, then set the project as potential project reference
+ if (
+ ancestor.project.isInitialLoadPending() &&
+ project.getCompilerOptions().composite
+ ) {
+ // Set a potential project reference
+ // Debug.assert(ancestor.);
+ ancestor.project.setPotentialProjectReference(project.canonicalConfigFilePath);
+ }
+ const result = cb(ancestor.project);
+ if (result) return result;
+ project = ancestor.project;
+ }
+}
+
+/**
+ * Goes through project's resolved project references and finds, creates or reloads project per kind
+ * If project for this resolved reference exists its used immediately otherwise,
+ * follows all references in order, deciding if references of the visited project can be loaded or not
+ * @internal
+ */
export function forEachResolvedProjectReferenceProject(
project: ConfiguredProject,
fileName: string | undefined,
- cb: (child: ConfiguredProject) => T | undefined,
- projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind,
- reason?: string,
+ cb: (child: ConfiguredProject, sentConfigFileDiag: boolean) => T | undefined,
+ kind: ConfiguredProjectLoadKind,
+ reason: string,
+ /** Used with ConfiguredProjectLoadKind.Find to get deferredClosed projects as well */
+ allowDeferredClosed?: boolean,
+ /** Used with ConfiguredProjectLoadKind.Create to send configFileDiag */
+ triggerFile?: NormalizedPath,
+ /** Used with ConfiguredProjectLoadKind.Reload to check if this project was already reloaded */
+ reloadedProjects?: Set,
): T | undefined {
const resolvedRefs = project.getCurrentProgram()?.getResolvedProjectReferences();
if (!resolvedRefs) return undefined;
- let seenResolvedRefs: Map | undefined;
const possibleDefaultRef = fileName ? project.getResolvedProjectReferenceToRedirect(fileName) : undefined;
if (possibleDefaultRef) {
// Try to find the name of the file directly through resolved project references
const configFileName = toNormalizedPath(possibleDefaultRef.sourceFile.fileName);
- const child = project.projectService.findConfiguredProjectByProjectName(configFileName);
+ // We are not using findCreateOrLoadConfiguredProject with kind thats passed in since
+ // we want to determine if we can really create a new project if it doesnt exist
+ // based on following references and determining based on disableReferencedProjectLoad
+ const child = project.projectService.findConfiguredProjectByProjectName(
+ configFileName,
+ allowDeferredClosed,
+ );
if (child) {
- const result = cb(child);
+ const result = callbackWithProjectFoundUsingFind(child);
if (result) return result;
}
- else if (projectReferenceProjectLoadKind !== ProjectReferenceProjectLoadKind.Find) {
- seenResolvedRefs = new Map();
- // Try to see if this project can be loaded
+ else if (kind !== ConfiguredProjectLoadKind.Find) {
+ // Try to see if this project can be loaded and load only that one instead of loading all the projects
const result = forEachResolvedProjectReferenceProjectWorker(
resolvedRefs,
project.getCompilerOptions(),
(ref, loadKind) => possibleDefaultRef === ref ? callback(ref, loadKind) : undefined,
- projectReferenceProjectLoadKind,
+ kind,
project.projectService,
- seenResolvedRefs,
);
if (result) return result;
- // Cleanup seenResolvedRefs
- seenResolvedRefs.clear();
}
}
@@ -717,36 +802,56 @@ export function forEachResolvedProjectReferenceProject(
resolvedRefs,
project.getCompilerOptions(),
(ref, loadKind) => possibleDefaultRef !== ref ? callback(ref, loadKind) : undefined,
- projectReferenceProjectLoadKind,
+ kind,
project.projectService,
- seenResolvedRefs,
);
- function callback(ref: ResolvedProjectReference, loadKind: ProjectReferenceProjectLoadKind) {
- const configFileName = toNormalizedPath(ref.sourceFile.fileName);
- const child = project.projectService.findConfiguredProjectByProjectName(configFileName) || (
- loadKind === ProjectReferenceProjectLoadKind.Find ?
- undefined :
- loadKind === ProjectReferenceProjectLoadKind.FindCreate ?
- project.projectService.createConfiguredProject(configFileName) :
- loadKind === ProjectReferenceProjectLoadKind.FindCreateLoad ?
- project.projectService.createAndLoadConfiguredProject(configFileName, reason!) :
- Debug.assertNever(loadKind)
+ function callback(ref: ResolvedProjectReference, loadKind: ConfiguredProjectLoadKind) {
+ const result = project.projectService.findCreateOrReloadConfiguredProject(
+ toNormalizedPath(ref.sourceFile.fileName),
+ loadKind,
+ reason,
+ allowDeferredClosed,
+ triggerFile,
+ reloadedProjects,
);
+ return result && (
+ loadKind === kind ?
+ cb(result.project, result.sentConfigFileDiag) :
+ callbackWithProjectFoundUsingFind(result.project)
+ );
+ }
- return child && cb(child);
+ function callbackWithProjectFoundUsingFind(child: ConfiguredProject) {
+ let sentConfigFileDiag = false;
+ // This project was found using "Find" instead of the actually specified kind of "Create" or "Reload",
+ // We need to update or reload this existing project before calling callback
+ switch (kind) {
+ case ConfiguredProjectLoadKind.Create:
+ sentConfigFileDiag = updateConfiguredProject(child, triggerFile);
+ break;
+ case ConfiguredProjectLoadKind.Reload:
+ sentConfigFileDiag = child.projectService.reloadConfiguredProjectClearingSemanticCache(child, reason, reloadedProjects!);
+ break;
+ case ConfiguredProjectLoadKind.Find:
+ break;
+ default:
+ Debug.assertNever(kind);
+ }
+ const result = cb(child, sentConfigFileDiag);
+ if (result) return result;
}
}
function forEachResolvedProjectReferenceProjectWorker(
resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[],
parentOptions: CompilerOptions,
- cb: (resolvedRef: ResolvedProjectReference, loadKind: ProjectReferenceProjectLoadKind) => T | undefined,
- projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind,
+ cb: (resolvedRef: ResolvedProjectReference, loadKind: ConfiguredProjectLoadKind) => T | undefined,
+ kind: ConfiguredProjectLoadKind,
projectService: ProjectService,
- seenResolvedRefs: Map | undefined,
+ seenResolvedRefs?: Map,
): T | undefined {
- const loadKind = parentOptions.disableReferencedProjectLoad ? ProjectReferenceProjectLoadKind.Find : projectReferenceProjectLoadKind;
+ const loadKind = parentOptions.disableReferencedProjectLoad ? ConfiguredProjectLoadKind.Find : kind;
return forEach(resolvedProjectReferences, ref => {
if (!ref) return undefined;
@@ -833,16 +938,6 @@ function isScriptInfoWatchedFromNodeModules(info: ScriptInfo) {
return !info.isScriptOpen() && info.mTime !== undefined;
}
-/**
- * true if script info is part of project and is not in project because it is referenced from project reference source
- *
- * @internal
- */
-export function projectContainsInfoDirectly(project: Project, info: ScriptInfo) {
- return project.containsScriptInfo(info) &&
- !project.isSourceOfProjectReferenceRedirect(info.path);
-}
-
/**
* returns true if project updated with new program
* @internal
@@ -852,10 +947,39 @@ export function updateProjectIfDirty(project: Project) {
return project.dirty && !project.updateGraph();
}
-function updateConfiguredProjectWithoutConfigDiagIfDirty(project: ConfiguredProject) {
- project.skipConfigDiagEvent = true;
- updateProjectIfDirty(project);
- project.skipConfigDiagEvent = undefined;
+/** Updates the program for triggerFile and returns true if sent configFileDiagEvent */
+function updateWithTriggerFile(project: ConfiguredProject, triggerFile: NormalizedPath, isReload: boolean): boolean {
+ if (!isReload) {
+ project.invalidateResolutionsOfFailedLookupLocations();
+ if (!project.dirty) return false;
+ }
+ project.triggerFileForConfigFileDiag = triggerFile;
+ const updateLevel = project.pendingUpdateLevel;
+ project.updateGraph();
+ // On full update the event is sent by recursive updateWithTrigger through reloadConfiguredProject
+ if (!project.triggerFileForConfigFileDiag && !isReload) return updateLevel === ProgramUpdateLevel.Full;
+ const sent = project.projectService.sendConfigFileDiagEvent(project, triggerFile, isReload);
+ project.triggerFileForConfigFileDiag = undefined;
+ return sent;
+}
+
+/** Updates with triggerFile if persent otherwise updateProjectIfDirty, returns true if sent configFileDiagEvent */
+function updateConfiguredProject(project: ConfiguredProject, triggerFile: NormalizedPath | undefined) {
+ if (triggerFile) {
+ if (updateWithTriggerFile(project, triggerFile, /*isReload*/ false)) return true;
+ }
+ else {
+ updateProjectIfDirty(project);
+ }
+ return false;
+}
+
+function fileOpenReason(info: ScriptInfo) {
+ return `Creating possible configured project for ${info.fileName} to open`;
+}
+
+function reloadReason(reason: string) {
+ return `User requested reload projects: ${reason}`;
}
function setProjectOptionsUsed(project: ConfiguredProject | ExternalProject) {
@@ -1070,8 +1194,10 @@ export class ProjectService {
* Open files: with value being project root path, and key being Path of the file that is open
*/
readonly openFiles: Map = new Map();
- /** @internal */
- readonly configFileForOpenFiles = new Map();
+ /** Config files looked up and cached config files for open script info */
+ private readonly configFileForOpenFiles = new Map();
+ /** Set of open script infos that are root of inferred project */
+ private rootOfInferredProjects = new Set();
/**
* Map of open files that are opened without complete path but have projectRoot as current directory
*/
@@ -1104,6 +1230,11 @@ export class ProjectService {
private readonly legacySafelist = new Map();
private pendingProjectUpdates = new Map();
+ /**
+ * All the open script info that needs recalculation of the default project,
+ * this also caches config file info before config file change was detected to use it in case projects are not updated yet
+ */
+ private pendingOpenFileProjectUpdates?: Map;
/** @internal */
pendingEnsureProjectForOpenFiles = false;
@@ -1536,9 +1667,29 @@ export class ProjectService {
return scriptInfo && !scriptInfo.isOrphan() ? scriptInfo.getDefaultProject() : undefined;
}
+ /**
+ * If there is default project calculation pending for this file,
+ * then it completes that calculation so that correct default project is used for the project
+ */
+ private tryGetDefaultProjectForEnsuringConfiguredProjectForFile(fileNameOrScriptInfo: NormalizedPath | ScriptInfo): Project | undefined {
+ const scriptInfo = isString(fileNameOrScriptInfo) ? this.getScriptInfoForNormalizedPath(fileNameOrScriptInfo) : fileNameOrScriptInfo;
+ if (!scriptInfo) return undefined;
+ if (this.pendingOpenFileProjectUpdates?.delete(scriptInfo.path)) {
+ this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
+ scriptInfo,
+ ConfiguredProjectLoadKind.Create,
+ );
+ if (scriptInfo.isOrphan()) {
+ this.assignOrphanScriptInfoToInferredProject(scriptInfo, this.openFiles.get(scriptInfo.path));
+ }
+ }
+
+ return this.tryGetDefaultProjectForFile(scriptInfo);
+ }
+
/** @internal */
ensureDefaultProjectForFile(fileNameOrScriptInfo: NormalizedPath | ScriptInfo): Project {
- return this.tryGetDefaultProjectForFile(fileNameOrScriptInfo) || this.doEnsureDefaultProjectForFile(fileNameOrScriptInfo);
+ return this.tryGetDefaultProjectForEnsuringConfiguredProjectForFile(fileNameOrScriptInfo) || this.doEnsureDefaultProjectForFile(fileNameOrScriptInfo);
}
private doEnsureDefaultProjectForFile(fileNameOrScriptInfo: NormalizedPath | ScriptInfo): Project {
@@ -1713,7 +1864,7 @@ export class ProjectService {
// Load root file names for configured project with the config file name
// But only schedule update if project references this config file
const updateLevel = configuredProjectForConfig === project ? ProgramUpdateLevel.RootNamesAndUpdate : ProgramUpdateLevel.Update;
- if (project.pendingUpdateLevel !== undefined && project.pendingUpdateLevel > updateLevel) return;
+ if (project.pendingUpdateLevel > updateLevel) return;
// don't trigger callback on open, existing files
if (this.openFiles.has(fileOrDirectoryPath)) {
@@ -1794,7 +1945,7 @@ export class ProjectService {
}
/** @internal */
- private onConfigFileChanged(canonicalConfigFilePath: NormalizedPath, eventKind: FileWatcherEventKind) {
+ private onConfigFileChanged(configFileName: NormalizedPath, canonicalConfigFilePath: NormalizedPath, eventKind: FileWatcherEventKind) {
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath)!;
const project = this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath);
const wasDefferedClose = project?.deferredClose;
@@ -1817,60 +1968,46 @@ export class ProjectService {
}
// Update projects watching config
- this.delayUpdateProjectsFromParsedConfigOnConfigFileChange(canonicalConfigFilePath, "Change in config file detected");
-
- // Reload the configured projects for the open files in the map as they are affected by this config file
- // If the configured project was deleted, we want to reload projects for all the open files including files
- // that are not root of the inferred project
- // Otherwise, we scheduled the update on configured project graph,
- // we would need to schedule the project reload for only the root of inferred projects
- // Get open files to reload projects for
- this.delayReloadConfiguredProjectsForFile(
- configFileExistenceInfo,
- !wasDefferedClose && eventKind !== FileWatcherEventKind.Deleted ?
- identity : // Reload open files if they are root of inferred project
- returnTrue, // Reload all the open files impacted by config file
+ this.delayUpdateProjectsFromParsedConfigOnConfigFileChange(
+ canonicalConfigFilePath,
"Change in config file detected",
);
- this.delayEnsureProjectForOpenFiles();
- }
- /**
- * This function goes through all the openFiles and tries to file the config file for them.
- * If the config file is found and it refers to existing project, it schedules the reload it for reload
- * If there is no existing project it just opens the configured project for the config file
- * shouldReloadProjectFor provides a way to filter out files to reload configured project for
- */
- private delayReloadConfiguredProjectsForFile(
- configFileExistenceInfo: ConfigFileExistenceInfo | undefined,
- shouldReloadProjectFor: (infoIsRootOfInferredProject: boolean) => boolean,
- reason: string,
- ) {
- const updatedProjects = new Set();
- // try to reload config file for all open files
- configFileExistenceInfo?.openFilesImpactedByConfigFile?.forEach((infoIsRootOfInferredProject, path) => {
+ const updatedProjects = new Set(project ? [project] : undefined);
+ this.openFiles.forEach((_projectRootPath, path) => {
+ const configFileForOpenFile = this.configFileForOpenFiles.get(path);
+
+ // If this open script info does not depend on this config file, skip
+ if (!configFileExistenceInfo.openFilesImpactedByConfigFile?.has(path)) return;
// Invalidate default config file name for open file
this.configFileForOpenFiles.delete(path);
- // Filter out the files that need to be ignored
- if (!shouldReloadProjectFor(infoIsRootOfInferredProject)) {
- return;
- }
const info = this.getScriptInfoForPath(path)!;
- Debug.assert(info.isScriptOpen());
- // This tries to search for a tsconfig.json for the given file. If we found it,
- // we first detect if there is already a configured project created for it: if so,
- // we re- read the tsconfig file content and update the project only if we havent already done so
- // otherwise we create a new one.
- const configFileName = this.getConfigFileNameForFile(info);
- if (configFileName) {
- const project = this.findConfiguredProjectByProjectName(configFileName) || this.createConfiguredProject(configFileName);
- if (tryAddToSet(updatedProjects, project)) {
- project.pendingUpdateLevel = ProgramUpdateLevel.Full;
- project.pendingUpdateReason = reason;
- this.delayUpdateProjectGraph(project);
- }
+
+ // Find new default config file name for this open file
+ const newConfigFileNameForInfo = this.getConfigFileNameForFile(info, /*findFromCacheOnly*/ false);
+ if (!newConfigFileNameForInfo) return;
+
+ // Create new project for this open file with delay load
+ const projectForInfo = this.findConfiguredProjectByProjectName(newConfigFileNameForInfo) ??
+ this.createConfiguredProject(
+ newConfigFileNameForInfo,
+ `Change in config file ${configFileName} detected, ${fileOpenReason(info)}`,
+ );
+
+ // Cache the existing config file info for this open file if not already done so
+ if (!this.pendingOpenFileProjectUpdates?.has(path)) {
+ (this.pendingOpenFileProjectUpdates ??= new Map()).set(path, configFileForOpenFile);
+ }
+
+ // If this was not already updated, and its new project, schedule for update
+ // Existing projects dont need to update if they were not using the changed config in any way
+ if (tryAddToSet(updatedProjects, projectForInfo) && projectForInfo.isInitialLoadPending()) {
+ this.delayUpdateProjectGraph(projectForInfo);
}
});
+
+ // Ensure that all the open files have project
+ this.delayEnsureProjectForOpenFiles();
}
private removeProject(project: Project) {
@@ -1926,7 +2063,6 @@ export class ProjectService {
/** @internal */
assignOrphanScriptInfoToInferredProject(info: ScriptInfo, projectRootPath: NormalizedPath | undefined) {
Debug.assert(info.isOrphan());
-
const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) ||
this.getOrCreateSingleInferredProjectIfEnabled() ||
this.getOrCreateSingleInferredWithoutProjectRoot(
@@ -1999,7 +2135,7 @@ export class ProjectService {
// to the disk, and the server's version of the file can be out of sync.
const fileExists = info.isDynamic ? false : this.host.fileExists(info.fileName);
info.close(fileExists);
- this.stopWatchingConfigFilesForClosedScriptInfo(info);
+ this.stopWatchingConfigFilesForScriptInfo(info);
const canonicalFileName = this.toCanonicalFileName(info.fileName);
if (this.openFilesWithNonRootedDiskPath.get(canonicalFileName) === info) {
@@ -2021,7 +2157,7 @@ export class ProjectService {
const updateLevel = p.openFileWatchTriggered.get(info.path);
if (updateLevel !== undefined) {
p.openFileWatchTriggered.delete(info.path);
- if (p.pendingUpdateLevel !== undefined && p.pendingUpdateLevel < updateLevel) {
+ if (p.pendingUpdateLevel < updateLevel) {
p.pendingUpdateLevel = updateLevel;
p.markFileAsDirty(info.path);
}
@@ -2048,6 +2184,8 @@ export class ProjectService {
this.openFiles.delete(info.path);
this.configFileForOpenFiles.delete(info.path);
+ this.pendingOpenFileProjectUpdates?.delete(info.path);
+ Debug.assert(!this.rootOfInferredProjects.has(info));
if (!skipAssignOrphanScriptInfosToInferredProject && ensureProjectsForOpenFiles) {
this.assignOrphanScriptInfosToInferredProject();
@@ -2081,16 +2219,18 @@ export class ProjectService {
}
private configFileExists(configFileName: NormalizedPath, canonicalConfigFilePath: NormalizedPath, info: OpenScriptInfoOrClosedOrConfigFileInfo) {
- let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
- if (configFileExistenceInfo) {
+ const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
+
+ let openFilesImpactedByConfigFile: Set | undefined;
+ if (this.openFiles.has(info.path) && !isAncestorConfigFileInfo(info)) {
// By default the info would get impacted by presence of config file since its in the detection path
// Only adding the info as a root to inferred project will need the existence to be watched by file watcher
- if (isOpenScriptInfo(info) && !configFileExistenceInfo.openFilesImpactedByConfigFile?.has(info.path)) {
- (configFileExistenceInfo.openFilesImpactedByConfigFile ||= new Map()).set(info.path, false);
- }
- return configFileExistenceInfo.exists;
+ if (configFileExistenceInfo) (configFileExistenceInfo.openFilesImpactedByConfigFile ??= new Set()).add(info.path);
+ else (openFilesImpactedByConfigFile = new Set()).add(info.path);
}
+ if (configFileExistenceInfo) return configFileExistenceInfo.exists;
+
// Theoretically we should be adding watch for the directory here itself.
// In practice there will be very few scenarios where the config file gets added
// somewhere inside the another config file directory.
@@ -2102,12 +2242,7 @@ export class ProjectService {
// Cache the host value of file exists and add the info to map of open files impacted by this config file
const exists = this.host.fileExists(configFileName);
- let openFilesImpactedByConfigFile: Map | undefined;
- if (isOpenScriptInfo(info)) {
- (openFilesImpactedByConfigFile ||= new Map()).set(info.path, false);
- }
- configFileExistenceInfo = { exists, openFilesImpactedByConfigFile };
- this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo);
+ this.configFileExistenceInfoCache.set(canonicalConfigFilePath, { exists, openFilesImpactedByConfigFile });
return exists;
}
@@ -2118,7 +2253,7 @@ export class ProjectService {
if (!configFileExistenceInfo.watcher || configFileExistenceInfo.watcher === noopConfigFileWatcher) {
configFileExistenceInfo.watcher = this.watchFactory.watchFile(
configFileName,
- (_fileName, eventKind) => this.onConfigFileChanged(canonicalConfigFilePath, eventKind),
+ (_fileName, eventKind) => this.onConfigFileChanged(configFileName, canonicalConfigFilePath, eventKind),
PollingInterval.High,
this.getWatchOptionsFromProjectWatchOptions(configFileExistenceInfo?.config?.parsedCommandLine?.watchOptions, getDirectoryPath(configFileName)),
WatchType.ConfigFile,
@@ -2130,14 +2265,6 @@ export class ProjectService {
projects.set(forProject.canonicalConfigFilePath, projects.get(forProject.canonicalConfigFilePath) || false);
}
- /**
- * Returns true if the configFileExistenceInfo is needed/impacted by open files that are root of inferred project
- */
- private configFileExistenceImpactsRootOfInferredProject(configFileExistenceInfo: ConfigFileExistenceInfo) {
- return configFileExistenceInfo.openFilesImpactedByConfigFile &&
- forEachEntry(configFileExistenceInfo.openFilesImpactedByConfigFile, identity);
- }
-
/** @internal */
releaseParsedConfig(canonicalConfigFilePath: NormalizedPath, forProject: ConfiguredProject) {
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath)!;
@@ -2152,7 +2279,7 @@ export class ProjectService {
// If there are open files that are impacted by this config file existence
// but none of them are root of inferred project, the config file watcher will be
// created when any of the script infos are added as root of inferred project
- if (this.configFileExistenceImpactsRootOfInferredProject(configFileExistenceInfo)) {
+ if (configFileExistenceInfo.inferredProjectRoots) {
// If we cannot watch config file existence without configured project, close the configured file watcher
if (!canWatchDirectoryOrFile(getPathComponents(getDirectoryPath(canonicalConfigFilePath) as Path))) {
configFileExistenceInfo.watcher!.close();
@@ -2173,56 +2300,58 @@ export class ProjectService {
}
/**
- * Close the config file watcher in the cached ConfigFileExistenceInfo
- * if there arent any open files that are root of inferred project and there is no parsed config held by any project
- *
+ * This is called on file close or when its removed from inferred project as root,
+ * so that we handle the watches and inferred project root data
* @internal
*/
- private closeConfigFileWatcherOnReleaseOfOpenFile(configFileExistenceInfo: ConfigFileExistenceInfo) {
- // Close the config file watcher if there are no more open files that are root of inferred project
- // or if there are no projects that need to watch this config file existence info
- if (
- configFileExistenceInfo.watcher &&
- !configFileExistenceInfo.config &&
- !this.configFileExistenceImpactsRootOfInferredProject(configFileExistenceInfo)
- ) {
- configFileExistenceInfo.watcher.close();
- configFileExistenceInfo.watcher = undefined;
- }
- }
-
- /**
- * This is called on file close, so that we stop watching the config file for this script info
- */
- private stopWatchingConfigFilesForClosedScriptInfo(info: ScriptInfo) {
- Debug.assert(!info.isScriptOpen());
+ stopWatchingConfigFilesForScriptInfo(info: ScriptInfo) {
+ if (this.serverMode !== LanguageServiceMode.Semantic) return;
+ const isRootOfInferredProject = this.rootOfInferredProjects.delete(info);
+ const isOpen = info.isScriptOpen();
+ // Nothing to stop watching if this is open script info and not root of inferred project
+ if (isOpen && !isRootOfInferredProject) return;
this.forEachConfigFileLocation(info, canonicalConfigFilePath => {
const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
- if (configFileExistenceInfo) {
- const infoIsRootOfInferredProject = configFileExistenceInfo.openFilesImpactedByConfigFile?.get(info.path);
+ if (!configFileExistenceInfo) return;
+ if (isOpen) {
+ // If this file doesnt get impacted by this config file, skip
+ if (!configFileExistenceInfo?.openFilesImpactedByConfigFile?.has(info.path)) return;
+ }
+ else {
// Delete the info from map, since this file is no more open
- configFileExistenceInfo.openFilesImpactedByConfigFile?.delete(info.path);
-
- // If the script info was not root of inferred project,
- // there wont be config file watch open because of this script info
- if (infoIsRootOfInferredProject) {
- // But if it is a root, it could be the last script info that is root of inferred project
- // and hence we would need to close the config file watcher
- this.closeConfigFileWatcherOnReleaseOfOpenFile(configFileExistenceInfo);
- }
+ if (!configFileExistenceInfo.openFilesImpactedByConfigFile?.delete(info.path)) return;
+ }
- // If there are no open files that are impacted by configFileExistenceInfo after closing this script info
- // and there is are no projects that need the config file existence or parsed config,
- // remove the cached existence info
+ // If the script info was not root of inferred project,
+ // there wont be config file watch open because of this script info
+ if (isRootOfInferredProject) {
+ // But if it is a root, it could be the last script info that is root of inferred project
+ // and hence we would need to close the config file watcher
+ configFileExistenceInfo.inferredProjectRoots!--;
+
+ // Close the config file watcher if there are no more open files that are root of inferred project
+ // or if there are no projects that need to watch this config file existence info
if (
- !configFileExistenceInfo.openFilesImpactedByConfigFile?.size &&
- !configFileExistenceInfo.config
+ configFileExistenceInfo.watcher &&
+ !configFileExistenceInfo.config &&
+ !configFileExistenceInfo.inferredProjectRoots
) {
- Debug.assert(!configFileExistenceInfo.watcher);
- this.configFileExistenceInfoCache.delete(canonicalConfigFilePath);
+ configFileExistenceInfo.watcher.close();
+ configFileExistenceInfo.watcher = undefined;
}
}
+
+ // If there are no open files that are impacted by configFileExistenceInfo after closing this script info
+ // and there is are no projects that need the config file existence or parsed config,
+ // remove the cached existence info
+ if (
+ !configFileExistenceInfo.openFilesImpactedByConfigFile?.size &&
+ !configFileExistenceInfo.config
+ ) {
+ Debug.assert(!configFileExistenceInfo.watcher);
+ this.configFileExistenceInfoCache.delete(canonicalConfigFilePath);
+ }
});
}
@@ -2232,23 +2361,30 @@ export class ProjectService {
* @internal
*/
startWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo) {
+ if (this.serverMode !== LanguageServiceMode.Semantic) return;
Debug.assert(info.isScriptOpen());
+ // Set this file as the root of inferred project
+ this.rootOfInferredProjects.add(info);
this.forEachConfigFileLocation(info, (canonicalConfigFilePath, configFileName) => {
let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
if (!configFileExistenceInfo) {
// Create the cache
- configFileExistenceInfo = { exists: this.host.fileExists(configFileName) };
+ configFileExistenceInfo = { exists: this.host.fileExists(configFileName), inferredProjectRoots: 1 };
this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo);
}
+ else {
+ configFileExistenceInfo.inferredProjectRoots = (configFileExistenceInfo.inferredProjectRoots ?? 0) + 1;
+ }
- // Set this file as the root of inferred project
- (configFileExistenceInfo.openFilesImpactedByConfigFile ||= new Map()).set(info.path, true);
+ // It might not have been marked as impacting by presence of this script info if
+ // this is in ancestor folder of config that was not looked up yet
+ (configFileExistenceInfo.openFilesImpactedByConfigFile ??= new Set()).add(info.path);
// If there is no configured project for this config file, add the file watcher
configFileExistenceInfo.watcher ||= canWatchDirectoryOrFile(getPathComponents(getDirectoryPath(canonicalConfigFilePath) as Path)) ?
this.watchFactory.watchFile(
configFileName,
- (_filename, eventKind) => this.onConfigFileChanged(canonicalConfigFilePath, eventKind),
+ (_filename, eventKind) => this.onConfigFileChanged(configFileName, canonicalConfigFilePath, eventKind),
PollingInterval.High,
this.hostConfiguration.watchOptions,
WatchType.ConfigFileForInferredRoot,
@@ -2257,26 +2393,6 @@ export class ProjectService {
});
}
- /**
- * This is called by inferred project whenever root script info is removed from it
- *
- * @internal
- */
- stopWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo) {
- this.forEachConfigFileLocation(info, canonicalConfigFilePath => {
- const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath);
- if (configFileExistenceInfo?.openFilesImpactedByConfigFile?.has(info.path)) {
- Debug.assert(info.isScriptOpen());
-
- // Info is not root of inferred project any more
- configFileExistenceInfo.openFilesImpactedByConfigFile.set(info.path, false);
-
- // Close the config file watcher
- this.closeConfigFileWatcherOnReleaseOfOpenFile(configFileExistenceInfo);
- }
- });
- }
-
/**
* This function tries to search for a tsconfig.json for the given file.
* This is different from the method the compiler uses because
@@ -2333,14 +2449,34 @@ export class ProjectService {
/** @internal */
findDefaultConfiguredProject(info: ScriptInfo) {
- if (!info.isScriptOpen()) return undefined;
- const configFileName = this.getConfigFileNameForFile(info);
- const project = configFileName &&
- this.findConfiguredProjectByProjectName(configFileName);
+ return info.isScriptOpen() ?
+ this.tryFindDefaultConfiguredProjectForOpenScriptInfo(
+ info,
+ ConfiguredProjectLoadKind.Find,
+ )?.defaultProject :
+ undefined;
+ }
- return project && projectContainsInfoDirectly(project, info) ?
- project :
- project?.getDefaultChildProjectFromProjectWithReferences(info);
+ /** Get cached configFileName for scriptInfo or ancestor of open script info */
+ private getConfigFileNameForFileFromCache(
+ info: OpenScriptInfoOrClosedOrConfigFileInfo,
+ lookInPendingFilesForValue: boolean,
+ ): ConfigFileName | undefined {
+ if (lookInPendingFilesForValue) {
+ const result = getConfigFileNameFromCache(info, this.pendingOpenFileProjectUpdates);
+ if (result !== undefined) return result;
+ }
+ return getConfigFileNameFromCache(info, this.configFileForOpenFiles);
+ }
+
+ /** Caches the configFilename for script info or ancestor of open script info */
+ private setConfigFileNameForFileInCache(
+ info: OpenScriptInfoOrClosedOrConfigFileInfo,
+ configFileName: NormalizedPath | undefined,
+ ) {
+ if (!this.openFiles.has(info.path)) return; // Dont cache for closed script infos
+ if (isAncestorConfigFileInfo(info)) return; // Dont cache for ancestors
+ this.configFileForOpenFiles.set(info.path, configFileName || false);
}
/**
@@ -2352,17 +2488,17 @@ export class ProjectService {
* the newly opened file.
* If script info is passed in, it is asserted to be open script info
* otherwise just file name
+ * when findFromCacheOnly is true only looked up in cache instead of hitting disk to figure things out
+ * @internal
*/
- private getConfigFileNameForFile(info: OpenScriptInfoOrClosedOrConfigFileInfo) {
- if (!isAncestorConfigFileInfo(info)) {
- const result = this.configFileForOpenFiles.get(info.path);
- if (result !== undefined) return result || undefined;
- }
+ getConfigFileNameForFile(info: OpenScriptInfoOrClosedOrConfigFileInfo, findFromCacheOnly: boolean) {
+ // If we are using already cached values, look for values from pending update as well
+ const fromCache = this.getConfigFileNameForFileFromCache(info, findFromCacheOnly);
+ if (fromCache !== undefined) return fromCache || undefined;
+ if (findFromCacheOnly) return undefined;
const configFileName = this.forEachConfigFileLocation(info, (canonicalConfigFilePath, configFileName) => this.configFileExists(configFileName, canonicalConfigFilePath, info));
this.logger.info(`getConfigFileNameForFile:: File: ${info.fileName} ProjectRootPath: ${this.openFiles.get(info.path)}:: Result: ${configFileName}`);
- if (isOpenScriptInfo(info)) {
- this.configFileForOpenFiles.set(info.path, configFileName || false);
- }
+ this.setConfigFileNameForFileInCache(info, configFileName);
return configFileName;
}
@@ -2388,11 +2524,11 @@ export class ProjectService {
}
/** @internal */
- findConfiguredProjectByProjectName(configFileName: NormalizedPath): ConfiguredProject | undefined {
+ findConfiguredProjectByProjectName(configFileName: NormalizedPath, allowDeferredClosed?: boolean): ConfiguredProject | undefined {
// make sure that casing of config file name is consistent
const canonicalConfigFilePath = asNormalizedPath(this.toCanonicalFileName(configFileName));
const result = this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath);
- return !result?.deferredClose ? result : undefined;
+ return allowDeferredClosed ? result : !result?.deferredClose ? result : undefined;
}
private getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath: string): ConfiguredProject | undefined {
@@ -2514,7 +2650,7 @@ export class ProjectService {
}
/** @internal */
- createConfiguredProject(configFileName: NormalizedPath) {
+ createConfiguredProject(configFileName: NormalizedPath, reason: string) {
tracing?.instant(tracing.Phase.Session, "createConfiguredProject", { configFilePath: configFileName });
this.logger.info(`Creating configuration project ${configFileName}`);
const canonicalConfigFilePath = asNormalizedPath(this.toCanonicalFileName(configFileName));
@@ -2541,6 +2677,7 @@ export class ProjectService {
this,
this.documentRegistry,
configFileExistenceInfo.config.cachedDirectoryStructureHost,
+ reason,
);
Debug.assert(!this.configuredProjects.has(canonicalConfigFilePath));
this.configuredProjects.set(canonicalConfigFilePath, project);
@@ -2548,29 +2685,6 @@ export class ProjectService {
return project;
}
- /** @internal */
- private createConfiguredProjectWithDelayLoad(configFileName: NormalizedPath, reason: string) {
- const project = this.createConfiguredProject(configFileName);
- project.pendingUpdateLevel = ProgramUpdateLevel.Full;
- project.pendingUpdateReason = reason;
- return project;
- }
-
- /** @internal */
- createAndLoadConfiguredProject(configFileName: NormalizedPath, reason: string) {
- const project = this.createConfiguredProject(configFileName);
- this.loadConfiguredProject(project, reason);
- return project;
- }
-
- /** @internal */
- private createLoadAndUpdateConfiguredProject(configFileName: NormalizedPath, reason: string) {
- const project = this.createAndLoadConfiguredProject(configFileName, reason);
- project.skipConfigDiagEvent = true;
- project.updateGraph();
- return project;
- }
-
/**
* Read the config file of the project, and update the project root file names.
*
@@ -2779,7 +2893,7 @@ export class ProjectService {
path = normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName);
const existingValue = projectRootFilesMap.get(path);
if (existingValue) {
- if (existingValue.info) {
+ if (existingValue.info?.path === path) {
project.removeFile(existingValue.info, /*fileExists*/ false, /*detachFromProject*/ true);
existingValue.info = undefined;
}
@@ -2880,31 +2994,42 @@ export class ProjectService {
this.updateNonInferredProjectFiles(project, fileNames, fileNamePropertyReader);
}
+ /** @internal */
+ reloadConfiguredProjectClearingSemanticCache(
+ project: ConfiguredProject,
+ reason: string,
+ reloadedProjects: Set,
+ ) {
+ if (!tryAddToSet(reloadedProjects, project)) return false;
+ this.clearSemanticCache(project);
+ this.reloadConfiguredProject(project, reloadReason(reason));
+ return true;
+ }
+
/**
* Read the config file of the project again by clearing the cache and update the project graph
*
* @internal
*/
- reloadConfiguredProject(project: ConfiguredProject, reason: string, isInitialLoad: boolean, clearSemanticCache: boolean) {
+ reloadConfiguredProject(project: ConfiguredProject, reason: string) {
+ project.isInitialLoadPending = returnFalse;
+ project.pendingUpdateReason = undefined;
+ project.pendingUpdateLevel = ProgramUpdateLevel.Update;
+
// At this point, there is no reason to not have configFile in the host
const host = project.getCachedDirectoryStructureHost();
- if (clearSemanticCache) this.clearSemanticCache(project);
// Clear the cache since we are reloading the project from disk
host.clearCache();
- const configFileName = project.getConfigFilePath();
- this.logger.info(`${isInitialLoad ? "Loading" : "Reloading"} configured project ${configFileName}`);
// Load project from the disk
this.loadConfiguredProject(project, reason);
- project.skipConfigDiagEvent = true;
- project.updateGraph();
-
- this.sendConfigFileDiagEvent(project, configFileName);
+ updateWithTriggerFile(project, project.triggerFileForConfigFileDiag ?? project.getConfigFilePath(), /*isReload*/ true);
}
/** @internal */
private clearSemanticCache(project: Project) {
+ project.originalConfiguredProjects = undefined;
project.resolutionCache.clear();
project.getLanguageService(/*ensureSynchronized*/ false).cleanupSemanticCache();
project.cleanupProgram();
@@ -2912,23 +3037,20 @@ export class ProjectService {
}
/** @internal */
- sendConfigFileDiagEvent(project: ConfiguredProject, triggerFile: NormalizedPath | undefined) {
- if (!this.eventHandler || this.suppressDiagnosticEvents) {
- return;
- }
+ sendConfigFileDiagEvent(project: ConfiguredProject, triggerFile: NormalizedPath | undefined, force: boolean) {
+ if (!this.eventHandler || this.suppressDiagnosticEvents) return false;
const diagnostics = project.getLanguageService().getCompilerOptionsDiagnostics();
diagnostics.push(...project.getAllProjectErrors());
- if (!triggerFile && !!diagnostics.length === !!project.hasConfigFileDiagnostics) return;
-
- project.hasConfigFileDiagnostics = !!diagnostics.length;
-
+ if (!force && diagnostics.length === (project.configDiagDiagnosticsReported ?? 0)) return false;
+ project.configDiagDiagnosticsReported = diagnostics.length;
this.eventHandler(
{
eventName: ConfigFileDiagEvent,
data: { configFileName: project.getConfigFilePath(), diagnostics, triggerFile: triggerFile ?? project.getConfigFilePath() },
} satisfies ConfigFileDiagEvent,
);
+ return true;
}
private getOrCreateInferredProjectForProjectRootPathIfEnabled(info: ScriptInfo, projectRootPath: NormalizedPath | undefined): InferredProject | undefined {
@@ -3580,9 +3702,8 @@ export class ProjectService {
if (
!project.deferredClose &&
!project.isClosed() &&
- project.hasExternalProjectRef() &&
project.pendingUpdateLevel === ProgramUpdateLevel.Full &&
- !this.pendingProjectUpdates.has(project.getProjectName())
+ !this.hasPendingProjectUpdate(project)
) {
project.updateGraph();
}
@@ -3668,81 +3789,74 @@ export class ProjectService {
this.pendingProjectUpdates.delete(projectName);
});
this.throttledOperations.cancel(ensureProjectForOpenFileSchedule);
+ this.pendingOpenFileProjectUpdates = undefined;
this.pendingEnsureProjectForOpenFiles = false;
// Ensure everything is reloaded for cached configs
this.configFileExistenceInfoCache.forEach(info => {
if (info.config) info.config.updateLevel = ProgramUpdateLevel.Full;
});
+ this.configFileForOpenFiles.clear();
// Reload Projects
- this.reloadConfiguredProjectForFiles("User requested reload projects");
this.externalProjects.forEach(project => {
this.clearSemanticCache(project);
project.updateGraph();
});
+
+ // Configured projects of external files
+ const reloadedConfiguredProjects = new Set();
+ const delayReloadedConfiguredProjects = new Set();
+ this.externalProjectToConfiguredProjectMap.forEach((projects, externalProjectName) => {
+ const reason = `Reloading configured project in external project: ${externalProjectName}`;
+ projects.forEach(project => {
+ if (this.getHostPreferences().lazyConfiguredProjectsFromExternalProject) {
+ if (!project.isInitialLoadPending()) {
+ this.clearSemanticCache(project);
+ project.pendingUpdateLevel = ProgramUpdateLevel.Full;
+ project.pendingUpdateReason = reloadReason(reason);
+ }
+ delayReloadedConfiguredProjects.add(project);
+ }
+ else {
+ this.reloadConfiguredProjectClearingSemanticCache(
+ project,
+ reason,
+ reloadedConfiguredProjects,
+ );
+ }
+ });
+ });
+
+ // Configured projects for open file
+ this.openFiles.forEach((_projectRootPath, path) => {
+ const info = this.getScriptInfoForPath(path)!;
+ if (find(info.containingProjects, isExternalProject)) return;
+ this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
+ info,
+ ConfiguredProjectLoadKind.Reload,
+ reloadedConfiguredProjects,
+ delayReloadedConfiguredProjects,
+ );
+ });
+
+ // Retain delay loaded configured projects too
+ delayReloadedConfiguredProjects.forEach(p => reloadedConfiguredProjects.add(p));
+
this.inferredProjects.forEach(project => this.clearSemanticCache(project));
this.ensureProjectForOpenFiles();
+ // Cleanup
+ this.cleanupProjectsAndScriptInfos(
+ reloadedConfiguredProjects,
+ new Set(this.openFiles.keys()),
+ new Set(this.externalProjectToConfiguredProjectMap.keys()),
+ );
+
this.logger.info("After reloading projects..");
this.printProjects();
}
- /**
- * This function goes through all the openFiles and tries to file the config file for them.
- * If the config file is found and it refers to existing project, it reloads it either immediately
- * If there is no existing project it just opens the configured project for the config file
- */
- private reloadConfiguredProjectForFiles(reason: string) {
- const updatedProjects = new Set();
- const reloadChildProject = (child: ConfiguredProject) => {
- if (tryAddToSet(updatedProjects, child)) {
- this.reloadConfiguredProject(child, reason, /*isInitialLoad*/ false, /*clearSemanticCache*/ true);
- }
- };
- // try to reload config file for all open files
- this.openFiles?.forEach((_projectRoot, path) => {
- // Invalidate default config file name for open file
- this.configFileForOpenFiles.delete(path);
-
- const info = this.getScriptInfoForPath(path)!; // TODO: GH#18217
- Debug.assert(info.isScriptOpen());
- // This tries to search for a tsconfig.json for the given file. If we found it,
- // we first detect if there is already a configured project created for it: if so,
- // we re- read the tsconfig file content and update the project only if we havent already done so
- // otherwise we create a new one.
- const configFileName = this.getConfigFileNameForFile(info);
- if (configFileName) {
- const project = this.findConfiguredProjectByProjectName(configFileName) || this.createConfiguredProject(configFileName);
- if (tryAddToSet(updatedProjects, project)) {
- // reload from the disk
- this.reloadConfiguredProject(project, reason, /*isInitialLoad*/ false, /*clearSemanticCache*/ true);
- // If this project does not contain this file directly, reload the project till the reloaded project contains the script info directly
- if (!projectContainsInfoDirectly(project, info)) {
- const referencedProject = forEachResolvedProjectReferenceProject(
- project,
- info.path,
- child => {
- reloadChildProject(child);
- return projectContainsInfoDirectly(child, info);
- },
- ProjectReferenceProjectLoadKind.FindCreate,
- );
- if (referencedProject) {
- // Reload the project's tree that is already present
- forEachResolvedProjectReferenceProject(
- project,
- /*fileName*/ undefined,
- reloadChildProject,
- ProjectReferenceProjectLoadKind.Find,
- );
- }
- }
- }
- }
- });
- }
-
/**
* Remove the root of inferred project if script info is part of another project
*/
@@ -3785,6 +3899,18 @@ export class ProjectService {
this.logger.info("Before ensureProjectForOpenFiles:");
this.printProjects();
+ // Ensure that default projects for pending openFile updates are created
+ const pendingOpenFileProjectUpdates = this.pendingOpenFileProjectUpdates;
+ this.pendingOpenFileProjectUpdates = undefined;
+ pendingOpenFileProjectUpdates?.forEach((_config, path) =>
+ this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
+ this.getScriptInfoForPath(path)!,
+ ConfiguredProjectLoadKind.Create,
+ )
+ );
+
+ // Assigned the orphan scriptInfos to inferred project
+ // Remove the infos from inferred project that no longer need to be part of it
this.openFiles.forEach((projectRootPath, path) => {
const info = this.getScriptInfoForPath(path)!;
// collect all orphaned script infos from open files
@@ -3825,7 +3951,7 @@ export class ProjectService {
if (!scriptInfo && !this.host.fileExists(fileName)) return undefined;
const originalFileInfo: OriginalFileInfo = { fileName: toNormalizedPath(fileName), path: this.toPath(fileName) };
- const configFileName = this.getConfigFileNameForFile(originalFileInfo);
+ const configFileName = this.getConfigFileNameForFile(originalFileInfo, /*findFromCacheOnly*/ false);
if (!configFileName) return undefined;
let configuredProject: ConfiguredProject | undefined = this.findConfiguredProjectByProjectName(configFileName);
@@ -3845,13 +3971,15 @@ export class ProjectService {
: location;
}
- configuredProject = this.createAndLoadConfiguredProject(configFileName, `Creating project for original file: ${originalFileInfo.fileName}${location !== originalLocation ? " for location: " + location.fileName : ""}`);
+ configuredProject = this.createConfiguredProject(configFileName, `Creating project for original file: ${originalFileInfo.fileName}${location !== originalLocation ? " for location: " + location.fileName : ""}`);
}
updateProjectIfDirty(configuredProject);
const projectContainsOriginalInfo = (project: ConfiguredProject) => {
const info = this.getScriptInfo(fileName);
- return info && projectContainsInfoDirectly(project, info);
+ return info &&
+ project.containsScriptInfo(info) &&
+ !project.isSourceOfProjectReferenceRedirect(info.path);
};
if (configuredProject.isSolution() || !projectContainsOriginalInfo(configuredProject)) {
@@ -3859,11 +3987,8 @@ export class ProjectService {
configuredProject = forEachResolvedProjectReferenceProject(
configuredProject,
fileName,
- child => {
- updateProjectIfDirty(child);
- return projectContainsOriginalInfo(child) ? child : undefined;
- },
- ProjectReferenceProjectLoadKind.FindCreateLoad,
+ child => projectContainsOriginalInfo(child) ? child : undefined,
+ ConfiguredProjectLoadKind.Create,
`Creating project referenced in solution ${configuredProject.projectName} to find possible configured project for original file: ${originalFileInfo.fileName}${location !== originalLocation ? " for location: " + location.fileName : ""}`,
);
if (!configuredProject) return undefined;
@@ -3926,73 +4051,21 @@ export class ProjectService {
private assignProjectToOpenedScriptInfo(info: ScriptInfo): AssignProjectResult {
let configFileName: NormalizedPath | undefined;
let configFileErrors: readonly Diagnostic[] | undefined;
- let project: ConfiguredProject | ExternalProject | undefined = this.findExternalProjectContainingOpenScriptInfo(info);
- let retainProjects: ConfiguredProject[] | ConfiguredProject | undefined;
- let projectForConfigFileDiag: ConfiguredProject | undefined;
- let defaultConfigProjectIsCreated = false;
+ const project = this.findExternalProjectContainingOpenScriptInfo(info);
+ let retainProjects: Set | undefined;
+ let sentConfigDiag: Set | undefined;
if (!project && this.serverMode === LanguageServiceMode.Semantic) { // Checking semantic mode is an optimization
- configFileName = this.getConfigFileNameForFile(info);
- if (configFileName) {
- project = this.findConfiguredProjectByProjectName(configFileName);
- if (!project) {
- project = this.createLoadAndUpdateConfiguredProject(configFileName, `Creating possible configured project for ${info.fileName} to open`);
- defaultConfigProjectIsCreated = true;
- }
- else {
- // Ensure project is ready to check if it contains opened script info
- updateConfiguredProjectWithoutConfigDiagIfDirty(project);
- }
-
- projectForConfigFileDiag = project.containsScriptInfo(info) ? project : undefined;
- retainProjects = project;
-
- // If this configured project doesnt contain script info but
- // it is solution with project references, try those project references
- if (!projectContainsInfoDirectly(project, info)) {
- forEachResolvedProjectReferenceProject(
- project,
- info.path,
- child => {
- updateConfiguredProjectWithoutConfigDiagIfDirty(child);
- // Retain these projects
- if (!isArray(retainProjects)) {
- retainProjects = [project as ConfiguredProject, child];
- }
- else {
- retainProjects.push(child);
- }
-
- // If script info belongs to this child project, use this as default config project
- if (projectContainsInfoDirectly(child, info)) {
- projectForConfigFileDiag = child;
- return child;
- }
-
- // If this project uses the script info (even through project reference), if default project is not found, use this for configFileDiag
- if (!projectForConfigFileDiag && child.containsScriptInfo(info)) {
- projectForConfigFileDiag = child;
- }
- },
- ProjectReferenceProjectLoadKind.FindCreateLoad,
- `Creating project referenced in solution ${project.projectName} to find possible configured project for ${info.fileName} to open`,
- );
- }
-
- // Send the event only if the project got created as part of this open request and info is part of the project
- if (projectForConfigFileDiag) {
- configFileName = projectForConfigFileDiag.getConfigFilePath();
- if (projectForConfigFileDiag !== project || defaultConfigProjectIsCreated) {
- configFileErrors = projectForConfigFileDiag.getAllProjectErrors();
- this.sendConfigFileDiagEvent(projectForConfigFileDiag, info.fileName);
- }
- }
- else {
- // Since the file isnt part of configured project, do not send config file info
- configFileName = undefined;
+ const result = this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
+ info,
+ ConfiguredProjectLoadKind.Create,
+ );
+ if (result) {
+ retainProjects = result.seenProjects;
+ sentConfigDiag = result.sentConfigDiag;
+ if (result.defaultProject) {
+ configFileName = result.defaultProject.getConfigFilePath();
+ configFileErrors = result.defaultProject.getAllProjectErrors();
}
-
- // Create ancestor configured project
- this.createAncestorProjects(info, project);
}
}
@@ -4009,12 +4082,9 @@ export class ProjectService {
// So if it still doesnt have any containing projects, it needs to be part of inferred project
if (info.isOrphan()) {
// Even though this info did not belong to any of the configured projects, send the config file diag
- if (isArray(retainProjects)) {
- retainProjects.forEach(project => this.sendConfigFileDiagEvent(project, info.fileName));
- }
- else if (retainProjects) {
- this.sendConfigFileDiagEvent(retainProjects, info.fileName);
- }
+ retainProjects?.forEach(project => {
+ if (!sentConfigDiag!.has(project)) this.sendConfigFileDiagEvent(project, info.fileName, /*force*/ true);
+ });
Debug.assert(this.openFiles.has(info.path));
this.assignOrphanScriptInfoToInferredProject(info, this.openFiles.get(info.path));
}
@@ -4022,38 +4092,183 @@ export class ProjectService {
return { configFileName, configFileErrors, retainProjects };
}
- private createAncestorProjects(info: ScriptInfo, project: ConfiguredProject) {
- // Skip if info is not part of default configured project
- if (!info.isAttached(project)) return;
+ /**
+ * Depending on kind
+ * - Find the configuedProject and return it - if allowDeferredClosed is set it will find the deferredClosed project as well
+ * - Create - if the project doesnt exist, it creates one as well. If not delayLoad, the project is updated (with triggerFile if passed)
+ * - Reload - if the project doesnt exist, it creates one. If not delayLoad, the project is reloaded clearing semantic cache
+ * @internal
+ */
+ findCreateOrReloadConfiguredProject(
+ configFileName: NormalizedPath,
+ kind: ConfiguredProjectLoadKind,
+ /** Used with ConfiguredProjectLoadKind.Create or ConfiguredProjectLoadKind.Reload for new projects or reload updates */
+ reason?: string,
+ /** Used with ConfiguredProjectLoadKind.Find to get deferredClosed projects as well */
+ allowDeferredClosed?: boolean,
+ /** Used with ConfiguredProjectLoadKind.Create to send configFileDiag */
+ triggerFile?: NormalizedPath,
+ /** Used with ConfiguredProjectLoadKind.Reload to check if this project was already reloaded */
+ reloadedProjects?: Set,
+ /** Used with ConfiguredProjectLoadKind.Create to specify only create project without updating */
+ delayLoad?: boolean,
+ /** Used with ConfiguredProjectLoadKind.Reload to specify delay reload, and also a set of configured projects already marked for delay load */
+ delayReloadedConfiguredProjects?: Set,
+ ): FindCreateOrLoadConfiguredProjectResult | undefined {
+ let project = this.findConfiguredProjectByProjectName(configFileName, allowDeferredClosed);
+ let sentConfigFileDiag = false;
+ switch (kind) {
+ case ConfiguredProjectLoadKind.Find:
+ if (!project) return;
+ break;
+ case ConfiguredProjectLoadKind.Create:
+ project ??= this.createConfiguredProject(configFileName, reason!);
+ // Ensure project is updated
+ sentConfigFileDiag = !delayLoad && updateConfiguredProject(project, triggerFile);
+ break;
+ case ConfiguredProjectLoadKind.Reload:
+ project ??= this.createConfiguredProject(configFileName, reloadReason(reason!));
+ // Reload immediately if not delayed
+ sentConfigFileDiag = !delayReloadedConfiguredProjects &&
+ this.reloadConfiguredProjectClearingSemanticCache(project, reason!, reloadedProjects!);
+ if (
+ delayReloadedConfiguredProjects &&
+ !delayReloadedConfiguredProjects.has(project) &&
+ !reloadedProjects!.has(project)
+ ) {
+ // Add to delayed reload
+ project.pendingUpdateLevel = ProgramUpdateLevel.Full;
+ project.pendingUpdateReason = reloadReason(reason!);
+ delayReloadedConfiguredProjects.add(project);
+ }
+ break;
+ default:
+ Debug.assertNever(kind);
+ }
+ return { project, sentConfigFileDiag };
+ }
+
+ /**
+ * Finds the default configured project for given info
+ * For any tsconfig found, it looks into that project, if not then all its references,
+ * The search happens for all tsconfigs till projectRootPath
+ */
+ private tryFindDefaultConfiguredProjectForOpenScriptInfo(
+ info: ScriptInfo,
+ kind: ConfiguredProjectLoadKind,
+ /** Used with ConfiguredProjectLoadKind.Find to get deferredClosed projects as well */
+ allowDeferredClosed?: boolean,
+ /** Used with ConfiguredProjectLoadKind.Reload to check if this project was already reloaded */
+ reloadedProjects?: Set,
+ ): DefaultConfiguredProjectResult | undefined {
+ const configFileName = this.getConfigFileNameForFile(info, kind === ConfiguredProjectLoadKind.Find);
+ // If no config file name, no result
+ if (!configFileName) return;
+
+ const result = this.findCreateOrReloadConfiguredProject(
+ configFileName,
+ kind,
+ fileOpenReason(info),
+ allowDeferredClosed,
+ info.fileName,
+ reloadedProjects,
+ );
+ // If the project for the configFileName does not exist, no result
+ if (!result) return;
+
+ const seenProjects = new Set();
+ const sentConfigDiag = new Set(result.sentConfigFileDiag ? [result.project] : undefined);
+ let defaultProject: ConfiguredProject | undefined;
+ let possiblyDefault: ConfiguredProject | undefined;
+ // See if this is the project or is it one of the references or find ancestor projects
+ tryFindDefaultConfiguredProject(result.project);
+ return {
+ defaultProject: defaultProject ?? possiblyDefault,
+ sentConfigDiag,
+ seenProjects,
+ };
- // Create configured project till project root
- while (true) {
- // Skip if project is not composite
- if (
- !project.isInitialLoadPending() &&
- (
- !project.getCompilerOptions().composite ||
- project.getCompilerOptions().disableSolutionSearching
- )
- ) return;
+ function tryFindDefaultConfiguredProject(project: ConfiguredProject): ConfiguredProject | undefined {
+ return isDefaultProject(project) ?
+ defaultProject :
+ tryFindDefaultConfiguredProjectFromReferences(project);
+ }
+
+ function isDefaultProject(project: ConfiguredProject): ConfiguredProject | undefined {
+ // Skip already looked up projects
+ if (!tryAddToSet(seenProjects, project)) return;
+ // If script info belongs to this project, use this as default config project
+ const projectWithInfo = project.containsScriptInfo(info);
+ if (projectWithInfo && !project.isSourceOfProjectReferenceRedirect(info.path)) return defaultProject = project;
+ // If this project uses the script info, if default project is not found, use this project as possible default
+ possiblyDefault ??= projectWithInfo ? project : undefined;
+ }
+
+ function tryFindDefaultConfiguredProjectFromReferences(project: ConfiguredProject) {
+ // If this configured project doesnt contain script info but
+ // if this is solution with project references, try those project references
+ return forEachResolvedProjectReferenceProject(
+ project,
+ info.path,
+ (child, sentConfigFileDiag) => {
+ if (sentConfigFileDiag) sentConfigDiag.add(child);
+ return isDefaultProject(child);
+ },
+ kind,
+ `Creating project referenced in solution ${project.projectName} to find possible configured project for ${info.fileName} to open`,
+ allowDeferredClosed,
+ info.fileName,
+ reloadedProjects,
+ );
+ }
+ }
- // Get config file name
- const configFileName = this.getConfigFileNameForFile({
- fileName: project.getConfigFilePath(),
- path: info.path,
- configFileInfo: true,
- });
- if (!configFileName) return;
-
- // find or delay load the project
- const ancestor = this.findConfiguredProjectByProjectName(configFileName) ||
- this.createConfiguredProjectWithDelayLoad(configFileName, `Creating project possibly referencing default composite project ${project.getProjectName()} of open file ${info.fileName}`);
- if (ancestor.isInitialLoadPending()) {
- // Set a potential project reference
- ancestor.setPotentialProjectReference(project.canonicalConfigFilePath);
- }
- project = ancestor;
+ /**
+ * Finds the default configured project, if found, it creates the solution projects (does not load them right away)
+ * with Find: finds the projects even if the project is deferredClosed
+ */
+ private tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
+ info: ScriptInfo,
+ kind: ConfiguredProjectLoadKind.Find | ConfiguredProjectLoadKind.Create,
+ ): DefaultConfiguredProjectResult | undefined;
+ private tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
+ info: ScriptInfo,
+ kind: ConfiguredProjectLoadKind.Reload,
+ reloadedProjects: Set,
+ delayReloadedConfiguredProjects: Set,
+ ): DefaultConfiguredProjectResult | undefined;
+ private tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
+ info: ScriptInfo,
+ kind: ConfiguredProjectLoadKind,
+ reloadedProjects?: Set,
+ delayReloadedConfiguredProjects?: Set,
+ ): DefaultConfiguredProjectResult | undefined {
+ const allowDeferredClosed = kind === ConfiguredProjectLoadKind.Find;
+ // Find default project
+ const result = this.tryFindDefaultConfiguredProjectForOpenScriptInfo(
+ info,
+ kind,
+ allowDeferredClosed,
+ reloadedProjects,
+ );
+ if (!result) return;
+ const { defaultProject, seenProjects } = result;
+ if (defaultProject) {
+ // Create ancestor tree for findAllRefs (dont load them right away)
+ forEachAncestorProject(
+ info,
+ defaultProject,
+ ancestor => {
+ seenProjects.add(ancestor);
+ },
+ kind,
+ `Creating project possibly referencing default composite project ${defaultProject.getProjectName()} of open file ${info.fileName}`,
+ allowDeferredClosed,
+ reloadedProjects,
+ delayReloadedConfiguredProjects,
+ );
}
+ return result;
}
/** @internal */
@@ -4091,8 +4306,11 @@ export class ProjectService {
// Load this project,
const configFileName = toNormalizedPath(child.sourceFile.fileName);
- const childProject = project.projectService.findConfiguredProjectByProjectName(configFileName) ||
- project.projectService.createAndLoadConfiguredProject(configFileName, `Creating project referenced by : ${project.projectName} as it references project ${referencedProject.sourceFile.fileName}`);
+ const childProject = this.findConfiguredProjectByProjectName(configFileName) ??
+ this.createConfiguredProject(
+ configFileName,
+ `Creating project referenced by : ${project.projectName} as it references project ${referencedProject.sourceFile.fileName}`,
+ );
updateProjectIfDirty(childProject);
// Ensure children for this project
@@ -4100,10 +4318,32 @@ export class ProjectService {
}
}
- private cleanupAfterOpeningFile(toRetainConfigProjects: readonly ConfiguredProject[] | ConfiguredProject | undefined) {
+ private cleanupConfiguredProjects(
+ toRetainConfiguredProjects?: Set,
+ externalProjectsRetainingConfiguredProjects?: Set,
+ openFilesWithRetainedConfiguredProject?: Set,
+ ) {
+ // Remove all orphan projects
+ this.getOrphanConfiguredProjects(
+ toRetainConfiguredProjects,
+ openFilesWithRetainedConfiguredProject,
+ externalProjectsRetainingConfiguredProjects,
+ ).forEach(project => this.removeProject(project));
+ }
+
+ private cleanupProjectsAndScriptInfos(
+ toRetainConfiguredProjects: Set | undefined,
+ openFilesWithRetainedConfiguredProject: Set | undefined,
+ externalProjectsRetainingConfiguredProjects: Set | undefined,
+ ) {
// This was postponed from closeOpenFile to after opening next file,
// so that we can reuse the project if we need to right away
- this.removeOrphanConfiguredProjects(toRetainConfigProjects);
+ // Remove all the non marked projects
+ this.cleanupConfiguredProjects(
+ toRetainConfiguredProjects,
+ externalProjectsRetainingConfiguredProjects,
+ openFilesWithRetainedConfiguredProject,
+ );
// Remove orphan inferred projects now that we have reused projects
// We need to create a duplicate because we cant guarantee order after removal
@@ -4123,20 +4363,22 @@ export class ProjectService {
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult {
const info = this.getOrCreateOpenScriptInfo(fileName, fileContent, scriptKind, hasMixedContent, projectRootPath);
const { retainProjects, ...result } = this.assignProjectToOpenedScriptInfo(info);
- this.cleanupAfterOpeningFile(retainProjects);
+ this.cleanupProjectsAndScriptInfos(
+ retainProjects,
+ new Set([info.path]),
+ /*externalProjectsRetainingConfiguredProjects*/ undefined,
+ );
this.telemetryOnOpenFile(info);
this.printProjects();
return result;
}
- private removeOrphanConfiguredProjects(toRetainConfiguredProjects: readonly ConfiguredProject[] | ConfiguredProject | undefined) {
- const orphanConfiguredProjects = this.getOrphanConfiguredProjects(toRetainConfiguredProjects);
- // Remove all the non marked projects
- orphanConfiguredProjects.forEach(project => this.removeProject(project));
- }
-
/** @internal */
- getOrphanConfiguredProjects(toRetainConfiguredProjects: readonly ConfiguredProject[] | ConfiguredProject | undefined) {
+ getOrphanConfiguredProjects(
+ toRetainConfiguredProjects: Set | undefined,
+ openFilesWithRetainedConfiguredProject: Set | undefined,
+ externalProjectsRetainingConfiguredProjects: Set | undefined,
+ ) {
const toRemoveConfiguredProjects = new Set(this.configuredProjects.values());
const markOriginalProjectsAsUsed = (project: Project) => {
if (project.originalConfiguredProjects && (isConfiguredProject(project) || !project.isOrphan())) {
@@ -4148,43 +4390,62 @@ export class ProjectService {
);
}
};
- if (toRetainConfiguredProjects) {
- if (isArray(toRetainConfiguredProjects)) {
- toRetainConfiguredProjects.forEach(retainConfiguredProject);
- }
- else {
- retainConfiguredProject(toRetainConfiguredProjects);
- }
- }
+ toRetainConfiguredProjects?.forEach(retainConfiguredProject);
// Do not remove configured projects that are used as original projects of other
this.inferredProjects.forEach(markOriginalProjectsAsUsed);
this.externalProjects.forEach(markOriginalProjectsAsUsed);
- this.configuredProjects.forEach(project => {
- if (!toRemoveConfiguredProjects.has(project)) return;
- // If project has open ref (there are more than zero references from external project/open file), keep it alive as well as any project it references
- if (project.hasOpenRef()) {
- retainConfiguredProject(project);
+ // Retain all configured projects referenced by external projects
+ this.externalProjectToConfiguredProjectMap.forEach((projects, externalProjectName) => {
+ if (!externalProjectsRetainingConfiguredProjects?.has(externalProjectName)) {
+ projects.forEach(retainConfiguredProject);
+ }
+ });
+ this.openFiles.forEach((_projectRootPath, path) => {
+ if (openFilesWithRetainedConfiguredProject?.has(path)) return;
+ const info = this.getScriptInfoForPath(path)!;
+ // Part of external project
+ if (find(info.containingProjects, isExternalProject)) return;
+ // We want to retain the projects for open file if they are pending updates so deferredClosed projects are ok
+ const result = this.tryFindDefaultConfiguredProjectAndLoadAncestorsForOpenScriptInfo(
+ info,
+ ConfiguredProjectLoadKind.Find,
+ );
+ if (result?.defaultProject) {
+ result?.seenProjects.forEach(retainConfiguredProject);
}
- // If the configured project for project reference has more than zero references, keep it alive
- else if (forEachReferencedProject(project, ref => isRetained(ref))) {
- retainConfiguredProject(project);
+ });
+
+ // Retain all the configured projects that have pending updates
+ // or the ones that is referencing retained project (or to be retained)
+ this.configuredProjects.forEach(project => {
+ if (toRemoveConfiguredProjects.has(project)) {
+ if (isPendingUpdate(project) || forEachReferencedProject(project, isRetained)) {
+ retainConfiguredProject(project);
+ }
}
});
return toRemoveConfiguredProjects;
function isRetained(project: ConfiguredProject) {
- return !toRemoveConfiguredProjects.has(project) || project.hasOpenRef();
+ return !toRemoveConfiguredProjects.has(project) || isPendingUpdate(project);
+ }
+
+ function isPendingUpdate(project: ConfiguredProject) {
+ return (
+ project.deferredClose ||
+ project.projectService.hasPendingProjectUpdate(project)
+ ) &&
+ !!project.projectService.configFileExistenceInfoCache.get(project.canonicalConfigFilePath)?.openFilesImpactedByConfigFile?.size;
}
function retainConfiguredProject(project: ConfiguredProject) {
- if (toRemoveConfiguredProjects.delete(project)) {
- // Keep original projects used
- markOriginalProjectsAsUsed(project);
- // Keep all the references alive
- forEachReferencedProject(project, retainConfiguredProject);
- }
+ if (!toRemoveConfiguredProjects.delete(project)) return;
+ // Keep original projects used
+ markOriginalProjectsAsUsed(project);
+ // Keep all the references alive
+ forEachReferencedProject(project, retainConfiguredProject);
}
}
@@ -4334,10 +4595,8 @@ export class ProjectService {
}
// All the script infos now exist, so ok to go update projects for open files
- let retainProjects: readonly ConfiguredProject[] | undefined;
- if (openScriptInfos) {
- retainProjects = flatMap(openScriptInfos, info => this.assignProjectToOpenedScriptInfo(info).retainProjects);
- }
+ let retainProjects: Set | undefined;
+ openScriptInfos?.forEach(info => this.assignProjectToOpenedScriptInfo(info).retainProjects?.forEach(p => (retainProjects ??= new Set()).add(p)));
// While closing files there could be open files that needed assigning new inferred projects, do it now
if (assignOrphanScriptInfosToInferredProject) {
@@ -4346,7 +4605,11 @@ export class ProjectService {
if (openScriptInfos) {
// Cleanup projects
- this.cleanupAfterOpeningFile(retainProjects);
+ this.cleanupProjectsAndScriptInfos(
+ retainProjects,
+ new Set(openScriptInfos.map(info => info.path)),
+ /*externalProjectsRetainingConfiguredProjects*/ undefined,
+ );
// Telemetry
openScriptInfos.forEach(info => this.telemetryOnOpenFile(info));
this.printProjects();
@@ -4363,23 +4626,13 @@ export class ProjectService {
}
}
- private closeConfiguredProjectReferencedFromExternalProject(configuredProjects: Set | undefined) {
- configuredProjects?.forEach(configuredProject => {
- if (!configuredProject.isClosed()) {
- configuredProject.deleteExternalProjectReference();
- if (!configuredProject.hasOpenRef()) this.removeProject(configuredProject);
- }
- });
- }
-
closeExternalProject(uncheckedFileName: string): void;
/** @internal */
- closeExternalProject(uncheckedFileName: string, print: boolean): void; // eslint-disable-line @typescript-eslint/unified-signatures
- closeExternalProject(uncheckedFileName: string, print?: boolean): void {
+ closeExternalProject(uncheckedFileName: string, cleanupAfter: boolean): void; // eslint-disable-line @typescript-eslint/unified-signatures
+ closeExternalProject(uncheckedFileName: string, cleanupAfter?: boolean) {
const fileName = toNormalizedPath(uncheckedFileName);
- const configuredProjects = this.externalProjectToConfiguredProjectMap.get(fileName);
- if (configuredProjects) {
- this.closeConfiguredProjectReferencedFromExternalProject(configuredProjects);
+ const projects = this.externalProjectToConfiguredProjectMap.get(fileName);
+ if (projects) {
this.externalProjectToConfiguredProjectMap.delete(fileName);
}
else {
@@ -4389,27 +4642,28 @@ export class ProjectService {
this.removeProject(externalProject);
}
}
- if (print) this.printProjects();
+ if (cleanupAfter) {
+ this.cleanupConfiguredProjects();
+ this.printProjects();
+ }
}
openExternalProjects(projects: protocol.ExternalProject[]): void {
// record project list before the update
- const projectsToClose = arrayToMap(this.externalProjects, p => p.getProjectName(), _ => true);
- forEachKey(this.externalProjectToConfiguredProjectMap, externalProjectName => {
- projectsToClose.set(externalProjectName, true);
- });
+ const projectsToClose = new Set(this.externalProjects.map(p => p.getProjectName()));
+ this.externalProjectToConfiguredProjectMap.forEach((_, externalProjectName) => projectsToClose.add(externalProjectName));
for (const externalProject of projects) {
- this.openExternalProject(externalProject, /*print*/ false);
+ this.openExternalProject(externalProject, /*cleanupAfter*/ false);
// delete project that is present in input list
projectsToClose.delete(externalProject.projectFileName);
}
// close projects that were missing in the input list
- forEachKey(projectsToClose, externalProjectName => {
- this.closeExternalProject(externalProjectName, /*print*/ false);
- });
+ projectsToClose.forEach(externalProjectName => this.closeExternalProject(externalProjectName, /*cleanupAfter*/ false));
+ // Cleanup
+ this.cleanupConfiguredProjects();
this.printProjects();
}
@@ -4542,14 +4796,11 @@ export class ProjectService {
excludedFiles.push(normalizedNames[index]);
}
}
-
openExternalProject(proj: protocol.ExternalProject): void;
/** @internal */
- openExternalProject(proj: protocol.ExternalProject, print: boolean): void; // eslint-disable-line @typescript-eslint/unified-signatures
- openExternalProject(proj: protocol.ExternalProject, print?: boolean): void {
+ openExternalProject(proj: protocol.ExternalProject, cleanupAfter: boolean): void; // eslint-disable-line @typescript-eslint/unified-signatures
+ openExternalProject(proj: protocol.ExternalProject, cleanupAfter?: boolean): void {
const existingExternalProject = this.findExternalProjectByProjectName(proj.projectFileName);
- const existingConfiguredProjects = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName);
-
let configuredProjects: Set | undefined;
let rootFiles: protocol.ExternalFile[] = [];
for (const file of proj.rootFiles) {
@@ -4559,16 +4810,11 @@ export class ProjectService {
let project = this.findConfiguredProjectByProjectName(normalized);
if (!project) {
// errors are stored in the project, do not need to update the graph
- project = this.getHostPreferences().lazyConfiguredProjectsFromExternalProject ?
- this.createConfiguredProjectWithDelayLoad(normalized, `Creating configured project in external project: ${proj.projectFileName}`) :
- this.createLoadAndUpdateConfiguredProject(normalized, `Creating configured project in external project: ${proj.projectFileName}`);
- }
- if (!existingConfiguredProjects?.has(project)) {
- // keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project
- project.addExternalProjectReference();
+ project = this.createConfiguredProject(normalized, `Creating configured project in external project: ${proj.projectFileName}`);
+ if (!this.getHostPreferences().lazyConfiguredProjectsFromExternalProject) project.updateGraph();
}
(configuredProjects ??= new Set()).add(project);
- existingConfiguredProjects?.delete(project);
+ Debug.assert(!project.isClosed()); // Should not have closed project
}
}
else {
@@ -4619,10 +4865,13 @@ export class ProjectService {
}
}
- // Remove unused configured projects
- this.closeConfiguredProjectReferencedFromExternalProject(existingConfiguredProjects);
-
- if (print) this.printProjects();
+ if (cleanupAfter) {
+ this.cleanupConfiguredProjects(
+ configuredProjects,
+ new Set(proj.projectFileName),
+ );
+ this.printProjects();
+ }
}
hasDeferredExtension() {
diff --git a/src/server/moduleSpecifierCache.ts b/src/server/moduleSpecifierCache.ts
index fd5d74fcd861e..73e1168afd2f6 100644
--- a/src/server/moduleSpecifierCache.ts
+++ b/src/server/moduleSpecifierCache.ts
@@ -9,7 +9,7 @@ import {
Path,
ResolvedModuleSpecifierInfo,
UserPreferences,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export interface ModuleSpecifierResolutionCacheHost {
@@ -27,8 +27,8 @@ export function createModuleSpecifierCache(host: ModuleSpecifierResolutionCacheH
if (!cache || currentKey !== key(fromFileName, preferences, options)) return undefined;
return cache.get(toFileName);
},
- set(fromFileName, toFileName, preferences, options, modulePaths, moduleSpecifiers) {
- ensureCache(fromFileName, preferences, options).set(toFileName, createInfo(modulePaths, moduleSpecifiers, /*isBlockedByPackageJsonDependencies*/ false));
+ set(fromFileName, toFileName, preferences, options, kind, modulePaths, moduleSpecifiers) {
+ ensureCache(fromFileName, preferences, options).set(toFileName, createInfo(kind, modulePaths, moduleSpecifiers, /*isBlockedByPackageJsonDependencies*/ false));
// If any module specifiers were generated based off paths in node_modules,
// a package.json file in that package was read and is an input to the cached.
@@ -58,7 +58,7 @@ export function createModuleSpecifierCache(host: ModuleSpecifierResolutionCacheH
info.modulePaths = modulePaths;
}
else {
- cache.set(toFileName, createInfo(modulePaths, /*moduleSpecifiers*/ undefined, /*isBlockedByPackageJsonDependencies*/ undefined));
+ cache.set(toFileName, createInfo(/*kind*/ undefined, modulePaths, /*moduleSpecifiers*/ undefined, /*isBlockedByPackageJsonDependencies*/ undefined));
}
},
setBlockedByPackageJsonDependencies(fromFileName, toFileName, preferences, options, isBlockedByPackageJsonDependencies) {
@@ -68,7 +68,7 @@ export function createModuleSpecifierCache(host: ModuleSpecifierResolutionCacheH
info.isBlockedByPackageJsonDependencies = isBlockedByPackageJsonDependencies;
}
else {
- cache.set(toFileName, createInfo(/*modulePaths*/ undefined, /*moduleSpecifiers*/ undefined, isBlockedByPackageJsonDependencies));
+ cache.set(toFileName, createInfo(/*kind*/ undefined, /*modulePaths*/ undefined, /*moduleSpecifiers*/ undefined, isBlockedByPackageJsonDependencies));
}
},
clear() {
@@ -100,10 +100,11 @@ export function createModuleSpecifierCache(host: ModuleSpecifierResolutionCacheH
}
function createInfo(
+ kind: ResolvedModuleSpecifierInfo["kind"] | undefined,
modulePaths: readonly ModulePath[] | undefined,
moduleSpecifiers: readonly string[] | undefined,
isBlockedByPackageJsonDependencies: boolean | undefined,
): ResolvedModuleSpecifierInfo {
- return { modulePaths, moduleSpecifiers, isBlockedByPackageJsonDependencies };
+ return { kind, modulePaths, moduleSpecifiers, isBlockedByPackageJsonDependencies };
}
}
diff --git a/src/server/packageJsonCache.ts b/src/server/packageJsonCache.ts
index 522bf0933d16e..e525d6b7b4a7e 100644
--- a/src/server/packageJsonCache.ts
+++ b/src/server/packageJsonCache.ts
@@ -8,8 +8,8 @@ import {
ProjectPackageJsonInfo,
Ternary,
tryFileExists,
-} from "./_namespaces/ts";
-import { ProjectService } from "./_namespaces/ts.server";
+} from "./_namespaces/ts.js";
+import { ProjectService } from "./_namespaces/ts.server.js";
/** @internal */
export interface PackageJsonCache {
diff --git a/src/server/project.ts b/src/server/project.ts
index db1e5307f74c4..d4c519614be56 100644
--- a/src/server/project.ts
+++ b/src/server/project.ts
@@ -1,4 +1,4 @@
-import * as ts from "./_namespaces/ts";
+import * as ts from "./_namespaces/ts.js";
import {
addRange,
append,
@@ -88,7 +88,6 @@ import {
noopFileWatcher,
normalizePath,
normalizeSlashes,
- orderedRemoveItem,
PackageJsonAutoImportPreference,
PackageJsonInfo,
ParsedCommandLine,
@@ -133,7 +132,7 @@ import {
WatchDirectoryFlags,
WatchOptions,
WatchType,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
ActionInvalidate,
asNormalizedPath,
@@ -141,15 +140,12 @@ import {
emptyArray,
Errors,
FileStats,
- forEachResolvedProjectReferenceProject,
LogLevel,
ModuleImportResult,
Msg,
NormalizedPath,
PackageJsonWatcher,
- projectContainsInfoDirectly,
ProjectOptions,
- ProjectReferenceProjectLoadKind,
ProjectService,
ScriptInfo,
ServerHost,
@@ -157,8 +153,8 @@ import {
toNormalizedPath,
TypingsCache,
updateProjectIfDirty,
-} from "./_namespaces/ts.server";
-import * as protocol from "./protocol";
+} from "./_namespaces/ts.server.js";
+import * as protocol from "./protocol.js";
export enum ProjectKind {
Inferred,
@@ -312,8 +308,7 @@ const enum TypingWatcherType {
type TypingWatchers = Map & { isInvoked?: boolean; };
export abstract class Project implements LanguageServiceHost, ModuleResolutionHost {
- private rootFiles: ScriptInfo[] = [];
- private rootFilesMap = new Map();
+ private rootFilesMap = new Map();
private program: Program | undefined;
private externalFiles: SortedReadonlyArray | undefined;
private missingFilesMap: Map | undefined;
@@ -644,7 +639,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
}
getScriptFileNames() {
- if (!this.rootFiles) {
+ if (!this.rootFilesMap.size) {
return ts.emptyArray;
}
@@ -670,7 +665,6 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
const existingValue = this.rootFilesMap.get(scriptInfo.path);
if (existingValue && existingValue.info !== scriptInfo) {
// This was missing path earlier but now the file exists. Update the root
- this.rootFiles.push(scriptInfo);
existingValue.info = scriptInfo;
}
scriptInfo.attachToProject(this);
@@ -1082,12 +1076,9 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
// Release external files
forEach(this.externalFiles, externalFile => this.detachScriptInfoIfNotRoot(externalFile));
// Always remove root files from the project
- for (const root of this.rootFiles) {
- root.detachFromProject(this);
- }
+ this.rootFilesMap.forEach(root => root.info?.detachFromProject(this));
this.projectService.pendingEnsureProjectForOpenFiles = true;
- this.rootFiles = undefined!;
this.rootFilesMap = undefined!;
this.externalFiles = undefined;
this.program = undefined;
@@ -1138,11 +1129,11 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
}
isClosed() {
- return this.rootFiles === undefined;
+ return this.rootFilesMap === undefined;
}
hasRoots() {
- return this.rootFiles && this.rootFiles.length > 0;
+ return !!this.rootFilesMap?.size;
}
/** @internal */
@@ -1150,8 +1141,8 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
return false;
}
- getRootFiles() {
- return this.rootFiles && this.rootFiles.map(info => info.fileName);
+ getRootFiles(): NormalizedPath[] {
+ return this.rootFilesMap && arrayFrom(ts.mapDefinedIterator(this.rootFilesMap.values(), value => value.info?.fileName));
}
/** @internal */
@@ -1160,13 +1151,13 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
}
getRootScriptInfos() {
- return this.rootFiles;
+ return arrayFrom(ts.mapDefinedIterator(this.rootFilesMap.values(), value => value.info));
}
getScriptInfos(): ScriptInfo[] {
if (!this.languageServiceEnabled) {
// if language service is not enabled - return just root files
- return this.rootFiles;
+ return this.getRootScriptInfos();
}
return map(this.program!.getSourceFiles(), sourceFile => {
const scriptInfo = this.projectService.getScriptInfoForPath(sourceFile.resolvedPath);
@@ -1259,13 +1250,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
}
isRoot(info: ScriptInfo) {
- return this.rootFilesMap && this.rootFilesMap.get(info.path)?.info === info;
+ return this.rootFilesMap?.get(info.path)?.info === info;
}
// add a root file to project
addRoot(info: ScriptInfo, fileName?: NormalizedPath) {
Debug.assert(!this.isRoot(info));
- this.rootFiles.push(info);
this.rootFilesMap.set(info.path, { fileName: fileName || info.fileName, info });
info.attachToProject(this);
@@ -1589,6 +1579,16 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
});
}
+ // Update roots
+ this.rootFilesMap.forEach((value, path) => {
+ const file = this.program!.getSourceFileByPath(path);
+ const info = value.info;
+ if (!file || value.info?.path === file.resolvedPath) return;
+ value.info = this.projectService.getScriptInfo(file.fileName)!;
+ Debug.assert(value.info.isAttached(this));
+ info?.detachFromProject(this);
+ });
+
// Update the missing file paths watcher
updateMissingFilePathsWatch(
this.program,
@@ -2009,7 +2009,6 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
// remove a root file from project
protected removeRoot(info: ScriptInfo): void {
- orderedRemoveItem(this.rootFiles, info);
this.rootFilesMap.delete(info.path);
}
@@ -2211,7 +2210,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
private isDefaultProjectForOpenFiles(): boolean {
return !!forEachEntry(
this.projectService.openFiles,
- (_, fileName) => this.projectService.tryGetDefaultProjectForFile(toNormalizedPath(fileName)) === this,
+ (_projectRootPath, path) => this.projectService.tryGetDefaultProjectForFile(this.projectService.getScriptInfoForPath(path)!) === this,
);
}
@@ -2238,6 +2237,18 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
return this.noDtsResolutionProject;
}
+ /** @internal */
+ runWithTemporaryFileUpdate(rootFile: string, updatedText: string, cb: (updatedProgram: Program, originalProgram: Program | undefined, updatedFile: SourceFile) => void) {
+ const originalProgram = this.program;
+ const rootSourceFile = Debug.checkDefined(this.program?.getSourceFile(rootFile), "Expected file to be part of program");
+ const originalText = Debug.checkDefined(rootSourceFile.getText());
+
+ this.getScriptInfo(rootFile)?.editContent(0, originalText.length, updatedText);
+ this.updateGraph();
+ cb(this.program!, originalProgram, (this.program?.getSourceFile(rootFile))!);
+ this.getScriptInfo(rootFile)?.editContent(0, this.program!.getSourceFile(rootFile)!.getText().length, originalText);
+ }
+
/** @internal */
private getCompilerOptionsForNoDtsResolutionProject() {
return {
@@ -2376,7 +2387,7 @@ export class InferredProject extends Project {
}
override removeRoot(info: ScriptInfo) {
- this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info);
+ this.projectService.stopWatchingConfigFilesForScriptInfo(info);
super.removeRoot(info);
// Delay toggling to isJsInferredProject = false till we actually need it again
if (!this.isOrphan() && this._isJsInferredProject && info.isJavaScript()) {
@@ -2400,7 +2411,7 @@ export class InferredProject extends Project {
}
override close() {
- forEach(this.getRootScriptInfos(), info => this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info));
+ forEach(this.getRootScriptInfos(), info => this.projectService.stopWatchingConfigFilesForScriptInfo(info));
super.close();
}
@@ -2741,7 +2752,7 @@ export class AutoImportProviderProject extends Project {
*/
export class ConfiguredProject extends Project {
/** @internal */
- pendingUpdateLevel: ProgramUpdateLevel | undefined;
+ pendingUpdateLevel: ProgramUpdateLevel;
/** @internal */
pendingUpdateReason: string | undefined;
@@ -2751,9 +2762,6 @@ export class ConfiguredProject extends Project {
/** @internal */
canConfigFileJsonReportNoInputFiles = false;
- /** Ref count to the project when opened from external project */
- private externalProjectRefCount = 0;
-
private projectReferences: readonly ProjectReference[] | undefined;
/**
@@ -2776,10 +2784,10 @@ export class ConfiguredProject extends Project {
private compilerHost?: CompilerHost;
/** @internal */
- hasConfigFileDiagnostics?: boolean;
+ configDiagDiagnosticsReported?: number;
/** @internal */
- skipConfigDiagEvent?: true;
+ triggerFileForConfigFileDiag?: NormalizedPath;
/** @internal */
deferredClose?: boolean;
@@ -2791,8 +2799,11 @@ export class ConfiguredProject extends Project {
projectService: ProjectService,
documentRegistry: DocumentRegistry,
cachedDirectoryStructureHost: CachedDirectoryStructureHost,
+ pendingUpdateReason: string,
) {
super(configFileName, ProjectKind.Configured, projectService, documentRegistry, /*hasExplicitListOfFiles*/ false, /*lastFileExceededProgramSize*/ undefined, /*compilerOptions*/ {}, /*compileOnSaveEnabled*/ false, /*watchOptions*/ undefined, cachedDirectoryStructureHost, getDirectoryPath(configFileName));
+ this.pendingUpdateLevel = ProgramUpdateLevel.Full;
+ this.pendingUpdateReason = pendingUpdateReason;
}
/** @internal */
@@ -2845,7 +2856,7 @@ export class ConfiguredProject extends Project {
*/
override updateGraph(): boolean {
if (this.deferredClose) return false;
- const isInitialLoad = this.isInitialLoadPending();
+ const isDirty = this.dirty;
this.isInitialLoadPending = returnFalse;
const updateLevel = this.pendingUpdateLevel;
this.pendingUpdateLevel = ProgramUpdateLevel.Update;
@@ -2858,8 +2869,7 @@ export class ConfiguredProject extends Project {
case ProgramUpdateLevel.Full:
this.openFileWatchTriggered.clear();
const reason = Debug.checkDefined(this.pendingUpdateReason);
- this.pendingUpdateReason = undefined;
- this.projectService.reloadConfiguredProject(this, reason, isInitialLoad, /*clearSemanticCache*/ false);
+ this.projectService.reloadConfiguredProject(this, reason);
result = true;
break;
default:
@@ -2868,8 +2878,21 @@ 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);
+ if (
+ updateLevel === ProgramUpdateLevel.Full || ( // Already sent event through reload
+ result && ( // Not new program
+ !isDirty ||
+ !this.triggerFileForConfigFileDiag ||
+ this.getCurrentProgram()!.structureIsReused === StructureIsReused.Completely
+ )
+ )
+ ) {
+ // Dont send the configFileDiag
+ this.triggerFileForConfigFileDiag = undefined;
+ }
+ else if (!this.triggerFileForConfigFileDiag) {
+ // If we arent tracking to send configFileDiag, send event if diagnostics presence has changed
+ this.projectService.sendConfigFileDiagEvent(this, /*triggerFile*/ undefined, /*force*/ false);
}
return result;
}
@@ -2970,91 +2993,17 @@ export class ConfiguredProject extends Project {
super.markAsDirty();
}
- /** @internal */
- addExternalProjectReference() {
- this.externalProjectRefCount++;
- }
-
- /** @internal */
- deleteExternalProjectReference() {
- this.externalProjectRefCount--;
- }
-
/** @internal */
isSolution() {
return this.getRootFilesMap().size === 0 &&
!this.canConfigFileJsonReportNoInputFiles;
}
- /**
- * Find the configured project from the project references in project which contains the info directly
- *
- * @internal
- */
- getDefaultChildProjectFromProjectWithReferences(info: ScriptInfo) {
- return forEachResolvedProjectReferenceProject(
- this,
- info.path,
- child =>
- projectContainsInfoDirectly(child, info) ?
- child :
- undefined,
- ProjectReferenceProjectLoadKind.Find,
- );
- }
-
- /**
- * Returns true if the project is needed by any of the open script info/external project
- *
- * @internal
- */
- hasOpenRef() {
- if (!!this.externalProjectRefCount) {
- return true;
- }
-
- // Closed project doesnt have any reference
- if (this.isClosed()) {
- return false;
- }
-
- 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
- // In that case keep the project alive if there are open files impacted by this project
- return !!configFileExistenceInfo.openFilesImpactedByConfigFile?.size;
- }
-
- // If there is no pending update for this project,
- // We know exact set of open files that get impacted by this configured project as the files in the project
- // The project is referenced only if open files impacted by this project are present in this project
- return !!configFileExistenceInfo.openFilesImpactedByConfigFile && forEachEntry(
- configFileExistenceInfo.openFilesImpactedByConfigFile,
- (_value, infoPath) => {
- const info = this.projectService.getScriptInfoForPath(infoPath)!;
- return this.containsScriptInfo(info) ||
- !!forEachResolvedProjectReferenceProject(
- this,
- info.path,
- child => child.containsScriptInfo(info),
- ProjectReferenceProjectLoadKind.Find,
- );
- },
- ) || false;
- }
-
/** @internal */
override isOrphan(): boolean {
return !!this.deferredClose;
}
- /** @internal */
- hasExternalProjectRef() {
- return !!this.externalProjectRefCount;
- }
-
getEffectiveTypeRoots() {
return getEffectiveTypeRoots(this.getCompilationSettings(), this) || [];
}
diff --git a/src/server/protocol.ts b/src/server/protocol.ts
index b27fb4d5c3dc1..d12c97bdebc32 100644
--- a/src/server/protocol.ts
+++ b/src/server/protocol.ts
@@ -1,4 +1,4 @@
-import type * as ts from "./_namespaces/ts";
+import type * as ts from "./_namespaces/ts.js";
import type {
ApplicableRefactorInfo,
CompilerOptionsValue,
@@ -6,13 +6,21 @@ import type {
EndOfLineState,
FileExtensionInfo,
HighlightSpanKind,
+ InlayHintKind,
InteractiveRefactorArguments,
OutputFile,
+ RefactorActionInfo,
RefactorTriggerReason,
RenameInfoFailure,
RenameLocation,
ScriptElementKind,
ScriptKind,
+ SignatureHelpCharacterTypedReason,
+ SignatureHelpInvokedReason,
+ SignatureHelpParameter,
+ SignatureHelpRetriggerCharacter,
+ SignatureHelpRetriggeredReason,
+ SignatureHelpTriggerCharacter,
SignatureHelpTriggerReason,
SymbolDisplayPart,
TextChange,
@@ -21,16 +29,16 @@ import type {
TodoCommentDescriptor,
TypeAcquisition,
UserPreferences,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
ClassificationType,
CompletionTriggerKind,
OrganizeImportsMode,
SemicolonPreference,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
// These types/enums used to be defined in duplicate here and exported. They are re-exported to avoid breaking changes.
-export { ApplicableRefactorInfo, ClassificationType, CompletionsTriggerCharacter, CompletionTriggerKind, OrganizeImportsMode, RefactorTriggerReason, RenameInfoFailure, SemicolonPreference, SignatureHelpTriggerReason, SymbolDisplayPart, UserPreferences };
+export { ApplicableRefactorInfo, ClassificationType, CompletionsTriggerCharacter, CompletionTriggerKind, InlayHintKind, OrganizeImportsMode, RefactorActionInfo, RefactorTriggerReason, RenameInfoFailure, SemicolonPreference, SignatureHelpCharacterTypedReason, SignatureHelpInvokedReason, SignatureHelpParameter, SignatureHelpRetriggerCharacter, SignatureHelpRetriggeredReason, SignatureHelpTriggerCharacter, SignatureHelpTriggerReason, SymbolDisplayPart, UserPreferences };
type ChangeStringIndexSignature = { [K in keyof T]: string extends K ? NewStringIndexSignatureType : T[K]; };
type ChangePropertyTypes = {
@@ -161,6 +169,7 @@ export const enum CommandTypes {
GetApplicableRefactors = "getApplicableRefactors",
GetEditsForRefactor = "getEditsForRefactor",
GetMoveToRefactoringFileSuggestions = "getMoveToRefactoringFileSuggestions",
+ GetPasteEdits = "getPasteEdits",
/** @internal */
GetEditsForRefactorFull = "getEditsForRefactor-full",
@@ -191,6 +200,7 @@ export const enum CommandTypes {
ProvideCallHierarchyOutgoingCalls = "provideCallHierarchyOutgoingCalls",
ProvideInlayHints = "provideInlayHints",
WatchChange = "watchChange",
+ MapCode = "mapCode",
}
/**
@@ -625,6 +635,35 @@ export interface GetMoveToRefactoringFileSuggestions extends Response {
};
}
+/**
+ * Request refactorings at a given position post pasting text from some other location.
+ */
+
+export interface GetPasteEditsRequest extends Request {
+ command: CommandTypes.GetPasteEdits;
+ arguments: GetPasteEditsRequestArgs;
+}
+
+export interface GetPasteEditsRequestArgs extends FileRequestArgs {
+ /** The text that gets pasted in a file. */
+ pastedText: string[];
+ /** Locations of where the `pastedText` gets added in a file. If the length of the `pastedText` and `pastedLocations` are not the same,
+ * then the `pastedText` is combined into one and added at all the `pastedLocations`.
+ */
+ pasteLocations: TextSpan[];
+ /** The source location of each `pastedText`. If present, the length of `spans` must be equal to the length of `pastedText`. */
+ copiedFrom?: { file: string; spans: TextSpan[]; };
+}
+
+export interface GetPasteEditsResponse extends Response {
+ body: PasteEditsAction;
+}
+
+export interface PasteEditsAction {
+ edits: FileCodeEdits[];
+ fixId?: {};
+}
+
export interface GetEditsForRefactorRequest extends Request {
command: CommandTypes.GetEditsForRefactor;
arguments: GetEditsForRefactorRequestArgs;
@@ -2304,6 +2343,38 @@ export interface InlayHintsResponse extends Response {
body?: InlayHintItem[];
}
+export interface MapCodeRequestArgs extends FileRequestArgs {
+ /**
+ * The files and changes to try and apply/map.
+ */
+ mapping: MapCodeRequestDocumentMapping;
+}
+
+export interface MapCodeRequestDocumentMapping {
+ /**
+ * The specific code to map/insert/replace in the file.
+ */
+ contents: string[];
+
+ /**
+ * Areas of "focus" to inform the code mapper with. For example, cursor
+ * location, current selection, viewport, etc. Nested arrays denote
+ * priority: toplevel arrays are more important than inner arrays, and
+ * inner array priorities are based on items within that array. Items
+ * earlier in the arrays have higher priority.
+ */
+ focusLocations?: TextSpan[][];
+}
+
+export interface MapCodeRequest extends FileRequest {
+ command: CommandTypes.MapCode;
+ arguments: MapCodeRequestArgs;
+}
+
+export interface MapCodeResponse extends Response {
+ body: readonly FileCodeEdits[];
+}
+
/**
* Synchronous request for semantic diagnostics of one file.
*/
diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts
index 42a0ba4782c9e..eaeec70784193 100644
--- a/src/server/scriptInfo.ts
+++ b/src/server/scriptInfo.ts
@@ -34,12 +34,11 @@ import {
SourceFile,
SourceFileLike,
TextSpan,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
AbsolutePositionAndLineText,
ConfiguredProject,
Errors,
- ExternalProject,
InferredProject,
isBackgroundProject,
isConfiguredProject,
@@ -51,8 +50,8 @@ import {
Project,
ScriptVersionCache,
ServerHost,
-} from "./_namespaces/ts.server";
-import * as protocol from "./protocol";
+} from "./_namespaces/ts.server.js";
+import * as protocol from "./protocol.js";
/** @internal */
export class TextStorage {
@@ -580,18 +579,16 @@ export class ScriptInfo {
case 0:
return Errors.ThrowNoProject();
case 1:
- return ensurePrimaryProjectKind(
- !isProjectDeferredClose(this.containingProjects[0]) ?
- this.containingProjects[0] : undefined,
- );
+ return isProjectDeferredClose(this.containingProjects[0]) || isBackgroundProject(this.containingProjects[0]) ?
+ Errors.ThrowNoProject() :
+ this.containingProjects[0];
default:
// If this file belongs to multiple projects, below is the order in which default project is used
+ // - first external project
// - for open script info, its default configured project during opening is default if info is part of it
// - first configured project of which script info is not a source of project reference redirect
// - first configured project
- // - first external project
// - first inferred project
- let firstExternalProject: ExternalProject | undefined;
let firstConfiguredProject: ConfiguredProject | undefined;
let firstInferredProject: InferredProject | undefined;
let firstNonSourceOfProjectReferenceRedirect: ConfiguredProject | undefined;
@@ -614,20 +611,17 @@ export class ScriptInfo {
}
if (!firstConfiguredProject) firstConfiguredProject = project;
}
- else if (!firstExternalProject && isExternalProject(project)) {
- firstExternalProject = project;
+ else if (isExternalProject(project)) {
+ return project;
}
else if (!firstInferredProject && isInferredProject(project)) {
firstInferredProject = project;
}
}
- return ensurePrimaryProjectKind(
- defaultConfiguredProject ||
- firstNonSourceOfProjectReferenceRedirect ||
- firstConfiguredProject ||
- firstExternalProject ||
- firstInferredProject,
- );
+ return (defaultConfiguredProject ||
+ firstNonSourceOfProjectReferenceRedirect ||
+ firstConfiguredProject ||
+ firstInferredProject) ?? Errors.ThrowNoProject();
}
}
@@ -742,18 +736,6 @@ export class ScriptInfo {
}
}
-/**
- * Throws an error if `project` is an AutoImportProvider or AuxiliaryProject,
- * which are used in the background by other Projects and should never be
- * reported as the default project for a ScriptInfo.
- */
-function ensurePrimaryProjectKind(project: Project | undefined) {
- if (!project || isBackgroundProject(project)) {
- return Errors.ThrowNoProject();
- }
- return project;
-}
-
function failIfInvalidPosition(position: number) {
Debug.assert(typeof position === "number", `Expected position ${position} to be a number.`);
Debug.assert(position >= 0, `Expected position to be non-negative.`);
diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts
index ecf62c7445f91..306e310f23ee3 100644
--- a/src/server/scriptVersionCache.ts
+++ b/src/server/scriptVersionCache.ts
@@ -8,9 +8,9 @@ import {
TextChangeRange,
TextSpan,
unchangedTextChangeRange,
-} from "./_namespaces/ts";
-import { emptyArray } from "./_namespaces/ts.server";
-import * as protocol from "./protocol";
+} from "./_namespaces/ts.js";
+import { emptyArray } from "./_namespaces/ts.server.js";
+import * as protocol from "./protocol.js";
const lineCollectionCapacity = 4;
diff --git a/src/server/session.ts b/src/server/session.ts
index f05b431aa9260..1d3b34d66f719 100644
--- a/src/server/session.ts
+++ b/src/server/session.ts
@@ -100,6 +100,7 @@ import {
OperationCanceledException,
OrganizeImportsMode,
OutliningSpan,
+ PasteEdits,
Path,
perfLogger,
PerformanceEvent,
@@ -136,7 +137,7 @@ import {
unmangleScopedPackageName,
version,
WithMetadata,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
AuxiliaryProject,
CloseFileWatcherEvent,
@@ -180,8 +181,8 @@ import {
stringifyIndented,
toNormalizedPath,
updateProjectIfDirty,
-} from "./_namespaces/ts.server";
-import * as protocol from "./protocol";
+} from "./_namespaces/ts.server.js";
+import * as protocol from "./protocol.js";
interface StackTraceError extends Error {
stack?: string;
@@ -910,6 +911,7 @@ const invalidPartialSemanticModeCommands: readonly protocol.CommandTypes[] = [
protocol.CommandTypes.PrepareCallHierarchy,
protocol.CommandTypes.ProvideCallHierarchyIncomingCalls,
protocol.CommandTypes.ProvideCallHierarchyOutgoingCalls,
+ protocol.CommandTypes.GetPasteEdits,
];
const invalidSyntacticModeCommands: readonly protocol.CommandTypes[] = [
@@ -1904,6 +1906,26 @@ export class Session implements EventSender {
});
}
+ private mapCode(args: protocol.MapCodeRequestArgs): protocol.FileCodeEdits[] {
+ const formatOptions = this.getHostFormatOptions();
+ const preferences = this.getHostPreferences();
+ const { file, languageService } = this.getFileAndLanguageServiceForSyntacticOperation(args);
+ const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!;
+ const focusLocations = args.mapping.focusLocations?.map(spans => {
+ return spans.map(loc => {
+ const start = scriptInfo.lineOffsetToPosition(loc.start.line, loc.start.offset);
+ const end = scriptInfo.lineOffsetToPosition(loc.end.line, loc.end.offset);
+ return {
+ start,
+ length: end - start,
+ };
+ });
+ });
+
+ const changes = languageService.mapCode(file, args.mapping.contents, focusLocations, formatOptions, preferences);
+ return this.mapTextChangesToCodeEdits(changes);
+ }
+
private setCompilerOptionsForInferredProjects(args: protocol.SetCompilerOptionsForInferredProjectsArgs): void {
this.projectService.setCompilerOptionsForInferredProjects(args.options, args.projectRootPath);
}
@@ -2796,6 +2818,24 @@ export class Session implements EventSender {
return project.getLanguageService().getMoveToRefactoringFileSuggestions(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file));
}
+ private getPasteEdits(args: protocol.GetPasteEditsRequestArgs): protocol.PasteEditsAction | undefined {
+ const { file, project } = this.getFileAndProject(args);
+ const copiedFrom = args.copiedFrom
+ ? { file: args.copiedFrom.file, range: args.copiedFrom.spans.map(copies => this.getRange({ file: args.copiedFrom!.file, startLine: copies.start.line, startOffset: copies.start.offset, endLine: copies.end.line, endOffset: copies.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(args.copiedFrom!.file))!)) }
+ : undefined;
+ const result = project.getLanguageService().getPasteEdits(
+ {
+ targetFile: file,
+ pastedText: args.pastedText,
+ pasteLocations: args.pasteLocations.map(paste => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file)!)),
+ copiedFrom,
+ preferences: this.getPreferences(file),
+ },
+ this.getFormatOptions(file),
+ );
+ return result && this.mapPasteEditsAction(result);
+ }
+
private organizeImports(args: protocol.OrganizeImportsRequestArgs, simplifiedResult: boolean): readonly protocol.FileCodeEdits[] | readonly FileTextChanges[] {
Debug.assert(args.scope.type === "file");
const { file, project } = this.getFileAndProject(args.scope.args);
@@ -2928,6 +2968,10 @@ export class Session implements EventSender {
return { fixName, description, changes: this.mapTextChangesToCodeEdits(changes), commands, fixId, fixAllDescription };
}
+ private mapPasteEditsAction({ edits, fixId }: PasteEdits): protocol.PasteEditsAction {
+ return { edits: this.mapTextChangesToCodeEdits(edits), fixId };
+ }
+
private mapTextChangesToCodeEdits(textChanges: readonly FileTextChanges[]): protocol.FileCodeEdits[] {
return textChanges.map(change => this.mapTextChangeToCodeEdit(change));
}
@@ -3190,7 +3234,7 @@ export class Session implements EventSender {
return this.requiredResponse(response);
},
[protocol.CommandTypes.OpenExternalProject]: (request: protocol.OpenExternalProjectRequest) => {
- this.projectService.openExternalProject(request.arguments, /*print*/ true);
+ this.projectService.openExternalProject(request.arguments, /*cleanupAfter*/ true);
// TODO: GH#20447 report errors
return this.requiredResponse(/*response*/ true);
},
@@ -3200,7 +3244,7 @@ export class Session implements EventSender {
return this.requiredResponse(/*response*/ true);
},
[protocol.CommandTypes.CloseExternalProject]: (request: protocol.CloseExternalProjectRequest) => {
- this.projectService.closeExternalProject(request.arguments.projectFileName, /*print*/ true);
+ this.projectService.closeExternalProject(request.arguments.projectFileName, /*cleanupAfter*/ true);
// TODO: GH#20447 report errors
return this.requiredResponse(/*response*/ true);
},
@@ -3521,6 +3565,9 @@ export class Session implements EventSender {
[protocol.CommandTypes.GetMoveToRefactoringFileSuggestions]: (request: protocol.GetMoveToRefactoringFileSuggestionsRequest) => {
return this.requiredResponse(this.getMoveToRefactoringFileSuggestions(request.arguments));
},
+ [protocol.CommandTypes.GetPasteEdits]: (request: protocol.GetPasteEditsRequest) => {
+ return this.requiredResponse(this.getPasteEdits(request.arguments));
+ },
[protocol.CommandTypes.GetEditsForRefactorFull]: (request: protocol.GetEditsForRefactorRequest) => {
return this.requiredResponse(this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ false));
},
@@ -3583,6 +3630,9 @@ export class Session implements EventSender {
[protocol.CommandTypes.ProvideInlayHints]: (request: protocol.InlayHintsRequest) => {
return this.requiredResponse(this.provideInlayHints(request.arguments));
},
+ [protocol.CommandTypes.MapCode]: (request: protocol.MapCodeRequest) => {
+ return this.requiredResponse(this.mapCode(request.arguments));
+ },
}));
public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse) {
diff --git a/src/server/types.ts b/src/server/types.ts
index 4a6aa56f7fb46..1ab26e0f20cf9 100644
--- a/src/server/types.ts
+++ b/src/server/types.ts
@@ -4,7 +4,7 @@ import {
FileWatcherCallback,
System,
WatchOptions,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export interface CompressedData {
length: number;
diff --git a/src/server/typingInstallerAdapter.ts b/src/server/typingInstallerAdapter.ts
index 9470a17c0496e..5f8e90b7f837d 100644
--- a/src/server/typingInstallerAdapter.ts
+++ b/src/server/typingInstallerAdapter.ts
@@ -8,7 +8,7 @@ import {
server,
SortedReadonlyArray,
TypeAcquisition,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
ActionInvalidate,
ActionPackageInstalled,
@@ -39,7 +39,7 @@ import {
stringifyIndented,
TypesRegistryResponse,
TypingInstallerRequestUnion,
-} from "./_namespaces/ts.server";
+} from "./_namespaces/ts.server.js";
/** @internal */
export interface TypingsInstallerWorkerProcess {
diff --git a/src/server/typingsCache.ts b/src/server/typingsCache.ts
index 726006c6cdf6e..daa3737344011 100644
--- a/src/server/typingsCache.ts
+++ b/src/server/typingsCache.ts
@@ -11,12 +11,12 @@ import {
sort,
SortedReadonlyArray,
TypeAcquisition,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
emptyArray,
Project,
ProjectService,
-} from "./_namespaces/ts.server";
+} from "./_namespaces/ts.server.js";
export interface InstallPackageOptionsWithProject extends InstallPackageOptions {
projectName: string;
diff --git a/src/server/utilities.ts b/src/server/utilities.ts
index 088a2f9f16684..012270f5d14ad 100644
--- a/src/server/utilities.ts
+++ b/src/server/utilities.ts
@@ -5,13 +5,13 @@ import {
identity,
perfLogger,
SortedArray,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
Logger,
LogLevel,
NormalizedPath,
ServerHost,
-} from "./_namespaces/ts.server";
+} from "./_namespaces/ts.server.js";
/** @internal */
export class ThrottledOperations {
diff --git a/src/server/utilitiesPublic.ts b/src/server/utilitiesPublic.ts
index ac8e0f3c131c3..c0ce5dfea1295 100644
--- a/src/server/utilitiesPublic.ts
+++ b/src/server/utilitiesPublic.ts
@@ -6,11 +6,11 @@ import {
SortedArray,
SortedReadonlyArray,
TypeAcquisition,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
import {
DiscoverTypings,
Project,
-} from "./_namespaces/ts.server";
+} from "./_namespaces/ts.server.js";
export enum LogLevel {
terse,
diff --git a/src/services/_namespaces/ts.BreakpointResolver.ts b/src/services/_namespaces/ts.BreakpointResolver.ts
index 25d68e38408d2..4e74d10c32023 100644
--- a/src/services/_namespaces/ts.BreakpointResolver.ts
+++ b/src/services/_namespaces/ts.BreakpointResolver.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.BreakpointResolver namespace. */
-export * from "../breakpoints";
+export * from "../breakpoints.js";
diff --git a/src/services/_namespaces/ts.CallHierarchy.ts b/src/services/_namespaces/ts.CallHierarchy.ts
index 412260c0935f4..b1055790b5bdc 100644
--- a/src/services/_namespaces/ts.CallHierarchy.ts
+++ b/src/services/_namespaces/ts.CallHierarchy.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.CallHierarchy namespace. */
-export * from "../callHierarchy";
+export * from "../callHierarchy.js";
diff --git a/src/services/_namespaces/ts.Completions.StringCompletions.ts b/src/services/_namespaces/ts.Completions.StringCompletions.ts
index 23e0c06c32ffd..144208dacca1c 100644
--- a/src/services/_namespaces/ts.Completions.StringCompletions.ts
+++ b/src/services/_namespaces/ts.Completions.StringCompletions.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.Completions.StringCompletions namespace. */
-export * from "../stringCompletions";
+export * from "../stringCompletions.js";
diff --git a/src/services/_namespaces/ts.Completions.ts b/src/services/_namespaces/ts.Completions.ts
index bd0d6a8522511..0a644a6391168 100644
--- a/src/services/_namespaces/ts.Completions.ts
+++ b/src/services/_namespaces/ts.Completions.ts
@@ -1,5 +1,5 @@
/* Generated file to emulate the ts.Completions namespace. */
-export * from "../completions";
-import * as StringCompletions from "./ts.Completions.StringCompletions";
+export * from "../completions.js";
+import * as StringCompletions from "./ts.Completions.StringCompletions.js";
export { StringCompletions };
diff --git a/src/services/_namespaces/ts.FindAllReferences.ts b/src/services/_namespaces/ts.FindAllReferences.ts
index a5325a82f0cc4..76f8567e81465 100644
--- a/src/services/_namespaces/ts.FindAllReferences.ts
+++ b/src/services/_namespaces/ts.FindAllReferences.ts
@@ -1,4 +1,4 @@
/* Generated file to emulate the ts.FindAllReferences namespace. */
-export * from "../importTracker";
-export * from "../findAllReferences";
+export * from "../importTracker.js";
+export * from "../findAllReferences.js";
diff --git a/src/services/_namespaces/ts.GoToDefinition.ts b/src/services/_namespaces/ts.GoToDefinition.ts
index 41c12c0d1f1dc..04a5f473c4119 100644
--- a/src/services/_namespaces/ts.GoToDefinition.ts
+++ b/src/services/_namespaces/ts.GoToDefinition.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.GoToDefinition namespace. */
-export * from "../goToDefinition";
+export * from "../goToDefinition.js";
diff --git a/src/services/_namespaces/ts.InlayHints.ts b/src/services/_namespaces/ts.InlayHints.ts
index fd189d5732578..920473f13537d 100644
--- a/src/services/_namespaces/ts.InlayHints.ts
+++ b/src/services/_namespaces/ts.InlayHints.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.InlayHints namespace. */
-export * from "../inlayHints";
+export * from "../inlayHints.js";
diff --git a/src/services/_namespaces/ts.JsDoc.ts b/src/services/_namespaces/ts.JsDoc.ts
index 1572df70c3b20..e283c34ba63d6 100644
--- a/src/services/_namespaces/ts.JsDoc.ts
+++ b/src/services/_namespaces/ts.JsDoc.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.JsDoc namespace. */
-export * from "../jsDoc";
+export * from "../jsDoc.js";
diff --git a/src/services/_namespaces/ts.MapCode.ts b/src/services/_namespaces/ts.MapCode.ts
new file mode 100644
index 0000000000000..1ef9ddd0f1283
--- /dev/null
+++ b/src/services/_namespaces/ts.MapCode.ts
@@ -0,0 +1,3 @@
+/* Generated file to emulate the ts.MapCode namespace. */
+
+export * from "../mapCode.js";
diff --git a/src/services/_namespaces/ts.NavigateTo.ts b/src/services/_namespaces/ts.NavigateTo.ts
index cf0e35ad1cf1c..ba6ef9d35f665 100644
--- a/src/services/_namespaces/ts.NavigateTo.ts
+++ b/src/services/_namespaces/ts.NavigateTo.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.NavigateTo namespace. */
-export * from "../navigateTo";
+export * from "../navigateTo.js";
diff --git a/src/services/_namespaces/ts.NavigationBar.ts b/src/services/_namespaces/ts.NavigationBar.ts
index ad1c32d373d63..46d2b628078d2 100644
--- a/src/services/_namespaces/ts.NavigationBar.ts
+++ b/src/services/_namespaces/ts.NavigationBar.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.NavigationBar namespace. */
-export * from "../navigationBar";
+export * from "../navigationBar.js";
diff --git a/src/services/_namespaces/ts.OrganizeImports.ts b/src/services/_namespaces/ts.OrganizeImports.ts
index 1a338fc8e12b1..f5f2c3e495954 100644
--- a/src/services/_namespaces/ts.OrganizeImports.ts
+++ b/src/services/_namespaces/ts.OrganizeImports.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.OrganizeImports namespace. */
-export * from "../organizeImports";
+export * from "../organizeImports.js";
diff --git a/src/services/_namespaces/ts.OutliningElementsCollector.ts b/src/services/_namespaces/ts.OutliningElementsCollector.ts
index b6b05f8f6772e..960464818a40d 100644
--- a/src/services/_namespaces/ts.OutliningElementsCollector.ts
+++ b/src/services/_namespaces/ts.OutliningElementsCollector.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.OutliningElementsCollector namespace. */
-export * from "../outliningElementsCollector";
+export * from "../outliningElementsCollector.js";
diff --git a/src/services/_namespaces/ts.PasteEdits.ts b/src/services/_namespaces/ts.PasteEdits.ts
new file mode 100644
index 0000000000000..b9a30dec6f501
--- /dev/null
+++ b/src/services/_namespaces/ts.PasteEdits.ts
@@ -0,0 +1 @@
+export * from "../pasteEdits.js";
diff --git a/src/services/_namespaces/ts.Rename.ts b/src/services/_namespaces/ts.Rename.ts
index e587684f8e689..de87aac59ebf3 100644
--- a/src/services/_namespaces/ts.Rename.ts
+++ b/src/services/_namespaces/ts.Rename.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.Rename namespace. */
-export * from "../rename";
+export * from "../rename.js";
diff --git a/src/services/_namespaces/ts.SignatureHelp.ts b/src/services/_namespaces/ts.SignatureHelp.ts
index c87bf5c7e8d14..592b993aab81b 100644
--- a/src/services/_namespaces/ts.SignatureHelp.ts
+++ b/src/services/_namespaces/ts.SignatureHelp.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.SignatureHelp namespace. */
-export * from "../signatureHelp";
+export * from "../signatureHelp.js";
diff --git a/src/services/_namespaces/ts.SmartSelectionRange.ts b/src/services/_namespaces/ts.SmartSelectionRange.ts
index f90161430d9b0..1e14c3b606ec9 100644
--- a/src/services/_namespaces/ts.SmartSelectionRange.ts
+++ b/src/services/_namespaces/ts.SmartSelectionRange.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.SmartSelectionRange namespace. */
-export * from "../smartSelection";
+export * from "../smartSelection.js";
diff --git a/src/services/_namespaces/ts.SymbolDisplay.ts b/src/services/_namespaces/ts.SymbolDisplay.ts
index fcb8050c44372..851401ae7f32e 100644
--- a/src/services/_namespaces/ts.SymbolDisplay.ts
+++ b/src/services/_namespaces/ts.SymbolDisplay.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.SymbolDisplay namespace. */
-export * from "../symbolDisplay";
+export * from "../symbolDisplay.js";
diff --git a/src/services/_namespaces/ts.classifier.ts b/src/services/_namespaces/ts.classifier.ts
index 34bc4e52196cc..fda72f72284f1 100644
--- a/src/services/_namespaces/ts.classifier.ts
+++ b/src/services/_namespaces/ts.classifier.ts
@@ -1,4 +1,4 @@
/* Generated file to emulate the ts.classifier namespace. */
-import * as v2020 from "./ts.classifier.v2020";
+import * as v2020 from "./ts.classifier.v2020.js";
export { v2020 };
diff --git a/src/services/_namespaces/ts.classifier.v2020.ts b/src/services/_namespaces/ts.classifier.v2020.ts
index 361c15f82351b..c4410e139a621 100644
--- a/src/services/_namespaces/ts.classifier.v2020.ts
+++ b/src/services/_namespaces/ts.classifier.v2020.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.classifier.v2020 namespace. */
-export * from "../classifier2020";
+export * from "../classifier2020.js";
diff --git a/src/services/_namespaces/ts.codefix.ts b/src/services/_namespaces/ts.codefix.ts
index b4b2dd37846e0..988323bd6a885 100644
--- a/src/services/_namespaces/ts.codefix.ts
+++ b/src/services/_namespaces/ts.codefix.ts
@@ -1,75 +1,75 @@
/* Generated file to emulate the ts.codefix namespace. */
-export * from "../codeFixProvider";
-export * from "../codefixes/addConvertToUnknownForNonOverlappingTypes";
-export * from "../codefixes/addEmptyExportDeclaration";
-export * from "../codefixes/addMissingAsync";
-export * from "../codefixes/addMissingAwait";
-export * from "../codefixes/addMissingConst";
-export * from "../codefixes/addMissingDeclareProperty";
-export * from "../codefixes/addMissingInvocationForDecorator";
-export * from "../codefixes/addNameToNamelessParameter";
-export * from "../codefixes/addOptionalPropertyUndefined";
-export * from "../codefixes/annotateWithTypeFromJSDoc";
-export * from "../codefixes/convertFunctionToEs6Class";
-export * from "../codefixes/convertToAsyncFunction";
-export * from "../codefixes/convertToEsModule";
-export * from "../codefixes/correctQualifiedNameToIndexedAccessType";
-export * from "../codefixes/convertToTypeOnlyExport";
-export * from "../codefixes/convertToTypeOnlyImport";
-export * from "../codefixes/convertTypedefToType";
-export * from "../codefixes/convertLiteralTypeToMappedType";
-export * from "../codefixes/fixClassIncorrectlyImplementsInterface";
-export * from "../codefixes/importFixes";
-export * from "../codefixes/fixAddMissingConstraint";
-export * from "../codefixes/fixOverrideModifier";
-export * from "../codefixes/fixNoPropertyAccessFromIndexSignature";
-export * from "../codefixes/fixImplicitThis";
-export * from "../codefixes/fixImportNonExportedMember";
-export * from "../codefixes/fixIncorrectNamedTupleSyntax";
-export * from "../codefixes/fixSpelling";
-export * from "../codefixes/returnValueCorrect";
-export * from "../codefixes/fixAddMissingMember";
-export * from "../codefixes/fixAddMissingNewOperator";
-export * from "../codefixes/fixAddMissingParam";
-export * from "../codefixes/fixCannotFindModule";
-export * from "../codefixes/fixClassDoesntImplementInheritedAbstractMember";
-export * from "../codefixes/fixClassSuperMustPrecedeThisAccess";
-export * from "../codefixes/fixConstructorForDerivedNeedSuperCall";
-export * from "../codefixes/fixEnableJsxFlag";
-export * from "../codefixes/fixNaNEquality";
-export * from "../codefixes/fixModuleAndTargetOptions";
-export * from "../codefixes/fixPropertyAssignment";
-export * from "../codefixes/fixExtendsInterfaceBecomesImplements";
-export * from "../codefixes/fixForgottenThisPropertyAccess";
-export * from "../codefixes/fixInvalidJsxCharacters";
-export * from "../codefixes/fixUnmatchedParameter";
-export * from "../codefixes/fixUnreferenceableDecoratorMetadata";
-export * from "../codefixes/fixUnusedIdentifier";
-export * from "../codefixes/fixUnreachableCode";
-export * from "../codefixes/fixUnusedLabel";
-export * from "../codefixes/fixJSDocTypes";
-export * from "../codefixes/fixMissingCallParentheses";
-export * from "../codefixes/fixMissingTypeAnnotationOnExports";
-export * from "../codefixes/fixAwaitInSyncFunction";
-export * from "../codefixes/fixPropertyOverrideAccessor";
-export * from "../codefixes/inferFromUsage";
-export * from "../codefixes/fixReturnTypeInAsyncFunction";
-export * from "../codefixes/disableJsDiagnostics";
-export * from "../codefixes/helpers";
-export * from "../codefixes/generateAccessors";
-export * from "../codefixes/fixInvalidImportSyntax";
-export * from "../codefixes/fixStrictClassInitialization";
-export * from "../codefixes/requireInTs";
-export * from "../codefixes/useDefaultImport";
-export * from "../codefixes/useBigintLiteral";
-export * from "../codefixes/fixAddModuleReferTypeMissingTypeof";
-export * from "../codefixes/wrapJsxInFragment";
-export * from "../codefixes/wrapDecoratorInParentheses";
-export * from "../codefixes/convertToMappedObjectType";
-export * from "../codefixes/removeAccidentalCallParentheses";
-export * from "../codefixes/removeUnnecessaryAwait";
-export * from "../codefixes/splitTypeOnlyImport";
-export * from "../codefixes/convertConstToLet";
-export * from "../codefixes/fixExpectedComma";
-export * from "../codefixes/fixAddVoidToPromise";
+export * from "../codeFixProvider.js";
+export * from "../codefixes/addConvertToUnknownForNonOverlappingTypes.js";
+export * from "../codefixes/addEmptyExportDeclaration.js";
+export * from "../codefixes/addMissingAsync.js";
+export * from "../codefixes/addMissingAwait.js";
+export * from "../codefixes/addMissingConst.js";
+export * from "../codefixes/addMissingDeclareProperty.js";
+export * from "../codefixes/addMissingInvocationForDecorator.js";
+export * from "../codefixes/addNameToNamelessParameter.js";
+export * from "../codefixes/addOptionalPropertyUndefined.js";
+export * from "../codefixes/annotateWithTypeFromJSDoc.js";
+export * from "../codefixes/convertFunctionToEs6Class.js";
+export * from "../codefixes/convertToAsyncFunction.js";
+export * from "../codefixes/convertToEsModule.js";
+export * from "../codefixes/correctQualifiedNameToIndexedAccessType.js";
+export * from "../codefixes/convertToTypeOnlyExport.js";
+export * from "../codefixes/convertToTypeOnlyImport.js";
+export * from "../codefixes/convertTypedefToType.js";
+export * from "../codefixes/convertLiteralTypeToMappedType.js";
+export * from "../codefixes/fixClassIncorrectlyImplementsInterface.js";
+export * from "../codefixes/importFixes.js";
+export * from "../codefixes/fixAddMissingConstraint.js";
+export * from "../codefixes/fixOverrideModifier.js";
+export * from "../codefixes/fixNoPropertyAccessFromIndexSignature.js";
+export * from "../codefixes/fixImplicitThis.js";
+export * from "../codefixes/fixImportNonExportedMember.js";
+export * from "../codefixes/fixIncorrectNamedTupleSyntax.js";
+export * from "../codefixes/fixSpelling.js";
+export * from "../codefixes/returnValueCorrect.js";
+export * from "../codefixes/fixAddMissingMember.js";
+export * from "../codefixes/fixAddMissingNewOperator.js";
+export * from "../codefixes/fixAddMissingParam.js";
+export * from "../codefixes/fixCannotFindModule.js";
+export * from "../codefixes/fixClassDoesntImplementInheritedAbstractMember.js";
+export * from "../codefixes/fixClassSuperMustPrecedeThisAccess.js";
+export * from "../codefixes/fixConstructorForDerivedNeedSuperCall.js";
+export * from "../codefixes/fixEnableJsxFlag.js";
+export * from "../codefixes/fixNaNEquality.js";
+export * from "../codefixes/fixModuleAndTargetOptions.js";
+export * from "../codefixes/fixPropertyAssignment.js";
+export * from "../codefixes/fixExtendsInterfaceBecomesImplements.js";
+export * from "../codefixes/fixForgottenThisPropertyAccess.js";
+export * from "../codefixes/fixInvalidJsxCharacters.js";
+export * from "../codefixes/fixUnmatchedParameter.js";
+export * from "../codefixes/fixUnreferenceableDecoratorMetadata.js";
+export * from "../codefixes/fixUnusedIdentifier.js";
+export * from "../codefixes/fixUnreachableCode.js";
+export * from "../codefixes/fixUnusedLabel.js";
+export * from "../codefixes/fixJSDocTypes.js";
+export * from "../codefixes/fixMissingCallParentheses.js";
+export * from "../codefixes/fixMissingTypeAnnotationOnExports.js";
+export * from "../codefixes/fixAwaitInSyncFunction.js";
+export * from "../codefixes/fixPropertyOverrideAccessor.js";
+export * from "../codefixes/inferFromUsage.js";
+export * from "../codefixes/fixReturnTypeInAsyncFunction.js";
+export * from "../codefixes/disableJsDiagnostics.js";
+export * from "../codefixes/helpers.js";
+export * from "../codefixes/generateAccessors.js";
+export * from "../codefixes/fixInvalidImportSyntax.js";
+export * from "../codefixes/fixStrictClassInitialization.js";
+export * from "../codefixes/requireInTs.js";
+export * from "../codefixes/useDefaultImport.js";
+export * from "../codefixes/useBigintLiteral.js";
+export * from "../codefixes/fixAddModuleReferTypeMissingTypeof.js";
+export * from "../codefixes/wrapJsxInFragment.js";
+export * from "../codefixes/wrapDecoratorInParentheses.js";
+export * from "../codefixes/convertToMappedObjectType.js";
+export * from "../codefixes/removeAccidentalCallParentheses.js";
+export * from "../codefixes/removeUnnecessaryAwait.js";
+export * from "../codefixes/splitTypeOnlyImport.js";
+export * from "../codefixes/convertConstToLet.js";
+export * from "../codefixes/fixExpectedComma.js";
+export * from "../codefixes/fixAddVoidToPromise.js";
diff --git a/src/services/_namespaces/ts.formatting.ts b/src/services/_namespaces/ts.formatting.ts
index 72e03b2f7e915..bd1396e355176 100644
--- a/src/services/_namespaces/ts.formatting.ts
+++ b/src/services/_namespaces/ts.formatting.ts
@@ -1,9 +1,9 @@
/* Generated file to emulate the ts.formatting namespace. */
-export * from "../formatting/formattingContext";
-export * from "../formatting/formattingScanner";
-export * from "../formatting/rule";
-export * from "../formatting/rules";
-export * from "../formatting/rulesMap";
-export * from "../formatting/formatting";
-export * from "../formatting/smartIndenter";
+export * from "../formatting/formattingContext.js";
+export * from "../formatting/formattingScanner.js";
+export * from "../formatting/rule.js";
+export * from "../formatting/rules.js";
+export * from "../formatting/rulesMap.js";
+export * from "../formatting/formatting.js";
+export * from "../formatting/smartIndenter.js";
diff --git a/src/services/_namespaces/ts.refactor.addOrRemoveBracesToArrowFunction.ts b/src/services/_namespaces/ts.refactor.addOrRemoveBracesToArrowFunction.ts
index 5dd00f2f63b86..6c5178ed60d8e 100644
--- a/src/services/_namespaces/ts.refactor.addOrRemoveBracesToArrowFunction.ts
+++ b/src/services/_namespaces/ts.refactor.addOrRemoveBracesToArrowFunction.ts
@@ -1,4 +1,4 @@
/* Generated file to emulate the ts.refactor.addOrRemoveBracesToArrowFunction namespace. */
-export * from "../refactors/convertOverloadListToSingleSignature";
-export * from "../refactors/addOrRemoveBracesToArrowFunction";
+export * from "../refactors/convertOverloadListToSingleSignature.js";
+export * from "../refactors/addOrRemoveBracesToArrowFunction.js";
diff --git a/src/services/_namespaces/ts.refactor.convertArrowFunctionOrFunctionExpression.ts b/src/services/_namespaces/ts.refactor.convertArrowFunctionOrFunctionExpression.ts
index 48fb788058cd4..fc3c0762497e5 100644
--- a/src/services/_namespaces/ts.refactor.convertArrowFunctionOrFunctionExpression.ts
+++ b/src/services/_namespaces/ts.refactor.convertArrowFunctionOrFunctionExpression.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.refactor.convertArrowFunctionOrFunctionExpression namespace. */
-export * from "../refactors/convertArrowFunctionOrFunctionExpression";
+export * from "../refactors/convertArrowFunctionOrFunctionExpression.js";
diff --git a/src/services/_namespaces/ts.refactor.convertParamsToDestructuredObject.ts b/src/services/_namespaces/ts.refactor.convertParamsToDestructuredObject.ts
index 3cc94f5e9f048..488602adfab5f 100644
--- a/src/services/_namespaces/ts.refactor.convertParamsToDestructuredObject.ts
+++ b/src/services/_namespaces/ts.refactor.convertParamsToDestructuredObject.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.refactor.convertParamsToDestructuredObject namespace. */
-export * from "../refactors/convertParamsToDestructuredObject";
+export * from "../refactors/convertParamsToDestructuredObject.js";
diff --git a/src/services/_namespaces/ts.refactor.convertStringOrTemplateLiteral.ts b/src/services/_namespaces/ts.refactor.convertStringOrTemplateLiteral.ts
index e084befebaafc..ba98999f2afa2 100644
--- a/src/services/_namespaces/ts.refactor.convertStringOrTemplateLiteral.ts
+++ b/src/services/_namespaces/ts.refactor.convertStringOrTemplateLiteral.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.refactor.convertStringOrTemplateLiteral namespace. */
-export * from "../refactors/convertStringOrTemplateLiteral";
+export * from "../refactors/convertStringOrTemplateLiteral.js";
diff --git a/src/services/_namespaces/ts.refactor.convertToOptionalChainExpression.ts b/src/services/_namespaces/ts.refactor.convertToOptionalChainExpression.ts
index d8b0ab31eabaa..f6eabd9e28e61 100644
--- a/src/services/_namespaces/ts.refactor.convertToOptionalChainExpression.ts
+++ b/src/services/_namespaces/ts.refactor.convertToOptionalChainExpression.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.refactor.convertToOptionalChainExpression namespace. */
-export * from "../refactors/convertToOptionalChainExpression";
+export * from "../refactors/convertToOptionalChainExpression.js";
diff --git a/src/services/_namespaces/ts.refactor.extractSymbol.ts b/src/services/_namespaces/ts.refactor.extractSymbol.ts
index c71cacd346c4d..1a0fb218580eb 100644
--- a/src/services/_namespaces/ts.refactor.extractSymbol.ts
+++ b/src/services/_namespaces/ts.refactor.extractSymbol.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.refactor.extractSymbol namespace. */
-export * from "../refactors/extractSymbol";
+export * from "../refactors/extractSymbol.js";
diff --git a/src/services/_namespaces/ts.refactor.generateGetAccessorAndSetAccessor.ts b/src/services/_namespaces/ts.refactor.generateGetAccessorAndSetAccessor.ts
index 8128f0cb6cb0e..961e779e74e2d 100644
--- a/src/services/_namespaces/ts.refactor.generateGetAccessorAndSetAccessor.ts
+++ b/src/services/_namespaces/ts.refactor.generateGetAccessorAndSetAccessor.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.refactor.generateGetAccessorAndSetAccessor namespace. */
-export * from "../refactors/generateGetAccessorAndSetAccessor";
+export * from "../refactors/generateGetAccessorAndSetAccessor.js";
diff --git a/src/services/_namespaces/ts.refactor.inferFunctionReturnType.ts b/src/services/_namespaces/ts.refactor.inferFunctionReturnType.ts
index 3dd2e0a9b04ad..36262dc39371b 100644
--- a/src/services/_namespaces/ts.refactor.inferFunctionReturnType.ts
+++ b/src/services/_namespaces/ts.refactor.inferFunctionReturnType.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.refactor.inferFunctionReturnType namespace. */
-export * from "../refactors/inferFunctionReturnType";
+export * from "../refactors/inferFunctionReturnType.js";
diff --git a/src/services/_namespaces/ts.refactor.ts b/src/services/_namespaces/ts.refactor.ts
index e397f484766ba..e0b976da62f2e 100644
--- a/src/services/_namespaces/ts.refactor.ts
+++ b/src/services/_namespaces/ts.refactor.ts
@@ -1,26 +1,26 @@
/* Generated file to emulate the ts.refactor namespace. */
-export * from "../refactorProvider";
-export * from "../refactors/convertExport";
-export * from "../refactors/convertImport";
-export * from "../refactors/extractType";
-export * from "../refactors/helpers";
-export * from "../refactors/inlineVariable";
-export * from "../refactors/moveToNewFile";
-export * from "../refactors/moveToFile";
-import * as addOrRemoveBracesToArrowFunction from "./ts.refactor.addOrRemoveBracesToArrowFunction";
+export * from "../refactorProvider.js";
+export * from "../refactors/convertExport.js";
+export * from "../refactors/convertImport.js";
+export * from "../refactors/extractType.js";
+export * from "../refactors/helpers.js";
+export * from "../refactors/inlineVariable.js";
+export * from "../refactors/moveToNewFile.js";
+export * from "../refactors/moveToFile.js";
+import * as addOrRemoveBracesToArrowFunction from "./ts.refactor.addOrRemoveBracesToArrowFunction.js";
export { addOrRemoveBracesToArrowFunction };
-import * as convertArrowFunctionOrFunctionExpression from "./ts.refactor.convertArrowFunctionOrFunctionExpression";
+import * as convertArrowFunctionOrFunctionExpression from "./ts.refactor.convertArrowFunctionOrFunctionExpression.js";
export { convertArrowFunctionOrFunctionExpression };
-import * as convertParamsToDestructuredObject from "./ts.refactor.convertParamsToDestructuredObject";
+import * as convertParamsToDestructuredObject from "./ts.refactor.convertParamsToDestructuredObject.js";
export { convertParamsToDestructuredObject };
-import * as convertStringOrTemplateLiteral from "./ts.refactor.convertStringOrTemplateLiteral";
+import * as convertStringOrTemplateLiteral from "./ts.refactor.convertStringOrTemplateLiteral.js";
export { convertStringOrTemplateLiteral };
-import * as convertToOptionalChainExpression from "./ts.refactor.convertToOptionalChainExpression";
+import * as convertToOptionalChainExpression from "./ts.refactor.convertToOptionalChainExpression.js";
export { convertToOptionalChainExpression };
-import * as extractSymbol from "./ts.refactor.extractSymbol";
+import * as extractSymbol from "./ts.refactor.extractSymbol.js";
export { extractSymbol };
-import * as generateGetAccessorAndSetAccessor from "./ts.refactor.generateGetAccessorAndSetAccessor";
+import * as generateGetAccessorAndSetAccessor from "./ts.refactor.generateGetAccessorAndSetAccessor.js";
export { generateGetAccessorAndSetAccessor };
-import * as inferFunctionReturnType from "./ts.refactor.inferFunctionReturnType";
+import * as inferFunctionReturnType from "./ts.refactor.inferFunctionReturnType.js";
export { inferFunctionReturnType };
diff --git a/src/services/_namespaces/ts.textChanges.ts b/src/services/_namespaces/ts.textChanges.ts
index 12a272788fd09..5e3ec149c9f35 100644
--- a/src/services/_namespaces/ts.textChanges.ts
+++ b/src/services/_namespaces/ts.textChanges.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.textChanges namespace. */
-export * from "../textChanges";
+export * from "../textChanges.js";
diff --git a/src/services/_namespaces/ts.ts b/src/services/_namespaces/ts.ts
index e30ea818a04b5..b98a2f743cf59 100644
--- a/src/services/_namespaces/ts.ts
+++ b/src/services/_namespaces/ts.ts
@@ -1,58 +1,62 @@
/* Generated file to emulate the ts namespace. */
-export * from "../../compiler/_namespaces/ts";
-export * from "../../jsTyping/_namespaces/ts";
-export * from "../types";
-export * from "../utilities";
-export * from "../exportInfoMap";
-export * from "../classifier";
-export * from "../documentHighlights";
-export * from "../documentRegistry";
-export * from "../getEditsForFileRename";
-export * from "../patternMatcher";
-export * from "../preProcess";
-export * from "../sourcemaps";
-export * from "../suggestionDiagnostics";
-export * from "../transpile";
-export * from "../services";
-export * from "../transform";
-import * as BreakpointResolver from "./ts.BreakpointResolver";
+export * from "../../compiler/_namespaces/ts.js";
+export * from "../../jsTyping/_namespaces/ts.js";
+export * from "../types.js";
+export * from "../utilities.js";
+export * from "../exportInfoMap.js";
+export * from "../classifier.js";
+export * from "../documentHighlights.js";
+export * from "../documentRegistry.js";
+export * from "../getEditsForFileRename.js";
+export * from "../patternMatcher.js";
+export * from "../preProcess.js";
+export * from "../sourcemaps.js";
+export * from "../suggestionDiagnostics.js";
+export * from "../transpile.js";
+export * from "../services.js";
+export * from "../transform.js";
+import * as BreakpointResolver from "./ts.BreakpointResolver.js";
export { BreakpointResolver };
-import * as CallHierarchy from "./ts.CallHierarchy";
+import * as CallHierarchy from "./ts.CallHierarchy.js";
export { CallHierarchy };
-import * as classifier from "./ts.classifier";
+import * as classifier from "./ts.classifier.js";
export { classifier };
-import * as codefix from "./ts.codefix";
+import * as codefix from "./ts.codefix.js";
export { codefix };
-import * as Completions from "./ts.Completions";
+import * as Completions from "./ts.Completions.js";
export { Completions };
-import * as FindAllReferences from "./ts.FindAllReferences";
+import * as FindAllReferences from "./ts.FindAllReferences.js";
export { FindAllReferences };
-import * as GoToDefinition from "./ts.GoToDefinition";
+import * as GoToDefinition from "./ts.GoToDefinition.js";
export { GoToDefinition };
-import * as InlayHints from "./ts.InlayHints";
+import * as InlayHints from "./ts.InlayHints.js";
export { InlayHints };
-import * as JsDoc from "./ts.JsDoc";
+import * as JsDoc from "./ts.JsDoc.js";
+import * as MapCode from "./ts.MapCode.js";
+export { MapCode };
export { JsDoc };
-import * as NavigateTo from "./ts.NavigateTo";
+import * as NavigateTo from "./ts.NavigateTo.js";
export { NavigateTo };
-import * as NavigationBar from "./ts.NavigationBar";
+import * as NavigationBar from "./ts.NavigationBar.js";
export { NavigationBar };
-import * as OrganizeImports from "./ts.OrganizeImports";
+import * as OrganizeImports from "./ts.OrganizeImports.js";
export { OrganizeImports };
-import * as OutliningElementsCollector from "./ts.OutliningElementsCollector";
+import * as OutliningElementsCollector from "./ts.OutliningElementsCollector.js";
export { OutliningElementsCollector };
-import * as refactor from "./ts.refactor";
+import * as refactor from "./ts.refactor.js";
export { refactor };
-import * as Rename from "./ts.Rename";
+import * as Rename from "./ts.Rename.js";
export { Rename };
-import * as SignatureHelp from "./ts.SignatureHelp";
+import * as SignatureHelp from "./ts.SignatureHelp.js";
export { SignatureHelp };
-import * as SmartSelectionRange from "./ts.SmartSelectionRange";
+import * as SmartSelectionRange from "./ts.SmartSelectionRange.js";
export { SmartSelectionRange };
-import * as SymbolDisplay from "./ts.SymbolDisplay";
+import * as SymbolDisplay from "./ts.SymbolDisplay.js";
export { SymbolDisplay };
-import * as textChanges from "./ts.textChanges";
+import * as textChanges from "./ts.textChanges.js";
export { textChanges };
-import * as formatting from "./ts.formatting";
+import * as formatting from "./ts.formatting.js";
export { formatting };
+import * as pasteEdits from "./ts.PasteEdits.js";
+export { pasteEdits };
diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts
index 8963a5dcf0d73..17d20da69ee92 100644
--- a/src/services/breakpoints.ts
+++ b/src/services/breakpoints.ts
@@ -70,7 +70,7 @@ import {
VariableStatement,
WhileStatement,
WithStatement,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/**
* Get the breakpoint span in given sourceFile
diff --git a/src/services/callHierarchy.ts b/src/services/callHierarchy.ts
index 6b354cbde9d73..77a3b4698e2c0 100644
--- a/src/services/callHierarchy.ts
+++ b/src/services/callHierarchy.ts
@@ -105,7 +105,7 @@ import {
TypeChecker,
usingSingleLineStringWriter,
VariableDeclaration,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export type NamedExpression =
diff --git a/src/services/classifier.ts b/src/services/classifier.ts
index df9b7d3e14880..0e9e509edcaa7 100644
--- a/src/services/classifier.ts
+++ b/src/services/classifier.ts
@@ -75,7 +75,7 @@ import {
TokenClass,
TypeChecker,
TypeParameterDeclaration,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** The classifier is used for syntactic highlighting in editors via the TSServer */
export function createClassifier(): Classifier {
diff --git a/src/services/classifier2020.ts b/src/services/classifier2020.ts
index 1fa90584974f5..529b0adc03563 100644
--- a/src/services/classifier2020.ts
+++ b/src/services/classifier2020.ts
@@ -43,7 +43,7 @@ import {
Type,
TypeChecker,
VariableDeclaration,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export const enum TokenEncodingConsts {
diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts
index 2e2282afbc6e1..686a96dea6c8e 100644
--- a/src/services/codeFixProvider.ts
+++ b/src/services/codeFixProvider.ts
@@ -23,7 +23,7 @@ import {
map,
TextChange,
textChanges,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
const errorCodeToFixes = createMultiMap();
const fixIdToRegistration = new Map();
diff --git a/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts b/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts
index 4b27aee72c953..942cb05ffb687 100644
--- a/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts
+++ b/src/services/codefixes/addConvertToUnknownForNonOverlappingTypes.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
AsExpression,
Diagnostics,
@@ -11,12 +16,7 @@ import {
SyntaxKind,
textChanges,
TypeAssertion,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "addConvertToUnknownForNonOverlappingTypes";
const errorCodes = [Diagnostics.Conversion_of_type_0_to_type_1_may_be_a_mistake_because_neither_type_sufficiently_overlaps_with_the_other_If_this_was_intentional_convert_the_expression_to_unknown_first.code];
diff --git a/src/services/codefixes/addEmptyExportDeclaration.ts b/src/services/codefixes/addEmptyExportDeclaration.ts
index d1c9bbf9a6e54..6241d9841c4e1 100644
--- a/src/services/codefixes/addEmptyExportDeclaration.ts
+++ b/src/services/codefixes/addEmptyExportDeclaration.ts
@@ -1,12 +1,12 @@
+import {
+ createCodeFixActionWithoutFixAll,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
factory,
textChanges,
-} from "../_namespaces/ts";
-import {
- createCodeFixActionWithoutFixAll,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
registerCodeFix({
errorCodes: [
diff --git a/src/services/codefixes/addMissingAsync.ts b/src/services/codefixes/addMissingAsync.ts
index 39a6f97c8bacd..9afd41691787a 100644
--- a/src/services/codefixes/addMissingAsync.ts
+++ b/src/services/codefixes/addMissingAsync.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
ArrowFunction,
CodeFixAllContext,
@@ -28,12 +33,7 @@ import {
TextSpan,
textSpanEnd,
textSpansEqual,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
type ContextualTrackChangesFunction = (cb: (changeTracker: textChanges.ChangeTracker) => void) => FileTextChanges[];
const fixId = "addMissingAsync";
diff --git a/src/services/codefixes/addMissingAwait.ts b/src/services/codefixes/addMissingAwait.ts
index 61c2692b3a8b5..0fc96ba514b37 100644
--- a/src/services/codefixes/addMissingAwait.ts
+++ b/src/services/codefixes/addMissingAwait.ts
@@ -1,3 +1,9 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ createCodeFixActionWithoutFixAll,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
CancellationToken,
CodeFixAllContext,
@@ -44,13 +50,7 @@ import {
tryCast,
TypeChecker,
TypeFlags,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- createCodeFixActionWithoutFixAll,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
type ContextualTrackChangesFunction = (cb: (changeTracker: textChanges.ChangeTracker) => void) => FileTextChanges[];
const fixId = "addMissingAwait";
diff --git a/src/services/codefixes/addMissingConst.ts b/src/services/codefixes/addMissingConst.ts
index 87adb892cd9f6..17340f6eafc3d 100644
--- a/src/services/codefixes/addMissingConst.ts
+++ b/src/services/codefixes/addMissingConst.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
every,
@@ -17,12 +22,7 @@ import {
textChanges,
tryAddToSet,
TypeChecker,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "addMissingConst";
const errorCodes = [
diff --git a/src/services/codefixes/addMissingDeclareProperty.ts b/src/services/codefixes/addMissingDeclareProperty.ts
index e78a76e25e96d..598195c23d192 100644
--- a/src/services/codefixes/addMissingDeclareProperty.ts
+++ b/src/services/codefixes/addMissingDeclareProperty.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
getTokenAtPosition,
@@ -7,12 +12,7 @@ import {
SyntaxKind,
textChanges,
tryAddToSet,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "addMissingDeclareProperty";
const errorCodes = [
diff --git a/src/services/codefixes/addMissingInvocationForDecorator.ts b/src/services/codefixes/addMissingInvocationForDecorator.ts
index 330757c9fa76f..020768dc8540a 100644
--- a/src/services/codefixes/addMissingInvocationForDecorator.ts
+++ b/src/services/codefixes/addMissingInvocationForDecorator.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Debug,
Diagnostics,
@@ -7,12 +12,7 @@ import {
isDecorator,
SourceFile,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "addMissingInvocationForDecorator";
const errorCodes = [Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0.code];
diff --git a/src/services/codefixes/addNameToNamelessParameter.ts b/src/services/codefixes/addNameToNamelessParameter.ts
index ca55406e9ca96..d8e5e24e1cdd6 100644
--- a/src/services/codefixes/addNameToNamelessParameter.ts
+++ b/src/services/codefixes/addNameToNamelessParameter.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
createRange,
Debug,
@@ -14,12 +19,7 @@ import {
SyntaxKind,
textChanges,
TypeNode,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "addNameToNamelessParameter";
const errorCodes = [Diagnostics.Parameter_has_a_name_but_no_type_Did_you_mean_0_Colon_1.code];
diff --git a/src/services/codefixes/addOptionalPropertyUndefined.ts b/src/services/codefixes/addOptionalPropertyUndefined.ts
index 4b584c3f617ca..cb33ed9d5fa98 100644
--- a/src/services/codefixes/addOptionalPropertyUndefined.ts
+++ b/src/services/codefixes/addOptionalPropertyUndefined.ts
@@ -1,3 +1,7 @@
+import {
+ createCodeFixActionWithoutFixAll,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
emptyArray,
@@ -26,11 +30,7 @@ import {
TextSpan,
TypeChecker,
UnionTypeNode,
-} from "../_namespaces/ts";
-import {
- createCodeFixActionWithoutFixAll,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const addOptionalPropertyUndefined = "addOptionalPropertyUndefined";
diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts
index a73a19abffe60..72a9cd7d19297 100644
--- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts
+++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Debug,
Diagnostics,
@@ -40,12 +45,7 @@ import {
visitEachChild,
visitNode,
visitNodes,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "annotateWithTypeFromJSDoc";
const errorCodes = [Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types.code];
diff --git a/src/services/codefixes/convertConstToLet.ts b/src/services/codefixes/convertConstToLet.ts
index fb1cefbc859b3..8497cb2ee8053 100644
--- a/src/services/codefixes/convertConstToLet.ts
+++ b/src/services/codefixes/convertConstToLet.ts
@@ -1,3 +1,9 @@
+import {
+ createCodeFixActionMaybeFixAll,
+ createCombinedCodeActions,
+ eachDiagnostic,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
addToSeen,
Diagnostics,
@@ -13,13 +19,7 @@ import {
textChanges,
Token,
tryCast,
-} from "../_namespaces/ts";
-import {
- createCodeFixActionMaybeFixAll,
- createCombinedCodeActions,
- eachDiagnostic,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixConvertConstToLet";
const errorCodes = [Diagnostics.Cannot_assign_to_0_because_it_is_a_constant.code];
diff --git a/src/services/codefixes/convertFunctionToEs6Class.ts b/src/services/codefixes/convertFunctionToEs6Class.ts
index 92d1c85f269f6..56fdaeec81da2 100644
--- a/src/services/codefixes/convertFunctionToEs6Class.ts
+++ b/src/services/codefixes/convertFunctionToEs6Class.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
__String,
AccessExpression,
@@ -60,12 +65,7 @@ import {
TypeChecker,
UserPreferences,
VariableDeclaration,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "convertFunctionToEs6Class";
const errorCodes = [Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration.code];
diff --git a/src/services/codefixes/convertLiteralTypeToMappedType.ts b/src/services/codefixes/convertLiteralTypeToMappedType.ts
index bde76824b8ce6..1811087c077c4 100644
--- a/src/services/codefixes/convertLiteralTypeToMappedType.ts
+++ b/src/services/codefixes/convertLiteralTypeToMappedType.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
cast,
Diagnostics,
@@ -10,12 +15,7 @@ import {
textChanges,
TypeLiteralNode,
TypeNode,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "convertLiteralTypeToMappedType";
const errorCodes = [Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here_Did_you_mean_to_use_1_in_0.code];
diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts
index cb122865c66ac..07ac83e40ea19 100644
--- a/src/services/codefixes/convertToAsyncFunction.ts
+++ b/src/services/codefixes/convertToAsyncFunction.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
ArrowFunction,
AwaitExpression,
@@ -77,12 +82,7 @@ import {
TypeNode,
TypeReference,
UnionReduction,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "convertToAsyncFunction";
const errorCodes = [Diagnostics.This_may_be_converted_to_an_async_function.code];
diff --git a/src/services/codefixes/convertToEsModule.ts b/src/services/codefixes/convertToEsModule.ts
index b78669dc244a0..02d1a5f930114 100644
--- a/src/services/codefixes/convertToEsModule.ts
+++ b/src/services/codefixes/convertToEsModule.ts
@@ -1,3 +1,7 @@
+import {
+ createCodeFixActionWithoutFixAll,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
__String,
arrayFrom,
@@ -54,6 +58,7 @@ import {
mapIterator,
MethodDeclaration,
Modifier,
+ moduleSpecifierToValidIdentifier,
Node,
NodeArray,
NodeFlags,
@@ -74,12 +79,7 @@ import {
textChanges,
TypeChecker,
VariableStatement,
-} from "../_namespaces/ts";
-import {
- createCodeFixActionWithoutFixAll,
- moduleSpecifierToValidIdentifier,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
registerCodeFix({
errorCodes: [Diagnostics.File_is_a_CommonJS_module_it_may_be_converted_to_an_ES_module.code],
@@ -106,7 +106,7 @@ function fixImportOfModuleExports(
quotePreference: QuotePreference,
) {
for (const moduleSpecifier of importingFile.imports) {
- const imported = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier)?.resolvedModule;
+ const imported = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier, importingFile)?.resolvedModule;
if (!imported || imported.resolvedFileName !== exportingFile.fileName) {
continue;
}
diff --git a/src/services/codefixes/convertToMappedObjectType.ts b/src/services/codefixes/convertToMappedObjectType.ts
index f07987f258c6b..c4330112e8100 100644
--- a/src/services/codefixes/convertToMappedObjectType.ts
+++ b/src/services/codefixes/convertToMappedObjectType.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
cast,
Diagnostics,
@@ -21,12 +26,7 @@ import {
TypeAliasDeclaration,
TypeLiteralNode,
TypeNode,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixConvertToMappedObjectType";
const errorCodes = [Diagnostics.An_index_signature_parameter_type_cannot_be_a_literal_type_or_generic_type_Consider_using_a_mapped_object_type_instead.code];
diff --git a/src/services/codefixes/convertToTypeOnlyExport.ts b/src/services/codefixes/convertToTypeOnlyExport.ts
index 14ec2e3e8e31d..5f2e80f4c8481 100644
--- a/src/services/codefixes/convertToTypeOnlyExport.ts
+++ b/src/services/codefixes/convertToTypeOnlyExport.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
addToSeen,
CodeFixContextBase,
@@ -17,12 +22,7 @@ import {
textChanges,
TextSpan,
tryCast,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const errorCodes = [Diagnostics.Re_exporting_a_type_when_0_is_enabled_requires_using_export_type.code];
const fixId = "convertToTypeOnlyExport";
diff --git a/src/services/codefixes/convertToTypeOnlyImport.ts b/src/services/codefixes/convertToTypeOnlyImport.ts
index 54f1121657432..3fdc81f3e4bbb 100644
--- a/src/services/codefixes/convertToTypeOnlyImport.ts
+++ b/src/services/codefixes/convertToTypeOnlyImport.ts
@@ -1,3 +1,9 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ createCodeFixActionWithoutFixAll,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
factory,
@@ -17,13 +23,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- createCodeFixActionWithoutFixAll,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const errorCodes = [
Diagnostics._0_is_a_type_and_must_be_imported_using_a_type_only_import_when_verbatimModuleSyntax_is_enabled.code,
diff --git a/src/services/codefixes/convertTypedefToType.ts b/src/services/codefixes/convertTypedefToType.ts
index 395ee58f1378f..70d02fb846678 100644
--- a/src/services/codefixes/convertTypedefToType.ts
+++ b/src/services/codefixes/convertTypedefToType.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
factory,
@@ -23,12 +28,7 @@ import {
SyntaxKind,
textChanges,
TypeAliasDeclaration,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "convertTypedefToType";
const errorCodes = [Diagnostics.JSDoc_typedef_may_be_converted_to_TypeScript_type.code];
diff --git a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts
index 3dbcb5e8f2180..96a7b8914bfe5 100644
--- a/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts
+++ b/src/services/codefixes/correctQualifiedNameToIndexedAccessType.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Debug,
Diagnostics,
@@ -10,12 +15,7 @@ import {
QualifiedName,
SourceFile,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "correctQualifiedNameToIndexedAccessType";
const errorCodes = [Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1.code];
diff --git a/src/services/codefixes/disableJsDiagnostics.ts b/src/services/codefixes/disableJsDiagnostics.ts
index 09d7a00d0c6c5..3d7aa72e4f672 100644
--- a/src/services/codefixes/disableJsDiagnostics.ts
+++ b/src/services/codefixes/disableJsDiagnostics.ts
@@ -1,3 +1,10 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ createCodeFixActionWithoutFixAll,
+ createFileTextChanges,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
CodeFixAction,
createTextChange,
@@ -13,14 +20,7 @@ import {
SourceFile,
textChanges,
tryAddToSet,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- createCodeFixActionWithoutFixAll,
- createFileTextChanges,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixName = "disableJsDiagnostics";
const fixId = "disableJsDiagnostics";
diff --git a/src/services/codefixes/fixAddMissingConstraint.ts b/src/services/codefixes/fixAddMissingConstraint.ts
index 267cabc534e02..fad9a8f003a5c 100644
--- a/src/services/codefixes/fixAddMissingConstraint.ts
+++ b/src/services/codefixes/fixAddMissingConstraint.ts
@@ -1,3 +1,13 @@
+import {
+ createCodeFixAction,
+ createCombinedCodeActions,
+ createImportAdder,
+ eachDiagnostic,
+ findAncestorMatchingSpan,
+ getNoopSymbolTrackerWithResolver,
+ registerCodeFix,
+ typeToAutoImportableTypeNode,
+} from "../_namespaces/ts.codefix.js";
import {
addToSeen,
createTextSpan,
@@ -25,17 +35,7 @@ import {
TypeChecker,
TypeParameterDeclaration,
UserPreferences,
-} from "../_namespaces/ts";
-import {
- createCodeFixAction,
- createCombinedCodeActions,
- createImportAdder,
- eachDiagnostic,
- findAncestorMatchingSpan,
- getNoopSymbolTrackerWithResolver,
- registerCodeFix,
- typeToAutoImportableTypeNode,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "addMissingConstraint";
const errorCodes = [
diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts
index 1210275178f6b..f5bf022fd5755 100644
--- a/src/services/codefixes/fixAddMissingMember.ts
+++ b/src/services/codefixes/fixAddMissingMember.ts
@@ -1,3 +1,16 @@
+import {
+ createCodeFixAction,
+ createCodeFixActionWithoutFixAll,
+ createCombinedCodeActions,
+ createImportAdder,
+ createSignatureDeclarationFromCallExpression,
+ createSignatureDeclarationFromSignature,
+ createStubbedBody,
+ eachDiagnostic,
+ getAllSupers,
+ ImportAdder,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
__String,
addToSeen,
@@ -112,20 +125,7 @@ import {
TypeNode,
TypeReference,
UnionType,
-} from "../_namespaces/ts";
-import {
- createCodeFixAction,
- createCodeFixActionWithoutFixAll,
- createCombinedCodeActions,
- createImportAdder,
- createSignatureDeclarationFromCallExpression,
- createSignatureDeclarationFromSignature,
- createStubbedBody,
- eachDiagnostic,
- getAllSupers,
- ImportAdder,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixMissingMember = "fixMissingMember";
const fixMissingProperties = "fixMissingProperties";
diff --git a/src/services/codefixes/fixAddMissingNewOperator.ts b/src/services/codefixes/fixAddMissingNewOperator.ts
index 8a44e267fb5f7..adbabbfe2e0a7 100644
--- a/src/services/codefixes/fixAddMissingNewOperator.ts
+++ b/src/services/codefixes/fixAddMissingNewOperator.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
cast,
Diagnostics,
@@ -9,12 +14,7 @@ import {
textChanges,
TextSpan,
textSpanEnd,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "addMissingNewOperator";
const errorCodes = [Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new.code];
diff --git a/src/services/codefixes/fixAddMissingParam.ts b/src/services/codefixes/fixAddMissingParam.ts
index df78a311337e6..c5ac4f25b2b09 100644
--- a/src/services/codefixes/fixAddMissingParam.ts
+++ b/src/services/codefixes/fixAddMissingParam.ts
@@ -1,3 +1,12 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ createImportAdder,
+ ImportAdder,
+ importSymbols,
+ registerCodeFix,
+ tryGetAutoImportableReferenceFromTypeNode,
+} from "../_namespaces/ts.codefix.js";
import {
append,
ArrowFunction,
@@ -44,16 +53,7 @@ import {
TypeChecker,
TypeNode,
UserPreferences,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- createImportAdder,
- ImportAdder,
- importSymbols,
- registerCodeFix,
- tryGetAutoImportableReferenceFromTypeNode,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const addMissingParamFixId = "addMissingParam";
const addOptionalParamFixId = "addOptionalParam";
diff --git a/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts b/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts
index 1523819f60190..3d9bb53799fb0 100644
--- a/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts
+++ b/src/services/codefixes/fixAddModuleReferTypeMissingTypeof.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Debug,
Diagnostics,
@@ -7,12 +12,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixIdAddMissingTypeof = "fixAddModuleReferTypeMissingTypeof";
const fixId = fixIdAddMissingTypeof;
diff --git a/src/services/codefixes/fixAddVoidToPromise.ts b/src/services/codefixes/fixAddVoidToPromise.ts
index 82114594c92fb..a9061b9d24ca7 100644
--- a/src/services/codefixes/fixAddVoidToPromise.ts
+++ b/src/services/codefixes/fixAddVoidToPromise.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
CodeFixAllContext,
Diagnostics,
@@ -24,12 +29,7 @@ import {
textChanges,
TextSpan,
TypeFlags,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixName = "addVoidToPromise";
const fixId = "addVoidToPromise";
diff --git a/src/services/codefixes/fixAwaitInSyncFunction.ts b/src/services/codefixes/fixAwaitInSyncFunction.ts
index e1f78e928cd00..d6b5d766caf12 100644
--- a/src/services/codefixes/fixAwaitInSyncFunction.ts
+++ b/src/services/codefixes/fixAwaitInSyncFunction.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
addToSeen,
ArrowFunction,
@@ -19,12 +24,7 @@ import {
SyntaxKind,
textChanges,
TypeNode,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixAwaitInSyncFunction";
const errorCodes = [
diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts
index d128045f7f075..4be66a264636b 100644
--- a/src/services/codefixes/fixCannotFindModule.ts
+++ b/src/services/codefixes/fixCannotFindModule.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Debug,
Diagnostics,
@@ -11,12 +16,7 @@ import {
parsePackageName,
SourceFile,
tryCast,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixName = "fixCannotFindModule";
const fixIdInstallTypesPackage = "installTypesPackage";
diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts
index d22e9b08678b7..8f77976267f1b 100644
--- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts
+++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts
@@ -1,3 +1,11 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ createImportAdder,
+ createMissingMemberNodes,
+ registerCodeFix,
+ TypeConstructionContext,
+} from "../_namespaces/ts.codefix.js";
import {
addToSeen,
cast,
@@ -15,15 +23,7 @@ import {
Symbol,
textChanges,
UserPreferences,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- createImportAdder,
- createMissingMemberNodes,
- registerCodeFix,
- TypeConstructionContext,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const errorCodes = [
Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code,
diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts
index 7c5e3652af32a..d5dacd51dc59d 100644
--- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts
+++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts
@@ -1,3 +1,12 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ createImportAdder,
+ createMissingMemberNodes,
+ getNoopSymbolTrackerWithResolver,
+ registerCodeFix,
+ TypeConstructionContext,
+} from "../_namespaces/ts.codefix.js";
import {
addToSeen,
and,
@@ -27,16 +36,7 @@ import {
textChanges,
TypeChecker,
UserPreferences,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- createImportAdder,
- createMissingMemberNodes,
- getNoopSymbolTrackerWithResolver,
- registerCodeFix,
- TypeConstructionContext,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const errorCodes = [
Diagnostics.Class_0_incorrectly_implements_interface_1.code,
diff --git a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts
index 66032b9f315ee..a3585ace24d79 100644
--- a/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts
+++ b/src/services/codefixes/fixClassSuperMustPrecedeThisAccess.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
addToSeen,
CallExpression,
@@ -16,12 +21,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "classSuperMustPrecedeThisAccess";
const errorCodes = [Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class.code];
diff --git a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts
index 20e0cb3b35d9a..8f46f23073b9f 100644
--- a/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts
+++ b/src/services/codefixes/fixConstructorForDerivedNeedSuperCall.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
ConstructorDeclaration,
Debug,
@@ -8,12 +13,7 @@ import {
isConstructorDeclaration,
SourceFile,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "constructorForDerivedNeedSuperCall";
const errorCodes = [Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code];
diff --git a/src/services/codefixes/fixEnableJsxFlag.ts b/src/services/codefixes/fixEnableJsxFlag.ts
index 6d00ac88e072b..de3f4b0bea557 100644
--- a/src/services/codefixes/fixEnableJsxFlag.ts
+++ b/src/services/codefixes/fixEnableJsxFlag.ts
@@ -1,15 +1,15 @@
-import {
- Diagnostics,
- factory,
- textChanges,
- TsConfigSourceFile,
-} from "../_namespaces/ts";
import {
codeFixAll,
createCodeFixActionWithoutFixAll,
registerCodeFix,
setJsonCompilerOptionValue,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.codefix.js";
+import {
+ Diagnostics,
+ factory,
+ textChanges,
+ TsConfigSourceFile,
+} from "../_namespaces/ts.js";
const fixID = "fixEnableJsxFlag";
const errorCodes = [Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided.code];
diff --git a/src/services/codefixes/fixExpectedComma.ts b/src/services/codefixes/fixExpectedComma.ts
index 352760d482a28..7882467591b7d 100644
--- a/src/services/codefixes/fixExpectedComma.ts
+++ b/src/services/codefixes/fixExpectedComma.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
factory,
@@ -8,12 +13,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixExpectedComma";
const expectedErrorCode = Diagnostics._0_expected.code;
diff --git a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts
index 65595a78b8b6a..0a92ba2013e64 100644
--- a/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts
+++ b/src/services/codefixes/fixExtendsInterfaceBecomesImplements.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
factory,
@@ -9,12 +14,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "extendsInterfaceBecomesImplements";
const errorCodes = [Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements.code];
diff --git a/src/services/codefixes/fixForgottenThisPropertyAccess.ts b/src/services/codefixes/fixForgottenThisPropertyAccess.ts
index 1bd0de54296ee..0f1d197414cea 100644
--- a/src/services/codefixes/fixForgottenThisPropertyAccess.ts
+++ b/src/services/codefixes/fixForgottenThisPropertyAccess.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
factory,
@@ -10,12 +15,7 @@ import {
SourceFile,
suppressLeadingAndTrailingTrivia,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "forgottenThisPropertyAccess";
const didYouMeanStaticMemberCode = Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0.code;
diff --git a/src/services/codefixes/fixImplicitThis.ts b/src/services/codefixes/fixImplicitThis.ts
index 9a867574cac10..91be565e56570 100644
--- a/src/services/codefixes/fixImplicitThis.ts
+++ b/src/services/codefixes/fixImplicitThis.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
ANONYMOUS,
Debug,
@@ -17,12 +22,7 @@ import {
SyntaxKind,
textChanges,
TypeChecker,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixImplicitThis";
const errorCodes = [Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation.code];
diff --git a/src/services/codefixes/fixImportNonExportedMember.ts b/src/services/codefixes/fixImportNonExportedMember.ts
index 56208667bdb5e..c7be6b5a9fe22 100644
--- a/src/services/codefixes/fixImportNonExportedMember.ts
+++ b/src/services/codefixes/fixImportNonExportedMember.ts
@@ -1,3 +1,9 @@
+import {
+ createCodeFixAction,
+ createCombinedCodeActions,
+ eachDiagnostic,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
canHaveExportModifier,
canHaveLocals,
@@ -30,13 +36,7 @@ import {
textChanges,
tryCast,
VariableStatement,
-} from "../_namespaces/ts";
-import {
- createCodeFixAction,
- createCombinedCodeActions,
- eachDiagnostic,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixImportNonExportedMember";
const errorCodes = [
@@ -119,7 +119,7 @@ function getInfo(sourceFile: SourceFile, pos: number, program: Program): Info |
const moduleSpecifier = isStringLiteral(importDeclaration.moduleSpecifier) ? importDeclaration.moduleSpecifier : undefined;
if (moduleSpecifier === undefined) return undefined;
- const resolvedModule = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier)?.resolvedModule;
+ const resolvedModule = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier, sourceFile)?.resolvedModule;
if (resolvedModule === undefined) return undefined;
const moduleSourceFile = program.getSourceFile(resolvedModule.resolvedFileName);
diff --git a/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts b/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts
index 4c831bac51529..7982f63b61ec5 100644
--- a/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts
+++ b/src/services/codefixes/fixIncorrectNamedTupleSyntax.ts
@@ -1,3 +1,7 @@
+import {
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
factory,
@@ -10,11 +14,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixIncorrectNamedTupleSyntax";
const errorCodes = [
diff --git a/src/services/codefixes/fixInvalidImportSyntax.ts b/src/services/codefixes/fixInvalidImportSyntax.ts
index 6301bf0ba6e16..2f2663825062f 100644
--- a/src/services/codefixes/fixInvalidImportSyntax.ts
+++ b/src/services/codefixes/fixInvalidImportSyntax.ts
@@ -1,3 +1,7 @@
+import {
+ createCodeFixActionWithoutFixAll,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
addRange,
CallExpression,
@@ -24,11 +28,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- createCodeFixActionWithoutFixAll,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixName = "invalidImportSyntax";
diff --git a/src/services/codefixes/fixInvalidJsxCharacters.ts b/src/services/codefixes/fixInvalidJsxCharacters.ts
index 744354c7fb87b..803bc8137a2d4 100644
--- a/src/services/codefixes/fixInvalidJsxCharacters.ts
+++ b/src/services/codefixes/fixInvalidJsxCharacters.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
hasProperty,
@@ -5,12 +10,7 @@ import {
SourceFile,
textChanges,
UserPreferences,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixIdExpression = "fixInvalidJsxCharacters_expression";
const fixIdHtmlEntity = "fixInvalidJsxCharacters_htmlEntity";
diff --git a/src/services/codefixes/fixJSDocTypes.ts b/src/services/codefixes/fixJSDocTypes.ts
index 2a35ba3fdb3a9..7d3983db3d48d 100644
--- a/src/services/codefixes/fixJSDocTypes.ts
+++ b/src/services/codefixes/fixJSDocTypes.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
append,
AsExpression,
@@ -30,12 +35,7 @@ import {
TypeFlags,
TypeNode,
VariableDeclaration,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixIdPlain = "fixJSDocTypes_plain";
const fixIdNullable = "fixJSDocTypes_nullable";
diff --git a/src/services/codefixes/fixMissingCallParentheses.ts b/src/services/codefixes/fixMissingCallParentheses.ts
index 5a254bc1392dc..5bbe7a04a58e3 100644
--- a/src/services/codefixes/fixMissingCallParentheses.ts
+++ b/src/services/codefixes/fixMissingCallParentheses.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
getTokenAtPosition,
@@ -8,12 +13,7 @@ import {
PropertyAccessExpression,
SourceFile,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixMissingCallParentheses";
const errorCodes = [
diff --git a/src/services/codefixes/fixMissingTypeAnnotationOnExports.ts b/src/services/codefixes/fixMissingTypeAnnotationOnExports.ts
index 9abf1758b64d2..70ceb0c31eba3 100644
--- a/src/services/codefixes/fixMissingTypeAnnotationOnExports.ts
+++ b/src/services/codefixes/fixMissingTypeAnnotationOnExports.ts
@@ -65,6 +65,7 @@ import {
isSpreadAssignment,
isSpreadElement,
isStatement,
+ isTypeNode,
isValueSignatureDeclaration,
isVariableDeclaration,
ModifierFlags,
@@ -94,7 +95,7 @@ import {
VariableDeclaration,
VariableStatement,
walkUpParenthesizedExpressions,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
createCodeFixAction,
@@ -103,8 +104,8 @@ import {
eachDiagnostic,
registerCodeFix,
typeToAutoImportableTypeNode,
-} from "../_namespaces/ts.codefix";
-import { getIdentifierForNode } from "../refactors/helpers";
+} from "../_namespaces/ts.codefix.js";
+import { getIdentifierForNode } from "../refactors/helpers.js";
const fixId = "fixMissingTypeAnnotationOnExports";
@@ -121,6 +122,7 @@ const errorCodes = [
Diagnostics.Property_must_have_an_explicit_type_annotation_with_isolatedDeclarations.code,
Diagnostics.Expression_type_can_t_be_inferred_with_isolatedDeclarations.code,
Diagnostics.Binding_elements_can_t_be_exported_directly_with_isolatedDeclarations.code,
+ Diagnostics.Computed_property_names_on_class_or_object_literals_cannot_be_inferred_with_isolatedDeclarations.code,
Diagnostics.Computed_properties_must_be_number_or_string_literals_variables_or_dotted_expressions_with_isolatedDeclarations.code,
Diagnostics.Enum_member_initializers_must_be_computable_without_references_to_external_symbols_with_isolatedDeclarations.code,
Diagnostics.Extends_clause_can_t_contain_an_expression_with_isolatedDeclarations.code,
@@ -131,6 +133,7 @@ const errorCodes = [
Diagnostics.Only_const_arrays_can_be_inferred_with_isolatedDeclarations.code,
Diagnostics.Assigning_properties_to_functions_without_declaring_them_is_not_supported_with_isolatedDeclarations_Add_an_explicit_declaration_for_the_properties_assigned_to_this_function.code,
Diagnostics.Declaration_emit_for_this_parameter_requires_implicitly_adding_undefined_to_it_s_type_This_is_not_supported_with_isolatedDeclarations.code,
+ Diagnostics.Type_containing_private_name_0_can_t_be_used_with_isolatedDeclarations.code,
Diagnostics.Add_satisfies_and_a_type_assertion_to_this_expression_satisfies_T_as_T_to_make_the_type_explicit.code,
];
@@ -180,7 +183,7 @@ registerCodeFix({
addCodeAction(addInlineTypeAssertion, fixes, context, TypePrintMode.Full, f => f.addInlineAssertion(context.span));
addCodeAction(addInlineTypeAssertion, fixes, context, TypePrintMode.Relative, f => f.addInlineAssertion(context.span));
- addCodeAction(addAnnotationFix, fixes, context, TypePrintMode.Widened, f => f.addInlineAssertion(context.span));
+ addCodeAction(addInlineTypeAssertion, fixes, context, TypePrintMode.Widened, f => f.addInlineAssertion(context.span));
addCodeAction(extractExpression, fixes, context, TypePrintMode.Full, f => f.extractAsVariable(context.span));
@@ -234,7 +237,6 @@ function withContext(
const sourceFile: SourceFile = context.sourceFile;
const program = context.program;
const typeChecker: TypeChecker = program.getTypeChecker();
- const emitResolver = typeChecker.getEmitResolver();
const scriptTarget = getEmitScriptTarget(program.getCompilerOptions());
const importAdder = createImportAdder(context.sourceFile, context.program, context.preferences, context.host);
const fixedNodes = new Set();
@@ -351,7 +353,7 @@ function withContext(
return undefined;
}
// No support for typeof in extends clauses
- if (isExpressionTarget && findAncestor(targetNode, isHeritageClause)) {
+ if (isExpressionTarget && (findAncestor(targetNode, isHeritageClause) || findAncestor(targetNode, isTypeNode))) {
return undefined;
}
// Can't inline type spread elements. Whatever you do isolated declarations will not infer from them
@@ -884,7 +886,7 @@ function withContext(
type = widenedType;
}
- if (isParameter(node) && emitResolver.requiresAddingImplicitUndefined(node)) {
+ if (isParameter(node) && typeChecker.requiresAddingImplicitUndefined(node)) {
type = typeChecker.getUnionType([typeChecker.getUndefinedType(), type], UnionReduction.None);
}
const flags = (
@@ -1105,26 +1107,26 @@ function withContext(
setEmitFlags(node, EmitFlags.None);
return result;
}
-}
-// Some --isolatedDeclarations errors are not present on the node that directly needs type annotation, so look in the
-// ancestors to look for node that needs type annotation. This function can return undefined if the AST is ill-formed.
-function findAncestorWithMissingType(node: Node): Node | undefined {
- return findAncestor(node, n => {
- return canHaveTypeAnnotation.has(n.kind) &&
- ((!isObjectBindingPattern(n) && !isArrayBindingPattern(n)) || isVariableDeclaration(n.parent));
- });
-}
-
-function findBestFittingNode(node: Node, span: TextSpan) {
- while (node && node.end < span.start + span.length) {
- node = node.parent;
- }
- while (node.parent.pos === node.pos && node.parent.end === node.end) {
- node = node.parent;
+ // Some --isolatedDeclarations errors are not present on the node that directly needs type annotation, so look in the
+ // ancestors to look for node that needs type annotation. This function can return undefined if the AST is ill-formed.
+ function findAncestorWithMissingType(node: Node): Node | undefined {
+ return findAncestor(node, n => {
+ return canHaveTypeAnnotation.has(n.kind) &&
+ ((!isObjectBindingPattern(n) && !isArrayBindingPattern(n)) || isVariableDeclaration(n.parent));
+ });
}
- if (isIdentifier(node) && hasInitializer(node.parent) && node.parent.initializer) {
- return node.parent.initializer;
+
+ function findBestFittingNode(node: Node, span: TextSpan) {
+ while (node && node.end < span.start + span.length) {
+ node = node.parent;
+ }
+ while (node.parent.pos === node.pos && node.parent.end === node.end) {
+ node = node.parent;
+ }
+ if (isIdentifier(node) && hasInitializer(node.parent) && node.parent.initializer) {
+ return node.parent.initializer;
+ }
+ return node;
}
- return node;
}
diff --git a/src/services/codefixes/fixModuleAndTargetOptions.ts b/src/services/codefixes/fixModuleAndTargetOptions.ts
index 5ae7d53a89438..8f24304624a05 100644
--- a/src/services/codefixes/fixModuleAndTargetOptions.ts
+++ b/src/services/codefixes/fixModuleAndTargetOptions.ts
@@ -1,3 +1,9 @@
+import {
+ createCodeFixActionWithoutFixAll,
+ registerCodeFix,
+ setJsonCompilerOptionValue,
+ setJsonCompilerOptionValues,
+} from "../_namespaces/ts.codefix.js";
import {
CodeFixAction,
Diagnostics,
@@ -9,13 +15,7 @@ import {
ModuleKind,
ScriptTarget,
textChanges,
-} from "../_namespaces/ts";
-import {
- createCodeFixActionWithoutFixAll,
- registerCodeFix,
- setJsonCompilerOptionValue,
- setJsonCompilerOptionValues,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
registerCodeFix({
errorCodes: [
diff --git a/src/services/codefixes/fixNaNEquality.ts b/src/services/codefixes/fixNaNEquality.ts
index bd64d8b82a70a..3e617cc77f303 100644
--- a/src/services/codefixes/fixNaNEquality.ts
+++ b/src/services/codefixes/fixNaNEquality.ts
@@ -1,3 +1,9 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ findAncestorMatchingSpan,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
BinaryExpression,
createTextSpan,
@@ -14,13 +20,7 @@ import {
SyntaxKind,
textChanges,
TextSpan,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- findAncestorMatchingSpan,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixNaNEquality";
const errorCodes = [
diff --git a/src/services/codefixes/fixNoPropertyAccessFromIndexSignature.ts b/src/services/codefixes/fixNoPropertyAccessFromIndexSignature.ts
index 3ae9b9045e223..2c5f37e715686 100644
--- a/src/services/codefixes/fixNoPropertyAccessFromIndexSignature.ts
+++ b/src/services/codefixes/fixNoPropertyAccessFromIndexSignature.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
cast,
Diagnostics,
@@ -11,12 +16,7 @@ import {
SourceFile,
textChanges,
UserPreferences,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixNoPropertyAccessFromIndexSignature";
const errorCodes = [
diff --git a/src/services/codefixes/fixOverrideModifier.ts b/src/services/codefixes/fixOverrideModifier.ts
index 2c3f8242a7ff5..360c7eda51c61 100644
--- a/src/services/codefixes/fixOverrideModifier.ts
+++ b/src/services/codefixes/fixOverrideModifier.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixActionMaybeFixAll,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
CodeFixAllContext,
CodeFixContext,
@@ -31,12 +36,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixActionMaybeFixAll,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixName = "fixOverrideModifier";
const fixAddOverrideId = "fixAddOverrideModifier";
diff --git a/src/services/codefixes/fixPropertyAssignment.ts b/src/services/codefixes/fixPropertyAssignment.ts
index d75fb8b365ac3..e24f3de7445c7 100644
--- a/src/services/codefixes/fixPropertyAssignment.ts
+++ b/src/services/codefixes/fixPropertyAssignment.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
cast,
Diagnostics,
@@ -8,12 +13,7 @@ import {
ShorthandPropertyAssignment,
SourceFile,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixPropertyAssignment";
const errorCodes = [
diff --git a/src/services/codefixes/fixPropertyOverrideAccessor.ts b/src/services/codefixes/fixPropertyOverrideAccessor.ts
index 4ee42dbbeee1e..c1b446bcf7d34 100644
--- a/src/services/codefixes/fixPropertyOverrideAccessor.ts
+++ b/src/services/codefixes/fixPropertyOverrideAccessor.ts
@@ -1,3 +1,10 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ generateAccessorFromProperty,
+ getAllSupers,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
CodeFixAllContext,
CodeFixContext,
@@ -11,14 +18,7 @@ import {
singleOrUndefined,
SourceFile,
unescapeLeadingUnderscores,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- generateAccessorFromProperty,
- getAllSupers,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const errorCodes = [
Diagnostics._0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property.code,
diff --git a/src/services/codefixes/fixReturnTypeInAsyncFunction.ts b/src/services/codefixes/fixReturnTypeInAsyncFunction.ts
index 8b33ec0c8cede..a6ada40a34175 100644
--- a/src/services/codefixes/fixReturnTypeInAsyncFunction.ts
+++ b/src/services/codefixes/fixReturnTypeInAsyncFunction.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
factory,
@@ -10,12 +15,7 @@ import {
Type,
TypeChecker,
TypeNode,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixReturnTypeInAsyncFunction";
const errorCodes = [
diff --git a/src/services/codefixes/fixSpelling.ts b/src/services/codefixes/fixSpelling.ts
index 8c2130ab57c91..21a32bd00c411 100644
--- a/src/services/codefixes/fixSpelling.ts
+++ b/src/services/codefixes/fixSpelling.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
CodeFixContextBase,
Debug,
@@ -36,12 +41,7 @@ import {
symbolName,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixSpelling";
const errorCodes = [
@@ -118,7 +118,7 @@ function getInfo(sourceFile: SourceFile, pos: number, context: CodeFixContextBas
else if (isImportSpecifier(parent) && parent.name === node) {
Debug.assertNode(node, isIdentifier, "Expected an identifier for spelling (import)");
const importDeclaration = findAncestor(node, isImportDeclaration)!;
- const resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(context, importDeclaration);
+ const resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(context, importDeclaration, sourceFile);
if (resolvedSourceFile && resolvedSourceFile.symbol) {
suggestedSymbol = checker.getSuggestedSymbolForNonexistentModule(node, resolvedSourceFile.symbol);
}
@@ -177,10 +177,10 @@ function convertSemanticMeaningToSymbolFlags(meaning: SemanticMeaning): SymbolFl
return flags;
}
-function getResolvedSourceFileFromImportDeclaration(context: CodeFixContextBase, importDeclaration: ImportDeclaration): SourceFile | undefined {
+function getResolvedSourceFileFromImportDeclaration(context: CodeFixContextBase, importDeclaration: ImportDeclaration, importingFile: SourceFile): SourceFile | undefined {
if (!importDeclaration || !isStringLiteralLike(importDeclaration.moduleSpecifier)) return undefined;
- const resolvedModule = context.program.getResolvedModuleFromModuleSpecifier(importDeclaration.moduleSpecifier)?.resolvedModule;
+ const resolvedModule = context.program.getResolvedModuleFromModuleSpecifier(importDeclaration.moduleSpecifier, importingFile)?.resolvedModule;
if (!resolvedModule) return undefined;
return context.program.getSourceFile(resolvedModule.resolvedFileName);
diff --git a/src/services/codefixes/fixStrictClassInitialization.ts b/src/services/codefixes/fixStrictClassInitialization.ts
index d42e858964a1b..4ce6108cea74e 100644
--- a/src/services/codefixes/fixStrictClassInitialization.ts
+++ b/src/services/codefixes/fixStrictClassInitialization.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
append,
BigIntLiteralType,
@@ -27,12 +32,7 @@ import {
TypeChecker,
TypeFlags,
TypeNode,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixName = "strictClassInitialization";
const fixIdAddDefiniteAssignmentAssertions = "addMissingPropertyDefiniteAssignmentAssertions";
diff --git a/src/services/codefixes/fixUnmatchedParameter.ts b/src/services/codefixes/fixUnmatchedParameter.ts
index bba50c32e589f..71a5c097deae0 100644
--- a/src/services/codefixes/fixUnmatchedParameter.ts
+++ b/src/services/codefixes/fixUnmatchedParameter.ts
@@ -1,3 +1,10 @@
+import {
+ createCodeFixAction,
+ createCodeFixActionWithoutFixAll,
+ createCombinedCodeActions,
+ eachDiagnostic,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
__String,
append,
@@ -21,14 +28,7 @@ import {
SignatureDeclaration,
SourceFile,
textChanges,
-} from "../_namespaces/ts";
-import {
- createCodeFixAction,
- createCodeFixActionWithoutFixAll,
- createCombinedCodeActions,
- eachDiagnostic,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const deleteUnmatchedParameter = "deleteUnmatchedParameter";
const renameUnmatchedParameter = "renameUnmatchedParameter";
diff --git a/src/services/codefixes/fixUnreachableCode.ts b/src/services/codefixes/fixUnreachableCode.ts
index 61c363c3fc868..948512305f27f 100644
--- a/src/services/codefixes/fixUnreachableCode.ts
+++ b/src/services/codefixes/fixUnreachableCode.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Debug,
Diagnostics,
@@ -13,12 +18,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixUnreachableCode";
const errorCodes = [Diagnostics.Unreachable_code_detected.code];
diff --git a/src/services/codefixes/fixUnreferenceableDecoratorMetadata.ts b/src/services/codefixes/fixUnreferenceableDecoratorMetadata.ts
index 4c35ee6b9629a..61c2a20949a4e 100644
--- a/src/services/codefixes/fixUnreferenceableDecoratorMetadata.ts
+++ b/src/services/codefixes/fixUnreferenceableDecoratorMetadata.ts
@@ -1,3 +1,7 @@
+import {
+ createCodeFixActionWithoutFixAll,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
append,
CodeFixAction,
@@ -23,11 +27,7 @@ import {
SyntaxKind,
textChanges,
tryCast,
-} from "../_namespaces/ts";
-import {
- createCodeFixActionWithoutFixAll,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixUnreferenceableDecoratorMetadata";
const errorCodes = [Diagnostics.A_type_referenced_in_a_decorated_signature_must_be_imported_with_import_type_or_a_namespace_import_when_isolatedModules_and_emitDecoratorMetadata_are_enabled.code];
diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts
index 9e3677d3e23b6..1974e8067a45f 100644
--- a/src/services/codefixes/fixUnusedIdentifier.ts
+++ b/src/services/codefixes/fixUnusedIdentifier.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
ArrayBindingPattern,
CancellationToken,
@@ -59,12 +64,7 @@ import {
TypeChecker,
VariableDeclaration,
VariableDeclarationList,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixName = "unusedIdentifier";
const fixIdPrefix = "unusedIdentifier_prefix";
diff --git a/src/services/codefixes/fixUnusedLabel.ts b/src/services/codefixes/fixUnusedLabel.ts
index 88e6aed5d41a6..0466f9c8419b2 100644
--- a/src/services/codefixes/fixUnusedLabel.ts
+++ b/src/services/codefixes/fixUnusedLabel.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
cast,
Diagnostics,
@@ -9,12 +14,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "fixUnusedLabel";
const errorCodes = [Diagnostics.Unused_label.code];
diff --git a/src/services/codefixes/generateAccessors.ts b/src/services/codefixes/generateAccessors.ts
index fe4af3faca1c1..75837f080749f 100644
--- a/src/services/codefixes/generateAccessors.ts
+++ b/src/services/codefixes/generateAccessors.ts
@@ -55,7 +55,7 @@ import {
textChanges,
TypeChecker,
TypeNode,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
/** @internal */
export type AcceptedDeclaration = ParameterPropertyDeclaration | PropertyDeclaration | PropertyAssignment;
diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts
index ee01e0f00a4b3..361141a7d8adf 100644
--- a/src/services/codefixes/helpers.ts
+++ b/src/services/codefixes/helpers.ts
@@ -1,3 +1,4 @@
+import { ImportAdder } from "../_namespaces/ts.codefix.js";
import {
AccessorDeclaration,
append,
@@ -110,8 +111,7 @@ import {
visitEachChild,
visitNode,
visitNodes,
-} from "../_namespaces/ts";
-import { ImportAdder } from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
/**
* Finds members of the resolved type that are missing in the class pointed to by class decl
@@ -397,7 +397,7 @@ export function createSignatureDeclarationFromSignature(
let typeParameters = isJs ? undefined : signatureDeclaration.typeParameters;
let parameters = signatureDeclaration.parameters;
- let type = isJs ? undefined : signatureDeclaration.type;
+ let type = isJs ? undefined : getSynthesizedDeepClone(signatureDeclaration.type);
if (importAdder) {
if (typeParameters) {
const newTypeParameters = sameMap(typeParameters, typeParameterDecl => {
diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts
index 0312c459d6c24..c584de5b475af 100644
--- a/src/services/codefixes/importFixes.ts
+++ b/src/services/codefixes/importFixes.ts
@@ -1,3 +1,9 @@
+import {
+ createCodeFixAction,
+ createCombinedCodeActions,
+ eachDiagnostic,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
AnyImportOrRequire,
AnyImportOrRequireStatement,
@@ -35,12 +41,12 @@ import {
flatMap,
flatMapIterator,
forEachExternalModuleToImportFrom,
+ forEachNameOfDefaultExport,
formatting,
FutureSourceFile,
FutureSymbolExportInfo,
getAllowSyntheticDefaultImports,
getBaseFileName,
- getDefaultExportInfoWorker,
getDefaultLikeExportInfo,
getDirectoryPath,
getEmitModuleFormatOfFileWorker,
@@ -49,7 +55,6 @@ import {
getEmitScriptTarget,
getExportInfoMap,
getImpliedNodeFormatForEmitWorker,
- getMeaningFromDeclaration,
getMeaningFromLocation,
getNameForExportedSymbol,
getOutputExtension,
@@ -65,6 +70,7 @@ import {
hasJSFileExtension,
hostGetCanonicalFileName,
Identifier,
+ identity,
ImportClause,
ImportEqualsDeclaration,
importFromModuleSpecifier,
@@ -75,8 +81,6 @@ import {
isExternalModuleReference,
isFullSourceFile,
isIdentifier,
- isIdentifierPart,
- isIdentifierStart,
isImportableFile,
isImportDeclaration,
isImportEqualsDeclaration,
@@ -90,7 +94,6 @@ import {
isNamespaceImport,
isRequireVariableStatement,
isSourceFileJS,
- isStringANonContextualKeyword,
isStringLiteral,
isStringLiteralLike,
isTypeOnlyImportDeclaration,
@@ -108,6 +111,7 @@ import {
ModuleKind,
moduleResolutionUsesNodeModules,
moduleSpecifiers,
+ moduleSymbolToValidIdentifier,
MultiMap,
Mutable,
NamedImports,
@@ -123,12 +127,9 @@ import {
pathIsBareSpecifier,
Program,
QuotePreference,
- removeFileExtension,
- removeSuffix,
RequireOrImportCall,
RequireVariableStatement,
sameMap,
- ScriptTarget,
SemanticMeaning,
shouldUseUriStyleNodeCoreModules,
single,
@@ -153,13 +154,7 @@ import {
TypeOnlyAliasDeclaration,
UserPreferences,
VariableDeclarationInitializedTo,
-} from "../_namespaces/ts";
-import {
- createCodeFixAction,
- createCombinedCodeActions,
- eachDiagnostic,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
/** @internal */
export const importFixName = "import";
@@ -345,6 +340,7 @@ function createImportAdderWorker(sourceFile: SourceFile | FutureSourceFile, prog
);
const fix: FixAddNewImport = {
kind: ImportFixKind.AddNew,
+ moduleSpecifierKind: "relative",
moduleSpecifier,
importKind,
addAsTypeOnly,
@@ -718,7 +714,7 @@ export function createImportSpecifierResolver(importingFile: SourceFile, program
importMap,
fromCacheOnly,
);
- const result = getBestFix(fixes, importingFile, program, packageJsonImportFilter, host);
+ const result = getBestFix(fixes, importingFile, program, packageJsonImportFilter, host, preferences);
return result && { ...result, computedWithoutCacheCount };
}
}
@@ -747,6 +743,7 @@ type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImpor
interface ImportFixBase {
readonly isReExport?: boolean;
readonly exportInfo?: SymbolExportInfo | FutureSymbolExportInfo;
+ readonly moduleSpecifierKind: moduleSpecifiers.ModuleSpecifierResult["kind"];
readonly moduleSpecifier: string;
}
interface Qualification {
@@ -855,7 +852,7 @@ export function getPromoteTypeOnlyCompletionAction(sourceFile: SourceFile, symbo
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);
+ return getBestFix(getImportFixes(exportInfos, position, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes, sourceFile, program, packageJsonImportFilter, host, preferences);
}
function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAction): CodeAction {
@@ -873,7 +870,6 @@ function getAllExportInfoForSymbol(importingFile: SourceFile | FutureSourceFile,
}
function getSingleExportInfoForSymbol(symbol: Symbol, symbolName: string, moduleSymbol: Symbol, program: Program, host: LanguageServiceHost): SymbolExportInfo {
- const compilerOptions = program.getCompilerOptions();
const mainProgramInfo = getInfoWithChecker(program.getTypeChecker(), /*isFromPackageJson*/ false);
if (mainProgramInfo) {
return mainProgramInfo;
@@ -882,7 +878,7 @@ function getSingleExportInfoForSymbol(symbol: Symbol, symbolName: string, module
return Debug.checkDefined(autoImportProvider && getInfoWithChecker(autoImportProvider, /*isFromPackageJson*/ true), `Could not find symbol in specified module for code actions`);
function getInfoWithChecker(checker: TypeChecker, isFromPackageJson: boolean): SymbolExportInfo | undefined {
- const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions);
+ const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker);
if (defaultInfo && skipAlias(defaultInfo.symbol, checker) === symbol) {
return { symbol: defaultInfo.symbol, moduleSymbol, moduleFileName: undefined, exportKind: defaultInfo.exportKind, targetFlags: skipAlias(symbol, checker).flags, isFromPackageJson };
}
@@ -893,10 +889,6 @@ 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[] | readonly FutureSymbolExportInfo[],
usagePosition: number | undefined,
@@ -910,7 +902,7 @@ function getImportFixes(
fromCacheOnly?: boolean,
): { computedWithoutCacheCount: number; fixes: readonly ImportFixWithModuleSpecifier[]; } {
const checker = program.getTypeChecker();
- const existingImports = importMap && !isFutureSymbolExportInfoArray(exportInfos) ? flatMap(exportInfos, importMap.getImportsForExportInfo) : emptyArray;
+ const existingImports = importMap ? flatMap(exportInfos, importMap.getImportsForExportInfo) : emptyArray;
const useNamespace = usagePosition !== undefined && tryUseExistingNamespaceImport(existingImports, usagePosition);
const addToExisting = tryAddToExistingImport(existingImports, isValidTypeOnlyUseSite, checker, program.getCompilerOptions());
if (addToExisting) {
@@ -957,7 +949,7 @@ function tryUseExistingNamespaceImport(existingImports: readonly FixAddToExistin
const namespacePrefix = getNamespaceLikeImportText(declaration);
const moduleSpecifier = namespacePrefix && tryGetModuleSpecifierFromDeclaration(declaration)?.text;
if (moduleSpecifier) {
- return { kind: ImportFixKind.UseNamespace, namespacePrefix, usagePosition: position, moduleSpecifier };
+ return { kind: ImportFixKind.UseNamespace, namespacePrefix, usagePosition: position, moduleSpecifierKind: undefined, moduleSpecifier };
}
});
}
@@ -1027,7 +1019,7 @@ function tryAddToExistingImport(existingImports: readonly FixAddToExistingImport
if (declaration.kind === SyntaxKind.VariableDeclaration) {
return (importKind === ImportKind.Named || importKind === ImportKind.Default) && declaration.name.kind === SyntaxKind.ObjectBindingPattern
- ? { kind: ImportFixKind.AddToExisting, importClauseOrBindingPattern: declaration.name, importKind, moduleSpecifier: declaration.initializer.arguments[0].text, addAsTypeOnly: AddAsTypeOnly.NotAllowed }
+ ? { kind: ImportFixKind.AddToExisting, importClauseOrBindingPattern: declaration.name, importKind, moduleSpecifierKind: undefined, moduleSpecifier: declaration.initializer.arguments[0].text, addAsTypeOnly: AddAsTypeOnly.NotAllowed }
: undefined;
}
@@ -1066,6 +1058,7 @@ function tryAddToExistingImport(existingImports: readonly FixAddToExistingImport
kind: ImportFixKind.AddToExisting,
importClauseOrBindingPattern: importClause,
importKind,
+ moduleSpecifierKind: undefined,
moduleSpecifier: declaration.moduleSpecifier.text,
addAsTypeOnly,
};
@@ -1092,7 +1085,7 @@ function createExistingImportMap(importingFile: SourceFile, program: Program) {
}
return {
- getImportsForExportInfo: ({ moduleSymbol, exportKind, targetFlags, symbol }: SymbolExportInfo): readonly FixAddToExistingImportInfo[] => {
+ getImportsForExportInfo: ({ moduleSymbol, exportKind, targetFlags, symbol }: SymbolExportInfo | FutureSymbolExportInfo): readonly FixAddToExistingImportInfo[] => {
const matchingDeclarations = importMap?.get(getSymbolId(moduleSymbol));
if (!matchingDeclarations) return emptyArray;
@@ -1164,13 +1157,13 @@ function getNewImportFixes(
const moduleResolution = getEmitModuleResolutionKind(compilerOptions);
const rejectNodeModulesRelativePaths = moduleResolutionUsesNodeModules(moduleResolution);
const getModuleSpecifiers = fromCacheOnly
- ? (exportInfo: SymbolExportInfo | FutureSymbolExportInfo) => ({ moduleSpecifiers: moduleSpecifiers.tryGetModuleSpecifiersFromCache(exportInfo.moduleSymbol, sourceFile, moduleSpecifierResolutionHost, preferences), computedWithoutCache: false })
+ ? (exportInfo: SymbolExportInfo | FutureSymbolExportInfo) => moduleSpecifiers.tryGetModuleSpecifiersFromCache(exportInfo.moduleSymbol, sourceFile, moduleSpecifierResolutionHost, preferences)
: (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, checker);
+ const { computedWithoutCache, moduleSpecifiers, kind: moduleSpecifierKind } = 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;
@@ -1180,7 +1173,7 @@ function getNewImportFixes(
}
if (!importedSymbolHasValueMeaning && isJs && usagePosition !== undefined) {
// `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 };
+ return { kind: ImportFixKind.JsdocTypeImport, moduleSpecifierKind, moduleSpecifier, usagePosition, exportInfo, isReExport: i > 0 };
}
const importKind = getImportKind(sourceFile, exportInfo.exportKind, program);
let qualification: Qualification | undefined;
@@ -1194,7 +1187,7 @@ function getNewImportFixes(
const exportEquals = checker.resolveExternalModuleSymbol(exportInfo.moduleSymbol);
let namespacePrefix;
if (exportEquals !== exportInfo.moduleSymbol) {
- namespacePrefix = getDefaultExportInfoWorker(exportEquals, checker, compilerOptions)?.name;
+ namespacePrefix = forEachNameOfDefaultExport(exportEquals, checker, compilerOptions, /*preferCapitalizedNames*/ false, identity)!;
}
namespacePrefix ||= moduleSymbolToValidIdentifier(
exportInfo.moduleSymbol,
@@ -1205,6 +1198,7 @@ function getNewImportFixes(
}
return {
kind: ImportFixKind.AddNew,
+ moduleSpecifierKind,
moduleSpecifier,
importKind,
useRequire,
@@ -1247,7 +1241,7 @@ function newImportInfoFromExistingSpecifier(
const addAsTypeOnly = useRequire
? AddAsTypeOnly.NotAllowed
: getAddAsTypeOnly(isValidTypeOnlyUseSite, /*isForNewImportDeclaration*/ true, symbol, targetFlags, checker, compilerOptions);
- return { kind: ImportFixKind.AddNew, moduleSpecifier, importKind, addAsTypeOnly, useRequire };
+ return { kind: ImportFixKind.AddNew, moduleSpecifierKind: undefined, moduleSpecifier, importKind, addAsTypeOnly, useRequire };
}
}
@@ -1276,24 +1270,24 @@ function getFixInfos(context: CodeFixContextBase, errorCode: number, pos: number
}
const packageJsonImportFilter = createPackageJsonImportFilter(context.sourceFile, context.preferences, context.host);
- return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host);
+ return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host, context.preferences);
}
-function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[] {
+function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost, preferences: UserPreferences): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[] {
const _toPath = (fileName: string) => toPath(fileName, host.getCurrentDirectory(), hostGetCanonicalFileName(host));
return sort(fixes, (a, b) =>
compareBooleans(!!a.isJsxNamespaceFix, !!b.isJsxNamespaceFix) ||
compareValues(a.fix.kind, b.fix.kind) ||
- compareModuleSpecifiers(a.fix, b.fix, sourceFile, program, packageJsonImportFilter.allowsImportingSpecifier, _toPath));
+ compareModuleSpecifiers(a.fix, b.fix, sourceFile, program, preferences, packageJsonImportFilter.allowsImportingSpecifier, _toPath));
}
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);
+ return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host, context.preferences);
}
-function getBestFix(fixes: readonly ImportFixWithModuleSpecifier[], sourceFile: SourceFile | FutureSourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): ImportFixWithModuleSpecifier | undefined {
+function getBestFix(fixes: readonly ImportFixWithModuleSpecifier[], sourceFile: SourceFile | FutureSourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost, preferences: UserPreferences): 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) {
@@ -1307,6 +1301,7 @@ function getBestFix(fixes: readonly ImportFixWithModuleSpecifier[], sourceFile:
best,
sourceFile,
program,
+ preferences,
packageJsonImportFilter.allowsImportingSpecifier,
fileName => toPath(fileName, host.getCurrentDirectory(), hostGetCanonicalFileName(host)),
) === Comparison.LessThan ? fix : best
@@ -1319,11 +1314,16 @@ function compareModuleSpecifiers(
b: ImportFixWithModuleSpecifier,
importingFile: SourceFile | FutureSourceFile,
program: Program,
+ preferences: UserPreferences,
allowsImportingSpecifier: (specifier: string) => boolean,
toPath: (fileName: string) => Path,
): Comparison {
if (a.kind !== ImportFixKind.UseNamespace && b.kind !== ImportFixKind.UseNamespace) {
- return compareBooleans(allowsImportingSpecifier(b.moduleSpecifier), allowsImportingSpecifier(a.moduleSpecifier))
+ return compareBooleans(
+ b.moduleSpecifierKind !== "node_modules" || allowsImportingSpecifier(b.moduleSpecifier),
+ a.moduleSpecifierKind !== "node_modules" || allowsImportingSpecifier(a.moduleSpecifier),
+ )
+ || compareModuleSpecifierRelativity(a, b, preferences)
|| compareNodeCoreModuleSpecifiers(a.moduleSpecifier, b.moduleSpecifier, importingFile, program)
|| compareBooleans(
isFixPossiblyReExportingImportingFile(a, importingFile.path, toPath),
@@ -1334,6 +1334,13 @@ function compareModuleSpecifiers(
return Comparison.EqualTo;
}
+function compareModuleSpecifierRelativity(a: ImportFixWithModuleSpecifier, b: ImportFixWithModuleSpecifier, preferences: UserPreferences): Comparison {
+ if (preferences.importModuleSpecifierPreference === "non-relative" || preferences.importModuleSpecifierPreference === "project-relative") {
+ return compareBooleans(a.moduleSpecifierKind === "relative", b.moduleSpecifierKind === "relative");
+ }
+ return Comparison.EqualTo;
+}
+
// This is a simple heuristic to try to avoid creating an import cycle with a barrel re-export.
// E.g., do not `import { Foo } from ".."` when you could `import { Foo } from "../Foo"`.
// This can produce false positives or negatives if re-exports cross into sibling directories
@@ -1533,14 +1540,18 @@ function getExportInfos(
cancellationToken.throwIfCancellationRequested();
const compilerOptions = program.getCompilerOptions();
- const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions);
- if (defaultInfo && (defaultInfo.name === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, getEmitScriptTarget(compilerOptions), isJsxTagName) === symbolName) && symbolHasMeaning(defaultInfo.resolvedSymbol, currentTokenMeaning)) {
+ const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker);
+ if (
+ defaultInfo
+ && symbolFlagsHaveMeaning(checker.getSymbolFlags(defaultInfo.symbol), currentTokenMeaning)
+ && forEachNameOfDefaultExport(defaultInfo.symbol, checker, compilerOptions, isJsxTagName, name => name === symbolName)
+ ) {
addSymbol(moduleSymbol, sourceFile, defaultInfo.symbol, defaultInfo.exportKind, program, isFromPackageJson);
}
// check exports with the same name
const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol);
- if (exportSymbolWithIdenticalName && symbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) {
+ if (exportSymbolWithIdenticalName && symbolFlagsHaveMeaning(checker.getSymbolFlags(exportSymbolWithIdenticalName), currentTokenMeaning)) {
addSymbol(moduleSymbol, sourceFile, exportSymbolWithIdenticalName, ExportKind.Named, program, isFromPackageJson);
}
});
@@ -1721,7 +1732,7 @@ function promoteFromTypeOnly(
// Change .ts extension to .js if necessary
if (!compilerOptions.allowImportingTsExtensions) {
const moduleSpecifier = tryGetModuleSpecifierFromDeclaration(importClause.parent);
- const resolvedModule = moduleSpecifier && program.getResolvedModuleFromModuleSpecifier(moduleSpecifier)?.resolvedModule;
+ const resolvedModule = moduleSpecifier && program.getResolvedModuleFromModuleSpecifier(moduleSpecifier, sourceFile)?.resolvedModule;
if (resolvedModule?.resolvedUsingTsExtension) {
const changedExtension = changeAnyExtension(moduleSpecifier!.text, getOutputExtension(moduleSpecifier!.text, compilerOptions));
changes.replaceNode(sourceFile, moduleSpecifier!, factory.createStringLiteral(changedExtension));
@@ -2009,44 +2020,12 @@ function createConstEqualsRequireDeclaration(name: string | ObjectBindingPattern
) as RequireVariableStatement;
}
-function symbolHasMeaning({ declarations }: Symbol, meaning: SemanticMeaning): boolean {
- return some(declarations, decl => !!(getMeaningFromDeclaration(decl) & meaning));
-}
-
-/** @internal */
-export function moduleSymbolToValidIdentifier(moduleSymbol: Symbol, target: ScriptTarget | undefined, forceCapitalize: boolean): string {
- return moduleSpecifierToValidIdentifier(removeFileExtension(stripQuotes(moduleSymbol.name)), target, forceCapitalize);
-}
-
-/** @internal */
-export function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget | undefined, forceCapitalize?: boolean): string {
- const baseName = getBaseFileName(removeSuffix(moduleSpecifier, "/index"));
- let res = "";
- let lastCharWasValid = true;
- const firstCharCode = baseName.charCodeAt(0);
- if (isIdentifierStart(firstCharCode, target)) {
- res += String.fromCharCode(firstCharCode);
- if (forceCapitalize) {
- res = res.toUpperCase();
- }
- }
- else {
- lastCharWasValid = false;
- }
- for (let i = 1; i < baseName.length; i++) {
- const ch = baseName.charCodeAt(i);
- const isValid = isIdentifierPart(ch, target);
- if (isValid) {
- let char = String.fromCharCode(ch);
- if (!lastCharWasValid) {
- char = char.toUpperCase();
- }
- res += char;
- }
- lastCharWasValid = isValid;
- }
- // Need `|| "_"` to ensure result isn't empty.
- return !isStringANonContextualKeyword(res) ? res || "_" : `_${res}`;
+function symbolFlagsHaveMeaning(flags: SymbolFlags, meaning: SemanticMeaning): boolean {
+ return meaning === SemanticMeaning.All ? true :
+ meaning & SemanticMeaning.Value ? !!(flags & SymbolFlags.Value) :
+ meaning & SemanticMeaning.Type ? !!(flags & SymbolFlags.Type) :
+ meaning & SemanticMeaning.Namespace ? !!(flags & SymbolFlags.Namespace) :
+ false;
}
function getImpliedNodeFormatForEmit(file: SourceFile | FutureSourceFile, program: Program) {
diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts
index 95a19e1d39638..620542686acab 100644
--- a/src/services/codefixes/inferFromUsage.ts
+++ b/src/services/codefixes/inferFromUsage.ts
@@ -1,3 +1,11 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ createImportAdder,
+ ImportAdder,
+ registerCodeFix,
+ tryGetAutoImportableReferenceFromTypeNode,
+} from "../_namespaces/ts.codefix.js";
import {
__String,
AnonymousType,
@@ -101,15 +109,7 @@ import {
UnionReduction,
UserPreferences,
VariableDeclaration,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- createImportAdder,
- ImportAdder,
- registerCodeFix,
- tryGetAutoImportableReferenceFromTypeNode,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "inferFromUsage";
const errorCodes = [
diff --git a/src/services/codefixes/removeAccidentalCallParentheses.ts b/src/services/codefixes/removeAccidentalCallParentheses.ts
index c4ad5c9ea3721..56f883cc54f6a 100644
--- a/src/services/codefixes/removeAccidentalCallParentheses.ts
+++ b/src/services/codefixes/removeAccidentalCallParentheses.ts
@@ -1,14 +1,14 @@
+import {
+ createCodeFixActionWithoutFixAll,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
findAncestor,
getTokenAtPosition,
isCallExpression,
textChanges,
-} from "../_namespaces/ts";
-import {
- createCodeFixActionWithoutFixAll,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "removeAccidentalCallParentheses";
const errorCodes = [
diff --git a/src/services/codefixes/removeUnnecessaryAwait.ts b/src/services/codefixes/removeUnnecessaryAwait.ts
index 45e6dcdef0dcd..1272ba512d38b 100644
--- a/src/services/codefixes/removeUnnecessaryAwait.ts
+++ b/src/services/codefixes/removeUnnecessaryAwait.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
AwaitKeyword,
Diagnostics,
@@ -13,12 +18,7 @@ import {
textChanges,
TextSpan,
tryCast,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "removeUnnecessaryAwait";
const errorCodes = [
diff --git a/src/services/codefixes/requireInTs.ts b/src/services/codefixes/requireInTs.ts
index 1c385d5ed0e19..f087722dbb047 100644
--- a/src/services/codefixes/requireInTs.ts
+++ b/src/services/codefixes/requireInTs.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
cast,
Debug,
@@ -21,12 +26,7 @@ import {
textChanges,
tryCast,
VariableStatement,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "requireInTs";
const errorCodes = [Diagnostics.require_call_may_be_converted_to_an_import.code];
diff --git a/src/services/codefixes/returnValueCorrect.ts b/src/services/codefixes/returnValueCorrect.ts
index 3aba6c183d29a..b021eb9f8105c 100644
--- a/src/services/codefixes/returnValueCorrect.ts
+++ b/src/services/codefixes/returnValueCorrect.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
append,
ArrowFunction,
@@ -39,12 +44,7 @@ import {
Type,
TypeChecker,
VariableLikeDeclaration,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "returnValueCorrect";
const fixIdAddReturnStatement = "fixAddReturnStatement";
diff --git a/src/services/codefixes/splitTypeOnlyImport.ts b/src/services/codefixes/splitTypeOnlyImport.ts
index 8ceba91300fbe..967d6fc837c10 100644
--- a/src/services/codefixes/splitTypeOnlyImport.ts
+++ b/src/services/codefixes/splitTypeOnlyImport.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
CodeFixContextBase,
Debug,
@@ -10,12 +15,7 @@ import {
SourceFile,
textChanges,
TextSpan,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const errorCodes = [Diagnostics.A_type_only_import_can_specify_a_default_import_or_named_bindings_but_not_both.code];
const fixId = "splitTypeOnlyImport";
diff --git a/src/services/codefixes/useBigintLiteral.ts b/src/services/codefixes/useBigintLiteral.ts
index 4492e176b5c57..33248f01b811b 100644
--- a/src/services/codefixes/useBigintLiteral.ts
+++ b/src/services/codefixes/useBigintLiteral.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Diagnostics,
factory,
@@ -7,12 +12,7 @@ import {
textChanges,
TextSpan,
tryCast,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "useBigintLiteral";
const errorCodes = [
diff --git a/src/services/codefixes/useDefaultImport.ts b/src/services/codefixes/useDefaultImport.ts
index 11d647517593a..a7efb9b98f33e 100644
--- a/src/services/codefixes/useDefaultImport.ts
+++ b/src/services/codefixes/useDefaultImport.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
AnyImportSyntax,
Diagnostics,
@@ -14,12 +19,7 @@ import {
SourceFile,
textChanges,
UserPreferences,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "useDefaultImport";
const errorCodes = [Diagnostics.Import_may_be_converted_to_a_default_import.code];
diff --git a/src/services/codefixes/wrapDecoratorInParentheses.ts b/src/services/codefixes/wrapDecoratorInParentheses.ts
index 10066eebda99f..74652e0794509 100644
--- a/src/services/codefixes/wrapDecoratorInParentheses.ts
+++ b/src/services/codefixes/wrapDecoratorInParentheses.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
Debug,
Diagnostics,
@@ -7,12 +12,7 @@ import {
isDecorator,
SourceFile,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixId = "wrapDecoratorInParentheses";
const errorCodes = [Diagnostics.Expression_must_be_enclosed_in_parentheses_to_be_used_as_a_decorator.code];
diff --git a/src/services/codefixes/wrapJsxInFragment.ts b/src/services/codefixes/wrapJsxInFragment.ts
index 11693d88a4c43..4c6c1470172e3 100644
--- a/src/services/codefixes/wrapJsxInFragment.ts
+++ b/src/services/codefixes/wrapJsxInFragment.ts
@@ -1,3 +1,8 @@
+import {
+ codeFixAll,
+ createCodeFixAction,
+ registerCodeFix,
+} from "../_namespaces/ts.codefix.js";
import {
BinaryExpression,
Diagnostics,
@@ -11,12 +16,7 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
-import {
- codeFixAll,
- createCodeFixAction,
- registerCodeFix,
-} from "../_namespaces/ts.codefix";
+} from "../_namespaces/ts.js";
const fixID = "wrapJsxInFragment";
const errorCodes = [Diagnostics.JSX_expressions_must_have_one_parent_element.code];
diff --git a/src/services/completions.ts b/src/services/completions.ts
index 386e53f2d8e19..d09e81736433f 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -1,3 +1,4 @@
+import { StringCompletions } from "./_namespaces/ts.Completions.js";
import {
__String,
addToSeen,
@@ -389,8 +390,7 @@ import {
UserPreferences,
VariableDeclaration,
walkUpParenthesizedExpressions,
-} from "./_namespaces/ts";
-import { StringCompletions } from "./_namespaces/ts.Completions";
+} from "./_namespaces/ts.js";
// Exported only for tests
/** @internal */
diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts
index 37faabf7b5328..0cb7654459ca4 100644
--- a/src/services/documentHighlights.ts
+++ b/src/services/documentHighlights.ts
@@ -81,7 +81,7 @@ import {
toPath,
tryCast,
TryStatement,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export interface DocumentHighlights {
fileName: string;
diff --git a/src/services/documentRegistry.ts b/src/services/documentRegistry.ts
index fc42cacce7d5b..5c9aefd0a0a05 100644
--- a/src/services/documentRegistry.ts
+++ b/src/services/documentRegistry.ts
@@ -28,7 +28,7 @@ import {
toPath,
tracing,
updateLanguageServiceSourceFile,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/**
* The document registry represents a store of SourceFile objects that can be shared between
diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts
index f7c6521448d3a..24d0c7b9b8000 100644
--- a/src/services/exportInfoMap.ts
+++ b/src/services/exportInfoMap.ts
@@ -1,6 +1,7 @@
import {
__String,
addToSeen,
+ append,
arrayIsEqualTo,
CancellationToken,
CompilerOptions,
@@ -10,15 +11,15 @@ import {
emptyArray,
ensureTrailingDirectorySeparator,
findIndex,
- firstDefined,
forEachAncestorDirectory,
forEachEntry,
FutureSourceFile,
getBaseFileName,
GetCanonicalFileName,
+ getDefaultLikeExportNameFromDeclaration,
getDirectoryPath,
+ getEmitScriptTarget,
getLocalSymbolForExportDefault,
- getNameForExportedSymbol,
getNamesForExportedSymbol,
getNodeModulePathParts,
getPackageNameFromTypesPackageName,
@@ -28,12 +29,9 @@ import {
hostGetCanonicalFileName,
hostUsesCaseSensitiveFileNames,
InternalSymbolName,
- isExportAssignment,
- isExportSpecifier,
isExternalModuleNameRelative,
isExternalModuleSymbol,
isExternalOrCommonJsModule,
- isIdentifier,
isKnownSymbol,
isNonGlobalAmbientModule,
isPrivateIdentifierSymbol,
@@ -42,13 +40,13 @@ import {
ModuleSpecifierCache,
ModuleSpecifierResolutionHost,
moduleSpecifiers,
+ moduleSymbolToValidIdentifier,
nodeModulesPathPart,
PackageJsonImportFilter,
Path,
pathContainsNodeModules,
Program,
skipAlias,
- skipOuterExpressions,
SourceFile,
startsWith,
Statement,
@@ -56,12 +54,11 @@ import {
Symbol,
SymbolFlags,
timestamp,
- tryCast,
TypeChecker,
unescapeLeadingUnderscores,
unmangleScopedPackageName,
UserPreferences,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export const enum ImportKind {
@@ -502,14 +499,13 @@ export function getExportInfoMap(importingFile: SourceFile | FutureSourceFile, h
}
host.log?.("getExportInfoMap: cache miss or empty; calculating new results");
- const compilerOptions = program.getCompilerOptions();
let moduleCount = 0;
try {
forEachExternalModuleToImportFrom(program, host, preferences, /*useAutoImportProvider*/ true, (moduleSymbol, moduleFile, program, isFromPackageJson) => {
if (++moduleCount % 100 === 0) cancellationToken?.throwIfCancellationRequested();
const seenExports = new Map<__String, true>();
const checker = program.getTypeChecker();
- const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker, compilerOptions);
+ const defaultInfo = getDefaultLikeExportInfo(moduleSymbol, checker);
// Note: I think we shouldn't actually see resolved module symbols here, but weird merges
// can cause it to happen: see 'completionsImport_mergedReExport.ts'
if (defaultInfo && isImportableSymbol(defaultInfo.symbol, checker)) {
@@ -551,61 +547,49 @@ export function getExportInfoMap(importingFile: SourceFile | FutureSourceFile, h
}
/** @internal */
-export function getDefaultLikeExportInfo(moduleSymbol: Symbol, checker: TypeChecker, compilerOptions: CompilerOptions) {
- const exported = getDefaultLikeExportWorker(moduleSymbol, checker);
- if (!exported) return undefined;
- const { symbol, exportKind } = exported;
- const info = getDefaultExportInfoWorker(symbol, checker, compilerOptions);
- return info && { symbol, exportKind, ...info };
+export function getDefaultLikeExportInfo(moduleSymbol: Symbol, checker: TypeChecker) {
+ const exportEquals = checker.resolveExternalModuleSymbol(moduleSymbol);
+ if (exportEquals !== moduleSymbol) return { symbol: exportEquals, exportKind: ExportKind.ExportEquals };
+ const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol);
+ if (defaultExport) return { symbol: defaultExport, exportKind: ExportKind.Default };
}
function isImportableSymbol(symbol: Symbol, checker: TypeChecker) {
return !checker.isUndefinedSymbol(symbol) && !checker.isUnknownSymbol(symbol) && !isKnownSymbol(symbol) && !isPrivateIdentifierSymbol(symbol);
}
-function getDefaultLikeExportWorker(moduleSymbol: Symbol, checker: TypeChecker): { readonly symbol: Symbol; readonly exportKind: ExportKind; } | undefined {
- const exportEquals = checker.resolveExternalModuleSymbol(moduleSymbol);
- if (exportEquals !== moduleSymbol) return { symbol: exportEquals, exportKind: ExportKind.ExportEquals };
- const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol);
- if (defaultExport) return { symbol: defaultExport, exportKind: ExportKind.Default };
-}
+/**
+ * @internal
+ * May call `cb` multiple times with the same name.
+ * Terminates when `cb` returns a truthy value.
+ */
+export function forEachNameOfDefaultExport(defaultExport: Symbol, checker: TypeChecker, compilerOptions: CompilerOptions, preferCapitalizedNames: boolean, cb: (name: string) => T | undefined): T | undefined {
+ let chain: Symbol[] | undefined;
+ let current: Symbol | undefined = defaultExport;
+
+ while (current) {
+ // The predecessor to this function also looked for a name on the `localSymbol`
+ // of default exports, but I think `getDefaultLikeExportNameFromDeclaration`
+ // accomplishes the same thing via syntax - no tests failed when I removed it.
+ const fromDeclaration = getDefaultLikeExportNameFromDeclaration(current);
+ if (fromDeclaration) {
+ const final = cb(fromDeclaration);
+ if (final) return final;
+ }
-/** @internal */
-export function getDefaultExportInfoWorker(defaultExport: Symbol, checker: TypeChecker, compilerOptions: CompilerOptions): { readonly resolvedSymbol: Symbol; readonly name: string; } | undefined {
- const localSymbol = getLocalSymbolForExportDefault(defaultExport);
- if (localSymbol) return { resolvedSymbol: localSymbol, name: localSymbol.name };
-
- const name = getNameForExportDefault(defaultExport);
- if (name !== undefined) return { resolvedSymbol: defaultExport, name };
-
- if (defaultExport.flags & SymbolFlags.Alias) {
- const aliased = checker.getImmediateAliasedSymbol(defaultExport);
- if (aliased && aliased.parent) {
- // - `aliased` will be undefined if the module is exporting an unresolvable name,
- // but we can still offer completions for it.
- // - `aliased.parent` will be undefined if the module is exporting `globalThis.something`,
- // or another expression that resolves to a global.
- return getDefaultExportInfoWorker(aliased, checker, compilerOptions);
+ if (current.escapedName !== InternalSymbolName.Default && current.escapedName !== InternalSymbolName.ExportEquals) {
+ const final = cb(current.name);
+ if (final) return final;
}
- }
- if (
- defaultExport.escapedName !== InternalSymbolName.Default &&
- defaultExport.escapedName !== InternalSymbolName.ExportEquals
- ) {
- return { resolvedSymbol: defaultExport, name: defaultExport.getName() };
+ chain = append(chain, current);
+ current = current.flags & SymbolFlags.Alias ? checker.getImmediateAliasedSymbol(current) : undefined;
}
- return { resolvedSymbol: defaultExport, name: getNameForExportedSymbol(defaultExport, compilerOptions.target) };
-}
-function getNameForExportDefault(symbol: Symbol): string | undefined {
- return symbol.declarations && firstDefined(symbol.declarations, declaration => {
- if (isExportAssignment(declaration)) {
- return tryCast(skipOuterExpressions(declaration.expression), isIdentifier)?.text;
- }
- else if (isExportSpecifier(declaration)) {
- Debug.assert(declaration.name.text === InternalSymbolName.Default, "Expected the specifier to be a default export");
- return declaration.propertyName && declaration.propertyName.text;
+ for (const symbol of chain ?? emptyArray) {
+ if (symbol.parent && isExternalModuleSymbol(symbol.parent)) {
+ const final = cb(moduleSymbolToValidIdentifier(symbol.parent, getEmitScriptTarget(compilerOptions), preferCapitalizedNames));
+ if (final) return final;
}
- });
+ }
}
diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts
index 9276c30ad8dba..7abf2257b6386 100644
--- a/src/services/findAllReferences.ts
+++ b/src/services/findAllReferences.ts
@@ -1,3 +1,15 @@
+import {
+ createImportTracker,
+ ExportInfo,
+ ExportKind,
+ findModuleReferences,
+ getExportInfo,
+ getImportOrExportSymbol,
+ ImportExport,
+ ImportsResult,
+ ImportTracker,
+ ModuleReference,
+} from "./_namespaces/ts.FindAllReferences.js";
import {
__String,
addToSeen,
@@ -253,19 +265,7 @@ import {
TypeChecker,
TypeLiteralNode,
VariableDeclaration,
-} from "./_namespaces/ts";
-import {
- createImportTracker,
- ExportInfo,
- ExportKind,
- findModuleReferences,
- getExportInfo,
- getImportOrExportSymbol,
- ImportExport,
- ImportsResult,
- ImportTracker,
- ModuleReference,
-} from "./_namespaces/ts.FindAllReferences";
+} from "./_namespaces/ts.js";
/** @internal */
export interface SymbolAndEntries {
@@ -757,7 +757,7 @@ interface PrefixAndSuffix {
readonly suffixText?: string;
}
function getPrefixAndSuffixText(entry: Entry, originalNode: Node, checker: TypeChecker, quotePreference: QuotePreference): PrefixAndSuffix {
- if (entry.kind !== EntryKind.Span && isIdentifier(originalNode)) {
+ if (entry.kind !== EntryKind.Span && (isIdentifier(originalNode) || isStringLiteralLike(originalNode))) {
const { node, kind } = entry;
const parent = node.parent;
const name = originalNode.text;
diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts
index 881a26c5e4e8a..2dc19c021e302 100644
--- a/src/services/formatting/formatting.ts
+++ b/src/services/formatting/formatting.ts
@@ -1,3 +1,14 @@
+import {
+ FormattingContext,
+ FormattingRequestKind,
+ FormattingScanner,
+ getFormattingScanner,
+ Rule,
+ RuleAction,
+ RuleFlags,
+ RulesMap,
+ SmartIndenter,
+} from "../_namespaces/ts.formatting.js";
import {
Block,
CallExpression,
@@ -65,18 +76,7 @@ import {
TextRange,
TriviaSyntaxKind,
TypeReferenceNode,
-} from "../_namespaces/ts";
-import {
- FormattingContext,
- FormattingRequestKind,
- FormattingScanner,
- getFormattingScanner,
- Rule,
- RuleAction,
- RuleFlags,
- RulesMap,
- SmartIndenter,
-} from "../_namespaces/ts.formatting";
+} from "../_namespaces/ts.js";
/** @internal */
export interface FormatContext {
diff --git a/src/services/formatting/formattingContext.ts b/src/services/formatting/formattingContext.ts
index be23fe764396b..f41b7ee0ca283 100644
--- a/src/services/formatting/formattingContext.ts
+++ b/src/services/formatting/formattingContext.ts
@@ -1,3 +1,4 @@
+import { TextRangeWithKind } from "../_namespaces/ts.formatting.js";
import {
Debug,
findChildOfKind,
@@ -5,8 +6,7 @@ import {
Node,
SourceFileLike,
SyntaxKind,
-} from "../_namespaces/ts";
-import { TextRangeWithKind } from "../_namespaces/ts.formatting";
+} from "../_namespaces/ts.js";
/** @internal */
export const enum FormattingRequestKind {
diff --git a/src/services/formatting/formattingScanner.ts b/src/services/formatting/formattingScanner.ts
index 78890ad3a29b3..8a3baa2d13896 100644
--- a/src/services/formatting/formattingScanner.ts
+++ b/src/services/formatting/formattingScanner.ts
@@ -1,3 +1,9 @@
+import {
+ createTextRangeWithKind,
+ TextRangeWithKind,
+ TextRangeWithTriviaKind,
+ TokenInfo,
+} from "../_namespaces/ts.formatting.js";
import {
append,
createScanner,
@@ -14,13 +20,7 @@ import {
NodeArray,
ScriptTarget,
SyntaxKind,
-} from "../_namespaces/ts";
-import {
- createTextRangeWithKind,
- TextRangeWithKind,
- TextRangeWithTriviaKind,
- TokenInfo,
-} from "../_namespaces/ts.formatting";
+} from "../_namespaces/ts.js";
const standardScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.Standard);
const jsxScanner = createScanner(ScriptTarget.Latest, /*skipTrivia*/ false, LanguageVariant.JSX);
diff --git a/src/services/formatting/rule.ts b/src/services/formatting/rule.ts
index ba4293102644e..4e10219d8e335 100644
--- a/src/services/formatting/rule.ts
+++ b/src/services/formatting/rule.ts
@@ -1,8 +1,8 @@
+import { FormattingContext } from "../_namespaces/ts.formatting.js";
import {
emptyArray,
SyntaxKind,
-} from "../_namespaces/ts";
-import { FormattingContext } from "../_namespaces/ts.formatting";
+} from "../_namespaces/ts.js";
/** @internal */
export interface Rule {
diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts
index 39a94b032fd66..806dc6003f510 100644
--- a/src/services/formatting/rules.ts
+++ b/src/services/formatting/rules.ts
@@ -1,3 +1,14 @@
+import {
+ anyContext,
+ ContextPredicate,
+ FormattingContext,
+ FormattingRequestKind,
+ Rule,
+ RuleAction,
+ RuleFlags,
+ TextRangeWithKind,
+ TokenRange,
+} from "../_namespaces/ts.formatting.js";
import {
BinaryExpression,
contains,
@@ -20,18 +31,7 @@ import {
SyntaxKind,
typeKeywords,
YieldExpression,
-} from "../_namespaces/ts";
-import {
- anyContext,
- ContextPredicate,
- FormattingContext,
- FormattingRequestKind,
- Rule,
- RuleAction,
- RuleFlags,
- TextRangeWithKind,
- TokenRange,
-} from "../_namespaces/ts.formatting";
+} from "../_namespaces/ts.js";
/** @internal */
export interface RuleSpec {
diff --git a/src/services/formatting/rulesMap.ts b/src/services/formatting/rulesMap.ts
index 15ee6fa629043..d3145b2728d64 100644
--- a/src/services/formatting/rulesMap.ts
+++ b/src/services/formatting/rulesMap.ts
@@ -1,10 +1,3 @@
-import {
- Debug,
- every,
- FormatCodeSettings,
- FormattingHost,
- SyntaxKind,
-} from "../_namespaces/ts";
import {
anyContext,
FormatContext,
@@ -13,7 +6,14 @@ import {
Rule,
RuleAction,
RuleSpec,
-} from "../_namespaces/ts.formatting";
+} from "../_namespaces/ts.formatting.js";
+import {
+ Debug,
+ every,
+ FormatCodeSettings,
+ FormattingHost,
+ SyntaxKind,
+} from "../_namespaces/ts.js";
/** @internal */
export function getFormatContext(options: FormatCodeSettings, host: FormattingHost): FormatContext {
diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts
index ca0936f3f7851..c2141602f1108 100644
--- a/src/services/formatting/smartIndenter.ts
+++ b/src/services/formatting/smartIndenter.ts
@@ -1,3 +1,7 @@
+import {
+ getRangeOfEnclosingComment,
+ TextRangeWithKind,
+} from "../_namespaces/ts.formatting.js";
import {
ArrayBindingPattern,
ArrayLiteralExpression,
@@ -52,11 +56,7 @@ import {
TypeLiteralNode,
TypeReferenceNode,
VariableDeclarationList,
-} from "../_namespaces/ts";
-import {
- getRangeOfEnclosingComment,
- TextRangeWithKind,
-} from "../_namespaces/ts.formatting";
+} from "../_namespaces/ts.js";
/** @internal */
export namespace SmartIndenter {
diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts
index 860202a0bb285..cffc15aeeabb3 100644
--- a/src/services/getEditsForFileRename.ts
+++ b/src/services/getEditsForFileRename.ts
@@ -48,7 +48,7 @@ import {
TextRange,
tryRemoveDirectoryPrefix,
UserPreferences,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export function getEditsForFileRename(
@@ -247,7 +247,7 @@ function getSourceFileToImport(
else {
const mode = program.getModeForUsageLocation(importingSourceFile, importLiteral);
const resolved = host.resolveModuleNameLiterals || !host.resolveModuleNames ?
- program.getResolvedModuleFromModuleSpecifier(importLiteral) :
+ program.getResolvedModuleFromModuleSpecifier(importLiteral, importingSourceFile) :
host.getResolvedModuleWithFailedLookupLocationsFromCache && host.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName, mode);
return getSourceFileToImportFromResolved(importLiteral, resolved, oldToNew, program.getSourceFiles());
}
diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts
index 8fbfbe145e6ef..a576f684ede54 100644
--- a/src/services/goToDefinition.ts
+++ b/src/services/goToDefinition.ts
@@ -1,3 +1,4 @@
+import { isContextWithStartAndEndNode } from "./_namespaces/ts.FindAllReferences.js";
import {
AssignmentDeclarationKind,
AssignmentExpression,
@@ -105,8 +106,7 @@ import {
TypeFlags,
TypeReference,
unescapeLeadingUnderscores,
-} from "./_namespaces/ts";
-import { isContextWithStartAndEndNode } from "./_namespaces/ts.FindAllReferences";
+} from "./_namespaces/ts.js";
/** @internal */
export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile, position: number, searchOtherFilesOnly?: boolean, stopAtAlias?: boolean): readonly DefinitionInfo[] | undefined {
@@ -199,7 +199,7 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
if (!symbol && isModuleSpecifierLike(fallbackNode)) {
// We couldn't resolve the module specifier as an external module, but it could
// be that module resolution succeeded but the target was not a module.
- const ref = program.getResolvedModuleFromModuleSpecifier(fallbackNode)?.resolvedModule;
+ const ref = program.getResolvedModuleFromModuleSpecifier(fallbackNode, sourceFile)?.resolvedModule;
if (ref) {
return [{
name: fallbackNode.text,
@@ -225,7 +225,7 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
const calledDeclaration = tryGetSignatureDeclaration(typeChecker, node);
// Don't go to the component constructor definition for a JSX element, just go to the component definition.
- if (calledDeclaration && !(isJsxOpeningLikeElement(node.parent) && isConstructorLike(calledDeclaration))) {
+ if (calledDeclaration && !(isJsxOpeningLikeElement(node.parent) && isJsxConstructorLike(calledDeclaration))) {
const sigInfo = createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration, failedAliasResolution);
// For a function, if this is the original function definition, return just sigInfo.
// If this is the original constructor definition, parent is the class.
@@ -341,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 || program.getDefaultResolutionModeForFile(sourceFile))?.resolvedTypeReferenceDirective;
+ const reference = program.getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(typeReferenceDirective, sourceFile)?.resolvedTypeReferenceDirective;
const file = reference && program.getSourceFile(reference.resolvedFileName!); // TODO:GH#18217
return file && { reference: typeReferenceDirective, fileName: file.fileName, file, unverified: false };
}
@@ -355,7 +355,7 @@ export function getReferenceAtPosition(sourceFile: SourceFile, position: number,
if (sourceFile.imports.length || sourceFile.moduleAugmentations.length) {
const node = getTouchingToken(sourceFile, position);
let resolution: ResolvedModuleWithFailedLookupLocations | undefined;
- if (isModuleSpecifierLike(node) && isExternalModuleNameRelative(node.text) && (resolution = program.getResolvedModuleFromModuleSpecifier(node))) {
+ if (isModuleSpecifierLike(node) && isExternalModuleNameRelative(node.text) && (resolution = program.getResolvedModuleFromModuleSpecifier(node, sourceFile))) {
const verifiedFileName = resolution.resolvedModule?.resolvedFileName;
const fileName = verifiedFileName || resolvePath(getDirectoryPath(sourceFile.fileName), node.text);
return {
@@ -741,10 +741,11 @@ function tryGetSignatureDeclaration(typeChecker: TypeChecker, node: Node): Signa
return tryCast(signature && signature.declaration, (d): d is SignatureDeclaration => isFunctionLike(d) && !isFunctionTypeNode(d));
}
-function isConstructorLike(node: Node): boolean {
+function isJsxConstructorLike(node: Node): boolean {
switch (node.kind) {
case SyntaxKind.Constructor:
case SyntaxKind.ConstructorType:
+ case SyntaxKind.CallSignature:
case SyntaxKind.ConstructSignature:
return true;
default:
diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts
index 516df4dbdb5b4..ade3cd39edd2a 100644
--- a/src/services/importTracker.ts
+++ b/src/services/importTracker.ts
@@ -83,7 +83,7 @@ import {
ValidImportTypeNode,
VariableDeclaration,
walkUpBindingElementsAndPatterns,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/* Code for finding imports of an exported symbol. Used only by FindAllReferences. */
@@ -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 || program.getDefaultResolutionModeForFile(referencingFile))?.resolvedTypeReferenceDirective;
+ const referenced = program.getResolvedTypeReferenceDirectiveFromTypeReferenceDirective(ref, referencingFile)?.resolvedTypeReferenceDirective;
if (referenced !== undefined && referenced.resolvedFileName === (searchSourceFile as SourceFile).fileName) {
refs.push({ kind: "reference", referencingFile, ref });
}
diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts
index ed084912c6863..ce779052a053a 100644
--- a/src/services/inlayHints.ts
+++ b/src/services/inlayHints.ts
@@ -123,7 +123,7 @@ import {
UserPreferences,
usingSingleLineStringWriter,
VariableDeclaration,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
const leadingParameterNameCommentRegexFactory = (name: string) => {
return new RegExp(`^\\s?/\\*\\*?\\s?${name}\\s?\\*\\/\\s?$`);
diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts
index a08937cfd7e99..94664ce5d4332 100644
--- a/src/services/jsDoc.ts
+++ b/src/services/jsDoc.ts
@@ -92,7 +92,7 @@ import {
TypeChecker,
typeParameterNamePart,
VariableStatement,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
const jsDocTagNames = [
"abstract",
diff --git a/src/services/mapCode.ts b/src/services/mapCode.ts
new file mode 100644
index 0000000000000..b87ea5e75301f
--- /dev/null
+++ b/src/services/mapCode.ts
@@ -0,0 +1,323 @@
+import {
+ Block,
+ ClassElement,
+ ClassLikeDeclaration,
+ createSourceFile,
+ FileTextChanges,
+ find,
+ findAncestor,
+ findLast,
+ flatten,
+ forEach,
+ formatting,
+ getTokenAtPosition,
+ isBlock,
+ isClassElement,
+ isClassLike,
+ isForInOrOfStatement,
+ isForStatement,
+ isIfStatement,
+ isInterfaceDeclaration,
+ isLabeledStatement,
+ isNamedDeclaration,
+ isSourceFile,
+ isTypeElement,
+ isWhileStatement,
+ LanguageServiceHost,
+ Mutable,
+ Node,
+ NodeArray,
+ or,
+ some,
+ SourceFile,
+ Statement,
+ SyntaxKind,
+ textChanges,
+ TextSpan,
+ TypeElement,
+ UserPreferences,
+} from "./_namespaces/ts.js";
+import { ChangeTracker } from "./textChanges.js";
+
+/** @internal */
+export function mapCode(
+ sourceFile: SourceFile,
+ contents: string[],
+ focusLocations: TextSpan[][] | undefined,
+ host: LanguageServiceHost,
+ formatContext: formatting.FormatContext,
+ preferences: UserPreferences,
+): FileTextChanges[] {
+ return textChanges.ChangeTracker.with(
+ { host, formatContext, preferences },
+ changeTracker => {
+ const parsed = contents.map(c => parse(sourceFile, c));
+ const flattenedLocations = focusLocations && flatten(focusLocations);
+ for (const nodes of parsed) {
+ placeNodeGroup(
+ sourceFile,
+ changeTracker,
+ nodes,
+ flattenedLocations,
+ );
+ }
+ },
+ );
+}
+
+/**
+ * Tries to parse something into either "top-level" statements, or into blocks
+ * of class-context definitions.
+ */
+function parse(sourceFile: SourceFile, content: string): NodeArray {
+ // We're going to speculatively parse different kinds of contexts to see
+ // which one makes the most sense, and grab the NodeArray from there. Do
+ // this as lazily as possible.
+ const nodeKinds = [
+ {
+ parse: () =>
+ createSourceFile(
+ "__mapcode_content_nodes.ts",
+ content,
+ sourceFile.languageVersion,
+ /*setParentNodes*/ true,
+ sourceFile.scriptKind,
+ ),
+ body: (sf: SourceFile) => sf.statements,
+ },
+ {
+ parse: () =>
+ createSourceFile(
+ "__mapcode_class_content_nodes.ts",
+ `class __class {\n${content}\n}`,
+ sourceFile.languageVersion,
+ /*setParentNodes*/ true,
+ sourceFile.scriptKind,
+ ),
+ body: (cw: SourceFile) => (cw.statements[0] as ClassLikeDeclaration).members,
+ },
+ ];
+
+ const parsedNodes = [];
+ for (const { parse, body } of nodeKinds) {
+ const sourceFile = parse();
+ const bod = body(sourceFile);
+ if (bod.length && sourceFile.parseDiagnostics.length === 0) {
+ // If we run into a case with no parse errors, this is likely the right kind.
+ return bod;
+ }
+ // We only want to keep the ones that have some kind of body.
+ else if (bod.length) {
+ // Otherwise, we'll need to look at others.
+ parsedNodes.push({ sourceFile, body: bod });
+ }
+ }
+ // Heuristic: fewer errors = more likely to be the right kind.
+ const { body } = parsedNodes.sort(
+ (a, b) =>
+ a.sourceFile.parseDiagnostics.length -
+ b.sourceFile.parseDiagnostics.length,
+ )[0];
+ return body;
+}
+
+function placeNodeGroup(
+ originalFile: SourceFile,
+ changeTracker: ChangeTracker,
+ changes: NodeArray,
+ focusLocations?: TextSpan[],
+) {
+ if (isClassElement(changes[0]) || isTypeElement(changes[0])) {
+ placeClassNodeGroup(
+ originalFile,
+ changeTracker,
+ changes as NodeArray,
+ focusLocations,
+ );
+ }
+ else {
+ placeStatements(
+ originalFile,
+ changeTracker,
+ changes as NodeArray,
+ focusLocations,
+ );
+ }
+}
+
+function placeClassNodeGroup(
+ originalFile: SourceFile,
+ changeTracker: ChangeTracker,
+ changes: NodeArray | NodeArray,
+ focusLocations?: TextSpan[],
+) {
+ let classOrInterface;
+ if (!focusLocations || !focusLocations.length) {
+ classOrInterface = find(originalFile.statements, or(isClassLike, isInterfaceDeclaration));
+ }
+ else {
+ classOrInterface = forEach(focusLocations, location =>
+ findAncestor(
+ getTokenAtPosition(originalFile, location.start),
+ or(isClassLike, isInterfaceDeclaration),
+ ));
+ }
+
+ if (!classOrInterface) {
+ // No class? don't insert.
+ return;
+ }
+
+ const firstMatch = classOrInterface.members.find(member => changes.some(change => matchNode(change, member)));
+ if (firstMatch) {
+ // can't be undefined here, since we know we have at least one match.
+ const lastMatch = findLast(
+ classOrInterface.members as NodeArray,
+ member => changes.some(change => matchNode(change, member)),
+ )!;
+
+ forEach(changes, wipeNode);
+ changeTracker.replaceNodeRangeWithNodes(
+ originalFile,
+ firstMatch,
+ lastMatch,
+ changes,
+ );
+ return;
+ }
+
+ forEach(changes, wipeNode);
+ changeTracker.insertNodesAfter(
+ originalFile,
+ classOrInterface.members[classOrInterface.members.length - 1],
+ changes,
+ );
+}
+
+function placeStatements(
+ originalFile: SourceFile,
+ changeTracker: ChangeTracker,
+ changes: NodeArray,
+ focusLocations?: TextSpan[],
+) {
+ if (!focusLocations?.length) {
+ changeTracker.insertNodesAtEndOfFile(
+ originalFile,
+ changes,
+ /*blankLineBetween*/ false,
+ );
+ return;
+ }
+
+ for (const location of focusLocations) {
+ const scope = findAncestor(
+ getTokenAtPosition(originalFile, location.start),
+ (block): block is Block | SourceFile =>
+ or(isBlock, isSourceFile)(block) &&
+ some(block.statements, origStmt => changes.some(newStmt => matchNode(newStmt, origStmt))),
+ );
+ if (scope) {
+ const start = scope.statements.find(stmt => changes.some(node => matchNode(node, stmt)));
+ if (start) {
+ // Can't be undefined here, since we know we have at least one match.
+ const end = findLast(scope.statements, stmt => changes.some(node => matchNode(node, stmt)))!;
+ forEach(changes, wipeNode);
+ changeTracker.replaceNodeRangeWithNodes(
+ originalFile,
+ start,
+ end,
+ changes,
+ );
+ return;
+ }
+ }
+ }
+
+ let scopeStatements: NodeArray = originalFile.statements;
+ for (const location of focusLocations) {
+ const block = findAncestor(
+ getTokenAtPosition(originalFile, location.start),
+ isBlock,
+ );
+ if (block) {
+ scopeStatements = block.statements;
+ break;
+ }
+ }
+ forEach(changes, wipeNode);
+ changeTracker.insertNodesAfter(
+ originalFile,
+ scopeStatements[scopeStatements.length - 1],
+ changes,
+ );
+}
+
+function matchNode(a: Node, b: Node): boolean {
+ if (a.kind !== b.kind) {
+ return false;
+ }
+
+ if (a.kind === SyntaxKind.Constructor) {
+ return a.kind === b.kind;
+ }
+
+ if (isNamedDeclaration(a) && isNamedDeclaration(b)) {
+ return a.name.getText() === b.name.getText();
+ }
+
+ if (isIfStatement(a) && isIfStatement(b)) {
+ return (
+ a.expression.getText() === b.expression.getText()
+ );
+ }
+
+ if (isWhileStatement(a) && isWhileStatement(b)) {
+ return (
+ a.expression.getText() ===
+ b.expression.getText()
+ );
+ }
+
+ if (isForStatement(a) && isForStatement(b)) {
+ return (
+ a.initializer?.getText() ===
+ b.initializer?.getText() &&
+ a.incrementor?.getText() ===
+ b.incrementor?.getText() &&
+ a.condition?.getText() === b.condition?.getText()
+ );
+ }
+
+ if (isForInOrOfStatement(a) && isForInOrOfStatement(b)) {
+ return (
+ a.expression.getText() ===
+ b.expression.getText() &&
+ a.initializer.getText() ===
+ b.initializer.getText()
+ );
+ }
+
+ if (isLabeledStatement(a) && isLabeledStatement(b)) {
+ // If we're actually labeling/naming something, we should be a bit
+ // more lenient about when we match, so we don't care what the actual
+ // related statement is: we just replace.
+ return a.label.getText() === b.label.getText();
+ }
+
+ if (a.getText() === b.getText()) {
+ return true;
+ }
+
+ return false;
+}
+
+function wipeNode(node: Mutable) {
+ resetNodePositions(node);
+ node.parent = undefined!;
+}
+
+function resetNodePositions(node: Mutable) {
+ node.pos = -1;
+ node.end = -1;
+ node.forEachChild(resetNodePositions);
+}
diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts
index 5beb279698d2e..cb75e1478113f 100644
--- a/src/services/navigateTo.ts
+++ b/src/services/navigateTo.ts
@@ -27,7 +27,7 @@ import {
SourceFile,
SyntaxKind,
TypeChecker,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
interface RawNavigateToItem {
readonly name: string;
diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts
index 167ca62982e94..fc2a316361c06 100644
--- a/src/services/navigationBar.ts
+++ b/src/services/navigationBar.ts
@@ -111,7 +111,7 @@ import {
TypeElement,
unescapeLeadingUnderscores,
VariableDeclaration,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/**
* Matches all whitespace characters in a string. Eg:
diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts
index 14a794c526af5..facc06742ded7 100644
--- a/src/services/organizeImports.ts
+++ b/src/services/organizeImports.ts
@@ -63,7 +63,7 @@ import {
TransformFlags,
tryCast,
UserPreferences,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/**
* Organize imports by:
diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts
index 740b246eb066f..19d1438c6ea3f 100644
--- a/src/services/outliningElementsCollector.ts
+++ b/src/services/outliningElementsCollector.ts
@@ -53,7 +53,7 @@ import {
TemplateExpression,
TextSpan,
TryStatement,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export function collectElements(sourceFile: SourceFile, cancellationToken: CancellationToken): OutliningSpan[] {
diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts
new file mode 100644
index 0000000000000..9b67d62e96576
--- /dev/null
+++ b/src/services/pasteEdits.ts
@@ -0,0 +1,126 @@
+import { findIndex } from "../compiler/core.js";
+import {
+ CancellationToken,
+ Program,
+ SourceFile,
+ Statement,
+ SymbolFlags,
+ TextRange,
+ UserPreferences,
+} from "../compiler/types.js";
+import {
+ codefix,
+ Debug,
+ fileShouldUseJavaScriptRequire,
+ forEachChild,
+ formatting,
+ getQuotePreference,
+ isIdentifier,
+ textChanges,
+} from "./_namespaces/ts.js";
+import { addTargetFileImports } from "./refactors/helpers.js";
+import {
+ addExportsInOldFile,
+ getExistingLocals,
+ getUsageInfo,
+} from "./refactors/moveToFile.js";
+import {
+ CodeFixContextBase,
+ FileTextChanges,
+ LanguageServiceHost,
+ PasteEdits,
+} from "./types.js";
+
+const fixId = "providePostPasteEdits";
+/** @internal */
+export function pasteEditsProvider(
+ targetFile: SourceFile,
+ pastedText: string[],
+ pasteLocations: TextRange[],
+ copiedFrom: { file: SourceFile; range: TextRange[]; } | undefined,
+ host: LanguageServiceHost,
+ preferences: UserPreferences,
+ formatContext: formatting.FormatContext,
+ cancellationToken: CancellationToken,
+): PasteEdits {
+ const changes: FileTextChanges[] = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => pasteEdits(targetFile, pastedText, pasteLocations, copiedFrom, host, preferences, formatContext, cancellationToken, changeTracker));
+ return { edits: changes, fixId };
+}
+
+function pasteEdits(
+ targetFile: SourceFile,
+ pastedText: string[],
+ pasteLocations: TextRange[],
+ copiedFrom: { file: SourceFile; range: TextRange[]; } | undefined,
+ host: LanguageServiceHost,
+ preferences: UserPreferences,
+ formatContext: formatting.FormatContext,
+ cancellationToken: CancellationToken,
+ changes: textChanges.ChangeTracker,
+) {
+ let actualPastedText: string[] | undefined;
+ if (pastedText.length !== pasteLocations.length) {
+ actualPastedText = pastedText.length === 1 ? pastedText : [pastedText.join("\n")];
+ }
+
+ const statements: Statement[] = [];
+
+ let newText = targetFile.text;
+ for (let i = pasteLocations.length - 1; i >= 0; i--) {
+ const { pos, end } = pasteLocations[i];
+ newText = actualPastedText ? newText.slice(0, pos) + actualPastedText[0] + newText.slice(end) : newText.slice(0, pos) + pastedText[i] + newText.slice(end);
+ }
+
+ Debug.checkDefined(host.runWithTemporaryFileUpdate).call(host, targetFile.fileName, newText, (updatedProgram: Program, originalProgram: Program | undefined, updatedFile: SourceFile) => {
+ const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host);
+ if (copiedFrom?.range) {
+ Debug.assert(copiedFrom.range.length === pastedText.length);
+ copiedFrom.range.forEach(copy => {
+ const statementsInSourceFile = copiedFrom.file.statements;
+ const startNodeIndex = findIndex(statementsInSourceFile, s => s.end > copy.pos);
+ if (startNodeIndex === -1) return undefined;
+ let endNodeIndex = findIndex(statementsInSourceFile, s => s.end >= copy.end, startNodeIndex);
+ /**
+ * [|console.log(a);
+ * |]
+ * console.log(b);
+ */
+ if (endNodeIndex !== -1 && copy.end <= statementsInSourceFile[endNodeIndex].getStart()) {
+ endNodeIndex--;
+ }
+ statements.push(...statementsInSourceFile.slice(startNodeIndex, endNodeIndex === -1 ? statementsInSourceFile.length : endNodeIndex + 1));
+ });
+ const usage = getUsageInfo(copiedFrom.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker()));
+ Debug.assertIsDefined(originalProgram);
+ const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, originalProgram, host, !!copiedFrom.file.commonJsModuleIndicator);
+ addExportsInOldFile(copiedFrom.file, usage.targetFileImportsFromOldFile, changes, useEsModuleSyntax);
+ addTargetFileImports(copiedFrom.file, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, originalProgram.getTypeChecker(), updatedProgram, importAdder);
+ }
+ else {
+ const context: CodeFixContextBase = {
+ sourceFile: updatedFile,
+ program: originalProgram!,
+ cancellationToken,
+ host,
+ preferences,
+ formatContext,
+ };
+ forEachChild(updatedFile, function cb(node) {
+ if (isIdentifier(node) && !originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) {
+ // generate imports
+ importAdder.addImportForUnresolvedIdentifier(context, node, /*useAutoImportProvider*/ true);
+ }
+ node.forEachChild(cb);
+ });
+ }
+ importAdder.writeFixes(changes, getQuotePreference(copiedFrom ? copiedFrom.file : targetFile, preferences));
+ });
+ pasteLocations.forEach((paste, i) => {
+ changes.replaceRangeWithText(
+ targetFile,
+ { pos: paste.pos, end: paste.end },
+ actualPastedText ?
+ actualPastedText[0] : pastedText[i],
+ );
+ });
+}
diff --git a/src/services/patternMatcher.ts b/src/services/patternMatcher.ts
index e3394439757b2..f146e8d32b4ae 100644
--- a/src/services/patternMatcher.ts
+++ b/src/services/patternMatcher.ts
@@ -10,7 +10,7 @@ import {
ScriptTarget,
startsWith,
TextSpan,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
// Note(cyrusn): this enum is ordered from strongest match type to weakest match type.
/** @internal */
diff --git a/src/services/preProcess.ts b/src/services/preProcess.ts
index 2d98a63586c55..5ae905fb506ba 100644
--- a/src/services/preProcess.ts
+++ b/src/services/preProcess.ts
@@ -11,7 +11,7 @@ import {
scanner,
ScriptTarget,
SyntaxKind,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo {
const pragmaContext: PragmaContext = {
diff --git a/src/services/refactorProvider.ts b/src/services/refactorProvider.ts
index 368bd8810962e..1b21149070931 100644
--- a/src/services/refactorProvider.ts
+++ b/src/services/refactorProvider.ts
@@ -6,8 +6,8 @@ import {
Refactor,
RefactorContext,
RefactorEditInfo,
-} from "./_namespaces/ts";
-import { refactorKindBeginsWith } from "./_namespaces/ts.refactor";
+} from "./_namespaces/ts.js";
+import { refactorKindBeginsWith } from "./_namespaces/ts.refactor.js";
// A map with the refactor code as key, the refactor itself as value
// e.g. nonSuggestableRefactors[refactorCode] -> the refactor you want
diff --git a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts
index 6cd5bb9f05ddd..4392c19211061 100644
--- a/src/services/refactors/addOrRemoveBracesToArrowFunction.ts
+++ b/src/services/refactors/addOrRemoveBracesToArrowFunction.ts
@@ -28,13 +28,13 @@ import {
SourceFile,
SyntaxKind,
textChanges,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
isRefactorErrorInfo,
RefactorErrorInfo,
refactorKindBeginsWith,
registerRefactor,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const refactorName = "Add or remove braces in an arrow function";
const refactorDescription = getLocaleSpecificMessage(Diagnostics.Add_or_remove_braces_in_an_arrow_function);
diff --git a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts
index 05d13bdc8fd91..ef0576e59f8bb 100644
--- a/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts
+++ b/src/services/refactors/convertArrowFunctionOrFunctionExpression.ts
@@ -52,11 +52,11 @@ import {
VariableDeclaration,
VariableDeclarationList,
VariableStatement,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
refactorKindBeginsWith,
registerRefactor,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const refactorName = "Convert arrow function or function expression";
const refactorDescription = getLocaleSpecificMessage(Diagnostics.Convert_arrow_function_or_function_expression);
diff --git a/src/services/refactors/convertExport.ts b/src/services/refactors/convertExport.ts
index 7f477fc1a86ac..5e722c083a9a0 100644
--- a/src/services/refactors/convertExport.ts
+++ b/src/services/refactors/convertExport.ts
@@ -50,12 +50,12 @@ import {
TypeAliasDeclaration,
TypeChecker,
VariableStatement,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
isRefactorErrorInfo,
RefactorErrorInfo,
registerRefactor,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const refactorName = "Convert export";
diff --git a/src/services/refactors/convertImport.ts b/src/services/refactors/convertImport.ts
index 4dbfd40d89185..55e14b576e1f7 100644
--- a/src/services/refactors/convertImport.ts
+++ b/src/services/refactors/convertImport.ts
@@ -1,7 +1,6 @@
import {
ApplicableRefactorInfo,
arrayFrom,
- codefix,
Debug,
Diagnostics,
emptyArray,
@@ -29,6 +28,7 @@ import {
isPropertyAccessOrQualifiedName,
isShorthandPropertyAssignment,
isStringLiteral,
+ moduleSpecifierToValidIdentifier,
NamedImports,
NamespaceImport,
or,
@@ -45,12 +45,12 @@ import {
SyntaxKind,
textChanges,
TypeChecker,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
isRefactorErrorInfo,
RefactorErrorInfo,
registerRefactor,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const refactorName = "Convert import";
@@ -222,7 +222,7 @@ export function doChangeNamedToNamespaceOrDefault(sourceFile: SourceFile, progra
toConvertSymbols.add(symbol);
}
});
- const preferredName = moduleSpecifier && isStringLiteral(moduleSpecifier) ? codefix.moduleSpecifierToValidIdentifier(moduleSpecifier.text, ScriptTarget.ESNext) : "module";
+ const preferredName = moduleSpecifier && isStringLiteral(moduleSpecifier) ? moduleSpecifierToValidIdentifier(moduleSpecifier.text, ScriptTarget.ESNext) : "module";
function hasNamespaceNameConflict(namedImport: ImportSpecifier): boolean {
// We need to check if the preferred namespace name (`preferredName`) we'd like to use in the refactored code will present a name conflict.
// A name conflict means that, in a scope where we would like to use the preferred namespace name, there already exists a symbol with that name in that scope.
diff --git a/src/services/refactors/convertOverloadListToSingleSignature.ts b/src/services/refactors/convertOverloadListToSingleSignature.ts
index 915b59077f8c3..c9fd31f1b4e70 100644
--- a/src/services/refactors/convertOverloadListToSingleSignature.ts
+++ b/src/services/refactors/convertOverloadListToSingleSignature.ts
@@ -39,8 +39,8 @@ import {
SyntaxKind,
textChanges,
TupleTypeNode,
-} from "../_namespaces/ts";
-import { registerRefactor } from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.js";
+import { registerRefactor } from "../_namespaces/ts.refactor.js";
const refactorName = "Convert overload list to single signature";
const refactorDescription = getLocaleSpecificMessage(Diagnostics.Convert_overload_list_to_single_signature);
diff --git a/src/services/refactors/convertParamsToDestructuredObject.ts b/src/services/refactors/convertParamsToDestructuredObject.ts
index 164c725f7a932..9c1792b9b8cbe 100644
--- a/src/services/refactors/convertParamsToDestructuredObject.ts
+++ b/src/services/refactors/convertParamsToDestructuredObject.ts
@@ -103,8 +103,8 @@ import {
TypeLiteralNode,
TypeNode,
VariableDeclaration,
-} from "../_namespaces/ts";
-import { registerRefactor } from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.js";
+import { registerRefactor } from "../_namespaces/ts.refactor.js";
const refactorName = "Convert parameters to destructured object";
const minimumParameterLength = 1;
diff --git a/src/services/refactors/convertStringOrTemplateLiteral.ts b/src/services/refactors/convertStringOrTemplateLiteral.ts
index cd8fe2ad5032b..c6eb8494fe3ad 100644
--- a/src/services/refactors/convertStringOrTemplateLiteral.ts
+++ b/src/services/refactors/convertStringOrTemplateLiteral.ts
@@ -36,8 +36,8 @@ import {
TemplateTail,
textChanges,
Token,
-} from "../_namespaces/ts";
-import { registerRefactor } from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.js";
+import { registerRefactor } from "../_namespaces/ts.refactor.js";
const refactorName = "Convert to template string";
const refactorDescription = getLocaleSpecificMessage(Diagnostics.Convert_to_template_string);
diff --git a/src/services/refactors/convertToOptionalChainExpression.ts b/src/services/refactors/convertToOptionalChainExpression.ts
index ebacc0935a5c2..333e200f6a0b4 100644
--- a/src/services/refactors/convertToOptionalChainExpression.ts
+++ b/src/services/refactors/convertToOptionalChainExpression.ts
@@ -40,12 +40,12 @@ import {
TextSpan,
TypeChecker,
VariableStatement,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
isRefactorErrorInfo,
RefactorErrorInfo,
registerRefactor,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const refactorName = "Convert to optional chain expression";
const convertToOptionalChainExpressionMessage = getLocaleSpecificMessage(Diagnostics.Convert_to_optional_chain_expression);
diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts
index 9e04d91d10d8e..d5ebc4e3c040d 100644
--- a/src/services/refactors/extractSymbol.ts
+++ b/src/services/refactors/extractSymbol.ts
@@ -157,12 +157,12 @@ import {
visitNode,
visitNodes,
VisitResult,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
getIdentifierForNode,
refactorKindBeginsWith,
registerRefactor,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const refactorName = "Extract Symbol";
diff --git a/src/services/refactors/extractType.ts b/src/services/refactors/extractType.ts
index fe1e8e3ddb2fa..b6f4c97b55a5d 100644
--- a/src/services/refactors/extractType.ts
+++ b/src/services/refactors/extractType.ts
@@ -67,12 +67,12 @@ import {
TypeElement,
TypeNode,
TypeParameterDeclaration,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
isRefactorErrorInfo,
RefactorErrorInfo,
registerRefactor,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const refactorName = "Extract type";
diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts
index 2756ae20471ed..7e0820c3e2224 100644
--- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts
+++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts
@@ -9,11 +9,11 @@ import {
isIdentifier,
isParameter,
RefactorContext,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
isRefactorErrorInfo,
registerRefactor,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const actionName = "Generate 'get' and 'set' accessors";
const actionDescription = getLocaleSpecificMessage(Diagnostics.Generate_get_and_set_accessors);
diff --git a/src/services/refactors/helpers.ts b/src/services/refactors/helpers.ts
index e72eea44693a6..459979c3ef0dc 100644
--- a/src/services/refactors/helpers.ts
+++ b/src/services/refactors/helpers.ts
@@ -18,8 +18,8 @@ import {
Symbol,
SymbolFlags,
TypeChecker,
-} from "../_namespaces/ts";
-import { addImportsForMovedSymbols } from "./moveToFile";
+} from "../_namespaces/ts.js";
+import { addImportsForMovedSymbols } from "./moveToFile.js";
/**
* Returned by refactor functions when some error message needs to be surfaced to users.
*
diff --git a/src/services/refactors/inferFunctionReturnType.ts b/src/services/refactors/inferFunctionReturnType.ts
index dc3a9adbd0d7f..3bf9bdb1afaf9 100644
--- a/src/services/refactors/inferFunctionReturnType.ts
+++ b/src/services/refactors/inferFunctionReturnType.ts
@@ -26,13 +26,13 @@ import {
Type,
TypeChecker,
TypeNode,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
isRefactorErrorInfo,
RefactorErrorInfo,
refactorKindBeginsWith,
registerRefactor,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const refactorName = "Infer function return type";
const refactorDescription = getLocaleSpecificMessage(Diagnostics.Infer_function_return_type);
diff --git a/src/services/refactors/inlineVariable.ts b/src/services/refactors/inlineVariable.ts
index bdd5af771e761..0bcf841ce39e2 100644
--- a/src/services/refactors/inlineVariable.ts
+++ b/src/services/refactors/inlineVariable.ts
@@ -38,11 +38,11 @@ import {
textRangeContainsPositionInclusive,
TypeChecker,
VariableDeclaration,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
RefactorErrorInfo,
registerRefactor,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const refactorName = "Inline variable";
const refactorDescription = getLocaleSpecificMessage(Diagnostics.Inline_variable);
diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts
index dea0ebc4c43e1..286b9c2a89533 100644
--- a/src/services/refactors/moveToFile.ts
+++ b/src/services/refactors/moveToFile.ts
@@ -1,4 +1,4 @@
-import { getModuleSpecifier } from "../../compiler/_namespaces/ts.moduleSpecifiers";
+import { getModuleSpecifier } from "../../compiler/_namespaces/ts.moduleSpecifiers.js";
import {
ApplicableRefactorInfo,
arrayFrom,
@@ -118,6 +118,7 @@ import {
ModifierLike,
ModuleDeclaration,
ModuleKind,
+ moduleSpecifierToValidIdentifier,
NamedImportBindings,
Node,
NodeFlags,
@@ -153,9 +154,9 @@ import {
VariableDeclaration,
VariableDeclarationList,
VariableStatement,
-} from "../_namespaces/ts";
-import { addTargetFileImports } from "../_namespaces/ts.refactor";
-import { registerRefactor } from "../refactorProvider";
+} from "../_namespaces/ts.js";
+import { addTargetFileImports } from "../_namespaces/ts.refactor.js";
+import { registerRefactor } from "../refactorProvider.js";
const refactorNameForMoveToFile = "Move to file";
const description = getLocaleSpecificMessage(Diagnostics.Move_to_file);
@@ -175,7 +176,7 @@ registerRefactor(refactorNameForMoveToFile, {
}
/** If the start/end nodes of the selection are inside a block like node do not show the `Move to file` code action
* This condition is used in order to show less often the `Move to file` code action */
- if (context.endPosition !== undefined) {
+ if (context.triggerReason === "implicit" && context.endPosition !== undefined) {
const startNodeAncestor = findAncestor(getTokenAtPosition(file, context.startPosition), isBlockLike);
const endNodeAncestor = findAncestor(getTokenAtPosition(file, context.endPosition), isBlockLike);
if (startNodeAncestor && !isSourceFile(startNodeAncestor) && endNodeAncestor && !isSourceFile(endNodeAncestor)) {
@@ -307,7 +308,8 @@ export function deleteUnusedOldImports(oldFile: SourceFile, toMove: readonly Sta
}
}
-function addExportsInOldFile(oldFile: SourceFile, targetFileImportsFromOldFile: Map, changes: textChanges.ChangeTracker, useEsModuleSyntax: boolean) {
+/** @internal */
+export function addExportsInOldFile(oldFile: SourceFile, targetFileImportsFromOldFile: Map, changes: textChanges.ChangeTracker, useEsModuleSyntax: boolean) {
const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`.
targetFileImportsFromOldFile.forEach((_, symbol) => {
if (!symbol.declarations) {
@@ -392,7 +394,7 @@ function updateNamespaceLikeImport(
oldImportNode: SupportedImport,
quotePreference: QuotePreference,
): void {
- const preferredNewNamespaceName = codefix.moduleSpecifierToValidIdentifier(newModuleSpecifier, ScriptTarget.ESNext);
+ const preferredNewNamespaceName = moduleSpecifierToValidIdentifier(newModuleSpecifier, ScriptTarget.ESNext);
let needUniqueName = false;
const toChange: Identifier[] = [];
FindAllReferences.Core.eachSymbolReferenceInFile(oldImportId, checker, sourceFile, ref => {
@@ -1118,7 +1120,8 @@ function getOverloadRangeToMove(sourceFile: SourceFile, statement: Statement) {
return undefined;
}
-function getExistingLocals(sourceFile: SourceFile, statements: readonly Statement[], checker: TypeChecker) {
+/** @internal */
+export function getExistingLocals(sourceFile: SourceFile, statements: readonly Statement[], checker: TypeChecker) {
const existingLocals = new Set();
for (const moduleSpecifier of sourceFile.imports) {
const declaration = importFromModuleSpecifier(moduleSpecifier);
@@ -1146,7 +1149,7 @@ function getExistingLocals(sourceFile: SourceFile, statements: readonly Statemen
for (const statement of statements) {
forEachReference(statement, checker, s => {
const symbol = skipAlias(s, checker);
- if (symbol.valueDeclaration && getSourceFileOfNode(symbol.valueDeclaration) === sourceFile) {
+ if (symbol.valueDeclaration && getSourceFileOfNode(symbol.valueDeclaration).path === sourceFile.path) {
existingLocals.add(symbol);
}
});
diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts
index 2665239e10483..90971ebaacfd8 100644
--- a/src/services/refactors/moveToNewFile.ts
+++ b/src/services/refactors/moveToNewFile.ts
@@ -5,9 +5,13 @@ import {
Debug,
Diagnostics,
emptyArray,
+ findAncestor,
getLineAndCharacterOfPosition,
getLocaleSpecificMessage,
+ getTokenAtPosition,
hostGetCanonicalFileName,
+ isBlockLike,
+ isSourceFile,
LanguageServiceHost,
last,
ModuleKind,
@@ -17,7 +21,7 @@ import {
SourceFile,
textChanges,
UserPreferences,
-} from "../_namespaces/ts";
+} from "../_namespaces/ts.js";
import {
addNewFileToTsconfig,
createNewFileName,
@@ -26,7 +30,7 @@ import {
getUsageInfo,
registerRefactor,
ToMove,
-} from "../_namespaces/ts.refactor";
+} from "../_namespaces/ts.refactor.js";
const refactorName = "Move to a new file";
const description = getLocaleSpecificMessage(Diagnostics.Move_to_a_new_file);
@@ -40,6 +44,16 @@ registerRefactor(refactorName, {
kinds: [moveToNewFileAction.kind],
getAvailableActions: function getRefactorActionsToMoveToNewFile(context): readonly ApplicableRefactorInfo[] {
const statements = getStatementsToMove(context);
+
+ const file = context.file;
+ if (context.triggerReason === "implicit" && context.endPosition !== undefined) {
+ const startNodeAncestor = findAncestor(getTokenAtPosition(file, context.startPosition), isBlockLike);
+ const endNodeAncestor = findAncestor(getTokenAtPosition(file, context.endPosition), isBlockLike);
+ if (startNodeAncestor && !isSourceFile(startNodeAncestor) && endNodeAncestor && !isSourceFile(endNodeAncestor)) {
+ return emptyArray;
+ }
+ }
+
if (context.preferences.allowTextChangesInNewFiles && statements) {
const file = context.file;
const affectedTextRange = {
diff --git a/src/services/rename.ts b/src/services/rename.ts
index 1260fef23d5cc..64f817dcd03e5 100644
--- a/src/services/rename.ts
+++ b/src/services/rename.ts
@@ -51,7 +51,7 @@ import {
TypeFlags,
UnionType,
UserPreferences,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export function getRenameInfo(program: Program, sourceFile: SourceFile, position: number, preferences: UserPreferences): RenameInfo {
diff --git a/src/services/services.ts b/src/services/services.ts
index 375c0ddce113e..2bd5c94bb0efe 100644
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@ -211,6 +211,7 @@ import {
LinkedEditingInfo,
LiteralType,
map,
+ MapCode,
mapDefined,
MapLike,
mapOneOrMany,
@@ -241,6 +242,9 @@ import {
ParseConfigFileHost,
ParsedCommandLine,
parseJsonSourceFileConfigFileContent,
+ PasteEdits,
+ pasteEdits,
+ PasteEditsArgs,
Path,
positionIsSynthesized,
PossibleProgramFileInfo,
@@ -326,16 +330,16 @@ import {
updateSourceFile,
UserPreferences,
VariableDeclaration,
-} from "./_namespaces/ts";
-import * as NavigateTo from "./_namespaces/ts.NavigateTo";
-import * as NavigationBar from "./_namespaces/ts.NavigationBar";
+} from "./_namespaces/ts.js";
+import * as NavigateTo from "./_namespaces/ts.NavigateTo.js";
+import * as NavigationBar from "./_namespaces/ts.NavigationBar.js";
import {
containsJsx,
createNewFileName,
getStatementsToMove,
-} from "./_namespaces/ts.refactor";
-import * as classifier from "./classifier";
-import * as classifier2020 from "./classifier2020";
+} from "./_namespaces/ts.refactor.js";
+import * as classifier from "./classifier.js";
+import * as classifier2020 from "./classifier2020.js";
/** The version of the language service API */
export const servicesVersion = "0.8";
@@ -1573,6 +1577,7 @@ const invalidOperationsInPartialSemanticMode: readonly (keyof LanguageService)[]
"provideCallHierarchyOutgoingCalls",
"provideInlayHints",
"getSupportedCodeFixes",
+ "getPasteEdits",
];
const invalidOperationsInSyntacticMode: readonly (keyof LanguageService)[] = [
@@ -1596,7 +1601,7 @@ const invalidOperationsInSyntacticMode: readonly (keyof LanguageService)[] = [
];
export function createLanguageService(
host: LanguageServiceHost,
- documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()),
+ documentRegistry: DocumentRegistry = createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory(), host.jsDocParsingMode),
syntaxOnlyOrLanguageServiceMode?: boolean | LanguageServiceMode,
): LanguageService {
let languageServiceMode: LanguageServiceMode;
@@ -2128,6 +2133,23 @@ export function createLanguageService(
};
}
+ function getPasteEdits(
+ args: PasteEditsArgs,
+ formatOptions: FormatCodeSettings,
+ ): PasteEdits {
+ synchronizeHostData();
+ return pasteEdits.pasteEditsProvider(
+ getValidSourceFile(args.targetFile),
+ args.pastedText,
+ args.pasteLocations,
+ args.copiedFrom ? { file: getValidSourceFile(args.copiedFrom.file), range: args.copiedFrom.range } : undefined,
+ host,
+ args.preferences,
+ formatting.getFormatContext(formatOptions, host),
+ cancellationToken,
+ );
+ }
+
function getNodeForQuickInfo(node: Node): Node {
if (isNewExpression(node.parent) && node.pos === node.parent.pos) {
return node.parent.expression;
@@ -3144,6 +3166,17 @@ export function createLanguageService(
return InlayHints.provideInlayHints(getInlayHintsContext(sourceFile, span, preferences));
}
+ function mapCode(sourceFile: string, contents: string[], focusLocations: TextSpan[][] | undefined, formatOptions: FormatCodeSettings, preferences: UserPreferences): FileTextChanges[] {
+ return MapCode.mapCode(
+ syntaxTreeCache.getCurrentSourceFile(sourceFile),
+ contents,
+ focusLocations,
+ host,
+ formatting.getFormatContext(formatOptions, host),
+ preferences,
+ );
+ }
+
const ls: LanguageService = {
dispose,
cleanupSemanticCache,
@@ -3214,6 +3247,8 @@ export function createLanguageService(
uncommentSelection,
provideInlayHints,
getSupportedCodeFixes,
+ getPasteEdits,
+ mapCode,
};
switch (languageServiceMode) {
diff --git a/src/services/signatureHelp.ts b/src/services/signatureHelp.ts
index 28f0d188854bb..ab1fdcbee22b2 100644
--- a/src/services/signatureHelp.ts
+++ b/src/services/signatureHelp.ts
@@ -91,7 +91,7 @@ import {
Type,
TypeChecker,
TypeParameter,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
const enum InvocationKind {
Call,
diff --git a/src/services/smartSelection.ts b/src/services/smartSelection.ts
index d726d177e682a..f58862d76ab68 100644
--- a/src/services/smartSelection.ts
+++ b/src/services/smartSelection.ts
@@ -46,7 +46,7 @@ import {
SyntaxList,
textSpanIntersectsWithPosition,
textSpansEqual,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/** @internal */
export function getSmartSelectionRange(pos: number, sourceFile: SourceFile): SelectionRange {
diff --git a/src/services/sourcemaps.ts b/src/services/sourcemaps.ts
index 0a58a2cda4705..954616d3f0317 100644
--- a/src/services/sourcemaps.ts
+++ b/src/services/sourcemaps.ts
@@ -25,7 +25,7 @@ import {
toPath as ts_toPath,
tryGetSourceMappingURL,
tryParseRawSourceMap,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
const base64UrlRegExp = /^data:(?:application\/json(?:;charset=[uU][tT][fF]-8);base64,([A-Za-z0-9+/=]+)$)?/;
diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts
index b1db1fc467bdd..06f488ed47bcb 100644
--- a/src/services/stringCompletions.ts
+++ b/src/services/stringCompletions.ts
@@ -1,4 +1,13 @@
-import { getModuleSpecifierPreferences } from "../compiler/moduleSpecifiers";
+import { getModuleSpecifierPreferences } from "../compiler/moduleSpecifiers.js";
+import {
+ CompletionKind,
+ createCompletionDetails,
+ createCompletionDetailsForSymbol,
+ getCompletionEntriesFromSymbols,
+ getPropertiesForObjectExpression,
+ Log,
+ SortText,
+} from "./_namespaces/ts.Completions.js";
import {
addToSeen,
altDirectorySeparator,
@@ -148,16 +157,7 @@ import {
UserPreferences,
walkUpParenthesizedExpressions,
walkUpParenthesizedTypes,
-} from "./_namespaces/ts";
-import {
- CompletionKind,
- createCompletionDetails,
- createCompletionDetailsForSymbol,
- getCompletionEntriesFromSymbols,
- getPropertiesForObjectExpression,
- Log,
- SortText,
-} from "./_namespaces/ts.Completions";
+} from "./_namespaces/ts.js";
interface NameAndKindSet {
add(value: NameAndKind): void;
diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts
index 91e99ba9450db..a5daf3e6666f2 100644
--- a/src/services/suggestionDiagnostics.ts
+++ b/src/services/suggestionDiagnostics.ts
@@ -57,7 +57,7 @@ import {
SyntaxKind,
TypeChecker,
VariableStatement,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
const visitedNestedConvertibleFunctions = new Map();
@@ -87,7 +87,7 @@ export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Pr
const importNode = importFromModuleSpecifier(moduleSpecifier);
const name = importNameForConvertToDefaultImport(importNode);
if (!name) continue;
- const module = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier)?.resolvedModule;
+ const module = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier, sourceFile)?.resolvedModule;
const resolvedFile = module && program.getSourceFile(module.resolvedFileName);
if (resolvedFile && resolvedFile.externalModuleIndicator && resolvedFile.externalModuleIndicator !== true && isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals) {
diags.push(createDiagnosticForNode(name, Diagnostics.Import_may_be_converted_to_a_default_import));
diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts
index 0524d150972bc..5ba8170b17b32 100644
--- a/src/services/symbolDisplay.ts
+++ b/src/services/symbolDisplay.ts
@@ -108,7 +108,7 @@ import {
TypeParameter,
typeToDisplayParts,
VariableDeclaration,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
const symbolDisplayNodeBuilderFlags = NodeBuilderFlags.OmitParameterModifiers | NodeBuilderFlags.IgnoreErrors | NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope;
@@ -557,7 +557,7 @@ function getSymbolDisplayPartsDocumentationAndSymbolKindWorker(typeChecker: Type
typeChecker,
resolvedSymbol,
getSourceFileOfNode(resolvedNode),
- resolvedNode,
+ enclosingDeclaration,
declarationName,
type,
semanticMeaning,
diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts
index 5887fba6ae2e6..1fa19379afc4c 100644
--- a/src/services/textChanges.ts
+++ b/src/services/textChanges.ts
@@ -174,7 +174,7 @@ import {
visitEachChild,
visitNodes,
Visitor,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/**
* Currently for simplicity we store recovered positions on the node itself.
diff --git a/src/services/transform.ts b/src/services/transform.ts
index 85fae890c0984..a8d03f62a19fb 100644
--- a/src/services/transform.ts
+++ b/src/services/transform.ts
@@ -9,7 +9,7 @@ import {
TransformationResult,
TransformerFactory,
transformNodes,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
/**
* Transform one or more nodes using the supplied transformers.
diff --git a/src/services/transpile.ts b/src/services/transpile.ts
index b9179bcd2a198..ccf8396247ca8 100644
--- a/src/services/transpile.ts
+++ b/src/services/transpile.ts
@@ -28,7 +28,7 @@ import {
ScriptTarget,
toPath,
transpileOptionValueCompilerOptions,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
export interface TranspileOptions {
compilerOptions?: CompilerOptions;
@@ -59,6 +59,7 @@ const optionsRedundantWithVerbatimModuleSyntax = new Set([
* - noLib = true
* - noResolve = true
* - declaration = false
+ * - noCheck = true
*/
export function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput {
return transpileWorker(input, transpileOptions, /*declaration*/ false);
@@ -142,7 +143,6 @@ function transpileWorker(input: string, transpileOptions: TranspileOptions, decl
options.declaration = true;
options.emitDeclarationOnly = true;
options.isolatedDeclarations = true;
- options.noCheck = true;
}
else {
options.declaration = false;
diff --git a/src/services/types.ts b/src/services/types.ts
index 3adcf0c39e65f..0dc8b87790260 100644
--- a/src/services/types.ts
+++ b/src/services/types.ts
@@ -41,9 +41,9 @@ import {
TextRange,
TextSpan,
UserPreferences,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
-declare module "../compiler/types" {
+declare module "../compiler/types.js" {
// Module transform: converted from interface augmentation
export interface Node {
getSourceFile(): SourceFile;
@@ -73,21 +73,21 @@ declare module "../compiler/types" {
}
}
-declare module "../compiler/types" {
+declare module "../compiler/types.js" {
// Module transform: converted from interface augmentation
export interface Identifier {
readonly text: string;
}
}
-declare module "../compiler/types" {
+declare module "../compiler/types.js" {
// Module transform: converted from interface augmentation
export interface PrivateIdentifier {
readonly text: string;
}
}
-declare module "../compiler/types" {
+declare module "../compiler/types.js" {
// Module transform: converted from interface augmentation
export interface Symbol {
readonly name: string;
@@ -104,7 +104,7 @@ declare module "../compiler/types" {
}
}
-declare module "../compiler/types" {
+declare module "../compiler/types.js" {
// Module transform: converted from interface augmentation
export interface Type {
getFlags(): TypeFlags;
@@ -136,14 +136,14 @@ declare module "../compiler/types" {
}
}
-declare module "../compiler/types" {
+declare module "../compiler/types.js" {
// Module transform: converted from interface augmentation
export interface TypeReference {
typeArguments?: readonly Type[];
}
}
-declare module "../compiler/types" {
+declare module "../compiler/types.js" {
// Module transform: converted from interface augmentation
export interface Signature {
getDeclaration(): SignatureDeclaration;
@@ -156,7 +156,7 @@ declare module "../compiler/types" {
}
}
-declare module "../compiler/types" {
+declare module "../compiler/types.js" {
// Module transform: converted from interface augmentation
export interface SourceFile {
/** @internal */ version: string;
@@ -175,14 +175,14 @@ declare module "../compiler/types" {
}
}
-declare module "../compiler/types" {
+declare module "../compiler/types.js" {
// Module transform: converted from interface augmentation
export interface SourceFileLike {
getLineAndCharacterOfPosition(pos: number): LineAndCharacter;
}
}
-declare module "../compiler/types" {
+declare module "../compiler/types.js" {
// Module transform: converted from interface augmentation
export interface SourceMapSource {
getLineAndCharacterOfPosition(pos: number): LineAndCharacter;
@@ -431,7 +431,7 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR
getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined;
/** @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void;
/** @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache;
-
+ /** @internal */ runWithTemporaryFileUpdate?(rootFile: string, updatedText: string, cb: (updatedProgram: Program, originalProgram: Program | undefined, updatedPastedText: SourceFile) => void): void;
jsDocParsingMode?: JSDocParsingMode | undefined;
}
@@ -683,7 +683,13 @@ export interface LanguageService {
getSupportedCodeFixes(fileName?: string): readonly string[];
+ /** @internal */ mapCode(fileName: string, contents: string[], focusLocations: TextSpan[][] | undefined, formatOptions: FormatCodeSettings, preferences: UserPreferences): readonly FileTextChanges[];
+
dispose(): void;
+ getPasteEdits(
+ args: PasteEditsArgs,
+ formatOptions: FormatCodeSettings,
+ ): PasteEdits;
}
export interface JsxClosingTagInfo {
@@ -706,6 +712,19 @@ export const enum OrganizeImportsMode {
RemoveUnused = "RemoveUnused",
}
+export interface PasteEdits {
+ edits: readonly FileTextChanges[];
+ fixId?: {};
+}
+
+export interface PasteEditsArgs {
+ targetFile: string;
+ pastedText: string[];
+ pasteLocations: TextRange[];
+ copiedFrom: { file: string; range: TextRange[]; } | undefined;
+ preferences: UserPreferences;
+}
+
export interface OrganizeImportsArgs extends CombinedCodeFixScope {
/** @deprecated Use `mode` instead */
skipDestructiveCodeActions?: boolean;
diff --git a/src/services/utilities.ts b/src/services/utilities.ts
index fe0de5d35e1cc..2d57952373316 100644
--- a/src/services/utilities.ts
+++ b/src/services/utilities.ts
@@ -20,7 +20,6 @@ import {
ClassDeclaration,
ClassExpression,
clone,
- codefix,
combinePaths,
CommentKind,
CommentRange,
@@ -92,6 +91,7 @@ import {
FunctionLikeDeclaration,
FutureSourceFile,
getAssignmentDeclarationKind,
+ getBaseFileName,
getCombinedNodeFlagsAlwaysIncludeJSDoc,
getDirectoryPath,
getEmitModuleKind,
@@ -181,6 +181,8 @@ import {
isGlobalScopeAugmentation,
isHeritageClause,
isIdentifier,
+ isIdentifierPart,
+ isIdentifierStart,
isImportCall,
isImportClause,
isImportDeclaration,
@@ -240,6 +242,7 @@ import {
isSetAccessorDeclaration,
isSourceFile,
isSourceFileJS,
+ isStringANonContextualKeyword,
isStringDoubleQuoted,
isStringLiteral,
isStringLiteralLike,
@@ -319,6 +322,8 @@ import {
pseudoBigIntToString,
QualifiedName,
RefactorContext,
+ removeFileExtension,
+ removeSuffix,
Scanner,
ScriptElementKind,
ScriptElementKindModifier,
@@ -327,6 +332,7 @@ import {
SemicolonPreference,
setConfigFileInOptions,
setOriginalNode,
+ setParentRecursive,
setTextRange,
Signature,
SignatureDeclaration,
@@ -384,7 +390,7 @@ import {
VoidExpression,
walkUpParenthesizedExpressions,
YieldExpression,
-} from "./_namespaces/ts";
+} from "./_namespaces/ts.js";
// These utilities are common to multiple language service features.
// #region
@@ -3167,7 +3173,7 @@ export function getPrecedingNonSpaceCharacterPosition(text: string, position: nu
export function getSynthesizedDeepClone(node: T, includeTrivia = true): T {
const clone = node && getSynthesizedDeepCloneWorker(node);
if (clone && !includeTrivia) suppressLeadingAndTrailingTrivia(clone);
- return clone;
+ return setParentRecursive(clone, /*incremental*/ false);
}
/** @internal */
@@ -4023,8 +4029,8 @@ export function getNamesForExportedSymbol(symbol: Symbol, scriptTarget: ScriptTa
if (needsNameFromDeclaration(symbol)) {
const fromDeclaration = getDefaultLikeExportNameFromDeclaration(symbol);
if (fromDeclaration) return fromDeclaration;
- const fileNameCase = codefix.moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, /*forceCapitalize*/ false);
- const capitalized = codefix.moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, /*forceCapitalize*/ true);
+ const fileNameCase = moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, /*forceCapitalize*/ false);
+ const capitalized = moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, /*forceCapitalize*/ true);
if (fileNameCase === capitalized) return fileNameCase;
return [fileNameCase, capitalized];
}
@@ -4039,7 +4045,7 @@ export function getNameForExportedSymbol(symbol: Symbol, scriptTarget: ScriptTar
// - export { foo as default } => foo
// - export default 0 => filename converted to camelCase
return getDefaultLikeExportNameFromDeclaration(symbol)
- || codefix.moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, !!preferCapitalized);
+ || moduleSymbolToValidIdentifier(getSymbolParentOrFail(symbol), scriptTarget, !!preferCapitalized);
}
return symbol.name;
}
@@ -4048,7 +4054,8 @@ function needsNameFromDeclaration(symbol: Symbol) {
return !(symbol.flags & SymbolFlags.Transient) && (symbol.escapedName === InternalSymbolName.ExportEquals || symbol.escapedName === InternalSymbolName.Default);
}
-function getDefaultLikeExportNameFromDeclaration(symbol: Symbol): string | undefined {
+/** @internal */
+export function getDefaultLikeExportNameFromDeclaration(symbol: Symbol): string | undefined {
return firstDefined(symbol.declarations, d => {
// "export default" in this case. See `ExportAssignment`for more details.
if (isExportAssignment(d)) {
@@ -4063,7 +4070,8 @@ function getDefaultLikeExportNameFromDeclaration(symbol: Symbol): string | undef
});
}
-function getSymbolParentOrFail(symbol: Symbol) {
+/** @internal */
+export function getSymbolParentOrFail(symbol: Symbol) {
return Debug.checkDefined(
symbol.parent,
`Symbol parent was undefined. Flags: ${Debug.formatSymbolFlags(symbol.flags)}. ` +
@@ -4078,6 +4086,42 @@ function getSymbolParentOrFail(symbol: Symbol) {
);
}
+/** @internal */
+export function moduleSymbolToValidIdentifier(moduleSymbol: Symbol, target: ScriptTarget | undefined, forceCapitalize: boolean): string {
+ return moduleSpecifierToValidIdentifier(removeFileExtension(stripQuotes(moduleSymbol.name)), target, forceCapitalize);
+}
+
+/** @internal */
+export function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target: ScriptTarget | undefined, forceCapitalize?: boolean): string {
+ const baseName = getBaseFileName(removeSuffix(moduleSpecifier, "/index"));
+ let res = "";
+ let lastCharWasValid = true;
+ const firstCharCode = baseName.charCodeAt(0);
+ if (isIdentifierStart(firstCharCode, target)) {
+ res += String.fromCharCode(firstCharCode);
+ if (forceCapitalize) {
+ res = res.toUpperCase();
+ }
+ }
+ else {
+ lastCharWasValid = false;
+ }
+ for (let i = 1; i < baseName.length; i++) {
+ const ch = baseName.charCodeAt(i);
+ const isValid = isIdentifierPart(ch, target);
+ if (isValid) {
+ let char = String.fromCharCode(ch);
+ if (!lastCharWasValid) {
+ char = char.toUpperCase();
+ }
+ res += char;
+ }
+ lastCharWasValid = isValid;
+ }
+ // Need `|| "_"` to ensure result isn't empty.
+ return !isStringANonContextualKeyword(res) ? res || "_" : `_${res}`;
+}
+
/**
* Useful to check whether a string contains another string at a specific index
* without allocating another string or traversing the entire contents of the outer string.
diff --git a/src/testRunner/_namespaces/FourSlash.ts b/src/testRunner/_namespaces/FourSlash.ts
index b81535c48ffd8..39911defc1d7a 100644
--- a/src/testRunner/_namespaces/FourSlash.ts
+++ b/src/testRunner/_namespaces/FourSlash.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the FourSlash namespace. */
-export * from "../../harness/_namespaces/FourSlash";
+export * from "../../harness/_namespaces/FourSlash.js";
diff --git a/src/testRunner/_namespaces/Harness.Parallel.Host.ts b/src/testRunner/_namespaces/Harness.Parallel.Host.ts
index 8104cc9ecfdf6..d8ebbf319731a 100644
--- a/src/testRunner/_namespaces/Harness.Parallel.Host.ts
+++ b/src/testRunner/_namespaces/Harness.Parallel.Host.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the Harness.Parallel.Host namespace. */
-export * from "../parallel/host";
+export * from "../parallel/host.js";
diff --git a/src/testRunner/_namespaces/Harness.Parallel.Worker.ts b/src/testRunner/_namespaces/Harness.Parallel.Worker.ts
index ecca4b9659e6e..de2a725adb08f 100644
--- a/src/testRunner/_namespaces/Harness.Parallel.Worker.ts
+++ b/src/testRunner/_namespaces/Harness.Parallel.Worker.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the Harness.Parallel.Worker namespace. */
-export * from "../parallel/worker";
+export * from "../parallel/worker.js";
diff --git a/src/testRunner/_namespaces/Harness.Parallel.ts b/src/testRunner/_namespaces/Harness.Parallel.ts
index 10087db7557c3..8f2b792e406d1 100644
--- a/src/testRunner/_namespaces/Harness.Parallel.ts
+++ b/src/testRunner/_namespaces/Harness.Parallel.ts
@@ -1,7 +1,7 @@
/* Generated file to emulate the Harness.Parallel namespace. */
-export * from "../parallel/shared";
-import * as Host from "./Harness.Parallel.Host";
+export * from "../parallel/shared.js";
+import * as Host from "./Harness.Parallel.Host.js";
export { Host };
-import * as Worker from "./Harness.Parallel.Worker";
+import * as Worker from "./Harness.Parallel.Worker.js";
export { Worker };
diff --git a/src/testRunner/_namespaces/Harness.ts b/src/testRunner/_namespaces/Harness.ts
index 7577c667a8050..fd50d80a5621f 100644
--- a/src/testRunner/_namespaces/Harness.ts
+++ b/src/testRunner/_namespaces/Harness.ts
@@ -1,17 +1,11 @@
/* Generated file to emulate the Harness namespace. */
-export * from "../../harness/_namespaces/Harness";
+export * from "../../harness/_namespaces/Harness.js";
-import * as Parallel from "./Harness.Parallel";
+import * as Parallel from "./Harness.Parallel.js";
export { Parallel };
-export * from "../fourslashRunner";
-export * from "../compilerRunner";
-export * from "../transpileRunner";
-export * from "../runner";
-
-// If running as emitted CJS, don't start executing the tests here; instead start in runner.ts.
-// If running bundled, we want this to be here so that esbuild places the tests after runner.ts.
-if (!__filename.endsWith("Harness.js")) {
- require("../tests");
-}
+export * from "../fourslashRunner.js";
+export * from "../compilerRunner.js";
+export * from "../transpileRunner.js";
+export * from "../runner.js";
diff --git a/src/testRunner/_namespaces/Utils.ts b/src/testRunner/_namespaces/Utils.ts
index f7bd754263d74..f513c8cfc9ed2 100644
--- a/src/testRunner/_namespaces/Utils.ts
+++ b/src/testRunner/_namespaces/Utils.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the Utils namespace. */
-export * from "../../harness/_namespaces/Utils";
+export * from "../../harness/_namespaces/Utils.js";
diff --git a/src/testRunner/_namespaces/compiler.ts b/src/testRunner/_namespaces/compiler.ts
index 62e194d59712a..fefbd43af363d 100644
--- a/src/testRunner/_namespaces/compiler.ts
+++ b/src/testRunner/_namespaces/compiler.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the compiler namespace. */
-export * from "../../harness/_namespaces/compiler";
+export * from "../../harness/_namespaces/compiler.js";
diff --git a/src/testRunner/_namespaces/documents.ts b/src/testRunner/_namespaces/documents.ts
index bf76b1332fc47..853d1defc3c0a 100644
--- a/src/testRunner/_namespaces/documents.ts
+++ b/src/testRunner/_namespaces/documents.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the documents namespace. */
-export * from "../../harness/_namespaces/documents";
+export * from "../../harness/_namespaces/documents.js";
diff --git a/src/testRunner/_namespaces/evaluator.ts b/src/testRunner/_namespaces/evaluator.ts
index 9710863c9b2ec..83ec0908821a7 100644
--- a/src/testRunner/_namespaces/evaluator.ts
+++ b/src/testRunner/_namespaces/evaluator.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the evaluator namespace. */
-export * from "../../harness/_namespaces/evaluator";
+export * from "../../harness/_namespaces/evaluator.js";
diff --git a/src/testRunner/_namespaces/fakes.ts b/src/testRunner/_namespaces/fakes.ts
index 1b6c51d409411..c7290912b6ce1 100644
--- a/src/testRunner/_namespaces/fakes.ts
+++ b/src/testRunner/_namespaces/fakes.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the fakes namespace. */
-export * from "../../harness/_namespaces/fakes";
+export * from "../../harness/_namespaces/fakes.js";
diff --git a/src/testRunner/_namespaces/project.ts b/src/testRunner/_namespaces/project.ts
index c9d999adbfff1..fe75d6e294718 100644
--- a/src/testRunner/_namespaces/project.ts
+++ b/src/testRunner/_namespaces/project.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the project namespace. */
-export * from "../projectsRunner";
+export * from "../projectsRunner.js";
diff --git a/src/testRunner/_namespaces/ts.server.ts b/src/testRunner/_namespaces/ts.server.ts
index b0a090fcfed08..5fa9fe89382e6 100644
--- a/src/testRunner/_namespaces/ts.server.ts
+++ b/src/testRunner/_namespaces/ts.server.ts
@@ -1,6 +1,6 @@
/* Generated file to emulate the ts.server namespace. */
-export * from "../../jsTyping/_namespaces/ts.server";
-export * from "../../server/_namespaces/ts.server";
-export * from "../../typingsInstallerCore/_namespaces/ts.server";
-export * from "../../harness/_namespaces/ts.server";
+export * from "../../jsTyping/_namespaces/ts.server.js";
+export * from "../../server/_namespaces/ts.server.js";
+export * from "../../typingsInstallerCore/_namespaces/ts.server.js";
+export * from "../../harness/_namespaces/ts.server.js";
diff --git a/src/testRunner/_namespaces/ts.ts b/src/testRunner/_namespaces/ts.ts
index 27efc73b10f55..11b145abe4621 100644
--- a/src/testRunner/_namespaces/ts.ts
+++ b/src/testRunner/_namespaces/ts.ts
@@ -1,11 +1,11 @@
/* Generated file to emulate the ts namespace. */
-export * from "../../compiler/_namespaces/ts";
-export * from "../../services/_namespaces/ts";
-export * from "../../jsTyping/_namespaces/ts";
-export * from "../../server/_namespaces/ts";
-export * from "../../typingsInstallerCore/_namespaces/ts";
-export * from "../../deprecatedCompat/_namespaces/ts";
-export * from "../../harness/_namespaces/ts";
-import * as server from "./ts.server";
+export * from "../../compiler/_namespaces/ts.js";
+export * from "../../services/_namespaces/ts.js";
+export * from "../../jsTyping/_namespaces/ts.js";
+export * from "../../server/_namespaces/ts.js";
+export * from "../../typingsInstallerCore/_namespaces/ts.js";
+export * from "../../deprecatedCompat/_namespaces/ts.js";
+export * from "../../harness/_namespaces/ts.js";
+import * as server from "./ts.server.js";
export { server };
diff --git a/src/testRunner/_namespaces/vfs.ts b/src/testRunner/_namespaces/vfs.ts
index 5fe2e7d9362b5..eeb46064fb93f 100644
--- a/src/testRunner/_namespaces/vfs.ts
+++ b/src/testRunner/_namespaces/vfs.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the vfs namespace. */
-export * from "../../harness/_namespaces/vfs";
+export * from "../../harness/_namespaces/vfs.js";
diff --git a/src/testRunner/_namespaces/vpath.ts b/src/testRunner/_namespaces/vpath.ts
index 9ae8ad3777f57..1c8261db73c3c 100644
--- a/src/testRunner/_namespaces/vpath.ts
+++ b/src/testRunner/_namespaces/vpath.ts
@@ -1,3 +1,3 @@
/* Generated file to emulate the vpath namespace. */
-export * from "../../harness/_namespaces/vpath";
+export * from "../../harness/_namespaces/vpath.js";
diff --git a/src/testRunner/compilerRunner.ts b/src/testRunner/compilerRunner.ts
index 3d82d232ccc05..93bc55c1159fe 100644
--- a/src/testRunner/compilerRunner.ts
+++ b/src/testRunner/compilerRunner.ts
@@ -9,11 +9,11 @@ import {
RunnerBase,
TestCaseParser,
TestRunnerKind,
-} from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import * as Utils from "./_namespaces/Utils";
-import * as vfs from "./_namespaces/vfs";
-import * as vpath from "./_namespaces/vpath";
+} from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import * as Utils from "./_namespaces/Utils.js";
+import * as vfs from "./_namespaces/vfs.js";
+import * as vpath from "./_namespaces/vpath.js";
export const enum CompilerTestType {
Conformance,
diff --git a/src/testRunner/fourslashRunner.ts b/src/testRunner/fourslashRunner.ts
index 6fd61eb0e3b08..e1a0535963ca3 100644
--- a/src/testRunner/fourslashRunner.ts
+++ b/src/testRunner/fourslashRunner.ts
@@ -1,10 +1,10 @@
-import * as FourSlash from "./_namespaces/FourSlash";
+import * as FourSlash from "./_namespaces/FourSlash.js";
import {
IO,
RunnerBase,
TestRunnerKind,
-} from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
+} from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
export class FourSlashRunner extends RunnerBase {
protected basePath: string;
diff --git a/src/testRunner/parallel/host.ts b/src/testRunner/parallel/host.ts
index 346982ae5fe1b..cbfc9b391c491 100644
--- a/src/testRunner/parallel/host.ts
+++ b/src/testRunner/parallel/host.ts
@@ -12,7 +12,7 @@ import {
TestConfig,
TestRunnerKind,
workerCount,
-} from "../_namespaces/Harness";
+} from "../_namespaces/Harness.js";
import {
ErrorInfo,
ParallelClientMessage,
@@ -21,11 +21,11 @@ import {
Task,
TaskTimeout,
TestInfo,
-} from "../_namespaces/Harness.Parallel";
-import * as ts from "../_namespaces/ts";
-import * as Utils from "../_namespaces/Utils";
+} from "../_namespaces/Harness.Parallel.js";
+import * as ts from "../_namespaces/ts.js";
+import * as Utils from "../_namespaces/Utils.js";
-export function start() {
+export function start(importTests: () => Promise) {
const Mocha = require("mocha") as typeof import("mocha");
const Base = Mocha.reporters.Base;
const color = Base.color;
@@ -656,5 +656,5 @@ export function start() {
shimNoopTestInterface(global);
}
- setTimeout(() => startDelayed(perfData, totalCost), 0); // Do real startup on next tick, so all unit tests have been collected
+ importTests().then(() => startDelayed(perfData, totalCost));
}
diff --git a/src/testRunner/parallel/shared.ts b/src/testRunner/parallel/shared.ts
index 755d353be1f9f..53d310eefcf15 100644
--- a/src/testRunner/parallel/shared.ts
+++ b/src/testRunner/parallel/shared.ts
@@ -1,5 +1,5 @@
-import { TestRunnerKind } from "../_namespaces/Harness";
-import * as ts from "../_namespaces/ts";
+import { TestRunnerKind } from "../_namespaces/Harness.js";
+import * as ts from "../_namespaces/ts.js";
export interface RunnerTask {
runner: TestRunnerKind;
diff --git a/src/testRunner/parallel/worker.ts b/src/testRunner/parallel/worker.ts
index 3637721240732..4b61633e45a53 100644
--- a/src/testRunner/parallel/worker.ts
+++ b/src/testRunner/parallel/worker.ts
@@ -3,7 +3,7 @@ import {
globalTimeout,
RunnerBase,
runUnitTests,
-} from "../_namespaces/Harness";
+} from "../_namespaces/Harness.js";
import {
ErrorInfo,
ParallelClientMessage,
@@ -14,9 +14,12 @@ import {
TaskResult,
TestInfo,
UnitTestTask,
-} from "../_namespaces/Harness.Parallel";
+} from "../_namespaces/Harness.Parallel.js";
+
+export function start(importTests: () => Promise) {
+ // This brings in the tests after we finish setting things up and yield to the event loop.
+ const importTestsPromise = importTests();
-export function start() {
function hookUncaughtExceptions() {
if (!exceptionsHooked) {
process.on("uncaughtException", handleUncaughtException);
@@ -277,7 +280,9 @@ export function start() {
return !!tasks && Array.isArray(tasks) && tasks.length > 0 && tasks.every(validateTest);
}
- function processHostMessage(message: ParallelHostMessage) {
+ async function processHostMessage(message: ParallelHostMessage) {
+ await importTestsPromise;
+
if (!validateHostMessage(message)) {
console.log("Invalid message:", message);
return;
diff --git a/src/testRunner/projectsRunner.ts b/src/testRunner/projectsRunner.ts
index 56394ed3ce28a..fa5d15a11a13e 100644
--- a/src/testRunner/projectsRunner.ts
+++ b/src/testRunner/projectsRunner.ts
@@ -1,10 +1,10 @@
-import * as documents from "./_namespaces/documents";
-import * as fakes from "./_namespaces/fakes";
-import * as Harness from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import * as Utils from "./_namespaces/Utils";
-import * as vfs from "./_namespaces/vfs";
-import * as vpath from "./_namespaces/vpath";
+import * as documents from "./_namespaces/documents.js";
+import * as fakes from "./_namespaces/fakes.js";
+import * as Harness from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import * as Utils from "./_namespaces/Utils.js";
+import * as vfs from "./_namespaces/vfs.js";
+import * as vpath from "./_namespaces/vpath.js";
// Test case is json of below type in tests/cases/project/
interface ProjectRunnerTestCase {
diff --git a/src/testRunner/runner.ts b/src/testRunner/runner.ts
index e5ac52c131025..12fc1308ecba7 100644
--- a/src/testRunner/runner.ts
+++ b/src/testRunner/runner.ts
@@ -1,4 +1,4 @@
-import * as FourSlash from "./_namespaces/FourSlash";
+import * as FourSlash from "./_namespaces/FourSlash.js";
import {
CompilerBaselineRunner,
CompilerTestType,
@@ -12,10 +12,10 @@ import {
setShards,
TestRunnerKind,
TranspileRunner,
-} from "./_namespaces/Harness";
-import * as project from "./_namespaces/project";
-import * as ts from "./_namespaces/ts";
-import * as vpath from "./_namespaces/vpath";
+} from "./_namespaces/Harness.js";
+import * as project from "./_namespaces/project.js";
+import * as ts from "./_namespaces/ts.js";
+import * as vpath from "./_namespaces/vpath.js";
/* eslint-disable prefer-const */
export let runners: RunnerBase[] = [];
@@ -249,6 +249,10 @@ function beginTests() {
}
}
+function importTests() {
+ return import("./tests.js");
+}
+
export let isWorker: boolean;
function startTestEnvironment() {
// For debugging convenience.
@@ -256,20 +260,13 @@ function startTestEnvironment() {
isWorker = handleTestConfig();
if (isWorker) {
- return Parallel.Worker.start();
+ return Parallel.Worker.start(importTests);
}
else if (taskConfigsFolder && workerCount && workerCount > 1) {
- return Parallel.Host.start();
+ return Parallel.Host.start(importTests);
}
beginTests();
+ importTests();
}
startTestEnvironment();
-
-// This brings in all of the unittests.
-
-// If running as emitted CJS, we want to start the tests here after startTestEnvironment.
-// If running bundled, we will do this in Harness.ts.
-if (__filename.endsWith("runner.js")) {
- require("./tests");
-}
diff --git a/src/testRunner/tests.ts b/src/testRunner/tests.ts
index 75a0ca1d32c70..af34d74a1ac66 100644
--- a/src/testRunner/tests.ts
+++ b/src/testRunner/tests.ts
@@ -1,221 +1,228 @@
-import "./unittests/asserts";
-import "./unittests/base64";
-import "./unittests/builder";
-import "./unittests/canWatch";
-import "./unittests/comments";
-import "./unittests/compilerCore";
-import "./unittests/convertToBase64";
-import "./unittests/customTransforms";
-import "./unittests/diagnosticCollection";
-import "./unittests/factory";
-import "./unittests/incrementalParser";
-import "./unittests/jsDocParsing";
-import "./unittests/jsonParserRecovery";
-import "./unittests/moduleResolution";
-import "./unittests/parsePseudoBigInt";
-import "./unittests/paths";
-import "./unittests/printer";
-import "./unittests/programApi";
-import "./unittests/publicApi";
-import "./unittests/reuseProgramStructure";
-import "./unittests/semver";
-import "./unittests/transform";
-import "./unittests/typeParameterIsPossiblyReferenced";
-import "./unittests/config/commandLineParsing";
-import "./unittests/config/configurationExtension";
-import "./unittests/config/convertCompilerOptionsFromJson";
-import "./unittests/config/convertTypeAcquisitionFromJson";
-import "./unittests/config/initializeTSConfig";
-import "./unittests/config/matchFiles";
-import "./unittests/config/showConfig";
-import "./unittests/config/tsconfigParsing";
-import "./unittests/config/tsconfigParsingWatchOptions";
-import "./unittests/evaluation/arraySpread";
-import "./unittests/evaluation/asyncArrow";
-import "./unittests/evaluation/asyncGenerator";
-import "./unittests/evaluation/autoAccessors";
-import "./unittests/evaluation/awaiter";
-import "./unittests/evaluation/constEnum";
-import "./unittests/evaluation/destructuring";
-import "./unittests/evaluation/externalModules";
-import "./unittests/evaluation/esDecorators";
-import "./unittests/evaluation/esDecoratorsMetadata";
-import "./unittests/evaluation/forAwaitOf";
-import "./unittests/evaluation/forOf";
-import "./unittests/evaluation/generator";
-import "./unittests/evaluation/optionalCall";
-import "./unittests/evaluation/objectRest";
-import "./unittests/evaluation/superInStaticInitializer";
-import "./unittests/evaluation/templateLiteral";
-import "./unittests/evaluation/updateExpressionInModule";
-import "./unittests/evaluation/usingDeclarations";
-import "./unittests/evaluation/awaitUsingDeclarations";
-import "./unittests/services/cancellableLanguageServiceOperations";
-import "./unittests/services/colorization";
-import "./unittests/services/convertToAsyncFunction";
-import "./unittests/services/documentRegistry";
-import "./unittests/services/extract/constants";
-import "./unittests/services/extract/functions";
-import "./unittests/services/extract/symbolWalker";
-import "./unittests/services/extract/ranges";
-import "./unittests/services/hostNewLineSupport";
-import "./unittests/services/languageService";
-import "./unittests/services/organizeImports";
-import "./unittests/services/patternMatcher";
-import "./unittests/services/preProcessFile";
-import "./unittests/services/textChanges";
-import "./unittests/services/transpile";
-import "./unittests/services/utilities";
-import "./unittests/sys/symlinkWatching";
-import "./unittests/tsbuild/amdModulesWithOut";
-import "./unittests/tsbuild/clean";
-import "./unittests/tsbuild/commandLine";
-import "./unittests/tsbuild/configFileErrors";
-import "./unittests/tsbuild/configFileExtends";
-import "./unittests/tsbuild/containerOnlyReferenced";
-import "./unittests/tsbuild/declarationEmit";
-import "./unittests/tsbuild/demo";
-import "./unittests/tsbuild/emitDeclarationOnly";
-import "./unittests/tsbuild/emptyFiles";
-import "./unittests/tsbuild/exitCodeOnBogusFile";
-import "./unittests/tsbuild/extends";
-import "./unittests/tsbuild/fileDelete";
-import "./unittests/tsbuild/graphOrdering";
-import "./unittests/tsbuild/inferredTypeFromTransitiveModule";
-import "./unittests/tsbuild/javascriptProjectEmit";
-import "./unittests/tsbuild/lateBoundSymbol";
-import "./unittests/tsbuild/libraryResolution";
-import "./unittests/tsbuild/moduleResolution";
-import "./unittests/tsbuild/moduleSpecifiers";
-import "./unittests/tsbuild/noCheck";
-import "./unittests/tsbuild/noEmit";
-import "./unittests/tsbuild/noEmitOnError";
-import "./unittests/tsbuild/outFile";
-import "./unittests/tsbuild/outputPaths";
-import "./unittests/tsbuild/publicApi";
-import "./unittests/tsbuild/referencesWithRootDirInParent";
-import "./unittests/tsbuild/resolveJsonModule";
-import "./unittests/tsbuild/roots";
-import "./unittests/tsbuild/sample";
-import "./unittests/tsbuild/transitiveReferences";
-import "./unittests/tsbuildWatch/configFileErrors";
-import "./unittests/tsbuildWatch/demo";
-import "./unittests/tsbuildWatch/extends";
-import "./unittests/tsbuildWatch/libraryResolution";
-import "./unittests/tsbuildWatch/moduleResolution";
-import "./unittests/tsbuildWatch/noEmit";
-import "./unittests/tsbuildWatch/noEmitOnError";
-import "./unittests/tsbuildWatch/programUpdates";
-import "./unittests/tsbuildWatch/projectsBuilding";
-import "./unittests/tsbuildWatch/publicApi";
-import "./unittests/tsbuildWatch/reexport";
-import "./unittests/tsbuildWatch/watchEnvironment";
-import "./unittests/tsc/cancellationToken";
-import "./unittests/tsc/composite";
-import "./unittests/tsc/declarationEmit";
-import "./unittests/tsc/extends";
-import "./unittests/tsc/forceConsistentCasingInFileNames";
-import "./unittests/tsc/incremental";
-import "./unittests/tsc/libraryResolution";
-import "./unittests/tsc/listFilesOnly";
-import "./unittests/tsc/moduleResolution";
-import "./unittests/tsc/projectReferences";
-import "./unittests/tsc/projectReferencesConfig";
-import "./unittests/tsc/redirect";
-import "./unittests/tsc/runWithoutArgs";
-import "./unittests/tscWatch/consoleClearing";
-import "./unittests/tscWatch/emit";
-import "./unittests/tscWatch/nodeNextWatch";
-import "./unittests/tscWatch/emitAndErrorUpdates";
-import "./unittests/tscWatch/extends";
-import "./unittests/tscWatch/forceConsistentCasingInFileNames";
-import "./unittests/tscWatch/incremental";
-import "./unittests/tscWatch/libraryResolution";
-import "./unittests/tscWatch/moduleResolution";
-import "./unittests/tscWatch/programUpdates";
-import "./unittests/tscWatch/projectsWithReferences";
-import "./unittests/tscWatch/resolutionCache";
-import "./unittests/tscWatch/resolveJsonModuleWithIncremental";
-import "./unittests/tscWatch/sourceOfProjectReferenceRedirect";
-import "./unittests/tscWatch/symlinks";
-import "./unittests/tscWatch/watchApi";
-import "./unittests/tscWatch/watchEnvironment";
-import "./unittests/tsserver/applyChangesToOpenFiles";
-import "./unittests/tsserver/autoImportProvider";
-import "./unittests/tsserver/auxiliaryProject";
-import "./unittests/tsserver/cachingFileSystemInformation";
-import "./unittests/tsserver/cancellationToken";
-import "./unittests/tsserver/codeFix";
-import "./unittests/tsserver/compileOnSave";
-import "./unittests/tsserver/completions";
-import "./unittests/tsserver/completionsIncomplete";
-import "./unittests/tsserver/configFileSearch";
-import "./unittests/tsserver/configuredProjects";
-import "./unittests/tsserver/declarationFileMaps";
-import "./unittests/tsserver/documentRegistry";
-import "./unittests/tsserver/duplicatePackages";
-import "./unittests/tsserver/dynamicFiles";
-import "./unittests/tsserver/events/largeFileReferenced";
-import "./unittests/tsserver/events/projectLanguageServiceState";
-import "./unittests/tsserver/events/projectLoading";
-import "./unittests/tsserver/events/projectUpdatedInBackground";
-import "./unittests/tsserver/events/watchEvents";
-import "./unittests/tsserver/exportMapCache";
-import "./unittests/tsserver/extends";
-import "./unittests/tsserver/externalProjects";
-import "./unittests/tsserver/findAllReferences";
-import "./unittests/tsserver/forceConsistentCasingInFileNames";
-import "./unittests/tsserver/formatSettings";
-import "./unittests/tsserver/getApplicableRefactors";
-import "./unittests/tsserver/getEditsForFileRename";
-import "./unittests/tsserver/getExportReferences";
-import "./unittests/tsserver/getFileReferences";
-import "./unittests/tsserver/goToDefinition";
-import "./unittests/tsserver/importHelpers";
-import "./unittests/tsserver/inlayHints";
-import "./unittests/tsserver/inferredProjects";
-import "./unittests/tsserver/jsdocTag";
-import "./unittests/tsserver/languageService";
-import "./unittests/tsserver/libraryResolution";
-import "./unittests/tsserver/maxNodeModuleJsDepth";
-import "./unittests/tsserver/metadataInResponse";
-import "./unittests/tsserver/moduleResolution";
-import "./unittests/tsserver/moduleSpecifierCache";
-import "./unittests/tsserver/navTo";
-import "./unittests/tsserver/occurences";
-import "./unittests/tsserver/openFile";
-import "./unittests/tsserver/packageJsonInfo";
-import "./unittests/tsserver/partialSemanticServer";
-import "./unittests/tsserver/plugins";
-import "./unittests/tsserver/pluginsAsync";
-import "./unittests/tsserver/projectErrors";
-import "./unittests/tsserver/projectReferenceCompileOnSave";
-import "./unittests/tsserver/projectReferenceErrors";
-import "./unittests/tsserver/projectReferences";
-import "./unittests/tsserver/projectReferencesSourcemap";
-import "./unittests/tsserver/projects";
-import "./unittests/tsserver/projectsWithReferences";
-import "./unittests/tsserver/refactors";
-import "./unittests/tsserver/reload";
-import "./unittests/tsserver/reloadProjects";
-import "./unittests/tsserver/rename";
-import "./unittests/tsserver/resolutionCache";
-import "./unittests/tsserver/session";
-import "./unittests/tsserver/skipLibCheck";
-import "./unittests/tsserver/smartSelection";
-import "./unittests/tsserver/symlinkCache";
-import "./unittests/tsserver/symLinks";
-import "./unittests/tsserver/syntacticServer";
-import "./unittests/tsserver/syntaxOperations";
-import "./unittests/tsserver/textStorage";
-import "./unittests/tsserver/telemetry";
-import "./unittests/tsserver/typeAquisition";
-import "./unittests/tsserver/typeOnlyImportChains";
-import "./unittests/tsserver/typeReferenceDirectives";
-import "./unittests/tsserver/typingsInstaller";
-import "./unittests/tsserver/versionCache";
-import "./unittests/tsserver/watchEnvironment";
-import "./unittests/debugDeprecation";
-import "./unittests/tsserver/inconsistentErrorInEditor";
-import "./unittests/tsserver/getMoveToRefactoringFileSuggestions";
-import "./unittests/skipJSDocParsing";
+export * from "./unittests/asserts.js";
+export * from "./unittests/base64.js";
+export * from "./unittests/builder.js";
+export * from "./unittests/canWatch.js";
+export * from "./unittests/comments.js";
+export * from "./unittests/compilerCore.js";
+export * from "./unittests/config/commandLineParsing.js";
+export * from "./unittests/config/configurationExtension.js";
+export * from "./unittests/config/convertCompilerOptionsFromJson.js";
+export * from "./unittests/config/convertTypeAcquisitionFromJson.js";
+export * from "./unittests/config/initializeTSConfig.js";
+export * from "./unittests/config/matchFiles.js";
+export * from "./unittests/config/showConfig.js";
+export * from "./unittests/config/tsconfigParsing.js";
+export * from "./unittests/config/tsconfigParsingWatchOptions.js";
+export * from "./unittests/convertToBase64.js";
+export * from "./unittests/customTransforms.js";
+export * from "./unittests/debugDeprecation.js";
+export * from "./unittests/diagnosticCollection.js";
+export * from "./unittests/evaluation/arraySpread.js";
+export * from "./unittests/evaluation/asyncArrow.js";
+export * from "./unittests/evaluation/asyncGenerator.js";
+export * from "./unittests/evaluation/autoAccessors.js";
+export * from "./unittests/evaluation/awaiter.js";
+export * from "./unittests/evaluation/awaitUsingDeclarations.js";
+export * from "./unittests/evaluation/constEnum.js";
+export * from "./unittests/evaluation/destructuring.js";
+export * from "./unittests/evaluation/esDecorators.js";
+export * from "./unittests/evaluation/esDecoratorsMetadata.js";
+export * from "./unittests/evaluation/externalModules.js";
+export * from "./unittests/evaluation/forAwaitOf.js";
+export * from "./unittests/evaluation/forOf.js";
+export * from "./unittests/evaluation/generator.js";
+export * from "./unittests/evaluation/objectRest.js";
+export * from "./unittests/evaluation/optionalCall.js";
+export * from "./unittests/evaluation/superInStaticInitializer.js";
+export * from "./unittests/evaluation/templateLiteral.js";
+export * from "./unittests/evaluation/updateExpressionInModule.js";
+export * from "./unittests/evaluation/usingDeclarations.js";
+export * from "./unittests/factory.js";
+export * from "./unittests/incrementalParser.js";
+export * from "./unittests/jsDocParsing.js";
+export * from "./unittests/jsonParserRecovery.js";
+export * from "./unittests/moduleResolution.js";
+export * from "./unittests/parsePseudoBigInt.js";
+export * from "./unittests/paths.js";
+export * from "./unittests/printer.js";
+export * from "./unittests/programApi.js";
+export * from "./unittests/publicApi.js";
+export * from "./unittests/regExpScannerRecovery.js";
+export * from "./unittests/reuseProgramStructure.js";
+export * from "./unittests/semver.js";
+export * from "./unittests/services/cancellableLanguageServiceOperations.js";
+export * from "./unittests/services/colorization.js";
+export * from "./unittests/services/convertToAsyncFunction.js";
+export * from "./unittests/services/documentRegistry.js";
+export * from "./unittests/services/extract/constants.js";
+export * from "./unittests/services/extract/functions.js";
+export * from "./unittests/services/extract/ranges.js";
+export * from "./unittests/services/extract/symbolWalker.js";
+export * from "./unittests/services/hostNewLineSupport.js";
+export * from "./unittests/services/languageService.js";
+export * from "./unittests/services/organizeImports.js";
+export * from "./unittests/services/patternMatcher.js";
+export * from "./unittests/services/preProcessFile.js";
+export * from "./unittests/services/textChanges.js";
+export * from "./unittests/services/transpile.js";
+export * from "./unittests/services/utilities.js";
+export * from "./unittests/skipJSDocParsing.js";
+export * from "./unittests/sys/symlinkWatching.js";
+export * from "./unittests/transform.js";
+export * from "./unittests/tsbuild/amdModulesWithOut.js";
+export * from "./unittests/tsbuild/clean.js";
+export * from "./unittests/tsbuild/commandLine.js";
+export * from "./unittests/tsbuild/configFileErrors.js";
+export * from "./unittests/tsbuild/configFileExtends.js";
+export * from "./unittests/tsbuild/containerOnlyReferenced.js";
+export * from "./unittests/tsbuild/declarationEmit.js";
+export * from "./unittests/tsbuild/demo.js";
+export * from "./unittests/tsbuild/emitDeclarationOnly.js";
+export * from "./unittests/tsbuild/emptyFiles.js";
+export * from "./unittests/tsbuild/exitCodeOnBogusFile.js";
+export * from "./unittests/tsbuild/extends.js";
+export * from "./unittests/tsbuild/fileDelete.js";
+export * from "./unittests/tsbuild/graphOrdering.js";
+export * from "./unittests/tsbuild/inferredTypeFromTransitiveModule.js";
+export * from "./unittests/tsbuild/javascriptProjectEmit.js";
+export * from "./unittests/tsbuild/lateBoundSymbol.js";
+export * from "./unittests/tsbuild/libraryResolution.js";
+export * from "./unittests/tsbuild/moduleResolution.js";
+export * from "./unittests/tsbuild/moduleSpecifiers.js";
+export * from "./unittests/tsbuild/noCheck.js";
+export * from "./unittests/tsbuild/noEmit.js";
+export * from "./unittests/tsbuild/noEmitOnError.js";
+export * from "./unittests/tsbuild/outFile.js";
+export * from "./unittests/tsbuild/outputPaths.js";
+export * from "./unittests/tsbuild/publicApi.js";
+export * from "./unittests/tsbuild/referencesWithRootDirInParent.js";
+export * from "./unittests/tsbuild/resolveJsonModule.js";
+export * from "./unittests/tsbuild/roots.js";
+export * from "./unittests/tsbuild/sample.js";
+export * from "./unittests/tsbuild/transitiveReferences.js";
+export * from "./unittests/tsbuildWatch/configFileErrors.js";
+export * from "./unittests/tsbuildWatch/demo.js";
+export * from "./unittests/tsbuildWatch/extends.js";
+export * from "./unittests/tsbuildWatch/libraryResolution.js";
+export * from "./unittests/tsbuildWatch/moduleResolution.js";
+export * from "./unittests/tsbuildWatch/noEmit.js";
+export * from "./unittests/tsbuildWatch/noEmitOnError.js";
+export * from "./unittests/tsbuildWatch/programUpdates.js";
+export * from "./unittests/tsbuildWatch/projectsBuilding.js";
+export * from "./unittests/tsbuildWatch/publicApi.js";
+export * from "./unittests/tsbuildWatch/reexport.js";
+export * from "./unittests/tsbuildWatch/roots.js";
+export * from "./unittests/tsbuildWatch/watchEnvironment.js";
+export * from "./unittests/tsc/cancellationToken.js";
+export * from "./unittests/tsc/composite.js";
+export * from "./unittests/tsc/declarationEmit.js";
+export * from "./unittests/tsc/extends.js";
+export * from "./unittests/tsc/forceConsistentCasingInFileNames.js";
+export * from "./unittests/tsc/incremental.js";
+export * from "./unittests/tsc/libraryResolution.js";
+export * from "./unittests/tsc/listFilesOnly.js";
+export * from "./unittests/tsc/moduleResolution.js";
+export * from "./unittests/tsc/noEmit.js";
+export * from "./unittests/tsc/noEmitOnError.js";
+export * from "./unittests/tsc/projectReferences.js";
+export * from "./unittests/tsc/projectReferencesConfig.js";
+export * from "./unittests/tsc/redirect.js";
+export * from "./unittests/tsc/runWithoutArgs.js";
+export * from "./unittests/tscWatch/consoleClearing.js";
+export * from "./unittests/tscWatch/emit.js";
+export * from "./unittests/tscWatch/emitAndErrorUpdates.js";
+export * from "./unittests/tscWatch/extends.js";
+export * from "./unittests/tscWatch/forceConsistentCasingInFileNames.js";
+export * from "./unittests/tscWatch/incremental.js";
+export * from "./unittests/tscWatch/libraryResolution.js";
+export * from "./unittests/tscWatch/moduleResolution.js";
+export * from "./unittests/tscWatch/nodeNextWatch.js";
+export * from "./unittests/tscWatch/noEmitOnError.js";
+export * from "./unittests/tscWatch/programUpdates.js";
+export * from "./unittests/tscWatch/projectsWithReferences.js";
+export * from "./unittests/tscWatch/resolutionCache.js";
+export * from "./unittests/tscWatch/resolveJsonModuleWithIncremental.js";
+export * from "./unittests/tscWatch/sourceOfProjectReferenceRedirect.js";
+export * from "./unittests/tscWatch/symlinks.js";
+export * from "./unittests/tscWatch/watchApi.js";
+export * from "./unittests/tscWatch/watchEnvironment.js";
+export * from "./unittests/tsserver/applyChangesToOpenFiles.js";
+export * from "./unittests/tsserver/autoImportProvider.js";
+export * from "./unittests/tsserver/auxiliaryProject.js";
+export * from "./unittests/tsserver/cachingFileSystemInformation.js";
+export * from "./unittests/tsserver/cancellationToken.js";
+export * from "./unittests/tsserver/codeFix.js";
+export * from "./unittests/tsserver/compileOnSave.js";
+export * from "./unittests/tsserver/completions.js";
+export * from "./unittests/tsserver/completionsIncomplete.js";
+export * from "./unittests/tsserver/configFileSearch.js";
+export * from "./unittests/tsserver/configuredProjects.js";
+export * from "./unittests/tsserver/declarationFileMaps.js";
+export * from "./unittests/tsserver/documentRegistry.js";
+export * from "./unittests/tsserver/duplicatePackages.js";
+export * from "./unittests/tsserver/dynamicFiles.js";
+export * from "./unittests/tsserver/events/largeFileReferenced.js";
+export * from "./unittests/tsserver/events/projectLanguageServiceState.js";
+export * from "./unittests/tsserver/events/projectLoading.js";
+export * from "./unittests/tsserver/events/projectUpdatedInBackground.js";
+export * from "./unittests/tsserver/events/watchEvents.js";
+export * from "./unittests/tsserver/exportMapCache.js";
+export * from "./unittests/tsserver/extends.js";
+export * from "./unittests/tsserver/externalProjects.js";
+export * from "./unittests/tsserver/findAllReferences.js";
+export * from "./unittests/tsserver/forceConsistentCasingInFileNames.js";
+export * from "./unittests/tsserver/formatSettings.js";
+export * from "./unittests/tsserver/getApplicableRefactors.js";
+export * from "./unittests/tsserver/getEditsForFileRename.js";
+export * from "./unittests/tsserver/getExportReferences.js";
+export * from "./unittests/tsserver/getFileReferences.js";
+export * from "./unittests/tsserver/getMoveToRefactoringFileSuggestions.js";
+export * from "./unittests/tsserver/goToDefinition.js";
+export * from "./unittests/tsserver/importHelpers.js";
+export * from "./unittests/tsserver/inconsistentErrorInEditor.js";
+export * from "./unittests/tsserver/inferredProjects.js";
+export * from "./unittests/tsserver/inlayHints.js";
+export * from "./unittests/tsserver/jsdocTag.js";
+export * from "./unittests/tsserver/languageService.js";
+export * from "./unittests/tsserver/libraryResolution.js";
+export * from "./unittests/tsserver/maxNodeModuleJsDepth.js";
+export * from "./unittests/tsserver/metadataInResponse.js";
+export * from "./unittests/tsserver/moduleResolution.js";
+export * from "./unittests/tsserver/moduleSpecifierCache.js";
+export * from "./unittests/tsserver/navTo.js";
+export * from "./unittests/tsserver/occurences.js";
+export * from "./unittests/tsserver/openFile.js";
+export * from "./unittests/tsserver/packageJsonInfo.js";
+export * from "./unittests/tsserver/partialSemanticServer.js";
+export * from "./unittests/tsserver/pasteEdits.js";
+export * from "./unittests/tsserver/plugins.js";
+export * from "./unittests/tsserver/pluginsAsync.js";
+export * from "./unittests/tsserver/projectErrors.js";
+export * from "./unittests/tsserver/projectReferenceCompileOnSave.js";
+export * from "./unittests/tsserver/projectReferenceErrors.js";
+export * from "./unittests/tsserver/projectReferences.js";
+export * from "./unittests/tsserver/projectReferencesSourcemap.js";
+export * from "./unittests/tsserver/projectRootFiles.js";
+export * from "./unittests/tsserver/projects.js";
+export * from "./unittests/tsserver/projectsWithReferences.js";
+export * from "./unittests/tsserver/refactors.js";
+export * from "./unittests/tsserver/reload.js";
+export * from "./unittests/tsserver/reloadProjects.js";
+export * from "./unittests/tsserver/rename.js";
+export * from "./unittests/tsserver/resolutionCache.js";
+export * from "./unittests/tsserver/session.js";
+export * from "./unittests/tsserver/skipLibCheck.js";
+export * from "./unittests/tsserver/smartSelection.js";
+export * from "./unittests/tsserver/symlinkCache.js";
+export * from "./unittests/tsserver/symLinks.js";
+export * from "./unittests/tsserver/syntacticServer.js";
+export * from "./unittests/tsserver/syntaxOperations.js";
+export * from "./unittests/tsserver/telemetry.js";
+export * from "./unittests/tsserver/textStorage.js";
+export * from "./unittests/tsserver/typeAquisition.js";
+export * from "./unittests/tsserver/typeOnlyImportChains.js";
+export * from "./unittests/tsserver/typeReferenceDirectives.js";
+export * from "./unittests/tsserver/typingsInstaller.js";
+export * from "./unittests/tsserver/versionCache.js";
+export * from "./unittests/tsserver/watchEnvironment.js";
+export * from "./unittests/typeParameterIsPossiblyReferenced.js";
diff --git a/src/testRunner/transpileRunner.ts b/src/testRunner/transpileRunner.ts
index fd8526d79a69d..80a9794fe2bc1 100644
--- a/src/testRunner/transpileRunner.ts
+++ b/src/testRunner/transpileRunner.ts
@@ -6,9 +6,9 @@ import {
RunnerBase,
TestCaseParser,
TestRunnerKind,
-} from "./_namespaces/Harness";
-import * as ts from "./_namespaces/ts";
-import * as vpath from "./_namespaces/vpath";
+} from "./_namespaces/Harness.js";
+import * as ts from "./_namespaces/ts.js";
+import * as vpath from "./_namespaces/vpath.js";
export class TranspileRunner extends RunnerBase {
protected basePath = "tests/cases/transpile";
diff --git a/src/testRunner/unittests/asserts.ts b/src/testRunner/unittests/asserts.ts
index 0656156e852c0..48f1d32fd146c 100644
--- a/src/testRunner/unittests/asserts.ts
+++ b/src/testRunner/unittests/asserts.ts
@@ -1,4 +1,4 @@
-import * as ts from "../_namespaces/ts";
+import * as ts from "../_namespaces/ts.js";
describe("unittests:: assert", () => {
it("deepEqual", () => {
diff --git a/src/testRunner/unittests/base64.ts b/src/testRunner/unittests/base64.ts
index 82ae5df634814..996cae1d12ebf 100644
--- a/src/testRunner/unittests/base64.ts
+++ b/src/testRunner/unittests/base64.ts
@@ -1,4 +1,4 @@
-import * as ts from "../_namespaces/ts";
+import * as ts from "../_namespaces/ts.js";
describe("unittests:: base64", () => {
describe("base64decode", () => {
diff --git a/src/testRunner/unittests/builder.ts b/src/testRunner/unittests/builder.ts
index 65ad35bfd6c6c..66b133cfa02c6 100644
--- a/src/testRunner/unittests/builder.ts
+++ b/src/testRunner/unittests/builder.ts
@@ -1,4 +1,4 @@
-import * as ts from "../_namespaces/ts";
+import * as ts from "../_namespaces/ts.js";
import {
NamedSourceText,
newProgram,
@@ -6,7 +6,7 @@ import {
SourceText,
updateProgram,
updateProgramText,
-} from "./helpers";
+} from "./helpers.js";
describe("unittests:: builder", () => {
it("emits dependent files", () => {
diff --git a/src/testRunner/unittests/canWatch.ts b/src/testRunner/unittests/canWatch.ts
index 736d45b5198ab..b5d4f4f58af1d 100644
--- a/src/testRunner/unittests/canWatch.ts
+++ b/src/testRunner/unittests/canWatch.ts
@@ -1,5 +1,5 @@
-import { Baseline } from "../_namespaces/Harness";
-import * as ts from "../_namespaces/ts";
+import { Baseline } from "../_namespaces/Harness.js";
+import * as ts from "../_namespaces/ts.js";
describe("unittests:: canWatch::", () => {
baselineCanWatch(
"canWatchDirectoryOrFile",
diff --git a/src/testRunner/unittests/comments.ts b/src/testRunner/unittests/comments.ts
index 74d6919285616..a1eeeb8aacfa1 100644
--- a/src/testRunner/unittests/comments.ts
+++ b/src/testRunner/unittests/comments.ts
@@ -1,4 +1,4 @@
-import * as ts from "../_namespaces/ts";
+import * as ts from "../_namespaces/ts.js";
describe("comment parsing", () => {
const withShebang = `#! node
@@ -14,19 +14,19 @@ describe("comment parsing", () => {
it("skips shebang", () => {
const result = ts.getLeadingCommentRanges(withShebang, 0);
assert.isDefined(result);
- assert.strictEqual(result!.length, 2);
+ assert.strictEqual(result.length, 2);
});
it("treats all comments at start of file as leading comments", () => {
const result = ts.getLeadingCommentRanges(noShebang, 0);
assert.isDefined(result);
- assert.strictEqual(result!.length, 2);
+ assert.strictEqual(result.length, 2);
});
it("returns leading comments if position is not 0", () => {
const result = ts.getLeadingCommentRanges(withTrailing, 1);
assert.isDefined(result);
- assert.strictEqual(result!.length, 1);
- assert.strictEqual(result![0].kind, ts.SyntaxKind.SingleLineCommentTrivia);
+ assert.strictEqual(result.length, 1);
+ assert.strictEqual(result[0].kind, ts.SyntaxKind.SingleLineCommentTrivia);
});
});
diff --git a/src/testRunner/unittests/compilerCore.ts b/src/testRunner/unittests/compilerCore.ts
index ed2415eb6aec5..82a259df154ef 100644
--- a/src/testRunner/unittests/compilerCore.ts
+++ b/src/testRunner/unittests/compilerCore.ts
@@ -1,4 +1,4 @@
-import * as ts from "../_namespaces/ts";
+import * as ts from "../_namespaces/ts.js";
describe("unittests:: compilerCore", () => {
describe("equalOwnProperties", () => {
diff --git a/src/testRunner/unittests/config/commandLineParsing.ts b/src/testRunner/unittests/config/commandLineParsing.ts
index 6173663884323..9c5dc6d3f2351 100644
--- a/src/testRunner/unittests/config/commandLineParsing.ts
+++ b/src/testRunner/unittests/config/commandLineParsing.ts
@@ -1,6 +1,6 @@
-import * as Harness from "../../_namespaces/Harness";
-import * as ts from "../../_namespaces/ts";
-import { jsonToReadableText } from "../helpers";
+import * as Harness from "../../_namespaces/Harness.js";
+import * as ts from "../../_namespaces/ts.js";
+import { jsonToReadableText } from "../helpers.js";
describe("unittests:: config:: commandLineParsing:: parseCommandLine", () => {
function assertParseResult(subScenario: string, commandLine: string[], workerDiagnostic?: () => ts.ParseCommandLineWorkerDiagnostics) {
diff --git a/src/testRunner/unittests/config/configurationExtension.ts b/src/testRunner/unittests/config/configurationExtension.ts
index 7006b3dbe7169..251cc965746c7 100644
--- a/src/testRunner/unittests/config/configurationExtension.ts
+++ b/src/testRunner/unittests/config/configurationExtension.ts
@@ -1,12 +1,12 @@
-import * as fakes from "../../_namespaces/fakes";
-import * as Harness from "../../_namespaces/Harness";
-import * as ts from "../../_namespaces/ts";
-import * as vfs from "../../_namespaces/vfs";
-import { jsonToReadableText } from "../helpers";
+import * as fakes from "../../_namespaces/fakes.js";
+import * as Harness from "../../_namespaces/Harness.js";
+import * as ts from "../../_namespaces/ts.js";
+import * as vfs from "../../_namespaces/vfs.js";
+import { jsonToReadableText } from "../helpers.js";
import {
baselineParseConfig,
baselineParseConfigHost,
-} from "./helpers";
+} from "./helpers.js";
function createFileSystem(ignoreCase: boolean, cwd: string, root: string) {
return new vfs.FileSystem(ignoreCase, {
diff --git a/src/testRunner/unittests/config/convertCompilerOptionsFromJson.ts b/src/testRunner/unittests/config/convertCompilerOptionsFromJson.ts
index 684484c6c2ce2..1acec6596358e 100644
--- a/src/testRunner/unittests/config/convertCompilerOptionsFromJson.ts
+++ b/src/testRunner/unittests/config/convertCompilerOptionsFromJson.ts
@@ -1,7 +1,7 @@
-import * as fakes from "../../_namespaces/fakes";
-import * as vfs from "../../_namespaces/vfs";
-import { jsonToReadableText } from "../helpers";
-import { baselineParseConfig } from "./helpers";
+import * as fakes from "../../_namespaces/fakes.js";
+import * as vfs from "../../_namespaces/vfs.js";
+import { jsonToReadableText } from "../helpers.js";
+import { baselineParseConfig } from "./helpers.js";
describe("unittests:: config:: convertCompilerOptionsFromJson", () => {
function baselineCompilerOptions(subScenario: string, json: any, configFileName: string) {
diff --git a/src/testRunner/unittests/config/convertTypeAcquisitionFromJson.ts b/src/testRunner/unittests/config/convertTypeAcquisitionFromJson.ts
index 2a0e1f458af1a..9cdad65b4c40b 100644
--- a/src/testRunner/unittests/config/convertTypeAcquisitionFromJson.ts
+++ b/src/testRunner/unittests/config/convertTypeAcquisitionFromJson.ts
@@ -1,7 +1,7 @@
-import * as fakes from "../../_namespaces/fakes";
-import * as vfs from "../../_namespaces/vfs";
-import { jsonToReadableText } from "../helpers";
-import { baselineParseConfig } from "./helpers";
+import * as fakes from "../../_namespaces/fakes.js";
+import * as vfs from "../../_namespaces/vfs.js";
+import { jsonToReadableText } from "../helpers.js";
+import { baselineParseConfig } from "./helpers.js";
describe("unittests:: config:: convertTypeAcquisitionFromJson", () => {
function baselineTypeAcquisition(subScenario: string, json: any, configFileName: string) {
diff --git a/src/testRunner/unittests/config/helpers.ts b/src/testRunner/unittests/config/helpers.ts
index dd219e84afe39..5a5aa78c24fed 100644
--- a/src/testRunner/unittests/config/helpers.ts
+++ b/src/testRunner/unittests/config/helpers.ts
@@ -1,7 +1,7 @@
-import * as fakes from "../../_namespaces/fakes";
-import * as Harness from "../../_namespaces/Harness";
-import * as ts from "../../_namespaces/ts";
-import * as vfs from "../../_namespaces/vfs";
+import * as fakes from "../../_namespaces/fakes.js";
+import * as Harness from "../../_namespaces/Harness.js";
+import * as ts from "../../_namespaces/ts.js";
+import * as vfs from "../../_namespaces/vfs.js";
function getParsedCommandJson(
jsonText: string,
diff --git a/src/testRunner/unittests/config/initializeTSConfig.ts b/src/testRunner/unittests/config/initializeTSConfig.ts
index d2965cdca7c17..713c693d0e807 100644
--- a/src/testRunner/unittests/config/initializeTSConfig.ts
+++ b/src/testRunner/unittests/config/initializeTSConfig.ts
@@ -1,5 +1,5 @@
-import * as Harness from "../../_namespaces/Harness";
-import * as ts from "../../_namespaces/ts";
+import * as Harness from "../../_namespaces/Harness.js";
+import * as ts from "../../_namespaces/ts.js";
describe("unittests:: config:: initTSConfig", () => {
function initTSConfigCorrectly(name: string, commandLinesArgs: string[]) {
diff --git a/src/testRunner/unittests/config/matchFiles.ts b/src/testRunner/unittests/config/matchFiles.ts
index f2359ca9922ea..05a668e3e079d 100644
--- a/src/testRunner/unittests/config/matchFiles.ts
+++ b/src/testRunner/unittests/config/matchFiles.ts
@@ -1,8 +1,8 @@
-import * as fakes from "../../_namespaces/fakes";
-import * as ts from "../../_namespaces/ts";
-import * as vfs from "../../_namespaces/vfs";
-import { jsonToReadableText } from "../helpers";
-import { baselineParseConfig } from "./helpers";
+import * as fakes from "../../_namespaces/fakes.js";
+import * as ts from "../../_namespaces/ts.js";
+import * as vfs from "../../_namespaces/vfs.js";
+import { jsonToReadableText } from "../helpers.js";
+import { baselineParseConfig } from "./helpers.js";
const caseInsensitiveBasePath = "c:/dev/";
const caseInsensitiveTsconfigPath = "c:/dev/tsconfig.json";
diff --git a/src/testRunner/unittests/config/showConfig.ts b/src/testRunner/unittests/config/showConfig.ts
index 3e02a256d8f29..0061df800a223 100644
--- a/src/testRunner/unittests/config/showConfig.ts
+++ b/src/testRunner/unittests/config/showConfig.ts
@@ -1,5 +1,5 @@
-import * as Harness from "../../_namespaces/Harness";
-import * as ts from "../../_namespaces/ts";
+import * as Harness from "../../_namespaces/Harness.js";
+import * as ts from "../../_namespaces/ts.js";
describe("unittests:: config:: showConfig", () => {
function showTSConfigCorrectly(name: string, commandLinesArgs: string[], configJson?: object) {
diff --git a/src/testRunner/unittests/config/tsconfigParsing.ts b/src/testRunner/unittests/config/tsconfigParsing.ts
index 6652c2ffb2b38..c3893dde6eb59 100644
--- a/src/testRunner/unittests/config/tsconfigParsing.ts
+++ b/src/testRunner/unittests/config/tsconfigParsing.ts
@@ -1,9 +1,9 @@
-import * as fakes from "../../_namespaces/fakes";
-import * as Harness from "../../_namespaces/Harness";
-import * as ts from "../../_namespaces/ts";
-import * as vfs from "../../_namespaces/vfs";
-import { jsonToReadableText } from "../helpers";
-import { baselineParseConfig } from "./helpers";
+import * as fakes from "../../_namespaces/fakes.js";
+import * as Harness from "../../_namespaces/Harness.js";
+import * as ts from "../../_namespaces/ts.js";
+import * as vfs from "../../_namespaces/vfs.js";
+import { jsonToReadableText } from "../helpers.js";
+import { baselineParseConfig } from "./helpers.js";
describe("unittests:: config:: tsconfigParsing:: parseConfigFileTextToJson", () => {
function formatErrors(errors: readonly ts.Diagnostic[]) {
diff --git a/src/testRunner/unittests/config/tsconfigParsingWatchOptions.ts b/src/testRunner/unittests/config/tsconfigParsingWatchOptions.ts
index 24837791623a7..1890be7fb560f 100644
--- a/src/testRunner/unittests/config/tsconfigParsingWatchOptions.ts
+++ b/src/testRunner/unittests/config/tsconfigParsingWatchOptions.ts
@@ -1,8 +1,8 @@
-import * as fakes from "../../_namespaces/fakes";
-import * as ts from "../../_namespaces/ts";
-import * as vfs from "../../_namespaces/vfs";
-import { jsonToReadableText } from "../helpers";
-import { baselineParseConfig } from "./helpers";
+import * as fakes from "../../_namespaces/fakes.js";
+import * as ts from "../../_namespaces/ts.js";
+import * as vfs from "../../_namespaces/vfs.js";
+import { jsonToReadableText } from "../helpers.js";
+import { baselineParseConfig } from "./helpers.js";
describe("unittests:: config:: tsconfigParsingWatchOptions:: parseConfigFileTextToJson", () => {
interface VerifyWatchOptions {
diff --git a/src/testRunner/unittests/convertToBase64.ts b/src/testRunner/unittests/convertToBase64.ts
index e801451208ef9..a3465854d7853 100644
--- a/src/testRunner/unittests/convertToBase64.ts
+++ b/src/testRunner/unittests/convertToBase64.ts
@@ -1,4 +1,4 @@
-import * as ts from "../_namespaces/ts";
+import * as ts from "../_namespaces/ts.js";
describe("unittests:: convertToBase64", () => {
function runTest(input: string): void {
diff --git a/src/testRunner/unittests/customTransforms.ts b/src/testRunner/unittests/customTransforms.ts
index 2af7834ccf72b..ec46c04206ad4 100644
--- a/src/testRunner/unittests/customTransforms.ts
+++ b/src/testRunner/unittests/customTransforms.ts
@@ -1,5 +1,5 @@
-import * as Harness from "../_namespaces/Harness";
-import * as ts from "../_namespaces/ts";
+import * as Harness from "../_namespaces/Harness.js";
+import * as ts from "../_namespaces/ts.js";
describe("unittests:: customTransforms", () => {
function emitsCorrectly(name: string, sources: { file: string; text: string; }[], customTransformers: ts.CustomTransformers, options: ts.CompilerOptions = {}) {
diff --git a/src/testRunner/unittests/debugDeprecation.ts b/src/testRunner/unittests/debugDeprecation.ts
index 4019a021bb807..09cc781114780 100644
--- a/src/testRunner/unittests/debugDeprecation.ts
+++ b/src/testRunner/unittests/debugDeprecation.ts
@@ -1,5 +1,5 @@
-import { deprecate } from "../../deprecatedCompat/deprecate";
-import * as ts from "../_namespaces/ts";
+import { deprecate } from "../../deprecatedCompat/deprecate.js";
+import * as ts from "../_namespaces/ts.js";
describe("unittests:: debugDeprecation", () => {
let loggingHost: ts.LoggingHost | undefined;
diff --git a/src/testRunner/unittests/diagnosticCollection.ts b/src/testRunner/unittests/diagnosticCollection.ts
index e0b543ac31272..4ea709f78049e 100644
--- a/src/testRunner/unittests/diagnosticCollection.ts
+++ b/src/testRunner/unittests/diagnosticCollection.ts
@@ -1,4 +1,4 @@
-import * as ts from "../_namespaces/ts";
+import * as ts from "../_namespaces/ts.js";
describe("unittests:: internalApi:: diagnosticCollection", () => {
describe("add", () => {
diff --git a/src/testRunner/unittests/evaluation/arraySpread.ts b/src/testRunner/unittests/evaluation/arraySpread.ts
index cc871a76a2f46..aaf113dcaf4ef 100644
--- a/src/testRunner/unittests/evaluation/arraySpread.ts
+++ b/src/testRunner/unittests/evaluation/arraySpread.ts
@@ -1,4 +1,4 @@
-import * as evaluator from "../../_namespaces/evaluator";
+import * as evaluator from "../../_namespaces/evaluator.js";
describe("unittests:: evaluation:: arraySpread", () => {
it("array spread preserves side-effects", async () => {
diff --git a/src/testRunner/unittests/evaluation/asyncArrow.ts b/src/testRunner/unittests/evaluation/asyncArrow.ts
index 6521e89e2befd..652a66a88e5ec 100644
--- a/src/testRunner/unittests/evaluation/asyncArrow.ts
+++ b/src/testRunner/unittests/evaluation/asyncArrow.ts
@@ -1,4 +1,4 @@
-import * as evaluator from "../../_namespaces/evaluator";
+import * as evaluator from "../../_namespaces/evaluator.js";
describe("unittests:: evaluation:: asyncArrowEvaluation", () => {
// https://github.com/Microsoft/TypeScript/issues/24722
@@ -17,4 +17,29 @@ describe("unittests:: evaluation:: asyncArrowEvaluation", () => {
await result.main();
assert.instanceOf(result.output[0].a(), result.A);
});
+
+ // https://github.com/microsoft/TypeScript/issues/57897
+ it("Class alias (es5)", async () => {
+ const result = evaluator.evaluateTypeScript(`
+ class X {
+ public static a = async (someVar: boolean = true) => {
+ return await X.b();
+ };
+
+ public static b = async () => {
+ return "GOOD";
+ };
+ }
+
+ export async function main() {
+ try {
+ return await X.a();
+ }
+ catch (e) {
+ return "BAD";
+ }
+ }`);
+ const output = await result.main();
+ assert.equal(output, "GOOD");
+ });
});
diff --git a/src/testRunner/unittests/evaluation/asyncGenerator.ts b/src/testRunner/unittests/evaluation/asyncGenerator.ts
index f067c872aaff2..78c54bde9238e 100644
--- a/src/testRunner/unittests/evaluation/asyncGenerator.ts
+++ b/src/testRunner/unittests/evaluation/asyncGenerator.ts
@@ -1,5 +1,5 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
describe("unittests:: evaluation:: asyncGeneratorEvaluation", () => {
it("return (es5)", async () => {
diff --git a/src/testRunner/unittests/evaluation/autoAccessors.ts b/src/testRunner/unittests/evaluation/autoAccessors.ts
index 6f4d37587a3f7..2a02ed1483786 100644
--- a/src/testRunner/unittests/evaluation/autoAccessors.ts
+++ b/src/testRunner/unittests/evaluation/autoAccessors.ts
@@ -1,5 +1,5 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
describe("unittests:: evaluation:: autoAccessors", () => {
const editions = [
@@ -20,8 +20,8 @@ describe("unittests:: evaluation:: autoAccessors", () => {
const desc = Object.getOwnPropertyDescriptor(C.prototype, "x");
assert.isDefined(desc);
- assert.isFunction(desc!.get);
- assert.isFunction(desc!.set);
+ assert.isFunction(desc.get);
+ assert.isFunction(desc.set);
});
it("storage is private", async () => {
diff --git a/src/testRunner/unittests/evaluation/awaitUsingDeclarations.ts b/src/testRunner/unittests/evaluation/awaitUsingDeclarations.ts
index aced8512f138f..2ba072b212270 100644
--- a/src/testRunner/unittests/evaluation/awaitUsingDeclarations.ts
+++ b/src/testRunner/unittests/evaluation/awaitUsingDeclarations.ts
@@ -1,5 +1,5 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
function FakeSuppressedError(error: any, suppressed: any) {
return { error, suppressed };
@@ -232,8 +232,8 @@ describe("unittests:: evaluation:: awaitUsingDeclarations", () => {
]);
assert.instanceOf(output[4], Error);
assert.strictEqual(output[4].name, "SuppressedError");
- assert.strictEqual(output[4].error, "dispose error");
- assert.strictEqual(output[4].suppressed, "body error");
+ assert.strictEqual((output[4] as any).error, "dispose error");
+ assert.strictEqual((output[4] as any).suppressed, "body error");
assert.deepEqual(output.slice(5), [
"after try",
]);
@@ -1791,4 +1791,87 @@ describe("unittests:: evaluation:: awaitUsingDeclarations", () => {
"no interleave",
]);
});
+
+ // https://github.com/microsoft/TypeScript/issues/58077
+ it("Promise returned by sync dispose is not awaited", async () => {
+ const { main, output } = evaluator.evaluateTypeScript(
+ `
+ export const output: any[] = [];
+
+ export async function main() {
+ const promiseDispose = new Promise((resolve) => {
+ setTimeout(() => {
+ output.push("y dispose promise body");
+ resolve();
+ }, 0);
+ });
+
+ {
+ await using x = {
+ async [Symbol.asyncDispose]() {
+ output.push("x asyncDispose body");
+ },
+ };
+ await using y = {
+ [Symbol.dispose]() {
+ output.push("y dispose body");
+ return promiseDispose;
+ },
+ };
+ }
+
+ output.push("body");
+ await promiseDispose;
+ }
+
+ `,
+ { target: ts.ScriptTarget.ES2018 },
+ );
+
+ await main();
+
+ assert.deepEqual(output, [
+ "y dispose body",
+ "x asyncDispose body",
+ "body",
+ "y dispose promise body",
+ ]);
+ });
+
+ // https://github.com/microsoft/TypeScript/issues/58077
+ it("Exception thrown by sync dispose is handled as rejection", async () => {
+ const { main, output } = evaluator.evaluateTypeScript(
+ `
+ export const output: any[] = [];
+
+ export async function main() {
+ const interleave = Promise.resolve().then(() => { output.push("interleave"); });
+
+ try {
+ await using x = {
+ [Symbol.dispose]() {
+ output.push("dispose");
+ throw null;
+ },
+ };
+ }
+ catch {
+ output.push("catch");
+ }
+
+ await interleave;
+ }
+
+ `,
+ { target: ts.ScriptTarget.ES2018 },
+ );
+
+ await main();
+
+ assert.deepEqual(output, [
+ "dispose",
+ "interleave",
+ "catch",
+ ]);
+ });
});
diff --git a/src/testRunner/unittests/evaluation/awaiter.ts b/src/testRunner/unittests/evaluation/awaiter.ts
index 87007d8925934..718521d0bb309 100644
--- a/src/testRunner/unittests/evaluation/awaiter.ts
+++ b/src/testRunner/unittests/evaluation/awaiter.ts
@@ -1,4 +1,4 @@
-import * as evaluator from "../../_namespaces/evaluator";
+import * as evaluator from "../../_namespaces/evaluator.js";
describe("unittests:: evaluation:: awaiter", () => {
// NOTE: This could break if the ECMAScript spec ever changes the timing behavior for Promises (again)
diff --git a/src/testRunner/unittests/evaluation/constEnum.ts b/src/testRunner/unittests/evaluation/constEnum.ts
index 8074c00627ff6..9060dba8d2843 100644
--- a/src/testRunner/unittests/evaluation/constEnum.ts
+++ b/src/testRunner/unittests/evaluation/constEnum.ts
@@ -1,4 +1,4 @@
-import * as evaluator from "../../_namespaces/evaluator";
+import * as evaluator from "../../_namespaces/evaluator.js";
describe("unittests:: evaluation:: constEnum", () => {
it("correct order of operations for inlined negative numbers", async () => {
diff --git a/src/testRunner/unittests/evaluation/destructuring.ts b/src/testRunner/unittests/evaluation/destructuring.ts
index 6a36f92fab830..a8dbf796653a2 100644
--- a/src/testRunner/unittests/evaluation/destructuring.ts
+++ b/src/testRunner/unittests/evaluation/destructuring.ts
@@ -1,5 +1,5 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
describe("unittests:: evaluation:: destructuring", () => {
// https://github.com/microsoft/TypeScript/issues/39205
diff --git a/src/testRunner/unittests/evaluation/esDecorators.ts b/src/testRunner/unittests/evaluation/esDecorators.ts
index 258bfcc803e6a..5c54951a57b95 100644
--- a/src/testRunner/unittests/evaluation/esDecorators.ts
+++ b/src/testRunner/unittests/evaluation/esDecorators.ts
@@ -1,6 +1,6 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
-import { ScriptTarget } from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
+import { ScriptTarget } from "../../_namespaces/ts.js";
describe("unittests:: evaluation:: esDecorators", () => {
const options: ts.CompilerOptions = { target: ts.ScriptTarget.ES2021 };
diff --git a/src/testRunner/unittests/evaluation/esDecoratorsMetadata.ts b/src/testRunner/unittests/evaluation/esDecoratorsMetadata.ts
index 3a5a979d4895d..5261c3d7cef96 100644
--- a/src/testRunner/unittests/evaluation/esDecoratorsMetadata.ts
+++ b/src/testRunner/unittests/evaluation/esDecoratorsMetadata.ts
@@ -1,6 +1,6 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
-import { ScriptTarget } from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
+import { ScriptTarget } from "../../_namespaces/ts.js";
describe("unittests:: evaluation:: esDecoratorsMetadata", () => {
const nodeVersion = new ts.Version(process.versions.node);
diff --git a/src/testRunner/unittests/evaluation/externalModules.ts b/src/testRunner/unittests/evaluation/externalModules.ts
index f6719764870bb..b387ad62b22a3 100644
--- a/src/testRunner/unittests/evaluation/externalModules.ts
+++ b/src/testRunner/unittests/evaluation/externalModules.ts
@@ -1,4 +1,4 @@
-import * as evaluator from "../../_namespaces/evaluator";
+import * as evaluator from "../../_namespaces/evaluator.js";
describe("unittests:: evaluation:: externalModules", () => {
// https://github.com/microsoft/TypeScript/issues/35420
diff --git a/src/testRunner/unittests/evaluation/forAwaitOf.ts b/src/testRunner/unittests/evaluation/forAwaitOf.ts
index 76b1f931c5540..1f2d4c2668261 100644
--- a/src/testRunner/unittests/evaluation/forAwaitOf.ts
+++ b/src/testRunner/unittests/evaluation/forAwaitOf.ts
@@ -1,5 +1,5 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
describe("unittests:: evaluation:: forAwaitOfEvaluation", () => {
it("sync (es5)", async () => {
diff --git a/src/testRunner/unittests/evaluation/forOf.ts b/src/testRunner/unittests/evaluation/forOf.ts
index 8b2fd226770e8..b95914a6d5970 100644
--- a/src/testRunner/unittests/evaluation/forOf.ts
+++ b/src/testRunner/unittests/evaluation/forOf.ts
@@ -1,5 +1,5 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
describe("unittests:: evaluation:: forOfEvaluation", () => {
it("es5 over a array with no Symbol", () => {
diff --git a/src/testRunner/unittests/evaluation/generator.ts b/src/testRunner/unittests/evaluation/generator.ts
index 676b9ff699750..06f22c3680fa5 100644
--- a/src/testRunner/unittests/evaluation/generator.ts
+++ b/src/testRunner/unittests/evaluation/generator.ts
@@ -1,5 +1,5 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
describe("unittests:: evaluation:: generatorEvaluation", () => {
it("throw before start (es5)", () => {
diff --git a/src/testRunner/unittests/evaluation/objectRest.ts b/src/testRunner/unittests/evaluation/objectRest.ts
index ebbaa7219a7f6..20f5481588eb6 100644
--- a/src/testRunner/unittests/evaluation/objectRest.ts
+++ b/src/testRunner/unittests/evaluation/objectRest.ts
@@ -1,4 +1,4 @@
-import * as evaluator from "../../_namespaces/evaluator";
+import * as evaluator from "../../_namespaces/evaluator.js";
describe("unittests:: evaluation:: objectRest", () => {
// https://github.com/microsoft/TypeScript/issues/31469
diff --git a/src/testRunner/unittests/evaluation/optionalCall.ts b/src/testRunner/unittests/evaluation/optionalCall.ts
index db92162a3e14f..392bdd3c40804 100644
--- a/src/testRunner/unittests/evaluation/optionalCall.ts
+++ b/src/testRunner/unittests/evaluation/optionalCall.ts
@@ -1,4 +1,4 @@
-import * as evaluator from "../../_namespaces/evaluator";
+import * as evaluator from "../../_namespaces/evaluator.js";
describe("unittests:: evaluation:: optionalCall", () => {
it("f?.()", async () => {
diff --git a/src/testRunner/unittests/evaluation/superInStaticInitializer.ts b/src/testRunner/unittests/evaluation/superInStaticInitializer.ts
index c5e2f84b4eb0b..ad07548f204bf 100644
--- a/src/testRunner/unittests/evaluation/superInStaticInitializer.ts
+++ b/src/testRunner/unittests/evaluation/superInStaticInitializer.ts
@@ -1,5 +1,5 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
describe("unittests:: evaluation:: superInStaticInitializer", () => {
it("super-property-get in es2015", () => {
diff --git a/src/testRunner/unittests/evaluation/templateLiteral.ts b/src/testRunner/unittests/evaluation/templateLiteral.ts
index 65fabb9d4ccbb..924bc60389066 100644
--- a/src/testRunner/unittests/evaluation/templateLiteral.ts
+++ b/src/testRunner/unittests/evaluation/templateLiteral.ts
@@ -1,4 +1,4 @@
-import * as evaluator from "../../_namespaces/evaluator";
+import * as evaluator from "../../_namespaces/evaluator.js";
describe("unittests:: evaluation:: templateLiteral", () => {
it("toString() over valueOf()", () => {
diff --git a/src/testRunner/unittests/evaluation/updateExpressionInModule.ts b/src/testRunner/unittests/evaluation/updateExpressionInModule.ts
index dc0eaade1c1eb..2dc7b5188a650 100644
--- a/src/testRunner/unittests/evaluation/updateExpressionInModule.ts
+++ b/src/testRunner/unittests/evaluation/updateExpressionInModule.ts
@@ -1,5 +1,5 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
describe("unittests:: evaluation:: updateExpressionInModule", () => {
// only run BigInt tests if BigInt is supported in the host environment
diff --git a/src/testRunner/unittests/evaluation/usingDeclarations.ts b/src/testRunner/unittests/evaluation/usingDeclarations.ts
index 11adef2fb2b31..d7c3bd26a47b5 100644
--- a/src/testRunner/unittests/evaluation/usingDeclarations.ts
+++ b/src/testRunner/unittests/evaluation/usingDeclarations.ts
@@ -1,5 +1,5 @@
-import * as evaluator from "../../_namespaces/evaluator";
-import * as ts from "../../_namespaces/ts";
+import * as evaluator from "../../_namespaces/evaluator.js";
+import * as ts from "../../_namespaces/ts.js";
function FakeSuppressedError(error: any, suppressed: any) {
return { error, suppressed };
@@ -351,8 +351,8 @@ describe("unittests:: evaluation:: usingDeclarations", () => {
]);
assert.instanceOf(output[4], Error);
assert.strictEqual(output[4].name, "SuppressedError");
- assert.strictEqual(output[4].error, "dispose error");
- assert.strictEqual(output[4].suppressed, "body error");
+ assert.strictEqual((output[4] as any).error, "dispose error");
+ assert.strictEqual((output[4] as any).suppressed, "body error");
assert.deepEqual(output.slice(5), [
"after try",
]);
diff --git a/src/testRunner/unittests/factory.ts b/src/testRunner/unittests/factory.ts
index 903388588aa69..c5e897e4d2066 100644
--- a/src/testRunner/unittests/factory.ts
+++ b/src/testRunner/unittests/factory.ts
@@ -1,4 +1,4 @@
-import * as ts from "../_namespaces/ts";
+import * as ts from "../_namespaces/ts.js";
describe("unittests:: FactoryAPI", () => {
function assertSyntaxKind(node: ts.Node, expected: ts.SyntaxKind) {
diff --git a/src/testRunner/unittests/helpers.ts b/src/testRunner/unittests/helpers.ts
index fb5b95a24802f..9ec9b57e6618e 100644
--- a/src/testRunner/unittests/helpers.ts
+++ b/src/testRunner/unittests/helpers.ts
@@ -1,4 +1,4 @@
-import * as ts from "../_namespaces/ts";
+import * as ts from "../_namespaces/ts.js";
const enum ChangedPart {
none = 0,
@@ -21,6 +21,7 @@ export interface NamedSourceText {
export interface ProgramWithSourceTexts extends ts.Program {
sourceTexts?: readonly NamedSourceText[];
host: TestCompilerHost;
+ version: number;
}
export interface TestCompilerHost extends ts.CompilerHost {
@@ -102,7 +103,7 @@ function createSourceFileWithText(fileName: string, sourceText: SourceText, targ
return file;
}
-export function createTestCompilerHost(texts: readonly NamedSourceText[], target: ts.ScriptTarget, oldProgram?: ProgramWithSourceTexts, useGetSourceFileByPath?: boolean) {
+export function createTestCompilerHost(texts: readonly NamedSourceText[], target: ts.ScriptTarget, oldProgram?: ProgramWithSourceTexts, useGetSourceFileByPath?: boolean, useCaseSensitiveFileNames?: boolean) {
const files = ts.arrayToMap(texts, t => t.name, t => {
if (oldProgram) {
let oldFile = oldProgram.getSourceFile(t.name) as SourceFileWithText;
@@ -115,14 +116,15 @@ export function createTestCompilerHost(texts: readonly NamedSourceText[], target
}
return createSourceFileWithText(t.name, t.text, target);
});
- const useCaseSensitiveFileNames = ts.sys && ts.sys.useCaseSensitiveFileNames;
+ if (useCaseSensitiveFileNames === undefined) useCaseSensitiveFileNames = ts.sys && ts.sys.useCaseSensitiveFileNames;
const getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitiveFileNames);
+ const filesByPath = ts.mapEntries(files, (fileName, file) => [ts.toPath(fileName, "", getCanonicalFileName), file]);
const trace: string[] = [];
const result: TestCompilerHost = {
trace: s => trace.push(s),
getTrace: () => trace,
clearTrace: () => trace.length = 0,
- getSourceFile: fileName => files.get(fileName),
+ getSourceFile: fileName => filesByPath.get(ts.toPath(fileName, "", getCanonicalFileName)),
getDefaultLibFileName: () => "lib.d.ts",
writeFile: ts.notImplemented,
getCurrentDirectory: () => "",
@@ -130,37 +132,48 @@ export function createTestCompilerHost(texts: readonly NamedSourceText[], target
getCanonicalFileName,
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
getNewLine: () => ts.sys ? ts.sys.newLine : newLine,
- fileExists: fileName => files.has(fileName),
+ fileExists: fileName => filesByPath.has(ts.toPath(fileName, "", getCanonicalFileName)),
readFile: fileName => {
- const file = files.get(fileName);
+ const file = filesByPath.get(ts.toPath(fileName, "", getCanonicalFileName));
return file && file.text;
},
};
if (useGetSourceFileByPath) {
- const filesByPath = ts.mapEntries(files, (fileName, file) => [ts.toPath(fileName, "", getCanonicalFileName), file]);
result.getSourceFileByPath = (_fileName, path) => filesByPath.get(path);
}
return result;
}
-export function newProgram(texts: NamedSourceText[], rootNames: string[], options: ts.CompilerOptions, useGetSourceFileByPath?: boolean): ProgramWithSourceTexts {
- const host = createTestCompilerHost(texts, options.target!, /*oldProgram*/ undefined, useGetSourceFileByPath);
- const program = ts.createProgram(rootNames, options, host) as ProgramWithSourceTexts;
- program.sourceTexts = texts;
- program.host = host;
- return program;
+export function newProgram(texts: NamedSourceText[], rootNames: string[], options: ts.CompilerOptions, useGetSourceFileByPath?: boolean, useCaseSensitiveFileNames?: boolean): ProgramWithSourceTexts {
+ const host = createTestCompilerHost(texts, options.target!, /*oldProgram*/ undefined, useGetSourceFileByPath, useCaseSensitiveFileNames);
+ return programToProgramWithSourceTexts(
+ ts.createProgram(rootNames, options, host),
+ texts,
+ host,
+ 1,
+ );
}
-export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: readonly string[], options: ts.CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[], useGetSourceFileByPath?: boolean) {
+function programToProgramWithSourceTexts(program: ts.Program, texts: NamedSourceText[], host: TestCompilerHost, version: number): ProgramWithSourceTexts {
+ const result = program as ProgramWithSourceTexts;
+ result.sourceTexts = texts;
+ result.host = host;
+ result.version = version;
+ return result;
+}
+
+export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: readonly string[], options: ts.CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[], useGetSourceFileByPath?: boolean, useCaseSensitiveFileNames?: boolean) {
if (!newTexts) {
newTexts = oldProgram.sourceTexts!.slice(0);
}
updater(newTexts);
- const host = createTestCompilerHost(newTexts, options.target!, oldProgram, useGetSourceFileByPath);
- const program = ts.createProgram(rootNames, options, host, oldProgram) as ProgramWithSourceTexts;
- program.sourceTexts = newTexts;
- program.host = host;
- return program;
+ const host = createTestCompilerHost(newTexts, options.target!, oldProgram, useGetSourceFileByPath, useCaseSensitiveFileNames);
+ return programToProgramWithSourceTexts(
+ ts.createProgram(rootNames, options, host, oldProgram),
+ newTexts,
+ host,
+ oldProgram.version + 1,
+ );
}
export function updateProgramText(files: readonly NamedSourceText[], fileName: string, newProgramText: string) {
diff --git a/src/testRunner/unittests/helpers/alternateResult.ts b/src/testRunner/unittests/helpers/alternateResult.ts
index d43e1eb8d68c9..265f9c0c0f767 100644
--- a/src/testRunner/unittests/helpers/alternateResult.ts
+++ b/src/testRunner/unittests/helpers/alternateResult.ts
@@ -1,7 +1,7 @@
-import { dedent } from "../../_namespaces/Utils";
-import { jsonToReadableText } from "../helpers";
-import { FsContents } from "./contents";
-import { libFile } from "./virtualFileSystemWithWatch";
+import { dedent } from "../../_namespaces/Utils.js";
+import { jsonToReadableText } from "../helpers.js";
+import { FsContents } from "./contents.js";
+import { libFile } from "./virtualFileSystemWithWatch.js";
export function getFsConentsForAlternateResultAtTypesPackageJson(packageName: string, addTypesCondition: boolean) {
return jsonToReadableText({
diff --git a/src/testRunner/unittests/helpers/baseline.ts b/src/testRunner/unittests/helpers/baseline.ts
index 21cf49ad95b90..11454d75d9f78 100644
--- a/src/testRunner/unittests/helpers/baseline.ts
+++ b/src/testRunner/unittests/helpers/baseline.ts
@@ -1,9 +1,15 @@
-import * as fakes from "../../_namespaces/fakes";
-import * as Harness from "../../_namespaces/Harness";
-import * as ts from "../../_namespaces/ts";
-import { jsonToReadableText } from "../helpers";
-import { TscCompileSystem } from "./tsc";
-import { TestServerHost } from "./virtualFileSystemWithWatch";
+import * as fakes from "../../_namespaces/fakes.js";
+import * as Harness from "../../_namespaces/Harness.js";
+import * as ts from "../../_namespaces/ts.js";
+import { jsonToReadableText } from "../helpers.js";
+import { TscCompileSystem } from "./tsc.js";
+import { TestServerHost } from "./virtualFileSystemWithWatch.js";
+
+export function sanitizeSysOutput(output: string) {
+ return output
+ .replace(/Elapsed::\s[0-9]+(?:\.\d+)?ms/g, "Elapsed:: *ms")
+ .replace(/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\s(A|P)M/g, "HH:MM:SS AM");
+}
export type CommandLineProgram = [ts.Program, ts.BuilderProgram?];
export interface CommandLineCallbacks {
@@ -130,10 +136,12 @@ export function generateSourceMapBaselineFiles(sys: ts.System & { writtenFiles:
}
}
-export type ReadableProgramBuildInfoDiagnostic = string | [string, readonly ts.ReusableDiagnostic[]];
+export type ReadableProgramBuildInfoDiagnosticOfFile = [file: string, diagnostics: readonly ts.ReusableDiagnostic[]];
+export type ReadableProgramBuildInfoDiagnostic = [file: string, "not cached or not changed"] | ReadableProgramBuildInfoDiagnosticOfFile;
+export type ReadableProgramBuildInfoEmitDiagnostic = ReadableProgramBuildInfoDiagnosticOfFile;
export type ReadableBuilderFileEmit = string & { __readableBuilderFileEmit: any; };
export type ReadableProgramBuilderInfoFilePendingEmit = [original: string | [string], emitKind: ReadableBuilderFileEmit];
-export type ReadableProgramBuildInfoEmitSignature = string | [string, ts.EmitSignature | []];
+export type ReadableProgramBuildInfoEmitSignature = string | [file: string, signature: ts.EmitSignature | []];
export type ReadableProgramBuildInfoFileInfo = Omit & {
impliedFormat: string | undefined;
original: T | undefined;
@@ -141,21 +149,28 @@ export type ReadableProgramBuildInfoFileInfo = Omit & {
+
+export type ReadableProgramBuildInfoResolvedRoot = [
+ original: ts.ProgramBuildInfoResolvedRoot,
+ readable: [resolved: string, root: string],
+];
+export type ReadableProgramMultiFileEmitBuildInfo = Omit & {
fileNamesList: readonly (readonly string[])[] | undefined;
fileInfos: ts.MapLike>;
root: readonly ReadableProgramBuildInfoRoot[];
+ resolvedRoot: readonly ReadableProgramBuildInfoResolvedRoot[] | undefined;
referencedMap: ts.MapLike | undefined;
semanticDiagnosticsPerFile: readonly ReadableProgramBuildInfoDiagnostic[] | undefined;
- emitDiagnosticsPerFile: readonly ReadableProgramBuildInfoDiagnostic[] | undefined;
+ emitDiagnosticsPerFile: readonly ReadableProgramBuildInfoEmitDiagnostic[] | undefined;
affectedFilesPendingEmit: readonly ReadableProgramBuilderInfoFilePendingEmit[] | undefined;
changeFileSet: readonly string[] | undefined;
emitSignatures: readonly ReadableProgramBuildInfoEmitSignature[] | undefined;
};
export type ReadableProgramBuildInfoBundlePendingEmit = [emitKind: ReadableBuilderFileEmit, original: ts.ProgramBuildInfoBundlePendingEmit];
-export type ReadableProgramBundleEmitBuildInfo = Omit & {
+export type ReadableProgramBundleEmitBuildInfo = Omit & {
fileInfos: ts.MapLike>;
root: readonly ReadableProgramBuildInfoRoot[];
+ resolvedRoot: readonly ReadableProgramBuildInfoResolvedRoot[] | undefined;
pendingEmit: ReadableProgramBuildInfoBundlePendingEmit | undefined;
};
@@ -180,6 +195,7 @@ function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string,
...buildInfo.program,
fileInfos,
root: buildInfo.program.root.map(toReadableProgramBuildInfoRoot),
+ resolvedRoot: buildInfo.program.resolvedRoot?.map(toReadableProgramBuildInfoResolvedRoot),
pendingEmit: pendingEmit === undefined ?
undefined :
[
@@ -198,10 +214,11 @@ function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string,
fileNamesList,
fileInfos: buildInfo.program.fileInfos ? fileInfos : undefined!,
root: buildInfo.program.root.map(toReadableProgramBuildInfoRoot),
+ resolvedRoot: buildInfo.program.resolvedRoot?.map(toReadableProgramBuildInfoResolvedRoot),
options: buildInfo.program.options,
referencedMap: toMapOfReferencedSet(buildInfo.program.referencedMap),
semanticDiagnosticsPerFile: toReadableProgramBuildInfoDiagnosticsPerFile(buildInfo.program.semanticDiagnosticsPerFile),
- emitDiagnosticsPerFile: toReadableProgramBuildInfoDiagnosticsPerFile(buildInfo.program.emitDiagnosticsPerFile),
+ emitDiagnosticsPerFile: toReadableProgramBuildInfoEmitDiagnosticsPerFile(buildInfo.program.emitDiagnosticsPerFile),
affectedFilesPendingEmit: buildInfo.program.affectedFilesPendingEmit?.map(value => toReadableProgramBuilderInfoFilePendingEmit(value, fullEmitForOptions!)),
changeFileSet: buildInfo.program.changeFileSet?.map(toFileName),
emitSignatures: buildInfo.program.emitSignatures?.map(s =>
@@ -245,6 +262,10 @@ function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string,
return [original, readable];
}
+ function toReadableProgramBuildInfoResolvedRoot(original: ts.ProgramBuildInfoResolvedRoot): ReadableProgramBuildInfoResolvedRoot {
+ return [original, [toFileName(original[0]), toFileName(original[1])]];
+ }
+
function toMapOfReferencedSet(referenceMap: ts.ProgramBuildInfoReferencedMap | undefined): ts.MapLike | undefined {
if (!referenceMap) return undefined;
const result: ts.MapLike = {};
@@ -279,10 +300,14 @@ function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string,
function toReadableProgramBuildInfoDiagnosticsPerFile(diagnostics: ts.ProgramBuildInfoDiagnostic[] | undefined): readonly ReadableProgramBuildInfoDiagnostic[] | undefined {
return diagnostics?.map(d =>
ts.isNumber(d) ?
- toFileName(d) :
+ [toFileName(d), "not cached or not changed"] :
[toFileName(d[0]), d[1]]
);
}
+
+ function toReadableProgramBuildInfoEmitDiagnosticsPerFile(diagnostics: ts.ProgramBuildInfoEmitDiagnostic[] | undefined): readonly ReadableProgramBuildInfoEmitDiagnostic[] | undefined {
+ return diagnostics?.map(d => [toFileName(d[0]), d[1]]);
+ }
}
export function toPathWithSystem(sys: ts.System, fileName: string): ts.Path {
diff --git a/src/testRunner/unittests/helpers/contents.ts b/src/testRunner/unittests/helpers/contents.ts
index c01f55d7d35f3..943093d2704af 100644
--- a/src/testRunner/unittests/helpers/contents.ts
+++ b/src/testRunner/unittests/helpers/contents.ts
@@ -1,5 +1,5 @@
-import * as ts from "../../_namespaces/ts";
-import { libFile } from "./virtualFileSystemWithWatch";
+import * as ts from "../../_namespaces/ts.js";
+import { libFile } from "./virtualFileSystemWithWatch.js";
export function compilerOptionsToConfigJson(options: ts.CompilerOptions) {
return ts.optionMapToObject(ts.serializeCompilerOptions(options));
diff --git a/src/testRunner/unittests/helpers/declarationEmit.ts b/src/testRunner/unittests/helpers/declarationEmit.ts
new file mode 100644
index 0000000000000..2b811b7cfd632
--- /dev/null
+++ b/src/testRunner/unittests/helpers/declarationEmit.ts
@@ -0,0 +1,93 @@
+import { CompilerOptions } from "../../_namespaces/ts.js";
+import { dedent } from "../../_namespaces/Utils.js";
+import { FileSystem } from "../../_namespaces/vfs.js";
+import { jsonToReadableText } from "../helpers.js";
+import { libContent } from "./contents.js";
+import { loadProjectFromFiles } from "./vfs.js";
+
+export function getFsForDeclarationEmitWithErrors(options: CompilerOptions, incremental: true | undefined) {
+ return loadProjectFromFiles({
+ "/src/project/tsconfig.json": jsonToReadableText({
+ compilerOptions: {
+ module: "NodeNext",
+ moduleResolution: "NodeNext",
+ ...options,
+ incremental,
+ skipLibCheck: true,
+ skipDefaultLibCheck: true,
+ },
+ }),
+ "/src/project/index.ts": dedent`
+ import ky from 'ky';
+ export const api = ky.extend({});
+ `,
+ "/src/project/package.json": jsonToReadableText({
+ type: "module",
+ }),
+ "/src/project/node_modules/ky/distribution/index.d.ts": dedent`
+ type KyInstance = {
+ extend(options: Record): KyInstance;
+ }
+ declare const ky: KyInstance;
+ export default ky;
+ `,
+ "/src/project/node_modules/ky/package.json": jsonToReadableText({
+ name: "ky",
+ type: "module",
+ main: "./distribution/index.js",
+ }),
+ "/lib/lib.esnext.full.d.ts": libContent,
+ });
+}
+
+export function getFsForDeclarationEmitWithErrorsWithOutFile(options: CompilerOptions, incremental: true | undefined) {
+ return loadProjectFromFiles({
+ "/src/project/tsconfig.json": jsonToReadableText({
+ compilerOptions: {
+ module: "amd",
+ ...options,
+ incremental,
+ skipLibCheck: true,
+ skipDefaultLibCheck: true,
+ outFile: "./outFile.js",
+ },
+ include: ["src"],
+ }),
+ "/src/project/src/index.ts": dedent`
+ import ky from 'ky';
+ export const api = ky.extend({});
+ `,
+ "/src/project/ky.d.ts": dedent`
+ type KyInstance = {
+ extend(options: Record