diff --git a/.eslintignore b/.eslintignore index 078de54900063..8d53899550031 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,7 +3,20 @@ /tests/** /lib/** /src/lib/*.generated.d.ts +# Ignore all compiled script outputs /scripts/*.js +# But, not the ones that are hand-written. +# TODO: remove once scripts are pure JS +!/scripts/browserIntegrationTest.js +!/scripts/createPlaygroundBuild.js +!/scripts/failed-tests.js +!/scripts/find-unused-diagnostic-messages.js +!/scripts/lint-hooks.js +!/scripts/perf-result-post.js +!/scripts/post-vsts-artifact-comment.js +!/scripts/regenerate-unicode-identifier-parts.js +!/scripts/run-sequence.js +!/scripts/update-experimental-branches.js /scripts/eslint/built/** /internal/** /coverage/** diff --git a/.eslintrc.json b/.eslintrc.json index 789725d782835..1711f8592ab18 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -2,7 +2,6 @@ "parser": "@typescript-eslint/parser", "parserOptions": { "warnOnUnsupportedTypeScriptVersion": false, - "ecmaVersion": 6, "sourceType": "module" }, "env": { @@ -22,11 +21,12 @@ // // 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. - { "files": ["*.ts"] } + { "files": ["*.ts", "*.mts", "*.cts", "*.mjs", "*.cjs"] } ], "rules": { "@typescript-eslint/adjacent-overload-signatures": "error", "@typescript-eslint/array-type": "error", + "@typescript-eslint/no-array-constructor": "error", "brace-style": "off", "@typescript-eslint/brace-style": ["error", "stroustrup", { "allowSingleLine": true }], @@ -62,12 +62,14 @@ "@typescript-eslint/prefer-for-of": "error", "@typescript-eslint/prefer-function-type": "error", "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/prefer-as-const": "error", "quotes": "off", "@typescript-eslint/quotes": ["error", "double", { "avoidEscape": true, "allowTemplateLiterals": true }], "semi": "off", "@typescript-eslint/semi": "error", + "@typescript-eslint/no-extra-semi": "error", "space-before-function-paren": "off", "@typescript-eslint/space-before-function-paren": ["error", { @@ -80,6 +82,8 @@ "@typescript-eslint/type-annotation-spacing": "error", "@typescript-eslint/unified-signatures": "error", + "@typescript-eslint/no-extra-non-null-assertion": "error", + // scripts/eslint/rules "local/object-literal-surrounding-space": "error", "local/no-type-assertion-whitespace": "error", @@ -143,6 +147,9 @@ "quote-props": ["error", "consistent-as-needed"], "space-in-parens": "error", "unicode-bom": ["error", "never"], - "use-isnan": "error" + "use-isnan": "error", + "no-prototype-builtins": "error", + "no-self-assign": "error", + "no-dupe-else-if": "error" } } diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91f44f272a645..956a41729655f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,7 +32,7 @@ jobs: - run: npm ci - name: Tests - run: npm test -- --no-lint + run: npm test lint: runs-on: ubuntu-latest @@ -46,7 +46,7 @@ jobs: - run: npm ci - name: Linter - run: npm run lint:ci + run: npm run lint browser-integration: runs-on: ubuntu-latest diff --git a/.github/workflows/twoslash-repros.yaml b/.github/workflows/twoslash-repros.yaml index 3ff59cf2e56e2..5f6fee2402d62 100644 --- a/.github/workflows/twoslash-repros.yaml +++ b/.github/workflows/twoslash-repros.yaml @@ -8,35 +8,31 @@ on: - cron: '0 8 * * *' repository_dispatch: types: run-twoslash-repros - issues: - types: - - labeled workflow_dispatch: inputs: - bisect_issue: - description: Triggers a bisect request on the given issue number instead of updating repros on all issues + issue: + description: Limits run to a single issue. + required: false + type: string + bisect: + description: If set, runs a git bisect on an existing repro. Requires 'issue' to be set. Value can be revision labels (e.g. `good v4.7.3 bad main`) or `true` to infer bisect range. required: false type: string jobs: run: - if: ${{ github.repository == 'microsoft/TypeScript' && !github.event.label && !github.event.inputs.bisect_issue }} - runs-on: ubuntu-latest - steps: - - uses: actions/setup-node@v3 - - uses: microsoft/TypeScript-Twoslash-Repro-Action@master - with: - github-token: ${{ secrets.TS_BOT_GITHUB_TOKEN }} - - bisect: - if: ${{ github.event.label.name == 'Bisect Repro' || github.event.inputs.bisect_issue }} + if: ${{ github.repository == 'microsoft/TypeScript' }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - if: ${{ github.event.inputs.bisect }} + uses: actions/checkout@v3 with: fetch-depth: 0 + - if: ${{ !github.event.inputs.bisect }} + uses: actions/checkout@v3 - uses: actions/setup-node@v3 - uses: microsoft/TypeScript-Twoslash-Repro-Action@master with: github-token: ${{ secrets.TS_BOT_GITHUB_TOKEN }} - bisect: ${{ github.event.issue.number || github.event.inputs.bisect_issue }} + issue: ${{ github.event.inputs.issue }} + bisect: ${{ github.event.inputs.bisect }} diff --git a/Gulpfile.js b/Gulpfile.js index 7f527a93a0b57..5f4f365915dda 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -372,9 +372,6 @@ const lint = eslint("."); lint.displayName = "lint"; task("lint", lint); task("lint").description = "Runs eslint on the compiler and scripts sources."; -task("lint").flags = { - " --ci": "Runs eslint additional rules", -}; const buildCancellationToken = () => buildProject("src/cancellationToken"); const cleanCancellationToken = () => cleanProject("src/cancellationToken"); @@ -427,10 +424,8 @@ task("watch-local").flags = { const preTest = parallel(buildTsc, buildTests, buildServices, buildLssl); preTest.displayName = "preTest"; -const postTest = (done) => cmdLineOptions.lint ? lint() : done(); - const runTests = () => runConsoleTests("built/local/run.js", "mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*watchMode*/ false); -task("runtests", series(preBuild, preTest, runTests, postTest)); +task("runtests", series(preBuild, preTest, runTests)); task("runtests").description = "Runs the tests using the built run.js file."; task("runtests").flags = { "-t --tests=": "Pattern for tests to run.", @@ -442,7 +437,6 @@ task("runtests").flags = { " --dirty": "Run tests without first cleaning test output directories", " --stackTraceLimit=": "Sets the maximum number of stack frames to display. Use 'full' to show all frames.", " --no-color": "Disables color", - " --no-lint": "Disables lint", " --timeout=": "Overrides the default test timeout.", " --built": "Compile using the built version of the compiler.", " --shards": "Total number of shards running tests (default: 1)", @@ -450,10 +444,9 @@ task("runtests").flags = { }; const runTestsParallel = () => runConsoleTests("built/local/run.js", "min", /*runInParallel*/ cmdLineOptions.workers > 1, /*watchMode*/ false); -task("runtests-parallel", series(preBuild, preTest, runTestsParallel, postTest)); +task("runtests-parallel", series(preBuild, preTest, runTestsParallel)); task("runtests-parallel").description = "Runs all the tests in parallel using the built run.js file."; task("runtests-parallel").flags = { - " --no-lint": "disables lint.", " --light": "Run tests in light mode (fewer verifications, but tests run faster).", " --keepFailed": "Keep tests in .failed-tests even if they pass.", " --dirty": "Run tests without first cleaning test output directories.", @@ -616,7 +609,6 @@ task("watch").flags = { " --dirty": "Run tests without first cleaning test output directories", " --stackTraceLimit=": "Sets the maximum number of stack frames to display. Use 'full' to show all frames.", " --no-color": "Disables color", - " --no-lint": "Disables lint", " --timeout=": "Overrides the default test timeout.", " --workers=": "The number of parallel workers to use.", " --built": "Compile using the built version of the compiler.", diff --git a/lib/tsc.js b/lib/tsc.js index 97db13aa62a50..ab79f9e91feec 100644 --- a/lib/tsc.js +++ b/lib/tsc.js @@ -69,7 +69,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { var ts; (function (ts) { ts.versionMajorMinor = "4.8"; - ts.version = "4.8.2"; + ts.version = "4.8.3"; var NativeCollections; (function (NativeCollections) { var globals = typeof globalThis !== "undefined" ? globalThis : @@ -6031,7 +6031,7 @@ var ts; Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig: diag(2591, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashno_2591", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig: diag(2592, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slash_2592", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery` and then add 'jquery' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig: diag(2593, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_type_2593", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig."), - This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the__2594", "This module is declared with using 'export =', and can only be used with a default import when using the '{0}' flag."), + This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag_2594", "This module is declared with 'export =', and can only be used with a default import when using the '{0}' flag."), _0_can_only_be_imported_by_using_a_default_import: diag(2595, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_default_import_2595", "'{0}' can only be imported by using a default import."), _0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2596, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import_2596", "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import."), _0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import: diag(2597, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import_2597", "'{0}' can only be imported by using a 'require' call or by using a default import."), @@ -36545,7 +36545,7 @@ var ts; var _a, _b; if (path === undefined) return path; - return ts.hostGetCanonicalFileName({ useCaseSensitiveFileNames: useCaseSensitiveFileNames })(ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a))); + return ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a)); } function combineDirectoryPath(root, dir) { return ts.ensureTrailingDirectorySeparator(ts.combinePaths(root, dir)); @@ -36560,7 +36560,7 @@ var ts; if ((extensions === Extensions.TypeScript || extensions === Extensions.JavaScript || extensions === Extensions.Json) && (state.compilerOptions.declarationDir || state.compilerOptions.outDir) && finalPath.indexOf("/node_modules/") === -1 - && (state.compilerOptions.configFile ? ts.startsWith(toAbsolutePath(state.compilerOptions.configFile.fileName), scope.packageDirectory) : true)) { + && (state.compilerOptions.configFile ? ts.containsPath(scope.packageDirectory, toAbsolutePath(state.compilerOptions.configFile.fileName), !useCaseSensitiveFileNames()) : true)) { var getCanonicalFileName = ts.hostGetCanonicalFileName({ useCaseSensitiveFileNames: useCaseSensitiveFileNames }); var commonSourceDirGuesses = []; if (state.compilerOptions.rootDir || (state.compilerOptions.composite && state.compilerOptions.configFilePath)) { @@ -36590,7 +36590,7 @@ var ts; var candidateDirectories = getOutputDirectoriesForBaseDirectory(commonSourceDirGuess); for (var _e = 0, candidateDirectories_1 = candidateDirectories; _e < candidateDirectories_1.length; _e++) { var candidateDir = candidateDirectories_1[_e]; - if (ts.startsWith(finalPath, candidateDir)) { + if (ts.containsPath(candidateDir, finalPath, !useCaseSensitiveFileNames())) { var pathFragment = finalPath.slice(candidateDir.length + 1); var possibleInputBase = ts.combinePaths(commonSourceDirGuess, pathFragment); var jsAndDtsExtensions = [".mjs", ".cjs", ".js", ".json", ".d.mts", ".d.cts", ".d.ts"]; @@ -41875,40 +41875,60 @@ var ts; return typeof file.externalModuleIndicator !== "object" && !resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), undefined, dontResolveAlias); } function getTargetOfImportClause(node, dontResolveAlias) { - var _a; var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier); if (moduleSymbol) { - var exportDefaultSymbol = void 0; - if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { - exportDefaultSymbol = moduleSymbol; - } - else { - exportDefaultSymbol = resolveExportByName(moduleSymbol, "default", node, dontResolveAlias); - } - var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); - var hasDefaultOnly = isOnlyImportedAsDefault(node.parent.moduleSpecifier); - var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, node.parent.moduleSpecifier); - if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { - if (hasExportAssignmentSymbol(moduleSymbol)) { - var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; - var exportEqualsSymbol = moduleSymbol.exports.get("export="); - var exportAssignment = exportEqualsSymbol.valueDeclaration; - var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); - if (exportAssignment) { - ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); - } - } - else { - reportNonDefaultExport(moduleSymbol, node); + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } + function getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias) { + var _a; + var exportDefaultSymbol; + if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { + exportDefaultSymbol = moduleSymbol; + } + else { + exportDefaultSymbol = resolveExportByName(moduleSymbol, "default", node, dontResolveAlias); + } + var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); + var specifier = getModuleSpecifierForImportOrExport(node); + if (!specifier) { + return exportDefaultSymbol; + } + var hasDefaultOnly = isOnlyImportedAsDefault(specifier); + var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, specifier); + if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { + if (hasExportAssignmentSymbol(moduleSymbol)) { + var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; + var exportEqualsSymbol = moduleSymbol.exports.get("export="); + var exportAssignment = exportEqualsSymbol.valueDeclaration; + var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); + if (exportAssignment) { + ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); } } - else if (hasSyntheticDefault || hasDefaultOnly) { - var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); - markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, false); - return resolved; + else if (ts.isImportClause(node)) { + reportNonDefaultExport(moduleSymbol, node); + } + else { + errorNoModuleMemberSymbol(moduleSymbol, moduleSymbol, node, ts.isImportOrExportSpecifier(node) && node.propertyName || node.name); } - markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, undefined, false); - return exportDefaultSymbol; + } + else if (hasSyntheticDefault || hasDefaultOnly) { + var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, false); + return resolved; + } + markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, undefined, false); + return exportDefaultSymbol; + } + function getModuleSpecifierForImportOrExport(node) { + switch (node.kind) { + case 267: return node.parent.moduleSpecifier; + case 265: return ts.isExternalModuleReference(node.moduleReference) ? node.moduleReference.expression : undefined; + case 268: return node.parent.parent.moduleSpecifier; + case 270: return node.parent.parent.parent.moduleSpecifier; + case 275: return node.parent.parent.moduleSpecifier; + default: return ts.Debug.assertNever(node); } } function reportNonDefaultExport(moduleSymbol, node) { @@ -41980,7 +42000,7 @@ var ts; } } function getExternalModuleMember(node, specifier, dontResolveAlias) { - var _a, _b; + var _a; if (dontResolveAlias === void 0) { dontResolveAlias = false; } var moduleSpecifier = ts.getExternalModuleRequireArgument(node) || node.moduleSpecifier; var moduleSymbol = resolveExternalModuleName(node, moduleSpecifier); @@ -42014,29 +42034,33 @@ var ts; combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { - var moduleName = getFullyQualifiedName(moduleSymbol, node); - var declarationName = ts.declarationNameToString(name); - var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); - if (suggestion !== undefined) { - var suggestionName = symbolToString(suggestion); - var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); - if (suggestion.valueDeclaration) { - ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); - } - } - else { - if ((_b = moduleSymbol.exports) === null || _b === void 0 ? void 0 : _b.has("default")) { - error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); - } - else { - reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); - } - } + errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name); } return symbol; } } } + function errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name) { + var _a; + var moduleName = getFullyQualifiedName(moduleSymbol, node); + var declarationName = ts.declarationNameToString(name); + var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); + if (suggestion !== undefined) { + var suggestionName = symbolToString(suggestion); + var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); + if (suggestion.valueDeclaration) { + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); + } + } + else { + if ((_a = moduleSymbol.exports) === null || _a === void 0 ? void 0 : _a.has("default")) { + error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); + } + else { + reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); + } + } + } function reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName) { var _a, _b; var localSymbol = (_b = (_a = moduleSymbol.valueDeclaration) === null || _a === void 0 ? void 0 : _a.locals) === null || _b === void 0 ? void 0 : _b.get(name.escapedText); @@ -42082,6 +42106,13 @@ var ts; } } function getTargetOfImportSpecifier(node, dontResolveAlias) { + if (ts.isImportSpecifier(node) && ts.idText(node.propertyName || node.name) === "default") { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } var root = ts.isBindingElement(node) ? ts.getRootDeclaration(node) : node.parent.parent.parent; var commonJSPropertyAccess = getCommonJSPropertyAccess(root); var resolved = getExternalModuleMember(root, commonJSPropertyAccess || node, dontResolveAlias); @@ -42103,6 +42134,13 @@ var ts; return resolved; } function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) { + if (ts.idText(node.propertyName || node.name) === "default") { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, !!dontResolveAlias); + } + } var resolved = node.parent.parent.moduleSpecifier ? getExternalModuleMember(node.parent.parent, node, dontResolveAlias) : resolveEntityName(node.propertyName || node.name, meaning, false, dontResolveAlias); @@ -51674,7 +51712,7 @@ var ts; return includes & 8388608 ? wildcardType : anyType; } if (!strictNullChecks && includes & 98304) { - return includes & 32768 ? undefinedType : nullType; + return includes & 16777216 ? neverType : includes & 32768 ? undefinedType : nullType; } if (includes & 4 && includes & (128 | 134217728 | 268435456) || includes & 8 && includes & 256 || @@ -52309,7 +52347,7 @@ var ts; type; } function distributeIndexOverObjectType(objectType, indexType, writing) { - if (objectType.flags & 3145728) { + if (objectType.flags & 1048576 || objectType.flags & 2097152 && !shouldDeferIndexType(objectType)) { var types = ts.map(objectType.types, function (t) { return getSimplifiedType(getIndexedAccessType(t, indexType), writing); }); return objectType.flags & 2097152 || writing ? getIntersectionType(types) : getUnionType(types); } @@ -54448,7 +54486,7 @@ var ts; if (reduced !== type) { return reduced; } - if (type.flags & 2097152) { + if (type.flags & 2097152 && ts.some(type.types, isEmptyAnonymousObjectType)) { var normalizedTypes = ts.sameMap(type.types, function (t) { return getNormalizedType(t, writing); }); if (normalizedTypes !== type.types) { return getIntersectionType(normalizedTypes); @@ -55432,7 +55470,7 @@ var ts; if (reportErrors && originalErrorInfo) { resetErrorInfo(saveErrorInfo); } - if (result = isRelatedTo(source, constraint, 2, reportErrors)) { + if (result = isRelatedTo(source, constraint, 2, reportErrors, undefined, intersectionState)) { return result; } if (reportErrors && originalErrorInfo && errorInfo) { @@ -55495,8 +55533,8 @@ var ts; if (!c.root.inferTypeParameters && !isDistributionDependent(c.root)) { var skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); var skipFalse = !skipTrue && isTypeAssignableTo(getRestrictiveInstantiation(c.checkType), getRestrictiveInstantiation(c.extendsType)); - if (result = skipTrue ? -1 : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2, false)) { - result &= skipFalse ? -1 : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2, false); + if (result = skipTrue ? -1 : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2, false, undefined, intersectionState)) { + result &= skipFalse ? -1 : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2, false, undefined, intersectionState); if (result) { return result; } @@ -59855,7 +59893,7 @@ var ts; var narrowedPropType = narrowType(propType); return filterType(type, function (t) { var discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); - return !(narrowedPropType.flags & 131072) && isTypeComparableTo(narrowedPropType, discriminantType); + return !(narrowedPropType.flags & 131072) && areTypesComparable(narrowedPropType, discriminantType); }); } function narrowTypeByDiscriminantProperty(type, access, operator, value, assumeTrue) { @@ -59904,7 +59942,7 @@ var ts; } function narrowByInKeyword(type, name, assumeTrue) { if (type.flags & 1048576 - || type.flags & 524288 && declaredType !== type + || type.flags & 524288 && declaredType !== type && !(declaredType === unknownType && isEmptyAnonymousObjectType(type)) || ts.isThisTypeParameter(type) || type.flags & 2097152 && ts.every(type.types, function (t) { return t.symbol !== globalThisSymbol; })) { return filterType(type, function (t) { return isTypePresencePossible(t, name, assumeTrue); }); @@ -60024,14 +60062,18 @@ var ts; assumeTrue = !assumeTrue; } var valueType = getTypeOfExpression(value); - if ((type.flags & 2) && assumeTrue && (operator === 36 || operator === 37)) { + if (((type.flags & 2) || isEmptyAnonymousObjectType(type) && !(valueType.flags & 98304)) && + assumeTrue && + (operator === 36 || operator === 37)) { if (valueType.flags & (131068 | 67108864)) { return valueType; } if (valueType.flags & 524288) { return nonPrimitiveType; } - return type; + if (type.flags & 2) { + return type; + } } if (valueType.flags & 98304) { if (!strictNullChecks) { @@ -60426,7 +60468,9 @@ var ts; !!(type.flags & 465829888 && getBaseConstraintOrType(type).flags & (98304 | 1048576)); } function isGenericTypeWithoutNullableConstraint(type) { - return !!(type.flags & 465829888 && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304)); + return type.flags & 2097152 ? + ts.some(type.types, isGenericTypeWithoutNullableConstraint) : + !!(type.flags & 465829888 && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304)); } function hasContextualTypeWithNoGenericTypes(node, checkMode) { var contextualType = (ts.isIdentifier(node) || ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) && @@ -105437,9 +105481,7 @@ var ts; } } } - var seenRefs = buildInfoPath ? new ts.Set() : undefined; var buildInfoCacheEntry = state.buildInfoCache.get(resolvedPath); - seenRefs === null || seenRefs === void 0 ? void 0 : seenRefs.add(resolvedPath); var pseudoUpToDate = false; var usesPrepend = false; var upstreamChangedProject; @@ -105450,7 +105492,7 @@ var ts; if (refStatus.newestInputFileTime && refStatus.newestInputFileTime <= oldestOutputFileTime) { continue; } - if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath)) { + if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath)) { return { type: ts.UpToDateStatusType.OutOfDateWithUpstream, outOfDateOutputFileName: buildInfoPath, @@ -105501,24 +105543,9 @@ var ts; oldestOutputFileName: oldestOutputFileName }; } - function hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath) { - if (seenRefs.has(resolvedRefPath)) - return false; - seenRefs.add(resolvedRefPath); + function hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath) { var refBuildInfo = state.buildInfoCache.get(resolvedRefPath); - if (refBuildInfo.path === buildInfoCacheEntry.path) - return true; - if (resolvedConfig.projectReferences) { - for (var _i = 0, _a = resolvedConfig.projectReferences; _i < _a.length; _i++) { - var ref = _a[_i]; - var resolvedRef = ts.resolveProjectReferencePath(ref); - var resolvedRefPath_1 = toResolvedConfigFilePath(state, resolvedRef); - var resolvedConfig_1 = parseConfigFile(state, resolvedRef, resolvedRefPath_1); - if (hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig_1, resolvedRefPath_1)) - return true; - } - } - return false; + return refBuildInfo.path === buildInfoCacheEntry.path; } function getUpToDateStatus(state, project, resolvedPath) { if (project === undefined) { diff --git a/lib/tsserver.js b/lib/tsserver.js index 481cb5866634e..b696263504d68 100644 --- a/lib/tsserver.js +++ b/lib/tsserver.js @@ -109,7 +109,7 @@ var ts; // 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 - ts.version = "4.8.2"; + ts.version = "4.8.3"; /* @internal */ var Comparison; (function (Comparison) { @@ -8875,7 +8875,7 @@ var ts; Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig: diag(2591, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashno_2591", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig: diag(2592, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slash_2592", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery` and then add 'jquery' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig: diag(2593, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_type_2593", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig."), - This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the__2594", "This module is declared with using 'export =', and can only be used with a default import when using the '{0}' flag."), + This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag_2594", "This module is declared with 'export =', and can only be used with a default import when using the '{0}' flag."), _0_can_only_be_imported_by_using_a_default_import: diag(2595, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_default_import_2595", "'{0}' can only be imported by using a default import."), _0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2596, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import_2596", "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import."), _0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import: diag(2597, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import_2597", "'{0}' can only be imported by using a 'require' call or by using a default import."), @@ -44636,7 +44636,7 @@ var ts; var _a, _b; if (path === undefined) return path; - return ts.hostGetCanonicalFileName({ useCaseSensitiveFileNames: useCaseSensitiveFileNames })(ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a))); + return ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a)); } function combineDirectoryPath(root, dir) { return ts.ensureTrailingDirectorySeparator(ts.combinePaths(root, dir)); @@ -44656,7 +44656,7 @@ var ts; if ((extensions === Extensions.TypeScript || extensions === Extensions.JavaScript || extensions === Extensions.Json) && (state.compilerOptions.declarationDir || state.compilerOptions.outDir) && finalPath.indexOf("/node_modules/") === -1 - && (state.compilerOptions.configFile ? ts.startsWith(toAbsolutePath(state.compilerOptions.configFile.fileName), scope.packageDirectory) : true)) { + && (state.compilerOptions.configFile ? ts.containsPath(scope.packageDirectory, toAbsolutePath(state.compilerOptions.configFile.fileName), !useCaseSensitiveFileNames()) : true)) { // So that all means we'll only try these guesses for files outside `node_modules` in a directory where the `package.json` and `tsconfig.json` are siblings. // Even with all that, we still don't know if the root of the output file structure will be (relative to the package file) // `.`, `./src` or any other deeper directory structure. (If project references are used, it's definitely `.` by fiat, so that should be pretty common.) @@ -44712,7 +44712,7 @@ var ts; var candidateDirectories = getOutputDirectoriesForBaseDirectory(commonSourceDirGuess); for (var _e = 0, candidateDirectories_1 = candidateDirectories; _e < candidateDirectories_1.length; _e++) { var candidateDir = candidateDirectories_1[_e]; - if (ts.startsWith(finalPath, candidateDir)) { + if (ts.containsPath(candidateDir, finalPath, !useCaseSensitiveFileNames())) { // The matched export is looking up something in either the out declaration or js dir, now map the written path back into the source dir and source extension var pathFragment = finalPath.slice(candidateDir.length + 1); // +1 to also remove directory seperator var possibleInputBase = ts.combinePaths(commonSourceDirGuess, pathFragment); @@ -50994,41 +50994,61 @@ var ts; return typeof file.externalModuleIndicator !== "object" && !resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias); } function getTargetOfImportClause(node, dontResolveAlias) { - var _a; var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier); if (moduleSymbol) { - var exportDefaultSymbol = void 0; - if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { - exportDefaultSymbol = moduleSymbol; - } - else { - exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* InternalSymbolName.Default */, node, dontResolveAlias); - } - var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); - var hasDefaultOnly = isOnlyImportedAsDefault(node.parent.moduleSpecifier); - var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, node.parent.moduleSpecifier); - if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { - if (hasExportAssignmentSymbol(moduleSymbol)) { - var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; - var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* InternalSymbolName.ExportEquals */); - var exportAssignment = exportEqualsSymbol.valueDeclaration; - var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); - if (exportAssignment) { - ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); - } - } - else { - reportNonDefaultExport(moduleSymbol, node); + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } + function getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias) { + var _a; + var exportDefaultSymbol; + if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { + exportDefaultSymbol = moduleSymbol; + } + else { + exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* InternalSymbolName.Default */, node, dontResolveAlias); + } + var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); + var specifier = getModuleSpecifierForImportOrExport(node); + if (!specifier) { + return exportDefaultSymbol; + } + var hasDefaultOnly = isOnlyImportedAsDefault(specifier); + var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, specifier); + if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { + if (hasExportAssignmentSymbol(moduleSymbol)) { + var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; + var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* InternalSymbolName.ExportEquals */); + var exportAssignment = exportEqualsSymbol.valueDeclaration; + var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); + if (exportAssignment) { + ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); } } - else if (hasSyntheticDefault || hasDefaultOnly) { - // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present - var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); - markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false); - return resolved; + else if (ts.isImportClause(node)) { + reportNonDefaultExport(moduleSymbol, node); } - markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false); - return exportDefaultSymbol; + else { + errorNoModuleMemberSymbol(moduleSymbol, moduleSymbol, node, ts.isImportOrExportSpecifier(node) && node.propertyName || node.name); + } + } + else if (hasSyntheticDefault || hasDefaultOnly) { + // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present + var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false); + return resolved; + } + markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false); + return exportDefaultSymbol; + } + function getModuleSpecifierForImportOrExport(node) { + switch (node.kind) { + case 267 /* SyntaxKind.ImportClause */: return node.parent.moduleSpecifier; + case 265 /* SyntaxKind.ImportEqualsDeclaration */: return ts.isExternalModuleReference(node.moduleReference) ? node.moduleReference.expression : undefined; + case 268 /* SyntaxKind.NamespaceImport */: return node.parent.parent.moduleSpecifier; + case 270 /* SyntaxKind.ImportSpecifier */: return node.parent.parent.parent.moduleSpecifier; + case 275 /* SyntaxKind.ExportSpecifier */: return node.parent.parent.moduleSpecifier; + default: return ts.Debug.assertNever(node); } } function reportNonDefaultExport(moduleSymbol, node) { @@ -51118,7 +51138,7 @@ var ts; } } function getExternalModuleMember(node, specifier, dontResolveAlias) { - var _a, _b; + var _a; if (dontResolveAlias === void 0) { dontResolveAlias = false; } var moduleSpecifier = ts.getExternalModuleRequireArgument(node) || node.moduleSpecifier; var moduleSymbol = resolveExternalModuleName(node, moduleSpecifier); // TODO: GH#18217 @@ -51154,29 +51174,33 @@ var ts; combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { - var moduleName = getFullyQualifiedName(moduleSymbol, node); - var declarationName = ts.declarationNameToString(name); - var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); - if (suggestion !== undefined) { - var suggestionName = symbolToString(suggestion); - var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); - if (suggestion.valueDeclaration) { - ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); - } - } - else { - if ((_b = moduleSymbol.exports) === null || _b === void 0 ? void 0 : _b.has("default" /* InternalSymbolName.Default */)) { - error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); - } - else { - reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); - } - } + errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name); } return symbol; } } } + function errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name) { + var _a; + var moduleName = getFullyQualifiedName(moduleSymbol, node); + var declarationName = ts.declarationNameToString(name); + var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); + if (suggestion !== undefined) { + var suggestionName = symbolToString(suggestion); + var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); + if (suggestion.valueDeclaration) { + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); + } + } + else { + if ((_a = moduleSymbol.exports) === null || _a === void 0 ? void 0 : _a.has("default" /* InternalSymbolName.Default */)) { + error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); + } + else { + reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); + } + } + } function reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName) { var _a, _b; var localSymbol = (_b = (_a = moduleSymbol.valueDeclaration) === null || _a === void 0 ? void 0 : _a.locals) === null || _b === void 0 ? void 0 : _b.get(name.escapedText); @@ -51222,6 +51246,13 @@ var ts; } } function getTargetOfImportSpecifier(node, dontResolveAlias) { + if (ts.isImportSpecifier(node) && ts.idText(node.propertyName || node.name) === "default" /* InternalSymbolName.Default */) { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } var root = ts.isBindingElement(node) ? ts.getRootDeclaration(node) : node.parent.parent.parent; var commonJSPropertyAccess = getCommonJSPropertyAccess(root); var resolved = getExternalModuleMember(root, commonJSPropertyAccess || node, dontResolveAlias); @@ -51243,6 +51274,13 @@ var ts; return resolved; } function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) { + if (ts.idText(node.propertyName || node.name) === "default" /* InternalSymbolName.Default */) { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, !!dontResolveAlias); + } + } var resolved = node.parent.parent.moduleSpecifier ? getExternalModuleMember(node.parent.parent, node, dontResolveAlias) : resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias); @@ -62193,7 +62231,7 @@ var ts; return includes & 8388608 /* TypeFlags.IncludesWildcard */ ? wildcardType : anyType; } if (!strictNullChecks && includes & 98304 /* TypeFlags.Nullable */) { - return includes & 32768 /* TypeFlags.Undefined */ ? undefinedType : nullType; + return includes & 16777216 /* TypeFlags.IncludesEmptyObject */ ? neverType : includes & 32768 /* TypeFlags.Undefined */ ? undefinedType : nullType; } if (includes & 4 /* TypeFlags.String */ && includes & (128 /* TypeFlags.StringLiteral */ | 134217728 /* TypeFlags.TemplateLiteral */ | 268435456 /* TypeFlags.StringMapping */) || includes & 8 /* TypeFlags.Number */ && includes & 256 /* TypeFlags.NumberLiteral */ || @@ -62883,7 +62921,7 @@ var ts; // (T | U)[K] -> T[K] | U[K] (reading) // (T | U)[K] -> T[K] & U[K] (writing) // (T & U)[K] -> T[K] & U[K] - if (objectType.flags & 3145728 /* TypeFlags.UnionOrIntersection */) { + if (objectType.flags & 1048576 /* TypeFlags.Union */ || objectType.flags & 2097152 /* TypeFlags.Intersection */ && !shouldDeferIndexType(objectType)) { var types = ts.map(objectType.types, function (t) { return getSimplifiedType(getIndexedAccessType(t, indexType), writing); }); return objectType.flags & 2097152 /* TypeFlags.Intersection */ || writing ? getIntersectionType(types) : getUnionType(types); } @@ -65291,7 +65329,7 @@ var ts; if (reduced !== type) { return reduced; } - if (type.flags & 2097152 /* TypeFlags.Intersection */) { + if (type.flags & 2097152 /* TypeFlags.Intersection */ && ts.some(type.types, isEmptyAnonymousObjectType)) { var normalizedTypes = ts.sameMap(type.types, function (t) { return getNormalizedType(t, writing); }); if (normalizedTypes !== type.types) { return getIntersectionType(normalizedTypes); @@ -66462,7 +66500,7 @@ var ts; // create a new chain for the constraint error resetErrorInfo(saveErrorInfo); } - if (result = isRelatedTo(source, constraint, 2 /* RecursionFlags.Target */, reportErrors)) { + if (result = isRelatedTo(source, constraint, 2 /* RecursionFlags.Target */, reportErrors, /* headMessage */ undefined, intersectionState)) { return result; } // prefer the shorter chain of the constraint comparison chain, and the direct comparison chain @@ -66554,8 +66592,8 @@ var ts; var skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); var skipFalse = !skipTrue && isTypeAssignableTo(getRestrictiveInstantiation(c.checkType), getRestrictiveInstantiation(c.extendsType)); // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) - if (result = skipTrue ? -1 /* Ternary.True */ : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false)) { - result &= skipFalse ? -1 /* Ternary.True */ : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false); + if (result = skipTrue ? -1 /* Ternary.True */ : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + result &= skipFalse ? -1 /* Ternary.True */ : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); if (result) { return result; } @@ -71584,7 +71622,7 @@ var ts; var narrowedPropType = narrowType(propType); return filterType(type, function (t) { var discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); - return !(narrowedPropType.flags & 131072 /* TypeFlags.Never */) && isTypeComparableTo(narrowedPropType, discriminantType); + return !(narrowedPropType.flags & 131072 /* TypeFlags.Never */) && areTypesComparable(narrowedPropType, discriminantType); }); } function narrowTypeByDiscriminantProperty(type, access, operator, value, assumeTrue) { @@ -71633,7 +71671,7 @@ var ts; } function narrowByInKeyword(type, name, assumeTrue) { if (type.flags & 1048576 /* TypeFlags.Union */ - || type.flags & 524288 /* TypeFlags.Object */ && declaredType !== type + || type.flags & 524288 /* TypeFlags.Object */ && declaredType !== type && !(declaredType === unknownType && isEmptyAnonymousObjectType(type)) || ts.isThisTypeParameter(type) || type.flags & 2097152 /* TypeFlags.Intersection */ && ts.every(type.types, function (t) { return t.symbol !== globalThisSymbol; })) { return filterType(type, function (t) { return isTypePresencePossible(t, name, assumeTrue); }); @@ -71766,14 +71804,18 @@ var ts; assumeTrue = !assumeTrue; } var valueType = getTypeOfExpression(value); - if ((type.flags & 2 /* TypeFlags.Unknown */) && assumeTrue && (operator === 36 /* SyntaxKind.EqualsEqualsEqualsToken */ || operator === 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { + if (((type.flags & 2 /* TypeFlags.Unknown */) || isEmptyAnonymousObjectType(type) && !(valueType.flags & 98304 /* TypeFlags.Nullable */)) && + assumeTrue && + (operator === 36 /* SyntaxKind.EqualsEqualsEqualsToken */ || operator === 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { if (valueType.flags & (131068 /* TypeFlags.Primitive */ | 67108864 /* TypeFlags.NonPrimitive */)) { return valueType; } if (valueType.flags & 524288 /* TypeFlags.Object */) { return nonPrimitiveType; } - return type; + if (type.flags & 2 /* TypeFlags.Unknown */) { + return type; + } } if (valueType.flags & 98304 /* TypeFlags.Nullable */) { if (!strictNullChecks) { @@ -72232,7 +72274,9 @@ var ts; !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && getBaseConstraintOrType(type).flags & (98304 /* TypeFlags.Nullable */ | 1048576 /* TypeFlags.Union */)); } function isGenericTypeWithoutNullableConstraint(type) { - return !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304 /* TypeFlags.Nullable */)); + return type.flags & 2097152 /* TypeFlags.Intersection */ ? + ts.some(type.types, isGenericTypeWithoutNullableConstraint) : + !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304 /* TypeFlags.Nullable */)); } function hasContextualTypeWithNoGenericTypes(node, checkMode) { // Computing the contextual type for a child of a JSX element involves resolving the type of the @@ -126929,9 +126973,7 @@ var ts; } } } - var seenRefs = buildInfoPath ? new ts.Set() : undefined; var buildInfoCacheEntry = state.buildInfoCache.get(resolvedPath); - seenRefs === null || seenRefs === void 0 ? void 0 : seenRefs.add(resolvedPath); /** Inputs are up-to-date, just need either timestamp update or bundle prepend manipulation to make it look up-to-date */ var pseudoUpToDate = false; var usesPrepend = false; @@ -126946,7 +126988,7 @@ var ts; continue; } // Check if tsbuildinfo path is shared, then we need to rebuild - if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath)) { + if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath)) { return { type: ts.UpToDateStatusType.OutOfDateWithUpstream, outOfDateOutputFileName: buildInfoPath, @@ -127004,25 +127046,9 @@ var ts; oldestOutputFileName: oldestOutputFileName }; } - function hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath) { - if (seenRefs.has(resolvedRefPath)) - return false; - seenRefs.add(resolvedRefPath); + function hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath) { var refBuildInfo = state.buildInfoCache.get(resolvedRefPath); - if (refBuildInfo.path === buildInfoCacheEntry.path) - return true; - if (resolvedConfig.projectReferences) { - // Check references - for (var _i = 0, _a = resolvedConfig.projectReferences; _i < _a.length; _i++) { - var ref = _a[_i]; - var resolvedRef = ts.resolveProjectReferencePath(ref); - var resolvedRefPath_1 = toResolvedConfigFilePath(state, resolvedRef); - var resolvedConfig_1 = parseConfigFile(state, resolvedRef, resolvedRefPath_1); - if (hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig_1, resolvedRefPath_1)) - return true; - } - } - return false; + return refBuildInfo.path === buildInfoCacheEntry.path; } function getUpToDateStatus(state, project, resolvedPath) { if (project === undefined) { @@ -171614,13 +171640,13 @@ var ts; return __generator(this, function (_a) { switch (_a.label) { case 0: - ts.Debug.assertIsDefined(host.importServicePlugin); + ts.Debug.assertIsDefined(host.importPlugin); resolvedPath = ts.combinePaths(initialDir, "node_modules"); log("Dynamically importing ".concat(moduleName, " from ").concat(initialDir, " (resolved to ").concat(resolvedPath, ")")); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); - return [4 /*yield*/, host.importServicePlugin(resolvedPath, moduleName)]; + return [4 /*yield*/, host.importPlugin(resolvedPath, moduleName)]; case 2: result = _a.sent(); return [3 /*break*/, 4]; @@ -172699,7 +172725,7 @@ var ts; }; Project.prototype.enableGlobalPlugins = function (options, pluginConfigOverrides) { var host = this.projectService.host; - if (!host.require && !host.importServicePlugin) { + if (!host.require && !host.importPlugin) { this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; } @@ -172756,7 +172782,7 @@ var ts; return __generator(this, function (_a) { switch (_a.label) { case 0: - ts.Debug.assertIsDefined(this.projectService.host.importServicePlugin); + ts.Debug.assertIsDefined(this.projectService.host.importPlugin); log = function (message) { return _this.projectService.logger.info(message); }; logError = function (message) { (errorLogs !== null && errorLogs !== void 0 ? errorLogs : (errorLogs = [])).push(message); @@ -173457,7 +173483,7 @@ var ts; /*@internal*/ ConfiguredProject.prototype.enablePluginsWithOptions = function (options, pluginConfigOverrides) { var host = this.projectService.host; - if (!host.require && !host.importServicePlugin) { + if (!host.require && !host.importPlugin) { this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; } @@ -176901,7 +176927,7 @@ var ts; /*@internal*/ ProjectService.prototype.requestEnablePlugin = function (project, pluginConfigEntry, searchPaths, pluginConfigOverrides) { var _a; - if (!this.host.importServicePlugin && !this.host.require) { + if (!this.host.importPlugin && !this.host.require) { this.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; } @@ -176911,7 +176937,7 @@ var ts; return; } // If the host supports dynamic import, begin enabling the plugin asynchronously. - if (this.host.importServicePlugin) { + if (this.host.importPlugin) { var importPromise = project.beginEnablePluginAsync(pluginConfigEntry, searchPaths, pluginConfigOverrides); (_a = this.pendingPluginEnablements) !== null && _a !== void 0 ? _a : (this.pendingPluginEnablements = new ts.Map()); var promises = this.pendingPluginEnablements.get(project); @@ -181210,7 +181236,7 @@ var ts; setImmediate: function (x) { return setTimeout(x, 0); }, clearImmediate: function (handle) { return clearTimeout(handle); }, /* eslint-enable no-restricted-globals */ - importServicePlugin: function (initialDir, moduleName) { return __awaiter(_this, void 0, void 0, function () { + importPlugin: function (initialDir, moduleName) { return __awaiter(_this, void 0, void 0, function () { var packageRoot, packageJson, packageJsonResponse, e_1, browser, scriptPath, module_1, e_2; return __generator(this, function (_a) { switch (_a.label) { diff --git a/lib/tsserverlibrary.d.ts b/lib/tsserverlibrary.d.ts index 4744d065a38ac..8003ac00a3c64 100644 --- a/lib/tsserverlibrary.d.ts +++ b/lib/tsserverlibrary.d.ts @@ -7033,7 +7033,6 @@ declare namespace ts.server { gc?(): void; trace?(s: string): void; require?(initialPath: string, moduleName: string): ModuleImportResult; - importServicePlugin?(root: string, moduleName: string): Promise; } } declare namespace ts.server { diff --git a/lib/tsserverlibrary.js b/lib/tsserverlibrary.js index 57276bce88f5a..53b8c929ba8f1 100644 --- a/lib/tsserverlibrary.js +++ b/lib/tsserverlibrary.js @@ -303,7 +303,7 @@ var ts; // 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 - ts.version = "4.8.2"; + ts.version = "4.8.3"; /* @internal */ var Comparison; (function (Comparison) { @@ -9069,7 +9069,7 @@ var ts; Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig: diag(2591, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashno_2591", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig: diag(2592, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slash_2592", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery` and then add 'jquery' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig: diag(2593, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_type_2593", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig."), - This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the__2594", "This module is declared with using 'export =', and can only be used with a default import when using the '{0}' flag."), + This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag_2594", "This module is declared with 'export =', and can only be used with a default import when using the '{0}' flag."), _0_can_only_be_imported_by_using_a_default_import: diag(2595, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_default_import_2595", "'{0}' can only be imported by using a default import."), _0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2596, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import_2596", "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import."), _0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import: diag(2597, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import_2597", "'{0}' can only be imported by using a 'require' call or by using a default import."), @@ -44830,7 +44830,7 @@ var ts; var _a, _b; if (path === undefined) return path; - return ts.hostGetCanonicalFileName({ useCaseSensitiveFileNames: useCaseSensitiveFileNames })(ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a))); + return ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a)); } function combineDirectoryPath(root, dir) { return ts.ensureTrailingDirectorySeparator(ts.combinePaths(root, dir)); @@ -44850,7 +44850,7 @@ var ts; if ((extensions === Extensions.TypeScript || extensions === Extensions.JavaScript || extensions === Extensions.Json) && (state.compilerOptions.declarationDir || state.compilerOptions.outDir) && finalPath.indexOf("/node_modules/") === -1 - && (state.compilerOptions.configFile ? ts.startsWith(toAbsolutePath(state.compilerOptions.configFile.fileName), scope.packageDirectory) : true)) { + && (state.compilerOptions.configFile ? ts.containsPath(scope.packageDirectory, toAbsolutePath(state.compilerOptions.configFile.fileName), !useCaseSensitiveFileNames()) : true)) { // So that all means we'll only try these guesses for files outside `node_modules` in a directory where the `package.json` and `tsconfig.json` are siblings. // Even with all that, we still don't know if the root of the output file structure will be (relative to the package file) // `.`, `./src` or any other deeper directory structure. (If project references are used, it's definitely `.` by fiat, so that should be pretty common.) @@ -44906,7 +44906,7 @@ var ts; var candidateDirectories = getOutputDirectoriesForBaseDirectory(commonSourceDirGuess); for (var _e = 0, candidateDirectories_1 = candidateDirectories; _e < candidateDirectories_1.length; _e++) { var candidateDir = candidateDirectories_1[_e]; - if (ts.startsWith(finalPath, candidateDir)) { + if (ts.containsPath(candidateDir, finalPath, !useCaseSensitiveFileNames())) { // The matched export is looking up something in either the out declaration or js dir, now map the written path back into the source dir and source extension var pathFragment = finalPath.slice(candidateDir.length + 1); // +1 to also remove directory seperator var possibleInputBase = ts.combinePaths(commonSourceDirGuess, pathFragment); @@ -51188,41 +51188,61 @@ var ts; return typeof file.externalModuleIndicator !== "object" && !resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias); } function getTargetOfImportClause(node, dontResolveAlias) { - var _a; var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier); if (moduleSymbol) { - var exportDefaultSymbol = void 0; - if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { - exportDefaultSymbol = moduleSymbol; - } - else { - exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* InternalSymbolName.Default */, node, dontResolveAlias); - } - var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); - var hasDefaultOnly = isOnlyImportedAsDefault(node.parent.moduleSpecifier); - var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, node.parent.moduleSpecifier); - if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { - if (hasExportAssignmentSymbol(moduleSymbol)) { - var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; - var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* InternalSymbolName.ExportEquals */); - var exportAssignment = exportEqualsSymbol.valueDeclaration; - var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); - if (exportAssignment) { - ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); - } - } - else { - reportNonDefaultExport(moduleSymbol, node); + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } + function getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias) { + var _a; + var exportDefaultSymbol; + if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { + exportDefaultSymbol = moduleSymbol; + } + else { + exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* InternalSymbolName.Default */, node, dontResolveAlias); + } + var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); + var specifier = getModuleSpecifierForImportOrExport(node); + if (!specifier) { + return exportDefaultSymbol; + } + var hasDefaultOnly = isOnlyImportedAsDefault(specifier); + var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, specifier); + if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { + if (hasExportAssignmentSymbol(moduleSymbol)) { + var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; + var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* InternalSymbolName.ExportEquals */); + var exportAssignment = exportEqualsSymbol.valueDeclaration; + var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); + if (exportAssignment) { + ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); } } - else if (hasSyntheticDefault || hasDefaultOnly) { - // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present - var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); - markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false); - return resolved; + else if (ts.isImportClause(node)) { + reportNonDefaultExport(moduleSymbol, node); } - markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false); - return exportDefaultSymbol; + else { + errorNoModuleMemberSymbol(moduleSymbol, moduleSymbol, node, ts.isImportOrExportSpecifier(node) && node.propertyName || node.name); + } + } + else if (hasSyntheticDefault || hasDefaultOnly) { + // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present + var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false); + return resolved; + } + markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false); + return exportDefaultSymbol; + } + function getModuleSpecifierForImportOrExport(node) { + switch (node.kind) { + case 267 /* SyntaxKind.ImportClause */: return node.parent.moduleSpecifier; + case 265 /* SyntaxKind.ImportEqualsDeclaration */: return ts.isExternalModuleReference(node.moduleReference) ? node.moduleReference.expression : undefined; + case 268 /* SyntaxKind.NamespaceImport */: return node.parent.parent.moduleSpecifier; + case 270 /* SyntaxKind.ImportSpecifier */: return node.parent.parent.parent.moduleSpecifier; + case 275 /* SyntaxKind.ExportSpecifier */: return node.parent.parent.moduleSpecifier; + default: return ts.Debug.assertNever(node); } } function reportNonDefaultExport(moduleSymbol, node) { @@ -51312,7 +51332,7 @@ var ts; } } function getExternalModuleMember(node, specifier, dontResolveAlias) { - var _a, _b; + var _a; if (dontResolveAlias === void 0) { dontResolveAlias = false; } var moduleSpecifier = ts.getExternalModuleRequireArgument(node) || node.moduleSpecifier; var moduleSymbol = resolveExternalModuleName(node, moduleSpecifier); // TODO: GH#18217 @@ -51348,29 +51368,33 @@ var ts; combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { - var moduleName = getFullyQualifiedName(moduleSymbol, node); - var declarationName = ts.declarationNameToString(name); - var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); - if (suggestion !== undefined) { - var suggestionName = symbolToString(suggestion); - var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); - if (suggestion.valueDeclaration) { - ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); - } - } - else { - if ((_b = moduleSymbol.exports) === null || _b === void 0 ? void 0 : _b.has("default" /* InternalSymbolName.Default */)) { - error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); - } - else { - reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); - } - } + errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name); } return symbol; } } } + function errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name) { + var _a; + var moduleName = getFullyQualifiedName(moduleSymbol, node); + var declarationName = ts.declarationNameToString(name); + var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); + if (suggestion !== undefined) { + var suggestionName = symbolToString(suggestion); + var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); + if (suggestion.valueDeclaration) { + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); + } + } + else { + if ((_a = moduleSymbol.exports) === null || _a === void 0 ? void 0 : _a.has("default" /* InternalSymbolName.Default */)) { + error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); + } + else { + reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); + } + } + } function reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName) { var _a, _b; var localSymbol = (_b = (_a = moduleSymbol.valueDeclaration) === null || _a === void 0 ? void 0 : _a.locals) === null || _b === void 0 ? void 0 : _b.get(name.escapedText); @@ -51416,6 +51440,13 @@ var ts; } } function getTargetOfImportSpecifier(node, dontResolveAlias) { + if (ts.isImportSpecifier(node) && ts.idText(node.propertyName || node.name) === "default" /* InternalSymbolName.Default */) { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } var root = ts.isBindingElement(node) ? ts.getRootDeclaration(node) : node.parent.parent.parent; var commonJSPropertyAccess = getCommonJSPropertyAccess(root); var resolved = getExternalModuleMember(root, commonJSPropertyAccess || node, dontResolveAlias); @@ -51437,6 +51468,13 @@ var ts; return resolved; } function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) { + if (ts.idText(node.propertyName || node.name) === "default" /* InternalSymbolName.Default */) { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, !!dontResolveAlias); + } + } var resolved = node.parent.parent.moduleSpecifier ? getExternalModuleMember(node.parent.parent, node, dontResolveAlias) : resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias); @@ -62387,7 +62425,7 @@ var ts; return includes & 8388608 /* TypeFlags.IncludesWildcard */ ? wildcardType : anyType; } if (!strictNullChecks && includes & 98304 /* TypeFlags.Nullable */) { - return includes & 32768 /* TypeFlags.Undefined */ ? undefinedType : nullType; + return includes & 16777216 /* TypeFlags.IncludesEmptyObject */ ? neverType : includes & 32768 /* TypeFlags.Undefined */ ? undefinedType : nullType; } if (includes & 4 /* TypeFlags.String */ && includes & (128 /* TypeFlags.StringLiteral */ | 134217728 /* TypeFlags.TemplateLiteral */ | 268435456 /* TypeFlags.StringMapping */) || includes & 8 /* TypeFlags.Number */ && includes & 256 /* TypeFlags.NumberLiteral */ || @@ -63077,7 +63115,7 @@ var ts; // (T | U)[K] -> T[K] | U[K] (reading) // (T | U)[K] -> T[K] & U[K] (writing) // (T & U)[K] -> T[K] & U[K] - if (objectType.flags & 3145728 /* TypeFlags.UnionOrIntersection */) { + if (objectType.flags & 1048576 /* TypeFlags.Union */ || objectType.flags & 2097152 /* TypeFlags.Intersection */ && !shouldDeferIndexType(objectType)) { var types = ts.map(objectType.types, function (t) { return getSimplifiedType(getIndexedAccessType(t, indexType), writing); }); return objectType.flags & 2097152 /* TypeFlags.Intersection */ || writing ? getIntersectionType(types) : getUnionType(types); } @@ -65485,7 +65523,7 @@ var ts; if (reduced !== type) { return reduced; } - if (type.flags & 2097152 /* TypeFlags.Intersection */) { + if (type.flags & 2097152 /* TypeFlags.Intersection */ && ts.some(type.types, isEmptyAnonymousObjectType)) { var normalizedTypes = ts.sameMap(type.types, function (t) { return getNormalizedType(t, writing); }); if (normalizedTypes !== type.types) { return getIntersectionType(normalizedTypes); @@ -66656,7 +66694,7 @@ var ts; // create a new chain for the constraint error resetErrorInfo(saveErrorInfo); } - if (result = isRelatedTo(source, constraint, 2 /* RecursionFlags.Target */, reportErrors)) { + if (result = isRelatedTo(source, constraint, 2 /* RecursionFlags.Target */, reportErrors, /* headMessage */ undefined, intersectionState)) { return result; } // prefer the shorter chain of the constraint comparison chain, and the direct comparison chain @@ -66748,8 +66786,8 @@ var ts; var skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); var skipFalse = !skipTrue && isTypeAssignableTo(getRestrictiveInstantiation(c.checkType), getRestrictiveInstantiation(c.extendsType)); // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) - if (result = skipTrue ? -1 /* Ternary.True */ : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false)) { - result &= skipFalse ? -1 /* Ternary.True */ : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false); + if (result = skipTrue ? -1 /* Ternary.True */ : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + result &= skipFalse ? -1 /* Ternary.True */ : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); if (result) { return result; } @@ -71778,7 +71816,7 @@ var ts; var narrowedPropType = narrowType(propType); return filterType(type, function (t) { var discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); - return !(narrowedPropType.flags & 131072 /* TypeFlags.Never */) && isTypeComparableTo(narrowedPropType, discriminantType); + return !(narrowedPropType.flags & 131072 /* TypeFlags.Never */) && areTypesComparable(narrowedPropType, discriminantType); }); } function narrowTypeByDiscriminantProperty(type, access, operator, value, assumeTrue) { @@ -71827,7 +71865,7 @@ var ts; } function narrowByInKeyword(type, name, assumeTrue) { if (type.flags & 1048576 /* TypeFlags.Union */ - || type.flags & 524288 /* TypeFlags.Object */ && declaredType !== type + || type.flags & 524288 /* TypeFlags.Object */ && declaredType !== type && !(declaredType === unknownType && isEmptyAnonymousObjectType(type)) || ts.isThisTypeParameter(type) || type.flags & 2097152 /* TypeFlags.Intersection */ && ts.every(type.types, function (t) { return t.symbol !== globalThisSymbol; })) { return filterType(type, function (t) { return isTypePresencePossible(t, name, assumeTrue); }); @@ -71960,14 +71998,18 @@ var ts; assumeTrue = !assumeTrue; } var valueType = getTypeOfExpression(value); - if ((type.flags & 2 /* TypeFlags.Unknown */) && assumeTrue && (operator === 36 /* SyntaxKind.EqualsEqualsEqualsToken */ || operator === 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { + if (((type.flags & 2 /* TypeFlags.Unknown */) || isEmptyAnonymousObjectType(type) && !(valueType.flags & 98304 /* TypeFlags.Nullable */)) && + assumeTrue && + (operator === 36 /* SyntaxKind.EqualsEqualsEqualsToken */ || operator === 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { if (valueType.flags & (131068 /* TypeFlags.Primitive */ | 67108864 /* TypeFlags.NonPrimitive */)) { return valueType; } if (valueType.flags & 524288 /* TypeFlags.Object */) { return nonPrimitiveType; } - return type; + if (type.flags & 2 /* TypeFlags.Unknown */) { + return type; + } } if (valueType.flags & 98304 /* TypeFlags.Nullable */) { if (!strictNullChecks) { @@ -72426,7 +72468,9 @@ var ts; !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && getBaseConstraintOrType(type).flags & (98304 /* TypeFlags.Nullable */ | 1048576 /* TypeFlags.Union */)); } function isGenericTypeWithoutNullableConstraint(type) { - return !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304 /* TypeFlags.Nullable */)); + return type.flags & 2097152 /* TypeFlags.Intersection */ ? + ts.some(type.types, isGenericTypeWithoutNullableConstraint) : + !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304 /* TypeFlags.Nullable */)); } function hasContextualTypeWithNoGenericTypes(node, checkMode) { // Computing the contextual type for a child of a JSX element involves resolving the type of the @@ -127123,9 +127167,7 @@ var ts; } } } - var seenRefs = buildInfoPath ? new ts.Set() : undefined; var buildInfoCacheEntry = state.buildInfoCache.get(resolvedPath); - seenRefs === null || seenRefs === void 0 ? void 0 : seenRefs.add(resolvedPath); /** Inputs are up-to-date, just need either timestamp update or bundle prepend manipulation to make it look up-to-date */ var pseudoUpToDate = false; var usesPrepend = false; @@ -127140,7 +127182,7 @@ var ts; continue; } // Check if tsbuildinfo path is shared, then we need to rebuild - if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath)) { + if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath)) { return { type: ts.UpToDateStatusType.OutOfDateWithUpstream, outOfDateOutputFileName: buildInfoPath, @@ -127198,25 +127240,9 @@ var ts; oldestOutputFileName: oldestOutputFileName }; } - function hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath) { - if (seenRefs.has(resolvedRefPath)) - return false; - seenRefs.add(resolvedRefPath); + function hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath) { var refBuildInfo = state.buildInfoCache.get(resolvedRefPath); - if (refBuildInfo.path === buildInfoCacheEntry.path) - return true; - if (resolvedConfig.projectReferences) { - // Check references - for (var _i = 0, _a = resolvedConfig.projectReferences; _i < _a.length; _i++) { - var ref = _a[_i]; - var resolvedRef = ts.resolveProjectReferencePath(ref); - var resolvedRefPath_1 = toResolvedConfigFilePath(state, resolvedRef); - var resolvedConfig_1 = parseConfigFile(state, resolvedRef, resolvedRefPath_1); - if (hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig_1, resolvedRefPath_1)) - return true; - } - } - return false; + return refBuildInfo.path === buildInfoCacheEntry.path; } function getUpToDateStatus(state, project, resolvedPath) { if (project === undefined) { @@ -171808,13 +171834,13 @@ var ts; return __generator(this, function (_a) { switch (_a.label) { case 0: - ts.Debug.assertIsDefined(host.importServicePlugin); + ts.Debug.assertIsDefined(host.importPlugin); resolvedPath = ts.combinePaths(initialDir, "node_modules"); log("Dynamically importing ".concat(moduleName, " from ").concat(initialDir, " (resolved to ").concat(resolvedPath, ")")); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); - return [4 /*yield*/, host.importServicePlugin(resolvedPath, moduleName)]; + return [4 /*yield*/, host.importPlugin(resolvedPath, moduleName)]; case 2: result = _a.sent(); return [3 /*break*/, 4]; @@ -172893,7 +172919,7 @@ var ts; }; Project.prototype.enableGlobalPlugins = function (options, pluginConfigOverrides) { var host = this.projectService.host; - if (!host.require && !host.importServicePlugin) { + if (!host.require && !host.importPlugin) { this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; } @@ -172950,7 +172976,7 @@ var ts; return __generator(this, function (_a) { switch (_a.label) { case 0: - ts.Debug.assertIsDefined(this.projectService.host.importServicePlugin); + ts.Debug.assertIsDefined(this.projectService.host.importPlugin); log = function (message) { return _this.projectService.logger.info(message); }; logError = function (message) { (errorLogs !== null && errorLogs !== void 0 ? errorLogs : (errorLogs = [])).push(message); @@ -173651,7 +173677,7 @@ var ts; /*@internal*/ ConfiguredProject.prototype.enablePluginsWithOptions = function (options, pluginConfigOverrides) { var host = this.projectService.host; - if (!host.require && !host.importServicePlugin) { + if (!host.require && !host.importPlugin) { this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; } @@ -177095,7 +177121,7 @@ var ts; /*@internal*/ ProjectService.prototype.requestEnablePlugin = function (project, pluginConfigEntry, searchPaths, pluginConfigOverrides) { var _a; - if (!this.host.importServicePlugin && !this.host.require) { + if (!this.host.importPlugin && !this.host.require) { this.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; } @@ -177105,7 +177131,7 @@ var ts; return; } // If the host supports dynamic import, begin enabling the plugin asynchronously. - if (this.host.importServicePlugin) { + if (this.host.importPlugin) { var importPromise = project.beginEnablePluginAsync(pluginConfigEntry, searchPaths, pluginConfigOverrides); (_a = this.pendingPluginEnablements) !== null && _a !== void 0 ? _a : (this.pendingPluginEnablements = new ts.Map()); var promises = this.pendingPluginEnablements.get(project); diff --git a/lib/typescript.js b/lib/typescript.js index 49899ec44b380..3c93c04e0e47a 100644 --- a/lib/typescript.js +++ b/lib/typescript.js @@ -294,7 +294,7 @@ var ts; // 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 - ts.version = "4.8.2"; + ts.version = "4.8.3"; /* @internal */ var Comparison; (function (Comparison) { @@ -9060,7 +9060,7 @@ var ts; Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig: diag(2591, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashno_2591", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig: diag(2592, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slash_2592", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery` and then add 'jquery' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig: diag(2593, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_type_2593", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig."), - This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the__2594", "This module is declared with using 'export =', and can only be used with a default import when using the '{0}' flag."), + This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag_2594", "This module is declared with 'export =', and can only be used with a default import when using the '{0}' flag."), _0_can_only_be_imported_by_using_a_default_import: diag(2595, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_default_import_2595", "'{0}' can only be imported by using a default import."), _0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2596, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import_2596", "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import."), _0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import: diag(2597, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import_2597", "'{0}' can only be imported by using a 'require' call or by using a default import."), @@ -44821,7 +44821,7 @@ var ts; var _a, _b; if (path === undefined) return path; - return ts.hostGetCanonicalFileName({ useCaseSensitiveFileNames: useCaseSensitiveFileNames })(ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a))); + return ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a)); } function combineDirectoryPath(root, dir) { return ts.ensureTrailingDirectorySeparator(ts.combinePaths(root, dir)); @@ -44841,7 +44841,7 @@ var ts; if ((extensions === Extensions.TypeScript || extensions === Extensions.JavaScript || extensions === Extensions.Json) && (state.compilerOptions.declarationDir || state.compilerOptions.outDir) && finalPath.indexOf("/node_modules/") === -1 - && (state.compilerOptions.configFile ? ts.startsWith(toAbsolutePath(state.compilerOptions.configFile.fileName), scope.packageDirectory) : true)) { + && (state.compilerOptions.configFile ? ts.containsPath(scope.packageDirectory, toAbsolutePath(state.compilerOptions.configFile.fileName), !useCaseSensitiveFileNames()) : true)) { // So that all means we'll only try these guesses for files outside `node_modules` in a directory where the `package.json` and `tsconfig.json` are siblings. // Even with all that, we still don't know if the root of the output file structure will be (relative to the package file) // `.`, `./src` or any other deeper directory structure. (If project references are used, it's definitely `.` by fiat, so that should be pretty common.) @@ -44897,7 +44897,7 @@ var ts; var candidateDirectories = getOutputDirectoriesForBaseDirectory(commonSourceDirGuess); for (var _e = 0, candidateDirectories_1 = candidateDirectories; _e < candidateDirectories_1.length; _e++) { var candidateDir = candidateDirectories_1[_e]; - if (ts.startsWith(finalPath, candidateDir)) { + if (ts.containsPath(candidateDir, finalPath, !useCaseSensitiveFileNames())) { // The matched export is looking up something in either the out declaration or js dir, now map the written path back into the source dir and source extension var pathFragment = finalPath.slice(candidateDir.length + 1); // +1 to also remove directory seperator var possibleInputBase = ts.combinePaths(commonSourceDirGuess, pathFragment); @@ -51179,41 +51179,61 @@ var ts; return typeof file.externalModuleIndicator !== "object" && !resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias); } function getTargetOfImportClause(node, dontResolveAlias) { - var _a; var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier); if (moduleSymbol) { - var exportDefaultSymbol = void 0; - if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { - exportDefaultSymbol = moduleSymbol; - } - else { - exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* InternalSymbolName.Default */, node, dontResolveAlias); - } - var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); - var hasDefaultOnly = isOnlyImportedAsDefault(node.parent.moduleSpecifier); - var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, node.parent.moduleSpecifier); - if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { - if (hasExportAssignmentSymbol(moduleSymbol)) { - var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; - var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* InternalSymbolName.ExportEquals */); - var exportAssignment = exportEqualsSymbol.valueDeclaration; - var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); - if (exportAssignment) { - ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); - } - } - else { - reportNonDefaultExport(moduleSymbol, node); + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } + function getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias) { + var _a; + var exportDefaultSymbol; + if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { + exportDefaultSymbol = moduleSymbol; + } + else { + exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* InternalSymbolName.Default */, node, dontResolveAlias); + } + var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); + var specifier = getModuleSpecifierForImportOrExport(node); + if (!specifier) { + return exportDefaultSymbol; + } + var hasDefaultOnly = isOnlyImportedAsDefault(specifier); + var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, specifier); + if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { + if (hasExportAssignmentSymbol(moduleSymbol)) { + var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; + var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* InternalSymbolName.ExportEquals */); + var exportAssignment = exportEqualsSymbol.valueDeclaration; + var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); + if (exportAssignment) { + ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); } } - else if (hasSyntheticDefault || hasDefaultOnly) { - // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present - var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); - markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false); - return resolved; + else if (ts.isImportClause(node)) { + reportNonDefaultExport(moduleSymbol, node); } - markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false); - return exportDefaultSymbol; + else { + errorNoModuleMemberSymbol(moduleSymbol, moduleSymbol, node, ts.isImportOrExportSpecifier(node) && node.propertyName || node.name); + } + } + else if (hasSyntheticDefault || hasDefaultOnly) { + // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present + var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false); + return resolved; + } + markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false); + return exportDefaultSymbol; + } + function getModuleSpecifierForImportOrExport(node) { + switch (node.kind) { + case 267 /* SyntaxKind.ImportClause */: return node.parent.moduleSpecifier; + case 265 /* SyntaxKind.ImportEqualsDeclaration */: return ts.isExternalModuleReference(node.moduleReference) ? node.moduleReference.expression : undefined; + case 268 /* SyntaxKind.NamespaceImport */: return node.parent.parent.moduleSpecifier; + case 270 /* SyntaxKind.ImportSpecifier */: return node.parent.parent.parent.moduleSpecifier; + case 275 /* SyntaxKind.ExportSpecifier */: return node.parent.parent.moduleSpecifier; + default: return ts.Debug.assertNever(node); } } function reportNonDefaultExport(moduleSymbol, node) { @@ -51303,7 +51323,7 @@ var ts; } } function getExternalModuleMember(node, specifier, dontResolveAlias) { - var _a, _b; + var _a; if (dontResolveAlias === void 0) { dontResolveAlias = false; } var moduleSpecifier = ts.getExternalModuleRequireArgument(node) || node.moduleSpecifier; var moduleSymbol = resolveExternalModuleName(node, moduleSpecifier); // TODO: GH#18217 @@ -51339,29 +51359,33 @@ var ts; combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { - var moduleName = getFullyQualifiedName(moduleSymbol, node); - var declarationName = ts.declarationNameToString(name); - var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); - if (suggestion !== undefined) { - var suggestionName = symbolToString(suggestion); - var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); - if (suggestion.valueDeclaration) { - ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); - } - } - else { - if ((_b = moduleSymbol.exports) === null || _b === void 0 ? void 0 : _b.has("default" /* InternalSymbolName.Default */)) { - error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); - } - else { - reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); - } - } + errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name); } return symbol; } } } + function errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name) { + var _a; + var moduleName = getFullyQualifiedName(moduleSymbol, node); + var declarationName = ts.declarationNameToString(name); + var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); + if (suggestion !== undefined) { + var suggestionName = symbolToString(suggestion); + var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); + if (suggestion.valueDeclaration) { + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); + } + } + else { + if ((_a = moduleSymbol.exports) === null || _a === void 0 ? void 0 : _a.has("default" /* InternalSymbolName.Default */)) { + error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); + } + else { + reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); + } + } + } function reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName) { var _a, _b; var localSymbol = (_b = (_a = moduleSymbol.valueDeclaration) === null || _a === void 0 ? void 0 : _a.locals) === null || _b === void 0 ? void 0 : _b.get(name.escapedText); @@ -51407,6 +51431,13 @@ var ts; } } function getTargetOfImportSpecifier(node, dontResolveAlias) { + if (ts.isImportSpecifier(node) && ts.idText(node.propertyName || node.name) === "default" /* InternalSymbolName.Default */) { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } var root = ts.isBindingElement(node) ? ts.getRootDeclaration(node) : node.parent.parent.parent; var commonJSPropertyAccess = getCommonJSPropertyAccess(root); var resolved = getExternalModuleMember(root, commonJSPropertyAccess || node, dontResolveAlias); @@ -51428,6 +51459,13 @@ var ts; return resolved; } function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) { + if (ts.idText(node.propertyName || node.name) === "default" /* InternalSymbolName.Default */) { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, !!dontResolveAlias); + } + } var resolved = node.parent.parent.moduleSpecifier ? getExternalModuleMember(node.parent.parent, node, dontResolveAlias) : resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias); @@ -62378,7 +62416,7 @@ var ts; return includes & 8388608 /* TypeFlags.IncludesWildcard */ ? wildcardType : anyType; } if (!strictNullChecks && includes & 98304 /* TypeFlags.Nullable */) { - return includes & 32768 /* TypeFlags.Undefined */ ? undefinedType : nullType; + return includes & 16777216 /* TypeFlags.IncludesEmptyObject */ ? neverType : includes & 32768 /* TypeFlags.Undefined */ ? undefinedType : nullType; } if (includes & 4 /* TypeFlags.String */ && includes & (128 /* TypeFlags.StringLiteral */ | 134217728 /* TypeFlags.TemplateLiteral */ | 268435456 /* TypeFlags.StringMapping */) || includes & 8 /* TypeFlags.Number */ && includes & 256 /* TypeFlags.NumberLiteral */ || @@ -63068,7 +63106,7 @@ var ts; // (T | U)[K] -> T[K] | U[K] (reading) // (T | U)[K] -> T[K] & U[K] (writing) // (T & U)[K] -> T[K] & U[K] - if (objectType.flags & 3145728 /* TypeFlags.UnionOrIntersection */) { + if (objectType.flags & 1048576 /* TypeFlags.Union */ || objectType.flags & 2097152 /* TypeFlags.Intersection */ && !shouldDeferIndexType(objectType)) { var types = ts.map(objectType.types, function (t) { return getSimplifiedType(getIndexedAccessType(t, indexType), writing); }); return objectType.flags & 2097152 /* TypeFlags.Intersection */ || writing ? getIntersectionType(types) : getUnionType(types); } @@ -65476,7 +65514,7 @@ var ts; if (reduced !== type) { return reduced; } - if (type.flags & 2097152 /* TypeFlags.Intersection */) { + if (type.flags & 2097152 /* TypeFlags.Intersection */ && ts.some(type.types, isEmptyAnonymousObjectType)) { var normalizedTypes = ts.sameMap(type.types, function (t) { return getNormalizedType(t, writing); }); if (normalizedTypes !== type.types) { return getIntersectionType(normalizedTypes); @@ -66647,7 +66685,7 @@ var ts; // create a new chain for the constraint error resetErrorInfo(saveErrorInfo); } - if (result = isRelatedTo(source, constraint, 2 /* RecursionFlags.Target */, reportErrors)) { + if (result = isRelatedTo(source, constraint, 2 /* RecursionFlags.Target */, reportErrors, /* headMessage */ undefined, intersectionState)) { return result; } // prefer the shorter chain of the constraint comparison chain, and the direct comparison chain @@ -66739,8 +66777,8 @@ var ts; var skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); var skipFalse = !skipTrue && isTypeAssignableTo(getRestrictiveInstantiation(c.checkType), getRestrictiveInstantiation(c.extendsType)); // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) - if (result = skipTrue ? -1 /* Ternary.True */ : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false)) { - result &= skipFalse ? -1 /* Ternary.True */ : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false); + if (result = skipTrue ? -1 /* Ternary.True */ : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + result &= skipFalse ? -1 /* Ternary.True */ : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); if (result) { return result; } @@ -71769,7 +71807,7 @@ var ts; var narrowedPropType = narrowType(propType); return filterType(type, function (t) { var discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); - return !(narrowedPropType.flags & 131072 /* TypeFlags.Never */) && isTypeComparableTo(narrowedPropType, discriminantType); + return !(narrowedPropType.flags & 131072 /* TypeFlags.Never */) && areTypesComparable(narrowedPropType, discriminantType); }); } function narrowTypeByDiscriminantProperty(type, access, operator, value, assumeTrue) { @@ -71818,7 +71856,7 @@ var ts; } function narrowByInKeyword(type, name, assumeTrue) { if (type.flags & 1048576 /* TypeFlags.Union */ - || type.flags & 524288 /* TypeFlags.Object */ && declaredType !== type + || type.flags & 524288 /* TypeFlags.Object */ && declaredType !== type && !(declaredType === unknownType && isEmptyAnonymousObjectType(type)) || ts.isThisTypeParameter(type) || type.flags & 2097152 /* TypeFlags.Intersection */ && ts.every(type.types, function (t) { return t.symbol !== globalThisSymbol; })) { return filterType(type, function (t) { return isTypePresencePossible(t, name, assumeTrue); }); @@ -71951,14 +71989,18 @@ var ts; assumeTrue = !assumeTrue; } var valueType = getTypeOfExpression(value); - if ((type.flags & 2 /* TypeFlags.Unknown */) && assumeTrue && (operator === 36 /* SyntaxKind.EqualsEqualsEqualsToken */ || operator === 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { + if (((type.flags & 2 /* TypeFlags.Unknown */) || isEmptyAnonymousObjectType(type) && !(valueType.flags & 98304 /* TypeFlags.Nullable */)) && + assumeTrue && + (operator === 36 /* SyntaxKind.EqualsEqualsEqualsToken */ || operator === 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { if (valueType.flags & (131068 /* TypeFlags.Primitive */ | 67108864 /* TypeFlags.NonPrimitive */)) { return valueType; } if (valueType.flags & 524288 /* TypeFlags.Object */) { return nonPrimitiveType; } - return type; + if (type.flags & 2 /* TypeFlags.Unknown */) { + return type; + } } if (valueType.flags & 98304 /* TypeFlags.Nullable */) { if (!strictNullChecks) { @@ -72417,7 +72459,9 @@ var ts; !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && getBaseConstraintOrType(type).flags & (98304 /* TypeFlags.Nullable */ | 1048576 /* TypeFlags.Union */)); } function isGenericTypeWithoutNullableConstraint(type) { - return !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304 /* TypeFlags.Nullable */)); + return type.flags & 2097152 /* TypeFlags.Intersection */ ? + ts.some(type.types, isGenericTypeWithoutNullableConstraint) : + !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304 /* TypeFlags.Nullable */)); } function hasContextualTypeWithNoGenericTypes(node, checkMode) { // Computing the contextual type for a child of a JSX element involves resolving the type of the @@ -127114,9 +127158,7 @@ var ts; } } } - var seenRefs = buildInfoPath ? new ts.Set() : undefined; var buildInfoCacheEntry = state.buildInfoCache.get(resolvedPath); - seenRefs === null || seenRefs === void 0 ? void 0 : seenRefs.add(resolvedPath); /** Inputs are up-to-date, just need either timestamp update or bundle prepend manipulation to make it look up-to-date */ var pseudoUpToDate = false; var usesPrepend = false; @@ -127131,7 +127173,7 @@ var ts; continue; } // Check if tsbuildinfo path is shared, then we need to rebuild - if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath)) { + if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath)) { return { type: ts.UpToDateStatusType.OutOfDateWithUpstream, outOfDateOutputFileName: buildInfoPath, @@ -127189,25 +127231,9 @@ var ts; oldestOutputFileName: oldestOutputFileName }; } - function hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath) { - if (seenRefs.has(resolvedRefPath)) - return false; - seenRefs.add(resolvedRefPath); + function hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath) { var refBuildInfo = state.buildInfoCache.get(resolvedRefPath); - if (refBuildInfo.path === buildInfoCacheEntry.path) - return true; - if (resolvedConfig.projectReferences) { - // Check references - for (var _i = 0, _a = resolvedConfig.projectReferences; _i < _a.length; _i++) { - var ref = _a[_i]; - var resolvedRef = ts.resolveProjectReferencePath(ref); - var resolvedRefPath_1 = toResolvedConfigFilePath(state, resolvedRef); - var resolvedConfig_1 = parseConfigFile(state, resolvedRef, resolvedRefPath_1); - if (hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig_1, resolvedRefPath_1)) - return true; - } - } - return false; + return refBuildInfo.path === buildInfoCacheEntry.path; } function getUpToDateStatus(state, project, resolvedPath) { if (project === undefined) { diff --git a/lib/typescriptServices.js b/lib/typescriptServices.js index 9e45164b7c4c9..61b1259b561f8 100644 --- a/lib/typescriptServices.js +++ b/lib/typescriptServices.js @@ -294,7 +294,7 @@ var ts; // 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 - ts.version = "4.8.2"; + ts.version = "4.8.3"; /* @internal */ var Comparison; (function (Comparison) { @@ -9060,7 +9060,7 @@ var ts; Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig: diag(2591, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashno_2591", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig: diag(2592, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slash_2592", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery` and then add 'jquery' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig: diag(2593, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_type_2593", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig."), - This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the__2594", "This module is declared with using 'export =', and can only be used with a default import when using the '{0}' flag."), + This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag_2594", "This module is declared with 'export =', and can only be used with a default import when using the '{0}' flag."), _0_can_only_be_imported_by_using_a_default_import: diag(2595, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_default_import_2595", "'{0}' can only be imported by using a default import."), _0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2596, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import_2596", "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import."), _0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import: diag(2597, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import_2597", "'{0}' can only be imported by using a 'require' call or by using a default import."), @@ -44821,7 +44821,7 @@ var ts; var _a, _b; if (path === undefined) return path; - return ts.hostGetCanonicalFileName({ useCaseSensitiveFileNames: useCaseSensitiveFileNames })(ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a))); + return ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a)); } function combineDirectoryPath(root, dir) { return ts.ensureTrailingDirectorySeparator(ts.combinePaths(root, dir)); @@ -44841,7 +44841,7 @@ var ts; if ((extensions === Extensions.TypeScript || extensions === Extensions.JavaScript || extensions === Extensions.Json) && (state.compilerOptions.declarationDir || state.compilerOptions.outDir) && finalPath.indexOf("/node_modules/") === -1 - && (state.compilerOptions.configFile ? ts.startsWith(toAbsolutePath(state.compilerOptions.configFile.fileName), scope.packageDirectory) : true)) { + && (state.compilerOptions.configFile ? ts.containsPath(scope.packageDirectory, toAbsolutePath(state.compilerOptions.configFile.fileName), !useCaseSensitiveFileNames()) : true)) { // So that all means we'll only try these guesses for files outside `node_modules` in a directory where the `package.json` and `tsconfig.json` are siblings. // Even with all that, we still don't know if the root of the output file structure will be (relative to the package file) // `.`, `./src` or any other deeper directory structure. (If project references are used, it's definitely `.` by fiat, so that should be pretty common.) @@ -44897,7 +44897,7 @@ var ts; var candidateDirectories = getOutputDirectoriesForBaseDirectory(commonSourceDirGuess); for (var _e = 0, candidateDirectories_1 = candidateDirectories; _e < candidateDirectories_1.length; _e++) { var candidateDir = candidateDirectories_1[_e]; - if (ts.startsWith(finalPath, candidateDir)) { + if (ts.containsPath(candidateDir, finalPath, !useCaseSensitiveFileNames())) { // The matched export is looking up something in either the out declaration or js dir, now map the written path back into the source dir and source extension var pathFragment = finalPath.slice(candidateDir.length + 1); // +1 to also remove directory seperator var possibleInputBase = ts.combinePaths(commonSourceDirGuess, pathFragment); @@ -51179,41 +51179,61 @@ var ts; return typeof file.externalModuleIndicator !== "object" && !resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias); } function getTargetOfImportClause(node, dontResolveAlias) { - var _a; var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier); if (moduleSymbol) { - var exportDefaultSymbol = void 0; - if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { - exportDefaultSymbol = moduleSymbol; - } - else { - exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* InternalSymbolName.Default */, node, dontResolveAlias); - } - var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); - var hasDefaultOnly = isOnlyImportedAsDefault(node.parent.moduleSpecifier); - var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, node.parent.moduleSpecifier); - if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { - if (hasExportAssignmentSymbol(moduleSymbol)) { - var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; - var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* InternalSymbolName.ExportEquals */); - var exportAssignment = exportEqualsSymbol.valueDeclaration; - var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); - if (exportAssignment) { - ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); - } - } - else { - reportNonDefaultExport(moduleSymbol, node); + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } + function getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias) { + var _a; + var exportDefaultSymbol; + if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { + exportDefaultSymbol = moduleSymbol; + } + else { + exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* InternalSymbolName.Default */, node, dontResolveAlias); + } + var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); + var specifier = getModuleSpecifierForImportOrExport(node); + if (!specifier) { + return exportDefaultSymbol; + } + var hasDefaultOnly = isOnlyImportedAsDefault(specifier); + var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, specifier); + if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { + if (hasExportAssignmentSymbol(moduleSymbol)) { + var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; + var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* InternalSymbolName.ExportEquals */); + var exportAssignment = exportEqualsSymbol.valueDeclaration; + var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); + if (exportAssignment) { + ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); } } - else if (hasSyntheticDefault || hasDefaultOnly) { - // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present - var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); - markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false); - return resolved; + else if (ts.isImportClause(node)) { + reportNonDefaultExport(moduleSymbol, node); } - markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false); - return exportDefaultSymbol; + else { + errorNoModuleMemberSymbol(moduleSymbol, moduleSymbol, node, ts.isImportOrExportSpecifier(node) && node.propertyName || node.name); + } + } + else if (hasSyntheticDefault || hasDefaultOnly) { + // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present + var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false); + return resolved; + } + markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false); + return exportDefaultSymbol; + } + function getModuleSpecifierForImportOrExport(node) { + switch (node.kind) { + case 267 /* SyntaxKind.ImportClause */: return node.parent.moduleSpecifier; + case 265 /* SyntaxKind.ImportEqualsDeclaration */: return ts.isExternalModuleReference(node.moduleReference) ? node.moduleReference.expression : undefined; + case 268 /* SyntaxKind.NamespaceImport */: return node.parent.parent.moduleSpecifier; + case 270 /* SyntaxKind.ImportSpecifier */: return node.parent.parent.parent.moduleSpecifier; + case 275 /* SyntaxKind.ExportSpecifier */: return node.parent.parent.moduleSpecifier; + default: return ts.Debug.assertNever(node); } } function reportNonDefaultExport(moduleSymbol, node) { @@ -51303,7 +51323,7 @@ var ts; } } function getExternalModuleMember(node, specifier, dontResolveAlias) { - var _a, _b; + var _a; if (dontResolveAlias === void 0) { dontResolveAlias = false; } var moduleSpecifier = ts.getExternalModuleRequireArgument(node) || node.moduleSpecifier; var moduleSymbol = resolveExternalModuleName(node, moduleSpecifier); // TODO: GH#18217 @@ -51339,29 +51359,33 @@ var ts; combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { - var moduleName = getFullyQualifiedName(moduleSymbol, node); - var declarationName = ts.declarationNameToString(name); - var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); - if (suggestion !== undefined) { - var suggestionName = symbolToString(suggestion); - var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); - if (suggestion.valueDeclaration) { - ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); - } - } - else { - if ((_b = moduleSymbol.exports) === null || _b === void 0 ? void 0 : _b.has("default" /* InternalSymbolName.Default */)) { - error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); - } - else { - reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); - } - } + errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name); } return symbol; } } } + function errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name) { + var _a; + var moduleName = getFullyQualifiedName(moduleSymbol, node); + var declarationName = ts.declarationNameToString(name); + var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); + if (suggestion !== undefined) { + var suggestionName = symbolToString(suggestion); + var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); + if (suggestion.valueDeclaration) { + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); + } + } + else { + if ((_a = moduleSymbol.exports) === null || _a === void 0 ? void 0 : _a.has("default" /* InternalSymbolName.Default */)) { + error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); + } + else { + reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); + } + } + } function reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName) { var _a, _b; var localSymbol = (_b = (_a = moduleSymbol.valueDeclaration) === null || _a === void 0 ? void 0 : _a.locals) === null || _b === void 0 ? void 0 : _b.get(name.escapedText); @@ -51407,6 +51431,13 @@ var ts; } } function getTargetOfImportSpecifier(node, dontResolveAlias) { + if (ts.isImportSpecifier(node) && ts.idText(node.propertyName || node.name) === "default" /* InternalSymbolName.Default */) { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } var root = ts.isBindingElement(node) ? ts.getRootDeclaration(node) : node.parent.parent.parent; var commonJSPropertyAccess = getCommonJSPropertyAccess(root); var resolved = getExternalModuleMember(root, commonJSPropertyAccess || node, dontResolveAlias); @@ -51428,6 +51459,13 @@ var ts; return resolved; } function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) { + if (ts.idText(node.propertyName || node.name) === "default" /* InternalSymbolName.Default */) { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, !!dontResolveAlias); + } + } var resolved = node.parent.parent.moduleSpecifier ? getExternalModuleMember(node.parent.parent, node, dontResolveAlias) : resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias); @@ -62378,7 +62416,7 @@ var ts; return includes & 8388608 /* TypeFlags.IncludesWildcard */ ? wildcardType : anyType; } if (!strictNullChecks && includes & 98304 /* TypeFlags.Nullable */) { - return includes & 32768 /* TypeFlags.Undefined */ ? undefinedType : nullType; + return includes & 16777216 /* TypeFlags.IncludesEmptyObject */ ? neverType : includes & 32768 /* TypeFlags.Undefined */ ? undefinedType : nullType; } if (includes & 4 /* TypeFlags.String */ && includes & (128 /* TypeFlags.StringLiteral */ | 134217728 /* TypeFlags.TemplateLiteral */ | 268435456 /* TypeFlags.StringMapping */) || includes & 8 /* TypeFlags.Number */ && includes & 256 /* TypeFlags.NumberLiteral */ || @@ -63068,7 +63106,7 @@ var ts; // (T | U)[K] -> T[K] | U[K] (reading) // (T | U)[K] -> T[K] & U[K] (writing) // (T & U)[K] -> T[K] & U[K] - if (objectType.flags & 3145728 /* TypeFlags.UnionOrIntersection */) { + if (objectType.flags & 1048576 /* TypeFlags.Union */ || objectType.flags & 2097152 /* TypeFlags.Intersection */ && !shouldDeferIndexType(objectType)) { var types = ts.map(objectType.types, function (t) { return getSimplifiedType(getIndexedAccessType(t, indexType), writing); }); return objectType.flags & 2097152 /* TypeFlags.Intersection */ || writing ? getIntersectionType(types) : getUnionType(types); } @@ -65476,7 +65514,7 @@ var ts; if (reduced !== type) { return reduced; } - if (type.flags & 2097152 /* TypeFlags.Intersection */) { + if (type.flags & 2097152 /* TypeFlags.Intersection */ && ts.some(type.types, isEmptyAnonymousObjectType)) { var normalizedTypes = ts.sameMap(type.types, function (t) { return getNormalizedType(t, writing); }); if (normalizedTypes !== type.types) { return getIntersectionType(normalizedTypes); @@ -66647,7 +66685,7 @@ var ts; // create a new chain for the constraint error resetErrorInfo(saveErrorInfo); } - if (result = isRelatedTo(source, constraint, 2 /* RecursionFlags.Target */, reportErrors)) { + if (result = isRelatedTo(source, constraint, 2 /* RecursionFlags.Target */, reportErrors, /* headMessage */ undefined, intersectionState)) { return result; } // prefer the shorter chain of the constraint comparison chain, and the direct comparison chain @@ -66739,8 +66777,8 @@ var ts; var skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); var skipFalse = !skipTrue && isTypeAssignableTo(getRestrictiveInstantiation(c.checkType), getRestrictiveInstantiation(c.extendsType)); // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) - if (result = skipTrue ? -1 /* Ternary.True */ : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false)) { - result &= skipFalse ? -1 /* Ternary.True */ : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false); + if (result = skipTrue ? -1 /* Ternary.True */ : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + result &= skipFalse ? -1 /* Ternary.True */ : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); if (result) { return result; } @@ -71769,7 +71807,7 @@ var ts; var narrowedPropType = narrowType(propType); return filterType(type, function (t) { var discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); - return !(narrowedPropType.flags & 131072 /* TypeFlags.Never */) && isTypeComparableTo(narrowedPropType, discriminantType); + return !(narrowedPropType.flags & 131072 /* TypeFlags.Never */) && areTypesComparable(narrowedPropType, discriminantType); }); } function narrowTypeByDiscriminantProperty(type, access, operator, value, assumeTrue) { @@ -71818,7 +71856,7 @@ var ts; } function narrowByInKeyword(type, name, assumeTrue) { if (type.flags & 1048576 /* TypeFlags.Union */ - || type.flags & 524288 /* TypeFlags.Object */ && declaredType !== type + || type.flags & 524288 /* TypeFlags.Object */ && declaredType !== type && !(declaredType === unknownType && isEmptyAnonymousObjectType(type)) || ts.isThisTypeParameter(type) || type.flags & 2097152 /* TypeFlags.Intersection */ && ts.every(type.types, function (t) { return t.symbol !== globalThisSymbol; })) { return filterType(type, function (t) { return isTypePresencePossible(t, name, assumeTrue); }); @@ -71951,14 +71989,18 @@ var ts; assumeTrue = !assumeTrue; } var valueType = getTypeOfExpression(value); - if ((type.flags & 2 /* TypeFlags.Unknown */) && assumeTrue && (operator === 36 /* SyntaxKind.EqualsEqualsEqualsToken */ || operator === 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { + if (((type.flags & 2 /* TypeFlags.Unknown */) || isEmptyAnonymousObjectType(type) && !(valueType.flags & 98304 /* TypeFlags.Nullable */)) && + assumeTrue && + (operator === 36 /* SyntaxKind.EqualsEqualsEqualsToken */ || operator === 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { if (valueType.flags & (131068 /* TypeFlags.Primitive */ | 67108864 /* TypeFlags.NonPrimitive */)) { return valueType; } if (valueType.flags & 524288 /* TypeFlags.Object */) { return nonPrimitiveType; } - return type; + if (type.flags & 2 /* TypeFlags.Unknown */) { + return type; + } } if (valueType.flags & 98304 /* TypeFlags.Nullable */) { if (!strictNullChecks) { @@ -72417,7 +72459,9 @@ var ts; !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && getBaseConstraintOrType(type).flags & (98304 /* TypeFlags.Nullable */ | 1048576 /* TypeFlags.Union */)); } function isGenericTypeWithoutNullableConstraint(type) { - return !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304 /* TypeFlags.Nullable */)); + return type.flags & 2097152 /* TypeFlags.Intersection */ ? + ts.some(type.types, isGenericTypeWithoutNullableConstraint) : + !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304 /* TypeFlags.Nullable */)); } function hasContextualTypeWithNoGenericTypes(node, checkMode) { // Computing the contextual type for a child of a JSX element involves resolving the type of the @@ -127114,9 +127158,7 @@ var ts; } } } - var seenRefs = buildInfoPath ? new ts.Set() : undefined; var buildInfoCacheEntry = state.buildInfoCache.get(resolvedPath); - seenRefs === null || seenRefs === void 0 ? void 0 : seenRefs.add(resolvedPath); /** Inputs are up-to-date, just need either timestamp update or bundle prepend manipulation to make it look up-to-date */ var pseudoUpToDate = false; var usesPrepend = false; @@ -127131,7 +127173,7 @@ var ts; continue; } // Check if tsbuildinfo path is shared, then we need to rebuild - if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath)) { + if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath)) { return { type: ts.UpToDateStatusType.OutOfDateWithUpstream, outOfDateOutputFileName: buildInfoPath, @@ -127189,25 +127231,9 @@ var ts; oldestOutputFileName: oldestOutputFileName }; } - function hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath) { - if (seenRefs.has(resolvedRefPath)) - return false; - seenRefs.add(resolvedRefPath); + function hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath) { var refBuildInfo = state.buildInfoCache.get(resolvedRefPath); - if (refBuildInfo.path === buildInfoCacheEntry.path) - return true; - if (resolvedConfig.projectReferences) { - // Check references - for (var _i = 0, _a = resolvedConfig.projectReferences; _i < _a.length; _i++) { - var ref = _a[_i]; - var resolvedRef = ts.resolveProjectReferencePath(ref); - var resolvedRefPath_1 = toResolvedConfigFilePath(state, resolvedRef); - var resolvedConfig_1 = parseConfigFile(state, resolvedRef, resolvedRefPath_1); - if (hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig_1, resolvedRefPath_1)) - return true; - } - } - return false; + return refBuildInfo.path === buildInfoCacheEntry.path; } function getUpToDateStatus(state, project, resolvedPath) { if (project === undefined) { diff --git a/lib/typingsInstaller.js b/lib/typingsInstaller.js index 8ab14c8266cf2..9303e787c1ef4 100644 --- a/lib/typingsInstaller.js +++ b/lib/typingsInstaller.js @@ -89,7 +89,7 @@ var ts; // 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 - ts.version = "4.8.2"; + ts.version = "4.8.3"; /* @internal */ var Comparison; (function (Comparison) { @@ -8855,7 +8855,7 @@ var ts; Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashnode_and_then_add_node_to_the_types_field_in_your_tsconfig: diag(2591, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_node_Try_npm_i_save_dev_types_Slashno_2591", "Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slashjquery_and_then_add_jquery_to_the_types_field_in_your_tsconfig: diag(2592, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_jQuery_Try_npm_i_save_dev_types_Slash_2592", "Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i --save-dev @types/jquery` and then add 'jquery' to the types field in your tsconfig."), Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_types_Slashjest_or_npm_i_save_dev_types_Slashmocha_and_then_add_jest_or_mocha_to_the_types_field_in_your_tsconfig: diag(2593, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Do_you_need_to_install_type_definitions_for_a_test_runner_Try_npm_i_save_dev_type_2593", "Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig."), - This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the__2594", "This module is declared with using 'export =', and can only be used with a default import when using the '{0}' flag."), + This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag: diag(2594, ts.DiagnosticCategory.Error, "This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag_2594", "This module is declared with 'export =', and can only be used with a default import when using the '{0}' flag."), _0_can_only_be_imported_by_using_a_default_import: diag(2595, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_default_import_2595", "'{0}' can only be imported by using a default import."), _0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import: diag(2596, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_turning_on_the_esModuleInterop_flag_and_using_a_default_import_2596", "'{0}' can only be imported by turning on the 'esModuleInterop' flag and using a default import."), _0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import: diag(2597, ts.DiagnosticCategory.Error, "_0_can_only_be_imported_by_using_a_require_call_or_by_using_a_default_import_2597", "'{0}' can only be imported by using a 'require' call or by using a default import."), @@ -44616,7 +44616,7 @@ var ts; var _a, _b; if (path === undefined) return path; - return ts.hostGetCanonicalFileName({ useCaseSensitiveFileNames: useCaseSensitiveFileNames })(ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a))); + return ts.getNormalizedAbsolutePath(path, (_b = (_a = state.host).getCurrentDirectory) === null || _b === void 0 ? void 0 : _b.call(_a)); } function combineDirectoryPath(root, dir) { return ts.ensureTrailingDirectorySeparator(ts.combinePaths(root, dir)); @@ -44636,7 +44636,7 @@ var ts; if ((extensions === Extensions.TypeScript || extensions === Extensions.JavaScript || extensions === Extensions.Json) && (state.compilerOptions.declarationDir || state.compilerOptions.outDir) && finalPath.indexOf("/node_modules/") === -1 - && (state.compilerOptions.configFile ? ts.startsWith(toAbsolutePath(state.compilerOptions.configFile.fileName), scope.packageDirectory) : true)) { + && (state.compilerOptions.configFile ? ts.containsPath(scope.packageDirectory, toAbsolutePath(state.compilerOptions.configFile.fileName), !useCaseSensitiveFileNames()) : true)) { // So that all means we'll only try these guesses for files outside `node_modules` in a directory where the `package.json` and `tsconfig.json` are siblings. // Even with all that, we still don't know if the root of the output file structure will be (relative to the package file) // `.`, `./src` or any other deeper directory structure. (If project references are used, it's definitely `.` by fiat, so that should be pretty common.) @@ -44692,7 +44692,7 @@ var ts; var candidateDirectories = getOutputDirectoriesForBaseDirectory(commonSourceDirGuess); for (var _e = 0, candidateDirectories_1 = candidateDirectories; _e < candidateDirectories_1.length; _e++) { var candidateDir = candidateDirectories_1[_e]; - if (ts.startsWith(finalPath, candidateDir)) { + if (ts.containsPath(candidateDir, finalPath, !useCaseSensitiveFileNames())) { // The matched export is looking up something in either the out declaration or js dir, now map the written path back into the source dir and source extension var pathFragment = finalPath.slice(candidateDir.length + 1); // +1 to also remove directory seperator var possibleInputBase = ts.combinePaths(commonSourceDirGuess, pathFragment); @@ -50974,41 +50974,61 @@ var ts; return typeof file.externalModuleIndicator !== "object" && !resolveExportByName(moduleSymbol, ts.escapeLeadingUnderscores("__esModule"), /*sourceNode*/ undefined, dontResolveAlias); } function getTargetOfImportClause(node, dontResolveAlias) { - var _a; var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier); if (moduleSymbol) { - var exportDefaultSymbol = void 0; - if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { - exportDefaultSymbol = moduleSymbol; - } - else { - exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* InternalSymbolName.Default */, node, dontResolveAlias); - } - var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); - var hasDefaultOnly = isOnlyImportedAsDefault(node.parent.moduleSpecifier); - var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, node.parent.moduleSpecifier); - if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { - if (hasExportAssignmentSymbol(moduleSymbol)) { - var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; - var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* InternalSymbolName.ExportEquals */); - var exportAssignment = exportEqualsSymbol.valueDeclaration; - var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); - if (exportAssignment) { - ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_using_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); - } - } - else { - reportNonDefaultExport(moduleSymbol, node); + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } + function getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias) { + var _a; + var exportDefaultSymbol; + if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { + exportDefaultSymbol = moduleSymbol; + } + else { + exportDefaultSymbol = resolveExportByName(moduleSymbol, "default" /* InternalSymbolName.Default */, node, dontResolveAlias); + } + var file = (_a = moduleSymbol.declarations) === null || _a === void 0 ? void 0 : _a.find(ts.isSourceFile); + var specifier = getModuleSpecifierForImportOrExport(node); + if (!specifier) { + return exportDefaultSymbol; + } + var hasDefaultOnly = isOnlyImportedAsDefault(specifier); + var hasSyntheticDefault = canHaveSyntheticDefault(file, moduleSymbol, dontResolveAlias, specifier); + if (!exportDefaultSymbol && !hasSyntheticDefault && !hasDefaultOnly) { + if (hasExportAssignmentSymbol(moduleSymbol)) { + var compilerOptionName = moduleKind >= ts.ModuleKind.ES2015 ? "allowSyntheticDefaultImports" : "esModuleInterop"; + var exportEqualsSymbol = moduleSymbol.exports.get("export=" /* InternalSymbolName.ExportEquals */); + var exportAssignment = exportEqualsSymbol.valueDeclaration; + var err = error(node.name, ts.Diagnostics.Module_0_can_only_be_default_imported_using_the_1_flag, symbolToString(moduleSymbol), compilerOptionName); + if (exportAssignment) { + ts.addRelatedInfo(err, ts.createDiagnosticForNode(exportAssignment, ts.Diagnostics.This_module_is_declared_with_export_and_can_only_be_used_with_a_default_import_when_using_the_0_flag, compilerOptionName)); } } - else if (hasSyntheticDefault || hasDefaultOnly) { - // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present - var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); - markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false); - return resolved; + else if (ts.isImportClause(node)) { + reportNonDefaultExport(moduleSymbol, node); + } + else { + errorNoModuleMemberSymbol(moduleSymbol, moduleSymbol, node, ts.isImportOrExportSpecifier(node) && node.propertyName || node.name); } - markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false); - return exportDefaultSymbol; + } + else if (hasSyntheticDefault || hasDefaultOnly) { + // per emit behavior, a synthetic default overrides a "real" .default member if `__esModule` is not present + var resolved = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); + markSymbolOfAliasDeclarationIfTypeOnly(node, moduleSymbol, resolved, /*overwriteTypeOnly*/ false); + return resolved; + } + markSymbolOfAliasDeclarationIfTypeOnly(node, exportDefaultSymbol, /*finalTarget*/ undefined, /*overwriteTypeOnly*/ false); + return exportDefaultSymbol; + } + function getModuleSpecifierForImportOrExport(node) { + switch (node.kind) { + case 267 /* SyntaxKind.ImportClause */: return node.parent.moduleSpecifier; + case 265 /* SyntaxKind.ImportEqualsDeclaration */: return ts.isExternalModuleReference(node.moduleReference) ? node.moduleReference.expression : undefined; + case 268 /* SyntaxKind.NamespaceImport */: return node.parent.parent.moduleSpecifier; + case 270 /* SyntaxKind.ImportSpecifier */: return node.parent.parent.parent.moduleSpecifier; + case 275 /* SyntaxKind.ExportSpecifier */: return node.parent.parent.moduleSpecifier; + default: return ts.Debug.assertNever(node); } } function reportNonDefaultExport(moduleSymbol, node) { @@ -51098,7 +51118,7 @@ var ts; } } function getExternalModuleMember(node, specifier, dontResolveAlias) { - var _a, _b; + var _a; if (dontResolveAlias === void 0) { dontResolveAlias = false; } var moduleSpecifier = ts.getExternalModuleRequireArgument(node) || node.moduleSpecifier; var moduleSymbol = resolveExternalModuleName(node, moduleSpecifier); // TODO: GH#18217 @@ -51134,29 +51154,33 @@ var ts; combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { - var moduleName = getFullyQualifiedName(moduleSymbol, node); - var declarationName = ts.declarationNameToString(name); - var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); - if (suggestion !== undefined) { - var suggestionName = symbolToString(suggestion); - var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); - if (suggestion.valueDeclaration) { - ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); - } - } - else { - if ((_b = moduleSymbol.exports) === null || _b === void 0 ? void 0 : _b.has("default" /* InternalSymbolName.Default */)) { - error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); - } - else { - reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); - } - } + errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name); } return symbol; } } } + function errorNoModuleMemberSymbol(moduleSymbol, targetSymbol, node, name) { + var _a; + var moduleName = getFullyQualifiedName(moduleSymbol, node); + var declarationName = ts.declarationNameToString(name); + var suggestion = getSuggestedSymbolForNonexistentModule(name, targetSymbol); + if (suggestion !== undefined) { + var suggestionName = symbolToString(suggestion); + var diagnostic = error(name, ts.Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, moduleName, declarationName, suggestionName); + if (suggestion.valueDeclaration) { + ts.addRelatedInfo(diagnostic, ts.createDiagnosticForNode(suggestion.valueDeclaration, ts.Diagnostics._0_is_declared_here, suggestionName)); + } + } + else { + if ((_a = moduleSymbol.exports) === null || _a === void 0 ? void 0 : _a.has("default" /* InternalSymbolName.Default */)) { + error(name, ts.Diagnostics.Module_0_has_no_exported_member_1_Did_you_mean_to_use_import_1_from_0_instead, moduleName, declarationName); + } + else { + reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName); + } + } + } function reportNonExportedMember(node, name, declarationName, moduleSymbol, moduleName) { var _a, _b; var localSymbol = (_b = (_a = moduleSymbol.valueDeclaration) === null || _a === void 0 ? void 0 : _a.locals) === null || _b === void 0 ? void 0 : _b.get(name.escapedText); @@ -51202,6 +51226,13 @@ var ts; } } function getTargetOfImportSpecifier(node, dontResolveAlias) { + if (ts.isImportSpecifier(node) && ts.idText(node.propertyName || node.name) === "default" /* InternalSymbolName.Default */) { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, dontResolveAlias); + } + } var root = ts.isBindingElement(node) ? ts.getRootDeclaration(node) : node.parent.parent.parent; var commonJSPropertyAccess = getCommonJSPropertyAccess(root); var resolved = getExternalModuleMember(root, commonJSPropertyAccess || node, dontResolveAlias); @@ -51223,6 +51254,13 @@ var ts; return resolved; } function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) { + if (ts.idText(node.propertyName || node.name) === "default" /* InternalSymbolName.Default */) { + var specifier = getModuleSpecifierForImportOrExport(node); + var moduleSymbol = specifier && resolveExternalModuleName(node, specifier); + if (moduleSymbol) { + return getTargetofModuleDefault(moduleSymbol, node, !!dontResolveAlias); + } + } var resolved = node.parent.parent.moduleSpecifier ? getExternalModuleMember(node.parent.parent, node, dontResolveAlias) : resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias); @@ -62173,7 +62211,7 @@ var ts; return includes & 8388608 /* TypeFlags.IncludesWildcard */ ? wildcardType : anyType; } if (!strictNullChecks && includes & 98304 /* TypeFlags.Nullable */) { - return includes & 32768 /* TypeFlags.Undefined */ ? undefinedType : nullType; + return includes & 16777216 /* TypeFlags.IncludesEmptyObject */ ? neverType : includes & 32768 /* TypeFlags.Undefined */ ? undefinedType : nullType; } if (includes & 4 /* TypeFlags.String */ && includes & (128 /* TypeFlags.StringLiteral */ | 134217728 /* TypeFlags.TemplateLiteral */ | 268435456 /* TypeFlags.StringMapping */) || includes & 8 /* TypeFlags.Number */ && includes & 256 /* TypeFlags.NumberLiteral */ || @@ -62863,7 +62901,7 @@ var ts; // (T | U)[K] -> T[K] | U[K] (reading) // (T | U)[K] -> T[K] & U[K] (writing) // (T & U)[K] -> T[K] & U[K] - if (objectType.flags & 3145728 /* TypeFlags.UnionOrIntersection */) { + if (objectType.flags & 1048576 /* TypeFlags.Union */ || objectType.flags & 2097152 /* TypeFlags.Intersection */ && !shouldDeferIndexType(objectType)) { var types = ts.map(objectType.types, function (t) { return getSimplifiedType(getIndexedAccessType(t, indexType), writing); }); return objectType.flags & 2097152 /* TypeFlags.Intersection */ || writing ? getIntersectionType(types) : getUnionType(types); } @@ -65271,7 +65309,7 @@ var ts; if (reduced !== type) { return reduced; } - if (type.flags & 2097152 /* TypeFlags.Intersection */) { + if (type.flags & 2097152 /* TypeFlags.Intersection */ && ts.some(type.types, isEmptyAnonymousObjectType)) { var normalizedTypes = ts.sameMap(type.types, function (t) { return getNormalizedType(t, writing); }); if (normalizedTypes !== type.types) { return getIntersectionType(normalizedTypes); @@ -66442,7 +66480,7 @@ var ts; // create a new chain for the constraint error resetErrorInfo(saveErrorInfo); } - if (result = isRelatedTo(source, constraint, 2 /* RecursionFlags.Target */, reportErrors)) { + if (result = isRelatedTo(source, constraint, 2 /* RecursionFlags.Target */, reportErrors, /* headMessage */ undefined, intersectionState)) { return result; } // prefer the shorter chain of the constraint comparison chain, and the direct comparison chain @@ -66534,8 +66572,8 @@ var ts; var skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); var skipFalse = !skipTrue && isTypeAssignableTo(getRestrictiveInstantiation(c.checkType), getRestrictiveInstantiation(c.extendsType)); // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) - if (result = skipTrue ? -1 /* Ternary.True */ : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false)) { - result &= skipFalse ? -1 /* Ternary.True */ : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false); + if (result = skipTrue ? -1 /* Ternary.True */ : isRelatedTo(source, getTrueTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + result &= skipFalse ? -1 /* Ternary.True */ : isRelatedTo(source, getFalseTypeFromConditionalType(c), 2 /* RecursionFlags.Target */, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); if (result) { return result; } @@ -71564,7 +71602,7 @@ var ts; var narrowedPropType = narrowType(propType); return filterType(type, function (t) { var discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); - return !(narrowedPropType.flags & 131072 /* TypeFlags.Never */) && isTypeComparableTo(narrowedPropType, discriminantType); + return !(narrowedPropType.flags & 131072 /* TypeFlags.Never */) && areTypesComparable(narrowedPropType, discriminantType); }); } function narrowTypeByDiscriminantProperty(type, access, operator, value, assumeTrue) { @@ -71613,7 +71651,7 @@ var ts; } function narrowByInKeyword(type, name, assumeTrue) { if (type.flags & 1048576 /* TypeFlags.Union */ - || type.flags & 524288 /* TypeFlags.Object */ && declaredType !== type + || type.flags & 524288 /* TypeFlags.Object */ && declaredType !== type && !(declaredType === unknownType && isEmptyAnonymousObjectType(type)) || ts.isThisTypeParameter(type) || type.flags & 2097152 /* TypeFlags.Intersection */ && ts.every(type.types, function (t) { return t.symbol !== globalThisSymbol; })) { return filterType(type, function (t) { return isTypePresencePossible(t, name, assumeTrue); }); @@ -71746,14 +71784,18 @@ var ts; assumeTrue = !assumeTrue; } var valueType = getTypeOfExpression(value); - if ((type.flags & 2 /* TypeFlags.Unknown */) && assumeTrue && (operator === 36 /* SyntaxKind.EqualsEqualsEqualsToken */ || operator === 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { + if (((type.flags & 2 /* TypeFlags.Unknown */) || isEmptyAnonymousObjectType(type) && !(valueType.flags & 98304 /* TypeFlags.Nullable */)) && + assumeTrue && + (operator === 36 /* SyntaxKind.EqualsEqualsEqualsToken */ || operator === 37 /* SyntaxKind.ExclamationEqualsEqualsToken */)) { if (valueType.flags & (131068 /* TypeFlags.Primitive */ | 67108864 /* TypeFlags.NonPrimitive */)) { return valueType; } if (valueType.flags & 524288 /* TypeFlags.Object */) { return nonPrimitiveType; } - return type; + if (type.flags & 2 /* TypeFlags.Unknown */) { + return type; + } } if (valueType.flags & 98304 /* TypeFlags.Nullable */) { if (!strictNullChecks) { @@ -72212,7 +72254,9 @@ var ts; !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && getBaseConstraintOrType(type).flags & (98304 /* TypeFlags.Nullable */ | 1048576 /* TypeFlags.Union */)); } function isGenericTypeWithoutNullableConstraint(type) { - return !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304 /* TypeFlags.Nullable */)); + return type.flags & 2097152 /* TypeFlags.Intersection */ ? + ts.some(type.types, isGenericTypeWithoutNullableConstraint) : + !!(type.flags & 465829888 /* TypeFlags.Instantiable */ && !maybeTypeOfKind(getBaseConstraintOrType(type), 98304 /* TypeFlags.Nullable */)); } function hasContextualTypeWithNoGenericTypes(node, checkMode) { // Computing the contextual type for a child of a JSX element involves resolving the type of the @@ -126909,9 +126953,7 @@ var ts; } } } - var seenRefs = buildInfoPath ? new ts.Set() : undefined; var buildInfoCacheEntry = state.buildInfoCache.get(resolvedPath); - seenRefs === null || seenRefs === void 0 ? void 0 : seenRefs.add(resolvedPath); /** Inputs are up-to-date, just need either timestamp update or bundle prepend manipulation to make it look up-to-date */ var pseudoUpToDate = false; var usesPrepend = false; @@ -126926,7 +126968,7 @@ var ts; continue; } // Check if tsbuildinfo path is shared, then we need to rebuild - if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath)) { + if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath)) { return { type: ts.UpToDateStatusType.OutOfDateWithUpstream, outOfDateOutputFileName: buildInfoPath, @@ -126984,25 +127026,9 @@ var ts; oldestOutputFileName: oldestOutputFileName }; } - function hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath) { - if (seenRefs.has(resolvedRefPath)) - return false; - seenRefs.add(resolvedRefPath); + function hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath) { var refBuildInfo = state.buildInfoCache.get(resolvedRefPath); - if (refBuildInfo.path === buildInfoCacheEntry.path) - return true; - if (resolvedConfig.projectReferences) { - // Check references - for (var _i = 0, _a = resolvedConfig.projectReferences; _i < _a.length; _i++) { - var ref = _a[_i]; - var resolvedRef = ts.resolveProjectReferencePath(ref); - var resolvedRefPath_1 = toResolvedConfigFilePath(state, resolvedRef); - var resolvedConfig_1 = parseConfigFile(state, resolvedRef, resolvedRefPath_1); - if (hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig_1, resolvedRefPath_1)) - return true; - } - } - return false; + return refBuildInfo.path === buildInfoCacheEntry.path; } function getUpToDateStatus(state, project, resolvedPath) { if (project === undefined) { diff --git a/package-lock.json b/package-lock.json index dd15f7a18aaec..d7aadc53daf6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -64,9 +64,8 @@ "mocha-fivemat-progress-reporter": "latest", "ms": "^2.1.3", "node-fetch": "^2.6.7", - "prex": "^0.4.7", "source-map-support": "latest", - "typescript": "^4.8.2", + "typescript": "^4.8.3", "vinyl": "latest", "which": "^2.0.2", "xml2js": "^0.4.23" @@ -89,55 +88,10 @@ "node": "^14 || ^16 || ^17 || ^18" } }, - "node_modules/@esfx/cancelable": { - "version": "1.0.0-pre.30", - "resolved": "https://registry.npmjs.org/@esfx/cancelable/-/cancelable-1.0.0-pre.30.tgz", - "integrity": "sha512-fo0+/D3tEcSOHdZ8HiCR7qOKl5Tkk6Nw6QJNNXSQ0ejlpP3HU4S2i0rb/tjHQ1EkUcWZfB3g2jzfL0ioQSEgGg==", - "dev": true, - "dependencies": { - "@esfx/disposable": "^1.0.0-pre.30", - "@esfx/internal-deprecate": "^1.0.0-pre.24", - "@esfx/internal-guards": "^1.0.0-pre.23", - "@esfx/internal-tag": "^1.0.0-pre.19" - } - }, - "node_modules/@esfx/disposable": { - "version": "1.0.0-pre.30", - "resolved": "https://registry.npmjs.org/@esfx/disposable/-/disposable-1.0.0-pre.30.tgz", - "integrity": "sha512-njBGIQO+HW+lMqqMjURC+MWn+55ufulgebPLXzlxbwVSz5hZkoCsv6n9sIBQbnvg/PYQmWK5Dk6gDSmFfihTUg==", - "dev": true - }, - "node_modules/@esfx/internal-deprecate": { - "version": "1.0.0-pre.24", - "resolved": "https://registry.npmjs.org/@esfx/internal-deprecate/-/internal-deprecate-1.0.0-pre.24.tgz", - "integrity": "sha512-TSU5k04+nuVQdyfYhaVXxyskdiwYQHgwN20J3cbyRrm/YFi2dOoFSLFvkMNh7LNOPGWSOg6pfAm3kd23ISR3Ow==", - "dev": true - }, - "node_modules/@esfx/internal-guards": { - "version": "1.0.0-pre.23", - "resolved": "https://registry.npmjs.org/@esfx/internal-guards/-/internal-guards-1.0.0-pre.23.tgz", - "integrity": "sha512-y2svuwRERA2eKF1T/Stq+O8kPjicFQcUTob5je3L6iloOHnOD0sX6aQLvheWmTXXS7hAnjlyMeSN/ec84BRyHg==", - "dev": true, - "dependencies": { - "@esfx/type-model": "^1.0.0-pre.23" - } - }, - "node_modules/@esfx/internal-tag": { - "version": "1.0.0-pre.19", - "resolved": "https://registry.npmjs.org/@esfx/internal-tag/-/internal-tag-1.0.0-pre.19.tgz", - "integrity": "sha512-/v1D5LfvBnbvHzL22Vh6yobrOTVCBhsW/l9M+/GRA51eqCN27yTmWGaYUSd1QXp2vxHwNr0sfckVoNtTzeaIqQ==", - "dev": true - }, - "node_modules/@esfx/type-model": { - "version": "1.0.0-pre.23", - "resolved": "https://registry.npmjs.org/@esfx/type-model/-/type-model-1.0.0-pre.23.tgz", - "integrity": "sha512-jwcSY9pqEmGoDNhfT+0LUmSTyk6zXF/pbgKb7KU7mTfCrWfVCT/ve61cD1CreerDRBSat/s55se0lJXwDSjhuA==", - "dev": true - }, "node_modules/@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -329,9 +283,9 @@ } }, "node_modules/@octokit/endpoint": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.1.tgz", - "integrity": "sha512-/wTXAJwt0HzJ2IeE4kQXO+mBScfzyCkI0hMtkIaqyXd9zg76OpOfNQfHL9FlaxAV2RsNiOXZibVWloy8EexENg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.2.tgz", + "integrity": "sha512-8/AUACfE9vpRpehE6ZLfEtzkibe5nfsSwFZVMsG8qabqRt1M81qZYUFRZa1B8w8lP6cdfDJfRq9HWS+MbmR7tw==", "dev": true, "dependencies": { "@octokit/types": "^7.0.0", @@ -357,18 +311,18 @@ } }, "node_modules/@octokit/openapi-types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-13.6.0.tgz", - "integrity": "sha512-bxftLwoZ2J6zsU1rzRvk0O32j7lVB0NWWn+P5CDHn9zPzytasR3hdAeXlTngRDkqv1LyEeuy5psVnDkmOSwrcQ==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-13.12.0.tgz", + "integrity": "sha512-1QYzZrwnn3rTQE7ZoSxXrO8lhu0aIbac1c+qIPOPEaVXBWSaUyLV1x9yt4uDQOwmu6u5ywVS8OJgs+ErDLf6vQ==", "dev": true }, "node_modules/@octokit/plugin-paginate-rest": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-4.2.0.tgz", - "integrity": "sha512-8otLCIK9esfmOCY14CBnG/xPqv0paf14rc+s9tHpbOpeFwrv5CnECKW1qdqMAT60ngAa9eB1bKQ+l2YCpi0HPQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-4.3.1.tgz", + "integrity": "sha512-h8KKxESmSFTcXX409CAxlaOYscEDvN2KGQRsLCGT1NSqRW+D6EXLVQ8vuHhFznS9MuH9QYw1GfsUN30bg8hjVA==", "dev": true, "dependencies": { - "@octokit/types": "^7.2.0" + "@octokit/types": "^7.5.0" }, "engines": { "node": ">= 14" @@ -387,12 +341,12 @@ } }, "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.4.0.tgz", - "integrity": "sha512-YP4eUqZ6vORy/eZOTdil1ZSrMt0kv7i/CVw+HhC2C0yJN+IqTc/rot957JQ7JfyeJD6HZOjLg6Jp1o9cPhI9KA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.6.2.tgz", + "integrity": "sha512-n9dL5KMpz9qVFSNdcVWC8ZPbl68QbTk7+CMPXCXqaMZOLn1n1YuoSFFCy84Ge0fx333fUqpnBHv8BFjwGtUQkA==", "dev": true, "dependencies": { - "@octokit/types": "^7.2.0", + "@octokit/types": "^7.5.0", "deprecation": "^2.3.1" }, "engines": { @@ -449,12 +403,12 @@ } }, "node_modules/@octokit/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-7.2.0.tgz", - "integrity": "sha512-pYQ/a1U6mHptwhGyp6SvsiM4bWP2s3V95olUeTxas85D/2kN78yN5C8cGN+P4LwJSWUqIEyvq0Qn2WUn6NQRjw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-7.5.0.tgz", + "integrity": "sha512-aHm+olfIZjQpzoODpl+RCZzchKOrdSLJs+yfI7pMMcmB19Li6vidgx0DwUDO/Ic4Q3fq/lOjJORVCcLZefcrJw==", "dev": true, "dependencies": { - "@octokit/openapi-types": "^13.6.0" + "@octokit/openapi-types": "^13.11.0" } }, "node_modules/@types/async": { @@ -614,9 +568,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.7.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz", - "integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA==", + "version": "18.7.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.18.tgz", + "integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==", "dev": true }, "node_modules/@types/node-fetch": { @@ -686,14 +640,14 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz", - "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.37.0.tgz", + "integrity": "sha512-Fde6W0IafXktz1UlnhGkrrmnnGpAo1kyX7dnyHHVrmwJOn72Oqm3eYtddrpOwwel2W8PAK9F3pIL5S+lfoM0og==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/type-utils": "5.36.1", - "@typescript-eslint/utils": "5.36.1", + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/type-utils": "5.37.0", + "@typescript-eslint/utils": "5.37.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -719,14 +673,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", - "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.37.0.tgz", + "integrity": "sha512-01VzI/ipYKuaG5PkE5+qyJ6m02fVALmMPY3Qq5BHflDx3y4VobbLdHQkSMg9VPRS4KdNt4oYTMaomFoHonBGAw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/typescript-estree": "5.37.0", "debug": "^4.3.4" }, "engines": { @@ -746,13 +700,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", - "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.37.0.tgz", + "integrity": "sha512-F67MqrmSXGd/eZnujjtkPgBQzgespu/iCZ+54Ok9X5tALb9L2v3G+QBSoWkXG0p3lcTJsL+iXz5eLUEdSiJU9Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1" + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/visitor-keys": "5.37.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -763,13 +717,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz", - "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.37.0.tgz", + "integrity": "sha512-BSx/O0Z0SXOF5tY0bNTBcDEKz2Ec20GVYvq/H/XNKiUorUFilH7NPbFUuiiyzWaSdN3PA8JV0OvYx0gH/5aFAQ==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.36.1", - "@typescript-eslint/utils": "5.36.1", + "@typescript-eslint/typescript-estree": "5.37.0", + "@typescript-eslint/utils": "5.37.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -790,9 +744,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", - "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.37.0.tgz", + "integrity": "sha512-3frIJiTa5+tCb2iqR/bf7XwU20lnU05r/sgPJnRpwvfZaqCJBrl8Q/mw9vr3NrNdB/XtVyMA0eppRMMBqdJ1bA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -803,13 +757,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", - "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.37.0.tgz", + "integrity": "sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1", + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/visitor-keys": "5.37.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -830,15 +784,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz", - "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.37.0.tgz", + "integrity": "sha512-jUEJoQrWbZhmikbcWSMDuUSxEE7ID2W/QCV/uz10WtQqfOuKZUqFGjqLJ+qhDd17rjgp+QJPqTdPIBWwoob2NQ==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/typescript-estree": "5.37.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -854,12 +808,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", - "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.37.0.tgz", + "integrity": "sha512-Hp7rT4cENBPIzMwrlehLW/28EVCOcE9U1Z1BQTc8EA8v5qpr7GRGuG+U58V5tTY48zvUOA3KHvw3rA8tY9fbdA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/types": "5.37.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2350,12 +2304,12 @@ } }, "node_modules/eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.23.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.1.tgz", + "integrity": "sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.1", + "@eslint/eslintrc": "^1.3.2", "@humanwhocodes/config-array": "^0.10.4", "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", "@humanwhocodes/module-importer": "^1.0.1", @@ -2374,7 +2328,6 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.15.0", "globby": "^11.1.0", @@ -2383,6 +2336,7 @@ "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -2982,9 +2936,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -3475,9 +3429,9 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "dependencies": { "function-bind": "^1.1.1", @@ -4592,9 +4546,9 @@ "dev": true }, "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.6.tgz", + "integrity": "sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -4969,6 +4923,12 @@ "node": ">=0.10.0" } }, + "node_modules/js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -6551,16 +6511,6 @@ "node": ">= 0.8" } }, - "node_modules/prex": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/prex/-/prex-0.4.7.tgz", - "integrity": "sha512-ulhl3iyjmAW/GroRQJN4CG+pC6KJ+W+deNRBkEShQwe16wLP9k92+x6RmLJuLiVSGkbxhnAqHpGdJJCh3bRpUQ==", - "dev": true, - "dependencies": { - "@esfx/cancelable": "^1.0.0-pre.13", - "@esfx/disposable": "^1.0.0-pre.13" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -8016,9 +7966,9 @@ "dev": true }, "node_modules/typescript": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", - "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", + "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8602,55 +8552,10 @@ "jsdoc-type-pratt-parser": "~3.1.0" } }, - "@esfx/cancelable": { - "version": "1.0.0-pre.30", - "resolved": "https://registry.npmjs.org/@esfx/cancelable/-/cancelable-1.0.0-pre.30.tgz", - "integrity": "sha512-fo0+/D3tEcSOHdZ8HiCR7qOKl5Tkk6Nw6QJNNXSQ0ejlpP3HU4S2i0rb/tjHQ1EkUcWZfB3g2jzfL0ioQSEgGg==", - "dev": true, - "requires": { - "@esfx/disposable": "^1.0.0-pre.30", - "@esfx/internal-deprecate": "^1.0.0-pre.24", - "@esfx/internal-guards": "^1.0.0-pre.23", - "@esfx/internal-tag": "^1.0.0-pre.19" - } - }, - "@esfx/disposable": { - "version": "1.0.0-pre.30", - "resolved": "https://registry.npmjs.org/@esfx/disposable/-/disposable-1.0.0-pre.30.tgz", - "integrity": "sha512-njBGIQO+HW+lMqqMjURC+MWn+55ufulgebPLXzlxbwVSz5hZkoCsv6n9sIBQbnvg/PYQmWK5Dk6gDSmFfihTUg==", - "dev": true - }, - "@esfx/internal-deprecate": { - "version": "1.0.0-pre.24", - "resolved": "https://registry.npmjs.org/@esfx/internal-deprecate/-/internal-deprecate-1.0.0-pre.24.tgz", - "integrity": "sha512-TSU5k04+nuVQdyfYhaVXxyskdiwYQHgwN20J3cbyRrm/YFi2dOoFSLFvkMNh7LNOPGWSOg6pfAm3kd23ISR3Ow==", - "dev": true - }, - "@esfx/internal-guards": { - "version": "1.0.0-pre.23", - "resolved": "https://registry.npmjs.org/@esfx/internal-guards/-/internal-guards-1.0.0-pre.23.tgz", - "integrity": "sha512-y2svuwRERA2eKF1T/Stq+O8kPjicFQcUTob5je3L6iloOHnOD0sX6aQLvheWmTXXS7hAnjlyMeSN/ec84BRyHg==", - "dev": true, - "requires": { - "@esfx/type-model": "^1.0.0-pre.23" - } - }, - "@esfx/internal-tag": { - "version": "1.0.0-pre.19", - "resolved": "https://registry.npmjs.org/@esfx/internal-tag/-/internal-tag-1.0.0-pre.19.tgz", - "integrity": "sha512-/v1D5LfvBnbvHzL22Vh6yobrOTVCBhsW/l9M+/GRA51eqCN27yTmWGaYUSd1QXp2vxHwNr0sfckVoNtTzeaIqQ==", - "dev": true - }, - "@esfx/type-model": { - "version": "1.0.0-pre.23", - "resolved": "https://registry.npmjs.org/@esfx/type-model/-/type-model-1.0.0-pre.23.tgz", - "integrity": "sha512-jwcSY9pqEmGoDNhfT+0LUmSTyk6zXF/pbgKb7KU7mTfCrWfVCT/ve61cD1CreerDRBSat/s55se0lJXwDSjhuA==", - "dev": true - }, "@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -8796,9 +8701,9 @@ } }, "@octokit/endpoint": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.1.tgz", - "integrity": "sha512-/wTXAJwt0HzJ2IeE4kQXO+mBScfzyCkI0hMtkIaqyXd9zg76OpOfNQfHL9FlaxAV2RsNiOXZibVWloy8EexENg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.2.tgz", + "integrity": "sha512-8/AUACfE9vpRpehE6ZLfEtzkibe5nfsSwFZVMsG8qabqRt1M81qZYUFRZa1B8w8lP6cdfDJfRq9HWS+MbmR7tw==", "dev": true, "requires": { "@octokit/types": "^7.0.0", @@ -8818,18 +8723,18 @@ } }, "@octokit/openapi-types": { - "version": "13.6.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-13.6.0.tgz", - "integrity": "sha512-bxftLwoZ2J6zsU1rzRvk0O32j7lVB0NWWn+P5CDHn9zPzytasR3hdAeXlTngRDkqv1LyEeuy5psVnDkmOSwrcQ==", + "version": "13.12.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-13.12.0.tgz", + "integrity": "sha512-1QYzZrwnn3rTQE7ZoSxXrO8lhu0aIbac1c+qIPOPEaVXBWSaUyLV1x9yt4uDQOwmu6u5ywVS8OJgs+ErDLf6vQ==", "dev": true }, "@octokit/plugin-paginate-rest": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-4.2.0.tgz", - "integrity": "sha512-8otLCIK9esfmOCY14CBnG/xPqv0paf14rc+s9tHpbOpeFwrv5CnECKW1qdqMAT60ngAa9eB1bKQ+l2YCpi0HPQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-4.3.1.tgz", + "integrity": "sha512-h8KKxESmSFTcXX409CAxlaOYscEDvN2KGQRsLCGT1NSqRW+D6EXLVQ8vuHhFznS9MuH9QYw1GfsUN30bg8hjVA==", "dev": true, "requires": { - "@octokit/types": "^7.2.0" + "@octokit/types": "^7.5.0" } }, "@octokit/plugin-request-log": { @@ -8840,12 +8745,12 @@ "requires": {} }, "@octokit/plugin-rest-endpoint-methods": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.4.0.tgz", - "integrity": "sha512-YP4eUqZ6vORy/eZOTdil1ZSrMt0kv7i/CVw+HhC2C0yJN+IqTc/rot957JQ7JfyeJD6HZOjLg6Jp1o9cPhI9KA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.6.2.tgz", + "integrity": "sha512-n9dL5KMpz9qVFSNdcVWC8ZPbl68QbTk7+CMPXCXqaMZOLn1n1YuoSFFCy84Ge0fx333fUqpnBHv8BFjwGtUQkA==", "dev": true, "requires": { - "@octokit/types": "^7.2.0", + "@octokit/types": "^7.5.0", "deprecation": "^2.3.1" } }, @@ -8887,12 +8792,12 @@ } }, "@octokit/types": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-7.2.0.tgz", - "integrity": "sha512-pYQ/a1U6mHptwhGyp6SvsiM4bWP2s3V95olUeTxas85D/2kN78yN5C8cGN+P4LwJSWUqIEyvq0Qn2WUn6NQRjw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-7.5.0.tgz", + "integrity": "sha512-aHm+olfIZjQpzoODpl+RCZzchKOrdSLJs+yfI7pMMcmB19Li6vidgx0DwUDO/Ic4Q3fq/lOjJORVCcLZefcrJw==", "dev": true, "requires": { - "@octokit/openapi-types": "^13.6.0" + "@octokit/openapi-types": "^13.11.0" } }, "@types/async": { @@ -9052,9 +8957,9 @@ "dev": true }, "@types/node": { - "version": "18.7.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz", - "integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA==", + "version": "18.7.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.18.tgz", + "integrity": "sha512-m+6nTEOadJZuTPkKR/SYK3A2d7FZrgElol9UP1Kae90VVU4a6mxnPuLiIW1m4Cq4gZ/nWb9GrdVXJCoCazDAbg==", "dev": true }, "@types/node-fetch": { @@ -9124,14 +9029,14 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz", - "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.37.0.tgz", + "integrity": "sha512-Fde6W0IafXktz1UlnhGkrrmnnGpAo1kyX7dnyHHVrmwJOn72Oqm3eYtddrpOwwel2W8PAK9F3pIL5S+lfoM0og==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/type-utils": "5.36.1", - "@typescript-eslint/utils": "5.36.1", + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/type-utils": "5.37.0", + "@typescript-eslint/utils": "5.37.0", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -9141,53 +9046,53 @@ } }, "@typescript-eslint/parser": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", - "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.37.0.tgz", + "integrity": "sha512-01VzI/ipYKuaG5PkE5+qyJ6m02fVALmMPY3Qq5BHflDx3y4VobbLdHQkSMg9VPRS4KdNt4oYTMaomFoHonBGAw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/typescript-estree": "5.37.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", - "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.37.0.tgz", + "integrity": "sha512-F67MqrmSXGd/eZnujjtkPgBQzgespu/iCZ+54Ok9X5tALb9L2v3G+QBSoWkXG0p3lcTJsL+iXz5eLUEdSiJU9Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1" + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/visitor-keys": "5.37.0" } }, "@typescript-eslint/type-utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz", - "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.37.0.tgz", + "integrity": "sha512-BSx/O0Z0SXOF5tY0bNTBcDEKz2Ec20GVYvq/H/XNKiUorUFilH7NPbFUuiiyzWaSdN3PA8JV0OvYx0gH/5aFAQ==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.36.1", - "@typescript-eslint/utils": "5.36.1", + "@typescript-eslint/typescript-estree": "5.37.0", + "@typescript-eslint/utils": "5.37.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", - "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.37.0.tgz", + "integrity": "sha512-3frIJiTa5+tCb2iqR/bf7XwU20lnU05r/sgPJnRpwvfZaqCJBrl8Q/mw9vr3NrNdB/XtVyMA0eppRMMBqdJ1bA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", - "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.37.0.tgz", + "integrity": "sha512-JkFoFIt/cx59iqEDSgIGnQpCTRv96MQnXCYvJi7QhBC24uyuzbD8wVbajMB1b9x4I0octYFJ3OwjAwNqk1AjDA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1", + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/visitor-keys": "5.37.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9196,26 +9101,26 @@ } }, "@typescript-eslint/utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz", - "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.37.0.tgz", + "integrity": "sha512-jUEJoQrWbZhmikbcWSMDuUSxEE7ID2W/QCV/uz10WtQqfOuKZUqFGjqLJ+qhDd17rjgp+QJPqTdPIBWwoob2NQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", + "@typescript-eslint/scope-manager": "5.37.0", + "@typescript-eslint/types": "5.37.0", + "@typescript-eslint/typescript-estree": "5.37.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", - "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.37.0.tgz", + "integrity": "sha512-Hp7rT4cENBPIzMwrlehLW/28EVCOcE9U1Z1BQTc8EA8v5qpr7GRGuG+U58V5tTY48zvUOA3KHvw3rA8tY9fbdA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/types": "5.37.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -10398,12 +10303,12 @@ "dev": true }, "eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.23.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.1.tgz", + "integrity": "sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.1", + "@eslint/eslintrc": "^1.3.2", "@humanwhocodes/config-array": "^0.10.4", "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", "@humanwhocodes/module-importer": "^1.0.1", @@ -10422,7 +10327,6 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.15.0", "globby": "^11.1.0", @@ -10431,6 +10335,7 @@ "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -10911,9 +10816,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -11305,9 +11210,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -12190,9 +12095,9 @@ "dev": true }, "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.6.tgz", + "integrity": "sha512-krO72EO2NptOGAX2KYyqbP9vYMlNAXdB53rq6f8LXY6RY7JdSR/3BD6wLUlPHSAesmY9vstNrjvqGaCiRK/91Q==", "dev": true }, "is-core-module": { @@ -12456,6 +12361,12 @@ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true }, + "js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -13666,16 +13577,6 @@ "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==", "dev": true }, - "prex": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/prex/-/prex-0.4.7.tgz", - "integrity": "sha512-ulhl3iyjmAW/GroRQJN4CG+pC6KJ+W+deNRBkEShQwe16wLP9k92+x6RmLJuLiVSGkbxhnAqHpGdJJCh3bRpUQ==", - "dev": true, - "requires": { - "@esfx/cancelable": "^1.0.0-pre.13", - "@esfx/disposable": "^1.0.0-pre.13" - } - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -14834,9 +14735,9 @@ "dev": true }, "typescript": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", - "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", + "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index da018f3c4263c..0d80542b7fab5 100644 --- a/package.json +++ b/package.json @@ -90,9 +90,8 @@ "mocha-fivemat-progress-reporter": "latest", "ms": "^2.1.3", "node-fetch": "^2.6.7", - "prex": "^0.4.7", "source-map-support": "latest", - "typescript": "^4.8.2", + "typescript": "^4.8.3", "vinyl": "latest", "which": "^2.0.2", "xml2js": "^0.4.23" @@ -110,7 +109,6 @@ "clean": "gulp clean", "gulp": "gulp", "lint": "gulp lint", - "lint:ci": "gulp lint --ci", "setup-hooks": "node scripts/link-hooks.js" }, "browser": { diff --git a/scripts/build/options.js b/scripts/build/options.js index 2c2d7c7b0a1db..fc237c5885584 100644 --- a/scripts/build/options.js +++ b/scripts/build/options.js @@ -2,9 +2,11 @@ const minimist = require("minimist"); const os = require("os"); +const ci = ["1", "true"].includes(process.env.CI); + /** @type {CommandLineOptions} */ module.exports = minimist(process.argv.slice(2), { - boolean: ["dirty", "light", "colors", "lint", "lkg", "soft", "fix", "failed", "keepFailed", "force", "built"], + boolean: ["dirty", "light", "colors", "lkg", "soft", "fix", "failed", "keepFailed", "force", "built", "ci"], string: ["browser", "tests", "break", "host", "reporter", "stackTraceLimit", "timeout", "shards", "shardId"], alias: { /* eslint-disable quote-props */ @@ -31,14 +33,14 @@ module.exports = minimist(process.argv.slice(2), { runners: process.env.runners || process.env.runner || process.env.ru, light: process.env.light === undefined || process.env.light !== "false", reporter: process.env.reporter || process.env.r, - lint: process.env.lint || true, fix: process.env.fix || process.env.f, - workers: process.env.workerCount || ((os.cpus().length - (process.env.CI ? 0 : 1)) || 1), + workers: process.env.workerCount || ((os.cpus().length - (ci ? 0 : 1)) || 1), failed: false, keepFailed: false, lkg: true, dirty: false, - built: false + built: false, + ci, } }); @@ -51,7 +53,6 @@ if (module.exports.built) { * @property {boolean} dirty * @property {boolean} light * @property {boolean} colors - * @property {boolean} lint * @property {boolean} lkg * @property {boolean} built * @property {boolean} soft @@ -67,6 +68,7 @@ if (module.exports.built) { * @property {string|number} timeout * @property {boolean} failed * @property {boolean} keepFailed + * @property {boolean} ci * * @typedef {import("minimist").ParsedArgs & TypedOptions} CommandLineOptions */ diff --git a/scripts/build/tests.js b/scripts/build/tests.js index 5c804035ed08c..4dd76c1f62e69 100644 --- a/scripts/build/tests.js +++ b/scripts/build/tests.js @@ -6,7 +6,6 @@ const path = require("path"); const mkdirP = require("mkdirp"); const log = require("fancy-log"); const cmdLineOptions = require("./options"); -const { CancellationToken } = require("prex"); const { exec } = require("./utils"); const { findUpFile } = require("./findUpDir"); @@ -22,9 +21,8 @@ exports.localTest262Baseline = "internal/baselines/test262/local"; * @param {string} defaultReporter * @param {boolean} runInParallel * @param {boolean} watchMode - * @param {import("prex").CancellationToken} [cancelToken] */ -async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, cancelToken = CancellationToken.none) { +async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode) { let testTimeout = cmdLineOptions.timeout; const tests = cmdLineOptions.tests; const inspect = cmdLineOptions.break || cmdLineOptions.inspect; @@ -38,7 +36,6 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, const shardId = +cmdLineOptions.shardId || undefined; if (!cmdLineOptions.dirty) { await cleanTestDirs(); - cancelToken.throwIfCancellationRequested(); } if (fs.existsSync(testConfigFile)) { @@ -121,19 +118,17 @@ async function runConsoleTests(runJs, defaultReporter, runInParallel, watchMode, try { setNodeEnvToDevelopment(); - const { exitCode } = await exec(process.execPath, args, { - cancelToken, - }); + const { exitCode } = await exec(process.execPath, args); if (exitCode !== 0) { errorStatus = exitCode; error = new Error(`Process exited with status code ${errorStatus}.`); } - else if (process.env.CI === "true") { + else if (cmdLineOptions.ci) { // finally, do a sanity check and build the compiler with the built version of itself log.info("Starting sanity check build..."); // Cleanup everything except lint rules (we'll need those later and would rather not waste time rebuilding them) - await exec("gulp", ["clean-tsc", "clean-services", "clean-tsserver", "clean-lssl", "clean-tests"], { cancelToken }); - const { exitCode } = await exec("gulp", ["local", "--lkg=false"], { cancelToken }); + await exec("gulp", ["clean-tsc", "clean-services", "clean-tsserver", "clean-lssl", "clean-tests"]); + const { exitCode } = await exec("gulp", ["local", "--lkg=false"]); if (exitCode !== 0) { errorStatus = exitCode; error = new Error(`Sanity check build process exited with status code ${errorStatus}.`); diff --git a/scripts/build/utils.js b/scripts/build/utils.js index 6dcccec02f47e..0e38a0b73d6cf 100644 --- a/scripts/build/utils.js +++ b/scripts/build/utils.js @@ -14,7 +14,6 @@ const ts = require("../../lib/typescript"); const chalk = require("chalk"); const which = require("which"); const { spawn } = require("child_process"); -const { CancellationToken, CancelError, Deferred } = require("prex"); const { Readable, Duplex } = require("stream"); /** @@ -25,26 +24,17 @@ const { Readable, Duplex } = require("stream"); * * @typedef ExecOptions * @property {boolean} [ignoreExitCode] - * @property {import("prex").CancellationToken} [cancelToken] * @property {boolean} [hidePrompt] * @property {boolean} [waitForExit=true] */ async function exec(cmd, args, options = {}) { return /**@type {Promise<{exitCode: number}>}*/(new Promise((resolve, reject) => { - const { ignoreExitCode, cancelToken = CancellationToken.none, waitForExit = true } = options; - cancelToken.throwIfCancellationRequested(); + const { ignoreExitCode, waitForExit = true } = options; if (!options.hidePrompt) log(`> ${chalk.green(cmd)} ${args.join(" ")}`); const proc = spawn(which.sync(cmd), args, { stdio: waitForExit ? "inherit" : "ignore" }); - const registration = cancelToken.register(() => { - log(`${chalk.red("killing")} '${chalk.green(cmd)} ${args.join(" ")}'...`); - proc.kill("SIGINT"); - proc.kill("SIGTERM"); - reject(new CancelError()); - }); if (waitForExit) { proc.on("exit", exitCode => { - registration.unregister(); if (exitCode === 0 || ignoreExitCode) { resolve({ exitCode }); } @@ -53,7 +43,6 @@ async function exec(cmd, args, options = {}) { } }); proc.on("error", error => { - registration.unregister(); reject(error); }); } @@ -395,6 +384,15 @@ function rm(dest, opts) { } exports.rm = rm; +class Deferred { + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } +} + class Debouncer { /** * @param {number} timeout diff --git a/scripts/failed-tests.js b/scripts/failed-tests.js index 66463e56c7c2d..41536e633755a 100644 --- a/scripts/failed-tests.js +++ b/scripts/failed-tests.js @@ -45,7 +45,7 @@ class FailedTestsReporter extends Mocha.reporters.Base { } } - const newOptions = Object.assign({}, options, { reporterOptions: reporterOptions.reporterOptions || {} }); + const newOptions = { ...options, reporterOptions: reporterOptions.reporterOptions || {} }; if (reporterOptions.reporter === "xunit") { newOptions.reporterOptions.output = "TEST-results.xml"; } @@ -142,4 +142,4 @@ class FailedTestsReporter extends Mocha.reporters.Base { } } -module.exports = FailedTestsReporter; \ No newline at end of file +module.exports = FailedTestsReporter; diff --git a/scripts/find-unused-diganostic-messages.mjs b/scripts/find-unused-diganostic-messages.mjs index 6ecff6642d3db..ba529cf81bcf0 100644 --- a/scripts/find-unused-diganostic-messages.mjs +++ b/scripts/find-unused-diganostic-messages.mjs @@ -17,7 +17,8 @@ startOfDiags.split(EOL).forEach(line => { try { execSync(`grep -rnw 'src' -e 'Diagnostics.${diagName}'`).toString(); process.stdout.write("."); - } catch (error) { + } + catch (error) { missingNames.push(diagName); process.stdout.write("x"); } diff --git a/scripts/post-vsts-artifact-comment.js b/scripts/post-vsts-artifact-comment.js index 125b047f51901..f0ffa2c4105ed 100644 --- a/scripts/post-vsts-artifact-comment.js +++ b/scripts/post-vsts-artifact-comment.js @@ -48,7 +48,7 @@ and then running \`npm install\`. // Temporarily disable until we get access controls set up right // Send a ping to https://github.com/microsoft/typescript-make-monaco-builds#pull-request-builds - await gh.request("POST /repos/microsoft/typescript-make-monaco-builds/dispatches", { event_type: process.env.SOURCE_ISSUE, headers: { Accept: "application/vnd.github.everest-preview+json" }}); + await gh.request("POST /repos/microsoft/typescript-make-monaco-builds/dispatches", { event_type: process.env.SOURCE_ISSUE, headers: { Accept: "application/vnd.github.everest-preview+json" } }); } main().catch(async e => { diff --git a/scripts/run-sequence.js b/scripts/run-sequence.js index 21c771ad9913a..6f5828f0b79c8 100644 --- a/scripts/run-sequence.js +++ b/scripts/run-sequence.js @@ -1,7 +1,6 @@ // @ts-check const cp = require("child_process"); /** - * * @param {[string, string[]][]} tasks * @param {cp.SpawnSyncOptions} opts */ @@ -17,4 +16,4 @@ function runSequence(tasks, opts = { timeout: 100000, shell: true }) { return lastResult && lastResult.stdout && lastResult.stdout.toString(); } -exports.runSequence = runSequence; \ No newline at end of file +exports.runSequence = runSequence; diff --git a/scripts/update-experimental-branches.js b/scripts/update-experimental-branches.js index 6f137db13c518..2dfea45e89330 100644 --- a/scripts/update-experimental-branches.js +++ b/scripts/update-experimental-branches.js @@ -10,7 +10,7 @@ const triggeredPR = process.env.SOURCE_ISSUE || process.env.SYSTEM_PULLREQUEST_P * This program should be invoked as `node ./scripts/update-experimental-branches ` * TODO: the following is racey - if two experiment-enlisted PRs trigger simultaneously and witness one another in an unupdated state, they'll both produce * a new experimental branch, but each will be missing a change from the other. There's no _great_ way to fix this beyond setting the maximum concurrency - * of this task to 1 (so only one job is allowed to update experiments at a time). + * of this task to 1 (so only one job is allowed to update experiments at a time). */ async function main() { const gh = new Octokit({ diff --git a/scripts/word2md.ts b/scripts/word2md.ts index ed0338617d8be..472699156bb8b 100644 --- a/scripts/word2md.ts +++ b/scripts/word2md.ts @@ -185,7 +185,7 @@ function convertDocumentToMarkdown(doc: Word.Document): string { function setProperties(target: any, properties: any) { for (const name in properties) { - if (properties.hasOwnProperty(name)) { + if (Object.prototype.hasOwnProperty.call(properties, name)) { const value = properties[name]; if (typeof value === "object") { setProperties(target[name], value); diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index a1b9b39dee41e..5684fe91cfb5b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3044,7 +3044,7 @@ namespace ts { return; } const rootExpr = getLeftmostAccessExpression(node.left); - if (isIdentifier(rootExpr) && lookupSymbolForName(container, rootExpr.escapedText)!?.flags & SymbolFlags.Alias) { + if (isIdentifier(rootExpr) && lookupSymbolForName(container, rootExpr.escapedText)?.flags! & SymbolFlags.Alias) { return; } // Fix up parent pointers since we're going to use these nodes before we bind into them diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9bdd19c05a169..cbe877f4632e1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -729,6 +729,7 @@ namespace ts { isPropertyAccessible, getTypeOnlyAliasDeclaration, getMemberOverrideModifierStatus, + isTypeParameterPossiblyReferenced, }; function runWithInferenceBlockedFromSourceNode(node: Node | undefined, fn: () => T): T { @@ -792,6 +793,7 @@ namespace ts { const wildcardType = createIntrinsicType(TypeFlags.Any, "any"); const errorType = createIntrinsicType(TypeFlags.Any, "error"); const unresolvedType = createIntrinsicType(TypeFlags.Any, "unresolved"); + const nonInferrableAnyType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.ContainsWideningType); const intrinsicMarkerType = createIntrinsicType(TypeFlags.Any, "intrinsic"); const unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); const nonNullUnknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); @@ -857,7 +859,8 @@ namespace ts { emptyTypeLiteralSymbol.members = createSymbolTable(); const emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, emptyArray, emptyArray, emptyArray); - const unknownUnionType = strictNullChecks ? getUnionType([undefinedType, nullType, createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray)]) : unknownType; + const unknownEmptyObjectType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray); + const unknownUnionType = strictNullChecks ? getUnionType([undefinedType, nullType, unknownEmptyObjectType]) : unknownType; const emptyGenericType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, emptyArray) as ObjectType as GenericType; emptyGenericType.instantiations = new Map(); @@ -997,6 +1000,7 @@ namespace ts { let deferredGlobalOmitSymbol: Symbol | undefined; let deferredGlobalAwaitedSymbol: Symbol | undefined; let deferredGlobalBigIntType: ObjectType | undefined; + let deferredGlobalRecordSymbol: Symbol | undefined; let deferredGlobalClassDecoratorContextType: GenericType | undefined; let deferredGlobalClassMethodDecoratorContextType: GenericType | undefined; let deferredGlobalClassGetterDecoratorContextType: GenericType | undefined; @@ -1837,6 +1841,7 @@ namespace ts { * the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with * the given name can be found. * + * @param nameNotFoundMessage If defined, we will report errors found during resolve. * @param isUse If true, this will count towards --noUnusedLocals / --noUnusedParameters. */ function resolveName( @@ -1847,8 +1852,8 @@ namespace ts { nameArg: __String | Identifier | undefined, isUse: boolean, excludeGlobals = false, - getSpellingSuggstions = true): Symbol | undefined { - return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSpellingSuggstions, getSymbol); + getSpellingSuggestions = true): Symbol | undefined { + return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, excludeGlobals, getSpellingSuggestions, getSymbol); } function resolveNameHelper( @@ -2021,7 +2026,9 @@ namespace ts { // TypeScript 1.0 spec (April 2014): 3.4.1 // The scope of a type parameter extends over the entire declaration with which the type // parameter list is associated, with the exception of static member declarations in classes. - error(errorLocation, Diagnostics.Static_members_cannot_reference_class_type_parameters); + if (nameNotFoundMessage) { + error(errorLocation, Diagnostics.Static_members_cannot_reference_class_type_parameters); + } return undefined; } break loop; @@ -2059,7 +2066,9 @@ namespace ts { if (isClassLike(grandparent) || grandparent.kind === SyntaxKind.InterfaceDeclaration) { // A reference to this grandparent's type parameters would be an error if (result = lookup(getSymbolOfNode(grandparent as ClassLikeDeclaration | InterfaceDeclaration).members!, name, meaning & SymbolFlags.Type)) { - error(errorLocation, Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type); + if (nameNotFoundMessage) { + error(errorLocation, Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type); + } return undefined; } } @@ -2269,7 +2278,7 @@ namespace ts { } return undefined; } - else if (checkAndReportErrorForInvalidInitializer()) { + else if (nameNotFoundMessage && checkAndReportErrorForInvalidInitializer()) { return undefined; } @@ -3637,7 +3646,7 @@ namespace ts { if (ext === Extension.Ts || ext === Extension.Js || ext === Extension.Tsx || ext === Extension.Jsx) { const scope = currentSourceFile.packageJsonScope; const targetExt = ext === Extension.Ts ? Extension.Mts : ext === Extension.Js ? Extension.Mjs : undefined; - if (scope && !scope.packageJsonContent.type) { + if (scope && !scope.contents.packageJsonContent.type) { if (targetExt) { diagnosticDetails = chainDiagnosticMessages( /*details*/ undefined, @@ -6123,29 +6132,19 @@ namespace ts { return parameterNode; function cloneBindingName(node: BindingName): BindingName { - return elideInitializerAndPropertyRenamingAndSetEmitFlags(node) as BindingName; - function elideInitializerAndPropertyRenamingAndSetEmitFlags(node: Node): Node { + return elideInitializerAndSetEmitFlags(node) as BindingName; + function elideInitializerAndSetEmitFlags(node: Node): Node { if (context.tracker.trackSymbol && isComputedPropertyName(node) && isLateBindableName(node)) { trackComputedName(node.expression, context.enclosingDeclaration, context); } - let visited = visitEachChild(node, elideInitializerAndPropertyRenamingAndSetEmitFlags, nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndPropertyRenamingAndSetEmitFlags)!; + let visited = visitEachChild(node, elideInitializerAndSetEmitFlags, nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags)!; if (isBindingElement(visited)) { - if (visited.propertyName && isIdentifier(visited.propertyName) && isIdentifier(visited.name) && !isStringAKeyword(idText(visited.propertyName))) { - visited = factory.updateBindingElement( - visited, - visited.dotDotDotToken, - /* propertyName*/ undefined, - visited.propertyName, - /*initializer*/ undefined); - } - else { - visited = factory.updateBindingElement( - visited, - visited.dotDotDotToken, - visited.propertyName, - visited.name, - /*initializer*/ undefined); - } + visited = factory.updateBindingElement( + visited, + visited.dotDotDotToken, + visited.propertyName, + visited.name, + /*initializer*/ undefined); } if (!nodeIsSynthesized(visited)) { visited = factory.cloneNode(visited); @@ -9228,7 +9227,7 @@ namespace ts { if (container && (container.kind === SyntaxKind.Constructor || isJSConstructor(container))) { return container as ConstructorDeclaration; } - }; + } } /** Create a synthetic property access flow node after the last statement of the file */ @@ -9568,7 +9567,11 @@ namespace ts { if (reportErrors && !declarationBelongsToPrivateAmbientMember(element)) { reportImplicitAny(element, anyType); } - return anyType; + // When we're including the pattern in the type (an indication we're obtaining a contextual type), we + // use a non-inferrable any type. Inference will never directly infer this type, but it is possible + // to infer a type that contains it, e.g. for a binding pattern like [foo] or { foo }. In such cases, + // widening of the binding pattern type substitutes a regular any for the non-inferrable any. + return includePatternInType ? nonInferrableAnyType : anyType; } // Return the type implied by an object binding pattern @@ -11808,6 +11811,12 @@ namespace ts { return mapType(type as UnionType, getLowerBoundOfKeyType); } if (type.flags & TypeFlags.Intersection) { + // Similarly to getTypeFromIntersectionTypeNode, we preserve the special string & {}, number & {}, + // and bigint & {} intersections that are used to prevent subtype reduction in union types. + const types = (type as IntersectionType).types; + if (types.length === 2 && !!(types[0].flags & (TypeFlags.String | TypeFlags.Number | TypeFlags.BigInt)) && types[1] === emptyTypeLiteralType) { + return type; + } return getIntersectionType(sameMap((type as UnionType).types, getLowerBoundOfKeyType)); } return type; @@ -14339,6 +14348,11 @@ namespace ts { return (deferredGlobalClassFieldDecoratorContextType ??= getGlobalType("ClassFieldDecoratorContext" as __String, /*arity*/ 2, reportErrors)) ?? emptyGenericType; } + function getGlobalRecordSymbol(): Symbol | undefined { + deferredGlobalRecordSymbol ||= getGlobalTypeAliasSymbol("Record" as __String, /*arity*/ 2, /*reportErrors*/ true) || unknownSymbol; + return deferredGlobalRecordSymbol === unknownSymbol ? undefined : deferredGlobalRecordSymbol; + } + /** * Instantiates a global type that is generic with some element type, and returns that instantiation. */ @@ -17224,9 +17238,10 @@ namespace ts { } function isTypeParameterPossiblyReferenced(tp: TypeParameter, node: Node) { - // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks + // If the type parameter doesn't have exactly one declaration, if there are intervening statement blocks // between the node and the type parameter declaration, if the node contains actual references to the - // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced. + // type parameter, or if the node contains type queries that we can't prove couldn't contain references to the type parameter, + // we consider the type parameter possibly referenced. if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { const container = tp.symbol.declarations[0].parent; for (let n = node; n !== container; n = n.parent) { @@ -17245,6 +17260,28 @@ namespace ts { return !tp.isThisType && isPartOfTypeNode(node) && maybeTypeParameterReference(node) && getTypeFromTypeNodeWorker(node as TypeNode) === tp; // use worker because we're looking for === equality case SyntaxKind.TypeQuery: + const entityName = (node as TypeQueryNode).exprName; + const firstIdentifier = getFirstIdentifier(entityName); + const firstIdentifierSymbol = getResolvedSymbol(firstIdentifier); + const tpDeclaration = tp.symbol.declarations![0]; // There is exactly one declaration, otherwise `containsReference` is not called + let tpScope: Node; + if (tpDeclaration.kind === SyntaxKind.TypeParameter) { // Type parameter is a regular type parameter, e.g. foo + tpScope = tpDeclaration.parent; + } + else if (tp.isThisType) { + // Type parameter is the this type, and its declaration is the class declaration. + tpScope = tpDeclaration; + } + else { + // Type parameter's declaration was unrecognized. + // This could happen if the type parameter comes from e.g. a JSDoc annotation, so we default to returning true. + return true; + } + + if (firstIdentifierSymbol.declarations) { + return some(firstIdentifierSymbol.declarations, idDecl => isNodeDescendantOf(idDecl, tpScope)) || + some((node as TypeQueryNode).typeArguments, containsReference); + } return true; case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: @@ -19237,11 +19274,15 @@ namespace ts { // parameter 'T extends 1 | 2', the intersection 'T & 1' should be reduced to '1' such that it doesn't // appear to be comparable to '2'. if (relation === comparableRelation && target.flags & TypeFlags.Primitive) { - const constraints = sameMap((source as IntersectionType).types, getBaseConstraintOrType); + const constraints = sameMap((source as IntersectionType).types, t => t.flags & TypeFlags.Instantiable ? getBaseConstraintOfType(t) || unknownType : t); if (constraints !== (source as IntersectionType).types) { source = getIntersectionType(constraints); + if (source.flags & TypeFlags.Never) { + return Ternary.False; + } if (!(source.flags & TypeFlags.Intersection)) { - return isRelatedTo(source, target, RecursionFlags.Source, /*reportErrors*/ false); + return isRelatedTo(source, target, RecursionFlags.Source, /*reportErrors*/ false) || + isRelatedTo(target, source, RecursionFlags.Source, /*reportErrors*/ false); } } } @@ -19562,7 +19603,7 @@ namespace ts { // the type param can be compared with itself in the target (with the influence of its constraint to match other parts) // For example, if `T extends 1 | 2` and `U extends 2 | 3` and we compare `T & U` to `T & U & (1 | 2 | 3)` const constraint = getEffectiveConstraintOfIntersection(source.flags & TypeFlags.Intersection ? (source as IntersectionType).types: [source], !!(target.flags & TypeFlags.Union)); - if (constraint && everyType(constraint, c => c !== source)) { // Skip comparison if expansion contains the source itself + if (constraint && !(constraint.flags & TypeFlags.Never) && everyType(constraint, c => c !== source)) { // Skip comparison if expansion contains the source itself // TODO: Stack errors so we get a pyramid for the "normal" comparison above, _and_ a second for this result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); } @@ -19873,8 +19914,8 @@ namespace ts { const skipTrue = !isTypeAssignableTo(getPermissiveInstantiation(c.checkType), getPermissiveInstantiation(c.extendsType)); const skipFalse = !skipTrue && isTypeAssignableTo(getRestrictiveInstantiation(c.checkType), getRestrictiveInstantiation(c.extendsType)); // TODO: Find a nice way to include potential conditional type breakdowns in error output, if they seem good (they usually don't) - if (result = skipTrue ? Ternary.True : isRelatedTo(source, getTrueTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false)) { - result &= skipFalse ? Ternary.True : isRelatedTo(source, getFalseTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false); + if (result = skipTrue ? Ternary.True : isRelatedTo(source, getTrueTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState)) { + result &= skipFalse ? Ternary.True : isRelatedTo(source, getFalseTypeFromConditionalType(c), RecursionFlags.Target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState); if (result) { return result; } @@ -22683,7 +22724,10 @@ namespace ts { // // This flag is infectious; if we produce Box (where never is silentNeverType), Box is // also non-inferrable. - if (getObjectFlags(source) & ObjectFlags.NonInferrableType) { + // + // As a special case, also ignore nonInferrableAnyType, which is a special form of the any type + // used as a stand-in for binding elements when they are being inferred. + if (getObjectFlags(source) & ObjectFlags.NonInferrableType || source === nonInferrableAnyType) { return; } if (!inference.isFixed) { @@ -25148,7 +25192,7 @@ namespace ts { const narrowedPropType = narrowType(propType); return filterType(type, t => { const discriminantType = getTypeOfPropertyOrIndexSignature(t, propName); - return !(narrowedPropType.flags & TypeFlags.Never) && areTypesComparable(narrowedPropType, discriminantType); + return !(discriminantType.flags & TypeFlags.Never) && !(narrowedPropType.flags & TypeFlags.Never) && areTypesComparable(narrowedPropType, discriminantType); }); } @@ -25194,19 +25238,27 @@ namespace ts { function isTypePresencePossible(type: Type, propName: __String, assumeTrue: boolean) { const prop = getPropertyOfType(type, propName); - if (prop) { - return prop.flags & SymbolFlags.Optional ? true : assumeTrue; - } - return getApplicableIndexInfoForName(type, propName) ? true : !assumeTrue; + return prop ? + !!(prop.flags & SymbolFlags.Optional) || assumeTrue : + !!getApplicableIndexInfoForName(type, propName) || !assumeTrue; } - function narrowByInKeyword(type: Type, name: __String, assumeTrue: boolean) { - if (type.flags & TypeFlags.Union - || type.flags & TypeFlags.Object && declaredType !== type && !(declaredType === unknownType && isEmptyAnonymousObjectType(type)) - || isThisTypeParameter(type) - || type.flags & TypeFlags.Intersection && every((type as IntersectionType).types, t => t.symbol !== globalThisSymbol)) { + function narrowByInKeyword(type: Type, nameType: StringLiteralType | NumberLiteralType | UniqueESSymbolType, assumeTrue: boolean) { + const name = getPropertyNameFromType(nameType); + const isKnownProperty = someType(type, t => isTypePresencePossible(t, name, /*assumeTrue*/ true)); + if (isKnownProperty) { + // If the check is for a known property (i.e. a property declared in some constituent of + // the target type), we filter the target type by presence of absence of the property. return filterType(type, t => isTypePresencePossible(t, name, assumeTrue)); } + if (assumeTrue) { + // If the check is for an unknown property, we intersect the target type with `Record`, + // where X is the name of the property. + const recordSymbol = getGlobalRecordSymbol(); + if (recordSymbol) { + return getIntersectionType([type, getTypeAliasInstantiation(recordSymbol, [nameType, unknownType])]); + } + } return type; } @@ -25266,15 +25318,14 @@ namespace ts { return narrowTypeByPrivateIdentifierInInExpression(type, expr, assumeTrue); } const target = getReferenceCandidate(expr.right); - const leftType = getTypeOfNode(expr.left); - if (leftType.flags & TypeFlags.StringLiteral) { - const name = escapeLeadingUnderscores((leftType as StringLiteralType).value); + const leftType = getTypeOfExpression(expr.left); + if (leftType.flags & TypeFlags.StringOrNumberLiteralOrUnique) { if (containsMissingType(type) && isAccessExpression(reference) && isMatchingReference(reference.expression, target) && - getAccessedPropertyName(reference) === name) { + getAccessedPropertyName(reference) === getPropertyNameFromType(leftType as StringLiteralType | NumberLiteralType | UniqueESSymbolType)) { return getTypeWithFacts(type, assumeTrue ? TypeFacts.NEUndefined : TypeFacts.EQUndefined); } if (isMatchingReference(reference, target)) { - return narrowByInKeyword(type, name, assumeTrue); + return narrowByInKeyword(type, leftType as StringLiteralType | NumberLiteralType | UniqueESSymbolType, assumeTrue); } } break; @@ -25340,25 +25391,11 @@ namespace ts { assumeTrue = !assumeTrue; } const valueType = getTypeOfExpression(value); - if (((type.flags & TypeFlags.Unknown) || isEmptyAnonymousObjectType(type) && !(valueType.flags & TypeFlags.Nullable)) && - assumeTrue && - (operator === SyntaxKind.EqualsEqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) - ) { - if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive)) { - return valueType; - } - if (valueType.flags & TypeFlags.Object) { - return nonPrimitiveType; - } - if (type.flags & TypeFlags.Unknown) { - return type; - } - } + const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken; if (valueType.flags & TypeFlags.Nullable) { if (!strictNullChecks) { return type; } - const doubleEquals = operator === SyntaxKind.EqualsEqualsToken || operator === SyntaxKind.ExclamationEqualsToken; const facts = doubleEquals ? assumeTrue ? TypeFacts.EQUndefinedOrNull : TypeFacts.NEUndefinedOrNull : valueType.flags & TypeFlags.Null ? @@ -25367,10 +25404,16 @@ namespace ts { return getAdjustedTypeWithFacts(type, facts); } if (assumeTrue) { - const filterFn: (t: Type) => boolean = operator === SyntaxKind.EqualsEqualsToken ? - t => areTypesComparable(t, valueType) || isCoercibleUnderDoubleEquals(t, valueType) : - t => areTypesComparable(t, valueType); - return replacePrimitivesWithLiterals(filterType(type, filterFn), valueType); + if (!doubleEquals && (type.flags & TypeFlags.Unknown || someType(type, isEmptyAnonymousObjectType))) { + if (valueType.flags & (TypeFlags.Primitive | TypeFlags.NonPrimitive) || isEmptyAnonymousObjectType(valueType)) { + return valueType; + } + if (valueType.flags & TypeFlags.Object) { + return nonPrimitiveType; + } + } + const filteredType = filterType(type, t => areTypesComparable(t, valueType) || doubleEquals && isCoercibleUnderDoubleEquals(t, valueType)); + return replacePrimitivesWithLiterals(filteredType, valueType); } if (isUnitType(valueType)) { return filterType(type, t => !(isUnitLikeType(t) && areTypesComparable(t, valueType))); @@ -25956,10 +25999,11 @@ namespace ts { if (!(links.flags & NodeCheckFlags.InCheckIdentifier)) { links.flags |= NodeCheckFlags.InCheckIdentifier; const parentType = getTypeForBindingElementParent(parent, CheckMode.Normal); + const parentTypeConstraint = parentType && mapType(parentType, getBaseConstraintOrType); links.flags &= ~NodeCheckFlags.InCheckIdentifier; - if (parentType && parentType.flags & TypeFlags.Union && !(parent.kind === SyntaxKind.Parameter && isSymbolAssigned(symbol))) { + if (parentTypeConstraint && parentTypeConstraint.flags & TypeFlags.Union && !(parent.kind === SyntaxKind.Parameter && isSymbolAssigned(symbol))) { const pattern = declaration.parent; - const narrowedType = getFlowTypeOfReference(pattern, parentType, parentType, /*flowContainer*/ undefined, location.flowNode); + const narrowedType = getFlowTypeOfReference(pattern, parentTypeConstraint, parentTypeConstraint, /*flowContainer*/ undefined, location.flowNode); if (narrowedType.flags & TypeFlags.Never) { return neverType; } @@ -29204,11 +29248,30 @@ namespace ts { } function reportObjectPossiblyNullOrUndefinedError(node: Node, facts: TypeFacts) { - error(node, facts & TypeFacts.IsUndefined ? facts & TypeFacts.IsNull ? - Diagnostics.Object_is_possibly_null_or_undefined : - Diagnostics.Object_is_possibly_undefined : - Diagnostics.Object_is_possibly_null - ); + const nodeText = isEntityNameExpression(node) ? entityNameToString(node) : undefined; + if (node.kind === SyntaxKind.NullKeyword) { + error(node, Diagnostics.The_value_0_cannot_be_used_here, "null"); + return; + } + if (nodeText !== undefined && nodeText.length < 100) { + if (isIdentifier(node) && nodeText === "undefined") { + error(node, Diagnostics.The_value_0_cannot_be_used_here, "undefined"); + return; + } + error(node, facts & TypeFacts.IsUndefined ? facts & TypeFacts.IsNull ? + Diagnostics._0_is_possibly_null_or_undefined : + Diagnostics._0_is_possibly_undefined : + Diagnostics._0_is_possibly_null, + nodeText + ); + } + else { + error(node, facts & TypeFacts.IsUndefined ? facts & TypeFacts.IsNull ? + Diagnostics.Object_is_possibly_null_or_undefined : + Diagnostics.Object_is_possibly_undefined : + Diagnostics.Object_is_possibly_null + ); + } } function reportCannotInvokePossiblyNullOrUndefinedError(node: Node, facts: TypeFacts) { @@ -29225,6 +29288,13 @@ namespace ts { reportError: (node: Node, facts: TypeFacts) => void ): Type { if (strictNullChecks && type.flags & TypeFlags.Unknown) { + if (isEntityNameExpression(node)) { + const nodeText = entityNameToString(node); + if (nodeText.length < 100) { + error(node, Diagnostics._0_is_of_type_unknown, nodeText); + return errorType; + } + } error(node, Diagnostics.Object_is_of_type_unknown); return errorType; } @@ -29244,6 +29314,17 @@ namespace ts { function checkNonNullNonVoidType(type: Type, node: Node): Type { const nonNullType = checkNonNullType(type, node); if (nonNullType.flags & TypeFlags.Void) { + if (isEntityNameExpression(node)) { + const nodeText = entityNameToString(node); + if (isIdentifier(node) && nodeText === "undefined") { + error(node, Diagnostics.The_value_0_cannot_be_used_here, nodeText); + return nonNullType; + } + if (nodeText.length < 100) { + error(node, Diagnostics._0_is_possibly_undefined, nodeText); + return nonNullType; + } + } error(node, Diagnostics.Object_is_possibly_undefined); } return nonNullType; @@ -29843,7 +29924,7 @@ namespace ts { return !!s && getMinArgumentCount(s) >= 1 && isTypeAssignableTo(keyedType, getTypeAtPosition(s, 0)); } return false; - }; + } const suggestedMethod = isAssignmentTarget(expr) ? "set" : "get"; if (!hasProp(suggestedMethod)) { @@ -33957,6 +34038,10 @@ namespace ts { return booleanType; } + function hasEmptyObjectIntersection(type: Type): boolean { + return someType(type, t => t === unknownEmptyObjectType || !!(t.flags & TypeFlags.Intersection) && some((t as IntersectionType).types, isEmptyAnonymousObjectType)); + } + function checkInExpression(left: Expression, right: Expression, leftType: Type, rightType: Type): Type { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; @@ -33973,43 +34058,20 @@ namespace ts { } } else { - leftType = checkNonNullType(leftType, left); - // TypeScript 1.0 spec (April 2014): 4.15.5 - // Require the left operand to be of type Any, the String primitive type, or the Number primitive type. - if (!(allTypesAssignableToKind(leftType, TypeFlags.StringLike | TypeFlags.NumberLike | TypeFlags.ESSymbolLike) || - isTypeAssignableToKind(leftType, TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.TypeParameter))) { - error(left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_a_private_identifier_or_of_type_any_string_number_or_symbol); + // The type of the lef operand must be assignable to string, number, or symbol. + checkTypeAssignableTo(checkNonNullType(leftType, left), stringNumberSymbolType, left); + } + // The type of the right operand must be assignable to 'object'. + if (checkTypeAssignableTo(checkNonNullType(rightType, right), nonPrimitiveType, right)) { + // The {} type is assignable to the object type, yet {} might represent a primitive type. Here we + // detect and error on {} that results from narrowing the unknown type, as well as intersections + // that include {} (we know that the other types in such intersections are assignable to object + // since we already checked for that). + if (hasEmptyObjectIntersection(rightType)) { + error(right, Diagnostics.Type_0_may_represent_a_primitive_value_which_is_not_permitted_as_the_right_operand_of_the_in_operator, typeToString(rightType)); } } - rightType = checkNonNullType(rightType, right); - // TypeScript 1.0 spec (April 2014): 4.15.5 - // The in operator requires the right operand to be - // - // 1. assignable to the non-primitive type, - // 2. an unconstrained type parameter, - // 3. a union or intersection including one or more type parameters, whose constituents are all assignable to the - // the non-primitive type, or are unconstrainted type parameters, or have constraints assignable to the - // non-primitive type, or - // 4. a type parameter whose constraint is - // i. an object type, - // ii. the non-primitive type, or - // iii. a union or intersection with at least one constituent assignable to an object or non-primitive type. - // - // The divergent behavior for type parameters and unions containing type parameters is a workaround for type - // parameters not being narrowable. If the right operand is a concrete type, we can error if there is any chance - // it is a primitive. But if the operand is a type parameter, it cannot be narrowed, so we don't issue an error - // unless *all* instantiations would result in an error. - // // The result is always of the Boolean primitive type. - const rightTypeConstraint = getConstraintOfType(rightType); - if (!allTypesAssignableToKind(rightType, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive) || - rightTypeConstraint && ( - isTypeAssignableToKind(rightType, TypeFlags.UnionOrIntersection) && !allTypesAssignableToKind(rightTypeConstraint, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive) || - !maybeTypeOfKind(rightTypeConstraint, TypeFlags.NonPrimitive | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object) - ) - ) { - error(right, Diagnostics.The_right_hand_side_of_an_in_expression_must_not_be_a_primitive); - } return booleanType; } @@ -36209,8 +36271,8 @@ namespace ts { } function getEffectiveTypeArgumentAtIndex(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: readonly TypeParameter[], index: number): Type { - if (index < typeParameters.length) { - return getTypeFromTypeNode(node.typeArguments![index]); + if (node.typeArguments && index < node.typeArguments.length) { + return getTypeFromTypeNode(node.typeArguments[index]); } return getEffectiveTypeArguments(node, typeParameters)[index]; } @@ -43435,7 +43497,8 @@ namespace ts { } const node = getParseTreeNode(nodeIn, isIdentifier); if (node) { - const symbol = getReferencedValueSymbol(node); + const symbol = getReferencedValueOrAliasSymbol(node); + // We should only get the declaration of an alias if there isn't a local value // declaration for the symbol if (isNonLocalAlias(symbol, /*excludes*/ SymbolFlags.Value) && !getTypeOnlyAliasDeclaration(symbol)) { @@ -43839,6 +43902,30 @@ namespace ts { return resolveName(location, reference.escapedText, SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); } + /** + * Get either a value-meaning symbol or an alias symbol. + * Unlike `getReferencedValueSymbol`, if the cached resolved symbol is the unknown symbol, + * we call `resolveName` to find a symbol. + * This is because when caching the resolved symbol, we only consider value symbols, but here + * we want to also get an alias symbol if one exists. + */ + function getReferencedValueOrAliasSymbol(reference: Identifier): Symbol | undefined { + const resolvedSymbol = getNodeLinks(reference).resolvedSymbol; + if (resolvedSymbol && resolvedSymbol !== unknownSymbol) { + return resolvedSymbol; + } + + return resolveName( + reference, + reference.escapedText, + SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias, + /*nodeNotFoundMessage*/ undefined, + /*nameArg*/ undefined, + /*isUse*/ true, + /*excludeGlobals*/ undefined, + /*getSpellingSuggestions*/ undefined); + } + function getReferencedValueDeclaration(referenceIn: Identifier): Declaration | undefined { if (!isGeneratedIdentifier(referenceIn)) { const reference = getParseTreeNode(referenceIn, isIdentifier); @@ -46058,7 +46145,7 @@ namespace ts { } const nodeArguments = node.arguments; - if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.NodeNext) { + if (moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.NodeNext && moduleKind !== ModuleKind.Node16) { // We are allowed trailing comma after proposal-import-assertions. checkGrammarForDisallowedTrailingComma(nodeArguments); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 9a8a99877c5b7..96a88264d26c4 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -195,6 +195,7 @@ namespace ts { shortName: "h", type: "boolean", showInSimplifiedHelpView: true, + isCommandLineOnly: true, category: Diagnostics.Command_line_Options, description: Diagnostics.Print_this_message, defaultValueDescription: false, @@ -203,6 +204,8 @@ namespace ts { name: "help", shortName: "?", type: "boolean", + isCommandLineOnly: true, + category: Diagnostics.Command_line_Options, defaultValueDescription: false, }, { @@ -3716,7 +3719,7 @@ namespace ts { export function convertCompilerOptionsForTelemetry(opts: CompilerOptions): CompilerOptions { const out: CompilerOptions = {}; for (const key in opts) { - if (opts.hasOwnProperty(key)) { + if (hasProperty(opts, key)) { const type = getOptionFromName(key); if (type !== undefined) { // Ignore unknown options out[key] = getOptionValueWithEmptyStrings(opts[key], type); diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index d6edd94b3dc49..70893ceb29bc1 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -279,7 +279,7 @@ namespace ts { if (typeof func !== "function") { return ""; } - else if (func.hasOwnProperty("name")) { + else if (hasProperty(func, "name")) { return (func as any).name; } else { @@ -625,7 +625,7 @@ namespace ts { ]; for (const ctor of nodeConstructors) { - if (!ctor.prototype.hasOwnProperty("__debugKind")) { + if (!hasProperty(ctor, "__debugKind")) { Object.defineProperties(ctor.prototype, { // for use with vscode-js-debug's new customDescriptionGenerator in launch.json __tsDebuggerDisplay: { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 584589ba17ffd..de2f6b3f033c5 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1844,14 +1844,6 @@ "category": "Error", "code": 2359 }, - "The left-hand side of an 'in' expression must be a private identifier or of type 'any', 'string', 'number', or 'symbol'.": { - "category": "Error", - "code": 2360 - }, - "The right-hand side of an 'in' expression must not be a primitive.": { - "category": "Error", - "code": 2361 - }, "The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": { "category": "Error", "code": 2362 @@ -2845,6 +2837,10 @@ "category": "Error", "code": 2637 }, + "Type '{0}' may represent a primitive value, which is not permitted as the right operand of the 'in' operator.": { + "category": "Error", + "code": 2638 + }, "Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": { "category": "Error", @@ -7497,5 +7493,25 @@ "Properties with the 'accessor' modifier are only available when targeting ECMAScript 2015 and higher.": { "category": "Error", "code": 18045 + }, + "'{0}' is of type 'unknown'.": { + "category": "Error", + "code": 18046 + }, + "'{0}' is possibly 'null'.": { + "category": "Error", + "code": 18047 + }, + "'{0}' is possibly 'undefined'.": { + "category": "Error", + "code": 18048 + }, + "'{0}' is possibly 'null' or 'undefined'.": { + "category": "Error", + "code": 18049 + }, + "The value '{0}' cannot be used here.": { + "category": "Error", + "code": 18050 } } diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 9cdd755f3b28c..f2d2c922e474f 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -5668,7 +5668,7 @@ namespace ts { setOriginalNode(clone, node); for (const key in node) { - if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) { + if (hasProperty(clone, key) || !hasProperty(node, key)) { continue; } diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 9e3b15f09580c..3e46edbec46c1 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -13,7 +13,7 @@ namespace ts { function withPackageId(packageInfo: PackageJsonInfo | undefined, r: PathAndExtension | undefined): Resolved | undefined { let packageId: PackageId | undefined; if (r && packageInfo) { - const packageJsonContent = packageInfo.packageJsonContent as PackageJson; + const packageJsonContent = packageInfo.contents.packageJsonContent as PackageJson; if (typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string") { packageId = { name: packageJsonContent.name, @@ -1679,8 +1679,8 @@ namespace ts { function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, considerPackageJson = true) { const packageInfo = considerPackageJson ? getPackageJsonInfo(candidate, onlyRecordFailures, state) : undefined; - const packageJsonContent = packageInfo && packageInfo.packageJsonContent; - const versionPaths = packageInfo && packageInfo.versionPaths; + const packageJsonContent = packageInfo && packageInfo.contents.packageJsonContent; + const versionPaths = packageInfo && packageInfo.contents.versionPaths; return withPackageId(packageInfo, loadNodeModuleFromDirectoryWorker(extensions, candidate, onlyRecordFailures, state, packageJsonContent, versionPaths)); } @@ -1692,10 +1692,10 @@ namespace ts { cache: ModuleResolutionCache | undefined, resolveJs?: boolean, ): string[] | false { - if (!resolveJs && packageJsonInfo.resolvedEntrypoints !== undefined) { + if (!resolveJs && packageJsonInfo.contents.resolvedEntrypoints !== undefined) { // Cached value excludes resolutions to JS files - those could be // cached separately, but they're used rarely. - return packageJsonInfo.resolvedEntrypoints; + return packageJsonInfo.contents.resolvedEntrypoints; } let entrypoints: string[] | undefined; @@ -1709,16 +1709,16 @@ namespace ts { packageJsonInfo.packageDirectory, /*onlyRecordFailures*/ false, requireState, - packageJsonInfo.packageJsonContent, - packageJsonInfo.versionPaths); + packageJsonInfo.contents.packageJsonContent, + packageJsonInfo.contents.versionPaths); entrypoints = append(entrypoints, requireResolution?.path); - if (features & NodeResolutionFeatures.Exports && packageJsonInfo.packageJsonContent.exports) { + if (features & NodeResolutionFeatures.Exports && packageJsonInfo.contents.packageJsonContent.exports) { for (const conditions of [["node", "import", "types"], ["node", "require", "types"]]) { const exportState = { ...requireState, failedLookupLocations: [], conditions }; const exportResolutions = loadEntrypointsFromExportMap( packageJsonInfo, - packageJsonInfo.packageJsonContent.exports, + packageJsonInfo.contents.packageJsonContent.exports, exportState, extensions); if (exportResolutions) { @@ -1729,7 +1729,7 @@ namespace ts { } } - return packageJsonInfo.resolvedEntrypoints = entrypoints || false; + return packageJsonInfo.contents.resolvedEntrypoints = entrypoints || false; } function loadEntrypointsFromExportMap( @@ -1808,6 +1808,10 @@ namespace ts { /*@internal*/ export interface PackageJsonInfo { packageDirectory: string; + contents: PackageJsonInfoContents; + } + /*@internal*/ + export interface PackageJsonInfoContents { packageJsonContent: PackageJsonPathFields; versionPaths: VersionPaths | undefined; /** false: resolved to nothing. undefined: not yet resolved */ @@ -1818,7 +1822,7 @@ namespace ts { * A function for locating the package.json scope for a given path */ /*@internal*/ - export function getPackageScopeForPath(fileName: Path, state: ModuleResolutionState): PackageJsonInfo | undefined { + export function getPackageScopeForPath(fileName: string, state: ModuleResolutionState): PackageJsonInfo | undefined { const parts = getPathComponents(fileName); parts.pop(); while (parts.length > 0) { @@ -1845,7 +1849,9 @@ namespace ts { if (typeof existing !== "boolean") { if (traceEnabled) trace(host, Diagnostics.File_0_exists_according_to_earlier_cached_lookups, packageJsonPath); state.affectingLocations.push(packageJsonPath); - return existing; + return existing.packageDirectory === packageDirectory ? + existing : + { packageDirectory, contents: existing.contents }; } else { if (existing && traceEnabled) trace(host, Diagnostics.File_0_does_not_exist_according_to_earlier_cached_lookups, packageJsonPath); @@ -1860,7 +1866,7 @@ namespace ts { trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath); } const versionPaths = readPackageJsonTypesVersionPaths(packageJsonContent, state); - const result = { packageDirectory, packageJsonContent, versionPaths, resolvedEntrypoints: undefined }; + const result: PackageJsonInfo = { packageDirectory, contents: { packageJsonContent, versionPaths, resolvedEntrypoints: undefined } }; state.packageJsonInfoCache?.setPackageJsonInfo(packageJsonPath, result); state.affectingLocations.push(packageJsonPath); return result; @@ -1994,17 +2000,16 @@ namespace ts { } function loadModuleFromSelfNameReference(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { - const useCaseSensitiveFileNames = typeof state.host.useCaseSensitiveFileNames === "function" ? state.host.useCaseSensitiveFileNames() : state.host.useCaseSensitiveFileNames; - const directoryPath = toPath(combinePaths(directory, "dummy"), state.host.getCurrentDirectory?.(), createGetCanonicalFileName(useCaseSensitiveFileNames === undefined ? true : useCaseSensitiveFileNames)); + const directoryPath = getNormalizedAbsolutePath(combinePaths(directory, "dummy"), state.host.getCurrentDirectory?.()); const scope = getPackageScopeForPath(directoryPath, state); - if (!scope || !scope.packageJsonContent.exports) { + if (!scope || !scope.contents.packageJsonContent.exports) { return undefined; } - if (typeof scope.packageJsonContent.name !== "string") { + if (typeof scope.contents.packageJsonContent.name !== "string") { return undefined; } const parts = getPathComponents(moduleName); // unrooted paths should have `""` as their 0th entry - const nameParts = getPathComponents(scope.packageJsonContent.name); + const nameParts = getPathComponents(scope.contents.packageJsonContent.name); if (!every(nameParts, (p, i) => parts[i] === p)) { return undefined; } @@ -2013,31 +2018,31 @@ namespace ts { } function loadModuleFromExports(scope: PackageJsonInfo, extensions: Extensions, subpath: string, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult { - if (!scope.packageJsonContent.exports) { + if (!scope.contents.packageJsonContent.exports) { return undefined; } if (subpath === ".") { let mainExport; - if (typeof scope.packageJsonContent.exports === "string" || Array.isArray(scope.packageJsonContent.exports) || (typeof scope.packageJsonContent.exports === "object" && noKeyStartsWithDot(scope.packageJsonContent.exports as MapLike))) { - mainExport = scope.packageJsonContent.exports; + if (typeof scope.contents.packageJsonContent.exports === "string" || Array.isArray(scope.contents.packageJsonContent.exports) || (typeof scope.contents.packageJsonContent.exports === "object" && noKeyStartsWithDot(scope.contents.packageJsonContent.exports as MapLike))) { + mainExport = scope.contents.packageJsonContent.exports; } - else if (hasProperty(scope.packageJsonContent.exports as MapLike, ".")) { - mainExport = (scope.packageJsonContent.exports as MapLike)["."]; + else if (hasProperty(scope.contents.packageJsonContent.exports as MapLike, ".")) { + mainExport = (scope.contents.packageJsonContent.exports as MapLike)["."]; } if (mainExport) { const loadModuleFromTargetImportOrExport = getLoadModuleFromTargetImportOrExport(extensions, state, cache, redirectedReference, subpath, scope, /*isImports*/ false); return loadModuleFromTargetImportOrExport(mainExport, "", /*pattern*/ false); } } - else if (allKeysStartWithDot(scope.packageJsonContent.exports as MapLike)) { - if (typeof scope.packageJsonContent.exports !== "object") { + else if (allKeysStartWithDot(scope.contents.packageJsonContent.exports as MapLike)) { + if (typeof scope.contents.packageJsonContent.exports !== "object") { if (state.traceEnabled) { trace(state.host, Diagnostics.Export_specifier_0_does_not_exist_in_package_json_scope_at_path_1, subpath, scope.packageDirectory); } return toSearchResult(/*value*/ undefined); } - const result = loadModuleFromImportsOrExports(extensions, state, cache, redirectedReference, subpath, scope.packageJsonContent.exports, scope, /*isImports*/ false); + const result = loadModuleFromImportsOrExports(extensions, state, cache, redirectedReference, subpath, scope.contents.packageJsonContent.exports, scope, /*isImports*/ false); if (result) { return result; } @@ -2056,8 +2061,7 @@ namespace ts { } return toSearchResult(/*value*/ undefined); } - const useCaseSensitiveFileNames = typeof state.host.useCaseSensitiveFileNames === "function" ? state.host.useCaseSensitiveFileNames() : state.host.useCaseSensitiveFileNames; - const directoryPath = toPath(combinePaths(directory, "dummy"), state.host.getCurrentDirectory?.(), createGetCanonicalFileName(useCaseSensitiveFileNames === undefined ? true : useCaseSensitiveFileNames)); + const directoryPath = getNormalizedAbsolutePath(combinePaths(directory, "dummy"), state.host.getCurrentDirectory?.()); const scope = getPackageScopeForPath(directoryPath, state); if (!scope) { if (state.traceEnabled) { @@ -2065,14 +2069,14 @@ namespace ts { } return toSearchResult(/*value*/ undefined); } - if (!scope.packageJsonContent.imports) { + if (!scope.contents.packageJsonContent.imports) { if (state.traceEnabled) { trace(state.host, Diagnostics.package_json_scope_0_has_no_imports_defined, scope.packageDirectory); } return toSearchResult(/*value*/ undefined); } - const result = loadModuleFromImportsOrExports(extensions, state, cache, redirectedReference, moduleName, scope.packageJsonContent.imports, scope, /*isImports*/ true); + const result = loadModuleFromImportsOrExports(extensions, state, cache, redirectedReference, moduleName, scope.contents.packageJsonContent.imports, scope, /*isImports*/ true); if (result) { return result; } @@ -2426,8 +2430,8 @@ namespace ts { candidate, !nodeModulesDirectoryExists, state, - packageInfo.packageJsonContent, - packageInfo.versionPaths + packageInfo.contents.packageJsonContent, + packageInfo.contents.versionPaths ); return withPackageId(packageInfo, fromDirectory); } @@ -2436,7 +2440,7 @@ namespace ts { const { packageName, rest } = parsePackageName(moduleName); const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => { // package exports are higher priority than file/directory lookups (and, if there's exports present, blocks them) - if (packageInfo && packageInfo.packageJsonContent.exports && state.features & NodeResolutionFeatures.Exports) { + if (packageInfo && packageInfo.contents.packageJsonContent.exports && state.features & NodeResolutionFeatures.Exports) { return loadModuleFromExports(packageInfo, extensions, combinePaths(".", rest), state, cache, redirectedReference)?.value; } let pathAndExtension = @@ -2446,13 +2450,13 @@ namespace ts { candidate, onlyRecordFailures, state, - packageInfo && packageInfo.packageJsonContent, - packageInfo && packageInfo.versionPaths + packageInfo && packageInfo.contents.packageJsonContent, + packageInfo && packageInfo.contents.versionPaths ); if ( !pathAndExtension && packageInfo // eslint-disable-next-line no-null/no-null - && (packageInfo.packageJsonContent.exports === undefined || packageInfo.packageJsonContent.exports === null) + && (packageInfo.contents.packageJsonContent.exports === undefined || packageInfo.contents.packageJsonContent.exports === null) && state.features & NodeResolutionFeatures.EsmMode ) { // EsmMode disables index lookup in `loadNodeModuleFromDirectoryWorker` generally, however non-relative package resolutions still assume @@ -2467,12 +2471,12 @@ namespace ts { // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId and path mappings. packageInfo = getPackageJsonInfo(packageDirectory, !nodeModulesDirectoryExists, state); - if (packageInfo && packageInfo.versionPaths) { + if (packageInfo && packageInfo.contents.versionPaths) { if (state.traceEnabled) { - trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, packageInfo.versionPaths.version, version, rest); + trace(state.host, Diagnostics.package_json_has_a_typesVersions_entry_0_that_matches_compiler_version_1_looking_for_a_pattern_to_match_module_name_2, packageInfo.contents.versionPaths.version, version, rest); } const packageDirectoryExists = nodeModulesDirectoryExists && directoryProbablyExists(packageDirectory, state.host); - const fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, packageInfo.versionPaths.paths, /*pathPatterns*/ undefined, loader, !packageDirectoryExists, state); + const fromPaths = tryLoadModuleUsingPaths(extensions, rest, packageDirectory, packageInfo.contents.versionPaths.paths, /*pathPatterns*/ undefined, loader, !packageDirectoryExists, state); if (fromPaths) { return fromPaths.value; } diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index e38dd46598587..32640fcb81579 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -807,7 +807,7 @@ namespace ts.moduleSpecifiers { let maybeBlockedByTypesVersions = false; const cachedPackageJson = host.getPackageJsonInfoCache?.()?.getPackageJsonInfo(packageJsonPath); if (typeof cachedPackageJson === "object" || cachedPackageJson === undefined && host.fileExists(packageJsonPath)) { - const packageJsonContent = cachedPackageJson?.packageJsonContent || JSON.parse(host.readFile!(packageJsonPath)!); + const packageJsonContent = cachedPackageJson?.contents.packageJsonContent || JSON.parse(host.readFile!(packageJsonPath)!); const importMode = overrideMode || importingSourceFile.impliedNodeFormat; if (getEmitModuleResolutionKind(options) === ModuleResolutionKind.Node16 || getEmitModuleResolutionKind(options) === ModuleResolutionKind.NodeNext) { const conditions = ["node", importMode === ModuleKind.ESNext ? "import" : "require", "types"]; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1dab0f8cfe9d2..78de7da838d62 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -718,6 +718,7 @@ namespace ts { [SyntaxKind.JSDocProtectedTag]: forEachChildInJSDocTag, [SyntaxKind.JSDocReadonlyTag]: forEachChildInJSDocTag, [SyntaxKind.JSDocDeprecatedTag]: forEachChildInJSDocTag, + [SyntaxKind.JSDocOverrideTag]: forEachChildInJSDocTag, [SyntaxKind.PartiallyEmittedExpression]: forEachChildInPartiallyEmittedExpression, }; @@ -727,7 +728,7 @@ namespace ts { return visitNodes(cbNode, cbNodes, node.typeParameters) || visitNodes(cbNode, cbNodes, node.parameters) || visitNode(cbNode, node.type); - }; + } function forEachChildInUnionOrIntersectionType(node: UnionTypeNode | IntersectionTypeNode, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { return visitNodes(cbNode, cbNodes, node.types); @@ -799,10 +800,10 @@ namespace ts { } function forEachChildInJSDocLinkCodeOrPlain(node: JSDocLink | JSDocLinkCode | JSDocLinkPlain, cbNode: (node: Node) => T | undefined, _cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { - return visitNode(cbNode, node.name); + return visitNode(cbNode, node.name); } - function forEachChildInJSDocTag(node: JSDocUnknownTag | JSDocClassTag | JSDocPublicTag | JSDocPrivateTag | JSDocProtectedTag | JSDocReadonlyTag | JSDocDeprecatedTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { + function forEachChildInJSDocTag(node: JSDocUnknownTag | JSDocClassTag | JSDocPublicTag | JSDocPrivateTag | JSDocProtectedTag | JSDocReadonlyTag | JSDocDeprecatedTag | JSDocOverrideTag, cbNode: (node: Node) => T | undefined, cbNodes?: (nodes: NodeArray) => T | undefined): T | undefined { return visitNode(cbNode, node.tagName) || (typeof node.comment === "string" ? undefined : visitNodes(cbNode, cbNodes, node.comment)); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 1ebef19e336a2..5b48d317db7df 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -503,7 +503,7 @@ namespace ts { /* @internal */ imports: SourceFile["imports"]; /* @internal */ moduleAugmentations: SourceFile["moduleAugmentations"]; impliedNodeFormat?: SourceFile["impliedNodeFormat"]; - }; + } /** * Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly @@ -849,7 +849,7 @@ namespace ts { /*@internal*/ export function getImpliedNodeFormatForFileWorker( - fileName: Path, + fileName: string, packageJsonInfoCache: PackageJsonInfoCache | undefined, host: ModuleResolutionHost, options: CompilerOptions, @@ -870,7 +870,7 @@ namespace ts { state.failedLookupLocations = packageJsonLocations; state.affectingLocations = packageJsonLocations; const packageJsonScope = getPackageScopeForPath(fileName, state); - const impliedNodeFormat = packageJsonScope?.packageJsonContent.type === "module" ? ModuleKind.ESNext : ModuleKind.CommonJS; + const impliedNodeFormat = packageJsonScope?.contents.packageJsonContent.type === "module" ? ModuleKind.ESNext : ModuleKind.CommonJS; return { impliedNodeFormat, packageJsonLocations, packageJsonScope }; } } @@ -2834,7 +2834,7 @@ namespace ts { // It's a _little odd_ that we can't set `impliedNodeFormat` until the program step - but it's the first and only time we have a resolution cache // and a freshly made source file node on hand at the same time, and we need both to set the field. Persisting the resolution cache all the way // to the check and emit steps would be bad - so we much prefer detecting and storing the format information on the source file node upfront. - const result = getImpliedNodeFormatForFileWorker(toPath(fileName), moduleResolutionCache?.getPackageJsonInfoCache(), host, options); + const result = getImpliedNodeFormatForFileWorker(getNormalizedAbsolutePath(fileName, currentDirectory), moduleResolutionCache?.getPackageJsonInfoCache(), host, options); const languageVersion = getEmitScriptTarget(options); const setExternalModuleIndicator = getSetExternalModuleIndicator(options); return typeof result === "object" ? @@ -3538,11 +3538,12 @@ namespace ts { createDiagnosticForOptionName(Diagnostics.Option_preserveConstEnums_cannot_be_disabled_when_isolatedModules_is_enabled, "preserveConstEnums", "isolatedModules"); } - const firstNonExternalModuleSourceFile = find(files, f => !isExternalModule(f) && !isSourceFileJS(f) && !f.isDeclarationFile && f.scriptKind !== ScriptKind.JSON); - if (firstNonExternalModuleSourceFile) { - const span = getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile); - programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, - Diagnostics._0_cannot_be_compiled_under_isolatedModules_because_it_is_considered_a_global_script_file_Add_an_import_export_or_an_empty_export_statement_to_make_it_a_module, getBaseFileName(firstNonExternalModuleSourceFile.fileName))); + for (const file of files) { + if (!isExternalModule(file) && !isSourceFileJS(file) && !file.isDeclarationFile && file.scriptKind !== ScriptKind.JSON) { + const span = getErrorSpanForNode(file, file); + programDiagnostics.add(createFileDiagnostic(file, span.start, span.length, + Diagnostics._0_cannot_be_compiled_under_isolatedModules_because_it_is_considered_a_global_script_file_Add_an_import_export_or_an_empty_export_statement_to_make_it_a_module, getBaseFileName(file.fileName))); + } } } else if (firstNonAmbientExternalModuleSourceFile && languageVersion < ScriptTarget.ES2015 && options.module === ModuleKind.None) { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index a54389fbb9474..1bb62f652241c 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -361,7 +361,7 @@ namespace ts { /* @internal */ export function computeLineStarts(text: string): number[] { - const result: number[] = new Array(); + const result: number[] = []; let pos = 0; let lineStart = 0; while (pos < text.length) { diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index b0cc058fd93bf..bcc37fcd5a857 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -35,8 +35,7 @@ namespace ts { export type FileWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, modifiedTime?: Date) => void; export type DirectoryWatcherCallback = (fileName: string) => void; - /*@internal*/ - export interface WatchedFile { + interface WatchedFile { readonly fileName: string; readonly callback: FileWatcherCallback; mtime: Date; @@ -81,8 +80,7 @@ namespace ts { /* @internal */ export let unchangedPollThresholds = createPollingIntervalBasedLevels(defaultChunkLevels); - /* @internal */ - export function setCustomPollingValues(system: System) { + function setCustomPollingValues(system: System) { if (!system.getEnvironmentVariable) { return; } @@ -189,31 +187,28 @@ namespace ts { } } - /* @internal */ - export function createDynamicPriorityPollingWatchFile(host: { + interface WatchedFileWithUnchangedPolls extends WatchedFileWithIsClosed { + unchangedPolls: number; + } + function createDynamicPriorityPollingWatchFile(host: { getModifiedTime: NonNullable; setTimeout: NonNullable; }): HostWatchFile { - interface WatchedFile extends ts.WatchedFile { - isClosed?: boolean; - unchangedPolls: number; - } - - interface PollingIntervalQueue extends Array { + interface PollingIntervalQueue extends Array { pollingInterval: PollingInterval; pollIndex: number; pollScheduled: boolean; } - const watchedFiles: WatchedFile[] = []; - const changedFilesInLastPoll: WatchedFile[] = []; + const watchedFiles: WatchedFileWithUnchangedPolls[] = []; + const changedFilesInLastPoll: WatchedFileWithUnchangedPolls[] = []; const lowPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.Low); const mediumPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.Medium); const highPollingIntervalQueue = createPollingIntervalQueue(PollingInterval.High); return watchFile; function watchFile(fileName: string, callback: FileWatcherCallback, defaultPollingInterval: PollingInterval): FileWatcher { - const file: WatchedFile = { + const file: WatchedFileWithUnchangedPolls = { fileName, callback, unchangedPolls: 0, @@ -233,7 +228,7 @@ namespace ts { } function createPollingIntervalQueue(pollingInterval: PollingInterval): PollingIntervalQueue { - const queue = [] as WatchedFile[] as PollingIntervalQueue; + const queue = [] as WatchedFileWithUnchangedPolls[] as PollingIntervalQueue; queue.pollingInterval = pollingInterval; queue.pollIndex = 0; queue.pollScheduled = false; @@ -265,7 +260,7 @@ namespace ts { } } - function pollQueue(queue: (WatchedFile | undefined)[], pollingInterval: PollingInterval, pollIndex: number, chunkSize: number) { + function pollQueue(queue: (WatchedFileWithUnchangedPolls | undefined)[], pollingInterval: PollingInterval, pollIndex: number, chunkSize: number) { return pollWatchedFileQueue( host, queue, @@ -274,7 +269,7 @@ namespace ts { onWatchFileStat ); - function onWatchFileStat(watchedFile: WatchedFile, pollIndex: number, fileChanged: boolean) { + function onWatchFileStat(watchedFile: WatchedFileWithUnchangedPolls, pollIndex: number, fileChanged: boolean) { if (fileChanged) { watchedFile.unchangedPolls = 0; // Changed files go to changedFilesInLastPoll queue @@ -311,12 +306,12 @@ namespace ts { } } - function addToPollingIntervalQueue(file: WatchedFile, pollingInterval: PollingInterval) { + function addToPollingIntervalQueue(file: WatchedFileWithUnchangedPolls, pollingInterval: PollingInterval) { pollingIntervalQueue(pollingInterval).push(file); scheduleNextPollIfNotAlreadyScheduled(pollingInterval); } - function addChangedFileToLowPollingIntervalQueue(file: WatchedFile) { + function addChangedFileToLowPollingIntervalQueue(file: WatchedFileWithUnchangedPolls) { changedFilesInLastPoll.push(file); scheduleNextPollIfNotAlreadyScheduled(PollingInterval.Low); } @@ -423,59 +418,50 @@ namespace ts { } } - /* @internal */ - export function createSingleFileWatcherPerName( - watchFile: HostWatchFile, - useCaseSensitiveFileNames: boolean - ): HostWatchFile { - interface SingleFileWatcher { - watcher: FileWatcher; - refCount: number; - } - const cache = new Map(); - const callbacksCache = createMultiMap(); + interface SingleFileWatcher{ + watcher: FileWatcher; + callbacks: T[]; + } + function createSingleWatcherPerName( + cache: Map>, + useCaseSensitiveFileNames: boolean, + name: string, + callback: T, + createWatcher: (callback: T) => FileWatcher, + ): FileWatcher { const toCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); + const path = toCanonicalFileName(name); + const existing = cache.get(path); + if (existing) { + existing.callbacks.push(callback); + } + else { + cache.set(path, { + watcher: createWatcher(( + // Cant infer types correctly so lets satisfy checker + (param1: any, param2: never, param3: any) => cache.get(path)?.callbacks.slice().forEach(cb => cb(param1, param2, param3)) + ) as T), + callbacks: [callback] + }); + } - return (fileName, callback, pollingInterval, options) => { - const path = toCanonicalFileName(fileName); - const existing = cache.get(path); - if (existing) { - existing.refCount++; - } - else { - cache.set(path, { - watcher: watchFile( - fileName, - (fileName, eventKind, modifiedTime) => forEach( - callbacksCache.get(path), - cb => cb(fileName, eventKind, modifiedTime) - ), - pollingInterval, - options - ), - refCount: 1 - }); + return { + close: () => { + const watcher = cache.get(path); + // Watcher is not expected to be undefined, but if it is normally its because + // exception was thrown somewhere else and watch state is not what it should be + if (!watcher) return; + if (!orderedRemoveItem(watcher.callbacks, callback) || watcher.callbacks.length) return; + cache.delete(path); + closeFileWatcherOf(watcher); } - callbacksCache.add(path, callback); - - return { - close: () => { - const watcher = Debug.checkDefined(cache.get(path)); - callbacksCache.remove(path, callback); - watcher.refCount--; - if (watcher.refCount) return; - cache.delete(path); - closeFileWatcherOf(watcher); - } - }; }; } /** * Returns true if file status changed */ - /*@internal*/ - export function onWatchedFileStat(watchedFile: WatchedFile, modifiedTime: Date): boolean { + function onWatchedFileStat(watchedFile: WatchedFile, modifiedTime: Date): boolean { const oldTime = watchedFile.mtime.getTime(); const newTime = modifiedTime.getTime(); if (oldTime !== newTime) { @@ -512,8 +498,7 @@ namespace ts { curSysLog = logger; } - /*@internal*/ - export interface RecursiveDirectoryWatcherHost { + interface RecursiveDirectoryWatcherHost { watchDirectory: HostWatchDirectory; useCaseSensitiveFileNames: boolean; getCurrentDirectory: System["getCurrentDirectory"]; @@ -529,8 +514,7 @@ namespace ts { * that means if this is recursive watcher, watch the children directories as well * (eg on OS that dont support recursive watch using fs.watch use fs.watchFile) */ - /*@internal*/ - export function createDirectoryWatcherSupportingRecursive({ + function createDirectoryWatcherSupportingRecursive({ watchDirectory, useCaseSensitiveFileNames, getCurrentDirectory, @@ -792,8 +776,7 @@ namespace ts { Directory, } - /*@internal*/ - export function createFileWatcherCallback(callback: FsWatchCallback): FileWatcherCallback { + function createFileWatcherCallback(callback: FsWatchCallback): FileWatcherCallback { return (_fileName, eventKind, modifiedTime) => callback(eventKind === FileWatcherEventKind.Changed ? "change" : "rename", "", modifiedTime); } @@ -854,7 +837,7 @@ namespace ts { /*@internal*/ export interface CreateSystemWatchFunctions { // Polling watch file - pollingWatchFile: HostWatchFile; + pollingWatchFileWorker: HostWatchFile; // For dynamic polling watch file getModifiedTime: NonNullable; setTimeout: NonNullable; @@ -878,7 +861,7 @@ namespace ts { /*@internal*/ export function createSystemWatchFunctions({ - pollingWatchFile, + pollingWatchFileWorker, getModifiedTime, setTimeout, clearTimeout, @@ -896,6 +879,9 @@ namespace ts { inodeWatching, sysLog, }: CreateSystemWatchFunctions): { watchFile: HostWatchFile; watchDirectory: HostWatchDirectory; } { + const pollingWatches = new Map>(); + const fsWatches = new Map>(); + const fsWatchesRecursive = new Map>(); let dynamicPollingWatchFile: HostWatchFile | undefined; let fixedChunkSizePollingWatchFile: HostWatchFile | undefined; let nonPollingWatchFile: HostWatchFile | undefined; @@ -968,7 +954,7 @@ namespace ts { // Use notifications from FS to watch with falling back to fs.watchFile generateWatchFileOptions(WatchFileKind.UseFsEventsOnParentDirectory, PollingWatchKind.PriorityInterval, options) : // Default to do not use fixed polling interval - { watchFile: defaultWatchFileKind?.() || WatchFileKind.FixedPollingInterval }; + { watchFile: defaultWatchFileKind?.() || WatchFileKind.UseFsEvents }; } } @@ -1073,6 +1059,15 @@ namespace ts { } } + function pollingWatchFile(fileName: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, options: WatchOptions | undefined) { + return createSingleWatcherPerName( + pollingWatches, + useCaseSensitiveFileNames, + fileName, + callback, + cb => pollingWatchFileWorker(fileName, cb, pollingInterval, options), + ); + } function fsWatch( fileOrDirectory: string, entryKind: FileSystemEntryKind, @@ -1080,6 +1075,23 @@ namespace ts { recursive: boolean, fallbackPollingInterval: PollingInterval, fallbackOptions: WatchOptions | undefined + ): FileWatcher { + return createSingleWatcherPerName( + recursive ? fsWatchesRecursive : fsWatches, + useCaseSensitiveFileNames, + fileOrDirectory, + callback, + cb => fsWatchHandlingExistenceOnHost(fileOrDirectory, entryKind, cb, recursive, fallbackPollingInterval, fallbackOptions), + ); + } + + function fsWatchHandlingExistenceOnHost( + fileOrDirectory: string, + entryKind: FileSystemEntryKind, + callback: FsWatchCallback, + recursive: boolean, + fallbackPollingInterval: PollingInterval, + fallbackOptions: WatchOptions | undefined ): FileWatcher { let lastDirectoryPartWithDirectorySeparator: string | undefined; let lastDirectoryPart: string | undefined; @@ -1445,7 +1457,7 @@ namespace ts { const fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin"); const getCurrentDirectory = memoize(() => process.cwd()); const { watchFile, watchDirectory } = createSystemWatchFunctions({ - pollingWatchFile: createSingleFileWatcherPerName(fsWatchFileWorker, useCaseSensitiveFileNames), + pollingWatchFileWorker: fsWatchFileWorker, getModifiedTime, setTimeout, clearTimeout, diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts index 5c7037b7e5c53..54f378d61cc16 100644 --- a/src/compiler/tracing.ts +++ b/src/compiler/tracing.ts @@ -25,7 +25,7 @@ namespace ts { // eslint-disable-line local/one-namespace-per-file // The actual constraint is that JSON.stringify be able to serialize it without throwing. interface Args { [key: string]: string | number | boolean | null | undefined | Args | readonly (string | number | boolean | null | undefined | Args)[]; - }; + } /** Starts tracing for the given project. */ export function startTracing(tracingMode: Mode, traceDir: string, configFilePath?: string) { diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index d64c14b2e0b2c..e453b77a3bff2 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -218,9 +218,9 @@ namespace ts { } function reportNonlocalAugmentation(containingFile: SourceFile, parentSymbol: Symbol, symbol: Symbol) { - const primaryDeclaration = parentSymbol.declarations?.find(d => getSourceFileOfNode(d) === containingFile)!; + const primaryDeclaration = parentSymbol.declarations?.find(d => getSourceFileOfNode(d) === containingFile); const augmentingDeclarations = filter(symbol.declarations, d => getSourceFileOfNode(d) !== containingFile); - if (augmentingDeclarations) { + if (primaryDeclaration && augmentingDeclarations) { for (const augmentations of augmentingDeclarations) { context.addDiagnostic(addRelatedInfo( createDiagnosticForNode(augmentations, Diagnostics.Declaration_augments_declaration_in_another_file_This_cannot_be_serialized), diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 7ae2837097a35..cf9b4fb6717cb 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -2509,9 +2509,10 @@ namespace ts { } function shouldEmitAliasDeclaration(node: Node): boolean { - return compilerOptions.preserveValueImports - ? resolver.isValueAliasDeclaration(node) - : resolver.isReferencedAliasDeclaration(node); + return isInJSFile(node) || + (compilerOptions.preserveValueImports + ? resolver.isValueAliasDeclaration(node) + : resolver.isReferencedAliasDeclaration(node)); } } } diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 2b9d97f324ee2..7c773f5bdc3c5 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -487,7 +487,7 @@ namespace ts { // TODO(rbuckton): Should be a `Set`, but that requires changing the code below that uses `mutateMapSkippingNewValues` const currentProjects = new Map( getBuildOrderFromAnyBuildOrder(buildOrder).map( - resolved => [toResolvedConfigFilePath(state, resolved), true as true]) + resolved => [toResolvedConfigFilePath(state, resolved), true as const]) ); const noopOnDelete = { onDeleteValue: noop }; @@ -1706,10 +1706,7 @@ namespace ts { } } - const seenRefs = buildInfoPath ? new Set() : undefined; const buildInfoCacheEntry = state.buildInfoCache.get(resolvedPath); - seenRefs?.add(resolvedPath); - /** Inputs are up-to-date, just need either timestamp update or bundle prepend manipulation to make it look up-to-date */ let pseudoUpToDate = false; let usesPrepend = false; @@ -1724,7 +1721,7 @@ namespace ts { } // Check if tsbuildinfo path is shared, then we need to rebuild - if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs!, resolvedConfig, resolvedRefPath)) { + if (buildInfoCacheEntry && hasSameBuildInfo(state, buildInfoCacheEntry, resolvedRefPath)) { return { type: UpToDateStatusType.OutOfDateWithUpstream, outOfDateOutputFileName: buildInfoPath!, @@ -1787,22 +1784,9 @@ namespace ts { }; } - function hasSameBuildInfo(state: SolutionBuilderState, buildInfoCacheEntry: BuildInfoCacheEntry, seenRefs: Set, resolvedConfig: ParsedCommandLine, resolvedRefPath: ResolvedConfigFilePath) { - if (seenRefs.has(resolvedRefPath)) return false; - seenRefs.add(resolvedRefPath); + function hasSameBuildInfo(state: SolutionBuilderState, buildInfoCacheEntry: BuildInfoCacheEntry, resolvedRefPath: ResolvedConfigFilePath) { const refBuildInfo = state.buildInfoCache.get(resolvedRefPath)!; - if (refBuildInfo.path === buildInfoCacheEntry.path) return true; - - if (resolvedConfig.projectReferences) { - // Check references - for (const ref of resolvedConfig.projectReferences) { - const resolvedRef = resolveProjectReferencePath(ref); - const resolvedRefPath = toResolvedConfigFilePath(state, resolvedRef); - const resolvedConfig = parseConfigFile(state, resolvedRef, resolvedRefPath)!; - if (hasSameBuildInfo(state, buildInfoCacheEntry, seenRefs, resolvedConfig, resolvedRefPath)) return true; - } - } - return false; + return refBuildInfo.path === buildInfoCacheEntry.path; } function getUpToDateStatus(state: SolutionBuilderState, project: ParsedCommandLine | undefined, resolvedPath: ResolvedConfigFilePath): UpToDateStatus { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f35b62aebf4c1..e36ba1b6f361c 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -936,6 +936,7 @@ namespace ts { | JSDocProtectedTag | JSDocReadonlyTag | JSDocDeprecatedTag + | JSDocOverrideTag ; /* @internal */ @@ -4858,6 +4859,7 @@ namespace ts { /* @internal */ isPropertyAccessible(node: Node, isSuper: boolean, isWrite: boolean, containingType: Type, property: Symbol): boolean; /* @internal */ getTypeOnlyAliasDeclaration(symbol: Symbol): TypeOnlyAliasDeclaration | undefined; /* @internal */ getMemberOverrideModifierStatus(node: ClassLikeDeclaration, member: ClassElement): MemberOverrideStatus; + /* @internal */ isTypeParameterPossiblyReferenced(tp: TypeParameter, node: Node): boolean; } /* @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 31a110c8c3ff5..3ecb70b2b0270 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -563,7 +563,7 @@ namespace ts { interface ScriptTargetFeatures { [key: string]: { [key: string]: string[] | undefined }; - }; + } export function getScriptTargetFeatures(): ScriptTargetFeatures { return { @@ -5625,7 +5625,7 @@ namespace ts { export function isWatchSet(options: CompilerOptions) { // Firefox has Object.prototype.watch - return options.watch && options.hasOwnProperty("watch"); + return options.watch && hasProperty(options, "watch"); } export function closeFileWatcher(watcher: FileWatcher) { diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 6c00d243bca19..fe2f87bf73200 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1126,7 +1126,7 @@ namespace ts { /* @internal */ export function isNodeArray(array: readonly T[]): array is NodeArray { - return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); + return hasProperty(array, "pos") && hasProperty(array, "end"); } // Literals diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 23e9da91c6243..d1851cd02cd08 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -262,7 +262,7 @@ namespace ts { if (file.packageJsonScope) { (result ??= []).push(chainDiagnosticMessages( /*details*/ undefined, - file.packageJsonScope.packageJsonContent.type ? + file.packageJsonScope.contents.packageJsonContent.type ? Diagnostics.File_is_CommonJS_module_because_0_has_field_type_whose_value_is_not_module : Diagnostics.File_is_CommonJS_module_because_0_does_not_have_field_type, toFileName(last(file.packageJsonLocations!), fileNameConvertor) diff --git a/src/executeCommandLine/executeCommandLine.ts b/src/executeCommandLine/executeCommandLine.ts index cb3ba0575a146..5a891ad05c580 100644 --- a/src/executeCommandLine/executeCommandLine.ts +++ b/src/executeCommandLine/executeCommandLine.ts @@ -431,7 +431,7 @@ namespace ts { function getHeader(sys: System, message: string) { const colors = createColors(sys); const header: string[] = []; - const terminalWidth = sys.getWidthOfTerminal?.() ?? 0;; + const terminalWidth = sys.getWidthOfTerminal?.() ?? 0; const tsIconLength = 5; const tsIconFirstLine = colors.blueBackground(padLeft("", tsIconLength)); diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 46d2bc242e772..72ceb827adf95 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -2737,7 +2737,7 @@ namespace FourSlash { const identifier = this.classificationToIdentifier(a.classificationType as number); const text = this.activeFile.content.slice(a.textSpan.start, a.textSpan.start + a.textSpan.length); replacement.push(` c2.semanticToken("${identifier}", "${text}"), `); - }; + } replacement.push(");"); throw new Error("You need to change the source code of fourslash test to use replaceWithSemanticClassifications"); diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 1cee8441fbeb1..596825762c079 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1912,11 +1912,11 @@ namespace FourSlashInterface { }; export interface DiagnosticIgnoredInterpolations { template: string - }; + } export type RenameLocationOptions = FourSlash.Range | { readonly range: FourSlash.Range, readonly prefixText?: string, readonly suffixText?: string }; export interface RenameOptions { readonly findInStrings?: boolean; readonly findInComments?: boolean; readonly providePrefixAndSuffixTextForRename?: boolean; - }; + } } diff --git a/src/harness/harnessIO.ts b/src/harness/harnessIO.ts index 2786498d41e1f..87148c13492a7 100644 --- a/src/harness/harnessIO.ts +++ b/src/harness/harnessIO.ts @@ -335,7 +335,7 @@ namespace Harness { export function setCompilerOptionsFromHarnessSetting(settings: TestCaseParser.CompilerSettings, options: ts.CompilerOptions & HarnessOptions): void { for (const name in settings) { - if (settings.hasOwnProperty(name)) { + if (ts.hasProperty(settings, name)) { const value = settings[name]; if (value === undefined) { throw new Error(`Cannot have undefined value for compiler option '${name}'.`); @@ -1496,7 +1496,7 @@ namespace Harness { export function getConfigNameFromFileName(filename: string): "tsconfig.json" | "jsconfig.json" | undefined { const flc = ts.getBaseFileName(filename).toLowerCase(); - return ts.find(["tsconfig.json" as "tsconfig.json", "jsconfig.json" as "jsconfig.json"], x => x === flc); + return ts.find(["tsconfig.json" as const, "jsconfig.json" as const], x => x === flc); } if (Error) (Error as any).stackTraceLimit = 100; diff --git a/src/harness/harnessUtils.ts b/src/harness/harnessUtils.ts index 97da7e0e3ec99..5ac968035346d 100644 --- a/src/harness/harnessUtils.ts +++ b/src/harness/harnessUtils.ts @@ -314,7 +314,7 @@ namespace Utils { function findChildName(parent: any, child: any) { for (const name in parent) { - if (parent.hasOwnProperty(name) && parent[name] === child) { + if (ts.hasProperty(parent, name) && parent[name] === child) { return name; } } diff --git a/src/harness/vfsUtil.ts b/src/harness/vfsUtil.ts index 63a3d6963d55e..f102bb0ddb63a 100644 --- a/src/harness/vfsUtil.ts +++ b/src/harness/vfsUtil.ts @@ -916,7 +916,6 @@ namespace vfs { if (this._shadowRoot) { this._copyShadowLinks(this._shadowRoot._getRootLinks(), this._lazy.links); } - this._lazy.links = this._lazy.links; } return this._lazy.links; } @@ -1578,7 +1577,7 @@ namespace vfs { const entry = normalizeFileSetEntry(container[name]); const file = dirname ? vpath.combine(dirname, name) : name; // eslint-disable-next-line no-null/no-null - if (entry === null || entry === undefined || entry instanceof Unlink || entry instanceof Rmdir) { + if (entry === null || entry === undefined || entry instanceof Unlink) { text += `//// [${file}] unlink\r\n`; } else if (entry instanceof Rmdir) { diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 80aa7f98eb412..3006a3f1ffdb3 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -283,13 +283,11 @@ interface Array { length: number; [n: number]: T; }` export interface TestFileWatcher { cb: FileWatcherCallback; - fileName: string; pollingInterval: PollingInterval; } export interface TestFsWatcher { cb: FsWatchCallback; - directoryName: string; inode: number | undefined; } @@ -310,7 +308,6 @@ interface Array { length: number; [n: number]: T; }` export enum Tsc_WatchFile { DynamicPolling = "DynamicPriorityPolling", - SingleFileWatcherPerName = "SingleFileWatcherPerName" } export enum Tsc_WatchDirectory { @@ -388,12 +385,7 @@ interface Array { length: number; [n: number]: T; }` // We dont have polling watch file // it is essentially fsWatch but lets get that separate from fsWatch and // into watchedFiles for easier testing - pollingWatchFile: tscWatchFile === Tsc_WatchFile.SingleFileWatcherPerName ? - createSingleFileWatcherPerName( - this.watchFileWorker.bind(this), - this.useCaseSensitiveFileNames - ) : - this.watchFileWorker.bind(this), + pollingWatchFileWorker: this.watchFileWorker.bind(this), getModifiedTime: this.getModifiedTime.bind(this), setTimeout: this.setTimeout.bind(this), clearTimeout: this.clearTimeout.bind(this), @@ -498,7 +490,7 @@ interface Array { length: number; [n: number]: T; }` this.fs.get(getDirectoryPath(currentEntry.path))!.modifiedTime = this.now(); if (options && options.invokeDirectoryWatcherInsteadOfFileChanged) { const directoryFullPath = getDirectoryPath(currentEntry.fullPath); - this.invokeFileWatcher(directoryFullPath, FileWatcherEventKind.Changed, currentEntry.modifiedTime, /*useFileNameInCallback*/ true); + this.invokeFileWatcher(directoryFullPath, FileWatcherEventKind.Changed, currentEntry.modifiedTime); this.invokeFsWatchesCallbacks(directoryFullPath, "rename", currentEntry.modifiedTime, currentEntry.fullPath, options.useTildeAsSuffixInRenameEventFileName); this.invokeRecursiveFsWatches(directoryFullPath, "rename", currentEntry.modifiedTime, currentEntry.fullPath, options.useTildeAsSuffixInRenameEventFileName); } @@ -679,7 +671,7 @@ interface Array { length: number; [n: number]: T; }` return createWatcher( this.watchedFiles, this.toFullPath(fileName), - { fileName, cb, pollingInterval } + { cb, pollingInterval } ); } @@ -696,7 +688,6 @@ interface Array { length: number; [n: number]: T; }` recursive ? this.fsWatchesRecursive : this.fsWatches, path, { - directoryName: fileOrDirectory, cb, inode: this.inodes?.get(path) } @@ -705,8 +696,8 @@ interface Array { length: number; [n: number]: T; }` return result; } - invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind, modifiedTime?: Date, useFileNameInCallback?: boolean) { - invokeWatcherCallbacks(this.watchedFiles.get(this.toPath(fileFullPath)), ({ cb, fileName }) => cb(useFileNameInCallback ? fileName : fileFullPath, eventKind, modifiedTime)); + invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind, modifiedTime: Date | undefined) { + invokeWatcherCallbacks(this.watchedFiles.get(this.toPath(fileFullPath)), ({ cb }) => cb(fileFullPath, eventKind, modifiedTime)); } private fsWatchCallback(map: MultiMap, fullPath: string, eventName: "rename" | "change", modifiedTime: Date | undefined, entryFullPath: string | undefined, useTildeSuffix: boolean | undefined) { @@ -1050,11 +1041,11 @@ interface Array { length: number; [n: number]: T; }` } serializeWatches(baseline: string[] = []) { - serializeMultiMap(baseline, "WatchedFiles", this.watchedFiles, ({ fileName, pollingInterval }) => ({ fileName, pollingInterval })); + serializeMultiMap(baseline, "PolledWatches", this.watchedFiles); baseline.push(""); - serializeMultiMap(baseline, "FsWatches", this.fsWatches, serializeTestFsWatcher); + serializeMultiMap(baseline, "FsWatches", this.fsWatches); baseline.push(""); - serializeMultiMap(baseline, "FsWatchesRecursive", this.fsWatchesRecursive, serializeTestFsWatcher); + serializeMultiMap(baseline, "FsWatchesRecursive", this.fsWatchesRecursive); baseline.push(""); return baseline; } @@ -1158,19 +1149,12 @@ interface Array { length: number; [n: number]: T; }` } } - function serializeTestFsWatcher({ directoryName, inode }: TestFsWatcher) { - return { - directoryName, - inode, - }; - } - - function serializeMultiMap(baseline: string[], caption: string, multiMap: MultiMap, valueMapper: (value: T) => U) { + function serializeMultiMap(baseline: string[], caption: string, multiMap: MultiMap) { baseline.push(`${caption}::`); multiMap.forEach((values, key) => { baseline.push(`${key}:`); for (const value of values) { - baseline.push(` ${JSON.stringify(valueMapper(value))}`); + baseline.push(` ${JSON.stringify(value)}`); } }); } diff --git a/src/lib/es2015.proxy.d.ts b/src/lib/es2015.proxy.d.ts index aa339edaebb77..572870f6a92b1 100644 --- a/src/lib/es2015.proxy.d.ts +++ b/src/lib/es2015.proxy.d.ts @@ -78,7 +78,7 @@ interface ProxyHandler { * @param target The original object which is being proxied. * @param p The name or `Symbol` of the property to set. * @param receiver The object to which the assignment was originally directed. - * @returns `A `Boolean` indicating whether or not the property was set. + * @returns A `Boolean` indicating whether or not the property was set. */ set?(target: T, p: string | symbol, newValue: any, receiver: any): boolean; diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 54ddf71ebbbd4..9433cc2347367 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -943,6 +943,10 @@ interface RegExpExecArray extends Array { * A copy of the search string. */ input: string; + /** + * The first match. This will always be present because `null` will be returned if there are no matches. + */ + 0: string; } interface RegExp { diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index 7dbe596b6d3b4..3935699561fad 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1743,6 +1743,15 @@ + + + + + + + + + @@ -10320,6 +10329,15 @@ + + + + + + + + + @@ -13599,6 +13617,15 @@ + + + + + + + + + @@ -15948,6 +15975,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16269,6 +16332,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index df6558f81e693..3ff52ce72a8fd 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1743,6 +1743,15 @@ + + + + + + + + + @@ -10320,6 +10329,15 @@ + + + + + + + + + @@ -13599,6 +13617,15 @@ + + + + + + + + + @@ -15948,6 +15975,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16269,6 +16332,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index 02f5e6f832a35..a720655caea5e 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1752,6 +1752,15 @@ + + + + + + + + + @@ -10329,6 +10338,15 @@ + + + + + + + + + @@ -13608,6 +13626,15 @@ + + + + + + + + + @@ -15957,6 +15984,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16278,6 +16341,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl index 8e868e73fe0ff..e91e478429e57 100644 --- a/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/deu/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1740,6 +1740,15 @@ + + + + + + + + + @@ -10314,6 +10323,15 @@ + + + + + + + + + @@ -13593,6 +13611,15 @@ + + + + + + + + + @@ -15942,6 +15969,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16263,6 +16326,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 71e68a1a3dd41..353db73633fb3 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1755,6 +1755,15 @@ + + + + + + + + + @@ -10332,6 +10341,15 @@ + + + + + + + + + @@ -13611,6 +13629,15 @@ + + + + + + + + + @@ -15960,6 +15987,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16281,6 +16344,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index 9e246ddca4569..d1e21b6763be2 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1755,6 +1755,15 @@ + + + + + + + + + @@ -10332,6 +10341,15 @@ + + + + + + + + + @@ -13611,6 +13629,15 @@ + + + + + + + + + @@ -15960,6 +15987,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16281,6 +16344,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index 5ce5e68b6a0cf..f6cb8d7d6df8d 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1743,6 +1743,15 @@ + + + + + + + + + @@ -10320,6 +10329,15 @@ + + + + + + + + + @@ -13599,6 +13617,15 @@ + + + + + + + + + @@ -15948,6 +15975,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16269,6 +16332,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 25a386cee0d1d..428d2f0a87145 100644 --- a/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/jpn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1743,6 +1743,15 @@ + + + + + + + + + @@ -10320,6 +10329,15 @@ + + + + + + + + + @@ -13599,6 +13617,15 @@ + + + + + + + + + @@ -15948,6 +15975,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16269,6 +16332,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index 969a44bfcd5f4..5e3749068f0dd 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1743,6 +1743,15 @@ + + + + + + + + + @@ -10320,6 +10329,15 @@ + + + + + + + + + @@ -13599,6 +13617,15 @@ + + + + + + + + + @@ -15948,6 +15975,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16269,6 +16332,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 89b0b89421f4f..147a468e272ea 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1733,6 +1733,15 @@ + + + + + + + + + @@ -10307,6 +10316,15 @@ + + + + + + + + + @@ -13586,6 +13604,15 @@ + + + + + + + + + @@ -15935,6 +15962,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16256,6 +16319,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index 5130242fdd5c8..9a538189334e2 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1736,6 +1736,15 @@ + + + + + + + + + @@ -10310,6 +10319,15 @@ + + + + + + + + + @@ -13589,6 +13607,15 @@ + + + + + + + + + @@ -15938,6 +15965,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16259,6 +16322,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3fbfc6779d7b9..aa66b8a06b949 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1742,6 +1742,15 @@ + + + + + + + + + @@ -10319,6 +10328,15 @@ + + + + + + + + + @@ -13598,6 +13616,15 @@ + + + + + + + + + @@ -15947,6 +15974,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16268,6 +16331,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 62b201af65357..7c46435575483 100644 --- a/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/trk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -1736,6 +1736,15 @@ + + + + + + + + + @@ -10313,6 +10322,15 @@ + + + + + + + + + @@ -13592,6 +13610,15 @@ + + + + + + + + + @@ -15941,6 +15968,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -16262,6 +16325,15 @@ + + + + + + + + + diff --git a/src/loggedIO/loggedIO.ts b/src/loggedIO/loggedIO.ts index 24b3f815f605e..6018ee1026e3d 100644 --- a/src/loggedIO/loggedIO.ts +++ b/src/loggedIO/loggedIO.ts @@ -94,7 +94,7 @@ namespace Playback { // eslint-disable-line local/one-namespace-per-file function memoize(func: (s: string) => T): Memoized { let lookup: { [s: string]: T } = {}; const run: Memoized = ((s: string) => { - if (lookup.hasOwnProperty(s)) return lookup[s]; + if (ts.hasProperty(lookup, s)) return lookup[s]; return lookup[s] = func(s); }) as Memoized; run.reset = () => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 3ab9f02741cc1..7b8e091a96205 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -940,7 +940,7 @@ namespace ts.server { // raw is now fixed and ready this.safelist = raw.typesMap; for (const key in raw.simpleMap) { - if (raw.simpleMap.hasOwnProperty(key)) { + if (hasProperty(raw.simpleMap, key)) { this.legacySafelist.set(key, raw.simpleMap[key].toLowerCase()); } } diff --git a/src/server/session.ts b/src/server/session.ts index 5eff52c6ad8e0..f0d26443dd522 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -297,7 +297,7 @@ namespace ts.server { interface ProjectNavigateToItems { project: Project; navigateToItems: readonly NavigateToItem[]; - }; + } function createDocumentSpanSet(): Set { return createSet(({textSpan}) => textSpan.start + 100003 * textSpan.length, documentSpansEqual); @@ -1378,7 +1378,7 @@ namespace ts.server { const packageDirectory = fileName.substring(0, nodeModulesPathParts.packageRootIndex); const packageJsonCache = project.getModuleResolutionCache()?.getPackageJsonInfoCache(); const compilerOptions = project.getCompilationSettings(); - const packageJson = getPackageScopeForPath(project.toPath(packageDirectory + "/package.json"), getTemporaryModuleResolutionState(packageJsonCache, project, compilerOptions)); + const packageJson = getPackageScopeForPath(getNormalizedAbsolutePath(packageDirectory + "/package.json", project.getCurrentDirectory()), getTemporaryModuleResolutionState(packageJsonCache, project, compilerOptions)); if (!packageJson) return undefined; // Use fake options instead of actual compiler options to avoid following export map if the project uses node16 or nodenext - // Mapping from an export map entry across packages is out of scope for now. Returned entrypoints will only be what can be diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 5e26fbb38ab63..6353834280970 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -70,11 +70,11 @@ namespace ts.codefix { * `MappedIndirect.ax` and `MappedIndirect.ay` have no declaration node attached (due to their mapped-type * parent): * - * >>> ```ts - * >>> type Base = { ax: number; ay: string }; - * >>> type BaseKeys = keyof Base; - * >>> type MappedIndirect = { [K in BaseKeys]: boolean }; - * >>> ``` + * ```ts + * type Base = { ax: number; ay: string }; + * type BaseKeys = keyof Base; + * type MappedIndirect = { [K in BaseKeys]: boolean }; + * ``` * * In such cases, we assume the declaration to be a `PropertySignature`. */ diff --git a/src/services/completions.ts b/src/services/completions.ts index 48e1c28bf01de..afea634c32b2c 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1107,7 +1107,7 @@ namespace ts.Completions { return { isSnippet, insertText, labelDetails }; - }; + } function createObjectLiteralMethod( symbol: Symbol, @@ -1171,7 +1171,7 @@ namespace ts.Completions { /*modifiers*/ undefined, typedParam.dotDotDotToken, typedParam.name, - typedParam.questionToken, + /*questionToken*/ undefined, /*type*/ undefined, typedParam.initializer, )); @@ -4335,7 +4335,7 @@ namespace ts.Completions { function isArrowFunctionBody(node: Node) { return node.parent && isArrowFunction(node.parent) && node.parent.body === node; - }; + } /** True if symbol is a type or a module containing at least one type. */ function symbolCanBeReferencedAtTypeLocation(symbol: Symbol, checker: TypeChecker, seenModules = new Map()): boolean { diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 9ed9c159cc7ca..85e67eb8cbb59 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -59,7 +59,7 @@ namespace ts.formatting { // in other cases there should be no space between '?' and next token rule("NoSpaceAfterQuestionMark", SyntaxKind.QuestionToken, anyToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), - rule("NoSpaceBeforeDot", anyToken, [SyntaxKind.DotToken, SyntaxKind.QuestionDotToken], [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), + rule("NoSpaceBeforeDot", anyToken, [SyntaxKind.DotToken, SyntaxKind.QuestionDotToken], [isNonJsxSameLineTokenContext, isNotPropertyAccessOnIntegerLiteral], RuleAction.DeleteSpace), rule("NoSpaceAfterDot", [SyntaxKind.DotToken, SyntaxKind.QuestionDotToken], anyToken, [isNonJsxSameLineTokenContext], RuleAction.DeleteSpace), rule("NoSpaceBetweenImportParenInImportType", SyntaxKind.ImportKeyword, SyntaxKind.OpenParenToken, [isNonJsxSameLineTokenContext, isImportTypeContext], RuleAction.DeleteSpace), @@ -411,23 +411,23 @@ namespace ts.formatting { } function isOptionEnabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { - return (context) => context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName]; + return (context) => context.options && hasProperty(context.options, optionName) && !!context.options[optionName]; } function isOptionDisabled(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { - return (context) => context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName]; + return (context) => context.options && hasProperty(context.options, optionName) && !context.options[optionName]; } function isOptionDisabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { - return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName]; + return (context) => !context.options || !hasProperty(context.options, optionName) || !context.options[optionName]; } function isOptionDisabledOrUndefinedOrTokensOnSameLine(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { - return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine(); + return (context) => !context.options || !hasProperty(context.options, optionName) || !context.options[optionName] || context.TokensAreOnSameLine(); } function isOptionEnabledOrUndefined(optionName: keyof FormatCodeSettings): (context: FormattingContext) => boolean { - return (context) => !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName]; + return (context) => !context.options || !hasProperty(context.options, optionName) || !!context.options[optionName]; } function isForContext(context: FormattingContext): boolean { @@ -894,4 +894,10 @@ namespace ts.formatting { function isSemicolonInsertionContext(context: FormattingContext): boolean { return positionIsASICandidate(context.currentTokenSpan.end, context.currentTokenParent, context.sourceFile); } + + function isNotPropertyAccessOnIntegerLiteral(context: FormattingContext): boolean { + return !isPropertyAccessExpression(context.contextNode) + || !isNumericLiteral(context.contextNode.expression) + || context.contextNode.expression.getText().indexOf(".") !== -1; + } } diff --git a/src/services/goToDefinition.ts b/src/services/goToDefinition.ts index 15ecb41bb4357..40cac0a916d41 100644 --- a/src/services/goToDefinition.ts +++ b/src/services/goToDefinition.ts @@ -16,7 +16,7 @@ namespace ts.GoToDefinition { const { parent } = node; const typeChecker = program.getTypeChecker(); - if (node.kind === SyntaxKind.OverrideKeyword || (isJSDocOverrideTag(node) && rangeContainsPosition(node.tagName, position))) { + if (node.kind === SyntaxKind.OverrideKeyword || (isIdentifier(node) && isJSDocOverrideTag(parent) && parent.tagName === node)) { return getDefinitionFromOverriddenMember(typeChecker, node) || emptyArray; } diff --git a/src/services/refactors/convertExport.ts b/src/services/refactors/convertExport.ts index cb79dd2672fa4..ffde52b9571ab 100644 --- a/src/services/refactors/convertExport.ts +++ b/src/services/refactors/convertExport.ts @@ -54,7 +54,7 @@ namespace ts.refactor { readonly exportName: Identifier; // This is exportNode.name except for VariableStatement_s. readonly wasDefault: boolean; readonly exportingModuleSymbol: Symbol; - }; + } function getInfo(context: RefactorContext, considerPartialSpans = true): ExportInfo | RefactorErrorInfo | undefined { const { file, program } = context; diff --git a/src/services/refactors/convertToOptionalChainExpression.ts b/src/services/refactors/convertToOptionalChainExpression.ts index ba40ec6a5e553..a8c13e42f94fc 100644 --- a/src/services/refactors/convertToOptionalChainExpression.ts +++ b/src/services/refactors/convertToOptionalChainExpression.ts @@ -51,7 +51,7 @@ namespace ts.refactor.convertToOptionalChainExpression { finalExpression: PropertyAccessExpression | ElementAccessExpression | CallExpression, occurrences: Occurrence[], expression: ValidExpression, - }; + } type ValidExpressionOrStatement = ValidExpression | ValidStatement; @@ -119,7 +119,7 @@ namespace ts.refactor.convertToOptionalChainExpression { function getBinaryInfo(expression: BinaryExpression): OptionalChainInfo | RefactorErrorInfo | undefined { if (expression.operatorToken.kind !== SyntaxKind.AmpersandAmpersandToken) { return { error: getLocaleSpecificMessage(Diagnostics.Can_only_convert_logical_AND_access_chains) }; - }; + } const finalExpression = getFinalExpressionInChain(expression.right); if (!finalExpression) return { error: getLocaleSpecificMessage(Diagnostics.Could_not_find_convertible_access_expression) }; diff --git a/src/services/refactors/helpers.ts b/src/services/refactors/helpers.ts index e86229af915d1..25fcc1a3f5bc1 100644 --- a/src/services/refactors/helpers.ts +++ b/src/services/refactors/helpers.ts @@ -5,7 +5,7 @@ namespace ts.refactor { */ export interface RefactorErrorInfo { error: string; - }; + } /** * Checks if some refactor info has refactor error info. diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 287178169e6c1..b01218a95ba5a 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -97,7 +97,7 @@ namespace ts.refactor { // Filters imports and prologue directives out of the range of statements to move. // Imports will be copied to the new file anyway, and may still be needed in the old file. // Prologue directives will be copied to the new file and should be left in the old file. - return !isPureImport(statement) && !isPrologueDirective(statement);; + return !isPureImport(statement) && !isPrologueDirective(statement); } function isPureImport(node: Node): boolean { diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 922e50654bbe1..33b508017683a 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -935,7 +935,7 @@ namespace ts.Completions.StringCompletions { const dependencies: object | undefined = (contents as any)[key]; if (!dependencies) continue; for (const dep in dependencies) { - if (dependencies.hasOwnProperty(dep) && !startsWith(dep, "@types/")) { + if (hasProperty(dependencies, dep) && !startsWith(dep, "@types/")) { result.push(dep); } } diff --git a/src/services/types.ts b/src/services/types.ts index 98de7db46fe90..d22416abb0b50 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1214,7 +1214,7 @@ namespace ts { isGlobalCompletion: boolean; isMemberCompletion: boolean; /** - * In the absence of `CompletionEntry["replacementSpan"], the editor may choose whether to use + * In the absence of `CompletionEntry["replacementSpan"]`, the editor may choose whether to use * this span or its default one. If `CompletionEntry["replacementSpan"]` is defined, that span * must be used to commit that completion entry. */ diff --git a/src/services/utilities.ts b/src/services/utilities.ts index cdb351bd454ef..85668e9483ec1 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1659,7 +1659,7 @@ namespace ts { /** * Returns true if the cursor at position in sourceFile is within a comment. * - * @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position) + * @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position)` * @param predicate Additional predicate to test on the comment range. */ export function isInComment(sourceFile: SourceFile, position: number, tokenAtPosition?: Node): CommentRange | undefined { diff --git a/src/testRunner/tsconfig.json b/src/testRunner/tsconfig.json index 9dd2a5859fb94..f69059c812bbb 100644 --- a/src/testRunner/tsconfig.json +++ b/src/testRunner/tsconfig.json @@ -76,6 +76,7 @@ "unittests/reuseProgramStructure.ts", "unittests/semver.ts", "unittests/transform.ts", + "unittests/typeParameterIsPossiblyReferenced.ts", "unittests/config/commandLineParsing.ts", "unittests/config/configurationExtension.ts", "unittests/config/convertCompilerOptionsFromJson.ts", diff --git a/src/testRunner/unittests/config/initializeTSConfig.ts b/src/testRunner/unittests/config/initializeTSConfig.ts index f7fb7d2a4398b..68c56ac4e179f 100644 --- a/src/testRunner/unittests/config/initializeTSConfig.ts +++ b/src/testRunner/unittests/config/initializeTSConfig.ts @@ -7,7 +7,7 @@ namespace ts { const outputFileName = `tsConfig/${name.replace(/[^a-z0-9\-. ]/ig, "")}/tsconfig.json`; it(`Correct output for ${outputFileName}`, () => { - Harness.Baseline.runBaseline(outputFileName, initResult); + Harness.Baseline.runBaseline(outputFileName, initResult, { PrintDiff: true }); }); }); } @@ -29,5 +29,9 @@ namespace ts { initTSConfigCorrectly("Initialized TSConfig with incorrect compiler option value", ["--init", "--lib", "nonExistLib,es5,es2015.promise"]); initTSConfigCorrectly("Initialized TSConfig with advanced options", ["--init", "--declaration", "--declarationDir", "lib", "--skipLibCheck", "--noErrorTruncation"]); + + initTSConfigCorrectly("Initialized TSConfig with --help", ["--init", "--help"]); + + initTSConfigCorrectly("Initialized TSConfig with --watch", ["--init", "--watch"]); }); } diff --git a/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts b/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts index e9eacf1fa657c..595bc509744d5 100644 --- a/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts +++ b/src/testRunner/unittests/tsbuild/containerOnlyReferenced.ts @@ -7,5 +7,36 @@ namespace ts { commandLineArgs: ["--b", "/src", "--verbose"], edits: noChangeOnlyRuns }); + + verifyTscWithEdits({ + scenario: "containerOnlyReferenced", + subScenario: "when solution is referenced indirectly", + fs: () => loadProjectFromFiles({ + "/src/project1/tsconfig.json": JSON.stringify({ + compilerOptions: { composite: true }, + references: [], + }), + "/src/project2/tsconfig.json": JSON.stringify({ + compilerOptions: { composite: true }, + references: [], + }), + "/src/project2/src/b.ts": "export const b = 10;", + "/src/project3/tsconfig.json": JSON.stringify({ + compilerOptions: { composite: true }, + references: [{ path: "../project1", }, { path: "../project2" }], + }), + "/src/project3/src/c.ts": "export const c = 10;", + "/src/project4/tsconfig.json": JSON.stringify({ + compilerOptions: { composite: true }, + references: [{ path: "../project3" }] + }), + "/src/project4/src/d.ts": "export const d = 10;", + }), + commandLineArgs: ["--b", "/src/project4", "--verbose", "--explainFiles"], + edits: [{ + subScenario: "modify project3 file", + modifyFs: fs => replaceText(fs, "/src/project3/src/c.ts", "c = ", "cc = "), + }], + }); }); } diff --git a/src/testRunner/unittests/tsbuild/outputPaths.ts b/src/testRunner/unittests/tsbuild/outputPaths.ts index 72374f846115f..3bcad56dd68ab 100644 --- a/src/testRunner/unittests/tsbuild/outputPaths.ts +++ b/src/testRunner/unittests/tsbuild/outputPaths.ts @@ -19,7 +19,7 @@ namespace ts { it("verify getOutputFileNames", () => { const sys = new fakes.System(input.fs().makeReadonly(), { executingFilePath: "/lib/tsc" }) as TscCompileSystem; - ; + assert.deepEqual( getOutputFileNames( parseConfigFileWithSystem("/src/tsconfig.json", {}, /*extendedConfigCache*/ undefined, {}, sys, noop)!, diff --git a/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts b/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts index 24902756eefe2..053719a368094 100644 --- a/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts +++ b/src/testRunner/unittests/tsbuildWatch/watchEnvironment.ts @@ -1,124 +1,111 @@ namespace ts.tscWatch { describe("unittests:: tsbuildWatch:: watchEnvironment:: tsbuild:: watchMode:: with different watch environments", () => { - describe("when watchFile can create multiple watchers per file", () => { - verifyWatchFileOnMultipleProjects(/*singleWatchPerFile*/ false); - }); - - describe("when watchFile is single watcher per file", () => { - verifyWatchFileOnMultipleProjects( - /*singleWatchPerFile*/ true, - arrayToMap(["TSC_WATCHFILE"], identity, () => TestFSWithWatch.Tsc_WatchFile.SingleFileWatcherPerName) - ); - }); + it("watchFile on same file multiple times because file is part of multiple projects", () => { + const project = `${TestFSWithWatch.tsbuildProjectsLocation}/myproject`; + let maxPkgs = 4; + const configPath = `${project}/tsconfig.json`; + const typing: File = { + path: `${project}/typings/xterm.d.ts`, + content: "export const typing = 10;" + }; - function verifyWatchFileOnMultipleProjects(singleWatchPerFile: boolean, environmentVariables?: ESMap) { - it("watchFile on same file multiple times because file is part of multiple projects", () => { - const project = `${TestFSWithWatch.tsbuildProjectsLocation}/myproject`; - let maxPkgs = 4; - const configPath = `${project}/tsconfig.json`; - const typing: File = { - path: `${project}/typings/xterm.d.ts`, - content: "export const typing = 10;" - }; - - const allPkgFiles = pkgs(pkgFiles); - const system = createWatchedSystem([libFile, typing, ...flatArray(allPkgFiles)], { currentDirectory: project, environmentVariables }); - writePkgReferences(system); - const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(system); - const host = createSolutionBuilderWithWatchHostForBaseline(sys, cb); - const solutionBuilder = createSolutionBuilderWithWatch(host, ["tsconfig.json"], { watch: true, verbose: true }); - solutionBuilder.build(); - runWatchBaseline({ - scenario: "watchEnvironment", - subScenario: `same file in multiple projects${singleWatchPerFile ? " with single watcher per file" : ""}`, - commandLineArgs: ["--b", "--w"], - sys, - baseline, - oldSnap, - getPrograms, - changes: [ - { - caption: "modify typing file", - change: sys => sys.writeFile(typing.path, `${typing.content}export const typing1 = 10;`), - timeouts: sys => { - sys.checkTimeoutQueueLengthAndRun(1); - checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout(sys); - } - }, - { - // Make change - caption: "change pkg references", - change: sys => { - maxPkgs--; - writePkgReferences(sys); - }, - timeouts: checkSingleTimeoutQueueLengthAndRun, - }, - { - caption: "modify typing file", - change: sys => sys.writeFile(typing.path, typing.content), - timeouts: sys => { - sys.checkTimeoutQueueLengthAndRun(1); - checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout(sys); - } - }, - { - // Make change to remove all watches - caption: "change pkg references to remove all watches", - change: sys => { - maxPkgs = 0; - writePkgReferences(sys); - }, - timeouts: checkSingleTimeoutQueueLengthAndRun, + const allPkgFiles = pkgs(pkgFiles); + const system = createWatchedSystem([libFile, typing, ...flatArray(allPkgFiles)], { currentDirectory: project }); + writePkgReferences(system); + const { sys, baseline, oldSnap, cb, getPrograms } = createBaseline(system); + const host = createSolutionBuilderWithWatchHostForBaseline(sys, cb); + const solutionBuilder = createSolutionBuilderWithWatch(host, ["tsconfig.json"], { watch: true, verbose: true }); + solutionBuilder.build(); + runWatchBaseline({ + scenario: "watchEnvironment", + subScenario: `same file in multiple projects with single watcher per file`, + commandLineArgs: ["--b", "--w"], + sys, + baseline, + oldSnap, + getPrograms, + changes: [ + { + caption: "modify typing file", + change: sys => sys.writeFile(typing.path, `${typing.content}export const typing1 = 10;`), + timeouts: sys => { + sys.checkTimeoutQueueLengthAndRun(1); + checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout(sys); + } + }, + { + // Make change + caption: "change pkg references", + change: sys => { + maxPkgs--; + writePkgReferences(sys); }, - { - caption: "modify typing file", - change: sys => sys.writeFile(typing.path, `${typing.content}export const typing1 = 10;`), - timeouts: sys => sys.checkTimeoutQueueLength(0), + timeouts: checkSingleTimeoutQueueLengthAndRun, + }, + { + caption: "modify typing file", + change: sys => sys.writeFile(typing.path, typing.content), + timeouts: sys => { + sys.checkTimeoutQueueLengthAndRun(1); + checkSingleTimeoutQueueLengthAndRunAndVerifyNoTimeout(sys); + } + }, + { + // Make change to remove all watches + caption: "change pkg references to remove all watches", + change: sys => { + maxPkgs = 0; + writePkgReferences(sys); }, - ], - watchOrSolution: solutionBuilder - }); + timeouts: checkSingleTimeoutQueueLengthAndRun, + }, + { + caption: "modify typing file", + change: sys => sys.writeFile(typing.path, `${typing.content}export const typing1 = 10;`), + timeouts: sys => sys.checkTimeoutQueueLength(0), + }, + ], + watchOrSolution: solutionBuilder + }); - function flatArray(arr: T[][]): readonly T[] { - return flatMap(arr, identity); + function flatArray(arr: T[][]): readonly T[] { + return flatMap(arr, identity); + } + function pkgs(cb: (index: number) => T): T[] { + const result: T[] = []; + for (let index = 0; index < maxPkgs; index++) { + result.push(cb(index)); } - function pkgs(cb: (index: number) => T): T[] { - const result: T[] = []; - for (let index = 0; index < maxPkgs; index++) { - result.push(cb(index)); + return result; + } + function createPkgReference(index: number) { + return { path: `./pkg${index}` }; + } + function pkgFiles(index: number): File[] { + return [ + { + path: `${project}/pkg${index}/index.ts`, + content: `export const pkg${index} = ${index};` + }, + { + path: `${project}/pkg${index}/tsconfig.json`, + content: JSON.stringify({ + complerOptions: { composite: true }, + include: [ + "**/*.ts", + "../typings/xterm.d.ts" + ] + }) } - return result; - } - function createPkgReference(index: number) { - return { path: `./pkg${index}` }; - } - function pkgFiles(index: number): File[] { - return [ - { - path: `${project}/pkg${index}/index.ts`, - content: `export const pkg${index} = ${index};` - }, - { - path: `${project}/pkg${index}/tsconfig.json`, - content: JSON.stringify({ - complerOptions: { composite: true }, - include: [ - "**/*.ts", - "../typings/xterm.d.ts" - ] - }) - } - ]; - } - function writePkgReferences(system: TestFSWithWatch.TestServerHost) { - system.writeFile(configPath, JSON.stringify({ - files: [], - include: [], - references: pkgs(createPkgReference) - })); - } - }); - } + ]; + } + function writePkgReferences(system: TestFSWithWatch.TestServerHost) { + system.writeFile(configPath, JSON.stringify({ + files: [], + include: [], + references: pkgs(createPkgReference) + })); + } + }); }); } diff --git a/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts b/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts index 584b32c33535c..d00ea144ea9d4 100644 --- a/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts +++ b/src/testRunner/unittests/tscWatch/forceConsistentCasingInFileNames.ts @@ -326,5 +326,36 @@ a;b; }, { currentDirectory: "/Users/name/projects/web" }), changes: emptyArray, }); + + + verifyTscWatch({ + scenario: "forceConsistentCasingInFileNames", + subScenario: "package json is looked up for file", + commandLineArgs: ["-w", "--explainFiles"], + sys: () => createWatchedSystem({ + "/Users/name/projects/lib-boilerplate/package.json": JSON.stringify({ + name: "lib-boilerplate", + version: "0.0.2", + type: "module", + exports: "./src/index.ts", + }), + "/Users/name/projects/lib-boilerplate/src/index.ts": Utils.dedent` + export function thing(): void {} + `, + "/Users/name/projects/lib-boilerplate/test/basic.spec.ts": Utils.dedent` + import { thing } from 'lib-boilerplate' + `, + "/Users/name/projects/lib-boilerplate/tsconfig.json": JSON.stringify({ + compilerOptions: { + module: "node16", + target: "es2021", + forceConsistentCasingInFileNames: true, + traceResolution: true, + } + }), + "/a/lib/lib.es2021.full.d.ts": libFile.content, + }, { currentDirectory: "/Users/name/projects/lib-boilerplate" }), + changes: emptyArray, + }); }); } diff --git a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts index e6048f6c7a6c6..0f042ba32abee 100644 --- a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts +++ b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts @@ -76,7 +76,7 @@ namespace ts.projectSystem { }; const host = createServerHost([root, imported]); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.setCompilerOptionsForInferredProjects({ module: ModuleKind.AMD, noLib: true }); projectService.openClientFile(root.path); const project = projectService.inferredProjects[0]; @@ -134,7 +134,7 @@ namespace ts.projectSystem { }; const host = createServerHost([root]); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.setCompilerOptionsForInferredProjects({ module: ModuleKind.AMD, noLib: true }); const logCacheAndClear = createLoggerTrackingHostCalls(host); projectService.openClientFile(root.path); @@ -195,7 +195,7 @@ namespace ts.projectSystem { }; const projectFiles = [clientFile, anotherModuleFile, moduleFile, tsconfigFile]; const host = createServerHost(projectFiles); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([clientFile], session); const logCacheAndClear = createLoggerTrackingHostCalls(host); @@ -273,7 +273,7 @@ namespace ts.projectSystem { }; const projectFiles = [file1, file2, es2016LibFile, tsconfigFile]; const host = createServerHost(projectFiles, { useCaseSensitiveFileNames }); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.openClientFile(file1.path); const logCacheAndClear = createLoggerTrackingHostCalls(host); @@ -383,7 +383,7 @@ namespace ts.projectSystem { ` }); const host = createServerHost([app, libFile, tsconfigJson, packageJson]); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.setHostConfiguration({ preferences: { includePackageJsonAutoImports: "off" } }); projectService.openClientFile(app.path); diff --git a/src/testRunner/unittests/tsserver/configFileSearch.ts b/src/testRunner/unittests/tsserver/configFileSearch.ts index 39ba56ced2127..a81bedb6431e0 100644 --- a/src/testRunner/unittests/tsserver/configFileSearch.ts +++ b/src/testRunner/unittests/tsserver/configFileSearch.ts @@ -38,7 +38,7 @@ namespace ts.projectSystem { content: "{}" }; const host = createServerHost([f1, libFile, configFile, configFile2]); - const service = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const service = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); service.openClientFile(f1.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectDir); // Delete config file - should create inferred project and not configured project @@ -67,7 +67,7 @@ namespace ts.projectSystem { const service = createProjectService(host, { useSingleInferredProject: true, useInferredProjectPerProjectRoot: true, - logger: createLoggerWithInMemoryLogs(), + logger: createLoggerWithInMemoryLogs(host), }); service.openClientFile(f1.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectDir); @@ -89,7 +89,7 @@ namespace ts.projectSystem { }; function openClientFile(files: File[]) { const host = createServerHost(files); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.openClientFile(file.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, "/a/b/projects/proj"); return { host, projectService }; } @@ -124,7 +124,7 @@ namespace ts.projectSystem { it(scenario, () => { const path = `/root/teams/VSCode68/Shared Documents/General/jt-ts-test-workspace/x.js`; const host = createServerHost([libFile, { path, content: "const x = 10" }], { useCaseSensitiveFileNames: true }); - const service = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const service = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); service.openClientFile(path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectRootPath); baselineTsserverLogs("configFileSearch", scenario, service); }); diff --git a/src/testRunner/unittests/tsserver/configuredProjects.ts b/src/testRunner/unittests/tsserver/configuredProjects.ts index d8246838c0756..3524e69206dfc 100644 --- a/src/testRunner/unittests/tsserver/configuredProjects.ts +++ b/src/testRunner/unittests/tsserver/configuredProjects.ts @@ -25,7 +25,7 @@ namespace ts.projectSystem { }; const host = createServerHost([configFile, libFile, file1, file2, file3]); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); const { configFileName, configFileErrors } = projectService.openClientFile(file1.path); assert(configFileName, "should find config file"); @@ -57,7 +57,7 @@ namespace ts.projectSystem { }; const host = createServerHost([configFile, libFile, file1, file2, file3]); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); const { configFileName, configFileErrors } = projectService.openClientFile(file1.path); assert(configFileName, "should find config file"); @@ -84,7 +84,7 @@ namespace ts.projectSystem { const host = createServerHost([libFile, commonFile1, commonFile2]); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.openClientFile(commonFile1.path); projectService.openClientFile(commonFile2.path); @@ -105,7 +105,7 @@ namespace ts.projectSystem { content: `{}` }; const host = createServerHost([commonFile1, libFile, configFile]); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.openClientFile(commonFile1.path); // add a new ts file @@ -537,7 +537,7 @@ namespace ts.projectSystem { const files = [file1, file2, file3, file4]; const host = createServerHost(files.concat(configFile)); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.openClientFile(file1.path); projectService.openClientFile(file2.path); @@ -577,6 +577,7 @@ namespace ts.projectSystem { content: "let zz = 1;" }; host.writeFile(file5.path, file5.content); + projectService.baselineHost("File5 written"); projectService.openClientFile(file5.path); baselineTsserverLogs("configuredProjects", "Open ref of configured project when open file gets added to the project as part of configured file update", projectService); @@ -793,7 +794,7 @@ declare var console: { };` }; const host = createServerHost([barConfig, barIndex, fooConfig, fooIndex, barSymLink, lib2017, libDom]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([fooIndex, barIndex], session); verifyGetErrRequest({ session, host, files: [barIndex, fooIndex] }); baselineTsserverLogs("configuredProjects", "when multiple projects are open detects correct default project", session); @@ -851,7 +852,7 @@ declare var console: { ]); const session = createSession(host, { canUseEvents: true, - logger: createLoggerWithInMemoryLogs(), + logger: createLoggerWithInMemoryLogs(host), }); session.executeCommandSeq({ command: protocol.CommandTypes.Open, @@ -1017,7 +1018,7 @@ foo();` }; const host = createServerHost([alphaExtendedConfig, aConfig, aFile, bravoExtendedConfig, bConfig, bFile, ...(additionalFiles || emptyArray)]); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); return { host, projectService, aFile, bFile, aConfig, bConfig, alphaExtendedConfig, bravoExtendedConfig }; } @@ -1178,7 +1179,7 @@ foo();` }; const files = [file1, file2a, configFile, libFile]; const host = createServerHost(files); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.openClientFile(file1.path); host.writeFile(file2.path, file2.content); @@ -1217,7 +1218,7 @@ foo();` nonLibFiles.forEach(f => f.path = root + f.path); const files = nonLibFiles.concat(libFile); const host = createServerHost(files); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.openClientFile(file1.path); baselineTsserverLogs("configuredProjects", "failed lookup locations uses parent most node_modules directory", projectService); }); diff --git a/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts b/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts index 08d66db76a16c..ab54f63075221 100644 --- a/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts +++ b/src/testRunner/unittests/tsserver/events/projectLanguageServiceState.ts @@ -68,11 +68,11 @@ namespace ts.projectSystem { content: "{}" }; const host = createServerHost([f1, f2, f3, libFile, config]); - const service = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const service = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); service.openClientFile(f1.path); const project = service.configuredProjects.get(config.path)!; - service.logger.logs.push(`languageServiceEnabled: ${project.languageServiceEnabled}`); - service.logger.logs.push(`lastFileExceededProgramSize: ${project.lastFileExceededProgramSize}`); + service.logger.info(`languageServiceEnabled: ${project.languageServiceEnabled}`); + service.logger.info(`lastFileExceededProgramSize: ${project.lastFileExceededProgramSize}`); baselineTsserverLogs("projectLanguageServiceStateEvent", "large file size is determined correctly", service); }); }); diff --git a/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts b/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts index 248fd25e95ca3..951c7215872d2 100644 --- a/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts +++ b/src/testRunner/unittests/tsserver/events/projectUpdatedInBackground.ts @@ -437,7 +437,7 @@ namespace ts.projectSystem { const openFiles = [file1.path]; const host = createServerHost([file1, file3, libFile, configFile]); - const { session, verifyInitialOpen, verifyProjectsUpdatedInBackgroundEventHandler } = createSession(host, createLoggerWithInMemoryLogs()); + const { session, verifyInitialOpen, verifyProjectsUpdatedInBackgroundEventHandler } = createSession(host, createLoggerWithInMemoryLogs(host)); verifyInitialOpen(file1); file3.content += "export class d {}"; diff --git a/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts b/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts index 674556e8cf135..2e834a43ad402 100644 --- a/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts +++ b/src/testRunner/unittests/tsserver/forceConsistentCasingInFileNames.ts @@ -59,7 +59,7 @@ namespace ts.projectSystem { }; const host = createServerHost([loggerFile, anotherFile, tsconfig, libFile, tsconfig]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([{ file: loggerFile, projectRootPath: tscWatch.projectRoot }], session); verifyGetErrRequest({ session, host, files: [loggerFile] }); @@ -108,7 +108,7 @@ namespace ts.projectSystem { }; const host = createServerHost([loggerFile, anotherFile, tsconfig, libFile, tsconfig]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([{ file: anotherFile, projectRootPath: tscWatch.projectRoot }], session); verifyGetErrRequest({ session, host, files: [anotherFile] }); diff --git a/src/testRunner/unittests/tsserver/helpers.ts b/src/testRunner/unittests/tsserver/helpers.ts index f87355f7491f9..323e07a876d1a 100644 --- a/src/testRunner/unittests/tsserver/helpers.ts +++ b/src/testRunner/unittests/tsserver/helpers.ts @@ -53,6 +53,7 @@ namespace ts.projectSystem { export interface Logger extends server.Logger { logs: string[]; + host?: TestServerHost; } export function nullLogger(): Logger { @@ -77,20 +78,52 @@ namespace ts.projectSystem { }; } - export function createLoggerWritingToConsole(): Logger { - return { + function handleLoggerGroup(logger: Logger, host: TestServerHost | undefined): Logger { + let inGroup = false; + let firstInGroup = false; + let seq = 0; + logger.startGroup = () => { + inGroup = true; + firstInGroup = true; + }; + logger.endGroup = () => inGroup = false; + logger.host = host; + const originalInfo = logger.info; + logger.info = s => msg(s, server.Msg.Info, s => originalInfo.call(logger, s)); + return logger; + + function msg(s: string, type = server.Msg.Err, write: (s: string) => void) { + s = `[${nowString()}] ${s}`; + if (!inGroup || firstInGroup) s = padStringRight(type + " " + seq.toString(), " ") + s; + write(s); + if (!inGroup) seq++; + } + + function padStringRight(str: string, padding: string) { + return (str + padding).slice(0, padding.length); + } + + function nowString() { + // E.g. "12:34:56.789" + const d = logger.host!.now(); + return `${padLeft(d.getUTCHours().toString(), 2, "0")}:${padLeft(d.getUTCMinutes().toString(), 2, "0")}:${padLeft(d.getUTCSeconds().toString(), 2, "0")}.${padLeft(d.getUTCMilliseconds().toString(), 3, "0")}`; + } + } + + export function createLoggerWritingToConsole(host: TestServerHost): Logger { + return handleLoggerGroup({ ...nullLogger(), hasLevel: returnTrue, loggingEnabled: returnTrue, perftrc: s => console.log(s), info: s => console.log(s), msg: (s, type) => console.log(`${type}:: ${s}`), - }; + }, host); } - export function createLoggerWithInMemoryLogs(): Logger { + export function createLoggerWithInMemoryLogs(host: TestServerHost): Logger { const logger = createHasErrorMessageLogger(); - return { + return handleLoggerGroup({ ...logger, hasLevel: returnTrue, loggingEnabled: returnTrue, @@ -109,9 +142,9 @@ namespace ts.projectSystem { .replace(/getExportInfoMap: done in \d+(?:\.\d+)?/g, `getExportInfoMap: done in *`) .replace(/collectAutoImports: \d+(?:\.\d+)?/g, `collectAutoImports: *`) .replace(/dependencies in \d+(?:\.\d+)?/g, `dependencies in *`) - .replace(/\"exportMapKey\"\:\"[_$a-zA-Z][_$_$a-zA-Z0-9]*\|\d+\|/g, match => match.replace(/\|\d+\|/, `|*|`)) + .replace(/\"exportMapKey\"\:\s*\"[_$a-zA-Z][_$_$a-zA-Z0-9]*\|\d+\|/g, match => match.replace(/\|\d+\|/, `|*|`)) ) - }; + }, host); } export function baselineTsserverLogs(scenario: string, subScenario: string, sessionOrService: { logger: Logger; }) { @@ -309,6 +342,41 @@ namespace ts.projectSystem { } } + function patchHostTimeouts(host: TestFSWithWatch.TestServerHostTrackingWrittenFiles, session: TestSession | TestProjectService) { + const originalCheckTimeoutQueueLength = host.checkTimeoutQueueLength; + const originalRunQueuedTimeoutCallbacks = host.runQueuedTimeoutCallbacks; + const originalRunQueuedImmediateCallbacks = host.runQueuedImmediateCallbacks; + + host.checkTimeoutQueueLengthAndRun = checkTimeoutQueueLengthAndRun; + host.checkTimeoutQueueLength = checkTimeoutQueueLength; + host.runQueuedTimeoutCallbacks = runQueuedTimeoutCallbacks; + host.runQueuedImmediateCallbacks = runQueuedImmediateCallbacks; + + function checkTimeoutQueueLengthAndRun(expected: number) { + session.baselineHost(`Before checking timeout queue length (${expected}) and running`); + originalCheckTimeoutQueueLength.call(host, expected); + originalRunQueuedTimeoutCallbacks.call(host); + session.baselineHost(`After checking timeout queue length (${expected}) and running`); + } + + function checkTimeoutQueueLength(expected: number) { + session.baselineHost(`Checking timeout queue length: ${expected}`); + originalCheckTimeoutQueueLength.call(host, expected); + } + + function runQueuedTimeoutCallbacks(timeoutId?: number) { + session.baselineHost(`Before running timeout callback${timeoutId === undefined ? "s" : timeoutId}`); + originalRunQueuedTimeoutCallbacks.call(host, timeoutId); + session.baselineHost(`After running timeout callback${timeoutId === undefined ? "s" : timeoutId}`); + } + + function runQueuedImmediateCallbacks(checkCount?: number) { + session.baselineHost(`Before running immediate callbacks${checkCount === undefined ? "" : ` and checking length (${checkCount})`}`); + originalRunQueuedImmediateCallbacks.call(host, checkCount); + session.baselineHost(`Before running immediate callbacks${checkCount === undefined ? "" : ` and checking length (${checkCount})`}`); + } + } + export interface TestSessionOptions extends server.SessionOptions { logger: Logger; } @@ -316,12 +384,15 @@ namespace ts.projectSystem { export class TestSession extends server.Session { private seq = 0; public events: protocol.Event[] = []; - public testhost: TestServerHost = this.host as TestServerHost; + public testhost: TestFSWithWatch.TestServerHostTrackingWrittenFiles; public logger: Logger; + private hostDiff: ReturnType | undefined; constructor(opts: TestSessionOptions) { super(opts); this.logger = opts.logger; + this.testhost = TestFSWithWatch.changeToHostTrackingWrittenFiles(this.host as TestServerHost); + patchHostTimeouts(this.testhost, this); } getProjectService() { @@ -337,11 +408,7 @@ namespace ts.projectSystem { } public executeCommand(request: protocol.Request) { - const verboseLogging = this.logger.hasLevel(server.LogLevel.verbose); - if (verboseLogging) this.logger.info(`request:${JSON.stringify(request)}`); - const result = super.executeCommand(request); - if (verboseLogging) this.logger.info(`response:${JSON.stringify(result)}`); - return result; + return this.baseline("response", super.executeCommand(this.baseline("request", request))); } public executeCommandSeq(request: Partial) { @@ -360,6 +427,23 @@ namespace ts.projectSystem { clear(this.events); this.testhost.clearOutput(); } + + private baseline(type: "request" | "response", requestOrResult: T): T { + if (!this.logger.hasLevel(server.LogLevel.verbose)) return requestOrResult; + if (type === "request") this.logger.info(`request:${server.indent(JSON.stringify(requestOrResult, undefined, 2))}`); + this.baselineHost(type === "request" ? "Before request" : "After request"); + if (type === "response") this.logger.info(`response:${server.indent(JSON.stringify(requestOrResult, undefined, 2))}`); + return requestOrResult; + } + + baselineHost(title: string) { + if (!this.logger.hasLevel(server.LogLevel.verbose)) return; + this.logger.logs.push(title); + this.testhost.diff(this.logger.logs, this.hostDiff); + this.testhost.serializeWatches(this.logger.logs); + this.hostDiff = this.testhost.snap(); + this.testhost.writtenFiles.clear(); + } } export function createSession(host: server.ServerHost, opts: Partial = {}) { @@ -426,7 +510,9 @@ namespace ts.projectSystem { } export class TestProjectService extends server.ProjectService { - constructor(host: server.ServerHost, public logger: Logger, cancellationToken: HostCancellationToken, useSingleInferredProject: boolean, + public testhost: TestFSWithWatch.TestServerHostTrackingWrittenFiles; + private hostDiff: ReturnType | undefined; + constructor(host: TestServerHost, public logger: Logger, cancellationToken: HostCancellationToken, useSingleInferredProject: boolean, typingsInstaller: server.ITypingsInstaller, opts: Partial = {}) { super({ host, @@ -439,14 +525,26 @@ namespace ts.projectSystem { typesMapLocation: customTypesMap.path, ...opts }); + this.testhost = TestFSWithWatch.changeToHostTrackingWrittenFiles(this.host as TestServerHost); + patchHostTimeouts(this.testhost, this); + this.baselineHost("Creating project service"); } checkNumberOfProjects(count: { inferredProjects?: number, configuredProjects?: number, externalProjects?: number }) { checkNumberOfProjects(this, count); } + + baselineHost(title: string) { + if (!this.logger.hasLevel(server.LogLevel.verbose)) return; + this.logger.logs.push(title); + this.testhost.diff(this.logger.logs, this.hostDiff); + this.testhost.serializeWatches(this.logger.logs); + this.hostDiff = this.testhost.snap(); + this.testhost.writtenFiles.clear(); + } } - export function createProjectService(host: server.ServerHost, options?: Partial) { + export function createProjectService(host: TestServerHost, options?: Partial) { const cancellationToken = options?.cancellationToken || server.nullCancellationToken; const logger = options?.logger || createHasErrorMessageLogger(); const useSingleInferredProject = options?.useSingleInferredProject !== undefined ? options.useSingleInferredProject : false; @@ -738,7 +836,7 @@ namespace ts.projectSystem { checkAllErrors(request); } - interface SkipErrors { semantic?: true; suggestion?: true }; + interface SkipErrors { semantic?: true; suggestion?: true } export interface CheckAllErrors extends VerifyGetErrRequestBase { files: readonly any[]; skip?: readonly (SkipErrors | undefined)[]; @@ -765,7 +863,7 @@ namespace ts.projectSystem { function verifyErrorsUsingGeterr({scenario, subScenario, allFiles, openFiles, getErrRequest }: VerifyGetErrScenario) { it("verifies the errors in open file", () => { const host = createServerHost([...allFiles(), libFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession(openFiles(), session); verifyGetErrRequest({ session, host, files: getErrRequest() }); @@ -776,7 +874,7 @@ namespace ts.projectSystem { function verifyErrorsUsingGeterrForProject({ scenario, subScenario, allFiles, openFiles, getErrForProjectRequest }: VerifyGetErrScenario) { it("verifies the errors in projects", () => { const host = createServerHost([...allFiles(), libFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession(openFiles(), session); for (const expected of getErrForProjectRequest()) { @@ -793,7 +891,7 @@ namespace ts.projectSystem { function verifyErrorsUsingSyncMethods({ scenario, subScenario, allFiles, openFiles, syncDiagnostics }: VerifyGetErrScenario) { it("verifies the errors using sync commands", () => { const host = createServerHost([...allFiles(), libFile]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession(openFiles(), session); for (const { file, project } of syncDiagnostics()) { const reqArgs = { file: filePath(file), projectFileName: project && filePath(project) }; diff --git a/src/testRunner/unittests/tsserver/inferredProjects.ts b/src/testRunner/unittests/tsserver/inferredProjects.ts index d4390e111add0..ce1747ee4fa5c 100644 --- a/src/testRunner/unittests/tsserver/inferredProjects.ts +++ b/src/testRunner/unittests/tsserver/inferredProjects.ts @@ -14,7 +14,7 @@ namespace ts.projectSystem { content: `export let x: number` }; const host = createServerHost([appFile, moduleFile, libFile]); - const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs() }); + const projectService = createProjectService(host, { logger: createLoggerWithInMemoryLogs(host) }); projectService.openClientFile(appFile.path); baselineTsserverLogs("inferredProjects", "create inferred project", projectService); }); diff --git a/src/testRunner/unittests/tsserver/moduleResolution.ts b/src/testRunner/unittests/tsserver/moduleResolution.ts index ec3535c5d73ab..914de1b3a22d3 100644 --- a/src/testRunner/unittests/tsserver/moduleResolution.ts +++ b/src/testRunner/unittests/tsserver/moduleResolution.ts @@ -32,7 +32,7 @@ namespace ts.projectSystem { ` }; const host = createServerHost([configFile, fileA, fileB, packageFile, { ...libFile, path: "/a/lib/lib.es2016.full.d.ts" }]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([fileA], session); return { host, session, packageFile, diff --git a/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts b/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts index a89d9d56fdd43..b9423ec98dd96 100644 --- a/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts +++ b/src/testRunner/unittests/tsserver/moduleSpecifierCache.ts @@ -59,7 +59,7 @@ namespace ts.projectSystem { }); it("invalidates module specifiers when changes happen in contained node_modules directories", () => { - const { host, session, moduleSpecifierCache, triggerCompletions } = setup(createLoggerWithInMemoryLogs()); + const { host, session, moduleSpecifierCache, triggerCompletions } = setup(host => createLoggerWithInMemoryLogs(host)); // Completion at an import statement will calculate and cache module specifiers triggerCompletions({ file: cTs.path, line: 1, offset: cTs.content.length + 1 }); host.writeFile("/node_modules/.staging/mobx-12345678/package.json", "{}"); @@ -123,9 +123,9 @@ namespace ts.projectSystem { }); }); - function setup(logger?: Logger) { + function setup(createLogger?: (host: TestServerHost) => Logger) { const host = createServerHost([aTs, bTs, cTs, bSymlink, ambientDeclaration, tsconfig, packageJson, mobxPackageJson, mobxDts]); - const session = createSession(host, logger && { logger }); + const session = createSession(host, createLogger && { logger: createLogger(host) }); openFilesForSession([aTs, bTs, cTs], session); const projectService = session.getProjectService(); const project = configuredProjectAt(projectService, 0); diff --git a/src/testRunner/unittests/tsserver/navTo.ts b/src/testRunner/unittests/tsserver/navTo.ts index eeebca75263fd..e484afaeab9c5 100644 --- a/src/testRunner/unittests/tsserver/navTo.ts +++ b/src/testRunner/unittests/tsserver/navTo.ts @@ -61,7 +61,7 @@ namespace ts.projectSystem { export const ghijkl = a.abcdef;` }; const host = createServerHost([configFile1, file1, configFile2, file2]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file1, file2], session); const request = makeSessionRequest(CommandNames.Navto, { searchValue: "abcdef", file: file1.path }); @@ -107,7 +107,7 @@ export const ghijkl = a.abcdef;` export const ghijkl = a.abcdef;` }; const host = createServerHost([configFile1, file1, configFile2, file2, solutionConfig]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file1], session); const request = makeSessionRequest(CommandNames.Navto, { searchValue: "abcdef" }); diff --git a/src/testRunner/unittests/tsserver/openFile.ts b/src/testRunner/unittests/tsserver/openFile.ts index 362c6ae16f005..de791a3e495a5 100644 --- a/src/testRunner/unittests/tsserver/openFile.ts +++ b/src/testRunner/unittests/tsserver/openFile.ts @@ -147,7 +147,7 @@ foo(); bar();` }; const host = createServerHost([file, libFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file], session); verifyGetErrRequest({ session, host, files: [file] }); diff --git a/src/testRunner/unittests/tsserver/partialSemanticServer.ts b/src/testRunner/unittests/tsserver/partialSemanticServer.ts index 621c4db5c5374..2a7a4157c6ff1 100644 --- a/src/testRunner/unittests/tsserver/partialSemanticServer.ts +++ b/src/testRunner/unittests/tsserver/partialSemanticServer.ts @@ -29,7 +29,7 @@ import { something } from "something"; const session = createSession(host, { serverMode: LanguageServiceMode.PartialSemantic, useSingleInferredProject: true, - logger: createLoggerWithInMemoryLogs(), + logger: createLoggerWithInMemoryLogs(host), }); return { host, session, file1, file2, file3, something, configFile }; } @@ -98,7 +98,7 @@ import { something } from "something"; const session = createSession(host, { serverMode: LanguageServiceMode.PartialSemantic, useSingleInferredProject: true, - logger: createLoggerWithInMemoryLogs() + logger: createLoggerWithInMemoryLogs(host) }); const service = session.getProjectService(); @@ -163,7 +163,7 @@ function fooB() { }` const session = createSession(host, { serverMode: LanguageServiceMode.PartialSemantic, useSingleInferredProject: true, - logger: createLoggerWithInMemoryLogs(), + logger: createLoggerWithInMemoryLogs(host), }); openFilesForSession([file1], session); baselineTsserverLogs("partialSemanticServer", "should not include referenced files from unopened files", session); diff --git a/src/testRunner/unittests/tsserver/projectErrors.ts b/src/testRunner/unittests/tsserver/projectErrors.ts index f721a27cf316f..750b968b6c0f8 100644 --- a/src/testRunner/unittests/tsserver/projectErrors.ts +++ b/src/testRunner/unittests/tsserver/projectErrors.ts @@ -232,7 +232,7 @@ namespace ts.projectSystem { content: "class c { }" }; const host = createServerHost([libFile, fileInRoot, fileInProjectRoot]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(), useInferredProjectPerProjectRoot: true }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host), useInferredProjectPerProjectRoot: true }); const untitledFile = "untitled:Untitled-1"; const refPathNotFound1 = "../../../../../../typings/@epic/Core.d.ts"; @@ -280,7 +280,7 @@ namespace ts.projectSystem { content: JSON.stringify({ compilerOptions: { module: "none", targer: "es5" }, exclude: ["node_modules"] }) }; const host = createServerHost([app, foo, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); session.executeCommandSeq({ command: server.CommandNames.Open, @@ -301,7 +301,7 @@ namespace ts.projectSystem { content: "let x: number = false;" }; const host = createServerHost([file, libFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); session.executeCommandSeq({ command: server.CommandNames.Geterr, arguments: { @@ -329,7 +329,7 @@ namespace ts.projectSystem { }; const files = [libFile, app, serverUtilities, backendTest]; const host = createServerHost(files); - const session = createSession(host, { useInferredProjectPerProjectRoot: true, canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { useInferredProjectPerProjectRoot: true, canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([{ file: app, projectRootPath: tscWatch.projectRoot }], session); openFilesForSession([{ file: backendTest, projectRootPath: tscWatch.projectRoot }], session); verifyGetErrRequest({ session, host, files: [backendTest.path, app.path] }); @@ -367,7 +367,7 @@ declare module '@custom/plugin' { }; const files = [libFile, aFile, config, plugin, pluginProposed]; const host = createServerHost(files); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([aFile], session); checkErrors(); @@ -430,7 +430,7 @@ declare module '@custom/plugin' { }` }; const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file], session); baselineTsserverLogs("projectErrors", "configFileDiagnostic events are generated when the config file has errors", session); }); @@ -447,7 +447,7 @@ declare module '@custom/plugin' { }` }; const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file], session); baselineTsserverLogs("projectErrors", "configFileDiagnostic events are generated when the config file doesnt have errors", session); }); @@ -465,7 +465,7 @@ declare module '@custom/plugin' { }; const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file], session); configFile.content = `{ @@ -508,7 +508,7 @@ declare module '@custom/plugin' { }` }; const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file2], session); openFilesForSession([file], session); // We generate only if project is created when opening file from the project @@ -531,7 +531,7 @@ declare module '@custom/plugin' { }` }; const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, suppressDiagnosticEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, suppressDiagnosticEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file], session); baselineTsserverLogs("projectErrors", "configFileDiagnostic events are not generated when the config file has errors but suppressDiagnosticEvents is true", session); }); @@ -557,7 +557,7 @@ declare module '@custom/plugin' { }; const host = createServerHost([file, file2, file3, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file2], session); openFilesForSession([file], session); // We generate only if project is created when opening file from the project @@ -580,7 +580,7 @@ declare module '@custom/plugin' { }; const host = createServerHost([file, libFile, configFile]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file], session); baselineTsserverLogs("projectErrors", "configFileDiagnostic events contains the project reference errors", session); }); @@ -788,7 +788,7 @@ console.log(blabla);` }; const host = createServerHost([test, blabla, libFile, tsconfig]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([test], session); return { host, session, test, blabla, tsconfig }; } @@ -827,7 +827,7 @@ console.log(blabla);` }; const projectFiles = [main, libFile, config]; const host = createServerHost(projectFiles); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([{ file: main, projectRootPath: tscWatch.projectRoot }], session); verifyGetErrRequest({ session, host, files: [main] }); diff --git a/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts b/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts index 8ea94a596c8a8..671813de33fc6 100644 --- a/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts +++ b/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts @@ -35,157 +35,60 @@ fn2(); const localChange = "function fn3() { }"; const change = `export ${localChange}`; - const changeJs = `function fn3() { } -exports.fn3 = fn3;`; - const changeDts = "export declare function fn3(): void;"; - - function expectedAffectedFiles(config: File, fileNames: readonly File[]): protocol.CompileOnSaveAffectedFileListSingleProject { - return { - projectFileName: config.path, - fileNames: fileNames.map(f => f.path), - projectUsesOutFile: false - }; - } - - function expectedUsageEmitFiles(appendJsText?: string): readonly File[] { - const appendJs = appendJsText ? `${appendJsText} -` : ""; - return [{ - path: `${usageLocation}/usage.js`, - content: `"use strict"; -exports.__esModule = true;${appendJsText === changeJs ? "\nexports.fn3 = void 0;" : ""} -var fns_1 = require("../decls/fns"); -(0, fns_1.fn1)(); -(0, fns_1.fn2)(); -${appendJs}` - }]; - } - - function expectedEmitOutput(expectedFiles: readonly File[]): EmitOutput { - return { - outputFiles: expectedFiles.map(({ path, content }) => ({ - name: path, - text: content, - writeByteOrderMark: false - })), - emitSkipped: false, - diagnostics: emptyArray - }; - } - - function noEmitOutput(): EmitOutput { - return { - emitSkipped: true, - outputFiles: [], - diagnostics: emptyArray - }; - } - - function expectedDependencyEmitFiles(appendJsText?: string, appendDtsText?: string): readonly File[] { - const appendJs = appendJsText ? `${appendJsText} -` : ""; - const appendDts = appendDtsText ? `${appendDtsText} -` : ""; - return [ - { - path: `${dependecyLocation}/fns.js`, - content: `"use strict"; -exports.__esModule = true; -${appendJsText === changeJs ? "exports.fn3 = " : ""}exports.fn2 = exports.fn1 = void 0; -function fn1() { } -exports.fn1 = fn1; -function fn2() { } -exports.fn2 = fn2; -${appendJs}` - }, - { - path: `${tscWatch.projectRoot}/decls/fns.d.ts`, - content: `export declare function fn1(): void; -export declare function fn2(): void; -${appendDts}` - } - ]; - } describe("when dependency project is not open", () => { describe("Of usageTs", () => { it("with initial file open, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage", session); }); it("with initial file open, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage with project", session); }); it("with local change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -193,42 +96,29 @@ ${appendDts}` arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage and local change to dependency", session); }); it("with local change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -236,42 +126,29 @@ ${appendDts}` arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage with project and local change to dependency", session); }); it("with local change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -290,42 +167,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(localChange); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage and local change to usage", session); }); it("with local change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -344,42 +208,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(localChange); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage with project and local change to usage", session); }); it("with change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -387,42 +238,29 @@ ${appendDts}` arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage and change to depenedency", session); }); it("with change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -430,42 +268,29 @@ ${appendDts}` arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage with project and change to depenedency", session); }); it("with change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -484,42 +309,29 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(changeJs); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage and change to usage", session); }); it("with change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -538,107 +350,80 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(changeJs); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on usage with project and change to usage", session); }); }); describe("Of dependencyTs in usage project", () => { it("with initial file open, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency", session); }); it("with initial file open, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency with project", session); }); it("with local change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -646,37 +431,29 @@ ${appendDts}` arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency and local change to dependency", session); }); it("with local change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -684,37 +461,29 @@ ${appendDts}` arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${localChange}`); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency with project and local change to dependency", session); }); it("with local change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -733,37 +502,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency and local change to usage", session); }); it("with local change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -782,37 +543,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency with project and local change to usage", session); }); it("with change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -820,37 +573,29 @@ ${appendDts}` arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency and change to dependency", session); }); it("with change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -858,37 +603,29 @@ ${appendDts}` arguments: { file: dependencyTs.path } }); host.writeFile(dependencyTs.path, `${dependencyTs.content}${change}`); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency with project and change to dependency", session); }); it("with change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -907,37 +644,29 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency and change to usage", session); }); it("with change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs], session); session.executeCommandSeq({ @@ -956,31 +685,25 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "when dependency project is not open and save on dependency with project and change to usage", session); }); }); }); @@ -988,82 +711,56 @@ ${appendDts}` describe("when the depedency file is open", () => { describe("Of usageTs", () => { it("with initial file open, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage", session); }); it("with initial file open, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage with project", session); }); it("with local change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1082,42 +779,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and local change to dependency", session); }); it("with local change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1136,42 +820,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and local change to dependency with file", session); }); it("with local change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1190,42 +861,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(localChange); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and local change to usage", session); }); it("with local change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1244,42 +902,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(localChange); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and local change to usage with project", session); }); it("with change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1298,42 +943,29 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and change to dependency", session); }); it("with change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1352,42 +984,29 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage with project and change to dependency", session); }); it("with change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1406,42 +1025,29 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(changeJs); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage and change to usage", session); }); it("with change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1460,76 +1066,55 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedUsageEmitFiles(changeJs); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } - + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: usageTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on usage with project and change to usage", session); }); }); describe("Of dependencyTs in usage project", () => { it("with initial file open, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with usage project", session); }); it("with local change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1548,37 +1133,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with usage project and local change to dependency", session); }); it("with local change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1597,37 +1174,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with usage project and local change to usage", session); }); it("with change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1646,37 +1215,29 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with usage project and change to dependency", session); }); it("with change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1695,113 +1256,80 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response; - assert.isFalse(actualEmit, "Emit files"); - assert.equal(host.writtenFiles.size, 0); + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: usageConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, noEmitOutput(), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with usage project and change to usage", session); }); }); describe("Of dependencyTs", () => { it("with initial file open, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]), - expectedAffectedFiles(dependencyConfig, [dependencyTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedDependencyEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency", session); }); it("with initial file open, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(dependencyConfig, [dependencyTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedDependencyEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with project", session); }); it("with local change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1820,43 +1348,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray), - expectedAffectedFiles(dependencyConfig, [dependencyTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedDependencyEmitFiles(localChange); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency and local change to dependency", session); }); it("with local change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1875,42 +1389,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(dependencyConfig, [dependencyTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedDependencyEmitFiles(localChange); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with project and local change to dependency", session); }); it("with local change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1929,43 +1430,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray), - expectedAffectedFiles(dependencyConfig, [dependencyTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedDependencyEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency and local change to usage", session); }); it("with local change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -1984,42 +1471,29 @@ ${appendDts}` insertString: localChange } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(dependencyConfig, [dependencyTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedDependencyEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with project and local change to usage", session); }); it("with change to dependency, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -2038,43 +1512,29 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, [usageTs]), - expectedAffectedFiles(dependencyConfig, [dependencyTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedDependencyEmitFiles(changeJs, changeDts); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency and change to dependency", session); }); it("with change to dependency, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -2093,42 +1553,29 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(dependencyConfig, [dependencyTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedDependencyEmitFiles(changeJs, changeDts); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with project and change to dependency", session); }); it("with change to usage, without specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -2147,43 +1594,29 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(usageConfig, emptyArray), - expectedAffectedFiles(dependencyConfig, [dependencyTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedDependencyEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency and change to usage", session); }); it("with change to usage, with specifying project file", () => { - const host = TestFSWithWatch.changeToHostTrackingWrittenFiles( - createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]) - ); - const session = createSession(host); + const host = createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile]); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([usageTs, dependencyTs], session); session.executeCommandSeq({ @@ -2202,36 +1635,25 @@ ${appendDts}` insertString: change } }); - host.writtenFiles.clear(); // Verify CompileOnSaveAffectedFileList - const actualAffectedFiles = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveAffectedFileList, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as protocol.CompileOnSaveAffectedFileListSingleProject[]; - assert.deepEqual(actualAffectedFiles, [ - expectedAffectedFiles(dependencyConfig, [dependencyTs]) - ], "Affected files"); + }); // Verify CompileOnSaveEmit - const actualEmit = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.CompileOnSaveEmitFile, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response; - assert.isTrue(actualEmit, "Emit files"); - const expectedFiles = expectedDependencyEmitFiles(); - assert.equal(host.writtenFiles.size, expectedFiles.length); - for (const file of expectedFiles) { - assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`); - assert.isTrue(host.writtenFiles.has(file.path as Path), `${file.path} is newly written`); - } + }); // Verify EmitOutput - const actualEmitOutput = session.executeCommandSeq({ + session.executeCommandSeq({ command: protocol.CommandTypes.EmitOutput, arguments: { file: dependencyTs.path, projectFileName: dependencyConfig.path } - }).response as EmitOutput; - assert.deepEqual(actualEmitOutput, expectedEmitOutput(expectedFiles), "Emit output"); + }); + baselineTsserverLogs("projectReferenceCompileOnSave", "save on dependency with project and change to usage", session); }); }); }); @@ -2297,10 +1719,8 @@ ${appendDts}` // ts build should succeed tscWatch.ensureErrorFreeBuild(host, [siblingConfig.path]); - const sourceJs = changeExtension(siblingSource.path, ".js"); - const expectedSiblingJs = host.readFile(sourceJs); - const session = createSession(host); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([siblingSource], session); session.executeCommandSeq({ @@ -2310,7 +1730,7 @@ ${appendDts}` projectFileName: siblingConfig.path } }); - assert.equal(host.readFile(sourceJs), expectedSiblingJs); + baselineTsserverLogs("projectReferenceCompileOnSave", "compile on save emits same output as project build with external project", session); }); }); } \ No newline at end of file diff --git a/src/testRunner/unittests/tsserver/projectReferences.ts b/src/testRunner/unittests/tsserver/projectReferences.ts index d5f2cf6339c74..694b279395294 100644 --- a/src/testRunner/unittests/tsserver/projectReferences.ts +++ b/src/testRunner/unittests/tsserver/projectReferences.ts @@ -26,7 +26,7 @@ namespace ts.projectSystem { const host = createHostWithSolutionBuild(files, [containerConfig.path]); // Open external project for the folder - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); const service = session.getProjectService(); service.openExternalProjects([{ projectFileName: TestFSWithWatch.getTsBuildProjectFilePath(project, project), @@ -57,7 +57,7 @@ namespace ts.projectSystem { it("can successfully find references with --out options", () => { const host = createHostWithSolutionBuild(files, [containerConfig.path]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([containerCompositeExec[1]], session); const myConstStart = protocolLocationFromSubstring(containerCompositeExec[1].content, "myConst"); session.executeCommandSeq({ @@ -74,7 +74,7 @@ namespace ts.projectSystem { content: "let x = 10" }; const host = createHostWithSolutionBuild(files.concat([tempFile]), [containerConfig.path]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([containerCompositeExec[1]], session); const service = session.getProjectService(); @@ -164,7 +164,7 @@ function foo() { [commonConfig, keyboardTs, keyboardTestTs, srcConfig, terminalTs, libFile], [srcConfig.path] ); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([keyboardTs, terminalTs], session); const searchStr = "evaluateKeyboardEvent"; @@ -341,7 +341,7 @@ function foo() { createServerHost(files); // Create symlink in node module - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([aTest], session); verifyGetErrRequest({ session, host, files: [aTest] }); session.executeCommandSeq({ @@ -492,7 +492,7 @@ testCompositeFunction('why hello there', 42);` symLink: `${tscWatch.projectRoot}/packages/emit-composite` }; const host = createServerHost([libFile, compositeConfig, compositePackageJson, compositeIndex, compositeTestModule, consumerConfig, consumerIndex, symlink], { useCaseSensitiveFileNames: true }); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([consumerIndex], session); verifyGetErrRequest({ host, session, files: [consumerIndex] }); baselineTsserverLogs("projectReferences", `when the referenced projects have allowJs and emitDeclarationOnly`, session); @@ -562,7 +562,7 @@ testCompositeFunction('why hello there', 42);` const files = [libFile, solution, compilerConfig, typesFile, programFile, servicesConfig, servicesFile, libFile]; const host = createServerHost(files); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([programFile], session); // Find all references for getSourceFile @@ -682,7 +682,7 @@ testCompositeFunction('why hello there', 42);` const files = [libFile, solutionConfig, aConfig, aFile, bConfig, bFile, cConfig, cFile, dConfig, dFile, libFile]; const host = createServerHost(files); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([bFile], session); // The first search will trigger project loads @@ -756,7 +756,7 @@ ${usage}` content: definition }; const host = createServerHost([libFile, solution, libFile, apiConfig, apiFile, appConfig, appFile, sharedConfig, sharedFile]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([apiFile], session); // Find all references @@ -874,7 +874,7 @@ export const foo = local;`, const files = [libFile, solution, compilerConfig, typesFile, programFile, servicesConfig, servicesFile, libFile]; const host = createServerHost(files); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([programFile], session); // Find all references @@ -969,7 +969,7 @@ export function bar() {}` mainDts, mainDtsMap, helperDts, helperDtsMap, tsconfigIndirect3, fileResolvingToMainDts, ...additionalFiles]); - const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { canUseEvents: true, logger: createLoggerWithInMemoryLogs(host) }); const service = session.getProjectService(); service.openClientFile(main.path); return { session, service, host }; @@ -979,10 +979,10 @@ export function bar() {}` const { session, service, host } = setup(input); const info = service.getScriptInfoForPath(main.path as Path)!; - session.logger.logs.push(""); - session.logger.logs.push(`getDefaultProject for ${main.path}: ${info.getDefaultProject().projectName}`); - session.logger.logs.push(`findDefaultConfiguredProject for ${main.path}: ${service.findDefaultConfiguredProject(info)!.projectName}`); - session.logger.logs.push(""); + session.logger.startGroup(); + session.logger.info(`getDefaultProject for ${main.path}: ${info.getDefaultProject().projectName}`); + session.logger.info(`findDefaultConfiguredProject for ${main.path}: ${service.findDefaultConfiguredProject(info)!.projectName}`); + session.logger.endGroup(); // Verify errors verifyGetErrRequest({ session, host, files: [main] }); @@ -1046,10 +1046,10 @@ export function bar() {}` const { session, service } = setup(input); const info = service.getScriptInfoForPath(main.path as Path)!; - session.logger.logs.push(""); - session.logger.logs.push(`getDefaultProject for ${main.path}: ${info.getDefaultProject().projectName}`); - session.logger.logs.push(`findDefaultConfiguredProject for ${main.path}: ${service.findDefaultConfiguredProject(info)?.projectName}`); - session.logger.logs.push(""); + session.logger.startGroup(); + session.logger.info(`getDefaultProject for ${main.path}: ${info.getDefaultProject().projectName}`); + session.logger.info(`findDefaultConfiguredProject for ${main.path}: ${service.findDefaultConfiguredProject(info)?.projectName}`); + session.logger.endGroup(); // Verify collection of script infos service.openClientFile(dummyFilePath); @@ -1246,7 +1246,7 @@ bar;` content: `class class2 {}` }; const host = createServerHost([config1, class1, class1Dts, config2, class2, libFile]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([class2], session); return { host, session, class1 }; } @@ -1401,7 +1401,7 @@ bar;` tscWatch.solutionBuildWithBaseline(host, [solnConfig.path]); host.clearOutput(); } - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([appIndex], session); session.executeCommandSeq({ command: protocol.CommandTypes.GetCodeFixes, @@ -1464,7 +1464,7 @@ bar;` refToCoreRef3File, refToCoreRef3Config, indirectNoCoreRefFile, indirectNoCoreRefConfig, noCoreRef2File, noCoreRef2Config ], { useCaseSensitiveFileNames: true }); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([mainFile, coreFile], session); // Find all refs in coreFile @@ -1549,7 +1549,7 @@ const b: B = new B();` }; const host = createServerHost([configA, indexA, configB, indexB, helperB, dtsB, ...(dtsMapPresent ? [dtsMapB] : [])]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([indexA, ...(projectAlreadyLoaded ? [helperB] : [])], session); session.executeCommandSeq({ diff --git a/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts b/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts index b0f2c2a15b85a..d951b02058c2c 100644 --- a/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts +++ b/src/testRunner/unittests/tsserver/projectReferencesSourcemap.ts @@ -216,14 +216,14 @@ fn5(); compilerOptions: { composite: true, declarationMap: true } })); onHostCreate?.(host); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); return { host, session }; } function createSessionWithProjectReferences(onHostCreate?: OnHostCreate) { const host = createHostWithSolutionBuild(files, [mainConfig.path]); onHostCreate?.(host); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); return { host, session }; } @@ -239,7 +239,7 @@ fn5(); references: [{ path: "../dependency" }] })); onHostCreate?.(host); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); return { host, session }; } @@ -815,7 +815,7 @@ ${dependencyTs.content}`); it("when projects are not built", () => { const host = createServerHost(files); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([mainTs, randomFile], session); verifyAllFnAction( session, @@ -1619,7 +1619,7 @@ ${dependencyTs.content}`); it("when projects are not built", () => { const host = createServerHost(files); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([dependencyTs, randomFile], session); verifyAllFnAction( session, @@ -2659,7 +2659,7 @@ ${dependencyTs.content}`); it("when projects are not built", () => { const host = createServerHost(files); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([mainTs, dependencyTs, randomFile], session); verifyAllFnAction( session, diff --git a/src/testRunner/unittests/tsserver/projects.ts b/src/testRunner/unittests/tsserver/projects.ts index 7a166dc1abbb2..10cc61ff6cd03 100644 --- a/src/testRunner/unittests/tsserver/projects.ts +++ b/src/testRunner/unittests/tsserver/projects.ts @@ -7,7 +7,7 @@ namespace ts.projectSystem { let x = y` }; const host = createServerHost([file1, libFile]); - const session = createSession(host, { logger: createLoggerWithInMemoryLogs() }); + const session = createSession(host, { logger: createLoggerWithInMemoryLogs(host) }); openFilesForSession([file1], session); const getErrRequest = makeSessionRequest( @@ -567,7 +567,7 @@ namespace ts.projectSystem { path: "/a/b/file1.js", content: "var x = 10;", fileName: "/a/b/file1.js", - scriptKind: "JS" as "JS" + scriptKind: "JS" as const }; const host = createServerHost([]); @@ -861,7 +861,7 @@ namespace ts.projectSystem { content: `