Merge branch 'main' into enforceReadonly

# Conflicts:
#	tests/baselines/reference/api/typescript.d.ts
#	tests/baselines/reference/es2018IntlAPIs.types
#	tests/baselines/reference/es2020IntlAPIs.types
#	tests/baselines/reference/inferenceOptionalPropertiesToIndexSignatures.types
#	tests/baselines/reference/instantiationExpressions.types
#	tests/baselines/reference/localesObjectArgument.types
#	tests/baselines/reference/mappedTypeConstraints2.types
#	tests/baselines/reference/mappedTypeRecursiveInference.errors.txt
#	tests/baselines/reference/unionTypeInference.types
#	tests/baselines/reference/useObjectValuesAndEntries1.types
#	tests/baselines/reference/useObjectValuesAndEntries4.types
This commit is contained in:
Anders Hejlsberg
2024-07-15 15:10:11 -07:00
7883 changed files with 592697 additions and 260781 deletions
+5 -3
View File
@@ -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.1.wasm",
"https://plugins.dprint.dev/json-0.19.3.wasm",
"https://plugins.dprint.dev/prettier-0.40.0.json@68c668863ec834d4be0f6f5ccaab415df75336a992aceb7eeeb14fdf096a9e9c"
]
}
-12
View File
@@ -1,12 +0,0 @@
const fs = require("fs");
const path = require("path");
const rulesDir = path.join(__dirname, "scripts", "eslint", "rules");
const ext = ".cjs";
const ruleFiles = fs.readdirSync(rulesDir).filter(p => p.endsWith(ext));
module.exports = {
rules: Object.fromEntries(ruleFiles.map(p => {
return [p.slice(0, -ext.length), require(path.join(rulesDir, p))];
})),
};
-175
View File
@@ -1,175 +0,0 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"warnOnUnsupportedTypeScriptVersion": false,
"sourceType": "module"
},
"env": {
"browser": false,
"node": true,
"es6": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/stylistic"
],
"plugins": [
"@typescript-eslint",
"eslint-plugin-local"
],
"ignorePatterns": [
"**/node_modules/**",
"/built/**",
"/tests/**",
"/lib/**",
"/src/lib/*.generated.d.ts",
"/scripts/**/*.js",
"/scripts/**/*.d.*",
"/internal/**",
"/coverage/**"
],
"rules": {
// eslint
"dot-notation": "error",
"eqeqeq": "error",
"no-caller": "error",
"no-constant-condition": ["error", { "checkLoops": false }],
"no-eval": "error",
"no-extra-bind": "error",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-return-await": "error",
"no-restricted-globals": [
"error",
{ "name": "setTimeout" },
{ "name": "clearTimeout" },
{ "name": "setInterval" },
{ "name": "clearInterval" },
{ "name": "setImmediate" },
{ "name": "clearImmediate" }
],
"no-template-curly-in-string": "error",
"no-throw-literal": "error",
"no-undef-init": "error",
"no-var": "error",
"object-shorthand": "error",
"prefer-const": "error",
"prefer-object-spread": "error",
"unicode-bom": ["error", "never"],
"no-restricted-syntax": [
"error",
{
"selector": "Literal[raw=null]",
"message": "Avoid using null; use undefined instead."
},
{
"selector": "TSNullKeyword",
"message": "Avoid using null; use undefined instead."
}
],
// Enabled in eslint:recommended, but not applicable here
"no-extra-boolean-cast": "off",
"no-case-declarations": "off",
"no-cond-assign": "off",
"no-control-regex": "off",
"no-inner-declarations": "off",
// @typescript-eslint/eslint-plugin
"@typescript-eslint/naming-convention": [
"error",
{ "selector": "typeLike", "format": ["PascalCase"], "filter": { "regex": "^(__String|[A-Za-z]+_[A-Za-z]+)$", "match": false } },
{ "selector": "interface", "format": ["PascalCase"], "custom": { "regex": "^I[A-Z]", "match": false }, "filter": { "regex": "^I(Arguments|TextWriter|O([A-Z][a-z]+[A-Za-z]*)?)$", "match": false } },
{ "selector": "variable", "format": ["camelCase", "PascalCase", "UPPER_CASE"], "leadingUnderscore": "allow", "filter": { "regex": "^(_{1,2}filename|_{1,2}dirname|_+|[A-Za-z]+_[A-Za-z]+)$", "match": false } },
{ "selector": "function", "format": ["camelCase", "PascalCase"], "leadingUnderscore": "allow", "filter": { "regex": "^[A-Za-z]+_[A-Za-z]+$", "match": false } },
{ "selector": "parameter", "format": ["camelCase"], "leadingUnderscore": "allow", "filter": { "regex": "^(_+|[A-Za-z]+_[A-Z][a-z]+)$", "match": false } },
{ "selector": "method", "format": ["camelCase", "PascalCase"], "leadingUnderscore": "allow", "filter": { "regex": "^([0-9]+|[A-Za-z]+_[A-Za-z]+)$", "match": false } },
{ "selector": "memberLike", "format": ["camelCase"], "leadingUnderscore": "allow", "filter": { "regex": "^([0-9]+|[A-Za-z]+_[A-Za-z]+)$", "match": false } },
{ "selector": "enumMember", "format": ["camelCase", "PascalCase"], "leadingUnderscore": "allow", "filter": { "regex": "^[A-Za-z]+_[A-Za-z]+$", "match": false } },
{ "selector": "property", "format": null }
],
"@typescript-eslint/unified-signatures": "error",
"no-unused-expressions": "off",
"@typescript-eslint/no-unused-expressions": ["error", { "allowTernary": true }],
// Rules enabled in typescript-eslint configs that are not applicable here
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/class-literal-property-style": "off",
"@typescript-eslint/consistent-indexed-object-style": "off",
"@typescript-eslint/no-duplicate-enum-values": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/no-non-null-asserted-optional-chain": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-types": [
"error",
{
"extendDefaults": true,
"types": {
// This is theoretically good, but ts-eslint appears to mistake our declaration of Symbol for the global Symbol type.
// See: https://github.com/typescript-eslint/typescript-eslint/issues/7306
"Symbol": false,
"{}": false // {} is a totally useful and valid type.
}
}
],
"@typescript-eslint/no-unused-vars": [
"warn",
{
// Ignore: (solely underscores | starting with exactly one underscore)
"argsIgnorePattern": "^(_+$|_[^_])",
"varsIgnorePattern": "^(_+$|_[^_])"
}
],
// Pending https://github.com/typescript-eslint/typescript-eslint/issues/4820
"@typescript-eslint/prefer-optional-chain": "off",
// scripts/eslint/rules
"local/only-arrow-functions": [
"error",
{
"allowNamedFunctions": true,
"allowDeclarations": true
}
],
"local/argument-trivia": "error",
"local/no-in-operator": "error",
"local/debug-assert": "error",
"local/no-keywords": "error",
"local/jsdoc-format": "error"
},
"overrides": [
// By default, the ESLint CLI only looks at .js files. But, it will also look at
// any files which are referenced in an override config. Most users of typescript-eslint
// get this behavior by default by extending a recommended typescript-eslint config, which
// just so happens to override some core ESLint rules. We don't extend from any config, so
// explicitly reference TS files here so the CLI picks them up.
//
// ESLint in VS Code will lint any opened file (so long as it's not eslintignore'd), so
// that will work regardless of the below.
//
// The same applies to mjs files; ESLint appears to not scan those either.
{ "files": ["*.ts", "*.mts", "*.cts", "*.mjs", "*.cjs"] },
{
"files": ["*.mjs", "*.mts"],
"rules": {
// These globals don't exist outside of CJS files.
"no-restricted-globals": [
"error",
{ "name": "__filename" },
{ "name": "__dirname" },
{ "name": "require" },
{ "name": "module" },
{ "name": "exports" }
]
}
}
]
}
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
+27 -12
View File
@@ -29,6 +29,7 @@ jobs:
- windows-latest
- macos-14
node-version:
- '22'
- '20'
- '18'
- '16'
@@ -48,7 +49,7 @@ jobs:
name: Test Node ${{ matrix.node-version }} on ${{ matrix.os }}${{ (!matrix.bundle && ' with --no-bundle') || '' }}
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Use node version ${{ matrix.node-version }}
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
@@ -72,7 +73,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -82,11 +83,25 @@ jobs:
- name: Linter
run: npm run lint
knip:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
check-latest: true
- run: npm ci
- name: Unused exports
run: npm run knip
format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -107,7 +122,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -124,7 +139,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -138,7 +153,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
@@ -180,11 +195,11 @@ jobs:
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
path: pr
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
path: base
ref: ${{ github.base_ref }}
@@ -222,7 +237,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -239,7 +254,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -259,7 +274,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: '*'
@@ -297,7 +312,7 @@ jobs:
- name: Upload baseline diff artifact
if: ${{ failure() && steps.check-baselines.conclusion == 'failure' }}
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
with:
name: fix_baselines.patch
path: fix_baselines.patch
+4 -4
View File
@@ -42,11 +42,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
uses: github/codeql-action/init@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11
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@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
uses: github/codeql-action/autobuild@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11
# ℹ️ 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@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
uses: github/codeql-action/analyze@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11
+1 -1
View File
@@ -47,7 +47,7 @@ jobs:
if: github.repository == 'microsoft/TypeScript'
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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.
+2 -2
View File
@@ -20,7 +20,7 @@ jobs:
if: github.repository == 'microsoft/TypeScript'
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
exit 1
fi
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
ref: ${{ inputs.branch_name }}
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
+1 -1
View File
@@ -50,7 +50,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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.
+2 -2
View File
@@ -21,7 +21,7 @@ jobs:
if: github.repository == 'microsoft/TypeScript'
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- 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@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
@@ -44,7 +44,7 @@ jobs:
npm pack ./
mv typescript-*.tgz typescript.tgz
- name: Upload built tarfile
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
with:
name: tgz
path: typescript.tgz
+4 -4
View File
@@ -29,12 +29,12 @@ jobs:
steps:
- name: 'Checkout code'
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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
@@ -47,7 +47,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: 'Upload artifact'
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
with:
name: SARIF file
path: results.sarif
@@ -55,6 +55,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: 'Upload to code-scanning'
uses: github/codeql-action/upload-sarif@4355270be187e1b672a7a1c7c7bae5afdc1ab94a # v3.24.10
uses: github/codeql-action/upload-sarif@b611370bb5703a7efb587f9d136a52ea24c5c38c # v3.25.11
with:
sarif_file: results.sarif
+1 -1
View File
@@ -49,7 +49,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
ref: ${{ inputs.branch_name }}
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
+1 -1
View File
@@ -45,7 +45,7 @@ jobs:
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
ref: ${{ inputs.branch_name }}
filter: blob:none # https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/
+1 -1
View File
@@ -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@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
repository: '${{ GITHUB.repository_owner }}/${{ env.BASENAME }}-wiki'
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
+2 -2
View File
@@ -49,12 +49,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- if: ${{ github.event.inputs.bisect }}
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
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@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
with:
node-version: 'lts/*'
+1 -1
View File
@@ -22,7 +22,7 @@ jobs:
if: github.repository == 'microsoft/TypeScript'
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
token: ${{ secrets.TS_BOT_GITHUB_TOKEN }}
- uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
+3
View File
@@ -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",
+8 -1
View File
@@ -216,7 +216,7 @@ function createBundler(entrypoint, outfile, taskOptions = {}) {
// Monaco bundles us as ESM by wrapping our code with something that defines module.exports
// but then does not use it, instead using the `ts` variable. Ensure that if we think we're CJS
// that we still set `ts` to the module.exports object.
options.footer = { js: `})(typeof module !== "undefined" && module.exports ? module : { exports: ts });\nif (typeof module !== "undefined" && module.exports) { ts = module.exports; }` };
options.footer = { js: `})({ get exports() { return ts; }, set exports(v) { ts = v; if (typeof module !== "undefined" && module.exports) { module.exports = v; } } })` };
// esbuild converts calls to "require" to "__require"; this function
// calls the real require if it exists, or throws if it does not (rather than
@@ -565,6 +565,13 @@ export const checkFormat = task({
run: () => exec(process.execPath, ["node_modules/dprint/bin.js", "check"], { ignoreStdout: true }),
});
export const knip = task({
name: "knip",
description: "Runs knip.",
dependencies: [generateDiagnostics],
run: () => exec(process.execPath, ["node_modules/knip/bin/knip.js", "--tags=+internal,-knipignore", "--exclude=duplicates,enumMembers", ...(cmdLineOptions.fix ? ["--fix"] : [])]),
});
const { main: cancellationToken, watch: watchCancellationToken } = entrypointBuildTask({
name: "cancellation-token",
project: "src/cancellationToken",
+253
View File
@@ -0,0 +1,253 @@
// @ts-check
import eslint from "@eslint/js";
import fs from "fs";
import globals from "globals";
import { createRequire } from "module";
import path from "path";
import tseslint from "typescript-eslint";
import url from "url";
const __filename = url.fileURLToPath(new URL(import.meta.url));
const __dirname = path.dirname(__filename);
const require = createRequire(import.meta.url);
const rulesDir = path.join(__dirname, "scripts", "eslint", "rules");
const ext = ".cjs";
const ruleFiles = fs.readdirSync(rulesDir).filter(p => p.endsWith(ext));
export default tseslint.config(
{
files: ["**/*.{ts,tsx,cts,mts,js,cjs,mjs}"],
},
{
ignores: [
"**/node_modules/**",
"built/**",
"tests/**",
"lib/**",
"src/lib/*.generated.d.ts",
"scripts/**/*.js",
"scripts/**/*.d.*",
"internal/**",
"coverage/**",
],
},
eslint.configs.recommended,
...tseslint.configs.recommended,
...tseslint.configs.stylistic,
{
plugins: {
local: {
rules: Object.fromEntries(ruleFiles.map(p => {
return [p.slice(0, -ext.length), require(path.join(rulesDir, p))];
})),
},
},
},
{
languageOptions: {
parserOptions: {
warnOnUnsupportedTypeScriptVersion: false,
},
globals: globals.node,
},
},
{
rules: {
// eslint
"dot-notation": "error",
"eqeqeq": "error",
"no-caller": "error",
"no-constant-condition": ["error", { checkLoops: false }],
"no-eval": "error",
"no-extra-bind": "error",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-return-await": "error",
"no-template-curly-in-string": "error",
"no-throw-literal": "error",
"no-undef-init": "error",
"no-var": "error",
"object-shorthand": "error",
"prefer-const": "error",
"prefer-object-spread": "error",
"unicode-bom": ["error", "never"],
"no-restricted-syntax": [
"error",
{
selector: "Literal[raw=null]",
message: "Avoid using null; use undefined instead.",
},
{
selector: "TSNullKeyword",
message: "Avoid using null; use undefined instead.",
},
],
// Enabled in eslint:recommended, but not applicable here
"no-extra-boolean-cast": "off",
"no-case-declarations": "off",
"no-cond-assign": "off",
"no-control-regex": "off",
"no-inner-declarations": "off",
// @typescript-eslint/eslint-plugin
"@typescript-eslint/naming-convention": [
"error",
{ selector: "typeLike", format: ["PascalCase"], filter: { regex: "^(__String|[A-Za-z]+_[A-Za-z]+)$", match: false } },
{ selector: "interface", format: ["PascalCase"], custom: { regex: "^I[A-Z]", match: false }, filter: { regex: "^I(Arguments|TextWriter|O([A-Z][a-z]+[A-Za-z]*)?)$", match: false } },
{ selector: "variable", format: ["camelCase", "PascalCase", "UPPER_CASE"], leadingUnderscore: "allow", filter: { regex: "^(_{1,2}filename|_{1,2}dirname|_+|[A-Za-z]+_[A-Za-z]+)$", match: false } },
{ selector: "function", format: ["camelCase", "PascalCase"], leadingUnderscore: "allow", filter: { regex: "^[A-Za-z]+_[A-Za-z]+$", match: false } },
{ selector: "parameter", format: ["camelCase"], leadingUnderscore: "allow", filter: { regex: "^(_+|[A-Za-z]+_[A-Z][a-z]+)$", match: false } },
{ selector: "method", format: ["camelCase", "PascalCase"], leadingUnderscore: "allow", filter: { regex: "^([0-9]+|[A-Za-z]+_[A-Za-z]+)$", match: false } },
{ selector: "memberLike", format: ["camelCase"], leadingUnderscore: "allow", filter: { regex: "^([0-9]+|[A-Za-z]+_[A-Za-z]+)$", match: false } },
{ selector: "enumMember", format: ["camelCase", "PascalCase"], leadingUnderscore: "allow", filter: { regex: "^[A-Za-z]+_[A-Za-z]+$", match: false } },
// eslint-disable-next-line no-restricted-syntax
{ selector: "property", format: null },
],
"@typescript-eslint/unified-signatures": "error",
"no-unused-expressions": "off",
"@typescript-eslint/no-unused-expressions": ["error", { allowTernary: true }],
// Rules enabled in typescript-eslint configs that are not applicable here
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/class-literal-property-style": "off",
"@typescript-eslint/consistent-indexed-object-style": "off",
"@typescript-eslint/no-duplicate-enum-values": "off",
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/no-non-null-asserted-optional-chain": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/no-empty-interface": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-types": [
"error",
{
extendDefaults: true,
types: {
// This is theoretically good, but ts-eslint appears to mistake our declaration of Symbol for the global Symbol type.
// See: https://github.com/typescript-eslint/typescript-eslint/issues/7306
"Symbol": false,
"{}": false, // {} is a totally useful and valid type.
},
},
],
"@typescript-eslint/no-unused-vars": [
"warn",
{
// Ignore: (solely underscores | starting with exactly one underscore)
argsIgnorePattern: "^(_+$|_[^_])",
varsIgnorePattern: "^(_+$|_[^_])",
},
],
"@typescript-eslint/no-inferrable-types": "off",
// Pending https://github.com/typescript-eslint/typescript-eslint/issues/4820
"@typescript-eslint/prefer-optional-chain": "off",
// scripts/eslint/rules
"local/only-arrow-functions": [
"error",
{
allowNamedFunctions: true,
allowDeclarations: true,
},
],
"local/argument-trivia": "error",
"local/no-in-operator": "error",
"local/debug-assert": "error",
"local/no-keywords": "error",
"local/jsdoc-format": "error",
"local/js-extensions": "error",
},
},
{
files: ["**/*.mjs", "**/*.mts"],
rules: {
// These globals don't exist outside of CJS files.
"no-restricted-globals": [
"error",
{ name: "__filename" },
{ name: "__dirname" },
{ name: "require" },
{ name: "module" },
{ name: "exports" },
],
},
},
{
files: ["src/**"],
languageOptions: {
parserOptions: {
tsconfigRootDir: __dirname,
project: "./src/tsconfig-eslint.json",
},
},
},
{
files: ["scripts/**"],
languageOptions: {
parserOptions: {
tsconfigRootDir: __dirname,
project: "./scripts/tsconfig.json",
},
},
},
{
files: ["src/**"],
rules: {
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"no-restricted-globals": [
"error",
{ name: "setTimeout" },
{ name: "clearTimeout" },
{ name: "setInterval" },
{ name: "clearInterval" },
{ name: "setImmediate" },
{ name: "clearImmediate" },
{ name: "performance" },
],
},
},
{
files: ["src/harness/**", "src/testRunner/**"],
rules: {
"no-restricted-globals": "off",
},
},
{
files: ["src/lib/*.d.ts"],
...tseslint.configs.disableTypeChecked,
},
{
files: ["src/lib/*.d.ts"],
languageOptions: {
globals: {},
},
rules: {
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/prefer-function-type": "off",
"@typescript-eslint/unified-signatures": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-unused-vars": "off",
// scripts/eslint/rules
"local/no-keywords": "off",
// eslint
"no-var": "off",
"no-restricted-globals": "off",
"no-shadow-restricted-names": "off",
"no-restricted-syntax": "off",
},
},
{
files: ["src/lib/es2019.array.d.ts"],
rules: {
"@typescript-eslint/array-type": "off",
},
},
);
+38
View File
@@ -0,0 +1,38 @@
{
"$schema": "https://unpkg.com/knip@5/schema.json",
"includeEntryExports": true,
"entry": [
"Herebyfile.mjs",
"src/cancellationToken/cancellationToken.ts",
"src/testRunner/_namespaces/Harness.ts",
"src/tsc/tsc.ts",
"src/tsserver/server.ts",
"src/typescript/typescript.ts",
"src/typingsInstaller/nodeTypingsInstaller.ts",
"src/watchGuard/watchGuard.ts",
"src/testRunner/tests.ts",
"src/testRunner/_namespaces/Harness.ts",
// The rest of the entry files, mostly to track used dependencies:
".eslint-plugin-local.cjs",
".gulp.js",
"scripts/eslint/{rules,tests}/*.cjs",
"scripts/*.{cjs,mjs}"
],
"project": [
"src/**",
"scripts/**",
"!src/lib/**/*.d.ts"
],
"ignore": [
"scripts/failed-tests.d.cts"
],
"ignoreDependencies": ["c8", "eslint-formatter-autolinkable-stylish", "mocha-fivemat-progress-reporter"],
"ignoreExportsUsedInFile": {
"enum": true,
"interface": true,
"type": true
},
"mocha": false
}
+1552 -1101
View File
File diff suppressed because it is too large Load Diff
+27 -24
View File
@@ -2,7 +2,7 @@
"name": "typescript",
"author": "Microsoft Corp.",
"homepage": "https://www.typescriptlang.org/",
"version": "5.5.0",
"version": "5.6.0",
"license": "Apache-2.0",
"description": "TypeScript is a language for application scale JavaScript development",
"keywords": [
@@ -13,11 +13,11 @@
"javascript"
],
"bugs": {
"url": "https://github.com/Microsoft/TypeScript/issues"
"url": "https://github.com/microsoft/TypeScript/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/TypeScript.git"
"url": "https://github.com/microsoft/TypeScript.git"
},
"main": "./lib/typescript.js",
"typings": "./lib/typescript.d.ts",
@@ -39,43 +39,46 @@
"!**/.gitattributes"
],
"devDependencies": {
"@dprint/formatter": "^0.3.0",
"@dprint/typescript": "0.91.1",
"@esfx/canceltoken": "^1.0.0",
"@octokit/rest": "^20.0.2",
"@types/chai": "^4.3.14",
"@types/microsoft__typescript-etw": "^0.1.3",
"@eslint/js": "^8.57.0",
"@octokit/rest": "^21.0.0",
"@types/chai": "^4.3.16",
"@types/diff": "^5.2.1",
"@types/minimist": "^1.2.5",
"@types/mocha": "^10.0.6",
"@types/mocha": "^10.0.7",
"@types/ms": "^0.7.34",
"@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",
"c8": "^9.1.0",
"@types/which": "^3.0.4",
"@typescript-eslint/utils": "^7.14.1",
"azure-devops-node-api": "^14.0.1",
"c8": "^10.1.2",
"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.3",
"esbuild": "^0.22.0",
"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",
"fast-xml-parser": "^4.4.0",
"glob": "^10.4.2",
"globals": "^13.24.0",
"hereby": "^1.8.9",
"jsonc-parser": "^3.2.1",
"jsonc-parser": "^3.3.1",
"knip": "^5.25.1",
"minimist": "^1.2.8",
"mocha": "^10.3.0",
"mocha": "^10.5.2",
"mocha-fivemat-progress-reporter": "^0.1.0",
"ms": "^2.1.3",
"node-fetch": "^3.3.2",
"playwright": "^1.42.1",
"playwright": "^1.45.0",
"source-map-support": "^0.5.21",
"tslib": "^2.6.2",
"typescript": "^5.4.3",
"tslib": "^2.6.3",
"typescript": "^5.5.2",
"typescript-eslint": "^7.14.1",
"which": "^3.0.1"
},
"overrides": {
@@ -91,6 +94,7 @@
"clean": "hereby clean",
"gulp": "hereby",
"lint": "hereby lint",
"knip": "hereby knip",
"format": "dprint fmt",
"setup-hooks": "node scripts/link-hooks.mjs"
},
@@ -100,7 +104,6 @@
"path": false,
"crypto": false,
"buffer": false,
"@microsoft/typescript-etw": false,
"source-map-support": false,
"inspector": false,
"perf_hooks": false
+1
View File
@@ -29,6 +29,7 @@ for (const browserType of browsers) {
await page.setContent(`
<html>
<script>${readFileSync(join("built", "local", "typescript.js"), "utf8")}</script>
<script>if (typeof ts.version !== "string") throw new Error("ts.version not set")</script>
</html>
`);
+1
View File
@@ -68,6 +68,7 @@ export default options;
* @property {boolean} fix
* @property {string} browser
* @property {string} tests
* @property {boolean} skipSysTests
* @property {string | boolean} break
* @property {string | boolean} inspect
* @property {string} runners
+10 -4
View File
@@ -15,6 +15,9 @@ import {
rimraf,
} from "./utils.mjs";
/** @import { CancelToken } from "@esfx/canceltoken" */
void 0;
const mochaJs = path.resolve(findUpRoot(), "node_modules", "mocha", "bin", "_mocha");
export const localBaseline = "tests/baselines/local/";
export const refBaseline = "tests/baselines/reference/";
@@ -25,12 +28,13 @@ export const coverageDir = "coverage";
* @param {string} defaultReporter
* @param {boolean} runInParallel
* @param {object} options
* @param {import("@esfx/canceltoken").CancelToken} [options.token]
* @param {CancelToken} [options.token]
* @param {boolean} [options.watching]
*/
export async function runConsoleTests(runJs, defaultReporter, runInParallel, options = {}) {
const testTimeout = cmdLineOptions.timeout;
const tests = cmdLineOptions.tests;
const skipSysTests = cmdLineOptions.skipSysTests;
const inspect = cmdLineOptions.break || cmdLineOptions.inspect;
const runners = cmdLineOptions.runners;
const light = cmdLineOptions.light;
@@ -74,8 +78,8 @@ export async function runConsoleTests(runJs, defaultReporter, runInParallel, opt
console.log(chalk.yellowBright(`[watch] running tests...`));
}
if (tests || runners || light || testTimeout || taskConfigsFolder || keepFailed || shards || shardId) {
writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, testTimeout, keepFailed, shards, shardId);
if (tests || skipSysTests || runners || light || testTimeout || taskConfigsFolder || keepFailed || shards || shardId) {
writeTestConfigFile(tests, skipSysTests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, testTimeout, keepFailed, shards, shardId);
}
const colors = cmdLineOptions.colors;
@@ -180,6 +184,7 @@ export async function cleanTestDirs() {
/**
* used to pass data from command line directly to run.js
* @param {string} tests
* @param {boolean} skipSysTests
* @param {string} runners
* @param {boolean} light
* @param {string} [taskConfigsFolder]
@@ -190,9 +195,10 @@ export async function cleanTestDirs() {
* @param {number | undefined} [shards]
* @param {number | undefined} [shardId]
*/
export function writeTestConfigFile(tests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, timeout, keepFailed, shards, shardId) {
export function writeTestConfigFile(tests, skipSysTests, runners, light, taskConfigsFolder, workerCount, stackTraceLimit, timeout, keepFailed, shards, shardId) {
const testConfigContents = JSON.stringify({
test: tests ? [tests] : undefined,
skipSysTests: skipSysTests ? skipSysTests : undefined,
runners: runners ? runners.split(",") : undefined,
light,
workerCount,
+4 -1
View File
@@ -6,6 +6,9 @@ import fs from "fs";
import JSONC from "jsonc-parser";
import which from "which";
/** @import { CancelToken } from "@esfx/canceltoken" */
void 0;
/**
* Executes the provided command once with the supplied arguments.
* @param {string} cmd
@@ -17,7 +20,7 @@ import which from "which";
* @property {boolean} [hidePrompt]
* @property {boolean} [waitForExit=true]
* @property {boolean} [ignoreStdout]
* @property {import("@esfx/canceltoken").CancelToken} [token]
* @property {CancelToken} [token]
*/
export async function exec(cmd, args, options = {}) {
return /**@type {Promise<{exitCode?: number}>}*/ (new Promise((resolve, reject) => {
+1 -1
View File
@@ -57,7 +57,7 @@ function main() {
// Finally write the changes to disk.
// Modify the package.json structure
packageJsonValue.version = `${majorMinor}.${prereleasePatch}`;
writeFileSync(packageJsonFilePath, JSON.stringify(packageJsonValue, /*replacer:*/ undefined, /*space:*/ 4));
writeFileSync(packageJsonFilePath, JSON.stringify(packageJsonValue, undefined, 4));
writeFileSync(tsFilePath, modifiedTsFileContents);
}
+29 -12
View File
@@ -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";
@@ -38,6 +39,13 @@ console.log(`Bundling ${entrypoint} to ${output} and ${internalOutput}`);
const newLineKind = ts.NewLineKind.LineFeed;
const newLine = newLineKind === ts.NewLineKind.LineFeed ? "\n" : "\r\n";
/**
* @param {ts.Node} node
*/
function removeAllComments(node) {
/** @type {any} */ (ts).removeAllComments(node);
}
/**
* @param {ts.VariableDeclaration} node
* @returns {ts.VariableStatement}
@@ -421,6 +429,15 @@ function emitAsNamespace(name, parent, moduleSymbol, needExportModifier) {
if (ts.isInternalDeclaration(node)) {
return undefined;
}
// TODO: remove after https://github.com/microsoft/TypeScript/pull/58187 is released
if (ts.canHaveModifiers(node)) {
for (const modifier of ts.getModifiers(node) ?? []) {
if (modifier.kind === ts.SyntaxKind.PrivateKeyword) {
removeAllComments(node);
break;
}
}
}
return node;
}, /*context*/ undefined);
@@ -475,23 +492,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");
}
+6 -4
View File
@@ -3,8 +3,10 @@ const { createRule } = require("./utils.cjs");
const ts = require("typescript");
/**
* @typedef {import("@typescript-eslint/utils").TSESTree.CallExpression | import("@typescript-eslint/utils").TSESTree.NewExpression} CallOrNewExpression
* @import { TSESTree } from "@typescript-eslint/utils"
* @typedef {TSESTree.CallExpression | TSESTree.NewExpression} CallOrNewExpression
*/
void 0;
const unset = Symbol();
/**
@@ -46,7 +48,7 @@ module.exports = createRule({
/** @type {(name: string) => boolean} */
const isSetOrAssert = name => name.startsWith("set") || name.startsWith("assert");
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */
/** @type {(node: TSESTree.Node) => boolean} */
const isTrivia = node => {
if (node.type === AST_NODE_TYPES.Identifier) {
return node.name === "undefined";
@@ -101,7 +103,7 @@ module.exports = createRule({
return false;
};
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node, i: number, getSignature: () => ts.Signature | undefined) => void} */
/** @type {(node: TSESTree.Node, i: number, getSignature: () => ts.Signature | undefined) => void} */
const checkArg = (node, i, getSignature) => {
if (!isTrivia(node)) {
return;
@@ -123,7 +125,7 @@ module.exports = createRule({
});
const comments = sourceCode.getCommentsBefore(node);
/** @type {import("@typescript-eslint/utils").TSESTree.Comment | undefined} */
/** @type {TSESTree.Comment | undefined} */
const comment = comments[comments.length - 1];
if (!comment || comment.type !== "Block") {
+7 -4
View File
@@ -1,6 +1,9 @@
const { AST_NODE_TYPES } = require("@typescript-eslint/utils");
const { createRule } = require("./utils.cjs");
/** @import { TSESTree } from "@typescript-eslint/utils" */
void 0;
module.exports = createRule({
name: "debug-assert",
meta: {
@@ -17,14 +20,14 @@ module.exports = createRule({
defaultOptions: [],
create(context) {
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */
/** @type {(node: TSESTree.Node) => boolean} */
const isArrowFunction = node => node.type === AST_NODE_TYPES.ArrowFunctionExpression;
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */
/** @type {(node: TSESTree.Node) => boolean} */
const isStringLiteral = node => (
(node.type === AST_NODE_TYPES.Literal && typeof node.value === "string") || node.type === AST_NODE_TYPES.TemplateLiteral
);
/** @type {(node: import("@typescript-eslint/utils").TSESTree.MemberExpression) => boolean} */
/** @type {(node: TSESTree.MemberExpression) => boolean} */
const isDebugAssert = node => (
node.object.type === AST_NODE_TYPES.Identifier
&& node.object.name === "Debug"
@@ -32,7 +35,7 @@ module.exports = createRule({
&& node.property.name === "assert"
);
/** @type {(node: import("@typescript-eslint/utils").TSESTree.CallExpression) => void} */
/** @type {(node: TSESTree.CallExpression) => void} */
const checkDebugAssert = node => {
const args = node.arguments;
const argsLen = args.length;
+73
View File
@@ -0,0 +1,73 @@
const { createRule } = require("./utils.cjs");
/** @import { TSESTree } from "@typescript-eslint/utils" */
void 0;
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:
* | TSESTree.ImportDeclaration
* | TSESTree.ExportAllDeclaration
* | TSESTree.ExportNamedDeclaration
* | TSESTree.TSImportEqualsDeclaration
* | 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,
};
},
});
+16 -15
View File
@@ -1,5 +1,8 @@
const { createRule } = require("./utils.cjs");
/** @import { TSESTree } from "@typescript-eslint/utils" */
void 0;
module.exports = createRule({
name: "jsdoc-format",
meta: {
@@ -12,6 +15,7 @@ module.exports = createRule({
multipleJSDocError: `Declaration has multiple JSDoc comments.`,
internalCommentOnParameterProperty: `@internal cannot appear on a JSDoc comment; use a declared property and an assignment in the constructor instead.`,
internalCommentOnUnexported: `@internal should not appear on an unexported declaration.`,
internalCommentOnPrivate: `@internal should not appear on a private declaration.`,
},
schema: [],
type: "problem",
@@ -24,17 +28,17 @@ module.exports = createRule({
const atInternal = "@internal";
const jsdocStart = "/**";
/** @type {Map<import("@typescript-eslint/utils").TSESTree.Node, boolean>} */
/** @type {Map<TSESTree.Node, boolean>} */
const isExportedCache = new Map();
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */
/** @type {(node: TSESTree.Node) => boolean} */
function isExported(node) {
const exported = isExportedCache.get(node);
if (exported !== undefined) {
return exported;
}
/** @type {import("@typescript-eslint/utils").TSESTree.Node | undefined} */
/** @type {TSESTree.Node | undefined} */
let current = node;
while (current) {
// https://github.com/typescript-eslint/typescript-eslint/blob/e44a1a280f08f9fd0d29f74e5c3e73b7b64a9606/packages/eslint-plugin/src/util/collectUnusedVariables.ts#L440
@@ -54,22 +58,15 @@ module.exports = createRule({
return text.startsWith(jsdocStart);
}
/** @type {(c: import("@typescript-eslint/utils").TSESTree.Comment, indexInComment: number) => import("@typescript-eslint/utils").TSESTree.SourceLocation} */
/** @type {(c: TSESTree.Comment, indexInComment: number) => TSESTree.SourceLocation} */
const getAtInternalLoc = (c, indexInComment) => {
const line = c.loc.start.line;
return {
start: {
line,
column: c.loc.start.column + indexInComment,
},
end: {
line,
column: c.loc.start.column + indexInComment + atInternal.length,
},
start: context.sourceCode.getLocFromIndex(c.range[0] + indexInComment),
end: context.sourceCode.getLocFromIndex(c.range[0] + indexInComment + atInternal.length),
};
};
/** @type {(c: import("@typescript-eslint/utils").TSESTree.Comment) => import("@typescript-eslint/utils").TSESTree.SourceLocation} */
/** @type {(c: TSESTree.Comment) => TSESTree.SourceLocation} */
const getJSDocStartLoc = c => {
return {
start: c.loc.start,
@@ -80,7 +77,7 @@ module.exports = createRule({
};
};
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => void} */
/** @type {(node: TSESTree.Node) => void} */
const checkDeclaration = node => {
const blockComments = sourceCode.getCommentsBefore(node).filter(c => c.type === "Block");
if (blockComments.length === 0) {
@@ -113,6 +110,10 @@ module.exports = createRule({
else if (!isExported(node)) {
context.report({ messageId: "internalCommentOnUnexported", node: c, loc: getAtInternalLoc(c, indexInComment) });
}
// eslint-disable-next-line local/no-in-operator
else if ("accessibility" in node && node.accessibility === "private") {
context.report({ messageId: "internalCommentOnPrivate", node: c, loc: getAtInternalLoc(c, indexInComment) });
}
else if (i !== last) {
context.report({ messageId: "internalCommentNotLastError", node: c, loc: getAtInternalLoc(c, indexInComment) });
}
+4 -1
View File
@@ -1,5 +1,8 @@
const { createRule } = require("./utils.cjs");
/** @import { TSESTree } from "@typescript-eslint/utils" */
void 0;
module.exports = createRule({
name: "no-in-operator",
meta: {
@@ -16,7 +19,7 @@ module.exports = createRule({
create(context) {
const IN_OPERATOR = "in";
/** @type {(node: import("@typescript-eslint/utils").TSESTree.BinaryExpression) => void} */
/** @type {(node: TSESTree.BinaryExpression) => void} */
const checkInOperator = node => {
if (node.operator === IN_OPERATOR) {
context.report({ messageId: "noInOperatorError", node });
+7 -4
View File
@@ -1,6 +1,9 @@
const { AST_NODE_TYPES } = require("@typescript-eslint/utils");
const { createRule } = require("./utils.cjs");
/** @import { TSESTree } from "@typescript-eslint/utils" */
void 0;
module.exports = createRule({
name: "no-keywords",
meta: {
@@ -37,12 +40,12 @@ module.exports = createRule({
/** @type {(name: string) => boolean} */
const isKeyword = name => keywords.includes(name);
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Identifier) => void} */
/** @type {(node: TSESTree.Identifier) => void} */
const report = node => {
context.report({ messageId: "noKeywordsError", data: { name: node.name }, node });
};
/** @type {(node: import("@typescript-eslint/utils").TSESTree.ObjectPattern) => void} */
/** @type {(node: TSESTree.ObjectPattern) => void} */
const checkProperties = node => {
node.properties.forEach(property => {
if (
@@ -56,7 +59,7 @@ module.exports = createRule({
});
};
/** @type {(node: import("@typescript-eslint/utils").TSESTree.ArrayPattern) => void} */
/** @type {(node: TSESTree.ArrayPattern) => void} */
const checkElements = node => {
node.elements.forEach(element => {
if (
@@ -69,7 +72,7 @@ module.exports = createRule({
});
};
/** @type {(node: import("@typescript-eslint/utils").TSESTree.ArrowFunctionExpression | import("@typescript-eslint/utils").TSESTree.FunctionDeclaration | import("@typescript-eslint/utils").TSESTree.FunctionExpression | import("@typescript-eslint/utils").TSESTree.TSMethodSignature | import("@typescript-eslint/utils").TSESTree.TSFunctionType) => void} */
/** @type {(node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.TSMethodSignature | TSESTree.TSFunctionType) => void} */
const checkParams = node => {
if (!node || !node.params || !node.params.length) {
return;
@@ -1,7 +1,11 @@
const { AST_NODE_TYPES } = require("@typescript-eslint/utils");
const { createRule } = require("./utils.cjs");
/** @typedef {import("@typescript-eslint/utils").TSESTree.FunctionDeclaration | import("@typescript-eslint/utils").TSESTree.FunctionExpression} FunctionDeclarationOrExpression */
/**
* @import { TSESTree } from "@typescript-eslint/utils"
* @typedef {TSESTree.FunctionDeclaration | TSESTree.FunctionExpression} FunctionDeclarationOrExpression
*/
void 0;
module.exports = createRule({
name: "only-arrow-functions",
@@ -32,7 +36,7 @@ module.exports = createRule({
/** @type {(node: FunctionDeclarationOrExpression) => boolean} */
const isThisParameter = node => !!node.params.length && !!node.params.find(param => param.type === AST_NODE_TYPES.Identifier && param.name === "this");
/** @type {(node: import("@typescript-eslint/utils").TSESTree.Node) => boolean} */
/** @type {(node: TSESTree.Node) => boolean} */
const isMethodType = node => {
const types = [
AST_NODE_TYPES.MethodDefinition,
+149
View File
@@ -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");
`,
},
],
});
+1 -1
View File
@@ -86,7 +86,7 @@ function buildInfoFileOutput(messageTable, inputFilePathRel) {
"// <auto-generated />",
`// 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 };",
@@ -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(", ")}];`);
-49
View File
@@ -1,49 +0,0 @@
{
"extends": "../.eslintrc.json",
"parserOptions": {
"tsconfigRootDir": "src",
"project": "./tsconfig-eslint.json"
},
"rules": {
"@typescript-eslint/no-unnecessary-type-assertion": "error",
"no-restricted-globals": [
"error",
{ "name": "setTimeout" },
{ "name": "clearTimeout" },
{ "name": "setInterval" },
{ "name": "clearInterval" },
{ "name": "setImmediate" },
{ "name": "clearImmediate" },
{ "name": "performance" }
]
},
"overrides": [
{
"files": ["lib/*.d.ts"],
"rules": {
"@typescript-eslint/interface-name-prefix": "off",
"@typescript-eslint/prefer-function-type": "off",
"@typescript-eslint/unified-signatures": "off",
// scripts/eslint/rules
"local/no-keywords": "off",
// eslint
"no-var": "off",
"no-restricted-globals": "off"
}
},
{
"files": ["lib/es2019.array.d.ts"],
"rules": {
"@typescript-eslint/array-type": "off"
}
},
{
"files": ["debug/**", "harness/**", "testRunner/**"],
"rules": {
"no-restricted-globals": "off"
}
}
]
}
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.moduleSpecifiers namespace. */
export * from "../moduleSpecifiers";
export * from "../moduleSpecifiers.js";
+1 -1
View File
@@ -1,3 +1,3 @@
/* Generated file to emulate the ts.performance namespace. */
export * from "../performance";
export * from "../performance.js";
+74 -75
View File
@@ -1,79 +1,78 @@
/* 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 "../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/node.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 };
+7 -6
View File
@@ -251,6 +251,7 @@ import {
ModifierFlags,
ModuleBlock,
ModuleDeclaration,
moduleExportNameIsDefault,
Mutable,
NamespaceExportDeclaration,
Node,
@@ -268,7 +269,6 @@ import {
ParenthesizedExpression,
Pattern,
PatternAmbientModule,
perfLogger,
PostfixUnaryExpression,
PrefixUnaryExpression,
PrivateIdentifier,
@@ -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 {
@@ -433,6 +433,9 @@ function getModuleInstanceStateWorker(node: Node, visited: Map<number, ModuleIns
function getModuleInstanceStateForAliasTarget(specifier: ExportSpecifier, visited: Map<number, ModuleInstanceState | undefined>) {
const name = specifier.propertyName || specifier.name;
if (name.kind !== SyntaxKind.Identifier) {
return ModuleInstanceState.Instantiated; // Skip for invalid syntax like this: export { "x" }
}
let p: Node | undefined = specifier.parent;
while (p) {
if (isBlock(p) || isModuleBlock(p) || isSourceFile(p)) {
@@ -509,9 +512,7 @@ const binder = /* @__PURE__ */ createBinder();
/** @internal */
export function bindSourceFile(file: SourceFile, options: CompilerOptions) {
performance.mark("beforeBind");
perfLogger?.logStartBindFile("" + file.fileName);
binder(file, options);
perfLogger?.logStopBindFile();
performance.mark("afterBind");
performance.measure("Bind", "beforeBind", "afterBind");
}
@@ -759,7 +760,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void {
function declareSymbol(symbolTable: SymbolTable, parent: Symbol | undefined, node: Declaration, includes: SymbolFlags, excludes: SymbolFlags, isReplaceableByMethod?: boolean, isComputedName?: boolean): Symbol {
Debug.assert(isComputedName || !hasDynamicName(node));
const isDefaultExport = hasSyntacticModifier(node, ModifierFlags.Default) || isExportSpecifier(node) && node.name.escapedText === "default";
const isDefaultExport = hasSyntacticModifier(node, ModifierFlags.Default) || isExportSpecifier(node) && moduleExportNameIsDefault(node.name);
// The exported symbol for an export default function/class node is always named "default"
const name = isComputedName ? InternalSymbolName.Computed
+913 -403
View File
File diff suppressed because it is too large Load Diff
+102 -20
View File
@@ -13,10 +13,9 @@ import {
Program,
ProjectReference,
ReusableBuilderProgramState,
SavedBuildProgramEmitState,
SourceFile,
WriteFileCallback,
} from "./_namespaces/ts";
} from "./_namespaces/ts.js";
export type AffectedFileResult<T> = { result: T; affected: SourceFile | Program; } | undefined;
@@ -46,11 +45,7 @@ export type HostForComputeHash = Pick<BuilderProgramHost, "createHash" | "storeS
*/
export interface BuilderProgram {
/** @internal */
getState(): ReusableBuilderProgramState;
/** @internal */
saveEmitState(): SavedBuildProgramEmitState;
/** @internal */
restoreEmitState(saved: SavedBuildProgramEmitState): void;
state: ReusableBuilderProgramState;
/** @internal */
hasChangedEmitSignature?(): boolean;
/**
@@ -164,28 +159,115 @@ export interface EmitAndSemanticDiagnosticsBuilderProgram extends SemanticDiagno
/**
* Create the builder to manage semantic diagnostics and cache them
*/
export function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[]): SemanticDiagnosticsBuilderProgram;
export function createSemanticDiagnosticsBuilderProgram(rootNames: readonly string[] | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]): SemanticDiagnosticsBuilderProgram;
export function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | readonly string[] | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: readonly Diagnostic[] | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]) {
return createBuilderProgram(BuilderProgramKind.SemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
export function createSemanticDiagnosticsBuilderProgram(
newProgram: Program,
host: BuilderProgramHost,
oldProgram?: SemanticDiagnosticsBuilderProgram,
configFileParsingDiagnostics?: readonly Diagnostic[],
): SemanticDiagnosticsBuilderProgram;
export function createSemanticDiagnosticsBuilderProgram(
rootNames: readonly string[] | undefined,
options: CompilerOptions | undefined,
host?: CompilerHost,
oldProgram?: SemanticDiagnosticsBuilderProgram,
configFileParsingDiagnostics?: readonly Diagnostic[],
projectReferences?: readonly ProjectReference[],
): SemanticDiagnosticsBuilderProgram;
export function createSemanticDiagnosticsBuilderProgram(
newProgramOrRootNames: Program | readonly string[] | undefined,
hostOrOptions: BuilderProgramHost | CompilerOptions | undefined,
oldProgramOrHost?: CompilerHost | SemanticDiagnosticsBuilderProgram,
configFileParsingDiagnosticsOrOldProgram?: readonly Diagnostic[] | SemanticDiagnosticsBuilderProgram,
configFileParsingDiagnostics?: readonly Diagnostic[],
projectReferences?: readonly ProjectReference[],
) {
return createBuilderProgram(
BuilderProgramKind.SemanticDiagnosticsBuilderProgram,
getBuilderCreationParameters(
newProgramOrRootNames,
hostOrOptions,
oldProgramOrHost,
configFileParsingDiagnosticsOrOldProgram,
configFileParsingDiagnostics,
projectReferences,
),
);
}
/**
* Create the builder that can handle the changes in program and iterate through changed files
* to emit the those files and manage semantic diagnostics cache as well
*/
export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[]): EmitAndSemanticDiagnosticsBuilderProgram;
export function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: readonly string[] | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]): EmitAndSemanticDiagnosticsBuilderProgram;
export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | readonly string[] | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: readonly Diagnostic[] | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]) {
return createBuilderProgram(BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences));
export function createEmitAndSemanticDiagnosticsBuilderProgram(
newProgram: Program,
host: BuilderProgramHost,
oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram,
configFileParsingDiagnostics?: readonly Diagnostic[],
): EmitAndSemanticDiagnosticsBuilderProgram;
export function createEmitAndSemanticDiagnosticsBuilderProgram(
rootNames: readonly string[] | undefined,
options: CompilerOptions | undefined,
host?: CompilerHost,
oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram,
configFileParsingDiagnostics?: readonly Diagnostic[],
projectReferences?: readonly ProjectReference[],
): EmitAndSemanticDiagnosticsBuilderProgram;
export function createEmitAndSemanticDiagnosticsBuilderProgram(
newProgramOrRootNames: Program | readonly string[] | undefined,
hostOrOptions: BuilderProgramHost | CompilerOptions | undefined,
oldProgramOrHost?: CompilerHost | EmitAndSemanticDiagnosticsBuilderProgram,
configFileParsingDiagnosticsOrOldProgram?: readonly Diagnostic[] | EmitAndSemanticDiagnosticsBuilderProgram,
configFileParsingDiagnostics?: readonly Diagnostic[],
projectReferences?: readonly ProjectReference[],
) {
return createBuilderProgram(
BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram,
getBuilderCreationParameters(
newProgramOrRootNames,
hostOrOptions,
oldProgramOrHost,
configFileParsingDiagnosticsOrOldProgram,
configFileParsingDiagnostics,
projectReferences,
),
);
}
/**
* Creates a builder thats just abstraction over program and can be used with watch
*/
export function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[]): BuilderProgram;
export function createAbstractBuilder(rootNames: readonly string[] | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]): BuilderProgram;
export function createAbstractBuilder(newProgramOrRootNames: Program | readonly string[] | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | BuilderProgram, configFileParsingDiagnosticsOrOldProgram?: readonly Diagnostic[] | BuilderProgram, configFileParsingDiagnostics?: readonly Diagnostic[], projectReferences?: readonly ProjectReference[]): BuilderProgram {
const { newProgram, configFileParsingDiagnostics: newConfigFileParsingDiagnostics } = getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics, projectReferences);
return createRedirectedBuilderProgram(() => ({ program: newProgram, compilerOptions: newProgram.getCompilerOptions() }), newConfigFileParsingDiagnostics);
export function createAbstractBuilder(
newProgram: Program,
host: BuilderProgramHost,
oldProgram?: BuilderProgram,
configFileParsingDiagnostics?: readonly Diagnostic[],
): BuilderProgram;
export function createAbstractBuilder(
rootNames: readonly string[] | undefined,
options: CompilerOptions | undefined,
host?: CompilerHost,
oldProgram?: BuilderProgram,
configFileParsingDiagnostics?: readonly Diagnostic[],
projectReferences?: readonly ProjectReference[],
): BuilderProgram;
export function createAbstractBuilder(
newProgramOrRootNames: Program | readonly string[] | undefined,
hostOrOptions: BuilderProgramHost | CompilerOptions | undefined,
oldProgramOrHost?: CompilerHost | BuilderProgram,
configFileParsingDiagnosticsOrOldProgram?: readonly Diagnostic[] | BuilderProgram,
configFileParsingDiagnostics?: readonly Diagnostic[],
projectReferences?: readonly ProjectReference[],
): BuilderProgram {
const { newProgram, configFileParsingDiagnostics: newConfigFileParsingDiagnostics } = getBuilderCreationParameters(
newProgramOrRootNames,
hostOrOptions,
oldProgramOrHost,
configFileParsingDiagnosticsOrOldProgram,
configFileParsingDiagnostics,
projectReferences,
);
return createRedirectedBuilderProgram(
{ program: newProgram, compilerOptions: newProgram.getCompilerOptions() },
newConfigFileParsingDiagnostics,
);
}
+12 -5
View File
@@ -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<Path> | undefined;
getValues(k: Path): ReadonlySet<Path> | undefined;
keys(): IterableIterator<Path>;
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<Path>()).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<BuilderState> | undefined, disableUseFileVersionAsSignature: boolean): BuilderState {
const fileInfos = new Map<Path, FileInfo>();
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,
});
}
+2 -2
View File
@@ -1,12 +1,12 @@
import {
Diagnostic,
WriteFileCallbackData,
} from "./_namespaces/ts";
} from "./_namespaces/ts.js";
export interface EmitOutput {
outputFiles: OutputFile[];
emitSkipped: boolean;
/** @internal */ diagnostics: readonly Diagnostic[];
diagnostics: readonly Diagnostic[];
}
export interface OutputFile {
+1934 -876
View File
File diff suppressed because it is too large Load Diff
+39 -27
View File
@@ -121,10 +121,9 @@ import {
WatchDirectoryKind,
WatchFileKind,
WatchOptions,
} from "./_namespaces/ts";
} from "./_namespaces/ts.js";
/** @internal */
export const compileOnSaveCommandLineOption: CommandLineOption = {
const compileOnSaveCommandLineOption: CommandLineOption = {
name: "compileOnSave",
type: "boolean",
defaultValueDescription: false,
@@ -502,6 +501,25 @@ export const commonOptionsWithBuild: CommandLineOption[] = [
description: Diagnostics.Include_sourcemap_files_inside_the_emitted_JavaScript,
defaultValueDescription: false,
},
{
name: "noCheck",
type: "boolean",
showInSimplifiedHelpView: false,
category: Diagnostics.Compiler_Diagnostics,
description: Diagnostics.Disable_full_type_checking_only_critical_parse_and_emit_errors_will_be_reported,
transpileOptionValue: true,
defaultValueDescription: false,
// Not setting affectsSemanticDiagnostics or affectsBuildInfo because we dont want all diagnostics to go away, its handled in builder
},
{
name: "noEmit",
type: "boolean",
showInSimplifiedHelpView: true,
category: Diagnostics.Emit,
description: Diagnostics.Disable_emitting_files_from_a_compilation,
transpileOptionValue: undefined,
defaultValueDescription: false,
},
{
name: "assumeChangesOnlyAffectDirectDependencies",
type: "boolean",
@@ -772,20 +790,12 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
defaultValueDescription: false,
description: Diagnostics.Disable_emitting_comments,
},
{
name: "noEmit",
type: "boolean",
showInSimplifiedHelpView: true,
category: Diagnostics.Emit,
description: Diagnostics.Disable_emitting_files_from_a_compilation,
transpileOptionValue: undefined,
defaultValueDescription: false,
},
{
name: "importHelpers",
type: "boolean",
affectsEmit: true,
affectsBuildInfo: true,
affectsSourceFile: true,
category: Diagnostics.Emit,
description: Diagnostics.Allow_importing_helper_functions_from_tslib_once_per_project_instead_of_including_them_per_file,
defaultValueDescription: false,
@@ -1265,6 +1275,7 @@ const commandOptionsWithoutBuild: CommandLineOption[] = [
affectsEmit: true,
affectsBuildInfo: true,
affectsModuleResolution: true,
affectsSourceFile: true,
category: Diagnostics.Language_and_Environment,
description: Diagnostics.Specify_module_specifier_used_to_import_the_JSX_factory_functions_when_using_jsx_Colon_react_jsx_Asterisk,
defaultValueDescription: "react",
@@ -1625,15 +1636,20 @@ export const optionsAffectingProgramStructure: readonly CommandLineOption[] = op
/** @internal */
export const transpileOptionValueCompilerOptions: readonly CommandLineOption[] = optionDeclarations.filter(option => hasProperty(option, "transpileOptionValue"));
/** @internal */
export const configDirTemplateSubstitutionOptions: readonly CommandLineOption[] = optionDeclarations.filter(
const configDirTemplateSubstitutionOptions: readonly CommandLineOption[] = optionDeclarations.filter(
option => option.allowConfigDirTemplateSubstitution || (!option.isCommandLineOnly && option.isFilePath),
);
/** @internal */
export const configDirTemplateSubstitutionWatchOptions: readonly CommandLineOption[] = optionsForWatch.filter(
const configDirTemplateSubstitutionWatchOptions: readonly CommandLineOption[] = optionsForWatch.filter(
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[] = [
@@ -1738,8 +1754,7 @@ const compilerOptionsAlternateMode: AlternateModeDiagnostics = {
getOptionsNameMap: getBuildOptionsNameMap,
};
/** @internal */
export const defaultInitCompilerOptions: CompilerOptions = {
const defaultInitCompilerOptions: CompilerOptions = {
module: ModuleKind.CommonJS,
target: ScriptTarget.ES2016,
strict: true,
@@ -2569,9 +2584,7 @@ export function convertToTSConfig(configParseResult: ParsedCommandLine, configFi
/** @internal */
export function optionMapToObject(optionMap: Map<string, CompilerOptionsValue>): object {
return {
...arrayFrom(optionMap.entries()).reduce((prev, cur) => ({ ...prev, [cur[0]]: cur[1] }), {}),
};
return Object.fromEntries(optionMap);
}
function filterSameAsDefaultInclude(specs: readonly string[] | undefined) {
@@ -2898,8 +2911,7 @@ function directoryOfCombinedPath(fileName: string, basePath: string) {
return getDirectoryPath(getNormalizedAbsolutePath(fileName, basePath));
}
/** @internal */
export const defaultIncludeSpec = "**/*";
const defaultIncludeSpec = "**/*";
/**
* Parse the contents of a config file from json or json source file (tsconfig.json).
@@ -2985,12 +2997,12 @@ function parseJsonConfigFileContentWorker(
const excludeOfRaw = getSpecsFromRaw("exclude");
let isDefaultIncludeSpec = false;
let excludeSpecs = toPropValue(excludeOfRaw);
if (excludeOfRaw === "no-prop" && raw.compilerOptions) {
const outDir = raw.compilerOptions.outDir;
const declarationDir = raw.compilerOptions.declarationDir;
if (excludeOfRaw === "no-prop") {
const outDir = options.outDir;
const declarationDir = options.declarationDir;
if (outDir || declarationDir) {
excludeSpecs = [outDir, declarationDir].filter(d => !!d);
excludeSpecs = filter([outDir, declarationDir], d => !!d) as string[];
}
}
+99 -209
View File
@@ -9,18 +9,18 @@ import {
SortedArray,
SortedReadonlyArray,
TextSpan,
} from "./_namespaces/ts";
} from "./_namespaces/ts.js";
/* eslint-disable @typescript-eslint/prefer-for-of */
/** @internal */
export const emptyArray: never[] = [] as never[];
/** @internal */
export const emptyMap: ReadonlyMap<never, never> = new Map<never, never>();
/** @internal */
export const emptySet: ReadonlySet<never> = new Set<never>();
/** @internal */
export function length(array: readonly any[] | undefined): number {
return array ? array.length : 0;
return array !== undefined ? array.length : 0;
}
/**
@@ -31,7 +31,7 @@ export function length(array: readonly any[] | undefined): number {
* @internal
*/
export function forEach<T, U>(array: readonly T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
if (array) {
if (array !== undefined) {
for (let i = 0; i < array.length; i++) {
const result = callback(array[i], i);
if (result) {
@@ -48,7 +48,7 @@ export function forEach<T, U>(array: readonly T[] | undefined, callback: (elemen
* @internal
*/
export function forEachRight<T, U>(array: readonly T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined {
if (array) {
if (array !== undefined) {
for (let i = array.length - 1; i >= 0; i--) {
const result = callback(array[i], i);
if (result) {
@@ -124,7 +124,7 @@ export function intersperse<T>(input: T[], element: T): T[] {
}
const result: T[] = [];
for (let i = 0, n = input.length; i < n; i++) {
if (i) result.push(element);
if (i !== 0) result.push(element);
result.push(input[i]);
}
return result;
@@ -143,7 +143,7 @@ export function every<T, U extends T>(array: readonly T[] | undefined, callback:
/** @internal */
export function every<T>(array: readonly T[] | undefined, callback: (element: T, index: number) => boolean): boolean;
export function every<T>(array: readonly T[] | undefined, callback: (element: T, index: number) => boolean): boolean {
if (array) {
if (array !== undefined) {
for (let i = 0; i < array.length; i++) {
if (!callback(array[i], i)) {
return false;
@@ -216,27 +216,11 @@ export function findLastIndex<T>(array: readonly T[] | undefined, predicate: (el
return -1;
}
/**
* Returns the first truthy result of `callback`, or else fails.
* This is like `forEach`, but never returns undefined.
*
* @internal
*/
export function findMap<T, U>(array: readonly T[], callback: (element: T, index: number) => U | undefined): U {
for (let i = 0; i < array.length; i++) {
const result = callback(array[i], i);
if (result) {
return result;
}
}
return Debug.fail();
}
/** @internal */
export function contains<T>(array: readonly T[] | undefined, value: T, equalityComparer: EqualityComparer<T> = equateValues): boolean {
if (array) {
for (const v of array) {
if (equalityComparer(v, value)) {
if (array !== undefined) {
for (let i = 0; i < array.length; i++) {
if (equalityComparer(array[i], value)) {
return true;
}
}
@@ -244,14 +228,9 @@ export function contains<T>(array: readonly T[] | undefined, value: T, equalityC
return false;
}
/** @internal */
export function arraysEqual<T>(a: readonly T[], b: readonly T[], equalityComparer: EqualityComparer<T> = equateValues): boolean {
return a.length === b.length && a.every((x, i) => equalityComparer(x, b[i]));
}
/** @internal */
export function indexOfAnyCharCode(text: string, charCodes: readonly number[], start?: number): number {
for (let i = start || 0; i < text.length; i++) {
for (let i = start ?? 0; i < text.length; i++) {
if (contains(charCodes, text.charCodeAt(i))) {
return i;
}
@@ -262,7 +241,7 @@ export function indexOfAnyCharCode(text: string, charCodes: readonly number[], s
/** @internal */
export function countWhere<T>(array: readonly T[] | undefined, predicate: (x: T, i: number) => boolean): number {
let count = 0;
if (array) {
if (array !== undefined) {
for (let i = 0; i < array.length; i++) {
const v = array[i];
if (predicate(v, i)) {
@@ -296,7 +275,7 @@ export function filter<T, U extends T>(array: readonly T[] | undefined, f: (x: T
export function filter<T>(array: readonly T[] | undefined, f: (x: T) => boolean): readonly T[] | undefined;
/** @internal */
export function filter<T>(array: readonly T[] | undefined, f: (x: T) => boolean): readonly T[] | undefined {
if (array) {
if (array !== undefined) {
const len = array.length;
let i = 0;
while (i < len && f(array[i])) i++;
@@ -340,7 +319,7 @@ export function map<T, U>(array: readonly T[] | undefined, f: (x: T, i: number)
/** @internal */
export function map<T, U>(array: readonly T[] | undefined, f: (x: T, i: number) => U): U[] | undefined {
let result: U[] | undefined;
if (array) {
if (array !== undefined) {
result = [];
for (let i = 0; i < array.length; i++) {
result.push(f(array[i], i));
@@ -369,7 +348,7 @@ export function sameMap<T, U = T>(array: T[] | undefined, f: (x: T, i: number) =
export function sameMap<T, U = T>(array: readonly T[] | undefined, f: (x: T, i: number) => U): readonly U[] | undefined;
/** @internal */
export function sameMap<T, U = T>(array: readonly T[] | undefined, f: (x: T, i: number) => U): readonly U[] | undefined {
if (array) {
if (array !== undefined) {
for (let i = 0; i < array.length; i++) {
const item = array[i];
const mapped = f(item, i);
@@ -395,7 +374,8 @@ export function sameMap<T, U = T>(array: readonly T[] | undefined, f: (x: T, i:
*/
export function flatten<T>(array: T[][] | readonly (T | readonly T[] | undefined)[]): T[] {
const result = [];
for (const v of array) {
for (let i = 0; i < array.length; i++) {
const v = array[i];
if (v) {
if (isArray(v)) {
addRange(result, v);
@@ -418,7 +398,7 @@ export function flatten<T>(array: T[][] | readonly (T | readonly T[] | undefined
*/
export function flatMap<T, U>(array: readonly T[] | undefined, mapfn: (x: T, i: number) => U | readonly U[] | undefined): readonly U[] {
let result: U[] | undefined;
if (array) {
if (array !== undefined) {
for (let i = 0; i < array.length; i++) {
const v = mapfn(array[i], i);
if (v) {
@@ -431,13 +411,13 @@ export function flatMap<T, U>(array: readonly T[] | undefined, mapfn: (x: T, i:
}
}
}
return result || emptyArray;
return result ?? emptyArray;
}
/** @internal */
export function flatMapToMutable<T, U>(array: readonly T[] | undefined, mapfn: (x: T, i: number) => U | readonly U[] | undefined): U[] {
const result: U[] = [];
if (array) {
if (array !== undefined) {
for (let i = 0; i < array.length; i++) {
const v = mapfn(array[i], i);
if (v) {
@@ -477,7 +457,7 @@ export function sameFlatMap<T>(array: readonly T[], mapfn: (x: T, i: number) =>
/** @internal */
export function sameFlatMap<T>(array: readonly T[], mapfn: (x: T, i: number) => T | readonly T[]): readonly T[] {
let result: T[] | undefined;
if (array) {
if (array !== undefined) {
for (let i = 0; i < array.length; i++) {
const item = array[i];
const mapped = mapfn(item, i);
@@ -494,7 +474,7 @@ export function sameFlatMap<T>(array: readonly T[], mapfn: (x: T, i: number) =>
}
}
}
return result || array;
return result ?? array;
}
/** @internal */
@@ -513,7 +493,7 @@ export function mapAllOrFail<T, U>(array: readonly T[], mapFn: (x: T, i: number)
/** @internal */
export function mapDefined<T, U>(array: readonly T[] | undefined, mapFn: (x: T, i: number) => U | undefined): U[] {
const result: U[] = [];
if (array) {
if (array !== undefined) {
for (let i = 0; i < array.length; i++) {
const mapped = mapFn(array[i], i);
if (mapped !== undefined) {
@@ -534,30 +514,6 @@ export function* mapDefinedIterator<T, U>(iter: Iterable<T>, mapFn: (x: T) => U
}
}
/** @internal */
export function mapDefinedEntries<K1, V1, K2, V2>(map: ReadonlyMap<K1, V1>, f: (key: K1, value: V1) => readonly [K2, V2] | undefined): Map<K2, V2>;
/** @internal */
export function mapDefinedEntries<K1, V1, K2, V2>(map: ReadonlyMap<K1, V1> | undefined, f: (key: K1, value: V1) => readonly [K2 | undefined, V2 | undefined] | undefined): Map<K2, V2> | undefined;
/** @internal */
export function mapDefinedEntries<K1, V1, K2, V2>(map: ReadonlyMap<K1, V1> | undefined, f: (key: K1, value: V1) => readonly [K2 | undefined, V2 | undefined] | undefined): Map<K2, V2> | undefined {
if (!map) {
return undefined;
}
const result = new Map<K2, V2>();
map.forEach((value, key) => {
const entry = f(key, value);
if (entry !== undefined) {
const [newKey, newValue] = entry;
if (newKey !== undefined && newValue !== undefined) {
result.set(newKey, newValue);
}
}
});
return result;
}
/** @internal */
export function getOrUpdate<K, V>(map: Map<K, V>, key: K, callback: () => V) {
if (map.has(key)) {
@@ -597,7 +553,7 @@ export function spanMap<T, K, U>(array: readonly T[] | undefined, keyfn: (x: T,
/** @internal */
export function spanMap<T, K, U>(array: readonly T[] | undefined, keyfn: (x: T, i: number) => K, mapfn: (chunk: T[], key: K, start: number, end: number) => U): U[] | undefined {
let result: U[] | undefined;
if (array) {
if (array !== undefined) {
result = [];
const len = array.length;
let previousKey: K | undefined;
@@ -641,7 +597,7 @@ export function mapEntries<K1, V1, K2, V2>(map: ReadonlyMap<K1, V1>, f: (key: K1
export function mapEntries<K1, V1, K2, V2>(map: ReadonlyMap<K1, V1> | undefined, f: (key: K1, value: V1) => readonly [K2, V2]): Map<K2, V2> | undefined;
/** @internal */
export function mapEntries<K1, V1, K2, V2>(map: ReadonlyMap<K1, V1> | undefined, f: (key: K1, value: V1) => readonly [K2, V2]): Map<K2, V2> | undefined {
if (!map) {
if (map === undefined) {
return undefined;
}
@@ -659,10 +615,10 @@ export function some<T>(array: readonly T[] | undefined): array is readonly T[];
export function some<T>(array: readonly T[] | undefined, predicate: (value: T) => boolean): boolean;
/** @internal */
export function some<T>(array: readonly T[] | undefined, predicate?: (value: T) => boolean): boolean {
if (array) {
if (predicate) {
for (const v of array) {
if (predicate(v)) {
if (array !== undefined) {
if (predicate !== undefined) {
for (let i = 0; i < array.length; i++) {
if (predicate(array[i])) {
return true;
}
}
@@ -713,8 +669,8 @@ export function concatenate<T>(array1: T[] | undefined, array2: T[] | undefined)
export function concatenate<T>(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined;
/** @internal */
export function concatenate<T>(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined {
if (!some(array2)) return array1;
if (!some(array1)) return array2;
if (array2 === undefined || array2.length === 0) return array1;
if (array1 === undefined || array1.length === 0) return array2;
return [...array1, ...array2];
}
@@ -751,8 +707,8 @@ function deduplicateRelational<T>(array: readonly T[], equalityComparer: Equalit
function deduplicateEquality<T>(array: readonly T[], equalityComparer: EqualityComparer<T>) {
const result: T[] = [];
for (const item of array) {
pushIfUnique(result, item, equalityComparer);
for (let i = 0; i < array.length; i++) {
pushIfUnique(result, array[i], equalityComparer);
}
return result;
}
@@ -808,7 +764,13 @@ export function createSortedArray<T>(): SortedArray<T> {
}
/** @internal */
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>, allowDuplicates?: boolean): boolean {
export function insertSorted<T>(
array: SortedArray<T>,
insert: T,
compare: Comparer<T>,
equalityComparer?: EqualityComparer<T>,
allowDuplicates?: boolean,
): boolean {
if (array.length === 0) {
array.push(insert);
return true;
@@ -816,6 +778,16 @@ export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Compa
const insertIndex = binarySearch(array, insert, identity, compare);
if (insertIndex < 0) {
if (equalityComparer && !allowDuplicates) {
const idx = ~insertIndex;
if (idx > 0 && equalityComparer(insert, array[idx - 1])) {
return false;
}
if (idx < array.length && equalityComparer(insert, array[idx])) {
array.splice(idx, 1, insert);
return true;
}
}
array.splice(~insertIndex, 0, insert);
return true;
}
@@ -834,23 +806,12 @@ export function sortAndDeduplicate(array: readonly string[]): SortedReadonlyArra
export function sortAndDeduplicate<T>(array: readonly T[], comparer: Comparer<T>, equalityComparer?: EqualityComparer<T>): SortedReadonlyArray<T>;
/** @internal */
export function sortAndDeduplicate<T>(array: readonly T[], comparer?: Comparer<T>, equalityComparer?: EqualityComparer<T>): SortedReadonlyArray<T> {
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer || compareStringsCaseSensitive as any as Comparer<T>);
}
/** @internal */
export function arrayIsSorted<T>(array: readonly T[], comparer: Comparer<T>) {
if (array.length < 2) return true;
for (let i = 1, len = array.length; i < len; i++) {
if (comparer(array[i - 1], array[i]) === Comparison.GreaterThan) {
return false;
}
}
return true;
return deduplicateSorted(sort(array, comparer), equalityComparer ?? comparer ?? compareStringsCaseSensitive as any as Comparer<T>);
}
/** @internal */
export function arrayIsEqualTo<T>(array1: readonly T[] | undefined, array2: readonly T[] | undefined, equalityComparer: (a: T, b: T, index: number) => boolean = equateValues): boolean {
if (!array1 || !array2) {
if (array1 === undefined || array2 === undefined) {
return array1 === array2;
}
@@ -883,20 +844,20 @@ export function compact<T>(array: readonly T[]): readonly T[]; // eslint-disable
/** @internal */
export function compact<T>(array: readonly T[]): readonly T[] {
let result: T[] | undefined;
if (array) {
if (array !== undefined) {
for (let i = 0; i < array.length; i++) {
const v = array[i];
if (result || !v) {
if (!result) {
result = array.slice(0, i);
}
// Either the result has been initialized (and is looking to collect truthy values separately),
// or we've hit our first falsy value and need to copy over the current stretch of truthy values.
if (result ?? !v) {
result ??= array.slice(0, i);
if (v) {
result.push(v);
}
}
}
}
return result || array;
return result ?? array;
}
/**
@@ -1059,7 +1020,7 @@ export function pushIfUnique<T>(array: T[], toAdd: T, equalityComparer?: Equalit
* @internal
*/
export function appendIfUnique<T>(array: T[] | undefined, toAdd: T, equalityComparer?: EqualityComparer<T>): T[] {
if (array) {
if (array !== undefined) {
pushIfUnique(array, toAdd, equalityComparer);
return array;
}
@@ -1120,7 +1081,7 @@ export function rangeEquals<T>(array1: readonly T[], array2: readonly T[], pos:
export const elementAt: <T>(array: readonly T[] | undefined, offset: number) => T | undefined = !!Array.prototype.at
? (array, offset) => array?.at(offset)
: (array, offset) => {
if (array) {
if (array !== undefined) {
offset = toOffset(array, offset);
if (offset < array.length) {
return array[offset];
@@ -1140,7 +1101,7 @@ export function firstOrUndefined<T>(array: readonly T[] | undefined): T | undefi
/** @internal */
export function firstOrUndefinedIterator<T>(iter: Iterable<T> | undefined): T | undefined {
if (iter) {
if (iter !== undefined) {
for (const value of iter) {
return value;
}
@@ -1183,7 +1144,7 @@ export function last<T>(array: readonly T[]): T {
* @internal
*/
export function singleOrUndefined<T>(array: readonly T[] | undefined): T | undefined {
return array && array.length === 1
return array !== undefined && array.length === 1
? array[0]
: undefined;
}
@@ -1212,7 +1173,7 @@ export function singleOrMany<T>(array: T[] | undefined): T | T[] | undefined;
export function singleOrMany<T>(array: readonly T[] | undefined): T | readonly T[] | undefined;
/** @internal */
export function singleOrMany<T>(array: readonly T[] | undefined): T | readonly T[] | undefined {
return array && array.length === 1
return array !== undefined && array.length === 1
? array[0]
: array;
}
@@ -1258,7 +1219,7 @@ export function binarySearchKey<T, U>(array: readonly T[], key: U, keySelector:
return -1;
}
let low = offset || 0;
let low = offset ?? 0;
let high = array.length - 1;
while (low <= high) {
const middle = low + ((high - low) >> 1);
@@ -1462,7 +1423,8 @@ export function arrayToMap<T, U>(array: readonly T[], makeKey: (value: T) => str
/** @internal */
export function arrayToMap<K, V1, V2>(array: readonly V1[], makeKey: (value: V1) => K | undefined, makeValue: (value: V1) => V1 | V2 = identity): Map<K, V1 | V2> {
const result = new Map<K, V1 | V2>();
for (const value of array) {
for (let i = 0; i < array.length; i++) {
const value = array[i];
const key = makeKey(value);
if (key !== undefined) result.set(key, makeValue(value));
}
@@ -1476,7 +1438,8 @@ export function arrayToNumericMap<T, U>(array: readonly T[], makeKey: (value: T)
/** @internal */
export function arrayToNumericMap<T, U>(array: readonly T[], makeKey: (value: T) => number, makeValue: (value: T) => T | U = identity): (T | U)[] {
const result: (T | U)[] = [];
for (const value of array) {
for (let i = 0; i < array.length; i++) {
const value = array[i];
result[makeKey(value)] = makeValue(value);
}
return result;
@@ -1489,7 +1452,8 @@ export function arrayToMultiMap<K, V, U>(values: readonly V[], makeKey: (value:
/** @internal */
export function arrayToMultiMap<K, V, U>(values: readonly V[], makeKey: (value: V) => K, makeValue: (value: V) => V | U = identity): MultiMap<K, V | U> {
const result = createMultiMap<K, V | U>();
for (const value of values) {
for (let i = 0; i < values.length; i++) {
const value = values[i];
result.add(makeKey(value), makeValue(value));
}
return result;
@@ -1514,8 +1478,9 @@ export function groupBy<T, U extends T>(values: readonly T[] | undefined, keySel
export function groupBy<T, K extends string | number | boolean | null | undefined>(values: readonly T[] | undefined, keySelector: (value: T) => K): { [P in K as `${P}`]?: T[]; }; // eslint-disable-line no-restricted-syntax
export function groupBy<T, K extends string | number | boolean | null | undefined>(values: readonly T[] | undefined, keySelector: (value: T) => K): { [P in K as `${P}`]?: T[]; } { // eslint-disable-line no-restricted-syntax
const result: Record<string, T[]> = {};
if (values) {
for (const value of values) {
if (values !== undefined) {
for (let i = 0; i < values.length; i++) {
const value = values[i];
const key = `${keySelector(value)}`;
const array = result[key] ??= [];
array.push(value);
@@ -1570,7 +1535,7 @@ export function copyProperties<T1 extends T2, T2>(first: T1, second: T2) {
/** @internal */
export function maybeBind<T, A extends any[], R>(obj: T, fn: ((this: T, ...args: A) => R) | undefined): ((...args: A) => R) | undefined {
return fn ? fn.bind(obj) : undefined;
return fn?.bind(obj);
}
/** @internal */
@@ -1597,7 +1562,7 @@ export function createMultiMap<K, V>(): MultiMap<K, V> {
}
function multiMapAdd<K, V>(this: MultiMap<K, V>, key: K, value: V) {
let values = this.get(key);
if (values) {
if (values !== undefined) {
values.push(value);
}
else {
@@ -1607,7 +1572,7 @@ function multiMapAdd<K, V>(this: MultiMap<K, V>, key: K, value: V) {
}
function multiMapRemove<K, V>(this: MultiMap<K, V>, key: K, value: V) {
const values = this.get(key);
if (values) {
if (values !== undefined) {
unorderedRemoveItem(values, value);
if (!values.length) {
this.delete(key);
@@ -1617,7 +1582,7 @@ function multiMapRemove<K, V>(this: MultiMap<K, V>, key: K, value: V) {
/** @internal */
export function createQueue<T>(items?: readonly T[]): Queue<T> {
const elements: (T | undefined)[] = items?.slice() || [];
const elements: (T | undefined)[] = items?.slice() ?? [];
let headIndex = 0;
function isEmpty() {
@@ -1689,14 +1654,9 @@ export function createSet<TElement, THash = number>(getHashCode: (element: TElem
const hash = getHashCode(element);
if (!multiMap.has(hash)) return false;
const candidates = multiMap.get(hash)!;
if (!isArray(candidates)) return equals(candidates, element);
if (isArray(candidates)) return contains(candidates, element, equals);
for (const candidate of candidates) {
if (equals(candidate, element)) {
return true;
}
}
return false;
return equals(candidates, element);
},
add(element: TElement): Set<TElement> {
const hash = getHashCode(element);
@@ -1763,6 +1723,8 @@ export function createSet<TElement, THash = number>(getHashCode: (element: TElem
return size;
},
forEach(action: (value: TElement, key: TElement, set: Set<TElement>) => void): void {
// NOTE: arrayFrom means that if the callback mutates the underlying collection,
// we won't have an accurate set of values
for (const elements of arrayFrom(multiMap.values())) {
if (isArray(elements)) {
for (const element of elements) {
@@ -1884,10 +1846,8 @@ export function identity<T>(x: T) {
/**
* Returns lower case string
*
* @internal
*/
export function toLowerCase(x: string) {
function toLowerCase(x: string) {
return x.toLowerCase();
}
@@ -1972,82 +1932,6 @@ export function memoizeOne<A extends string | number | boolean | undefined, T>(c
};
}
/**
* A version of `memoize` that supports a single non-primitive argument, stored as keys of a WeakMap.
*
* @internal
*/
export function memoizeWeak<A extends object, T>(callback: (arg: A) => T): (arg: A) => T {
const map = new WeakMap<A, T>();
return (arg: A) => {
let value = map.get(arg);
if (value === undefined && !map.has(arg)) {
value = callback(arg);
map.set(arg, value);
}
return value!;
};
}
/** @internal */
export interface MemoizeCache<A extends any[], T> {
has(args: A): boolean;
get(args: A): T | undefined;
set(args: A, value: T): void;
}
/**
* A version of `memoize` that supports multiple arguments, backed by a provided cache.
*
* @internal
*/
export function memoizeCached<A extends any[], T>(callback: (...args: A) => T, cache: MemoizeCache<A, T>): (...args: A) => T {
return (...args: A) => {
let value = cache.get(args);
if (value === undefined && !cache.has(args)) {
value = callback(...args);
cache.set(args, value);
}
return value!;
};
}
/**
* High-order function, composes functions. Note that functions are composed inside-out;
* for example, `compose(a, b)` is the equivalent of `x => b(a(x))`.
*
* @param args The functions to compose.
*
* @internal
*/
export function compose<T>(...args: ((t: T) => T)[]): (t: T) => T;
/** @internal */
export function compose<T>(a: (t: T) => T, b: (t: T) => T, c: (t: T) => T, d: (t: T) => T, e: (t: T) => T): (t: T) => T {
if (!!e) {
const args: ((t: T) => T)[] = [];
for (let i = 0; i < arguments.length; i++) {
// eslint-disable-next-line prefer-rest-params
args[i] = arguments[i];
}
return t => reduceLeft(args, (u, f) => f(u), t);
}
else if (d) {
return t => d(c(b(a(t))));
}
else if (c) {
return t => c(b(a(t)));
}
else if (b) {
return t => b(a(t));
}
else if (a) {
return t => a(t);
}
else {
return t => t;
}
}
/** @internal */
export const enum AssertionLevel {
None = 0,
@@ -2063,8 +1947,6 @@ export const enum AssertionLevel {
* @internal
*/
export type AnyFunction = (...args: never[]) => void;
/** @internal */
export type AnyConstructor = new (...args: unknown[]) => unknown;
/** @internal */
export function equateValues<T>(a: T, b: T) {
@@ -2129,6 +2011,14 @@ export function compareTextSpans(a: Partial<TextSpan> | undefined, b: Partial<Te
return compareValues(a?.start, b?.start) || compareValues(a?.length, b?.length);
}
/** @internal */
export function maxBy<T>(arr: readonly T[], init: number, mapper: (x: T) => number): number {
for (let i = 0; i < arr.length; i++) {
init = Math.max(init, mapper(arr[i]));
}
return init;
}
/** @internal */
export function min<T>(items: readonly [T, ...T[]], compare: Comparer<T>): T;
/** @internal */
@@ -2254,8 +2144,8 @@ export function setUILocale(value: string | undefined) {
* @internal
*/
export function compareStringsCaseSensitiveUI(a: string, b: string) {
const comparer = uiComparerCaseSensitive || (uiComparerCaseSensitive = createUIStringComparer(uiLocale));
return comparer(a, b);
uiComparerCaseSensitive ??= createUIStringComparer(uiLocale);
return uiComparerCaseSensitive(a, b);
}
/** @internal */
@@ -2468,8 +2358,7 @@ export function orderedRemoveItemAt<T>(array: T[], index: number): void {
array.pop();
}
/** @internal */
export function unorderedRemoveItemAt<T>(array: T[], index: number): void {
function unorderedRemoveItemAt<T>(array: T[], index: number): void {
// Fill in the "hole" left at `index`.
array[index] = array[array.length - 1];
array.pop();
@@ -2538,7 +2427,8 @@ export function findBestPatternMatch<T>(values: readonly T[], getPattern: (value
// use length of prefix as betterness criteria
let longestMatchPrefixLength = -1;
for (const v of values) {
for (let i = 0; i < values.length; i++) {
const v = values[i];
const pattern = getPattern(v);
if (isPatternMatch(pattern, candidate) && pattern.prefix.length > longestMatchPrefixLength) {
longestMatchPrefixLength = pattern.prefix.length;
@@ -2613,7 +2503,7 @@ export function singleElementArray<T>(t: T | undefined): T[] | undefined {
/** @internal */
export function enumerateInsertsAndDeletes<T, U>(newItems: readonly T[], oldItems: readonly U[], comparer: (a: T, b: U) => Comparison, inserted: (newItem: T) => void, deleted: (oldItem: U) => void, unchanged?: (oldItem: U, newItem: T) => void) {
unchanged = unchanged || noop;
unchanged ??= noop;
let newIndex = 0;
let oldIndex = 0;
const newLen = newItems.length;
@@ -2681,7 +2571,7 @@ export function takeWhile<T, U extends T>(array: readonly T[], predicate: (eleme
/** @internal */
export function takeWhile<T, U extends T>(array: readonly T[] | undefined, predicate: (element: T) => element is U): U[] | undefined;
export function takeWhile<T, U extends T>(array: readonly T[] | undefined, predicate: (element: T) => element is U): U[] | undefined {
if (array) {
if (array !== undefined) {
const len = array.length;
let index = 0;
while (index < len && predicate(array[index])) {
@@ -2697,7 +2587,7 @@ export function skipWhile<T, U extends T>(array: readonly T[], predicate: (eleme
export function skipWhile<T, U extends T>(array: readonly T[] | undefined, predicate: (element: T) => element is U): Exclude<T, U>[] | undefined;
/** @internal */
export function skipWhile<T, U extends T>(array: readonly T[] | undefined, predicate: (element: T) => element is U): Exclude<T, U>[] | undefined {
if (array) {
if (array !== undefined) {
const len = array.length;
let index = 0;
while (index < len && predicate(array[index])) {
+1 -12
View File
@@ -1,9 +1,8 @@
// WARNING: The script `configurePrerelease.ts` uses a regexp to parse out these values.
// If changing the text in this section, be sure to test `configurePrerelease` too.
export const versionMajorMinor = "5.5";
export const versionMajorMinor = "5.6";
// The following is baselined as a literal template type without intervention
/** The version of the TypeScript compiler release */
// eslint-disable-next-line @typescript-eslint/no-inferrable-types
export const version: string = `${versionMajorMinor}.0-dev`;
/**
@@ -34,16 +33,6 @@ export interface ReadonlyCollection<K> {
keys(): IterableIterator<K>;
}
/**
* Common write methods for ES6 Map/Set.
*
* @internal
*/
export interface Collection<K> extends ReadonlyCollection<K> {
delete(key: K): boolean;
clear(): void;
}
/** @internal */
export type EqualityComparer<T> = (a: T, b: T) => boolean;
+9 -3
View File
@@ -1,4 +1,4 @@
import * as ts from "./_namespaces/ts";
import * as ts from "./_namespaces/ts.js";
import {
AnyFunction,
AssertionLevel,
@@ -61,9 +61,11 @@ import {
LiteralType,
map,
MatchingKeys,
maxBy,
ModifierFlags,
Node,
NodeArray,
NodeCheckFlags,
NodeFlags,
nodeIsSynthesized,
noop,
@@ -91,7 +93,7 @@ import {
unescapeLeadingUnderscores,
VarianceFlags,
zipWith,
} from "./_namespaces/ts";
} from "./_namespaces/ts.js";
/** @internal */
export enum LogLevel {
@@ -455,6 +457,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);
}
@@ -1121,7 +1127,7 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n")
function renderGraph() {
const columnCount = columnWidths.length;
const laneCount = nodes.reduce((x, n) => Math.max(x, n.lane), 0) + 1;
const laneCount = maxBy(nodes, 0, n => n.lane) + 1;
const lanes: string[] = fill(Array(laneCount), "");
const grid: (FlowGraphNode | undefined)[][] = columnWidths.map(() => Array(laneCount));
const connectors: Connection[][] = columnWidths.map(() => fill(Array(laneCount), 0));
+81 -41
View File
@@ -967,10 +967,6 @@
"category": "Error",
"code": 1292
},
"ESM syntax is not allowed in a CommonJS module when 'module' is set to 'preserve'.": {
"category": "Error",
"code": 1293
},
"'with' statements are not allowed in an async function block.": {
"category": "Error",
@@ -1032,7 +1028,7 @@
"category": "Error",
"code": 1323
},
"Dynamic imports only support a second argument when the '--module' option is set to 'esnext', 'node16', or 'nodenext'.": {
"Dynamic imports only support a second argument when the '--module' option is set to 'esnext', 'node16', 'nodenext', or 'preserve'.": {
"category": "Error",
"code": 1324
},
@@ -1733,7 +1729,7 @@
"category": "Error",
"code": 1519
},
"Expected a class set oprand.": {
"Expected a class set operand.": {
"category": "Error",
"code": 1520
},
@@ -1785,11 +1781,11 @@
"category": "Error",
"code": 1532
},
"A decimal escape must refer to an existent capturing group. There are only {0} capturing groups in this regular expression.": {
"This backreference refers to a group that does not exist. There are only {0} capturing groups in this regular expression.": {
"category": "Error",
"code": 1533
},
"Decimal escapes are invalid when there are no capturing groups in a regular expression.": {
"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 +1793,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",
@@ -2676,10 +2680,6 @@
"category": "Error",
"code": 2524
},
"Initializer provides no value for this binding element and the binding element has no default value.": {
"category": "Error",
"code": 2525
},
"A 'this' type is available only in a non-static member of a class or interface.": {
"category": "Error",
"code": 2526
@@ -4200,10 +4200,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
@@ -4212,7 +4208,7 @@
"category": "Error",
"code": 4092
},
"Property '{0}' of exported class expression may not be private or protected.": {
"Property '{0}' of exported anonymous class type may not be private or protected.": {
"category": "Error",
"code": 4094
},
@@ -4369,10 +4365,6 @@
"category": "Error",
"code": 5012
},
"Failed to parse file '{0}': {1}.": {
"category": "Error",
"code": 5014
},
"Unknown compiler option '{0}'.": {
"category": "Error",
"code": 5023
@@ -4621,6 +4613,10 @@
"category": "Error",
"code": 5110
},
"Option 'tsBuildInfoFile' cannot be specified without specifying option 'incremental' or 'composite' or if not running 'tsc -b'.": {
"category": "Error",
"code": 5111
},
"Generates a sourcemap for each corresponding '.d.ts' file.": {
"category": "Message",
@@ -5121,10 +5117,6 @@
"category": "Message",
"code": 6144
},
"Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified.": {
"category": "Message",
"code": 6145
},
"Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'.": {
"category": "Message",
"code": 6146
@@ -5696,14 +5688,6 @@
"category": "Message",
"code": 6361
},
"Skipping build of project '{0}' because its dependency '{1}' has errors": {
"category": "Message",
"code": 6362
},
"Project '{0}' can't be built because its dependency '{1}' has errors": {
"category": "Message",
"code": 6363
},
"Build one or more projects and their dependencies, if out of date": {
"category": "Message",
"code": 6364
@@ -5748,14 +5732,6 @@
"category": "Message",
"code": 6381
},
"Skipping build of project '{0}' because its dependency '{1}' was not built": {
"category": "Message",
"code": 6382
},
"Project '{0}' can't be built because its dependency '{1}' was not built": {
"category": "Message",
"code": 6383
},
"Have recompiles in '--incremental' and '--watch' assume that changes within a file will only affect files directly depending on it.": {
"category": "Message",
"code": 6384
@@ -5898,6 +5874,14 @@
"category": "Message",
"code": 6418
},
"Project '{0}' is out of date because buildinfo file '{1}' indicates that program needs to report errors.": {
"category": "Message",
"code": 6419
},
"Project '{0}' is out of date because {1}.": {
"category": "Message",
"code": 6420
},
"The expected type comes from property '{0}' which is declared here on type '{1}'": {
"category": "Message",
@@ -6400,6 +6384,10 @@
"category": "Message",
"code": 6804
},
"Disable full type checking (only critical parse and emit errors will be reported).": {
"category": "Message",
"code": 6805
},
"one of:": {
"category": "Message",
@@ -7026,6 +7014,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
@@ -7344,6 +7340,46 @@
"category": "Message",
"code": 90061
},
"Add annotation of type '{0}'": {
"category": "Message",
"code": 90062
},
"Add return type '{0}'": {
"category": "Message",
"code": 90063
},
"Extract base class to variable": {
"category": "Message",
"code": 90064
},
"Extract default export to variable": {
"category": "Message",
"code": 90065
},
"Extract binding expressions to variable": {
"category": "Message",
"code": 90066
},
"Add all missing type annotations": {
"category": "Message",
"code": 90067
},
"Add satisfies and an inline type assertion with '{0}'": {
"category": "Message",
"code": 90068
},
"Extract to variable and replace with '{0} as typeof {0}'": {
"category": "Message",
"code": 90069
},
"Mark array literal as const": {
"category": "Message",
"code": 90070
},
"Annotate types of properties expando function in a namespace": {
"category": "Message",
"code": 90071
},
"Convert function to an ES2015 class": {
"category": "Message",
@@ -8281,5 +8317,9 @@
"Enum member following a non-literal numeric member must have an initializer when 'isolatedModules' is enabled.": {
"category": "Error",
"code": 18056
},
"String literal import and export names are not supported when the '--module' flag is set to 'es2015' or 'es2020'.": {
"category": "Error",
"code": 18057
}
}
+197 -158
View File
@@ -1,4 +1,4 @@
import * as ts from "./_namespaces/ts";
import * as ts from "./_namespaces/ts.js";
import {
AccessorDeclaration,
ArrayBindingPattern,
@@ -21,6 +21,7 @@ import {
CallExpression,
CallSignatureDeclaration,
canHaveLocals,
canIncludeBindAndCheckDiagnostics,
CaseBlock,
CaseClause,
CaseOrDefaultClause,
@@ -130,7 +131,6 @@ import {
getEmitFlags,
getEmitHelpers,
getEmitModuleKind,
getEmitModuleResolutionKind,
getEmitScriptTarget,
getExternalModuleName,
getIdentifierTypeArguments,
@@ -207,6 +207,7 @@ import {
isGeneratedPrivateIdentifier,
isIdentifier,
isImportAttributes,
isImportEqualsDeclaration,
isIncrementalCompilation,
isInJsonFile,
isJSDocLikeText,
@@ -339,7 +340,6 @@ import {
PrinterOptions,
PrintHandlers,
PrivateIdentifier,
ProgramBuildInfo,
PropertyAccessExpression,
PropertyAssignment,
PropertyDeclaration,
@@ -419,9 +419,10 @@ import {
WithStatement,
writeCommentRange,
writeFile,
WriteFileCallbackData,
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();
@@ -451,17 +452,17 @@ export function forEachEmittedFile<T>(
) {
const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile, forceDtsEmit);
const options = host.getCompilerOptions();
if (options.outFile) {
if (sourceFiles.length) {
const bundle = factory.createBundle(sourceFiles);
const result = action(getOutputPathsFor(bundle, host, forceDtsEmit), bundle);
if (result) {
return result;
if (!onlyBuildInfo) {
if (options.outFile) {
if (sourceFiles.length) {
const bundle = factory.createBundle(sourceFiles);
const result = action(getOutputPathsFor(bundle, host, forceDtsEmit), bundle);
if (result) {
return result;
}
}
}
}
else {
if (!onlyBuildInfo) {
else {
for (const sourceFile of sourceFiles) {
const result = action(getOutputPathsFor(sourceFile, host, forceDtsEmit), sourceFile);
if (result) {
@@ -469,16 +470,16 @@ export function forEachEmittedFile<T>(
}
}
}
if (includeBuildInfo) {
const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options);
if (buildInfoPath) return action({ buildInfoPath }, /*sourceFileOrBundle*/ undefined);
}
}
if (includeBuildInfo) {
const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options);
if (buildInfoPath) return action({ buildInfoPath }, /*sourceFileOrBundle*/ undefined);
}
}
export function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions) {
const configFile = options.configFilePath;
if (!isIncrementalCompilation(options)) return undefined;
if (!canEmitTsBuildInfo(options)) return undefined;
if (options.tsBuildInfoFile) return options.tsBuildInfoFile;
const outPath = options.outFile;
let buildInfoExtensionLess: string;
@@ -498,14 +499,17 @@ export function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions) {
}
/** @internal */
export function getOutputPathsForBundle(options: CompilerOptions, forceDtsPaths: boolean): EmitFileNames {
export function canEmitTsBuildInfo(options: CompilerOptions) {
return isIncrementalCompilation(options) || !!options.tscBuild;
}
function getOutputPathsForBundle(options: CompilerOptions, forceDtsPaths: boolean): EmitFileNames {
const outPath = options.outFile!;
const jsFilePath = options.emitDeclarationOnly ? undefined : outPath;
const sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options);
const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(outPath) + Extension.Dts : undefined;
const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
const buildInfoPath = getTsBuildInfoEmitOutputFilePath(options);
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath };
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath };
}
/** @internal */
@@ -524,7 +528,7 @@ export function getOutputPathsFor(sourceFile: SourceFile | Bundle, host: EmitHos
const sourceMapFilePath = !jsFilePath || isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options);
const declarationFilePath = (forceDtsPaths || (getEmitDeclarations(options) && !isJsonFile)) ? getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined;
const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath: undefined };
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath };
}
}
@@ -533,7 +537,7 @@ function getSourceMapFilePath(jsFilePath: string, options: CompilerOptions) {
}
/** @internal */
export function getOutputExtension(fileName: string, options: CompilerOptions): Extension {
export function getOutputExtension(fileName: string, options: Pick<CompilerOptions, "jsx">): Extension {
return fileExtensionIs(fileName, Extension.Json) ? Extension.Json :
options.jsx === JsxEmit.Preserve && fileExtensionIsOneOf(fileName, [Extension.Jsx, Extension.Tsx]) ? Extension.Jsx :
fileExtensionIsOneOf(fileName, [Extension.Mts, Extension.Mjs]) ? Extension.Mjs :
@@ -599,12 +603,11 @@ function createAddOutput() {
}
function getSingleOutputFileNames(configFile: ParsedCommandLine, addOutput: ReturnType<typeof createAddOutput>["addOutput"]) {
const { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath } = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false);
const { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath } = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false);
addOutput(jsFilePath);
addOutput(sourceMapFilePath);
addOutput(declarationFilePath);
addOutput(declarationMapPath);
addOutput(buildInfoPath);
}
function getOwnOutputFileNames(configFile: ParsedCommandLine, inputFileName: string, ignoreCase: boolean, addOutput: ReturnType<typeof createAddOutput>["addOutput"], getCommonSourceDirectory?: () => string) {
@@ -677,8 +680,8 @@ export function getAllProjectOutputs(configFile: ParsedCommandLine, ignoreCase:
for (const inputFileName of configFile.fileNames) {
getOwnOutputFileNames(configFile, inputFileName, ignoreCase, addOutput, getCommonSourceDirectory);
}
addOutput(getTsBuildInfoEmitOutputFilePath(configFile.options));
}
addOutput(getTsBuildInfoEmitOutputFilePath(configFile.options));
return getOutputs();
}
@@ -717,9 +720,23 @@ 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 {
export function emitFiles(
resolver: EmitResolver,
host: EmitHost,
targetSourceFile: SourceFile | undefined,
{ scriptTransformers, declarationTransformers }: EmitTransformers,
emitOnly: boolean | EmitOnly | undefined,
onlyBuildInfo: boolean,
forceDtsEmit?: boolean,
skipBuildInfo?: boolean,
): EmitResult {
// 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 */
@@ -741,7 +758,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
getSourceFilesToEmit(host, targetSourceFile, forceDtsEmit),
forceDtsEmit,
onlyBuildInfo,
!targetSourceFile,
!targetSourceFile && !skipBuildInfo,
);
exit();
@@ -768,12 +785,12 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
function emitBuildInfo(buildInfoPath: string | undefined) {
// Write build information if applicable
if (!buildInfoPath || targetSourceFile || emitSkipped) return;
if (!buildInfoPath || targetSourceFile) return;
if (host.isEmitBlocked(buildInfoPath)) {
emitSkipped = true;
return;
}
const buildInfo = host.getBuildInfo() || createBuildInfo(/*program*/ undefined);
const buildInfo = host.getBuildInfo() || { version };
// Pass buildinfo as additional data to avoid having to reparse
writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText(buildInfo), /*writeByteOrderMark*/ false, /*sourceFiles*/ undefined, { buildInfo });
emittedFilesList?.push(buildInfoPath);
@@ -793,6 +810,16 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
emitSkipped = true;
return;
}
(isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : filter(sourceFileOrBundle.sourceFiles, isSourceFileNotJson)).forEach(
sourceFile => {
if (
compilerOptions.noCheck ||
!canIncludeBindAndCheckDiagnostics(sourceFile, compilerOptions)
) markLinkedReferences(sourceFile);
},
);
// Transform the source files
const transform = transformNodes(resolver, host, factory, compilerOptions, [sourceFileOrBundle], scriptTransformers, /*allowDtsFiles*/ false);
@@ -801,7 +828,6 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
newLine: compilerOptions.newLine,
noEmitHelpers: compilerOptions.noEmitHelpers,
module: getEmitModuleKind(compilerOptions),
moduleResolution: getEmitModuleResolutionKind(compilerOptions),
target: getEmitScriptTarget(compilerOptions),
sourceMap: compilerOptions.sourceMap,
inlineSourceMap: compilerOptions.inlineSourceMap,
@@ -848,11 +874,19 @@ 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)) {
// Checker wont collect the linked aliases since thats only done when declaration is enabled.
// Do that here when emitting only dts files
filesForEmit.forEach(collectLinkedAliases);
}
// 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(sourceFile => {
if (
(emitOnly && !getEmitDeclarations(compilerOptions)) ||
compilerOptions.noCheck ||
emitResolverSkipsTypeChecking(emitOnly, forceDtsEmit) ||
!canIncludeBindAndCheckDiagnostics(sourceFile, compilerOptions)
) {
collectLinkedAliases(sourceFile);
}
});
const declarationTransform = transformNodes(resolver, host, factory, compilerOptions, inputListOrBundle, declarationTransformers, /*allowDtsFiles*/ false);
if (length(declarationTransform.diagnostics)) {
for (const diagnostic of declarationTransform.diagnostics!) {
@@ -869,7 +903,6 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
newLine: compilerOptions.newLine,
noEmitHelpers: true,
module: compilerOptions.module,
moduleResolution: compilerOptions.moduleResolution,
target: compilerOptions.target,
sourceMap: !forceDtsEmit && compilerOptions.declarationMap,
inlineSourceMap: compilerOptions.inlineSourceMap,
@@ -887,7 +920,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
isEmitNotificationEnabled: declarationTransform.isEmitNotificationEnabled,
substituteNode: declarationTransform.substituteNode,
});
printSourceFileOrBundle(
const dtsWritten = printSourceFileOrBundle(
declarationFilePath,
declarationMapPath,
declarationTransform,
@@ -901,7 +934,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
},
);
if (emittedFilesList) {
emittedFilesList.push(declarationFilePath);
if (dtsWritten) emittedFilesList.push(declarationFilePath);
if (declarationMapPath) {
emittedFilesList.push(declarationMapPath);
}
@@ -924,6 +957,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<SourceFile | Bundle>, printer: Printer, mapOptions: SourceMapOptions) {
const sourceFileOrBundle = transform.transformed[0];
const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined;
@@ -983,10 +1024,12 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
// Write the output file
const text = writer.getText();
writeFile(host, emitterDiagnostics, jsFilePath, text, !!compilerOptions.emitBOM, sourceFiles, { sourceMapUrlPos, diagnostics: transform.diagnostics });
const data: WriteFileCallbackData = { sourceMapUrlPos, diagnostics: transform.diagnostics };
writeFile(host, emitterDiagnostics, jsFilePath, text, !!compilerOptions.emitBOM, sourceFiles, data);
// Reset state
writer.clear();
return !data.skippedDtsWrite;
}
interface SourceMapOptions {
@@ -1065,11 +1108,6 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
}
}
/** @internal */
export function createBuildInfo(program: ProgramBuildInfo | undefined): BuildInfo {
return { program, version };
}
/** @internal */
export function getBuildInfoText(buildInfo: BuildInfo) {
return JSON.stringify(buildInfo);
@@ -1090,10 +1128,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,12 +1153,12 @@ export const notImplementedResolver: EmitResolver = {
isArgumentsLocalBinding: notImplemented,
getExternalModuleFileFromDeclaration: notImplemented,
isLiteralConstDeclaration: notImplemented,
isNonNarrowedBindableName: notImplemented,
getJsxFactoryEntity: notImplemented,
getJsxFragmentFactoryEntity: notImplemented,
isBindingCapturedByNode: notImplemented,
getDeclarationStatementsForSourceFile: notImplemented,
isImportRequiredByAugmentation: notImplemented,
isDefinitelyReferenceToGlobalSymbolObject: notImplemented,
};
const enum PipelinePhase {
@@ -2049,7 +2088,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
// SyntaxKind.TemplateMiddle
// SyntaxKind.TemplateTail
function emitLiteral(node: LiteralLikeNode, jsxAttributeEscape: boolean) {
const text = getLiteralTextOfNode(node, printerOptions.neverAsciiEscape, jsxAttributeEscape);
const text = getLiteralTextOfNode(node, /*sourceFile*/ undefined, printerOptions.neverAsciiEscape, jsxAttributeEscape);
if (
(printerOptions.sourceMap || printerOptions.inlineSourceMap)
&& (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))
@@ -2125,13 +2164,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 +2233,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 +2244,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 +2266,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 +2319,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 +2357,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 +2371,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 +2588,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 +2604,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
decreaseIndent();
}
popPrivateNameGenerationScope();
popNameGenerationScope(node);
}
function emitPropertyAccessExpression(node: PropertyAccessExpression) {
@@ -2624,7 +2641,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
expression = skipPartiallyEmittedExpressions(expression);
if (isNumericLiteral(expression)) {
// check if numeric literal is a decimal literal that was originally written with a dot
const text = getLiteralTextOfNode(expression as LiteralExpression, /*neverAsciiEscape*/ true, /*jsxAttributeEscape*/ false);
const text = getLiteralTextOfNode(expression as LiteralExpression, /*sourceFile*/ undefined, /*neverAsciiEscape*/ true, /*jsxAttributeEscape*/ false);
// If the number will be printed verbatim and it doesn't already contain a dot or an exponent indicator, add one
// if the expression doesn't have any comments that will be emitted.
return !(expression.numericLiteralFlags & TokenFlags.WithSpecifier)
@@ -2714,7 +2731,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 +2742,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 +3332,40 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emit(node.asteriskToken);
writeSpace();
emitIdentifierName(node.name);
emitSignatureAndBody(node, emitSignatureHead);
emitSignatureAndBody(node, emitSignatureHead, emitFunctionBody);
}
function emitSignatureAndBody<T extends FunctionLikeDeclaration>(node: T, emitSignatureHead: (node: T) => void) {
function emitSignatureAndBody<T extends SignatureDeclaration>(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);
emitSignatureHead(node);
emitBody(node);
popNameGenerationScope(node);
if (indentedFlag) {
decreaseIndent();
}
}
function emitFunctionBody<T extends Exclude<FunctionLikeDeclaration, ArrowFunction>>(node: T) {
const body = node.body;
if (body) {
if (isBlock(body)) {
const indentedFlag = getEmitFlags(node) & EmitFlags.Indented;
if (indentedFlag) {
increaseIndent();
}
pushNameGenerationScope(node);
forEach(node.parameters, generateNames);
generateNames(node.body);
emitSignatureHead(node);
emitBlockFunctionBody(body);
popNameGenerationScope(node);
if (indentedFlag) {
decreaseIndent();
}
}
else {
emitSignatureHead(node);
writeSpace();
emitExpression(body, parenthesizer.parenthesizeConciseBodyOfArrowFunction);
}
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 +3413,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
}
function emitBlockFunctionBody(body: Block) {
generateNames(body);
onBeforeEmitNode?.(body);
writeSpace();
writePunctuation("{");
@@ -3428,10 +3454,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 +3468,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 +3492,13 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emitList(node, node.heritageClauses, ListFormat.HeritageClauses);
writeSpace();
writePunctuation("{");
emitList(node, node.members, ListFormat.InterfaceMembers);
writePunctuation("}");
popPrivateNameGenerationScope();
pushNameGenerationScope(node);
forEach(node.members, generateMemberNames);
emitList(node, node.members, ListFormat.InterfaceMembers);
popNameGenerationScope(node);
writePunctuation("}");
}
function emitTypeAliasDeclaration(node: TypeAliasDeclaration) {
@@ -4488,7 +4511,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
emitList(parentNode, parameters, ListFormat.Parameters);
}
function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray<ParameterDeclaration>) {
function canEmitSimpleArrowHead(parentNode: FunctionTypeNode | ConstructorTypeNode | ArrowFunction, parameters: NodeArray<ParameterDeclaration>) {
const parameter = singleOrUndefined(parameters);
return parameter
&& parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter
@@ -4504,7 +4527,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
&& isIdentifier(parameter.name); // parameter name must be identifier
}
function emitParametersForArrow(parentNode: FunctionTypeNode | ArrowFunction, parameters: NodeArray<ParameterDeclaration>) {
function emitParametersForArrow(parentNode: FunctionTypeNode | ConstructorTypeNode | ArrowFunction, parameters: NodeArray<ParameterDeclaration>) {
if (canEmitSimpleArrowHead(parentNode, parameters)) {
emitList(parentNode, parameters, ListFormat.Parameters & ~ListFormat.Parenthesis);
}
@@ -5146,7 +5169,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
return getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia);
}
function getLiteralTextOfNode(node: LiteralLikeNode, neverAsciiEscape: boolean | undefined, jsxAttributeEscape: boolean): string {
function getLiteralTextOfNode(node: LiteralLikeNode, sourceFile = currentSourceFile, neverAsciiEscape: boolean | undefined, jsxAttributeEscape: boolean): string {
if (node.kind === SyntaxKind.StringLiteral && (node as StringLiteral).textSourceNode) {
const textSourceNode = (node as StringLiteral).textSourceNode!;
if (isIdentifier(textSourceNode) || isPrivateIdentifier(textSourceNode) || isNumericLiteral(textSourceNode) || isJsxNamespacedName(textSourceNode)) {
@@ -5156,7 +5179,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
`"${escapeNonAsciiString(text)}"`;
}
else {
return getLiteralTextOfNode(textSourceNode, neverAsciiEscape, jsxAttributeEscape);
return getLiteralTextOfNode(textSourceNode, getSourceFileOfNode(textSourceNode), neverAsciiEscape, jsxAttributeEscape);
}
}
@@ -5165,16 +5188,21 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
| (printerOptions.terminateUnterminatedLiterals ? GetLiteralTextFlags.TerminateUnterminatedLiterals : 0)
| (printerOptions.target && printerOptions.target >= ScriptTarget.ES2021 ? GetLiteralTextFlags.AllowNumericSeparator : 0);
return getLiteralText(node, currentSourceFile, flags);
return getLiteralText(node, sourceFile, flags);
}
/**
* 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 +5214,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 +5233,6 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri
reservedNames.add(name);
}
/**
* Push a new member name generation scope.
*/
function pushPrivateNameGenerationScope(newPrivateNameTempFlags: TempFlags, newReservedMemberNames: Set<string> | 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 +5332,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 +5388,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<string> | undefined;
let stack: (Set<string> | 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;
}
/**
+2 -2
View File
@@ -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;
+13 -23
View File
@@ -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) && !resolver.isDefinitelyReferenceToGlobalSymbolObject(expression)) {
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 => {
+1 -1
View File
@@ -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
+47 -74
View File
@@ -35,7 +35,7 @@ import {
TextRange,
TransformationContext,
UnscopedEmitHelper,
} from "../_namespaces/ts";
} from "../_namespaces/ts.js";
/** @internal */
export const enum PrivateIdentifierKind {
@@ -696,10 +696,8 @@ export function compareEmitHelpers(x: EmitHelper, y: EmitHelper) {
/**
* @param input Template string input strings
* @param args Names which need to be made file-level unique
*
* @internal
*/
export function helperString(input: TemplateStringsArray, ...args: string[]) {
function helperString(input: TemplateStringsArray, ...args: string[]) {
return (uniqueName: EmitHelperUniqueNameCallback) => {
let result = "";
for (let i = 0; i < args.length; i++) {
@@ -713,8 +711,7 @@ export function helperString(input: TemplateStringsArray, ...args: string[]) {
// TypeScript Helpers
/** @internal */
export const decorateHelper: UnscopedEmitHelper = {
const decorateHelper: UnscopedEmitHelper = {
name: "typescript:decorate",
importName: "__decorate",
scoped: false,
@@ -728,8 +725,7 @@ export const decorateHelper: UnscopedEmitHelper = {
};`,
};
/** @internal */
export const metadataHelper: UnscopedEmitHelper = {
const metadataHelper: UnscopedEmitHelper = {
name: "typescript:metadata",
importName: "__metadata",
scoped: false,
@@ -740,8 +736,7 @@ export const metadataHelper: UnscopedEmitHelper = {
};`,
};
/** @internal */
export const paramHelper: UnscopedEmitHelper = {
const paramHelper: UnscopedEmitHelper = {
name: "typescript:param",
importName: "__param",
scoped: false,
@@ -753,8 +748,7 @@ export const paramHelper: UnscopedEmitHelper = {
};
// ES Decorators Helpers
/** @internal */
export const esDecorateHelper: UnscopedEmitHelper = {
const esDecorateHelper: UnscopedEmitHelper = {
name: "typescript:esDecorate",
importName: "__esDecorate",
scoped: false,
@@ -789,8 +783,7 @@ export const esDecorateHelper: UnscopedEmitHelper = {
};`,
};
/** @internal */
export const runInitializersHelper: UnscopedEmitHelper = {
const runInitializersHelper: UnscopedEmitHelper = {
name: "typescript:runInitializers",
importName: "__runInitializers",
scoped: false,
@@ -807,8 +800,7 @@ export const runInitializersHelper: UnscopedEmitHelper = {
// ES2018 Helpers
/** @internal */
export const assignHelper: UnscopedEmitHelper = {
const assignHelper: UnscopedEmitHelper = {
name: "typescript:assign",
importName: "__assign",
scoped: false,
@@ -827,8 +819,7 @@ export const assignHelper: UnscopedEmitHelper = {
};`,
};
/** @internal */
export const awaitHelper: UnscopedEmitHelper = {
const awaitHelper: UnscopedEmitHelper = {
name: "typescript:await",
importName: "__await",
scoped: false,
@@ -836,8 +827,7 @@ export const awaitHelper: UnscopedEmitHelper = {
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }`,
};
/** @internal */
export const asyncGeneratorHelper: UnscopedEmitHelper = {
const asyncGeneratorHelper: UnscopedEmitHelper = {
name: "typescript:asyncGenerator",
importName: "__asyncGenerator",
scoped: false,
@@ -857,8 +847,7 @@ export const asyncGeneratorHelper: UnscopedEmitHelper = {
};`,
};
/** @internal */
export const asyncDelegator: UnscopedEmitHelper = {
const asyncDelegator: UnscopedEmitHelper = {
name: "typescript:asyncDelegator",
importName: "__asyncDelegator",
scoped: false,
@@ -871,8 +860,7 @@ export const asyncDelegator: UnscopedEmitHelper = {
};`,
};
/** @internal */
export const asyncValues: UnscopedEmitHelper = {
const asyncValues: UnscopedEmitHelper = {
name: "typescript:asyncValues",
importName: "__asyncValues",
scoped: false,
@@ -888,8 +876,7 @@ export const asyncValues: UnscopedEmitHelper = {
// ES2018 Destructuring Helpers
/** @internal */
export const restHelper: UnscopedEmitHelper = {
const restHelper: UnscopedEmitHelper = {
name: "typescript:rest",
importName: "__rest",
scoped: false,
@@ -909,8 +896,7 @@ export const restHelper: UnscopedEmitHelper = {
// ES2017 Helpers
/** @internal */
export const awaiterHelper: UnscopedEmitHelper = {
const awaiterHelper: UnscopedEmitHelper = {
name: "typescript:awaiter",
importName: "__awaiter",
scoped: false,
@@ -929,8 +915,7 @@ export const awaiterHelper: UnscopedEmitHelper = {
// ES2015 Helpers
/** @internal */
export const extendsHelper: UnscopedEmitHelper = {
const extendsHelper: UnscopedEmitHelper = {
name: "typescript:extends",
importName: "__extends",
scoped: false,
@@ -954,8 +939,7 @@ export const extendsHelper: UnscopedEmitHelper = {
})();`,
};
/** @internal */
export const templateObjectHelper: UnscopedEmitHelper = {
const templateObjectHelper: UnscopedEmitHelper = {
name: "typescript:makeTemplateObject",
importName: "__makeTemplateObject",
scoped: false,
@@ -967,8 +951,7 @@ export const templateObjectHelper: UnscopedEmitHelper = {
};`,
};
/** @internal */
export const readHelper: UnscopedEmitHelper = {
const readHelper: UnscopedEmitHelper = {
name: "typescript:read",
importName: "__read",
scoped: false,
@@ -991,8 +974,7 @@ export const readHelper: UnscopedEmitHelper = {
};`,
};
/** @internal */
export const spreadArrayHelper: UnscopedEmitHelper = {
const spreadArrayHelper: UnscopedEmitHelper = {
name: "typescript:spreadArray",
importName: "__spreadArray",
scoped: false,
@@ -1008,8 +990,7 @@ export const spreadArrayHelper: UnscopedEmitHelper = {
};`,
};
/** @internal */
export const propKeyHelper: UnscopedEmitHelper = {
const propKeyHelper: UnscopedEmitHelper = {
name: "typescript:propKey",
importName: "__propKey",
scoped: false,
@@ -1020,8 +1001,7 @@ export const propKeyHelper: UnscopedEmitHelper = {
};
// https://tc39.es/ecma262/#sec-setfunctionname
/** @internal */
export const setFunctionNameHelper: UnscopedEmitHelper = {
const setFunctionNameHelper: UnscopedEmitHelper = {
name: "typescript:setFunctionName",
importName: "__setFunctionName",
scoped: false,
@@ -1034,8 +1014,7 @@ export const setFunctionNameHelper: UnscopedEmitHelper = {
// ES2015 Destructuring Helpers
/** @internal */
export const valuesHelper: UnscopedEmitHelper = {
const valuesHelper: UnscopedEmitHelper = {
name: "typescript:values",
importName: "__values",
scoped: false,
@@ -1116,8 +1095,7 @@ export const valuesHelper: UnscopedEmitHelper = {
// entering a finally block.
//
// For examples of how these are used, see the comments in ./transformers/generators.ts
/** @internal */
export const generatorHelper: UnscopedEmitHelper = {
const generatorHelper: UnscopedEmitHelper = {
name: "typescript:generator",
importName: "__generator",
scoped: false,
@@ -1154,8 +1132,7 @@ export const generatorHelper: UnscopedEmitHelper = {
// ES Module Helpers
/** @internal */
export const createBindingHelper: UnscopedEmitHelper = {
const createBindingHelper: UnscopedEmitHelper = {
name: "typescript:commonjscreatebinding",
importName: "__createBinding",
scoped: false,
@@ -1174,8 +1151,7 @@ export const createBindingHelper: UnscopedEmitHelper = {
}));`,
};
/** @internal */
export const setModuleDefaultHelper: UnscopedEmitHelper = {
const setModuleDefaultHelper: UnscopedEmitHelper = {
name: "typescript:commonjscreatevalue",
importName: "__setModuleDefault",
scoped: false,
@@ -1189,8 +1165,7 @@ export const setModuleDefaultHelper: UnscopedEmitHelper = {
};
// emit helper for `import * as Name from "foo"`
/** @internal */
export const importStarHelper: UnscopedEmitHelper = {
const importStarHelper: UnscopedEmitHelper = {
name: "typescript:commonjsimportstar",
importName: "__importStar",
scoped: false,
@@ -1207,8 +1182,7 @@ export const importStarHelper: UnscopedEmitHelper = {
};
// emit helper for `import Name from "foo"`
/** @internal */
export const importDefaultHelper: UnscopedEmitHelper = {
const importDefaultHelper: UnscopedEmitHelper = {
name: "typescript:commonjsimportdefault",
importName: "__importDefault",
scoped: false,
@@ -1218,8 +1192,7 @@ export const importDefaultHelper: UnscopedEmitHelper = {
};`,
};
/** @internal */
export const exportStarHelper: UnscopedEmitHelper = {
const exportStarHelper: UnscopedEmitHelper = {
name: "typescript:export-star",
importName: "__exportStar",
scoped: false,
@@ -1278,10 +1251,8 @@ export const exportStarHelper: UnscopedEmitHelper = {
*
* Reading from a private static method (TS 4.3+):
* __classPrivateFieldGet(<any>, <constructor>, "m", <function>)
*
* @internal
*/
export const classPrivateFieldGetHelper: UnscopedEmitHelper = {
const classPrivateFieldGetHelper: UnscopedEmitHelper = {
name: "typescript:classPrivateFieldGet",
importName: "__classPrivateFieldGet",
scoped: false,
@@ -1343,10 +1314,8 @@ export const classPrivateFieldGetHelper: UnscopedEmitHelper = {
* Writing to a private static method (TS 4.3+):
* __classPrivateFieldSet(<any>, <constructor>, <any>, "m", <function>)
* NOTE: This always results in a runtime error.
*
* @internal
*/
export const classPrivateFieldSetHelper: UnscopedEmitHelper = {
const classPrivateFieldSetHelper: UnscopedEmitHelper = {
name: "typescript:classPrivateFieldSet",
importName: "__classPrivateFieldSet",
scoped: false,
@@ -1370,10 +1339,8 @@ export const classPrivateFieldSetHelper: UnscopedEmitHelper = {
* Usage:
* This helper is used to transform `#field in expression` to
* `__classPrivateFieldIn(<weakMap/weakSet/constructor>, expression)`
*
* @internal
*/
export const classPrivateFieldInHelper: UnscopedEmitHelper = {
const classPrivateFieldInHelper: UnscopedEmitHelper = {
name: "typescript:classPrivateFieldIn",
importName: "__classPrivateFieldIn",
scoped: false,
@@ -1384,10 +1351,7 @@ export const classPrivateFieldInHelper: UnscopedEmitHelper = {
};`,
};
/**
* @internal
*/
export const addDisposableResourceHelper: UnscopedEmitHelper = {
const addDisposableResourceHelper: UnscopedEmitHelper = {
name: "typescript:addDisposableResource",
importName: "__addDisposableResource",
scoped: false,
@@ -1395,7 +1359,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 +1367,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) {
@@ -1415,9 +1381,11 @@ export const addDisposableResourceHelper: UnscopedEmitHelper = {
};
/**
* @internal
* The `s` variable represents two boolean flags from the `DisposeResources` algorithm:
* - `needsAwait` (`1`) — Indicates that an `await using` for a `null` or `undefined` resource was encountered.
* - `hasAwaited` (`2`) — Indicates that the algorithm has performed an Await.
*/
export const disposeResourcesHelper: UnscopedEmitHelper = {
const disposeResourcesHelper: UnscopedEmitHelper = {
name: "typescript:disposeResources",
importName: "__disposeResources",
scoped: false,
@@ -1428,17 +1396,22 @@ export const disposeResourcesHelper: UnscopedEmitHelper = {
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
env.hasError = true;
}
var r, s = 0;
function next() {
while (env.stack.length) {
var rec = env.stack.pop();
while (r = env.stack.pop()) {
try {
var result = rec.dispose && rec.dispose.call(rec.value);
if (rec.async) return Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
if (r.dispose) {
var result = r.dispose.call(r.value);
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
}
else s |= 1;
}
catch (e) {
fail(e);
}
}
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
if (env.hasError) throw env.error;
}
return next();
+2 -2
View File
@@ -26,7 +26,7 @@ import {
TextRange,
TypeNode,
TypeParameterDeclaration,
} from "../_namespaces/ts";
} from "../_namespaces/ts.js";
/**
* Associates a node with the current transformation, initializing
@@ -364,7 +364,7 @@ export function setIdentifierAutoGenerate<T extends Identifier | PrivateIdentifi
return node;
}
/** @internal */
/** @internal @knipignore */
export function getIdentifierAutoGenerate(node: Identifier | PrivateIdentifier): AutoGenerateInfo | undefined {
return node.emitNode?.autoGenerate;
}
+45 -9
View File
@@ -1,25 +1,61 @@
import {
Debug,
emptyArray,
isNodeKind,
Node,
} from "../_namespaces/ts";
SourceFileLike,
SyntaxKind,
SyntaxList,
} from "../_namespaces/ts.js";
const nodeChildren = new WeakMap<Node, readonly Node[] | undefined>();
const sourceFileToNodeChildren = new WeakMap<SourceFileLike, WeakMap<Node, readonly Node[] | undefined>>();
/** @internal */
export function getNodeChildren(node: Node): readonly Node[] | undefined {
if (!isNodeKind(node.kind)) return emptyArray;
export function getNodeChildren(node: Node, sourceFile: SourceFileLike): readonly Node[] | undefined {
const kind = node.kind;
if (!isNodeKind(kind)) {
return emptyArray;
}
if (kind === SyntaxKind.SyntaxList) {
return (node as SyntaxList)._children;
}
return nodeChildren.get(node);
return sourceFileToNodeChildren.get(sourceFile)?.get(node);
}
/** @internal */
export function setNodeChildren(node: Node, children: readonly Node[]): readonly Node[] {
nodeChildren.set(node, children);
export function setNodeChildren(node: Node, sourceFile: SourceFileLike, children: readonly Node[]): readonly Node[] {
if (node.kind === SyntaxKind.SyntaxList) {
// SyntaxList children are always eagerly created in the process of
// creating their parent's `children` list. We shouldn't need to set them here.
Debug.fail("Should not need to re-set the children of a SyntaxList.");
}
let map = sourceFileToNodeChildren.get(sourceFile);
if (map === undefined) {
map = new WeakMap();
sourceFileToNodeChildren.set(sourceFile, map);
}
map.set(node, children);
return children;
}
/** @internal */
export function unsetNodeChildren(node: Node) {
nodeChildren.delete(node);
export function unsetNodeChildren(node: Node, origSourceFile: SourceFileLike) {
if (node.kind === SyntaxKind.SyntaxList) {
// Syntax lists are synthesized and we store their children directly on them.
// They are a special case where we expect incremental parsing to toss them away entirely
// if a change intersects with their containing parents.
Debug.fail("Did not expect to unset the children of a SyntaxList.");
}
sourceFileToNodeChildren.get(origSourceFile)?.delete(node);
}
/** @internal */
export function transferSourceFileChildren(sourceFile: SourceFileLike, targetSourceFile: SourceFileLike) {
const map = sourceFileToNodeChildren.get(sourceFile);
if (map !== undefined) {
sourceFileToNodeChildren.delete(sourceFile);
sourceFileToNodeChildren.set(targetSourceFile, map);
}
}
+1 -1
View File
@@ -35,7 +35,7 @@ import {
setStartsOnNewLine,
setTextRange,
SyntaxKind,
} from "../_namespaces/ts";
} from "../_namespaces/ts.js";
/** @internal */
export function createNodeConverters(factory: NodeFactory): NodeConverters {
+11 -13
View File
@@ -309,6 +309,7 @@ import {
ModuleBlock,
ModuleBody,
ModuleDeclaration,
ModuleExportName,
ModuleName,
ModuleReference,
Mutable,
@@ -387,7 +388,6 @@ import {
setEmitFlags,
setIdentifierAutoGenerate,
setIdentifierTypeArguments,
setNodeChildren,
setParent,
setTextRange,
ShorthandPropertyAssignment,
@@ -456,7 +456,7 @@ import {
WhileStatement,
WithStatement,
YieldExpression,
} from "../_namespaces/ts";
} from "../_namespaces/ts.js";
let nextAutoGenerateId = 0;
@@ -475,7 +475,7 @@ export const enum NodeFactoryFlags {
const nodeFactoryPatchers: ((factory: NodeFactory) => void)[] = [];
/** @internal */
/** @internal @knipignore */
export function addNodeFactoryPatcher(fn: (factory: NodeFactory) => void) {
nodeFactoryPatchers.push(fn);
}
@@ -4842,7 +4842,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
}
// @api
function createNamespaceExport(name: Identifier): NamespaceExport {
function createNamespaceExport(name: ModuleExportName): NamespaceExport {
const node = createBaseDeclaration<NamespaceExport>(SyntaxKind.NamespaceExport);
node.name = name;
node.transformFlags |= propagateChildFlags(node.name) |
@@ -4852,7 +4852,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
}
// @api
function updateNamespaceExport(node: NamespaceExport, name: Identifier) {
function updateNamespaceExport(node: NamespaceExport, name: ModuleExportName) {
return node.name !== name
? update(createNamespaceExport(name), node)
: node;
@@ -4875,7 +4875,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
}
// @api
function createImportSpecifier(isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) {
function createImportSpecifier(isTypeOnly: boolean, propertyName: ModuleExportName | undefined, name: Identifier) {
const node = createBaseDeclaration<ImportSpecifier>(SyntaxKind.ImportSpecifier);
node.isTypeOnly = isTypeOnly;
node.propertyName = propertyName;
@@ -4887,7 +4887,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
}
// @api
function updateImportSpecifier(node: ImportSpecifier, isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) {
function updateImportSpecifier(node: ImportSpecifier, isTypeOnly: boolean, propertyName: ModuleExportName | undefined, name: Identifier) {
return node.isTypeOnly !== isTypeOnly
|| node.propertyName !== propertyName
|| node.name !== name
@@ -4994,7 +4994,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
}
// @api
function createExportSpecifier(isTypeOnly: boolean, propertyName: string | Identifier | undefined, name: string | Identifier) {
function createExportSpecifier(isTypeOnly: boolean, propertyName: string | ModuleExportName | undefined, name: string | ModuleExportName) {
const node = createBaseNode<ExportSpecifier>(SyntaxKind.ExportSpecifier);
node.isTypeOnly = isTypeOnly;
node.propertyName = asName(propertyName);
@@ -5008,7 +5008,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
}
// @api
function updateExportSpecifier(node: ExportSpecifier, isTypeOnly: boolean, propertyName: Identifier | undefined, name: Identifier) {
function updateExportSpecifier(node: ExportSpecifier, isTypeOnly: boolean, propertyName: ModuleExportName | undefined, name: ModuleExportName) {
return node.isTypeOnly !== isTypeOnly
|| node.propertyName !== propertyName
|| node.name !== name
@@ -6211,7 +6211,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode
// @api
function createSyntaxList(children: readonly Node[]) {
const node = createBaseNode<SyntaxList>(SyntaxKind.SyntaxList);
setNodeChildren(node, children);
node._children = children;
return node;
}
@@ -7294,10 +7294,8 @@ function aggregateChildrenFlags(children: MutableNodeArray<Node>) {
/**
* Gets the transform flags to exclude when unioning the transform flags of a subtree.
*
* @internal
*/
export function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) {
function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) {
if (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) {
return TransformFlags.TypeExcludes;
}
+6 -1
View File
@@ -146,6 +146,7 @@ import {
MissingDeclaration,
ModuleBlock,
ModuleDeclaration,
ModuleExportName,
NamedExports,
NamedImports,
NamedTupleMember,
@@ -227,7 +228,7 @@ import {
WhileStatement,
WithStatement,
YieldExpression,
} from "../_namespaces/ts";
} from "../_namespaces/ts.js";
// Literals
@@ -898,6 +899,10 @@ export function isExportSpecifier(node: Node): node is ExportSpecifier {
return node.kind === SyntaxKind.ExportSpecifier;
}
export function isModuleExportName(node: Node): node is ModuleExportName {
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.StringLiteral;
}
export function isMissingDeclaration(node: Node): node is MissingDeclaration {
return node.kind === SyntaxKind.MissingDeclaration;
}
+1 -1
View File
@@ -48,7 +48,7 @@ import {
SyntaxKind,
TypeNode,
UnaryExpression,
} from "../_namespaces/ts";
} from "../_namespaces/ts.js";
/** @internal */
export function createParenthesizerRules(factory: NodeFactory): ParenthesizerRules {
+10 -49
View File
@@ -17,8 +17,6 @@ import {
BindingOrAssignmentPattern,
BitwiseOperator,
BitwiseOperatorOrHigher,
Block,
BooleanLiteral,
CharacterCodes,
CommaListExpression,
compareStringsCaseSensitive,
@@ -53,12 +51,10 @@ import {
getAllAccessorDeclarations,
getEmitFlags,
getEmitHelpers,
getEmitModuleFormatOfFileWorker,
getEmitModuleKind,
getESModuleInterop,
getExternalModuleName,
getExternalModuleNameFromPath,
getImpliedNodeFormatForEmitWorker,
getJSDocType,
getJSDocTypeTag,
getModifiers,
@@ -80,7 +76,6 @@ import {
isAssignmentExpression,
isAssignmentOperator,
isAssignmentPattern,
isBlock,
isCommaListExpression,
isComputedPropertyName,
isDeclarationBindingElement,
@@ -93,10 +88,8 @@ import {
isGeneratedPrivateIdentifier,
isIdentifier,
isInJSFile,
isLiteralExpression,
isMemberName,
isMinusToken,
isModifierKind,
isObjectLiteralElementLike,
isParenthesizedExpression,
isPlusToken,
@@ -141,7 +134,6 @@ import {
NodeArray,
NodeFactory,
nodeIsSynthesized,
NullLiteral,
NumericLiteral,
ObjectLiteralElementLike,
ObjectLiteralExpression,
@@ -180,7 +172,7 @@ import {
TransformFlags,
TypeNode,
WrappedExpression,
} from "../_namespaces/ts";
} from "../_namespaces/ts.js";
// Compound nodes
@@ -335,16 +327,6 @@ export function createForOfBindingStatement(factory: NodeFactory, node: ForIniti
}
}
/** @internal */
export function insertLeadingStatement(factory: NodeFactory, dest: Statement, source: Statement): Block {
if (isBlock(dest)) {
return factory.updateBlock(dest, setTextRange(factory.createNodeArray([source, ...dest.statements]), dest.statements));
}
else {
return factory.createBlock(factory.createNodeArray([dest, source]), /*multiLine*/ true);
}
}
/** @internal */
export function createExpressionFromEntityName(factory: NodeFactory, node: EntityName | Expression): Expression {
if (isQualifiedName(node)) {
@@ -681,15 +663,6 @@ export function walkUpOuterExpressions(node: Expression, kinds = OuterExpression
return parent;
}
/** @internal */
export function skipAssertions(node: Expression): Expression;
/** @internal */
export function skipAssertions(node: Node): Node;
/** @internal */
export function skipAssertions(node: Node): Node {
return skipOuterExpressions(node, OuterExpressionKinds.Assertions);
}
/** @internal */
export function startOnNewLine<T extends Node>(node: T): T {
return setStartsOnNewLine(node, /*newLine*/ true);
@@ -714,7 +687,7 @@ export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: Node
if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) {
let namedBindings: NamedImportBindings | undefined;
const moduleKind = getEmitModuleKind(compilerOptions);
if ((moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) || getImpliedNodeFormatForEmitWorker(sourceFile, compilerOptions) === ModuleKind.ESNext) {
if ((moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext) || sourceFile.impliedNodeFormat === ModuleKind.ESNext) {
// use named imports
const helpers = getEmitHelpers(sourceFile);
if (helpers) {
@@ -763,16 +736,17 @@ export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: Node
}
}
/** @internal */
export function getOrCreateExternalHelpersModuleNameIfNeeded(factory: NodeFactory, node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) {
function getOrCreateExternalHelpersModuleNameIfNeeded(factory: NodeFactory, node: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStarOrImportDefault?: boolean) {
if (compilerOptions.importHelpers && isEffectiveExternalModule(node, compilerOptions)) {
const externalHelpersModuleName = getExternalHelpersModuleName(node);
if (externalHelpersModuleName) {
return externalHelpersModuleName;
}
const moduleKind = getEmitModuleKind(compilerOptions);
let create = (hasExportStarsToExportValues || (getESModuleInterop(compilerOptions) && hasImportStarOrImportDefault))
&& getEmitModuleFormatOfFileWorker(node, compilerOptions) < ModuleKind.System;
&& moduleKind !== ModuleKind.System
&& (moduleKind < ModuleKind.ES2015 || node.impliedNodeFormat === ModuleKind.CommonJS);
if (!create) {
const helpers = getEmitHelpers(node);
if (helpers) {
@@ -802,6 +776,9 @@ export function getLocalNameForExternalImport(factory: NodeFactory, node: Import
const namespaceDeclaration = getNamespaceDeclarationNode(node);
if (namespaceDeclaration && !isDefaultImport(node) && !isExportNamespaceAsDefaultDeclaration(node)) {
const name = namespaceDeclaration.name;
if (name.kind === SyntaxKind.StringLiteral) {
return factory.getGeneratedNameForNode(node);
}
return isGeneratedIdentifier(name) ? name : factory.createIdentifier(getSourceTextOfNodeFromSourceFile(sourceFile, name) || idText(name));
}
if (node.kind === SyntaxKind.ImportDeclaration && node.importClause) {
@@ -1113,7 +1090,7 @@ export function getJSDocTypeAliasName(fullName: JSDocNamespaceBody | undefined)
}
}
/** @internal */
/** @internal @knipignore */
export function canHaveIllegalType(node: Node): node is HasIllegalType {
const kind = node.kind;
return kind === SyntaxKind.Constructor
@@ -1180,16 +1157,6 @@ export function isModuleName(node: Node): node is ModuleName {
return isIdentifier(node) || isStringLiteral(node);
}
/** @internal */
export function isLiteralTypeLikeExpression(node: Node): node is NullLiteral | BooleanLiteral | LiteralExpression | PrefixUnaryExpression {
const kind = node.kind;
return kind === SyntaxKind.NullKeyword
|| kind === SyntaxKind.TrueKeyword
|| kind === SyntaxKind.FalseKeyword
|| isLiteralExpression(node)
|| isPrefixUnaryExpression(node);
}
function isExponentiationOperator(kind: SyntaxKind): kind is ExponentiationOperator {
return kind === SyntaxKind.AsteriskAsteriskToken;
}
@@ -1518,12 +1485,6 @@ export function isExportOrDefaultModifier(node: Node): node is ExportKeyword | D
return isExportOrDefaultKeywordKind(kind);
}
/** @internal */
export function isNonExportDefaultModifier(node: Node): node is Exclude<Modifier, ExportKeyword | DefaultKeyword> {
const kind = node.kind;
return isModifierKind(kind) && !isExportOrDefaultKeywordKind(kind);
}
/**
* If `nodes` is not undefined, creates an empty `NodeArray` that preserves the `pos` and `end` of `nodes`.
* @internal
+1 -1
View File
@@ -5,7 +5,7 @@ import {
setTextRangePosEnd,
SyntaxKind,
TextRange,
} from "../_namespaces/ts";
} from "../_namespaces/ts.js";
export function setTextRange<T extends TextRange>(range: T, location: TextRange | undefined): T {
return location ? setTextRangePosEnd(range, location.pos, location.end) : range;
+6 -10
View File
@@ -83,7 +83,6 @@ import {
pathIsRelative,
Pattern,
patternText,
perfLogger,
readJson,
removeExtension,
removeFileExtension,
@@ -108,7 +107,7 @@ import {
version,
versionMajorMinor,
VersionRange,
} from "./_namespaces/ts";
} from "./_namespaces/ts.js";
/** @internal */
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void {
@@ -968,8 +967,7 @@ export interface CacheWithRedirects<K, V> {
/** @internal */
export type RedirectsCacheKey = string & { __compilerOptionsKey: any; };
/** @internal */
export function createCacheWithRedirects<K, V>(ownOptions: CompilerOptions | undefined, optionsToRedirectsKey: Map<CompilerOptions, RedirectsCacheKey>): CacheWithRedirects<K, V> {
function createCacheWithRedirects<K, V>(ownOptions: CompilerOptions | undefined, optionsToRedirectsKey: Map<CompilerOptions, RedirectsCacheKey>): CacheWithRedirects<K, V> {
const redirectsMap = new Map<CompilerOptions, Map<K, V>>();
const redirectsKeyToMap = new Map<RedirectsCacheKey, Map<K, V>>();
let ownMap = new Map<K, V>();
@@ -1431,7 +1429,6 @@ export function resolveModuleName(moduleName: string, containingFile: string, co
}
}
perfLogger?.logStartResolveModule(moduleName /* , containingFile, ModuleResolutionKind[moduleResolution]*/);
switch (moduleResolution) {
case ModuleResolutionKind.Node16:
result = node16ModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference, resolutionMode);
@@ -1451,8 +1448,6 @@ export function resolveModuleName(moduleName: string, containingFile: string, co
default:
return Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`);
}
if (result && result.resolvedModule) perfLogger?.logInfoEvent(`Module "${moduleName}" resolved to "${result.resolvedModule.resolvedFileName}"`);
perfLogger?.logStopResolveModule((result && result.resolvedModule) ? "" + result.resolvedModule.resolvedFileName : "null");
if (cache && !cache.isReadonly) {
cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference).set(moduleName, resolutionMode, result);
@@ -1756,8 +1751,10 @@ function tryResolveJSModuleWorker(moduleName: string, initialDir: string, host:
/*conditions*/ undefined,
);
}
// knip applies the internal marker to _all_ declarations, not just the one overload.
export function bundlerModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
/** @internal */
/** @internal @knipignore */
export function bundlerModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, conditions?: string[]): ResolvedModuleWithFailedLookupLocations; // eslint-disable-line @typescript-eslint/unified-signatures
export function bundlerModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, conditions?: string[]): ResolvedModuleWithFailedLookupLocations {
const containingDirectory = getDirectoryPath(containingFile);
@@ -2436,8 +2433,7 @@ function readPackageJsonPeerDependencies(packageJsonInfo: PackageJsonInfo, state
return result;
}
/** @internal */
export function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined {
function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PackageJsonInfo | undefined {
const { host, traceEnabled } = state;
const packageJsonPath = combinePaths(packageDirectory, "package.json");
if (onlyRecordFailures) {
+42 -45
View File
@@ -37,9 +37,9 @@ import {
getBaseFileName,
GetCanonicalFileName,
getConditions,
getDefaultResolutionModeForFileWorker,
getDirectoryPath,
getEmitModuleResolutionKind,
getModeForResolutionAtIndex,
getModuleNameStringLiteralAt,
getModuleSpecifierEndingPreference,
getNodeModulePathParts,
@@ -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.
@@ -142,13 +143,12 @@ export interface ModuleSpecifierPreferences {
/**
* @param syntaxImpliedNodeFormat Used when the import syntax implies ESM or CJS irrespective of the mode of the file.
*/
getAllowedEndingsInPreferredOrder(syntaxImpliedNodeFormat?: ResolutionMode): ModuleSpecifierEnding[];
getAllowedEndingsInPreferredOrder(syntaxImpliedNodeFormat?: SourceFile["impliedNodeFormat"]): ModuleSpecifierEnding[];
}
/** @internal */
export function getModuleSpecifierPreferences(
{ importModuleSpecifierPreference, importModuleSpecifierEnding }: UserPreferences,
host: Pick<ModuleSpecifierResolutionHost, "getDefaultResolutionModeForFile">,
compilerOptions: CompilerOptions,
importingSourceFile: Pick<SourceFile, "fileName" | "impliedNodeFormat">,
oldImportSpecifier?: string,
@@ -163,10 +163,8 @@ export function getModuleSpecifierPreferences(
importModuleSpecifierPreference === "project-relative" ? RelativePreference.ExternalNonRelative :
RelativePreference.Shortest,
getAllowedEndingsInPreferredOrder: syntaxImpliedNodeFormat => {
const impliedNodeFormat = getDefaultResolutionModeForFile(importingSourceFile, host, compilerOptions);
const preferredEnding = syntaxImpliedNodeFormat !== impliedNodeFormat ? getPreferredEnding(syntaxImpliedNodeFormat) : filePreferredEnding;
const moduleResolution = getEmitModuleResolutionKind(compilerOptions);
if ((syntaxImpliedNodeFormat ?? impliedNodeFormat) === ModuleKind.ESNext && ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext) {
const preferredEnding = syntaxImpliedNodeFormat !== importingSourceFile.impliedNodeFormat ? getPreferredEnding(syntaxImpliedNodeFormat) : filePreferredEnding;
if ((syntaxImpliedNodeFormat ?? importingSourceFile.impliedNodeFormat) === ModuleKind.ESNext) {
if (shouldAllowImportingTsExtension(compilerOptions, importingSourceFile.fileName)) {
return [ModuleSpecifierEnding.TsExtension, ModuleSpecifierEnding.JsExtension];
}
@@ -206,7 +204,7 @@ export function getModuleSpecifierPreferences(
}
return getModuleSpecifierEndingPreference(
importModuleSpecifierEnding,
resolutionMode ?? getDefaultResolutionModeForFile(importingSourceFile, host, compilerOptions),
resolutionMode ?? importingSourceFile.impliedNodeFormat,
compilerOptions,
isFullSourceFile(importingSourceFile) ? importingSourceFile : undefined,
);
@@ -227,7 +225,7 @@ export function updateModuleSpecifier(
oldImportSpecifier: string,
options: ModuleSpecifierOptions = {},
): string | undefined {
const res = getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getModuleSpecifierPreferences({}, host, compilerOptions, importingSourceFile, oldImportSpecifier), {}, options);
const res = getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getModuleSpecifierPreferences({}, compilerOptions, importingSourceFile, oldImportSpecifier), {}, options);
if (res === oldImportSpecifier) return undefined;
return res;
}
@@ -247,7 +245,7 @@ export function getModuleSpecifier(
host: ModuleSpecifierResolutionHost,
options: ModuleSpecifierOptions = {},
): string {
return getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getModuleSpecifierPreferences({}, host, compilerOptions, importingSourceFile), {}, options);
return getModuleSpecifierWorker(compilerOptions, importingSourceFile, importingSourceFileName, toFileName, host, getModuleSpecifierPreferences({}, compilerOptions, importingSourceFile), {}, options);
}
/** @internal */
@@ -277,7 +275,7 @@ function getModuleSpecifierWorker(
const info = getInfo(importingSourceFileName, host);
const modulePaths = getAllModulePaths(info, toFileName, host, userPreferences, compilerOptions, options);
return firstDefined(modulePaths, modulePath => tryGetModuleNameAsNodeModule(modulePath, info, importingSourceFile, host, compilerOptions, userPreferences, /*packageNameOnly*/ undefined, options.overrideImportMode)) ||
getLocalModuleSpecifier(toFileName, info, compilerOptions, host, options.overrideImportMode || getDefaultResolutionModeForFile(importingSourceFile, host, compilerOptions), preferences);
getLocalModuleSpecifier(toFileName, info, compilerOptions, host, options.overrideImportMode || importingSourceFile.impliedNodeFormat, preferences);
}
/** @internal */
@@ -287,14 +285,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 +302,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 +310,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 +339,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 +356,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 +383,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 */
@@ -397,7 +403,7 @@ export function getLocalModuleSpecifierBetweenFileNames(
compilerOptions,
host,
importMode,
getModuleSpecifierPreferences({}, host, compilerOptions, importingFile),
getModuleSpecifierPreferences({}, compilerOptions, importingFile),
);
}
@@ -409,9 +415,9 @@ 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 preferences = getModuleSpecifierPreferences(userPreferences, compilerOptions, importingSourceFile);
const existingSpecifier = isFullSourceFile(importingSourceFile) && forEach(modulePaths, modulePath =>
forEach(
host.getFileIncludeReasons().get(toPath(modulePath.path, host.getCurrentDirectory(), info.getCanonicalFileName)),
@@ -419,11 +425,7 @@ function computeModuleSpecifiers(
if (reason.kind !== FileIncludeKind.Import || reason.file !== importingSourceFile.path) return undefined;
// If the candidate import mode doesn't match the mode we're generating for, don't consider it
// TODO: maybe useful to keep around as an alternative option for certain contexts where the mode is overridable
const existingMode = host.getModeForResolutionAtIndex(importingSourceFile, reason.index);
const targetMode = options.overrideImportMode ?? host.getDefaultResolutionModeForFile(importingSourceFile);
if (existingMode !== targetMode && existingMode !== undefined && targetMode !== undefined) {
return undefined;
}
if (importingSourceFile.impliedNodeFormat && importingSourceFile.impliedNodeFormat !== getModeForResolutionAtIndex(importingSourceFile, reason.index, compilerOptions)) return undefined;
const specifier = getModuleNameStringLiteralAt(importingSourceFile, reason.index).text;
// If the preference is for non relative and the module specifier is relative, ignore it
return preferences.relativePreference !== RelativePreference.NonRelative || !pathIsRelative(specifier) ?
@@ -432,8 +434,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 +456,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 +502,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 {
@@ -1092,7 +1093,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan
// Simplify the full file path to something that can be resolved by Node.
const preferences = getModuleSpecifierPreferences(userPreferences, host, options, importingSourceFile);
const preferences = getModuleSpecifierPreferences(userPreferences, options, importingSourceFile);
const allowedEndings = preferences.getAllowedEndingsInPreferredOrder();
let moduleSpecifier = path;
let isPackageRootPath = false;
@@ -1152,7 +1153,7 @@ function tryGetModuleNameAsNodeModule({ path, isRedirect }: ModulePath, { getCan
const cachedPackageJson = host.getPackageJsonInfoCache?.()?.getPackageJsonInfo(packageJsonPath);
if (isPackageJsonInfo(cachedPackageJson) || cachedPackageJson === undefined && host.fileExists(packageJsonPath)) {
const packageJsonContent: Record<string, any> | undefined = cachedPackageJson?.contents.packageJsonContent || tryParseJson(host.readFile!(packageJsonPath)!);
const importMode = overrideMode || getDefaultResolutionModeForFile(importingSourceFile, host, options);
const importMode = overrideMode || importingSourceFile.impliedNodeFormat;
if (getResolvePackageJsonExports(options)) {
// The package name that we found in node_modules could be different from the package
// name in the package.json content via url/filepath dependency specifiers. We need to
@@ -1347,7 +1348,3 @@ function getRelativePathIfInSameVolume(path: string, directoryPath: string, getC
function isPathRelativeToParent(path: string): boolean {
return startsWith(path, "..");
}
function getDefaultResolutionModeForFile(file: Pick<SourceFile, "fileName" | "impliedNodeFormat" | "packageJsonScope">, host: Pick<ModuleSpecifierResolutionHost, "getDefaultResolutionModeForFile">, compilerOptions: CompilerOptions) {
return isFullSourceFile(file) ? host.getDefaultResolutionModeForFile(file) : getDefaultResolutionModeForFileWorker(file, compilerOptions);
}
+53 -36
View File
@@ -62,7 +62,6 @@ import {
DeleteExpression,
Diagnostic,
DiagnosticArguments,
DiagnosticCategory,
DiagnosticMessage,
Diagnostics,
DiagnosticWithDetachedLocation,
@@ -257,6 +256,7 @@ import {
modifiersToFlags,
ModuleBlock,
ModuleDeclaration,
ModuleExportName,
ModuleKind,
Mutable,
NamedExportBindings,
@@ -293,7 +293,6 @@ import {
ParenthesizedExpression,
ParenthesizedTypeNode,
PartiallyEmittedExpression,
perfLogger,
PlusToken,
PostfixUnaryExpression,
PostfixUnaryOperator,
@@ -370,6 +369,7 @@ import {
tokenIsIdentifierOrKeywordOrGreaterThan,
tokenToString,
tracing,
transferSourceFileChildren,
TransformFlags,
TryStatement,
TupleTypeNode,
@@ -397,8 +397,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,
@@ -425,6 +425,7 @@ let SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: n
* NOTE: You should not use this, it is only exported to support `createNode` in `~/src/deprecatedCompat/deprecations.ts`.
*
* @internal
* @knipignore
*/
export const parseBaseNodeFactory: BaseNodeFactory = {
createBaseSourceFileNode: kind => new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, -1, -1),
@@ -1343,7 +1344,6 @@ export function createSourceFile(fileName: string, sourceText: string, languageV
performance.mark("beforeParse");
let result: SourceFile;
perfLogger?.logStartParseSourceFile(fileName);
const {
languageVersion,
setExternalModuleIndicator: overrideSetExternalModuleIndicator,
@@ -1360,7 +1360,6 @@ export function createSourceFile(fileName: string, sourceText: string, languageV
};
result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind, setIndicator, jsDocParsingMode);
}
perfLogger?.logStopParseSourceFile();
performance.mark("afterParse");
performance.measure("Parse", "beforeParse", "afterParse");
@@ -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);
}
@@ -2642,7 +2637,7 @@ namespace Parser {
function createIdentifier(isIdentifier: boolean, diagnosticMessage?: DiagnosticMessage, privateIdentifierDiagnosticMessage?: DiagnosticMessage): Identifier {
if (isIdentifier) {
identifierCount++;
const pos = getNodePos();
const pos = scanner.hasPrecedingJSDocLeadingAsterisks() ? scanner.getTokenStart() : getNodePos();
// Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker
const originalKeywordKind = token();
const text = internIdentifier(scanner.getTokenValue());
@@ -2911,6 +2906,9 @@ namespace Parser {
if (token() === SyntaxKind.FromKeyword && lookAhead(nextTokenIsStringLiteral)) {
return false;
}
if (token() === SyntaxKind.StringLiteral) {
return true; // For "arbitrary module namespace identifiers"
}
return tokenIsIdentifierOrKeyword(token());
case ParsingContext.JsxAttributes:
return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.OpenBraceToken;
@@ -8509,6 +8507,14 @@ namespace Parser {
return finishNode(factory.createNamespaceImport(name), pos);
}
function canParseModuleExportName(): boolean {
return tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.StringLiteral;
}
function parseModuleExportName(parseName: () => Identifier): ModuleExportName {
return token() === SyntaxKind.StringLiteral ? parseLiteralNode() as StringLiteral : parseName();
}
function parseNamedImportsOrExports(kind: SyntaxKind.NamedImports): NamedImports;
function parseNamedImportsOrExports(kind: SyntaxKind.NamedExports): NamedExports;
function parseNamedImportsOrExports(kind: SyntaxKind): NamedImportsOrExports {
@@ -8541,18 +8547,18 @@ namespace Parser {
const pos = getNodePos();
// ImportSpecifier:
// BindingIdentifier
// IdentifierName as BindingIdentifier
// ModuleExportName as BindingIdentifier
// ExportSpecifier:
// IdentifierName
// IdentifierName as IdentifierName
// ModuleExportName
// ModuleExportName as ModuleExportName
let checkIdentifierIsKeyword = isKeyword(token()) && !isIdentifier();
let checkIdentifierStart = scanner.getTokenStart();
let checkIdentifierEnd = scanner.getTokenEnd();
let isTypeOnly = false;
let propertyName: Identifier | undefined;
let propertyName: ModuleExportName | undefined;
let canParseAsKeyword = true;
let name = parseIdentifierName();
if (name.escapedText === "type") {
let name = parseModuleExportName(parseIdentifierName);
if (name.kind === SyntaxKind.Identifier && name.escapedText === "type") {
// If the first token of an import specifier is 'type', there are a lot of possibilities,
// especially if we see 'as' afterwards:
//
@@ -8566,11 +8572,12 @@ namespace Parser {
if (token() === SyntaxKind.AsKeyword) {
// { type as as ...? }
const secondAs = parseIdentifierName();
if (tokenIsIdentifierOrKeyword(token())) {
if (canParseModuleExportName()) {
// { type as as something }
// { type as as "something" }
isTypeOnly = true;
propertyName = firstAs;
name = parseNameWithKeywordCheck();
name = parseModuleExportName(parseNameWithKeywordCheck);
canParseAsKeyword = false;
}
else {
@@ -8580,11 +8587,12 @@ namespace Parser {
canParseAsKeyword = false;
}
}
else if (tokenIsIdentifierOrKeyword(token())) {
else if (canParseModuleExportName()) {
// { type as something }
// { type as "something" }
propertyName = name;
canParseAsKeyword = false;
name = parseNameWithKeywordCheck();
name = parseModuleExportName(parseNameWithKeywordCheck);
}
else {
// { type as }
@@ -8592,23 +8600,31 @@ namespace Parser {
name = firstAs;
}
}
else if (tokenIsIdentifierOrKeyword(token())) {
else if (canParseModuleExportName()) {
// { type something ...? }
// { type "something" ...? }
isTypeOnly = true;
name = parseNameWithKeywordCheck();
name = parseModuleExportName(parseNameWithKeywordCheck);
}
}
if (canParseAsKeyword && token() === SyntaxKind.AsKeyword) {
propertyName = name;
parseExpected(SyntaxKind.AsKeyword);
name = parseNameWithKeywordCheck();
name = parseModuleExportName(parseNameWithKeywordCheck);
}
if (kind === SyntaxKind.ImportSpecifier && checkIdentifierIsKeyword) {
parseErrorAt(checkIdentifierStart, checkIdentifierEnd, Diagnostics.Identifier_expected);
if (kind === SyntaxKind.ImportSpecifier) {
if (name.kind !== SyntaxKind.Identifier) {
// ImportSpecifier casts "name" to Identifier below, so make sure it's an identifier
parseErrorAt(skipTrivia(sourceText, name.pos), name.end, Diagnostics.Identifier_expected);
name = setTextRangePosEnd(createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false), name.pos, name.pos);
}
else if (checkIdentifierIsKeyword) {
parseErrorAt(checkIdentifierStart, checkIdentifierEnd, Diagnostics.Identifier_expected);
}
}
const node = kind === SyntaxKind.ImportSpecifier
? factory.createImportSpecifier(isTypeOnly, propertyName, name)
? factory.createImportSpecifier(isTypeOnly, propertyName, name as Identifier)
: factory.createExportSpecifier(isTypeOnly, propertyName, name);
return finishNode(node, pos);
@@ -8621,7 +8637,7 @@ namespace Parser {
}
function parseNamespaceExport(pos: number): NamespaceExport {
return finishNode(factory.createNamespaceExport(parseIdentifierName()), pos);
return finishNode(factory.createNamespaceExport(parseModuleExportName(parseIdentifierName)), pos);
}
function parseExportDeclaration(pos: number, hasJSDoc: boolean, modifiers: NodeArray<ModifierLike> | undefined): ExportDeclaration {
@@ -9954,6 +9970,7 @@ namespace IncrementalParser {
aggressiveChecks,
);
result.impliedNodeFormat = sourceFile.impliedNodeFormat;
transferSourceFileChildren(sourceFile, result);
return result;
}
@@ -10006,9 +10023,9 @@ namespace IncrementalParser {
}
}
function moveElementEntirelyPastChangeRange(element: Node, isArray: false, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void;
function moveElementEntirelyPastChangeRange(element: NodeArray<Node>, isArray: true, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void;
function moveElementEntirelyPastChangeRange(element: Node | NodeArray<Node>, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) {
function moveElementEntirelyPastChangeRange(element: Node, origSourceFile: SourceFile, isArray: false, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void;
function moveElementEntirelyPastChangeRange(element: NodeArray<Node>, origSourceFile: SourceFile, isArray: true, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void;
function moveElementEntirelyPastChangeRange(element: Node | NodeArray<Node>, origSourceFile: SourceFile, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) {
if (isArray) {
visitArray(element as NodeArray<Node>);
}
@@ -10025,7 +10042,7 @@ namespace IncrementalParser {
// Ditch any existing LS children we may have created. This way we can avoid
// moving them forward.
unsetNodeChildren(node);
unsetNodeChildren(node, origSourceFile);
setTextRangePosEnd(node, node.pos + delta, node.end + delta);
@@ -10172,7 +10189,7 @@ namespace IncrementalParser {
if (child.pos > changeRangeOldEnd) {
// Node is entirely past the change range. We need to move both its pos and
// end, forward or backward appropriately.
moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
moveElementEntirelyPastChangeRange(child, sourceFile, /*isArray*/ false, delta, oldText, newText, aggressiveChecks);
return;
}
@@ -10182,7 +10199,7 @@ namespace IncrementalParser {
const fullEnd = child.end;
if (fullEnd >= changeStart) {
markAsIntersectingIncrementalChange(child);
unsetNodeChildren(child);
unsetNodeChildren(child, sourceFile);
// Adjust the pos or end (or both) of the intersecting element accordingly.
adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta);
@@ -10205,7 +10222,7 @@ namespace IncrementalParser {
if (array.pos > changeRangeOldEnd) {
// Array is entirely after the change range. We need to move it, and move any of
// its children.
moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
moveElementEntirelyPastChangeRange(array, sourceFile, /*isArray*/ true, delta, oldText, newText, aggressiveChecks);
return;
}
+2 -3
View File
@@ -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.
@@ -907,8 +907,7 @@ export function startsWithDirectory(fileName: string, directoryName: string, get
//// Relative Paths
/** @internal */
export function getPathComponentsRelativeTo(from: string, to: string, stringEqualityComparer: (a: string, b: string) => boolean, getCanonicalFileName: GetCanonicalFileName) {
function getPathComponentsRelativeTo(from: string, to: string, stringEqualityComparer: (a: string, b: string) => boolean, getCanonicalFileName: GetCanonicalFileName) {
const fromComponents = reducePathComponents(getPathComponents(from));
const toComponents = reducePathComponents(getPathComponents(to));
-44
View File
@@ -1,44 +0,0 @@
/** @internal */
export interface PerfLogger {
logEvent(msg: string): void;
logErrEvent(msg: string): void;
logPerfEvent(msg: string): void;
logInfoEvent(msg: string): void;
logStartCommand(command: string, msg: string): void;
logStopCommand(command: string, msg: string): void;
logStartUpdateProgram(msg: string): void;
logStopUpdateProgram(msg: string): void;
logStartUpdateGraph(): void;
logStopUpdateGraph(): void;
logStartResolveModule(name: string): void;
logStopResolveModule(success: string): void;
logStartParseSourceFile(filename: string): void;
logStopParseSourceFile(): void;
logStartReadFile(filename: string): void;
logStopReadFile(): void;
logStartBindFile(filename: string): void;
logStopBindFile(): void;
logStartScheduledOperation(operationId: string): void;
logStopScheduledOperation(): void;
}
// Load optional module to enable Event Tracing for Windows
// See https://github.com/microsoft/typescript-etw for more information
let etwModule: typeof import("@microsoft/typescript-etw") | undefined;
try {
const etwModulePath = process.env.TS_ETW_MODULE_PATH ?? "./node_modules/@microsoft/typescript-etw";
// require() will throw an exception if the module is not found
// It may also return undefined if not installed properly
etwModule = require(etwModulePath);
}
catch (e) {
etwModule = undefined;
}
/**
* Performance logger that will generate ETW events if possible - check for `logEvent` member, as `etwModule` will be `{}` when browserified
*
* @internal
*/
export const perfLogger: PerfLogger | undefined = etwModule?.logEvent ? etwModule : undefined;
+1 -1
View File
@@ -7,7 +7,7 @@ import {
System,
timestamp,
tryGetNativePerformanceHooks,
} from "./_namespaces/ts";
} from "./_namespaces/ts.js";
/** Performance measurements for the compiler. */
+1 -1
View File
@@ -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:
+554 -542
View File
File diff suppressed because it is too large Load Diff
+61 -91
View File
@@ -6,7 +6,6 @@ import {
CompilerOptions,
createModeAwareCache,
createModuleResolutionCache,
createMultiMap,
createTypeReferenceDirectiveResolutionCache,
createTypeReferenceResolutionLoader,
Debug,
@@ -30,9 +29,10 @@ import {
getOptionsForLibraryResolution,
getPathComponents,
getPathFromPathComponents,
getResolvedModuleFromResolution,
getResolvedTypeReferenceDirectiveFromResolution,
HasInvalidatedLibResolutions,
HasInvalidatedResolutions,
hasTrailingDirectorySeparator,
ignoredPaths,
inferredTypesContainingFile,
isDiskPathRoot,
@@ -51,7 +51,6 @@ import {
mutateMap,
noopFileWatcher,
normalizePath,
PackageId,
packageIdToString,
PackageJsonInfoCacheEntry,
parseNodeModuleFromPath,
@@ -63,6 +62,7 @@ import {
resolutionExtensionIsTSOrJson,
ResolutionLoader,
ResolutionMode,
ResolutionWithResolvedFileName,
ResolvedModuleWithFailedLookupLocations,
ResolvedProjectReference,
ResolvedTypeReferenceDirectiveWithFailedLookupLocations,
@@ -76,7 +76,7 @@ import {
trace,
updateResolutionField,
WatchDirectoryFlags,
} from "./_namespaces/ts";
} from "./_namespaces/ts.js";
/** @internal */
export interface HasInvalidatedFromResolutionCache {
@@ -140,7 +140,7 @@ export interface ResolutionCache {
invalidateResolutionsOfFailedLookupLocations(): boolean;
invalidateResolutionOfFile(filePath: Path): void;
removeResolutionsOfFile(filePath: Path, syncDirWatcherRemove?: boolean): void;
removeResolutionsOfFile(filePath: Path): void;
removeResolutionsFromProjectReferenceRedirects(filePath: Path): void;
setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map<Path, readonly string[]>): void;
createHasInvalidatedResolutions(
@@ -167,18 +167,11 @@ export interface ResolutionWithFailedLookupLocations {
failedLookupLocations?: string[];
affectingLocations?: string[];
isInvalidated?: boolean;
refCount?: number;
// Files that have this resolution using
files?: Set<Path>;
alternateResult?: string;
}
/** @internal */
export interface ResolutionWithResolvedFileName {
resolvedFileName: string | undefined;
packageId?: PackageId;
}
/** @internal */
export interface CachedResolvedModuleWithFailedLookupLocations extends ResolvedModuleWithFailedLookupLocations, ResolutionWithFailedLookupLocations {
}
@@ -192,6 +185,7 @@ export interface ResolutionCacheHost extends MinimalResolutionCacheHost {
toPath(fileName: string): Path;
getCanonicalFileName: GetCanonicalFileName;
getCompilationSettings(): CompilerOptions;
preferNonRecursiveWatch: boolean | undefined;
watchDirectoryOfFailedLookupLocation(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher;
watchAffectingFileLocation(file: string, cb: FileWatcherCallback): FileWatcher;
onInvalidatedResolution(): void;
@@ -351,6 +345,7 @@ export function getDirectoryToWatchFailedLookupLocation(
rootPath: Path,
rootPathComponents: Readonly<PathPathComponents>,
getCurrentDirectory: () => string | undefined,
preferNonRecursiveWatch: boolean | undefined,
): DirectoryOfFailedLookupWatch | undefined {
const failedLookupPathComponents: Readonly<PathPathComponents> = getPathComponents(failedLookupLocationPath);
// Ensure failed look up is normalized path
@@ -390,6 +385,7 @@ export function getDirectoryToWatchFailedLookupLocation(
nodeModulesIndex,
rootPathComponents,
lastNodeModulesIndex,
preferNonRecursiveWatch,
);
}
@@ -401,6 +397,7 @@ function getDirectoryToWatchFromFailedLookupLocationDirectory(
nodeModulesIndex: number,
rootPathComponents: Readonly<PathPathComponents>,
lastNodeModulesIndex: number,
preferNonRecursiveWatch: boolean | undefined,
): DirectoryOfFailedLookupWatch | undefined {
// If directory path contains node module, get the most parent node_modules directory for watching
if (nodeModulesIndex !== -1) {
@@ -412,14 +409,17 @@ function getDirectoryToWatchFromFailedLookupLocationDirectory(
lastNodeModulesIndex,
);
}
// Use some ancestor of the root directory
let nonRecursive = true;
let length = dirPathComponentsLength;
for (let i = 0; i < dirPathComponentsLength; i++) {
if (dirPathComponents[i] !== rootPathComponents[i]) {
nonRecursive = false;
length = Math.max(i + 1, perceivedOsRootLength + 1);
break;
if (!preferNonRecursiveWatch) {
for (let i = 0; i < dirPathComponentsLength; i++) {
if (dirPathComponents[i] !== rootPathComponents[i]) {
nonRecursive = false;
length = Math.max(i + 1, perceivedOsRootLength + 1);
break;
}
}
}
return getDirectoryOfFailedLookupWatch(
@@ -463,6 +463,7 @@ export function getDirectoryToWatchFailedLookupLocationFromTypeRoot(
rootPath: Path,
rootPathComponents: Readonly<PathPathComponents>,
getCurrentDirectory: () => string | undefined,
preferNonRecursiveWatch: boolean | undefined,
filterCustomPath: (path: Path) => boolean, // Return true if this path can be used
): Path | undefined {
const typeRootPathComponents = getPathComponents(typeRootPath);
@@ -479,6 +480,7 @@ export function getDirectoryToWatchFailedLookupLocationFromTypeRoot(
typeRootPathComponents.indexOf("node_modules" as Path),
rootPathComponents,
typeRootPathComponents.lastIndexOf("node_modules" as Path),
preferNonRecursiveWatch,
);
return toWatch && filterCustomPath(toWatch.dirPath) ? toWatch.dirPath : undefined;
}
@@ -491,11 +493,6 @@ export function getRootDirectoryOfResolutionCache(rootDirForResolution: string,
normalized;
}
/** @internal */
export function getRootPathSplitLength(rootPath: Path) {
return rootPath.split(directorySeparator).length - (hasTrailingDirectorySeparator(rootPath) ? 1 : 0);
}
function getModuleResolutionHost(resolutionHost: ResolutionCacheHost) {
return resolutionHost.getCompilerHost?.() || resolutionHost;
}
@@ -574,7 +571,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
let filesWithInvalidatedResolutions: Set<Path> | undefined;
let filesWithInvalidatedNonRelativeUnresolvedImports: ReadonlyMap<Path, readonly string[]> | undefined;
const nonRelativeExternalModuleResolutions = createMultiMap<string, ResolutionWithFailedLookupLocations>();
const nonRelativeExternalModuleResolutions = new Set<ResolutionWithFailedLookupLocations>();
const resolutionsWithFailedLookups = new Set<ResolutionWithFailedLookupLocations>();
const resolutionsWithOnlyAffectingLocations = new Set<ResolutionWithFailedLookupLocations>();
@@ -670,14 +667,6 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
onChangesAffectModuleResolution,
};
function getResolvedModule(resolution: CachedResolvedModuleWithFailedLookupLocations) {
return resolution.resolvedModule;
}
function getResolvedTypeReferenceDirective(resolution: CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations) {
return resolution.resolvedTypeReferenceDirective;
}
function clear() {
clearMap(directoryWatchesOfFailedLookups, closeFileWatcherOf);
clearMap(fileWatchesOfAffectingLocations, closeFileWatcherOf);
@@ -765,8 +754,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
libraryResolutionCache.clearAllExceptPackageJsonInfoCache();
// perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update
// (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution)
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
nonRelativeExternalModuleResolutions.clear();
watchFailedLookupLocationOfNonRelativeModuleResolutions();
isSymlinkCache.clear();
}
@@ -776,7 +764,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
stopWatchFailedLookupLocationOfResolution(
resolution,
resolutionHost.toPath(getInferredLibraryNameResolveFrom(resolutionHost.getCompilationSettings(), getCurrentDirectory(), libFileName)),
getResolvedModule,
getResolvedModuleFromResolution,
);
resolvedLibraries.delete(libFileName);
}
@@ -786,8 +774,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
function finishCachingPerDirectoryResolution(newProgram: Program | undefined, oldProgram: Program | undefined) {
filesWithInvalidatedNonRelativeUnresolvedImports = undefined;
allModuleAndTypeResolutionsAreInvalidated = false;
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
nonRelativeExternalModuleResolutions.clear();
watchFailedLookupLocationOfNonRelativeModuleResolutions();
// Update file watches
if (newProgram !== oldProgram) {
cleanupLibResolutionWatching(newProgram);
@@ -1003,7 +990,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
getModuleResolutionHost(resolutionHost),
typeReferenceDirectiveResolutionCache,
),
getResolutionWithResolvedFileName: getResolvedTypeReferenceDirective,
getResolutionWithResolvedFileName: getResolvedTypeReferenceDirectiveFromResolution,
shouldRetryResolution: resolution => resolution.resolvedTypeReferenceDirective === undefined,
deferWatchingNonRelativeResolution: false,
});
@@ -1032,7 +1019,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
resolutionHost,
moduleResolutionCache,
),
getResolutionWithResolvedFileName: getResolvedModule,
getResolutionWithResolvedFileName: getResolvedModuleFromResolution,
shouldRetryResolution: resolution => !resolution.resolvedModule || !resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension),
logChanges: logChangesWhenResolvingModule,
deferWatchingNonRelativeResolution: true, // Defer non relative resolution watch because we could be using ambient modules
@@ -1051,15 +1038,15 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
const existingResolution = resolution;
resolution = ts_resolveLibrary(libraryName, resolveFrom, options, host, libraryResolutionCache);
const path = resolutionHost.toPath(resolveFrom);
watchFailedLookupLocationsOfExternalModuleResolutions(libraryName, resolution, path, getResolvedModule, /*deferWatchingNonRelativeResolution*/ false);
watchFailedLookupLocationsOfExternalModuleResolutions(libraryName, resolution, path, getResolvedModuleFromResolution, /*deferWatchingNonRelativeResolution*/ false);
resolvedLibraries.set(libFileName, resolution);
if (existingResolution) {
stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolvedModule);
stopWatchFailedLookupLocationOfResolution(existingResolution, path, getResolvedModuleFromResolution);
}
}
else {
if (isTraceEnabled(options, host)) {
const resolved = getResolvedModule(resolution);
const resolved = getResolvedModuleFromResolution(resolution);
trace(
host,
resolved?.resolvedFileName ?
@@ -1107,28 +1094,21 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
deferWatchingNonRelativeResolution: boolean,
) {
if (resolution.refCount) {
resolution.refCount++;
Debug.assertIsDefined(resolution.files);
(resolution.files ??= new Set()).add(filePath);
if (resolution.files.size !== 1) return;
if (!deferWatchingNonRelativeResolution || isExternalModuleNameRelative(name)) {
watchFailedLookupLocationOfResolution(resolution);
}
else {
resolution.refCount = 1;
Debug.assert(!resolution.files?.size); // This resolution shouldnt be referenced by any file yet
if (!deferWatchingNonRelativeResolution || isExternalModuleNameRelative(name)) {
watchFailedLookupLocationOfResolution(resolution);
}
else {
nonRelativeExternalModuleResolutions.add(name, resolution);
}
const resolved = getResolutionWithResolvedFileName(resolution);
if (resolved && resolved.resolvedFileName) {
const key = resolutionHost.toPath(resolved.resolvedFileName);
let resolutions = resolvedFileToResolution.get(key);
if (!resolutions) resolvedFileToResolution.set(key, resolutions = new Set());
resolutions.add(resolution);
}
nonRelativeExternalModuleResolutions.add(resolution);
}
const resolved = getResolutionWithResolvedFileName(resolution);
if (resolved && resolved.resolvedFileName) {
const key = resolutionHost.toPath(resolved.resolvedFileName);
let resolutions = resolvedFileToResolution.get(key);
if (!resolutions) resolvedFileToResolution.set(key, resolutions = new Set());
resolutions.add(resolution);
}
(resolution.files ??= new Set()).add(filePath);
}
function watchFailedLookupLocation(failedLookupLocation: string, setAtRoot: boolean) {
@@ -1140,6 +1120,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
rootPath,
rootPathComponents,
getCurrentDirectory,
resolutionHost.preferNonRecursiveWatch,
);
if (toWatch) {
const { dir, dirPath, nonRecursive, packageDir, packageDirPath } = toWatch;
@@ -1156,7 +1137,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
}
function watchFailedLookupLocationOfResolution(resolution: ResolutionWithFailedLookupLocations) {
Debug.assert(!!resolution.refCount);
Debug.assert(!!resolution.files?.size);
const { failedLookupLocations, affectingLocations, alternateResult } = resolution;
if (!failedLookupLocations?.length && !affectingLocations?.length && !alternateResult) return;
@@ -1177,7 +1158,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
}
function watchAffectingLocationsOfResolution(resolution: ResolutionWithFailedLookupLocations, addToResolutionsWithOnlyAffectingLocations: boolean) {
Debug.assert(!!resolution.refCount);
Debug.assert(!!resolution.files?.size);
const { affectingLocations } = resolution;
if (!affectingLocations?.length) return;
if (addToResolutionsWithOnlyAffectingLocations) resolutionsWithOnlyAffectingLocations.add(resolution);
@@ -1252,14 +1233,9 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
packageJsonMap?.delete(resolutionHost.toPath(path));
}
function watchFailedLookupLocationOfNonRelativeModuleResolutions(resolutions: ResolutionWithFailedLookupLocations[], name: string) {
const program = resolutionHost.getCurrentProgram();
if (!program || !program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(name)) {
resolutions.forEach(watchFailedLookupLocationOfResolution);
}
else {
resolutions.forEach(resolution => watchAffectingLocationsOfResolution(resolution, /*addToResolutionsWithOnlyAffectingLocations*/ true));
}
function watchFailedLookupLocationOfNonRelativeModuleResolutions() {
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfResolution);
nonRelativeExternalModuleResolutions.clear();
}
function createDirectoryWatcherForPackageDir(
@@ -1289,7 +1265,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
else if (packageDirWatcher.isSymlink !== isSymlink) {
// Handle the change
packageDirWatcher.dirPathToWatcher.forEach(watcher => {
removeDirectoryWatcher(packageDirWatcher!.isSymlink ? packageDirPath : dirPath, /*syncDirWatcherRemove*/ false);
removeDirectoryWatcher(packageDirWatcher!.isSymlink ? packageDirPath : dirPath);
watcher.watcher = createDirPathToWatcher();
});
packageDirWatcher.isSymlink = isSymlink;
@@ -1345,7 +1321,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
return dirWatcher;
}
function stopWatchFailedLookupLocation(failedLookupLocation: string, removeAtRoot: boolean, syncDirWatcherRemove: boolean | undefined) {
function stopWatchFailedLookupLocation(failedLookupLocation: string, removeAtRoot: boolean) {
const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
const toWatch = getDirectoryToWatchFailedLookupLocation(
failedLookupLocation,
@@ -1354,6 +1330,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
rootPath,
rootPathComponents,
getCurrentDirectory,
resolutionHost.preferNonRecursiveWatch,
);
if (toWatch) {
const { dirPath, packageDirPath } = toWatch;
@@ -1365,7 +1342,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
const forDirPath = packageDirWatcher.dirPathToWatcher.get(dirPath)!;
forDirPath.refCount--;
if (forDirPath.refCount === 0) {
removeDirectoryWatcher(packageDirWatcher.isSymlink ? packageDirPath : dirPath, syncDirWatcherRemove);
removeDirectoryWatcher(packageDirWatcher.isSymlink ? packageDirPath : dirPath);
packageDirWatcher.dirPathToWatcher.delete(dirPath);
if (packageDirWatcher.isSymlink) {
const refCount = dirPathToSymlinkPackageRefCount.get(dirPath)! - 1;
@@ -1376,11 +1353,10 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
dirPathToSymlinkPackageRefCount.set(dirPath, refCount);
}
}
if (syncDirWatcherRemove) closePackageDirWatcher(packageDirWatcher, packageDirPath);
}
}
else {
removeDirectoryWatcher(dirPath, syncDirWatcherRemove);
removeDirectoryWatcher(dirPath);
}
}
return removeAtRoot;
@@ -1390,13 +1366,10 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
resolution: T,
filePath: Path,
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
syncDirWatcherRemove?: boolean,
) {
Debug.checkDefined(resolution.files).delete(filePath);
resolution.refCount!--;
if (resolution.refCount) {
return;
}
if (resolution.files!.size) return;
resolution.files = undefined;
const resolved = getResolutionWithResolvedFileName(resolution);
if (resolved && resolved.resolvedFileName) {
const key = resolutionHost.toPath(resolved.resolvedFileName);
@@ -1409,11 +1382,11 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
let removeAtRoot = false;
if (failedLookupLocations) {
for (const failedLookupLocation of failedLookupLocations) {
removeAtRoot = stopWatchFailedLookupLocation(failedLookupLocation, removeAtRoot, syncDirWatcherRemove);
removeAtRoot = stopWatchFailedLookupLocation(failedLookupLocation, removeAtRoot);
}
}
if (alternateResult) removeAtRoot = stopWatchFailedLookupLocation(alternateResult, removeAtRoot, syncDirWatcherRemove);
if (removeAtRoot) removeDirectoryWatcher(rootPath, syncDirWatcherRemove);
if (alternateResult) removeAtRoot = stopWatchFailedLookupLocation(alternateResult, removeAtRoot);
if (removeAtRoot) removeDirectoryWatcher(rootPath);
}
else if (affectingLocations?.length) {
resolutionsWithOnlyAffectingLocations.delete(resolution);
@@ -1423,16 +1396,14 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
for (const affectingLocation of affectingLocations) {
const watcher = fileWatchesOfAffectingLocations.get(affectingLocation)!;
watcher.resolutions--;
if (syncDirWatcherRemove) closeFileWatcherOfAffectingLocation(watcher, affectingLocation);
}
}
}
function removeDirectoryWatcher(dirPath: Path, syncDirWatcherRemove: boolean | undefined) {
function removeDirectoryWatcher(dirPath: Path) {
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath)!;
// Do not close the watcher yet since it might be needed by other failed lookup locations.
dirWatcher.refCount--;
if (syncDirWatcherRemove) closeDirectoryWatchesOfFailedLookup(dirWatcher, dirPath);
}
function createDirectoryWatcher(directory: string, dirPath: Path, nonRecursive: boolean | undefined) {
@@ -1451,7 +1422,6 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
cache: Map<string, ModeAwareCache<T>>,
filePath: Path,
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
syncDirWatcherRemove: boolean | undefined,
) {
// Deleted file, stop watching failed lookups for all the resolutions in the file
const resolutions = cache.get(filePath);
@@ -1461,7 +1431,6 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
resolution,
filePath,
getResolutionWithResolvedFileName,
syncDirWatcherRemove,
)
);
cache.delete(filePath);
@@ -1482,9 +1451,9 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
resolvedProjectReference.commandLine.fileNames.forEach(f => removeResolutionsOfFile(resolutionHost.toPath(f)));
}
function removeResolutionsOfFile(filePath: Path, syncDirWatcherRemove?: boolean) {
removeResolutionsOfFileFromCache(resolvedModuleNames, filePath, getResolvedModule, syncDirWatcherRemove);
removeResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath, getResolvedTypeReferenceDirective, syncDirWatcherRemove);
function removeResolutionsOfFile(filePath: Path) {
removeResolutionsOfFileFromCache(resolvedModuleNames, filePath, getResolvedModuleFromResolution);
removeResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath, getResolvedTypeReferenceDirectiveFromResolution);
}
function invalidateResolutions(resolutions: Set<ResolutionWithFailedLookupLocations> | Map<string, ResolutionWithFailedLookupLocations> | undefined, canInvalidate: (resolution: ResolutionWithFailedLookupLocations) => boolean | undefined) {
@@ -1662,6 +1631,7 @@ export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootD
rootPath,
rootPathComponents,
getCurrentDirectory,
resolutionHost.preferNonRecursiveWatch,
dirPath => directoryWatchesOfFailedLookups.has(dirPath) || dirPathToSymlinkPackageRefCount.has(dirPath),
);
if (dirPath) {
+1260 -1072
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -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
+3 -4
View File
@@ -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 {
@@ -405,8 +405,7 @@ function isStringOrNull(x: any) {
return typeof x === "string" || x === null;
}
/** @internal */
export function isRawSourceMap(x: any): x is RawSourceMap {
function isRawSourceMap(x: any): x is RawSourceMap {
return x !== null
&& typeof x === "object"
&& x.version === 3
+1 -1
View File
@@ -24,7 +24,7 @@ import {
TypeQueryNode,
TypeReference,
UnionOrIntersectionType,
} from "./_namespaces/ts";
} from "./_namespaces/ts.js";
/** @internal */
export function createGetSymbolWalker(
+5 -13
View File
@@ -35,7 +35,6 @@ import {
normalizeSlashes,
orderedRemoveItem,
Path,
perfLogger,
PollingWatchKind,
resolveJSModule,
some,
@@ -46,7 +45,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;
@@ -1410,6 +1409,7 @@ export interface System {
*/
watchFile?(path: string, callback: FileWatcherCallback, pollingInterval?: number, options?: WatchOptions): FileWatcher;
watchDirectory?(path: string, callback: DirectoryWatcherCallback, recursive?: boolean, options?: WatchOptions): FileWatcher;
/**@internal */ preferNonRecursiveWatch?: boolean;
resolvePath(path: string): string;
fileExists(path: string): boolean;
directoryExists(path: string): boolean;
@@ -1535,6 +1535,7 @@ export let sys: System = (() => {
writeFile,
watchFile,
watchDirectory,
preferNonRecursiveWatch: !fsSupportsRecursiveFsWatch,
resolvePath: path => _path.resolve(path),
fileExists,
directoryExists,
@@ -1786,7 +1787,7 @@ export let sys: System = (() => {
);
}
function readFileWorker(fileName: string, _encoding?: string): string | undefined {
function readFile(fileName: string, _encoding?: string): string | undefined {
let buffer: Buffer;
try {
buffer = _fs.readFileSync(fileName);
@@ -1818,15 +1819,7 @@ export let sys: System = (() => {
return buffer.toString("utf8");
}
function readFile(fileName: string, _encoding?: string): string | undefined {
perfLogger?.logStartReadFile(fileName);
const file = readFileWorker(fileName, _encoding);
perfLogger?.logStopReadFile();
return file;
}
function writeFile(fileName: string, data: string, writeByteOrderMark?: boolean): void {
perfLogger?.logEvent("WriteFile: " + fileName);
// If a BOM is required, emit one
if (writeByteOrderMark) {
data = byteOrderMarkIndicator + data;
@@ -1846,7 +1839,6 @@ export let sys: System = (() => {
}
function getAccessibleFileSystemEntries(path: string): FileSystemEntries {
perfLogger?.logEvent("ReadDir: " + (path || "."));
try {
const entries = _fs.readdirSync(path || ".", { withFileTypes: true });
const files: string[] = [];
@@ -2004,7 +1996,7 @@ export let sys: System = (() => {
return sys!;
})();
/** @internal */
/** @internal @knipignore */
export function setSys(s: System) {
sys = s;
}
+2 -2
View File
@@ -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. */
+8 -14
View File
@@ -65,35 +65,29 @@ import {
transformESDecorators,
transformESNext,
transformGenerators,
transformImpliedNodeFormatDependentModule,
transformJsx,
transformLegacyDecorators,
transformModule,
transformNodeModule,
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<SourceFile | Bundle> {
switch (moduleKind) {
case ModuleKind.Preserve:
// `transformECMAScriptModule` contains logic for preserving
// CJS input syntax in `--module preserve`
return transformECMAScriptModule;
case ModuleKind.ESNext:
case ModuleKind.ES2022:
case ModuleKind.ES2020:
case ModuleKind.ES2015:
case ModuleKind.Node16:
case ModuleKind.NodeNext:
case ModuleKind.CommonJS:
// Wraps `transformModule` and `transformECMAScriptModule` and
// selects between them based on the `impliedNodeFormat` of the
// source file.
return transformImpliedNodeFormatDependentModule;
case ModuleKind.Preserve:
return transformECMAScriptModule;
case ModuleKind.System:
return transformSystemModule;
case ModuleKind.Node16:
case ModuleKind.NodeNext:
return transformNodeModule;
default:
return transformModule;
}
+13 -17
View File
@@ -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 {
/**
@@ -464,8 +464,6 @@ export function transformClassFields(context: TransformationContext): (x: Source
}
switch (node.kind) {
case SyntaxKind.AccessorKeyword:
return Debug.fail("Use `modifierVisitor` instead.");
case SyntaxKind.ClassDeclaration:
return visitClassDeclaration(node as ClassDeclaration);
case SyntaxKind.ClassExpression:
@@ -901,10 +899,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<Node> {
@@ -946,7 +943,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 +1710,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 +1752,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 +1886,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 +1962,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 +1980,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 +2708,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 +2956,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 +3291,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.
+2 -3
View File
@@ -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.
@@ -29,9 +29,8 @@ import {
* @param classThis The identifier to use for the captured static `this` reference, usually with the name `_classThis`.
* @param thisExpression Overrides the expression to use for the actual `this` reference. This can be used to provide an
* expression that has already had its `EmitFlags` set or may have been tracked to prevent substitution.
* @internal
*/
export function createClassThisAssignmentBlock(factory: NodeFactory, classThis: Identifier, thisExpression = factory.createThis()): ClassThisAssignmentBlock {
function createClassThisAssignmentBlock(factory: NodeFactory, classThis: Identifier, thisExpression = factory.createThis()): ClassThisAssignmentBlock {
// produces:
//
// static { _classThis = this; }
+49 -19
View File
@@ -70,6 +70,7 @@ import {
getResolvedExternalModuleName,
getSetAccessorValueParameter,
getSourceFileOfNode,
getSourceFilesToEmit,
GetSymbolAccessibilityDiagnostic,
getTextOfNode,
getThisParameter,
@@ -138,6 +139,7 @@ import {
isTupleTypeNode,
isTypeAliasDeclaration,
isTypeElement,
isTypeLiteralNode,
isTypeNode,
isTypeParameterDeclaration,
isTypeQueryNode,
@@ -209,13 +211,27 @@ import {
visitNode,
visitNodes,
VisitResult,
} from "../_namespaces/ts";
} from "../_namespaces/ts.js";
/** @internal */
export function getDeclarationDiagnostics(host: EmitHost, resolver: EmitResolver, file: SourceFile | undefined): DiagnosticWithLocation[] | undefined {
export function getDeclarationDiagnostics(
host: EmitHost,
resolver: EmitResolver,
file: SourceFile,
): DiagnosticWithLocation[] | undefined {
const compilerOptions = host.getCompilerOptions();
const result = transformNodes(resolver, host, factory, compilerOptions, file ? [file] : filter(host.getSourceFiles(), isSourceFileNotJson), [transformDeclarations], /*allowDtsFiles*/ false);
return result.diagnostics;
const files = filter(getSourceFilesToEmit(host, file), isSourceFileNotJson);
return contains(files, file) ?
transformNodes(
resolver,
host,
factory,
compilerOptions,
[file],
[transformDeclarations],
/*allowDtsFiles*/ false,
).diagnostics :
undefined;
}
const declarationEmitNodeBuilderFlags = NodeBuilderFlags.MultilineObjectLiterals |
@@ -223,6 +239,7 @@ const declarationEmitNodeBuilderFlags = NodeBuilderFlags.MultilineObjectLiterals
NodeBuilderFlags.UseTypeOfFunction |
NodeBuilderFlags.UseStructuralFallback |
NodeBuilderFlags.AllowEmptyTuple |
NodeBuilderFlags.AllowUnresolvedNames |
NodeBuilderFlags.GenerateNamesForShadowedTypeParams |
NodeBuilderFlags.NoTruncation;
@@ -291,6 +308,7 @@ export function transformDeclarations(context: TransformationContext) {
}
function reportInferenceFallback(node: Node) {
if (!isolatedDeclarations || isSourceFileJS(currentSourceFile)) return;
if (getSourceFileOfNode(node) !== currentSourceFile) return; // Nested error on a declaration in another file - ignore, will be reemitted if file is in the output file set
if (isVariableDeclaration(node) && resolver.isExpandoFunctionDeclaration(node)) {
reportExpandoFunctionErrors(node);
}
@@ -313,7 +331,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) {
@@ -338,7 +357,10 @@ export function transformDeclarations(context: TransformationContext) {
function reportPrivateInBaseOfClassExpression(propertyName: string) {
if (errorNameNode || errorFallbackNode) {
context.addDiagnostic(
createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName),
addRelatedInfo(
createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.Property_0_of_exported_anonymous_class_type_may_not_be_private_or_protected, propertyName),
...(isVariableDeclaration((errorNameNode || errorFallbackNode)!.parent) ? [createDiagnosticForNode((errorNameNode || errorFallbackNode)!, Diagnostics.Add_a_type_annotation_to_the_variable_0, errorDeclarationNameWithFallback())] : []),
),
);
}
}
@@ -983,20 +1005,28 @@ 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 (!resolver.isDefinitelyReferenceToGlobalSymbolObject(input.name.expression)) {
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;
}
}
@@ -1768,7 +1798,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);
@@ -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<WithIsolatedDeclarationDiagnostic>(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<FunctionLikeDeclaration, ConstructorDeclaration> => 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));
+1 -1
View File
@@ -60,7 +60,7 @@ import {
VariableDeclaration,
visitNode,
VisitResult,
} from "../_namespaces/ts";
} from "../_namespaces/ts.js";
interface FlattenContext {
context: TransformationContext;
+8 -9
View File
@@ -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)) {
+1 -1
View File
@@ -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 {
+10 -10
View File
@@ -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);
+5 -5
View File
@@ -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;
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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:
//
+3 -6
View File
@@ -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);
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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 {

Some files were not shown because too many files have changed in this diff Show More