diff --git a/external-declarations/fixed-tests.jsonc b/external-declarations/fixed-tests.jsonc index 7626f305afda5..e4961773ebb53 100644 --- a/external-declarations/fixed-tests.jsonc +++ b/external-declarations/fixed-tests.jsonc @@ -5,10 +5,11 @@ 9008, // Declaration_emit_for_this_file_requires_adding_a_type_reference_directive_Add_a_type_reference_directive_to_0_to_unblock_declaration_emit 9009, // Assigning_properties_to_functions_without_declaring_them_is_not_supported_with_isolatedDeclarations_Add_an_explicit_declaration_for_the_properties_assigned_to_this_function 9010, // Reference directives are not supported in isolated declaration mode. - ], + 9011 // Heritage_clause_for_Class_Expressions_is_not_allowed_with_isolatedDeclarations + ], "with-unreliable-errors": [ 2784, // 'get' and 'set' accessors cannot declare 'this' parameters. - 1162, // An object member cannot be declared optional. + 1162 // An object member cannot be declared optional. ] }, "test-categories": { @@ -26,9 +27,9 @@ "enumErrors", "enumExportMergingES6", "verbatimModuleSyntaxConstEnumUsage", - "templateLiteralTypes4", + "templateLiteralTypes4" ], - "code-fixer-issues" : [ + "code-fixer-issues": [ "arrayFakeFlatNoCrashInferenceDeclarations", "commonJsImportClassExpression", "constEnumNamespaceReferenceCausesNoImport2", @@ -50,20 +51,20 @@ "reexportClassDefinition", "parserEqualsGreaterThanAfterFunction1", "parserSkippedTokens16", - "declarationFiles", + "declarationFiles" ], "not-fixed-with-unreliable-errors": [ // Language service crash on computing diagnostic (call stack size exceeded) "binderBinaryExpressionStress", - // Bad syntax beyond recovery + // Bad syntax beyond recovery "destructuringParameterDeclaration6", - "thisTypeInFunctionsNegative", + "thisTypeInFunctionsNegative" ], "with-unreliable-errors": [ "thisTypeErrors", // Assertion to this in static context produces this in DTE and any in TSC "parseInvalidNonNullableTypes", // Prefix ! operator - "thisInConstructorParameter2", // this type used in invalid context - "parseInvalidNullableTypes", // Prefix ? operator + "thisInConstructorParameter2", // this type used in invalid context + "parseInvalidNullableTypes", // Prefix ? operator "ArrowFunction1", // Missing type annotation syntax error "parserX_ArrowFunction1", // Missing type annotation syntax error "typeParameterDirectlyConstrainedToItself", // Circular type constraints makes emit unreliable @@ -80,10 +81,10 @@ "duplicatePropertiesInTypeAssertions02", "parserCastVersusArrowFunction1", "invalidMultipleVariableDeclarations", - "validMultipleVariableDeclarations", + "validMultipleVariableDeclarations", "augmentedTypesVar", "objectLiteralErrors", - "duplicateObjectLiteralProperty_computedName2", + "duplicateObjectLiteralProperty_computedName2", "arrowFunctionExpressions", "castingTuple", // contains both duplicate variables and print differences. // Identifier expected. @@ -117,18 +118,18 @@ "decoratorsOnComputedProperties", "indexSignatureMustHaveTypeAnnotation", "intTypeCheck", - // Invalid escape sequences + // Invalid escape sequences "invalidTaggedTemplateEscapeSequences", "objectTypeWithStringNamedPropertyOfIllegalCharacters", "noUsedBeforeDefinedErrorInTypeContext", // Variable used before definition in type context - "accessorBodyInTypeContext", //An implementation cannot be declared in ambient contexts. + "accessorBodyInTypeContext", // An implementation cannot be declared in ambient contexts. "commonJsExportTypeDeclarationError", // Duplicate name, TS resolves to the type alias symbol, DTE resolves to import. Neither is wrong, code is wrong. "parseAssertEntriesError", // Syntactic invalid import assertions. "decoratorMetadataWithImportDeclarationNameCollision7", // Import does not have the accessed member. TS removes the import as unused. A DTE will keep it as it is syntactically used. "classExtendingNonConstructor", // Not reported as isolated declaration error, but the extends clause is invalid. "nodeModulesImportTypeModeDeclarationEmitErrors1", // Invalid import asserts - "wellKnownSymbolExpando", // Expando function with well known symbols error in TS, but generate the expando function namepsace, DTE does not. - "genericsWithDuplicateTypeParameters1", // Duplicate type parameters + "wellKnownSymbolExpando", // Expando function with well known symbols error in TS, but generate the expando function namepsace, DTE does not. + "genericsWithDuplicateTypeParameters1" // Duplicate type parameters ], "with-isolated-declaration-errors/9008": [ "declarationEmitHasTypesRefOnNamespaceUse", @@ -142,13 +143,12 @@ // Will not actually error because of https://github.com/microsoft/TypeScript/issues/55636 // In isolated declarations we walk the type in the return as if it was hand written in the variable // This triggers the difference in behavior described in the issue. - "jsxNamespaceGlobalReexport", - + "jsxNamespaceGlobalReexport" ], "with-isolated-declaration-errors": [ "typeFromPropertyAssignment38", // Nested expando functions. Can in principle be detected, but are not yet implemented "contextualReturnTypeOfIIFE2", // Nested expando functions. Can in principle be detected, but are not yet implemented - // Computed property errors a DTE can't detect + // Computed property errors a DTE can't detect "complicatedPrivacy", "computedPropertyNames12_ES5", "computedPropertyNames12_ES6", @@ -216,15 +216,15 @@ "declarationEmitForModuleImportingModuleAugmentationRetainsImport" // Import augments and must be kept ], "ts-bugs": [ - // Type parameter renamed - // Reported as https://github.com/microsoft/TypeScript/issues/55653 + // Type parameter renamed + // Reported as https://github.com/microsoft/TypeScript/issues/55653 "objectTypesIdentityWithGenericCallSignaturesDifferingTypeParameterCounts", "objectTypesIdentityWithGenericCallSignaturesDifferingTypeParameterNames", "objectTypesIdentityWithGenericConstructSignaturesDifferingTypeParameterCounts", "typeAssertionToGenericFunctionType", // Default type parameters is written in declarations - "conditionalTypesSimplifyWhenTrivial", - // https://github.com/microsoft/TypeScript/issues/55571 + "conditionalTypesSimplifyWhenTrivial", + // https://github.com/microsoft/TypeScript/issues/55571 "reExportAliasMakesInstantiated" ], // Needs TS Fix @@ -306,8 +306,7 @@ "declarationEmitPropertyNumericStringKey", "templateLiteralsSourceMap", // template literal is evaluated in constant value. "nodeModulesImportTypeModeDeclarationEmit1", // resolution-mode in assert from type assertion is preserved - "literalTypesAndTypeAssertions", // (0 | 1) written in code is preserved by dte - ], + "literalTypesAndTypeAssertions" // (0 | 1) written in code is preserved by dte + ] } } - diff --git a/external-declarations/original-tests.jsonc b/external-declarations/original-tests.jsonc index ce0b6c2a99972..ca5b1dbcc128d 100644 --- a/external-declarations/original-tests.jsonc +++ b/external-declarations/original-tests.jsonc @@ -36,18 +36,18 @@ "computedPropertiesNarrowed", // error on used to be indexer, now it is a computed property "propertyAssignment", - "invalidTaggedTemplateEscapeSequences", // Invalid escape sequences + "invalidTaggedTemplateEscapeSequences", // Invalid escape sequences // duplicate field/accessor "symbolDeclarationEmit12" ], "ts-bugs": [ - // https://github.com/microsoft/TypeScript/issues/55571 - "reExportAliasMakesInstantiated" - ], + // https://github.com/microsoft/TypeScript/issues/55571 + "reExportAliasMakesInstantiated" + ], // Just Printing differences "print-differences": [ - "parseBigInt", // number literals are normalized by ts - "templateLiteralsSourceMap", // template literal is evaluated in constant value. + "parseBigInt", // number literals are normalized by ts + "templateLiteralsSourceMap" // template literal is evaluated in constant value. ], "enums-issues": [ // External eval @@ -60,12 +60,12 @@ "verbatimModuleSyntaxConstEnumUsage", "templateLiteralTypes4", "enumConstantMembers", - // merge + // merge "mergedEnumDeclarationCodeGen", "enumExportMergingES6", - "mergedDeclarations2", + "mergedDeclarations2" ], - // Some 9007 errors will result in differences. This is fine. + // Some 9007 errors will result in differences. This is fine. "with-isolated-declaration-errors/9007": [ // computed property differences "complicatedPrivacy", @@ -74,8 +74,7 @@ "overloadsWithComputedNames", "typeUsedAsTypeLiteralIndex", // computed property errors but in type aliases "forwardRefInEnum", // Circular enums result in different values - "enumErrors", + "enumErrors" ] } } - diff --git a/external-declarations/package.json b/external-declarations/package.json index 6b18e1fe3bf1b..3dda5983edc39 100644 --- a/external-declarations/package.json +++ b/external-declarations/package.json @@ -1,32 +1,32 @@ { - "name": "external-declarations", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "build": "node ../built/local/tsc.js -p ./src", - "watch": "node ../built/local/tsc.js -w -p ./src", - "run-tests-parallel": "node ./build/test-runner/parallel-run.js --rootPaths=../tests/cases --libPath=../tests/lib --type=all --shardCount=8 --forceIsolatedDeclarations --outputPath=./tsc-tests/$original --configFile=./original-tests.jsonc", - "run-tests": "node ./build/test-runner/test-runner-main.js --type=all --rootPaths=../tests/cases --outputPath=./tsc-tests/$original --configFile=./original-tests.jsonc", - "transform-tests-parallel": "node ./build/code-mod/tsc-test-fixer/run-test-updater-parallel.js --rootPaths=../tests/cases --shardCount=8", - "transform-tests": "node ./build/code-mod/tsc-test-fixer/run-test-updater.js --rootPaths=../tests/cases", - "run-transformed-tests-parallel": "node ./build/test-runner/parallel-run.js --rootPaths=./tsc-tests/updated-tests --libPath=../tests/lib --type=all --shardCount=8 --outputPath=./tsc-tests/$transformed --configFile=./fixed-tests.jsonc", - "run-transformed-tests": "node ./build/test-runner/test-runner-main.js --type=all --rootPaths=./tsc-tests/updated-tests --libPath=../tests/lib --outputPath=./tsc-tests/$transformed --configFile=./fixed-tests.jsonc", - "fixer-tests": "node ./build/code-mod/fixer-test.js --rootPaths=./fixer-test/source ", - "fixer-tests-update": "node ./build/code-mod/fixer-test.js --rootPaths=./fixer-test/source --update " - }, - "author": "", - "license": "ISC", - "dependencies": { - "json5": "^2.2.3", - "source-map-support": "^0.5.21", - "typescript": "../", - "@types/inquirer": "^8.2.6", - "@types/node": "^20.7.1", - "chalk": "^4.1.2", - "inquirer": "^8.2.6" - }, - "devDependencies": { - "@types/node": "^18.11.18" - } + "name": "external-declarations", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "node ../built/local/tsc.js -p ./src", + "watch": "node ../built/local/tsc.js -w -p ./src", + "run-tests-parallel": "node ./build/test-runner/parallel-run.js --rootPaths=../tests/cases --libPath=../tests/lib --type=all --shardCount=8 --forceIsolatedDeclarations --outputPath=./tsc-tests/$original --configFile=./original-tests.jsonc", + "run-tests": "node ./build/test-runner/test-runner-main.js --type=all --rootPaths=../tests/cases --outputPath=./tsc-tests/$original --configFile=./original-tests.jsonc", + "transform-tests-parallel": "node ./build/code-mod/tsc-test-fixer/run-test-updater-parallel.js --rootPaths=../tests/cases --shardCount=8", + "transform-tests": "node ./build/code-mod/tsc-test-fixer/run-test-updater.js --rootPaths=../tests/cases", + "run-transformed-tests-parallel": "node ./build/test-runner/parallel-run.js --rootPaths=./tsc-tests/updated-tests --libPath=../tests/lib --type=all --shardCount=8 --outputPath=./tsc-tests/$transformed --configFile=./fixed-tests.jsonc", + "run-transformed-tests": "node ./build/test-runner/test-runner-main.js --type=all --rootPaths=./tsc-tests/updated-tests --libPath=../tests/lib --outputPath=./tsc-tests/$transformed --configFile=./fixed-tests.jsonc", + "fixer-tests": "node ./build/code-mod/fixer-test.js --rootPaths=./fixer-test/source ", + "fixer-tests-update": "node ./build/code-mod/fixer-test.js --rootPaths=./fixer-test/source --update " + }, + "author": "", + "license": "ISC", + "dependencies": { + "json5": "^2.2.3", + "source-map-support": "^0.5.21", + "typescript": "../", + "@types/inquirer": "^8.2.6", + "@types/node": "^20.7.1", + "chalk": "^4.1.2", + "inquirer": "^8.2.6" + }, + "devDependencies": { + "@types/node": "^18.11.18" + } } diff --git a/external-declarations/src/code-mod/fixer-test.ts b/external-declarations/src/code-mod/fixer-test.ts index b34b7bbea3952..643c9b94d7d89 100644 --- a/external-declarations/src/code-mod/fixer-test.ts +++ b/external-declarations/src/code-mod/fixer-test.ts @@ -7,7 +7,9 @@ import ts from "typescript"; import { normalizePath, } from "../compiler/path-utils"; -import { TestCaseContent } from "../test-runner/tsc-infrastructure/test-file-parser"; +import { + TestCaseContent, +} from "../test-runner/tsc-infrastructure/test-file-parser"; import { loadTestCase, } from "../test-runner/utils"; @@ -57,11 +59,11 @@ async function main() { const updatedTestFileName = testFile.replace(rootPath, "./fixer-test/expected"); const result = await fixTestCase(caseData, { - target: ts.ScriptTarget.ES2019 + target: ts.ScriptTarget.ES2019, }); - const resultFiles = !(result instanceof Error)? result : [{ - unitName: caseData.testUnitData[0].name, - content: ` + const resultFiles = !(result instanceof Error) ? result : [{ + unitName: caseData.testUnitData[0].name, + content: ` ================= CODE MOD ERROR ============== ${result.message} ${result.stack} @@ -71,21 +73,24 @@ ${result.stack} // ${caseData.code.split("\n").join("\n// ")} `, }]; - await compareTestCase({ - ...caseData, - testUnitData: caseData.testUnitData.map(u => ({ - ...u, - content: resultFiles.find(o => o.unitName === u.name)?.content!, - })), - }, updatedTestFileName, !!parsedArgs.update); + await compareTestCase( + { + ...caseData, + testUnitData: caseData.testUnitData.map(u => ({ + ...u, + content: resultFiles.find(o => o.unitName === u.name)?.content!, + })), + }, + updatedTestFileName, + !!parsedArgs.update, + ); console.log(`Ran: ${count}`); } } -async function compareTestCase(testData: TestCaseContent & { BOM: string }, path: string, update: boolean) { +async function compareTestCase(testData: TestCaseContent & { BOM: string; }, path: string, update: boolean) { const content = await testCaseToString(testData); - const original = - !fsSync.existsSync(path) ? undefined: await fs.readFile(path, "utf-8"); + const original = !fsSync.existsSync(path) ? undefined : await fs.readFile(path, "utf-8"); if (content !== original) { if (!update) { throw new Error(`Expected \n${original}\n for file ${path} but seen \n${content}`); @@ -96,5 +101,4 @@ async function compareTestCase(testData: TestCaseContent & { BOM: string }, path } } - main(); diff --git a/external-declarations/src/code-mod/fixer/isolated-declarations-errors.ts b/external-declarations/src/code-mod/fixer/isolated-declarations-errors.ts index 20f2edfb725f2..e933c29440287 100644 --- a/external-declarations/src/code-mod/fixer/isolated-declarations-errors.ts +++ b/external-declarations/src/code-mod/fixer/isolated-declarations-errors.ts @@ -3,4 +3,5 @@ export const isolatedDeclarationsErrors = new Set([ 9008, 9009, 9010, + 9011, ]); diff --git a/external-declarations/src/code-mod/fixer/utils.ts b/external-declarations/src/code-mod/fixer/utils.ts index d64775dfca587..886105e320dba 100644 --- a/external-declarations/src/code-mod/fixer/utils.ts +++ b/external-declarations/src/code-mod/fixer/utils.ts @@ -1,22 +1,23 @@ import chalk from "chalk"; import * as path from "path"; -import { Diagnostic } from "typescript"; - +import { + Diagnostic, +} from "typescript"; export function printDiagnostics(diag: Diagnostic) { - const pos = getLineColumn(diag) + const pos = getLineColumn(diag); const relative = path.relative(process.cwd(), diag.file?.fileName!); console.log(`${chalk.blueBright(relative)}:${pos.line}:${pos.col} - ${diag.messageText}`); } export function getLineColumn(diag: Diagnostic) { - const text = diag.file?.text! - let line = 1; + const text = diag.file?.text!; + let line = 1; let lineStart = text.lastIndexOf("\n", diag.start); - const col = lineStart === -1 ? diag.start!: diag.start!- lineStart; - while(lineStart > 0) { - line++ + const col = lineStart === -1 ? diag.start! : diag.start! - lineStart; + while (lineStart > 0) { + line++; lineStart = text.lastIndexOf("\n", lineStart - 1); } - return { line, col } -} \ No newline at end of file + return { line, col }; +} diff --git a/external-declarations/src/code-mod/tsc-test-fixer/test-case-utils.ts b/external-declarations/src/code-mod/tsc-test-fixer/test-case-utils.ts index 5d90b49793a7e..dafe58bdacc4a 100644 --- a/external-declarations/src/code-mod/tsc-test-fixer/test-case-utils.ts +++ b/external-declarations/src/code-mod/tsc-test-fixer/test-case-utils.ts @@ -10,7 +10,7 @@ import { } from "../../utils/fs-utils"; export async function writeTestCase(testData: TestCaseContent & { BOM: string; }, path: string) { - await ensureDir(fsPath.dirname(path)) + await ensureDir(fsPath.dirname(path)); await fs.writeFile(path, await testCaseToString(testData)); } export async function testCaseToString(testData: TestCaseContent & { BOM: string; }) { diff --git a/external-declarations/src/compiler/lang-utils.ts b/external-declarations/src/compiler/lang-utils.ts index 68f9f7d1e93d3..77336aacfd812 100644 --- a/external-declarations/src/compiler/lang-utils.ts +++ b/external-declarations/src/compiler/lang-utils.ts @@ -1,8 +1,10 @@ -import { MapLike, SortedArray, SortedReadonlyArray } from "typescript"; - - -export type Mutable = { -readonly [K in keyof T]: T[K] }; +import { + MapLike, + SortedArray, + SortedReadonlyArray, +} from "typescript"; +export type Mutable = { -readonly [K in keyof T]: T[K]; }; /** @internal */ export type EqualityComparer = (a: T, b: T) => boolean; @@ -22,7 +24,6 @@ export function forEach(array: readonly T[] | undefined, callback: (elemen return undefined; } - /** @internal */ export function some(array: readonly T[] | undefined): array is readonly T[]; /** @internal */ @@ -44,18 +45,16 @@ export function some(array: readonly T[] | undefined, predicate?: (value: T) return false; } - /** @internal */ export function stringContains(str: string, substring: string): boolean { return str.indexOf(substring) !== -1; } - - /** - * @return Whether the value was added. - * - * @internal - */ +/** + * @return Whether the value was added. + * + * @internal + */ export function pushIfUnique(array: T[], toAdd: T, equalityComparer?: EqualityComparer): boolean { if (contains(array, toAdd, equalityComparer)) { return false; @@ -78,12 +77,11 @@ export function contains(array: readonly T[] | undefined, value: T, equalityC return false; } - /** @internal */ export const enum Comparison { - LessThan = -1, - EqualTo = 0, - GreaterThan = 1 + LessThan = -1, + EqualTo = 0, + GreaterThan = 1, } export function equateValues(a: T, b: T) { return a === b; @@ -94,7 +92,6 @@ export function length(array: readonly any[] | undefined): number { return array ? array.length : 0; } - /** * Flattens an array containing a mix of array or non-array elements. * @@ -102,7 +99,7 @@ export function length(array: readonly any[] | undefined): number { * * @internal */ - export function flatten(array: T[][] | readonly (T | readonly T[] | undefined)[]): T[] { +export function flatten(array: T[][] | readonly (T | readonly T[] | undefined)[]): T[] { const result: T[] = []; for (const v of array) { if (v) { @@ -117,20 +114,15 @@ export function length(array: readonly any[] | undefined): number { return result; } - - /** * Tests whether a value is an array. * * @internal */ - export function isArray(value: any): value is readonly unknown[] { +export function isArray(value: any): value is readonly unknown[] { return Array.isArray ? Array.isArray(value) : value instanceof Array; } - - - /** * Appends a range of value to an array, returning the array. * @@ -143,22 +135,22 @@ export function length(array: readonly any[] | undefined): number { * * @internal */ - export function addRange(to: T[], from: readonly T[] | undefined, start?: number, end?: number): T[]; - /** @internal */ - export function addRange(to: T[] | undefined, from: readonly T[] | undefined, start?: number, end?: number): T[] | undefined; - /** @internal */ - export function addRange(to: T[] | undefined, from: readonly T[] | undefined, start?: number, end?: number): T[] | undefined { - if (from === undefined || from.length === 0) return to; - if (to === undefined) return from.slice(start, end); - start = start === undefined ? 0 : toOffset(from, start); - end = end === undefined ? from.length : toOffset(from, end); - for (let i = start; i < end && i < from.length; i++) { - if (from[i] !== undefined) { - to.push(from[i]); - } - } - return to; - } +export function addRange(to: T[], from: readonly T[] | undefined, start?: number, end?: number): T[]; +/** @internal */ +export function addRange(to: T[] | undefined, from: readonly T[] | undefined, start?: number, end?: number): T[] | undefined; +/** @internal */ +export function addRange(to: T[] | undefined, from: readonly T[] | undefined, start?: number, end?: number): T[] | undefined { + if (from === undefined || from.length === 0) return to; + if (to === undefined) return from.slice(start, end); + start = start === undefined ? 0 : toOffset(from, start); + end = end === undefined ? from.length : toOffset(from, end); + for (let i = start; i < end && i < from.length; i++) { + if (from[i] !== undefined) { + to.push(from[i]); + } + } + return to; +} /** * Gets the actual offset into an array for a relative offset. Negative offsets indicate a @@ -168,7 +160,6 @@ function toOffset(array: readonly any[], offset: number) { return offset < 0 ? array.length + offset : offset; } - /** @internal */ export function map(array: readonly T[], f: (x: T, i: number) => U): U[]; /** @internal */ @@ -185,46 +176,41 @@ export function map(array: readonly T[] | undefined, f: (x: T, i: number) return result; } - - /** * Compacts an array, removing any falsey elements. * * @internal */ - export function compact(array: (T | undefined | null | false | 0 | "")[]): T[]; - /** @internal */ - export function compact(array: readonly (T | undefined | null | false | 0 | "")[]): readonly T[]; - // ESLint thinks these can be combined with the above - they cannot; they'd produce higher-priority inferences and prevent the falsey types from being stripped - /** @internal */ - export function compact(array: T[]): T[]; // eslint-disable-line @typescript-eslint/unified-signatures - /** @internal */ - export function compact(array: readonly T[]): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures - /** @internal */ - export function compact(array: T[]): T[] { - let result: T[] | undefined; - if (array) { - for (let i = 0; i < array.length; i++) { - const v = array[i]; - if (result || !v) { - if (!result) { - result = array.slice(0, i); - } - if (v) { - result.push(v); - } - } - } - } - return result || array; - } - +export function compact(array: (T | undefined | null | false | 0 | "")[]): T[]; +/** @internal */ +export function compact(array: readonly (T | undefined | null | false | 0 | "")[]): readonly T[]; +// ESLint thinks these can be combined with the above - they cannot; they'd produce higher-priority inferences and prevent the falsey types from being stripped +/** @internal */ +export function compact(array: T[]): T[]; // eslint-disable-line @typescript-eslint/unified-signatures +/** @internal */ +export function compact(array: readonly T[]): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures +/** @internal */ +export function compact(array: T[]): T[] { + let result: T[] | undefined; + if (array) { + for (let i = 0; i < array.length; i++) { + const v = array[i]; + if (result || !v) { + if (!result) { + result = array.slice(0, i); + } + if (v) { + result.push(v); + } + } + } + } + return result || array; +} /** @internal */ export const emptyArray: never[] = [] as never[]; - - /** * Appends a value to an array, returning the array. * @@ -235,22 +221,22 @@ export const emptyArray: never[] = [] as never[]; * * @internal */ - export function append[number] | undefined>(to: TArray, value: TValue): [undefined, undefined] extends [TArray, TValue] ? TArray : NonNullable[number][]; - /** @internal */ - export function append(to: T[], value: T | undefined): T[]; - /** @internal */ - export function append(to: T[] | undefined, value: T): T[]; - /** @internal */ - export function append(to: T[] | undefined, value: T | undefined): T[] | undefined; - /** @internal */ - export function append(to: Push, value: T | undefined): void; - /** @internal */ - export function append(to: T[], value: T | undefined): T[] | undefined { - if (value === undefined) return to; - if (to === undefined) return [value]; - to.push(value); - return to; - } +export function append[number] | undefined>(to: TArray, value: TValue): [undefined, undefined] extends [TArray, TValue] ? TArray : NonNullable[number][]; +/** @internal */ +export function append(to: T[], value: T | undefined): T[]; +/** @internal */ +export function append(to: T[] | undefined, value: T): T[]; +/** @internal */ +export function append(to: T[] | undefined, value: T | undefined): T[] | undefined; +/** @internal */ +export function append(to: Push, value: T | undefined): void; +/** @internal */ +export function append(to: T[], value: T | undefined): T[] | undefined { + if (value === undefined) return to; + if (to === undefined) return [value]; + to.push(value); + return to; +} /** Array that is only intended to be pushed to, never read. */ export interface Push { @@ -258,13 +244,12 @@ export interface Push { /** @internal */ readonly length: number; } - /** * Stable sort of an array. Elements equal to each other maintain their relative position in the array. * * @internal */ - export function stableSort(array: readonly T[], comparer: Comparer): SortedReadonlyArray { +export function stableSort(array: readonly T[], comparer: Comparer): SortedReadonlyArray { const indices = indicesOf(array); stableSortIndices(array, indices, comparer); return indices.map(i => array[i]) as SortedArray as SortedReadonlyArray; @@ -283,28 +268,27 @@ function stableSortIndices(array: readonly T[], indices: number[], comparer: * * @internal */ - export function find(array: readonly T[] | undefined, predicate: (element: T, index: number) => element is U, startIndex?: number): U | undefined; - /** @internal */ - export function find(array: readonly T[] | undefined, predicate: (element: T, index: number) => boolean, startIndex?: number): T | undefined; - /** @internal */ - export function find(array: readonly T[] | undefined, predicate: (element: T, index: number) => boolean, startIndex?: number): T | undefined { - if (array === undefined) return undefined; - for (let i = startIndex ?? 0; i < array.length; i++) { - const value = array[i]; - if (predicate(value, i)) { - return value; - } - } - return undefined; - } - +export function find(array: readonly T[] | undefined, predicate: (element: T, index: number) => element is U, startIndex?: number): U | undefined; +/** @internal */ +export function find(array: readonly T[] | undefined, predicate: (element: T, index: number) => boolean, startIndex?: number): T | undefined; +/** @internal */ +export function find(array: readonly T[] | undefined, predicate: (element: T, index: number) => boolean, startIndex?: number): T | undefined { + if (array === undefined) return undefined; + for (let i = startIndex ?? 0; i < array.length; i++) { + const value = array[i]; + if (predicate(value, i)) { + return value; + } + } + return undefined; +} /** * Returns the last element of an array if non-empty, `undefined` otherwise. * * @internal */ - export function lastOrUndefined(array: readonly T[] | undefined): T | undefined { +export function lastOrUndefined(array: readonly T[] | undefined): T | undefined { return array === undefined || array.length === 0 ? undefined : array[array.length - 1]; } @@ -339,11 +323,11 @@ export function findLastIndex(array: readonly T[] | undefined, predicate: (el * * @internal */ - export function equateStringsCaseInsensitive(a: string, b: string) { +export function equateStringsCaseInsensitive(a: string, b: string) { return a === b || a !== undefined - && b !== undefined - && a.toUpperCase() === b.toUpperCase(); + && b !== undefined + && a.toUpperCase() === b.toUpperCase(); } /** @@ -354,7 +338,7 @@ export function findLastIndex(array: readonly T[] | undefined, predicate: (el * * @internal */ - export function equateStringsCaseSensitive(a: string, b: string) { +export function equateStringsCaseSensitive(a: string, b: string) { return equateValues(a, b); } @@ -378,7 +362,6 @@ export function compareValues(a: number | undefined, b: number | undefined): Com return compareComparableValues(a, b); } - /** * Compare two strings using a case-insensitive ordinal comparison. * @@ -393,7 +376,7 @@ export function compareValues(a: number | undefined, b: number | undefined): Com * * @internal */ - export function compareStringsCaseInsensitive(a: string, b: string) { +export function compareStringsCaseInsensitive(a: string, b: string) { if (a === b) return Comparison.EqualTo; if (a === undefined) return Comparison.LessThan; if (b === undefined) return Comparison.GreaterThan; @@ -414,7 +397,7 @@ export function compareValues(a: number | undefined, b: number | undefined): Com * * @internal */ - export function compareStringsCaseSensitive(a: string | undefined, b: string | undefined): Comparison { +export function compareStringsCaseSensitive(a: string | undefined, b: string | undefined): Comparison { return compareComparableValues(a, b); } @@ -423,7 +406,6 @@ export function getStringComparer(ignoreCase?: boolean) { return ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; } - /** * Iterates through `array` by index and performs the callback on each element of array until the callback * returns a falsey value, then returns false. @@ -431,7 +413,7 @@ export function getStringComparer(ignoreCase?: boolean) { * * @internal */ - export function every(array: readonly T[] | undefined, callback: (element: T, index: number) => boolean): boolean { +export function every(array: readonly T[] | undefined, callback: (element: T, index: number) => boolean): boolean { if (array) { for (let i = 0; i < array.length; i++) { if (!callback(array[i], i)) { @@ -443,7 +425,6 @@ export function getStringComparer(ignoreCase?: boolean) { return true; } - /** @internal */ export function mapDefined(array: readonly T[] | undefined, mapFn: (x: T, i: number) => U | undefined): U[] { const result: U[] = []; @@ -458,30 +439,28 @@ export function mapDefined(array: readonly T[] | undefined, mapFn: (x: T, return result; } - /** * Shims `Array.from`. * * @internal */ - export function arrayFrom(iterator: Iterator | IterableIterator, map: (t: T) => U): U[]; - /** @internal */ - export function arrayFrom(iterator: Iterator | IterableIterator): T[]; - /** @internal */ - export function arrayFrom(iterator: Iterator | IterableIterator, map?: (t: T) => U): (T | U)[] { - const result: (T | U)[] = []; - for (let iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) { - result.push(map ? map(iterResult.value) : iterResult.value); - } - return result; - } +export function arrayFrom(iterator: Iterator | IterableIterator, map: (t: T) => U): U[]; +/** @internal */ +export function arrayFrom(iterator: Iterator | IterableIterator): T[]; +/** @internal */ +export function arrayFrom(iterator: Iterator | IterableIterator, map?: (t: T) => U): (T | U)[] { + const result: (T | U)[] = []; + for (let iterResult = iterator.next(); !iterResult.done; iterResult = iterator.next()) { + result.push(map ? map(iterResult.value) : iterResult.value); + } + return result; +} - /** @internal */ +/** @internal */ export function startsWith(str: string, prefix: string): boolean { return str.lastIndexOf(prefix, 0) === 0; } - /** @internal */ export function endsWith(str: string, suffix: string): boolean { const expectedPos = str.length - suffix.length; @@ -498,33 +477,30 @@ export function tryRemoveSuffix(str: string, suffix: string): string | undefined return endsWith(str, suffix) ? str.slice(0, str.length - suffix.length) : undefined; } - /** * Returns lower case string * * @internal */ - export function toLowerCase(x: string) { +export function toLowerCase(x: string) { return x.toLowerCase(); } - /** * Returns its argument. * * @internal */ - export function identity(x: T) { +export function identity(x: T) { return x; } - /** * Remove an item from an array, moving everything to its right one space left. * * @internal */ - export function orderedRemoveItem(array: T[], item: T): boolean { +export function orderedRemoveItem(array: T[], item: T): boolean { for (let i = 0; i < array.length; i++) { if (array[i] === item) { orderedRemoveItemAt(array, i); @@ -534,13 +510,12 @@ export function tryRemoveSuffix(str: string, suffix: string): string | undefined return false; } - /** * Remove an item by index from an array, moving everything to its right one space left. * * @internal */ - export function orderedRemoveItemAt(array: T[], index: number): void { +export function orderedRemoveItemAt(array: T[], index: number): void { // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`. for (let i = index; i < array.length - 1; i++) { array[i] = array[i + 1]; @@ -571,19 +546,18 @@ const hasOwnProperty = Object.prototype.hasOwnProperty; * * @internal */ -export function hasProperty(map: T, key: K): map is Extract>>; +export function hasProperty(map: T, key: K): map is Extract>>; export function hasProperty(map: MapLike, key: string): boolean; export function hasProperty(map: MapLike, key: string): boolean { return hasOwnProperty.call(map, key); } - /** * Gets the owned, enumerable property keys of a map-like. * * @internal */ - export function getOwnKeys(map: MapLike): string[] { +export function getOwnKeys(map: MapLike): string[] { const keys: string[] = []; for (const key in map) { if (hasOwnProperty.call(map, key)) { @@ -603,13 +577,12 @@ export function tryCast(value: T, test: (value: T) => boolean): T | undefined return value !== undefined && test(value) ? value : undefined; } - /** * Like `forEach`, but suitable for use with numbers and strings (which may be falsy). * * @internal */ - export function firstDefined(array: readonly T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined { +export function firstDefined(array: readonly T[] | undefined, callback: (element: T, index: number) => U | undefined): U | undefined { if (array === undefined) { return undefined; } @@ -628,7 +601,7 @@ export function tryCast(value: T, test: (value: T) => boolean): T | undefined * * @internal */ - export function compareBooleans(a: boolean, b: boolean): Comparison { +export function compareBooleans(a: boolean, b: boolean): Comparison { return compareValues(a ? 1 : 0, b ? 1 : 0); } @@ -637,7 +610,7 @@ export function tryCast(value: T, test: (value: T) => boolean): T | undefined * * @internal */ - export function isString(text: unknown): text is string { +export function isString(text: unknown): text is string { return typeof text === "string"; } /** @internal */ @@ -645,7 +618,6 @@ export function isNumber(x: unknown): x is number { return typeof x === "number"; } - /** * patternOrStrings contains both patterns (containing "*") and regular strings. * Return an exact match if possible, or a pattern match, or undefined. @@ -653,7 +625,7 @@ export function isNumber(x: unknown): x is number { * * @internal */ - export function matchPatternOrExact(patternOrStrings: readonly (string | Pattern)[], candidate: string): string | Pattern | undefined { +export function matchPatternOrExact(patternOrStrings: readonly (string | Pattern)[], candidate: string): string | Pattern | undefined { const patterns: Pattern[] = []; for (const patternOrString of patternOrStrings) { if (patternOrString === candidate) { @@ -673,18 +645,17 @@ export function isNumber(x: unknown): x is number { * * @internal */ - export interface Pattern { +export interface Pattern { prefix: string; suffix: string; } - /** * Return the object corresponding to the best pattern to match `candidate`. * * @internal */ - export function findBestPatternMatch(values: readonly T[], getPattern: (value: T) => Pattern, candidate: string): T | undefined { +export function findBestPatternMatch(values: readonly T[], getPattern: (value: T) => Pattern, candidate: string): T | undefined { let matchedValue: T | undefined; // use length of prefix as betterness criteria let longestMatchPrefixLength = -1; @@ -726,11 +697,10 @@ export function tryParsePattern(pattern: string): string | Pattern | undefined { ? undefined : { prefix: pattern.substr(0, indexOfStar), - suffix: pattern.substr(indexOfStar + 1) + suffix: pattern.substr(indexOfStar + 1), }; } - /** @internal */ export function min(items: readonly [T, ...T[]], compare: Comparer): T; /** @internal */ @@ -775,7 +745,6 @@ export function isNullOrUndefined(x: any): x is null | undefined { return x === undefined || x === null; // eslint-disable-line no-null/no-null } - /** * Performs a binary search, finding the index at which `value` occurs in `array`. * If no such index is found, returns the 2's-complement of first index at which @@ -789,7 +758,7 @@ export function isNullOrUndefined(x: any): x is null | undefined { * * @internal */ - export function binarySearch(array: readonly T[], value: T, keySelector: (v: T) => U, keyComparer: Comparer, offset?: number): number { +export function binarySearch(array: readonly T[], value: T, keySelector: (v: T) => U, keyComparer: Comparer, offset?: number): number { return binarySearchKey(array, keySelector(value), keySelector, keyComparer, offset); } @@ -830,13 +799,12 @@ export function binarySearchKey(array: readonly T[], key: U, keySelector: return ~low; } - /** * Works like Array.prototype.findIndex, returning `-1` if no element satisfying the predicate is found. * * @internal */ - export function findIndex(array: readonly T[] | undefined, predicate: (element: T, index: number) => boolean, startIndex?: number): number { +export function findIndex(array: readonly T[] | undefined, predicate: (element: T, index: number) => boolean, startIndex?: number): number { if (array === undefined) return -1; for (let i = startIndex ?? 0; i < array.length; i++) { if (predicate(array[i], i)) { @@ -846,7 +814,6 @@ export function binarySearchKey(array: readonly T[], key: U, keySelector: return -1; } - /** @internal */ export function clone(object: T): T { const result: any = {}; @@ -857,5 +824,3 @@ export function clone(object: T): T { } return result; } - - diff --git a/external-declarations/src/compiler/path-utils.ts b/external-declarations/src/compiler/path-utils.ts index 67862199dc201..b194bbab5a186 100644 --- a/external-declarations/src/compiler/path-utils.ts +++ b/external-declarations/src/compiler/path-utils.ts @@ -1,8 +1,31 @@ -import { Extension, Path } from "typescript"; - -import { Debug } from "./debug"; -import { compareStringsCaseInsensitive, compareStringsCaseSensitive, compareValues, Comparison, endsWith, equateStringsCaseInsensitive, equateStringsCaseSensitive, getStringComparer, identity, lastOrUndefined, some, startsWith, stringContains, toLowerCase } from "./lang-utils"; -import { CharacterCodes, GetCanonicalFileName } from "./types"; +import { + Extension, + Path, +} from "typescript"; + +import { + Debug, +} from "./debug"; +import { + compareStringsCaseInsensitive, + compareStringsCaseSensitive, + compareValues, + Comparison, + endsWith, + equateStringsCaseInsensitive, + equateStringsCaseSensitive, + getStringComparer, + identity, + lastOrUndefined, + some, + startsWith, + stringContains, + toLowerCase, +} from "./lang-utils"; +import { + CharacterCodes, + GetCanonicalFileName, +} from "./types"; /** * Internally, we represent paths as strings with '/' as the directory separator. @@ -131,8 +154,10 @@ function getEncodedRootLength(path: string): number { // special case interpreted as "the machine from which the URL is being interpreted". const scheme = path.slice(0, schemeEnd); const authority = path.slice(authorityStart, authorityEnd); - if (scheme === "file" && (authority === "" || authority === "localhost") && - isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) { + if ( + scheme === "file" && (authority === "" || authority === "localhost") && + isVolumeCharacter(path.charCodeAt(authorityEnd + 1)) + ) { const volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2); if (volumeSeparatorEnd !== -1) { if (path.charCodeAt(volumeSeparatorEnd) === CharacterCodes.slash) { @@ -577,7 +602,6 @@ export function normalizePath(path: string): string { return normalized && hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(normalized) : normalized; } - /** @internal */ export function toPath(fileName: string, basePath: string | undefined, getCanonicalFileName: (path: string) => string): Path { const nonCanonicalizedPath = isRootedDiskPath(fileName) @@ -787,10 +811,8 @@ export function getRelativePathFromDirectory(fromDirectory: string, to: string, return getPathFromPathComponents(pathComponents); } - //// Path Traversal - /** * Case insensitive file systems have descripencies in how they handle some characters (eg. turkish Upper case I with dot on top - \u0130) * This function is used in places where we want to make file name as a key on these systems @@ -810,7 +832,6 @@ function toFileNameLowerCase(x: string) { x; } - // We convert the file names to lower case as key for file name on case insensitive file system // While doing so we need to handle special characters (eg \u0130) to ensure that we dont convert // it to lower case, fileName with its lowercase form can exist along side it. @@ -835,13 +856,11 @@ function toFileNameLowerCase(x: string) { // a-z, 0-9, \u0131, \u00DF, \, /, ., : and space const fileNameLowerCaseRegExp = /[^\u0130\u0131\u00DFa-z0-9\\/:\-_. ]+/g; - /** @internal */ export function removeExtension(path: string, extension: string): string { return path.substring(0, path.length - extension.length); } - /** @internal */ export function createGetCanonicalFileName(useCaseSensitiveFileNames: boolean): GetCanonicalFileName { return useCaseSensitiveFileNames ? identity : toFileNameLowerCase; @@ -869,11 +888,10 @@ export function isJavaScriptFile(f: string) { || f.endsWith(Extension.Mjs); } - export function getDeclarationExtension(path: string) { return ( - path.endsWith(Extension.Mjs) || path.endsWith(Extension.Mts) ? Extension.Dmts: - path.endsWith(Extension.Cjs) || path.endsWith(Extension.Cts) ? Extension.Dcts: - Extension.Dts + path.endsWith(Extension.Mjs) || path.endsWith(Extension.Mts) ? Extension.Dmts : + path.endsWith(Extension.Cjs) || path.endsWith(Extension.Cts) ? Extension.Dcts : + Extension.Dts ); } diff --git a/external-declarations/src/compiler/perf-tracer.ts b/external-declarations/src/compiler/perf-tracer.ts index 175a04692a1df..7e86fdf8df40b 100644 --- a/external-declarations/src/compiler/perf-tracer.ts +++ b/external-declarations/src/compiler/perf-tracer.ts @@ -6,7 +6,7 @@ export const tracer: { end(name: string): void; }; } = { - current: undefined + current: undefined, }; export function installTracer() { @@ -26,4 +26,4 @@ export function installTracer() { startTimes[name] = undefined; }, }; -} \ No newline at end of file +} diff --git a/external-declarations/src/compiler/utils.ts b/external-declarations/src/compiler/utils.ts index 43f516318838e..c4f4bb50c6990 100644 --- a/external-declarations/src/compiler/utils.ts +++ b/external-declarations/src/compiler/utils.ts @@ -1,7 +1,27 @@ -import { __String, CompilerOptions, Extension, JsxEmit, ModuleKind, NewLineKind, Node, NodeFlags, PrinterOptions, ScriptTarget, sys, TsConfigSourceFile } from "typescript"; - -import { clone, flatten, some } from "./lang-utils"; -import { fileExtensionIs, fileExtensionIsOneOf } from "./path-utils"; +import { + __String, + CompilerOptions, + Extension, + JsxEmit, + ModuleKind, + NewLineKind, + Node, + NodeFlags, + PrinterOptions, + ScriptTarget, + sys, + TsConfigSourceFile, +} from "typescript"; + +import { + clone, + flatten, + some, +} from "./lang-utils"; +import { + fileExtensionIs, + fileExtensionIsOneOf, +} from "./path-utils"; /** @internal */ export function isInJSFile(node: Node | undefined): boolean { @@ -16,19 +36,17 @@ export function getDeclarationEmitExtensionForPath(path: string) { Extension.Dts; } - /** @internal */ export function getOutputExtension(fileName: string, options: CompilerOptions): Extension { return fileExtensionIs(fileName, Extension.Json) ? Extension.Json : - options.jsx === JsxEmit.Preserve && fileExtensionIsOneOf(fileName, [Extension.Jsx, Extension.Tsx]) ? Extension.Jsx : - fileExtensionIsOneOf(fileName, [Extension.Mts, Extension.Mjs]) ? Extension.Mjs : - fileExtensionIsOneOf(fileName, [Extension.Cts, Extension.Cjs]) ? Extension.Cjs : - Extension.Js; + options.jsx === JsxEmit.Preserve && fileExtensionIsOneOf(fileName, [Extension.Jsx, Extension.Tsx]) ? Extension.Jsx : + fileExtensionIsOneOf(fileName, [Extension.Mts, Extension.Mjs]) ? Extension.Mjs : + fileExtensionIsOneOf(fileName, [Extension.Cts, Extension.Cjs]) ? Extension.Cjs : + Extension.Js; } - /** @internal */ -export function getEmitScriptTarget(compilerOptions: {module?: CompilerOptions["module"], target?: CompilerOptions["target"]}) { +export function getEmitScriptTarget(compilerOptions: { module?: CompilerOptions["module"]; target?: CompilerOptions["target"]; }) { return compilerOptions.target || (compilerOptions.module === ModuleKind.Node16 && ScriptTarget.ES2022) || (compilerOptions.module === ModuleKind.NodeNext && ScriptTarget.ESNext) || @@ -45,7 +63,7 @@ const supportedJSExtensionsFlat: readonly Extension[] = flatten(supportedJSExten * @internal */ const supportedTSExtensions: readonly Extension[][] = [[Extension.Ts, Extension.Tsx, Extension.Dts], [Extension.Cts, Extension.Dcts], [Extension.Mts, Extension.Dmts]]; - /** @internal */ +/** @internal */ const supportedTSExtensionsFlat: readonly Extension[] = flatten(supportedTSExtensions); /** @internal */ @@ -64,8 +82,6 @@ export function isDeclarationFileName(fileName: string): boolean { return fileExtensionIsOneOf(fileName, supportedDeclarationExtensions); } - - /** @internal */ export function cloneCompilerOptions(options: CompilerOptions): CompilerOptions { const result = clone(options); @@ -91,6 +107,3 @@ export function getNewLineCharacter(options: CompilerOptions | PrinterOptions, g } return getNewLine ? getNewLine() : sys ? sys.newLine : carriageReturnLineFeed; } - - - diff --git a/external-declarations/src/test-runner/cli-arg-config.ts b/external-declarations/src/test-runner/cli-arg-config.ts index a68f58329c357..17651c43439f6 100644 --- a/external-declarations/src/test-runner/cli-arg-config.ts +++ b/external-declarations/src/test-runner/cli-arg-config.ts @@ -1,4 +1,8 @@ -import { ArgType,parseArgs,parserConfiguration } from "../utils/cli-parser"; +import { + ArgType, + parseArgs, + parserConfiguration, +} from "../utils/cli-parser"; export const testRunnerCLIConfiguration = parserConfiguration({ default: { @@ -19,8 +23,6 @@ export const testRunnerCLIConfiguration = parserConfiguration({ forceIsolatedDeclarations: ArgType.Boolean(), }); - - const { value, printUsageOnErrors } = parseArgs(process.argv.slice(2), testRunnerCLIConfiguration); printUsageOnErrors(); diff --git a/external-declarations/src/test-runner/excluded-ts-tests.ts b/external-declarations/src/test-runner/excluded-ts-tests.ts index 878fc2e5c3eeb..ee3977776acff 100644 --- a/external-declarations/src/test-runner/excluded-ts-tests.ts +++ b/external-declarations/src/test-runner/excluded-ts-tests.ts @@ -18,4 +18,4 @@ export const excludedTsTests = new Set([ // The function is elided because the eval function is merged with eval from libs into a single symbol // We can't reproduce this behavior "parserStrictMode8", -]); \ No newline at end of file +]); diff --git a/external-declarations/src/test-runner/parallel-run.ts b/external-declarations/src/test-runner/parallel-run.ts index 2fac400e2d29c..c1540be7cfa60 100644 --- a/external-declarations/src/test-runner/parallel-run.ts +++ b/external-declarations/src/test-runner/parallel-run.ts @@ -1,27 +1,31 @@ import * as childProcess from "child_process"; import * as path from "path"; -import { parseArgs } from "../utils/cli-parser"; -import { testRunnerCLIConfiguration } from "./cli-arg-config"; +import { + parseArgs, +} from "../utils/cli-parser"; +import { + testRunnerCLIConfiguration, +} from "./cli-arg-config"; interface ExecuteResult { - error: childProcess.ExecException | undefined - stdout: string, - stderr: string, + error: childProcess.ExecException | undefined; + stdout: string; + stderr: string; } function exec(cmd: string, dir: string, onStdOut: (s: string) => void) { - return new Promise((resolve) => { + return new Promise(resolve => { console.log(`In ${dir} Executing: ${cmd}`); - const ls = childProcess.spawn(cmd, [], { + const ls = childProcess.spawn(cmd, [], { cwd: path.resolve(path.join(process.cwd(), dir)), - shell: true + shell: true, }); let stdout = ""; let stderr = ""; - ls.stdout.on("data", (data) => { - if(!onStdOut) { + ls.stdout.on("data", data => { + if (!onStdOut) { process.stdout.write(data.toString()); } else { @@ -30,15 +34,15 @@ function exec(cmd: string, dir: string, onStdOut: (s: string) => void) { stdout += data.toString(); }); - ls.stderr.on("data", (data) => { + ls.stderr.on("data", data => { process.stderr.write(data.toString()); stderr += data.toString(); }); - ls.on("error", (err) => { + ls.on("error", err => { console.log(err); }); - ls.on("exit", (code) => { + ls.on("exit", code => { console.log("exited:" + code?.toString()); resolve({ error: !code ? undefined : Object.assign(new Error(""), { @@ -46,7 +50,7 @@ function exec(cmd: string, dir: string, onStdOut: (s: string) => void) { cmd, }), stderr, - stdout + stdout, }); }); }); @@ -66,7 +70,7 @@ async function main() { const promisees = Array.from({ length: shardCount }).map(async (_, index) => { await exec(commandLine + ` --shard=${index}`, "./", out => { runCount += (out.match(/Ran:/g) || []).length; - if(new Date().getTime() - lastWrite > 2000) { + if (new Date().getTime() - lastWrite > 2000) { lastWrite = new Date().getTime(); console.log(`Run count: ${runCount} after ${elapsedTime(lastWrite)}`); } diff --git a/external-declarations/src/test-runner/tsc-infrastructure/collections.ts b/external-declarations/src/test-runner/tsc-infrastructure/collections.ts index 8adffb7804207..658eb1d3358df 100644 --- a/external-declarations/src/test-runner/tsc-infrastructure/collections.ts +++ b/external-declarations/src/test-runner/tsc-infrastructure/collections.ts @@ -51,9 +51,9 @@ export class SortedMap { return index >= 0 ? this._values[index] : undefined; } - public getEntry(key: K): [ K, V ] | undefined { + public getEntry(key: K): [K, V] | undefined { const index = ts.binarySearch(this._keys, key, ts.identity, this._comparer); - return index >= 0 ? [ this._keys[index], this._values[index] ] : undefined; + return index >= 0 ? [this._keys[index], this._values[index]] : undefined; } public set(key: K, value: V) { @@ -119,7 +119,7 @@ export class SortedMap { } } - public * keys() { + public *keys() { const keys = this._keys; const indices = this.getIterationOrder(); const version = this._version; @@ -141,7 +141,7 @@ export class SortedMap { } } - public * values() { + public *values() { const values = this._values; const indices = this.getIterationOrder(); const version = this._version; @@ -163,7 +163,7 @@ export class SortedMap { } } - public * entries() { + public *entries() { const keys = this._keys; const values = this._values; const indices = this.getIterationOrder(); @@ -251,7 +251,7 @@ export function closeIterator(iterator: Iterator) { export class Metadata { private static readonly _undefinedValue = {}; private _parent: Metadata | undefined; - private _map: { [key: string]: any }; + private _map: { [key: string]: any; }; private _version = 0; private _size = -1; private _parentVersion: number | undefined; diff --git a/external-declarations/src/test-runner/tsc-infrastructure/fakesHosts.ts b/external-declarations/src/test-runner/tsc-infrastructure/fakesHosts.ts index 7eb2dedda4f48..9ed2adec6e71e 100644 --- a/external-declarations/src/test-runner/tsc-infrastructure/fakesHosts.ts +++ b/external-declarations/src/test-runner/tsc-infrastructure/fakesHosts.ts @@ -1,235 +1,238 @@ import * as ts from "typescript"; -import { getNewLineCharacter } from "../../compiler/utils"; +import { + getNewLineCharacter, +} from "../../compiler/utils"; import * as collections from "./collections"; -import { Utils } from "./compiler-run"; +import { + Utils, +} from "./compiler-run"; import * as documents from "./test-document"; import * as vfs from "./vfs"; import * as vpath from "./vpath"; - /** * Fake implementations of various compiler dependencies. */ - const processExitSentinel = new Error("System exit"); - - export interface SystemOptions { - executingFilePath?: string; - newLine?: "\r\n" | "\n"; - env?: Record; - } - - /** - * A fake `ts.System` that leverages a virtual file system. - */ - export class System implements ts.System { - public readonly vfs: vfs.FileSystem; - public readonly args: string[] = []; - public readonly output: string[] = []; - public readonly newLine: string; - public readonly useCaseSensitiveFileNames: boolean; - public exitCode: number | undefined; - - private readonly _executingFilePath: string | undefined; - private readonly _env: Record | undefined; - - constructor(vfs: vfs.FileSystem, { executingFilePath, newLine = "\r\n", env }: SystemOptions = {}) { - this.vfs = vfs.isReadonly ? vfs.shadow() : vfs; - this.useCaseSensitiveFileNames = !this.vfs.ignoreCase; - this.newLine = newLine; - this._executingFilePath = executingFilePath; - this._env = env; - } - - private testTerminalWidth = Number.parseInt(this.getEnvironmentVariable("TS_TEST_TERMINAL_WIDTH")); - getWidthOfTerminal = Number.isNaN(this.testTerminalWidth) ? undefined : () => this.testTerminalWidth; - - // Pretty output - writeOutputIsTTY() { - return true; - } - - public write(message: string) { - console.log(message); - this.output.push(message); - } - - public readFile(path: string) { - try { - const content = this.vfs.readFileSync(path, "utf8"); - return content === undefined ? undefined : Utils.removeByteOrderMark(content); - } - catch { - return undefined; - } - } - - public writeFile(path: string, data: string, writeByteOrderMark?: boolean): void { - this.vfs.mkdirpSync(vpath.dirname(path)); - this.vfs.writeFileSync(path, writeByteOrderMark ? Utils.addUTF8ByteOrderMark(data) : data); - } - - public deleteFile(path: string) { - this.vfs.unlinkSync(path); - } - - public fileExists(path: string) { - const stats = this._getStats(path); - return stats ? stats.isFile() : false; - } - - public directoryExists(path: string) { - const stats = this._getStats(path); - return stats ? stats.isDirectory() : false; - } - - public createDirectory(path: string): void { - this.vfs.mkdirpSync(path); - } - - public getCurrentDirectory() { - return this.vfs.cwd(); - } - - public getDirectories(path: string) { - const result: string[] = []; - try { - for (const file of this.vfs.readdirSync(path)) { - if (this.vfs.statSync(vpath.combine(path, file)).isDirectory()) { - result.push(file); - } - } - } - catch { /*ignore*/ } - return result; - } - - public readDirectory(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[] { +const processExitSentinel = new Error("System exit"); + +export interface SystemOptions { + executingFilePath?: string; + newLine?: "\r\n" | "\n"; + env?: Record; +} + +/** + * A fake `ts.System` that leverages a virtual file system. + */ +export class System implements ts.System { + public readonly vfs: vfs.FileSystem; + public readonly args: string[] = []; + public readonly output: string[] = []; + public readonly newLine: string; + public readonly useCaseSensitiveFileNames: boolean; + public exitCode: number | undefined; + + private readonly _executingFilePath: string | undefined; + private readonly _env: Record | undefined; + + constructor(vfs: vfs.FileSystem, { executingFilePath, newLine = "\r\n", env }: SystemOptions = {}) { + this.vfs = vfs.isReadonly ? vfs.shadow() : vfs; + this.useCaseSensitiveFileNames = !this.vfs.ignoreCase; + this.newLine = newLine; + this._executingFilePath = executingFilePath; + this._env = env; + } + + private testTerminalWidth = Number.parseInt(this.getEnvironmentVariable("TS_TEST_TERMINAL_WIDTH")); + getWidthOfTerminal = Number.isNaN(this.testTerminalWidth) ? undefined : () => this.testTerminalWidth; + + // Pretty output + writeOutputIsTTY() { + return true; + } + + public write(message: string) { + console.log(message); + this.output.push(message); + } + + public readFile(path: string) { + try { + const content = this.vfs.readFileSync(path, "utf8"); + return content === undefined ? undefined : Utils.removeByteOrderMark(content); + } + catch { + return undefined; + } + } + + public writeFile(path: string, data: string, writeByteOrderMark?: boolean): void { + this.vfs.mkdirpSync(vpath.dirname(path)); + this.vfs.writeFileSync(path, writeByteOrderMark ? Utils.addUTF8ByteOrderMark(data) : data); + } + + public deleteFile(path: string) { + this.vfs.unlinkSync(path); + } + + public fileExists(path: string) { + const stats = this._getStats(path); + return stats ? stats.isFile() : false; + } + + public directoryExists(path: string) { + const stats = this._getStats(path); + return stats ? stats.isDirectory() : false; + } + + public createDirectory(path: string): void { + this.vfs.mkdirpSync(path); + } + + public getCurrentDirectory() { + return this.vfs.cwd(); + } + + public getDirectories(path: string) { + const result: string[] = []; + try { + for (const file of this.vfs.readdirSync(path)) { + if (this.vfs.statSync(vpath.combine(path, file)).isDirectory()) { + result.push(file); + } + } + } + catch { /*ignore*/ } + return result; + } + + public readDirectory(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[] { throw new Error("Not implemented"); // return matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, path => this.getAccessibleFileSystemEntries(path), path => this.realpath(path)); - } - - public getAccessibleFileSystemEntries(path: string): vfs.FileSystemEntries { - const files: string[] = []; - const directories: string[] = []; - try { - for (const file of this.vfs.readdirSync(path)) { - try { - const stats = this.vfs.statSync(vpath.combine(path, file)); - if (stats.isFile()) { - files.push(file); - } - else if (stats.isDirectory()) { - directories.push(file); - } - } - catch { /*ignored*/ } - } - } - catch { /*ignored*/ } - return { files, directories }; - } - - public exit(exitCode?: number) { - this.exitCode = exitCode; - throw processExitSentinel; - } - - public getFileSize(path: string) { - const stats = this._getStats(path); - return stats && stats.isFile() ? stats.size : 0; - } - - public resolvePath(path: string) { - return vpath.resolve(this.vfs.cwd(), path); - } - - public getExecutingFilePath() { - if (this._executingFilePath === undefined) throw new Error("ts.notImplemented"); - return this._executingFilePath; - } - - public getModifiedTime(path: string) { - const stats = this._getStats(path); - return stats ? stats.mtime : undefined!; // TODO: GH#18217 - } - - public setModifiedTime(path: string, time: Date) { - this.vfs.utimesSync(path, time, time); - } - - public createHash(data: string): string { - return `${generateDjb2Hash(data)}-${data}`; - } - - public realpath(path: string) { - try { - return this.vfs.realpathSync(path); - } - catch { - return path; - } - } - - public getEnvironmentVariable(name: string): string { - return (this._env && this._env[name])!; // TODO: GH#18217 - } - - private _getStats(path: string) { - try { - return this.vfs.existsSync(path) ? this.vfs.statSync(path) : undefined; - } - catch { - return undefined; - } - } - - now() { - return new Date(this.vfs.time()); - } - } - - /** - * A fake `ts.ParseConfigHost` that leverages a virtual file system. - */ - export class ParseConfigHost implements ts.ParseConfigHost { - public readonly sys: System; - - constructor(sys: System | vfs.FileSystem) { - if (sys instanceof vfs.FileSystem) sys = new System(sys); - this.sys = sys; - } - - public get vfs() { - return this.sys.vfs; - } - - public get useCaseSensitiveFileNames() { - return this.sys.useCaseSensitiveFileNames; - } - - public fileExists(fileName: string): boolean { - return this.sys.fileExists(fileName); - } - - public directoryExists(directoryName: string): boolean { - return this.sys.directoryExists(directoryName); - } - - public readFile(path: string): string | undefined { - return this.sys.readFile(path); - } - - public readDirectory(path: string, extensions: string[], excludes: string[], includes: string[], depth: number): string[] { - return this.sys.readDirectory(path, extensions, excludes, includes, depth); - } - } + } + + public getAccessibleFileSystemEntries(path: string): vfs.FileSystemEntries { + const files: string[] = []; + const directories: string[] = []; + try { + for (const file of this.vfs.readdirSync(path)) { + try { + const stats = this.vfs.statSync(vpath.combine(path, file)); + if (stats.isFile()) { + files.push(file); + } + else if (stats.isDirectory()) { + directories.push(file); + } + } + catch { /*ignored*/ } + } + } + catch { /*ignored*/ } + return { files, directories }; + } + + public exit(exitCode?: number) { + this.exitCode = exitCode; + throw processExitSentinel; + } + + public getFileSize(path: string) { + const stats = this._getStats(path); + return stats && stats.isFile() ? stats.size : 0; + } + + public resolvePath(path: string) { + return vpath.resolve(this.vfs.cwd(), path); + } + + public getExecutingFilePath() { + if (this._executingFilePath === undefined) throw new Error("ts.notImplemented"); + return this._executingFilePath; + } + + public getModifiedTime(path: string) { + const stats = this._getStats(path); + return stats ? stats.mtime : undefined!; // TODO: GH#18217 + } + + public setModifiedTime(path: string, time: Date) { + this.vfs.utimesSync(path, time, time); + } + + public createHash(data: string): string { + return `${generateDjb2Hash(data)}-${data}`; + } + + public realpath(path: string) { + try { + return this.vfs.realpathSync(path); + } + catch { + return path; + } + } + + public getEnvironmentVariable(name: string): string { + return (this._env && this._env[name])!; // TODO: GH#18217 + } + + private _getStats(path: string) { + try { + return this.vfs.existsSync(path) ? this.vfs.statSync(path) : undefined; + } + catch { + return undefined; + } + } + + now() { + return new Date(this.vfs.time()); + } +} + +/** + * A fake `ts.ParseConfigHost` that leverages a virtual file system. + */ +export class ParseConfigHost implements ts.ParseConfigHost { + public readonly sys: System; + + constructor(sys: System | vfs.FileSystem) { + if (sys instanceof vfs.FileSystem) sys = new System(sys); + this.sys = sys; + } + + public get vfs() { + return this.sys.vfs; + } + + public get useCaseSensitiveFileNames() { + return this.sys.useCaseSensitiveFileNames; + } + + public fileExists(fileName: string): boolean { + return this.sys.fileExists(fileName); + } + + public directoryExists(directoryName: string): boolean { + return this.sys.directoryExists(directoryName); + } + + public readFile(path: string): string | undefined { + return this.sys.readFile(path); + } + + public readDirectory(path: string, extensions: string[], excludes: string[], includes: string[], depth: number): string[] { + return this.sys.readDirectory(path, extensions, excludes, includes, depth); + } +} /** * A fake `ts.CompilerHost` that leverages a virtual file system. */ - export class CompilerHost implements ts.CompilerHost { +export class CompilerHost implements ts.CompilerHost { public readonly sys: System; public readonly defaultLibLocation: string; public readonly outputs: documents.TextDocument[] = []; @@ -374,9 +377,11 @@ import * as vpath from "./vpath"; while (fs.shadowRoot) { try { const shadowRootStats = fs.shadowRoot.existsSync(canonicalFileName) ? fs.shadowRoot.statSync(canonicalFileName) : undefined!; // TODO: GH#18217 - if (shadowRootStats.dev !== stats.dev || + if ( + shadowRootStats.dev !== stats.dev || shadowRootStats.ino !== stats.ino || - shadowRootStats.mtimeMs !== stats.mtimeMs) { + shadowRootStats.mtimeMs !== stats.mtimeMs + ) { break; } @@ -401,7 +406,7 @@ import * as vpath from "./vpath"; * * @internal */ - export function generateDjb2Hash(data: string): string { +export function generateDjb2Hash(data: string): string { let acc = 5381; for (let i = 0; i < data.length; i++) { acc = ((acc << 5) + acc) + data.charCodeAt(i); diff --git a/external-declarations/src/test-runner/tsc-infrastructure/io.ts b/external-declarations/src/test-runner/tsc-infrastructure/io.ts index 2cdda290ccb4c..8e23ded2d7381 100644 --- a/external-declarations/src/test-runner/tsc-infrastructure/io.ts +++ b/external-declarations/src/test-runner/tsc-infrastructure/io.ts @@ -1,7 +1,14 @@ -import { sys } from "typescript"; - -import { compareStringsCaseInsensitive,compareStringsCaseSensitive } from "../../compiler/lang-utils"; -import { FileSystemEntries } from "./vfs"; +import { + sys, +} from "typescript"; + +import { + compareStringsCaseInsensitive, + compareStringsCaseSensitive, +} from "../../compiler/lang-utils"; +import { + FileSystemEntries, +} from "./vfs"; import * as vpath from "./vpath"; export interface IO { @@ -18,7 +25,7 @@ export interface IO { fileExists(fileName: string): boolean; directoryExists(path: string): boolean; deleteFile(fileName: string): void; - listFiles(path: string, filter?: RegExp, options?: { recursive?: boolean }): string[]; + listFiles(path: string, filter?: RegExp, options?: { recursive?: boolean; }): string[]; log(text: string): void; args(): string[]; getExecutingFilePath(): string; @@ -29,7 +36,7 @@ export interface IO { tryEnableSourceMapsForHost?(): void; getEnvironmentVariable?(name: string): string; getMemoryUsage?(): number | undefined; - joinPath(...components: string[]): string + joinPath(...components: string[]): string; } // harness always uses one kind of new line @@ -65,7 +72,7 @@ function createNodeIO(): IO { return pathModule.join(...components); } - function listFiles(path: string, spec: RegExp, options: { recursive?: boolean } = {}) { + function listFiles(path: string, spec: RegExp, options: { recursive?: boolean; } = {}) { function filesInFolder(folder: string): string[] { let paths: string[] = []; @@ -151,14 +158,15 @@ function createNodeIO(): IO { exit: exitCode => sys.exit(exitCode), readDirectory: (path, extension, exclude, include, depth) => sys.readDirectory(path, extension, exclude, include, depth), getAccessibleFileSystemEntries, - tryEnableSourceMapsForHost: () => { throw new Error("Not supported");}, + tryEnableSourceMapsForHost: () => { + throw new Error("Not supported"); + }, getMemoryUsage: () => sys.getMemoryUsage && sys.getMemoryUsage(), getEnvironmentVariable(name: string) { return process.env[name] || ""; }, - joinPath + joinPath, }; } - export const IO = createNodeIO(); diff --git a/external-declarations/src/test-runner/tsc-infrastructure/options.ts b/external-declarations/src/test-runner/tsc-infrastructure/options.ts index 4427c9ee8a738..43ac31fe4c433 100644 --- a/external-declarations/src/test-runner/tsc-infrastructure/options.ts +++ b/external-declarations/src/test-runner/tsc-infrastructure/options.ts @@ -1,10 +1,31 @@ - // Watch related options -import { CompilerOptionsValue, Diagnostic,DiagnosticMessage, ImportsNotUsedAsValues, JsxEmit, ModuleDetectionKind, ModuleKind, ModuleResolutionKind, NewLineKind, PollingWatchKind, ScriptTarget, WatchDirectoryKind, WatchFileKind } from "typescript"; +import { + CompilerOptionsValue, + Diagnostic, + DiagnosticMessage, + ImportsNotUsedAsValues, + JsxEmit, + ModuleDetectionKind, + ModuleKind, + ModuleResolutionKind, + NewLineKind, + PollingWatchKind, + ScriptTarget, + WatchDirectoryKind, + WatchFileKind, +} from "typescript"; -import { getEntries, isNullOrUndefined, mapDefined, startsWith, trimString } from "../../compiler/lang-utils"; -import { Diagnostics } from "./diagnosticInformationMap.generated"; +import { + getEntries, + isNullOrUndefined, + mapDefined, + startsWith, + trimString, +} from "../../compiler/lang-utils"; +import { + Diagnostics, +} from "./diagnosticInformationMap.generated"; const jsxOptionMap = new Map(getEntries({ "preserve": JsxEmit.Preserve, @@ -14,7 +35,6 @@ const jsxOptionMap = new Map(getEntries({ "react-jsxdev": JsxEmit.ReactJSXDev, })); - // NOTE: The order here is important to default lib ordering as entries will have the same // order in the generated program (see `getDefaultLibPriority` in program.ts). This // order also affects overload resolution when a type declared in one lib is @@ -91,7 +111,7 @@ const libEntries: [string, string][] = [ ["esnext.bigint", "lib.es2020.bigint.d.ts"], ["esnext.string", "lib.es2022.string.d.ts"], ["esnext.promise", "lib.es2021.promise.d.ts"], - ["esnext.weakref", "lib.es2021.weakref.d.ts"] + ["esnext.weakref", "lib.es2021.weakref.d.ts"], ]; /** @@ -111,7 +131,6 @@ export const libs = libEntries.map(entry => entry[0]); */ export const libMap = new Map(libEntries); - /** @internal */ export const optionsForWatch = [ { @@ -278,7 +297,7 @@ export const commonOptionsWithBuild = [ paramType: Diagnostics.FILE_OR_DIRECTORY, category: Diagnostics.Compiler_Diagnostics, description: Diagnostics.Emit_a_v8_CPU_profile_of_the_compiler_run_for_debugging, - defaultValueDescription: "profile.cpuprofile" + defaultValueDescription: "profile.cpuprofile", }, { name: "generateTrace", @@ -287,7 +306,7 @@ export const commonOptionsWithBuild = [ isCommandLineOnly: true, paramType: Diagnostics.DIRECTORY, category: Diagnostics.Compiler_Diagnostics, - description: Diagnostics.Generates_an_event_trace_and_a_list_of_types + description: Diagnostics.Generates_an_event_trace_and_a_list_of_types, }, { name: "incremental", @@ -296,7 +315,7 @@ export const commonOptionsWithBuild = [ category: Diagnostics.Projects, description: Diagnostics.Save_tsbuildinfo_files_to_allow_for_incremental_compilation_of_projects, transpileOptionValue: undefined, - defaultValueDescription: Diagnostics.false_unless_composite_is_set + defaultValueDescription: Diagnostics.false_unless_composite_is_set, }, { name: "declaration", @@ -319,7 +338,7 @@ export const commonOptionsWithBuild = [ category: Diagnostics.Emit, transpileOptionValue: undefined, defaultValueDescription: false, - description: Diagnostics.Create_sourcemaps_for_d_ts_files + description: Diagnostics.Create_sourcemaps_for_d_ts_files, }, { name: "emitDeclarationOnly", @@ -367,7 +386,7 @@ export const commonOptionsWithBuild = [ category: Diagnostics.Command_line_Options, isCommandLineOnly: true, description: Diagnostics.Set_the_language_of_the_messaging_from_TypeScript_This_does_not_affect_emit, - defaultValueDescription: Diagnostics.Platform_specific + defaultValueDescription: Diagnostics.Platform_specific, }, ] as const; @@ -507,7 +526,7 @@ const commandOptionsWithoutBuild = [ showInSimplifiedHelpView: true, category: Diagnostics.Language_and_Environment, description: Diagnostics.Specify_a_set_of_bundled_library_declaration_files_that_describe_the_target_runtime_environment, - transpileOptionValue: undefined + transpileOptionValue: undefined, }, { name: "allowJs", @@ -574,7 +593,7 @@ const commandOptionsWithoutBuild = [ paramType: Diagnostics.LOCATION, category: Diagnostics.Modules, description: Diagnostics.Specify_the_root_folder_within_your_source_files, - defaultValueDescription: Diagnostics.Computed_from_the_list_of_input_files + defaultValueDescription: Diagnostics.Computed_from_the_list_of_input_files, }, { name: "composite", @@ -689,7 +708,7 @@ const commandOptionsWithoutBuild = [ strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Enable_error_reporting_for_expressions_and_declarations_with_an_implied_any_type, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, }, { name: "strictNullChecks", @@ -699,7 +718,7 @@ const commandOptionsWithoutBuild = [ strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.When_type_checking_take_into_account_null_and_undefined, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, }, { name: "strictFunctionTypes", @@ -709,7 +728,7 @@ const commandOptionsWithoutBuild = [ strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.When_assigning_functions_check_to_ensure_parameters_and_the_return_values_are_subtype_compatible, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, }, { name: "strictBindCallApply", @@ -719,7 +738,7 @@ const commandOptionsWithoutBuild = [ strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Check_that_the_arguments_for_bind_call_and_apply_methods_match_the_original_function, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, }, { name: "strictPropertyInitialization", @@ -729,7 +748,7 @@ const commandOptionsWithoutBuild = [ strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Check_for_class_properties_that_are_declared_but_not_set_in_the_constructor, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, }, { name: "noImplicitThis", @@ -739,7 +758,7 @@ const commandOptionsWithoutBuild = [ strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Enable_error_reporting_when_this_is_given_the_type_any, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, }, { name: "useUnknownInCatchVariables", @@ -760,7 +779,7 @@ const commandOptionsWithoutBuild = [ strictFlag: true, category: Diagnostics.Type_Checking, description: Diagnostics.Ensure_use_strict_is_always_emitted, - defaultValueDescription: Diagnostics.false_unless_strict_is_set + defaultValueDescription: Diagnostics.false_unless_strict_is_set, }, // Additional Checks @@ -852,7 +871,7 @@ const commandOptionsWithoutBuild = [ paramType: Diagnostics.STRATEGY, category: Diagnostics.Modules, description: Diagnostics.Specify_how_TypeScript_looks_up_a_file_from_a_given_module_specifier, - defaultValueDescription: Diagnostics.module_AMD_or_UMD_or_System_or_ES6_then_Classic_Otherwise_Node + defaultValueDescription: Diagnostics.module_AMD_or_UMD_or_System_or_ES6_then_Classic_Otherwise_Node, }, { name: "baseUrl", @@ -860,7 +879,7 @@ const commandOptionsWithoutBuild = [ affectsModuleResolution: true, isFilePath: true, category: Diagnostics.Modules, - description: Diagnostics.Specify_the_base_directory_to_resolve_non_relative_module_names + description: Diagnostics.Specify_the_base_directory_to_resolve_non_relative_module_names, }, { // this option can only be specified in tsconfig.json @@ -871,7 +890,7 @@ const commandOptionsWithoutBuild = [ isTSConfigOnly: true, category: Diagnostics.Modules, description: Diagnostics.Specify_a_set_of_entries_that_re_map_imports_to_additional_lookup_locations, - transpileOptionValue: undefined + transpileOptionValue: undefined, }, { // this option can only be specified in tsconfig.json @@ -882,13 +901,13 @@ const commandOptionsWithoutBuild = [ element: { name: "rootDirs", type: "string", - isFilePath: true + isFilePath: true, }, affectsModuleResolution: true, category: Diagnostics.Modules, description: Diagnostics.Allow_multiple_folders_to_be_treated_as_one_when_resolving_modules, transpileOptionValue: undefined, - defaultValueDescription: Diagnostics.Computed_from_the_list_of_input_files + defaultValueDescription: Diagnostics.Computed_from_the_list_of_input_files, }, { name: "typeRoots", @@ -896,24 +915,24 @@ const commandOptionsWithoutBuild = [ element: { name: "typeRoots", type: "string", - isFilePath: true + isFilePath: true, }, affectsModuleResolution: true, category: Diagnostics.Modules, - description: Diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types + description: Diagnostics.Specify_multiple_folders_that_act_like_Slashnode_modules_Slash_types, }, { name: "types", type: "list", element: { name: "types", - type: "string" + type: "string", }, affectsProgramStructure: true, showInSimplifiedHelpView: true, category: Diagnostics.Modules, description: Diagnostics.Specify_type_package_names_to_be_included_without_being_referenced_in_a_source_file, - transpileOptionValue: undefined + transpileOptionValue: undefined, }, { name: "allowSyntheticDefaultImports", @@ -922,7 +941,7 @@ const commandOptionsWithoutBuild = [ affectsBuildInfo: true, category: Diagnostics.Interop_Constraints, description: Diagnostics.Allow_import_x_from_y_when_a_module_doesn_t_have_a_default_export, - defaultValueDescription: Diagnostics.module_system_or_esModuleInterop + defaultValueDescription: Diagnostics.module_system_or_esModuleInterop, }, { name: "esModuleInterop", @@ -1020,7 +1039,7 @@ const commandOptionsWithoutBuild = [ type: "string", category: Diagnostics.Language_and_Environment, description: Diagnostics.Specify_the_JSX_factory_function_used_when_targeting_React_JSX_emit_e_g_React_createElement_or_h, - defaultValueDescription: "`React.createElement`" + defaultValueDescription: "`React.createElement`", }, { name: "jsxFragmentFactory", @@ -1038,7 +1057,7 @@ const commandOptionsWithoutBuild = [ affectsModuleResolution: true, category: Diagnostics.Language_and_Environment, description: Diagnostics.Specify_module_specifier_used_to_import_the_JSX_factory_functions_when_using_jsx_Colon_react_jsx_Asterisk, - defaultValueDescription: "react" + defaultValueDescription: "react", }, { name: "resolveJsonModule", @@ -1085,7 +1104,7 @@ const commandOptionsWithoutBuild = [ type: "string", category: Diagnostics.Backwards_Compatibility, description: Diagnostics.No_longer_supported_In_early_versions_manually_set_the_text_encoding_for_reading_files, - defaultValueDescription: "utf8" + defaultValueDescription: "utf8", }, { name: "emitBOM", @@ -1100,14 +1119,14 @@ const commandOptionsWithoutBuild = [ name: "newLine", type: new Map(getEntries({ crlf: NewLineKind.CarriageReturnLineFeed, - lf: NewLineKind.LineFeed + lf: NewLineKind.LineFeed, })), affectsEmit: true, affectsBuildInfo: true, paramType: Diagnostics.NEWLINE, category: Diagnostics.Emit, description: Diagnostics.Set_the_newline_character_for_emitting_files, - defaultValueDescription: Diagnostics.Platform_specific + defaultValueDescription: Diagnostics.Platform_specific, }, { name: "noErrorTruncation", @@ -1310,7 +1329,7 @@ const commandOptionsWithoutBuild = [ affectsBuildInfo: true, category: Diagnostics.Language_and_Environment, description: Diagnostics.Emit_ECMAScript_standard_compliant_class_fields, - defaultValueDescription: Diagnostics.true_for_ES2022_and_above_including_ESNext + defaultValueDescription: Diagnostics.true_for_ES2022_and_above_including_ESNext, }, { name: "preserveValueImports", @@ -1336,11 +1355,10 @@ const commandOptionsWithoutBuild = [ isTSConfigOnly: true, element: { name: "plugin", - type: "object" + type: "object", }, description: Diagnostics.Specify_a_list_of_language_service_plugins_to_include, category: Diagnostics.Editor_Support, - }, { name: "moduleDetection", @@ -1353,7 +1371,7 @@ const commandOptionsWithoutBuild = [ description: Diagnostics.Control_what_method_is_used_to_detect_module_format_JS_files, category: Diagnostics.Language_and_Environment, defaultValueDescription: Diagnostics.auto_Colon_Treat_files_with_imports_exports_import_meta_jsx_with_jsx_Colon_react_jsx_or_esm_format_with_module_Colon_node16_as_modules, - } + }, ] as const; /** @internal */ @@ -1362,10 +1380,8 @@ export const optionDeclarations = [ ...commandOptionsWithoutBuild, ]; - export type CommandLineOption = CommandLineOptionOfCustomType | CommandLineOptionOfStringType | CommandLineOptionOfNumberType | CommandLineOptionOfBooleanType | TsConfigOnlyOption | CommandLineOptionOfListType; - /** @internal */ export interface CommandLineOptionOfStringType extends CommandLineOptionBase { type: "string"; @@ -1386,11 +1402,10 @@ export interface CommandLineOptionOfBooleanType extends CommandLineOptionBase { /** @internal */ export interface CommandLineOptionOfCustomType extends CommandLineOptionBase { - type: Map; // an object literal mapping named values to actual values + type: Map; // an object literal mapping named values to actual values defaultValueDescription: number | string | undefined | DiagnosticMessage; } - /** @internal */ export interface TsConfigOnlyOption extends CommandLineOptionBase { type: "object"; @@ -1404,34 +1419,31 @@ export interface CommandLineOptionOfListType extends CommandLineOptionBase { listPreserveFalsyValues?: boolean; } - /** @internal */ export interface CommandLineOptionBase { name: string; - type: "string" | "number" | "boolean" | "object" | "list" | Map; // a value of a primitive type, or an object literal mapping named values to actual values - isFilePath?: boolean; // True if option value is a path or fileName - shortName?: string; // A short mnemonic for convenience - for instance, 'h' can be used in place of 'help' - description?: DiagnosticMessage; // The message describing what the command line switch does. - defaultValueDescription?: string | number | boolean | DiagnosticMessage; // The message describing what the dafault value is. string type is prepared for fixed chosen like "false" which do not need I18n. - paramType?: DiagnosticMessage; // The name to be used for a non-boolean option's parameter - isTSConfigOnly?: boolean; // True if option can only be specified via tsconfig.json file + type: "string" | "number" | "boolean" | "object" | "list" | Map; // a value of a primitive type, or an object literal mapping named values to actual values + isFilePath?: boolean; // True if option value is a path or fileName + shortName?: string; // A short mnemonic for convenience - for instance, 'h' can be used in place of 'help' + description?: DiagnosticMessage; // The message describing what the command line switch does. + defaultValueDescription?: string | number | boolean | DiagnosticMessage; // The message describing what the dafault value is. string type is prepared for fixed chosen like "false" which do not need I18n. + paramType?: DiagnosticMessage; // The name to be used for a non-boolean option's parameter + isTSConfigOnly?: boolean; // True if option can only be specified via tsconfig.json file isCommandLineOnly?: boolean; showInSimplifiedHelpView?: boolean; category?: DiagnosticMessage; - strictFlag?: true; // true if the option is one of the flag under strict - affectsSourceFile?: true; // true if we should recreate SourceFiles after this option changes - affectsModuleResolution?: true; // currently same effect as `affectsSourceFile` - affectsBindDiagnostics?: true; // true if this affects binding (currently same effect as `affectsSourceFile`) - affectsSemanticDiagnostics?: true; // true if option affects semantic diagnostics - affectsEmit?: true; // true if the options affects emit - affectsProgramStructure?: true; // true if program should be reconstructed from root files if option changes and does not affect module resolution as affectsModuleResolution indirectly means program needs to reconstructed - affectsDeclarationPath?: true; // true if the options affects declaration file path computed - affectsBuildInfo?: true; // true if this options should be emitted in buildInfo - transpileOptionValue?: boolean | undefined; // If set this means that the option should be set to this value when transpiling + strictFlag?: true; // true if the option is one of the flag under strict + affectsSourceFile?: true; // true if we should recreate SourceFiles after this option changes + affectsModuleResolution?: true; // currently same effect as `affectsSourceFile` + affectsBindDiagnostics?: true; // true if this affects binding (currently same effect as `affectsSourceFile`) + affectsSemanticDiagnostics?: true; // true if option affects semantic diagnostics + affectsEmit?: true; // true if the options affects emit + affectsProgramStructure?: true; // true if program should be reconstructed from root files if option changes and does not affect module resolution as affectsModuleResolution indirectly means program needs to reconstructed + affectsDeclarationPath?: true; // true if the options affects declaration file path computed + affectsBuildInfo?: true; // true if this options should be emitted in buildInfo + transpileOptionValue?: boolean | undefined; // If set this means that the option should be set to this value when transpiling } - - function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) { if (isNullOrUndefined(value)) return undefined; const key = value.toLowerCase(); @@ -1444,13 +1456,11 @@ function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value } } - function validateJsonOptionValue(opt: CommandLineOption, value: T, errors: Diagnostic[]): T | undefined { if (isNullOrUndefined(value)) return undefined; return value; } - /** @internal */ export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) { return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors); diff --git a/external-declarations/src/test-runner/tsc-infrastructure/test-document.ts b/external-declarations/src/test-runner/tsc-infrastructure/test-document.ts index f39a68544861c..b8eba7f719c64 100644 --- a/external-declarations/src/test-runner/tsc-infrastructure/test-document.ts +++ b/external-declarations/src/test-runner/tsc-infrastructure/test-document.ts @@ -1,9 +1,13 @@ -import { isLineBreak } from "typescript"; - -import { CharacterCodes } from "../../compiler/types"; -import { TestFile } from "./compiler-run"; - +import { + isLineBreak, +} from "typescript"; +import { + CharacterCodes, +} from "../../compiler/types"; +import { + TestFile, +} from "./compiler-run"; /** @internal */ export function computeLineStarts(text: string): number[] { @@ -58,7 +62,8 @@ export class TextDocument { file.unitName, file.content, file.fileOptions && Object.keys(file.fileOptions) - .reduce((meta, key) => meta.set(key, file.fileOptions[key]), new Map())); + .reduce((meta, key) => meta.set(key, file.fileOptions[key]), new Map()), + ); } public asTestFile() { @@ -66,7 +71,7 @@ export class TextDocument { unitName: this.file, content: this.text, fileOptions: Array.from(this.meta) - .reduce((obj, [key, value]) => (obj[key] = value, obj), {} as Record) + .reduce((obj, [key, value]) => (obj[key] = value, obj), {} as Record), }); } -} \ No newline at end of file +} diff --git a/external-declarations/src/test-runner/tsc-infrastructure/test-file-parser.ts b/external-declarations/src/test-runner/tsc-infrastructure/test-file-parser.ts index d5bdab0fe8d3f..e2c90f851b8ba 100644 --- a/external-declarations/src/test-runner/tsc-infrastructure/test-file-parser.ts +++ b/external-declarations/src/test-runner/tsc-infrastructure/test-file-parser.ts @@ -1,8 +1,19 @@ import * as ts from "typescript"; -import { Path } from "typescript"; - -import { find, forEach, orderedRemoveItemAt } from "../../compiler/lang-utils"; -import { getBaseFileName, getDirectoryPath, getNormalizedAbsolutePath, normalizePath } from "../../compiler/path-utils"; +import { + Path, +} from "typescript"; + +import { + find, + forEach, + orderedRemoveItemAt, +} from "../../compiler/lang-utils"; +import { + getBaseFileName, + getDirectoryPath, + getNormalizedAbsolutePath, + normalizePath, +} from "../../compiler/path-utils"; import * as vfs from "./vfs"; /** all the necessary information to set the right compiler settings */ @@ -65,13 +76,11 @@ export function splitContentByNewlines(content: string) { return lines; } - export function getConfigNameFromFileName(filename: string): "tsconfig.json" | "jsconfig.json" | undefined { const flc = getBaseFileName(filename).toLowerCase(); return find(["tsconfig.json" as const, "jsconfig.json" as const], x => x === flc); } - export function parseSymlinkFromTest(line: string, symlinks: vfs.FileSet | undefined) { const linkMetaData = linkRegex.exec(line); linkRegex.lastIndex = 0; @@ -82,7 +91,6 @@ export function parseSymlinkFromTest(line: string, symlinks: vfs.FileSet | undef return symlinks; } - export interface TestCaseContent { settings: CompilerSettings; testUnitData: TestUnitData[]; @@ -188,7 +196,7 @@ export function makeUnitsFromTest(code: string, fileName: string, rootDir?: stri useCaseSensitiveFileNames: false, readDirectory: () => [], fileExists: () => true, - readFile: (name) => forEach(testUnitData, data => data.name.toLowerCase() === name.toLowerCase() ? data.content : undefined) + readFile: name => forEach(testUnitData, data => data.name.toLowerCase() === name.toLowerCase() ? data.content : undefined), }; // check if project has tsconfig.json in the list of files diff --git a/external-declarations/src/test-runner/tsc-infrastructure/vary-by.ts b/external-declarations/src/test-runner/tsc-infrastructure/vary-by.ts index 5092a3072d552..36b24de5e79c9 100644 --- a/external-declarations/src/test-runner/tsc-infrastructure/vary-by.ts +++ b/external-declarations/src/test-runner/tsc-infrastructure/vary-by.ts @@ -1,6 +1,20 @@ -import { arrayFrom, equateStringsCaseInsensitive, findIndex, forEach, getEntries, hasProperty,map, orderedRemoveItemAt, startsWith } from "../../compiler/lang-utils"; -import { optionDeclarations } from "./options"; -import { CompilerSettings } from "./test-file-parser"; +import { + arrayFrom, + equateStringsCaseInsensitive, + findIndex, + forEach, + getEntries, + hasProperty, + map, + orderedRemoveItemAt, + startsWith, +} from "../../compiler/lang-utils"; +import { + optionDeclarations, +} from "./options"; +import { + CompilerSettings, +} from "./test-file-parser"; interface FileBasedTestConfiguration { [key: string]: string; @@ -104,7 +118,7 @@ function splitVaryBySettingValue(text: string, varyBy: string): string[] | undef return undefined; } - const variations: { key: string, value?: string | number }[] = []; + const variations: { key: string; value?: string | number; }[] = []; const values = getVaryByStarSettingValues(varyBy); // add (and deduplicate) all included entries @@ -151,7 +165,7 @@ function getVaryByStarSettingValues(varyBy: string): ReadonlyMap | undefined; - constructor(files: FileSet, { meta }: { meta?: Record } = {}) { + constructor(files: FileSet, { meta }: { meta?: Record; } = {}) { this.files = files; this.meta = meta; } @@ -1404,7 +1423,7 @@ export class File { public readonly data: Buffer | string; public readonly encoding: string | undefined; public readonly meta: Record | undefined; - constructor(data: Buffer | string, { meta, encoding }: { encoding?: string, meta?: Record } = {}) { + constructor(data: Buffer | string, { meta, encoding }: { encoding?: string; meta?: Record; } = {}) { this.data = data; this.encoding = encoding; this.meta = meta; @@ -1412,13 +1431,13 @@ export class File { } export class SameFileContentFile extends File { - constructor(data: Buffer | string, metaAndEncoding?: { encoding?: string, meta?: Record }) { + constructor(data: Buffer | string, metaAndEncoding?: { encoding?: string; meta?: Record; }) { super(data, metaAndEncoding); } } export class SameFileWithModifiedTime extends File { - constructor(data: Buffer | string, metaAndEncoding?: { encoding?: string, meta?: Record }) { + constructor(data: Buffer | string, metaAndEncoding?: { encoding?: string; meta?: Record; }) { super(data, metaAndEncoding); } } @@ -1445,7 +1464,7 @@ export class Unlink { export class Symlink { public readonly symlink: string; public readonly meta: Record | undefined; - constructor(symlink: string, { meta }: { meta?: Record } = {}) { + constructor(symlink: string, { meta }: { meta?: Record; } = {}) { this.symlink = symlink; this.meta = meta; } @@ -1456,7 +1475,7 @@ export class Mount { public readonly source: string; public readonly resolver: FileSystemResolver; public readonly meta: Record | undefined; - constructor(source: string, resolver: FileSystemResolver, { meta }: { meta?: Record } = {}) { + constructor(source: string, resolver: FileSystemResolver, { meta }: { meta?: Record; } = {}) { this.source = source; this.resolver = resolver; this.meta = meta; @@ -1558,10 +1577,10 @@ function getBuiltLocal(host: FileSystemResolverHost, ignoreCase: boolean): FileS [builtFolder]: new Mount(vpath.resolve(host.getWorkspaceRoot(), "built/local"), resolver), [testLibFolder]: new Mount(vpath.resolve(host.getWorkspaceRoot(), "tests/lib"), resolver), [projectsFolder]: new Mount(vpath.resolve(host.getWorkspaceRoot(), "tests/projects"), resolver), - [srcFolder]: {} + [srcFolder]: {}, }, cwd: srcFolder, - meta: { defaultLibLocation: builtFolder } + meta: { defaultLibLocation: builtFolder }, }); builtLocalCI.makeReadonly(); } @@ -1575,7 +1594,8 @@ function getBuiltLocal(host: FileSystemResolverHost, ignoreCase: boolean): FileS /* eslint-disable no-null/no-null */ function normalizeFileSetEntry(value: FileSet[string]) { - if (value === undefined || + if ( + value === undefined || value === null || value instanceof Directory || value instanceof File || @@ -1583,7 +1603,8 @@ function normalizeFileSetEntry(value: FileSet[string]) { value instanceof Symlink || value instanceof Mount || value instanceof Rmdir || - value instanceof Unlink) { + value instanceof Unlink + ) { return value; } return typeof value === "string" || Buffer.isBuffer(value) ? new File(value) : new Directory(value); diff --git a/external-declarations/src/test-runner/tsc-infrastructure/vpath.ts b/external-declarations/src/test-runner/tsc-infrastructure/vpath.ts index 3fe922615d1a4..f15cf2186c0ca 100644 --- a/external-declarations/src/test-runner/tsc-infrastructure/vpath.ts +++ b/external-declarations/src/test-runner/tsc-infrastructure/vpath.ts @@ -1,8 +1,31 @@ -import { Path } from "typescript"; - -import { changeAnyExtension, comparePaths, comparePathsCaseInsensitive, comparePathsCaseSensitive, getAnyExtensionFromPath, getBaseFileName, getDirectoryPath, getPathComponents, getPathFromPathComponents, getRelativePathFromDirectory, isDiskPathRoot, isRootedDiskPath, reducePathComponents, resolvePath } from "../../compiler/path-utils"; -import { CharacterCodes } from "../../compiler/types"; -import { hasJSFileExtension, hasTSFileExtension, isDeclarationFileName } from "../../compiler/utils"; +import { + Path, +} from "typescript"; + +import { + changeAnyExtension, + comparePaths, + comparePathsCaseInsensitive, + comparePathsCaseSensitive, + getAnyExtensionFromPath, + getBaseFileName, + getDirectoryPath, + getPathComponents, + getPathFromPathComponents, + getRelativePathFromDirectory, + isDiskPathRoot, + isRootedDiskPath, + reducePathComponents, + resolvePath, +} from "../../compiler/path-utils"; +import { + CharacterCodes, +} from "../../compiler/types"; +import { + hasJSFileExtension, + hasTSFileExtension, + isDeclarationFileName, +} from "../../compiler/utils"; import * as vfs from "./vfs"; /** @@ -19,8 +42,6 @@ const urlSchemeSeparator = "://"; const backslashRegExp = /\\/g; export const sep = directorySeparator; - - /** * Combines paths. If a path is absolute, it replaces any previous path. Relative paths are not simplified. * @@ -67,7 +88,6 @@ export function normalizeSlashes(path: string): string { : path; } - /** * Adds a trailing directory separator to a path, if it does not already have one. * @@ -107,7 +127,6 @@ export function isAnyDirectorySeparator(charCode: number): boolean { return charCode === CharacterCodes.slash || charCode === CharacterCodes.backslash; } - /** * Returns length of the root part of a path or URL (i.e. length of "/", "x:/", "//server/share/, file:///user/files"). * @@ -176,8 +195,10 @@ function getEncodedRootLength(path: string): number { // special case interpreted as "the machine from which the URL is being interpreted". const scheme = path.slice(0, schemeEnd); const authority = path.slice(authorityStart, authorityEnd); - if (scheme === "file" && (authority === "" || authority === "localhost") && - isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) { + if ( + scheme === "file" && (authority === "" || authority === "localhost") && + isVolumeCharacter(path.charCodeAt(authorityEnd + 1)) + ) { const volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2); if (volumeSeparatorEnd !== -1) { if (path.charCodeAt(volumeSeparatorEnd) === CharacterCodes.slash) { @@ -287,7 +308,6 @@ export function validate(path: string, flags: ValidationFlags = ValidationFlags. return components.length > 1 && trailing ? format(reduce(components)) + sep : format(reduce(components)); } - const invalidRootComponentRegExp = /^(?!(\/|\/\/\w+\/|[a-zA-Z]:\/?|)$)/; const invalidNavigableComponentRegExp = /[:*?"<>|]/; const invalidNavigableComponentWithWildcardsRegExp = /[:"<>|]/; diff --git a/external-declarations/src/tsconfig.json b/external-declarations/src/tsconfig.json index b7c2046ebd846..aaf9a80a1d38f 100644 --- a/external-declarations/src/tsconfig.json +++ b/external-declarations/src/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "pretty": true, "lib": ["ES2021"], "target": "ES2021", @@ -25,4 +24,4 @@ "outDir": "../build", "noUnusedLocals": true } -} \ No newline at end of file +} diff --git a/external-declarations/src/utils/cli-parser.ts b/external-declarations/src/utils/cli-parser.ts index 5ba27b877a8a9..3279d43889d3e 100644 --- a/external-declarations/src/utils/cli-parser.ts +++ b/external-declarations/src/utils/cli-parser.ts @@ -1,5 +1,6 @@ -import { hasProperty } from "../compiler/lang-utils"; - +import { + hasProperty, +} from "../compiler/lang-utils"; type ArgTypeParser = (name: string, value: string | undefined, existingValue: T | undefined) => T; function mustNotExist(fn: ArgTypeParser): ArgTypeParser { @@ -11,36 +12,40 @@ function mustNotExist(fn: ArgTypeParser): ArgTypeParser { }; } export const ArgType = { - String: () => mustNotExist((name, value) => { - if (value) { - return value; - } - throw new Error(`String value was not specified for ${name}`); - }), - Boolean: () => mustNotExist((name, value) => { - if (value === undefined) { - return true; - } - if (value.toLowerCase() === "false") { - return false; - } - if (value.toLowerCase() === "true") { - return true; - } - throw new Error(`Invalid Boolean Value ${value} for ${name}`); - }), - Enum: (...values: T[]) => mustNotExist((name, value,) => { - if (values.includes(value as T)) { - return value as T; - } - throw new Error(`Invalid Enum value, Expected one of ${values.join(",")}`); - }), - Number: () => mustNotExist((name, value) => { - if (value && !Number.isNaN(+value)) { - return +value; - } - throw new Error(`Invalid Number value, found ${value}`); - }), + String: () => + mustNotExist((name, value) => { + if (value) { + return value; + } + throw new Error(`String value was not specified for ${name}`); + }), + Boolean: () => + mustNotExist((name, value) => { + if (value === undefined) { + return true; + } + if (value.toLowerCase() === "false") { + return false; + } + if (value.toLowerCase() === "true") { + return true; + } + throw new Error(`Invalid Boolean Value ${value} for ${name}`); + }), + Enum: (...values: T[]) => + mustNotExist((name, value) => { + if (values.includes(value as T)) { + return value as T; + } + throw new Error(`Invalid Enum value, Expected one of ${values.join(",")}`); + }), + Number: () => + mustNotExist((name, value) => { + if (value && !Number.isNaN(+value)) { + return +value; + } + throw new Error(`Invalid Number value, found ${value}`); + }), StringArray: () => (name, value, existingValue: string[] | undefined) => { existingValue ??= []; if (value) { @@ -51,28 +56,30 @@ export const ArgType = { }, } satisfies Record ArgTypeParser>; - -type ParserConfiguration = Record | { - type: ArgTypeParser, - required?: V, - description: string, -}>; +type ParserConfiguration = Record< + string, + ArgTypeParser | { + type: ArgTypeParser; + required?: V; + description: string; + } +>; type ParsedValue> = { - [P in keyof T]: - T[P] extends ArgTypeParser ? A | undefined : + [P in keyof T]: T[P] extends ArgTypeParser ? A | undefined : T[P] extends { - type: ArgTypeParser, - required?: infer R - } ? R extends true ? A : A | undefined : never + type: ArgTypeParser; + required?: infer R; + } ? R extends true ? A : A | undefined : + never; }; export function parserConfiguration>(config: T) { return config; } export function parseArgs>(args: string[], types: T): { - value: ParsedValue, - diagnostics: string[], - usage: () => string + value: ParsedValue; + diagnostics: string[]; + usage: () => string; printUsageOnErrors: () => void; } { const config: Record = {}; @@ -80,17 +87,17 @@ export function parseArgs>(a function parseArgument(name: string, value: string | undefined) { const existingValue = config[name]; const parser = types[name]; - if(!parser) { + if (!parser) { diagnostics.push(`Parameter ${name} was unexpected`); return; } - const parserFn = typeof parser === "function" ? parser: parser.type; + const parserFn = typeof parser === "function" ? parser : parser.type; try { const newValue = parserFn(name, value, existingValue); config[name] = newValue; } - catch(e) { - if(e instanceof Error) { + catch (e) { + if (e instanceof Error) { diagnostics.push(e.message); } throw e; @@ -102,7 +109,7 @@ export function parseArgs>(a parseArgument(named.groups?.name!, named.groups?.value); } else { - const flagParam =/--(?.*)/.exec(arg); + const flagParam = /--(?.*)/.exec(arg); if (flagParam) { parseArgument(flagParam.groups?.name!, /*value*/ undefined); } @@ -112,9 +119,9 @@ export function parseArgs>(a } } - for(const key of Object.keys(types)) { + for (const key of Object.keys(types)) { const cfg = types[key]; - if(!(hasProperty(config, key)) && typeof cfg !== "function" && cfg.required) { + if (!(hasProperty(config, key)) && typeof cfg !== "function" && cfg.required) { diagnostics.push(`Parameters ${key} is required`); } } @@ -122,10 +129,10 @@ export function parseArgs>(a return Object.entries(types) .map(([name, v]) => ({ name, - ...(typeof v === "object" ? v: { }) + ...(typeof v === "object" ? v : {}), })) .filter(o => !!o.description) - .map(({ name, description, required }) => `--${name} \t ${description} \t ${required? "required": ""}`) + .map(({ name, description, required }) => `--${name} \t ${description} \t ${required ? "required" : ""}`) .join("\n"); } return { @@ -133,7 +140,7 @@ export function parseArgs>(a diagnostics, usage, printUsageOnErrors() { - if(diagnostics.length) { + if (diagnostics.length) { diagnostics.forEach(s => console.log(s)); console.log(usage()); process.exit(); diff --git a/external-declarations/src/utils/fs-utils.ts b/external-declarations/src/utils/fs-utils.ts index 6c324b3c724ab..4dc7d1b05a6bb 100644 --- a/external-declarations/src/utils/fs-utils.ts +++ b/external-declarations/src/utils/fs-utils.ts @@ -1,13 +1,22 @@ import * as fs from "fs"; import * as fsp from "fs/promises"; -import { compareStringsCaseSensitive,flatten, stableSort } from "../compiler/lang-utils"; -import { combinePaths,createGetCanonicalFileName, normalizePath } from "../compiler/path-utils"; -import { FileSystemEntries } from "../test-runner/tsc-infrastructure/vfs"; +import { + compareStringsCaseSensitive, + flatten, + stableSort, +} from "../compiler/lang-utils"; +import { + combinePaths, + createGetCanonicalFileName, + normalizePath, +} from "../compiler/path-utils"; +import { + FileSystemEntries, +} from "../test-runner/tsc-infrastructure/vfs"; const cache: Record = {}; export async function ensureDir(dirName: string) { - const exists = cache[dirName] ?? (await fsp.access(dirName).then(() => true, () => false)); @@ -30,7 +39,6 @@ export function flushQueue() { return Promise.all(writeQueue); } - /** * @param path directory of the tsconfig.json * @@ -117,4 +125,3 @@ function getAccessibleFileSystemEntries(path: string): FileSystemEntries { return { files: [], directories: [] }; } } - diff --git a/parallel-build/package.json b/parallel-build/package.json index f37ac6a9bd7ee..029e18a56a527 100644 --- a/parallel-build/package.json +++ b/parallel-build/package.json @@ -1,20 +1,20 @@ { - "name": "parallel-build", - "version": "1.0.0", - "description": "", - "main": "index.js", - "type": "module", - "scripts": { - "build": "tsc -p ./", - "watch": "tsc -w -p ./" - }, - "author": "", - "license": "ISC", - "dependencies": { - "@types/node": "^20.1.3", - "external-declarations": "file:../external-declarations", - "json5": "^2.2.3", - "systeminformation": "^5.21.8", - "typescript": "file:.." - } + "name": "parallel-build", + "version": "1.0.0", + "description": "", + "main": "index.js", + "type": "module", + "scripts": { + "build": "tsc -p ./", + "watch": "tsc -w -p ./" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@types/node": "^20.1.3", + "external-declarations": "file:../external-declarations", + "json5": "^2.2.3", + "systeminformation": "^5.21.8", + "typescript": "file:.." + } } diff --git a/parallel-build/src/dep-builder/dep-builder-tsconfig.json.ts b/parallel-build/src/dep-builder/dep-builder-tsconfig.json.ts index feeef0f01996c..fc5234437b6ac 100644 --- a/parallel-build/src/dep-builder/dep-builder-tsconfig.json.ts +++ b/parallel-build/src/dep-builder/dep-builder-tsconfig.json.ts @@ -73,8 +73,7 @@ async function loadBundlesDependencies(tsConfigs: string[]) { if (entry === undefined) return 0; if (entry.depth) return entry.depth; - - entry.depth = 1 + (entry.dependencies.length === 0? 0: Math.max(...entry.dependencies.map(depth))); + entry.depth = 1 + (entry.dependencies.length === 0 ? 0 : Math.max(...entry.dependencies.map(depth))); return entry.depth; } diff --git a/parallel-build/src/main.ts b/parallel-build/src/main.ts index 3219a3b8de455..bedbb3cb81930 100644 --- a/parallel-build/src/main.ts +++ b/parallel-build/src/main.ts @@ -112,8 +112,8 @@ async function main() { const nextTasks = tasks.filter(t => t.dependencies.every(d => completedTasks.has(d))); if (nextTasks.length === 0) { console.log(`${taskNameLog("NONE")}: Waiting for deps to finish. Unscheduled Tasks: ${tasks.length}`); - if(activeTasks.length === 0) { - throw new Error(`No tasks are running but tasks still have required dependencies. Check your task file. Sample uncompleted task: ${tasks[0].dependencies.find(o => !completedTasks.has(o))}`) + if (activeTasks.length === 0) { + throw new Error(`No tasks are running but tasks still have required dependencies. Check your task file. Sample uncompleted task: ${tasks[0].dependencies.find(o => !completedTasks.has(o))}`); } await waitForTaskCompletion(); continue; diff --git a/parallel-build/src/run-all-tasks.ts b/parallel-build/src/run-all-tasks.ts index 067fcc2f9a241..474dc8d9982f9 100644 --- a/parallel-build/src/run-all-tasks.ts +++ b/parallel-build/src/run-all-tasks.ts @@ -2,7 +2,7 @@ import * as child from "node:child_process"; import path from "node:path"; import * as fs from "fs/promises"; -import * as sys from "systeminformation" +import * as sys from "systeminformation"; const taskDir = "./tasks"; const statsDir = taskDir + "-stats"; diff --git a/parallel-build/tsconfig.json b/parallel-build/tsconfig.json index b3dca25527a24..66764f422db67 100644 --- a/parallel-build/tsconfig.json +++ b/parallel-build/tsconfig.json @@ -5,8 +5,8 @@ "target": "ESNext", "rootDir": "./src", "outDir": "./build", - "moduleResolution":"nodenext", + "moduleResolution": "nodenext", "sourceMap": true, - "allowSyntheticDefaultImports": true, + "allowSyntheticDefaultImports": true } -} \ No newline at end of file +} diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 38287315fb7b1..a683cdb4806be 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -6710,6 +6710,10 @@ "category": "Error", "code": 9010 }, + "To use heritage clauses in class expressions with --isolatedDeclarations, you need explicit type annotation on the variable.": { + "category": "Error", + "code": 9011 + }, "JSX attributes must only be assigned a non-empty 'expression'.": { "category": "Error", "code": 17000 diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index e3a29cb79541a..f18c75e012f89 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -331,7 +331,7 @@ export function transformDeclarations(context: TransformationContext) { let libs: Map; let emittedImports: readonly AnyImportSyntax[] | undefined; // must be declared in container so it can be `undefined` while transformer's first pass const resolver = context.getEmitResolver(); - const localInferenceResolver = createLocalInferenceResolver({ + const { resolver: localInferenceResolver, isolatedDeclarations } = createLocalInferenceResolver({ ensureParameter, context, visitDeclarationSubtree, @@ -346,7 +346,6 @@ export function transformDeclarations(context: TransformationContext) { }); const options = context.getCompilerOptions(); const { noResolve, stripInternal } = options; - const isolatedDeclarations = options.isolatedDeclarations; return transformRoot; function reportIsolatedDeclarationError(node: Node) { @@ -852,7 +851,7 @@ export function transformDeclarations(context: TransformationContext) { // Literal const declarations will have an initializer ensured rather than a type return; } - if (isolatedDeclarations && localInferenceResolver) { + if (isolatedDeclarations) { return localInferenceResolver.fromInitializer(node, type, currentSourceFile); } const shouldUseResolverType = node.kind === SyntaxKind.Parameter && @@ -1502,7 +1501,7 @@ export function transformDeclarations(context: TransformationContext) { }); errorFallbackNode = input; const type = isolatedDeclarations ? - localInferenceResolver?.fromInitializer(input, /*type*/ undefined, currentSourceFile) : + localInferenceResolver.fromInitializer(input, /*type*/ undefined, currentSourceFile) : resolver.createTypeOfExpression(input.expression, input, declarationEmitNodeBuilderFlags, symbolTracker); const varDecl = factory.createVariableDeclaration(newId, /*exclamationToken*/ undefined, type, /*initializer*/ undefined); errorFallbackNode = undefined; diff --git a/src/compiler/transformers/declarations/emit-binder.ts b/src/compiler/transformers/declarations/emit-binder.ts index 398b79cfae276..ea3da2b676a55 100644 --- a/src/compiler/transformers/declarations/emit-binder.ts +++ b/src/compiler/transformers/declarations/emit-binder.ts @@ -70,12 +70,13 @@ import { } from "../../utilitiesPublic"; import { IsolatedEmitHost, + MemberKey, } from "./types"; import { getMemberKey, - MemberKey, } from "./utils"; +/** @internal */ export interface EmitDeclarationNodeLinks { isVisible?: boolean; symbol?: EmitDeclarationSymbol; @@ -84,7 +85,10 @@ export interface EmitDeclarationNodeLinks { enumValue?: string | number | undefined; } -type EmitDeclarationSymbolTable = Map; +/** @internal */ +export type EmitDeclarationSymbolTable = Map; + +/** @internal */ export interface EmitDeclarationSymbol { name?: MemberKey; exportSymbol?: EmitDeclarationSymbol; @@ -136,6 +140,7 @@ const syntaxKindToSymbolMap = { [SyntaxKind.ImportClause]: [SymbolFlags.Alias, SymbolFlags.AliasExcludes], } as const satisfies Partial>>; +/** @internal */ export function bindSourceFileForDeclarationEmit(file: SourceFile, host: IsolatedEmitHost) { const options: CompilerOptions = host.getCompilerOptions(); const nodeLinks: EmitDeclarationNodeLinks[] = []; @@ -544,8 +549,9 @@ export function bindSourceFileForDeclarationEmit(file: SourceFile, host: Isolate /** * Gets the symbolic name for a member from its type. + * @internal */ -function getMemberNameFromElement(element: TypeElement | ClassElement | EnumMember): MemberKey | undefined { +export function getMemberNameFromElement(element: TypeElement | ClassElement | EnumMember): MemberKey | undefined { if (isConstructorDeclaration(element) || isConstructSignatureDeclaration(element)) { return "@constructor" as MemberKey; } diff --git a/src/compiler/transformers/declarations/emit-host.ts b/src/compiler/transformers/declarations/emit-host.ts index baa185f3eb495..db57fcea12f64 100644 --- a/src/compiler/transformers/declarations/emit-host.ts +++ b/src/compiler/transformers/declarations/emit-host.ts @@ -17,6 +17,7 @@ import { IsolatedEmitHost, } from "./types"; +/** @internal */ export function createEmitDeclarationHost(allProjectFiles: string[], tsLibFiles: string[], options: CompilerOptions, sys: System): IsolatedEmitHost { const getCompilerOptions = () => options; const getCurrentDirectory = () => "."; diff --git a/src/compiler/transformers/declarations/emit-resolver.ts b/src/compiler/transformers/declarations/emit-resolver.ts index 429d0a4b8b7e5..5371411cd7a6e 100644 --- a/src/compiler/transformers/declarations/emit-resolver.ts +++ b/src/compiler/transformers/declarations/emit-resolver.ts @@ -96,10 +96,10 @@ import { import { IsolatedEmitHost, IsolatedEmitResolver, + MemberKey, } from "./types"; import { getMemberKey, - MemberKey, } from "./utils"; const knownFunctionMembers = new Set([ @@ -110,6 +110,8 @@ const knownFunctionMembers = new Set([ "I:prototype", "I:length", ]); + +/** @internal */ export function createEmitDeclarationResolver(file: SourceFile, host: IsolatedEmitHost): IsolatedEmitResolver { const { getNodeLinks, resolveMemberKey, resolveName } = bindSourceFileForDeclarationEmit(file, host); diff --git a/src/compiler/transformers/declarations/localInferenceResolver.ts b/src/compiler/transformers/declarations/localInferenceResolver.ts index eb49b12062149..6a541b0a02b20 100644 --- a/src/compiler/transformers/declarations/localInferenceResolver.ts +++ b/src/compiler/transformers/declarations/localInferenceResolver.ts @@ -2,17 +2,17 @@ import { getCommentRange, setCommentRange, } from "../../_namespaces/ts"; -import { - Debug, -} from "../../debug"; import { Diagnostics, } from "../../diagnosticInformationMap.generated"; import { + isClassExpression, isComputedPropertyName, + isConstructorDeclaration, isExportAssignment, isGetAccessorDeclaration, isIdentifier, + isIndexSignatureDeclaration, isInterfaceDeclaration, isLiteralTypeNode, isMethodDeclaration, @@ -49,12 +49,14 @@ import { ArrayLiteralExpression, ArrowFunction, AsExpression, + ClassExpression, EntityNameOrEntityNameExpression, ExportAssignment, Expression, FunctionExpression, GetAccessorDeclaration, HasInferredType, + HasModifiers, Identifier, KeywordTypeSyntaxKind, LanguageVariant, @@ -62,10 +64,10 @@ import { MethodDeclaration, MethodSignature, Modifier, + ModifierLike, Node, NodeArray, NodeFlags, - ObjectLiteralElementLike, ObjectLiteralExpression, ParameterDeclaration, ParenthesizedExpression, @@ -85,6 +87,7 @@ import { } from "../../types"; import { createDiagnosticForNode, + createDiagnosticForRange, isEntityNameExpression, } from "../../utilities"; import { @@ -110,6 +113,7 @@ enum LocalTypeInfoFlags { None = 0, Invalid = 1 << 1, } +const propertyLikeModifiers = new Set([SyntaxKind.ReadonlyKeyword, SyntaxKind.PublicKeyword]); interface LocalInferenceResolver { makeInvalidType(): Node; @@ -127,35 +131,38 @@ export function createLocalInferenceResolver({ checkEntityNameVisibility(name: EntityNameOrEntityNameExpression, container?: Node): void; ensureParameter(p: ParameterDeclaration): ParameterDeclaration; context: TransformationContext; -}): LocalInferenceResolver | undefined { - let currentSourceFile: SourceFile | undefined; +}): { resolver: LocalInferenceResolver; isolatedDeclarations: true; } | { resolver: undefined; isolatedDeclarations: false; } { + let currentSourceFile: SourceFile; const options = context.getCompilerOptions(); const resolver = context.getEmitResolver(); if (!options.isolatedDeclarations) { - return undefined; + return { resolver: undefined, isolatedDeclarations: false }; } const { factory } = context; const strictNullChecks = !!options.strict || !!options.strictNullChecks; return { - fromInitializer(node: HasInferredType, type: TypeNode | undefined, sourceFile: SourceFile) { - const oldSourceFile = currentSourceFile; - currentSourceFile = sourceFile; - try { - const localType = localInferenceFromInitializer(node, type); - if (localType !== undefined) { - return localType; + resolver: { + fromInitializer(node: HasInferredType, type: TypeNode | undefined, sourceFile: SourceFile) { + const oldSourceFile = currentSourceFile; + currentSourceFile = sourceFile; + try { + const localType = localInferenceFromInitializer(node, type); + if (localType !== undefined) { + return localType; + } + if (type) { + return visitNode(type, visitDeclarationSubtree, isTypeNode)!; + } + return makeInvalidType(); } - if (type) { - return visitNode(type, visitDeclarationSubtree, isTypeNode)!; + finally { + currentSourceFile = oldSourceFile; } - return makeInvalidType(); - } - finally { - currentSourceFile = oldSourceFile; - } + }, + makeInvalidType, }, - makeInvalidType, + isolatedDeclarations: options.isolatedDeclarations, }; function reportIsolatedDeclarationError(node: Node) { const message = createDiagnosticForNode( @@ -175,28 +182,38 @@ export function createLocalInferenceResolver({ flags: LocalTypeInfoFlags; } - function mergeFlags(existing: LocalTypeInfoFlags, newFlags: LocalTypeInfoFlags): LocalTypeInfoFlags { - return existing | newFlags; - } - function getAccessorInfo(properties: NodeArray, knownAccessor: SetAccessorDeclaration | GetAccessorDeclaration) { + function getAccessorInfo(parent: ClassExpression | ObjectLiteralExpression, knownAccessor: SetAccessorDeclaration | GetAccessorDeclaration) { const nameKey = getMemberKey(knownAccessor); - const knownIsGetAccessor = isGetAccessorDeclaration(knownAccessor); - const otherAccessorTest = knownIsGetAccessor ? isSetAccessorDeclaration : isGetAccessorDeclaration; - const otherAccessorIndex = properties.findIndex(n => otherAccessorTest(n) && getMemberKey(n) === nameKey); - const otherAccessor = properties[otherAccessorIndex] as SetAccessorDeclaration | GetAccessorDeclaration | undefined; - - const getAccessor = knownIsGetAccessor ? knownAccessor : - otherAccessor && isGetAccessorDeclaration(otherAccessor) ? otherAccessor : - undefined; - const setAccessor = !knownIsGetAccessor ? knownAccessor : - otherAccessor && isSetAccessorDeclaration(otherAccessor) ? otherAccessor : - undefined; + const members = isClassExpression(parent) ? parent.members : parent.properties; + let getAccessor, setAccessor; + let otherAccessorIdx = -1, knownAccessorIdx = -1; + for (let i = 0; i < members.length; ++i) { + const member = members[i]; + if (isGetAccessorDeclaration(member) && getMemberKey(member) === nameKey) { + getAccessor = member; + if (knownAccessor !== member) { + otherAccessorIdx = i; + } + else { + knownAccessorIdx = i; + } + } + else if (isSetAccessorDeclaration(member) && getMemberKey(member) === nameKey) { + setAccessor = member; + if (knownAccessor !== member) { + otherAccessorIdx = i; + } + else { + knownAccessorIdx = i; + } + } + } return { - otherAccessorIndex, - otherAccessor, getAccessor, setAccessor, + otherAccessorIdx, + knownAccessorIdx, }; } function inferAccessorType(getAccessor?: GetAccessorDeclaration, setAccessor?: SetAccessorDeclaration): LocalTypeInfo { @@ -212,10 +229,9 @@ export function createLocalInferenceResolver({ return invalid(getAccessor ?? setAccessor!); } function localInference(node: Node, inferenceFlags: NarrowBehavior = NarrowBehavior.None): LocalTypeInfo { - const nextInferenceFlags = inferenceFlags & NarrowBehavior.NotKeepLiterals; switch (node.kind) { case SyntaxKind.ParenthesizedExpression: - return localInference((node as ParenthesizedExpression).expression, nextInferenceFlags); + return localInference((node as ParenthesizedExpression).expression, inferenceFlags & NarrowBehavior.NotKeepLiterals); case SyntaxKind.Identifier: { if ((node as Identifier).escapedText === "undefined") { return createUndefinedTypeNode(node); @@ -240,8 +256,7 @@ export function createLocalInferenceResolver({ fnNode.parameters.map(p => deepClone(ensureParameter(p))), returnType.typeNode, ); - const flags = mergeFlags(LocalTypeInfoFlags.None, returnType.flags); - return regular(fnTypeNode, node, flags); + return regular(fnTypeNode, node, LocalTypeInfoFlags.None | returnType.flags); } finally { setEnclosingDeclarations(oldEnclosingDeclaration); @@ -330,8 +345,8 @@ export function createLocalInferenceResolver({ ); } else { - const elementType = localInference(element, nextInferenceFlags); - inheritedArrayTypeFlags = mergeFlags(inheritedArrayTypeFlags, elementType.flags); + const elementType = localInference(element, inferenceFlags & NarrowBehavior.NotKeepLiterals); + inheritedArrayTypeFlags |= elementType.flags; elementTypesInfo.push(elementType); } } @@ -340,162 +355,314 @@ export function createLocalInferenceResolver({ ); tupleType.emitNode = { flags: 1, autoGenerate: undefined, internalFlags: 0 }; return regular(factory.createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleType), node, inheritedArrayTypeFlags); + case SyntaxKind.ObjectLiteralExpression: + return getTypeForObjectLiteralExpression(node as ObjectLiteralExpression, inferenceFlags); + case SyntaxKind.ClassExpression: + return getClassExpressionTypeNode(node as ClassExpression); + } - case SyntaxKind.ObjectLiteralExpression: { - const objectLiteral = node as ObjectLiteralExpression; - const properties: TypeElement[] = []; - let inheritedObjectTypeFlags = LocalTypeInfoFlags.None; - const members = new Map(); - let replaceWithInvalid = false; - for (let propIndex = 0, length = objectLiteral.properties.length; propIndex < length; propIndex++) { - const prop = objectLiteral.properties[propIndex]; - - if (isShorthandPropertyAssignment(prop)) { - invalid(prop); - inheritedObjectTypeFlags |= LocalTypeInfoFlags.Invalid; - continue; - } - else if (isSpreadAssignment(prop)) { - invalid(prop); - inheritedObjectTypeFlags |= LocalTypeInfoFlags.Invalid; - continue; - } + return invalid(node); + } + function invalid(sourceNode: Node): LocalTypeInfo { + reportIsolatedDeclarationError(sourceNode); + return { typeNode: makeInvalidType(), flags: LocalTypeInfoFlags.Invalid, sourceNode }; + } + function regular(typeNode: TypeNode, sourceNode: Node, flags = LocalTypeInfoFlags.None): LocalTypeInfo { + return { typeNode, flags, sourceNode }; + } + function getTypeForObjectLiteralExpression(objectLiteral: ObjectLiteralExpression, inferenceFlags: NarrowBehavior) { + const properties: TypeElement[] = []; + let inheritedObjectTypeFlags = LocalTypeInfoFlags.None; + const members = new Map(); + let replaceWithInvalid = false; + for (let propIndex = 0, length = objectLiteral.properties.length; propIndex < length; propIndex++) { + const prop = objectLiteral.properties[propIndex]; + + if (isShorthandPropertyAssignment(prop)) { + reportIsolatedDeclarationError(prop); + inheritedObjectTypeFlags |= LocalTypeInfoFlags.Invalid; + continue; + } + else if (isSpreadAssignment(prop)) { + reportIsolatedDeclarationError(prop); + inheritedObjectTypeFlags |= LocalTypeInfoFlags.Invalid; + continue; + } - if (isPrivateIdentifier(prop.name)) { - // Not valid in object literals but the compiler will complain about this, we just ignore it here. - continue; - } - if (isComputedPropertyName(prop.name)) { - if (!resolver.isLiteralComputedName(prop.name)) { - reportIsolatedDeclarationError(node); - replaceWithInvalid = true; - continue; - } - if (isEntityNameExpression(prop.name.expression)) { - checkEntityNameVisibility(prop.name.expression, prop); - } - } + if (isPrivateIdentifier(prop.name)) { + // Not valid in object literals but the compiler will complain about this, we just ignore it here. + continue; + } + if (isComputedPropertyName(prop.name)) { + if (!resolver.isLiteralComputedName(prop.name)) { + reportIsolatedDeclarationError(prop.name); + replaceWithInvalid = true; + continue; + } + if (isEntityNameExpression(prop.name.expression)) { + checkEntityNameVisibility(prop.name.expression, prop); + } + } - const nameKey = getMemberKey(prop); - const existingMember = nameKey ? members.get(nameKey) : undefined; - const name = simplifyComputedPropertyName(prop.name, existingMember?.name) ?? - deepClone(visitNode(prop.name, visitDeclarationSubtree, isPropertyName)!); - - let newProp; - if (isMethodDeclaration(prop)) { - const oldEnclosingDeclaration = setEnclosingDeclarations(prop); - try { - const returnType = visitTypeAndClone(prop.type, prop); - - const typeParameters = visitNodes(prop.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration)?.map(deepClone); - // TODO: We need to see about inheriting flags from parameters - const parameters = prop.parameters.map(p => deepClone(ensureParameter(p))); - inheritedObjectTypeFlags = mergeFlags(inheritedObjectTypeFlags, returnType.flags); - if (inferenceFlags & NarrowBehavior.AsConst) { - newProp = factory.createPropertySignature( - [factory.createModifier(SyntaxKind.ReadonlyKeyword)], - name, - /*questionToken*/ undefined, - factory.createFunctionTypeNode( - typeParameters, - parameters, - returnType.typeNode, - ), - ); - } - else { - newProp = factory.createMethodSignature( - [], - name, - /*questionToken*/ undefined, - typeParameters, - parameters, - returnType.typeNode, - ); - } - } - finally { - setEnclosingDeclarations(oldEnclosingDeclaration); - } - } - else if (isPropertyAssignment(prop)) { - const modifiers = inferenceFlags & NarrowBehavior.AsConst ? - [factory.createModifier(SyntaxKind.ReadonlyKeyword)] : - []; - const { typeNode, flags: propTypeFlags } = localInference(prop.initializer, nextInferenceFlags); - inheritedObjectTypeFlags = mergeFlags(inheritedObjectTypeFlags, propTypeFlags); - newProp = factory.createPropertySignature( - modifiers, - name, - /*questionToken*/ undefined, - typeNode, - ); + const nameKey = getMemberKey(prop); + const existingMember = nameKey ? members.get(nameKey) : undefined; + const name = simplifyComputedPropertyName(prop.name, existingMember?.name) ?? + deepClone(visitNode(prop.name, visitDeclarationSubtree, isPropertyName)!); + + let newProp; + if (isMethodDeclaration(prop)) { + const { method, flags } = handleMethodDeclaration(prop, name, inferenceFlags); + newProp = method; + inheritedObjectTypeFlags |= flags; + } + else if (isPropertyAssignment(prop)) { + const modifiers = inferenceFlags & NarrowBehavior.AsConst ? + [factory.createModifier(SyntaxKind.ReadonlyKeyword)] : + []; + const { typeNode, flags: propTypeFlags } = localInference(prop.initializer, inferenceFlags & NarrowBehavior.NotKeepLiterals); + inheritedObjectTypeFlags |= propTypeFlags; + newProp = factory.createPropertySignature( + modifiers, + name, + /*questionToken*/ undefined, + typeNode, + ); + } + else { + const accessorType = handleAccessors(prop, objectLiteral, name, nameKey); + if (accessorType) { + inheritedObjectTypeFlags |= accessorType.flags; + newProp = accessorType.type; + } + else { + return invalid(prop); + } + } + + if (newProp) { + const commentRange = getCommentRange(prop); + setCommentRange(newProp, { + pos: commentRange.pos, + end: newProp.name.end, + }); + + if (nameKey) { + if (existingMember !== undefined && !isMethodDeclaration(prop)) { + properties[existingMember.location] = newProp; } else { - if (!isGetAccessorDeclaration(prop) && !isSetAccessorDeclaration(prop)) { - Debug.assertNever(prop); - } - if (!nameKey) { - return invalid(prop); - } - const { getAccessor, setAccessor, otherAccessorIndex } = getAccessorInfo(objectLiteral.properties, prop); - if (otherAccessorIndex === -1 || otherAccessorIndex > propIndex) { - const accessorType = inferAccessorType(getAccessor, setAccessor); - const modifiers: Modifier[] = []; - if (!setAccessor) { - modifiers.push(factory.createModifier(SyntaxKind.ReadonlyKeyword)); - } - inheritedObjectTypeFlags = mergeFlags(inheritedObjectTypeFlags, accessorType.flags); - newProp = factory.createPropertySignature( - modifiers, - name, - /*questionToken*/ undefined, - accessorType.typeNode, - ); - } + members.set(nameKey, { + location: properties.length, + name, + }); + properties.push(newProp); } + } + else { + properties.push(newProp); + } + } + } - if (newProp) { - const commentRange = getCommentRange(prop); - setCommentRange(newProp, { - pos: commentRange.pos, - end: newProp.name.end, - }); + const typeNode: TypeNode = replaceWithInvalid ? makeInvalidType() : factory.createTypeLiteralNode(properties); + return regular(typeNode, objectLiteral, inheritedObjectTypeFlags); + } - if (nameKey) { - if (existingMember !== undefined && !isMethodDeclaration(prop)) { - properties[existingMember.location] = newProp; - } - else { - members.set(nameKey, { - location: properties.length, - name, - }); - properties.push(newProp); - } - } - else { - properties.push(newProp); - } + function handleMethodDeclaration(method: MethodDeclaration, name: PropertyName, inferenceFlags: NarrowBehavior) { + const oldEnclosingDeclaration = setEnclosingDeclarations(method); + try { + const returnType = visitTypeAndClone(method.type, method); + const typeParameters = visitNodes(method.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration)?.map(deepClone); + // TODO: We need to see about inheriting flags from parameters + const parameters = method.parameters.map(p => deepClone(ensureParameter(p))); + if (inferenceFlags & NarrowBehavior.AsConst) { + return { + flags: returnType.flags, + method: factory.createPropertySignature( + [factory.createModifier(SyntaxKind.ReadonlyKeyword)], + name, + /*questionToken*/ undefined, + factory.createFunctionTypeNode( + typeParameters, + parameters, + returnType.typeNode, + ), + ), + }; + } + else { + return { + flags: returnType.flags, + method: factory.createMethodSignature( + [], + name, + /*questionToken*/ undefined, + typeParameters, + parameters, + returnType.typeNode, + ), + }; + } + } + finally { + setEnclosingDeclarations(oldEnclosingDeclaration); + } + } + + function handleAccessors(accessor: GetAccessorDeclaration | SetAccessorDeclaration, parent: ObjectLiteralExpression | ClassExpression, name: PropertyName, nameKey: string | undefined) { + if (!nameKey) { + return; + } + + const { getAccessor, setAccessor, knownAccessorIdx, otherAccessorIdx } = getAccessorInfo(parent, accessor); + if (otherAccessorIdx === -1 || otherAccessorIdx > knownAccessorIdx) { + const accessorType = inferAccessorType(getAccessor, setAccessor); + return { + flags: accessorType.flags, + type: factory.createPropertySignature( + setAccessor ? [factory.createModifier(SyntaxKind.ReadonlyKeyword)] : [], + name, + /*questionToken*/ undefined, + accessorType.typeNode, + ), + }; + } + } + + function getClassExpressionTypeNode(node: ClassExpression): LocalTypeInfo { + let invalid = false; + const staticMembers: TypeElement[] = []; + const nonStaticMembers: TypeElement[] = []; + const constructorParameters: ParameterDeclaration[] = []; + + if (node.heritageClauses && node.heritageClauses.length > 0) { + context.addDiagnostic({ + ...createDiagnosticForNode(node, Diagnostics.Declaration_emit_for_this_file_requires_type_resolution_An_explicit_type_annotation_may_unblock_declaration_emit), + relatedInformation: [ + createDiagnosticForRange( + currentSourceFile, + { + pos: node.heritageClauses[0].pos, + end: node.heritageClauses[node.heritageClauses.length - 1].end, + }, + Diagnostics.To_use_heritage_clauses_in_class_expressions_with_isolatedDeclarations_you_need_explicit_type_annotation_on_the_variable, + ), + ], + }); + invalid = true; + } + + for (const member of node.members) { + if (isConstructorDeclaration(member)) { + for (const parameter of member.parameters) { + const type = localInferenceFromInitializer(parameter, parameter.type); + if (!type) { + invalid = true; + continue; + } + // TODO: See what happens on private modifiers. + if (parameter.modifiers?.some(modifier => propertyLikeModifiers.has(modifier.kind))) { + nonStaticMembers.push(factory.createPropertySignature( + keepReadonlyKeyword(parameter.modifiers), + parameter.name as Identifier, + parameter.questionToken, + type, + )); } + constructorParameters.push(factory.createParameterDeclaration( + /*modifiers*/ undefined, + parameter.dotDotDotToken, + parameter.name, + parameter.questionToken, + type, + parameter.initializer, + )); + } + } + else if (isMethodDeclaration(member)) { + const { method, flags } = handleMethodDeclaration(member, member.name, NarrowBehavior.None); + if (flags & LocalTypeInfoFlags.Invalid) { + invalid = true; + continue; + } + if (hasStaticModifier(member)) { + staticMembers.push(method); + } + else { + nonStaticMembers.push(method); + } + } + else if (isGetAccessorDeclaration(member) || isSetAccessorDeclaration(member)) { + const accessorType = handleAccessors(member, node, member.name, getMemberKey(member)); + if (accessorType && accessorType.flags !== LocalTypeInfoFlags.None) { + nonStaticMembers.push(accessorType.type); + } + else { + invalid = true; + continue; + } + } + else if (isIndexSignatureDeclaration(member)) { + nonStaticMembers.push(member); + } + else if (isPropertyDeclaration(member)) { + const name = isPrivateIdentifier(member.name) ? + // imitating the behavior from utilities.ts : getSymbolNameForPrivateIdentifier, but as we don't have + // a Symbol & SymbolId in hand, we use NodeId of the declaration instead as an approximiation and to provide uniqueness. + // TODO: This seems to have a high collision possibilitiy than the vanilla implementation as we have much less + // ids for nodes in DTE. + factory.createStringLiteral(`__#${node.parent.id}@${member.name.escapedText}`) : + member.name; + const type = localInferenceFromInitializer(member, member.type); + if (!type) { + invalid = true; + continue; + } + const propertySignature = factory.createPropertySignature( + keepReadonlyKeyword(member.modifiers), + name, + member.questionToken, + type, + ); + if (hasStaticModifier(member)) { + staticMembers.push(propertySignature); + } + else { + nonStaticMembers.push(propertySignature); } - - const typeNode: TypeNode = replaceWithInvalid ? makeInvalidType() : factory.createTypeLiteralNode(properties); - return regular(typeNode, objectLiteral, inheritedObjectTypeFlags); } } - return invalid(node); + if (invalid) { + return { typeNode: makeInvalidType(), flags: LocalTypeInfoFlags.Invalid, sourceNode: node }; + } + else { + const constructorSignature = factory.createConstructSignature( + node.typeParameters, + constructorParameters, + factory.createTypeLiteralNode(nonStaticMembers), + ); + const typeNode = factory.createTypeLiteralNode([constructorSignature, ...staticMembers]); + return { typeNode, flags: LocalTypeInfoFlags.None, sourceNode: node }; + } } - function invalid(sourceNode: Node): LocalTypeInfo { - return { typeNode: makeInvalidTypeAndReport(sourceNode), flags: LocalTypeInfoFlags.Invalid, sourceNode }; + + function hasStaticModifier(node: HasModifiers) { + return node.modifiers?.some(modifier => modifier.kind === SyntaxKind.StaticKeyword); } - function regular(typeNode: TypeNode, sourceNode: Node, flags = LocalTypeInfoFlags.None): LocalTypeInfo { - return { typeNode, flags, sourceNode }; + + function keepReadonlyKeyword(modifiers?: NodeArray): Modifier[] { + if (modifiers?.some(modifier => modifier.kind === SyntaxKind.ReadonlyKeyword)) { + return [factory.createModifier(SyntaxKind.ReadonlyKeyword)]; + } + else { + return []; + } } + function normalizeLiteralValue(literal: LiteralExpression) { switch (literal.kind) { case SyntaxKind.BigIntLiteral: @@ -540,10 +707,7 @@ export function createLocalInferenceResolver({ ); } } - function makeInvalidTypeAndReport(node: Node) { - reportIsolatedDeclarationError(node); - return makeInvalidType(); - } + function visitTypeAndClone(type: TypeNode | undefined, owner: Node) { const visitedType = visitNode(type, visitDeclarationSubtree, isTypeNode); if (!visitedType) return invalid(owner); @@ -717,7 +881,7 @@ export function createLocalInferenceResolver({ else if (type) { return visitNode(type, visitDeclarationSubtree, isTypeNode); } - else if (isExportAssignment(node) && node.expression) { + else if (isExportAssignment(node)) { localType = localInference(node.expression, NarrowBehavior.KeepLiterals); } else if (isVariableDeclaration(node) && node.initializer) { diff --git a/src/compiler/transformers/declarations/transform-project.ts b/src/compiler/transformers/declarations/transform-project.ts index dbce718bc72ac..55f188a53cfd5 100644 --- a/src/compiler/transformers/declarations/transform-project.ts +++ b/src/compiler/transformers/declarations/transform-project.ts @@ -45,7 +45,7 @@ function joinToRootIfNeeded(rootDir: string, existingPath: string) { return normalizePath(pathIsAbsolute(existingPath) ? existingPath : sys.resolvePath(combinePaths(rootDir, existingPath))); } -export function createIsolatedDeclarationsEmitter(rootDir: string, options: CompilerOptions) { +function createIsolatedDeclarationsEmitter(rootDir: string, options: CompilerOptions) { const declarationDir = options.declarationDir ? joinToRootIfNeeded(rootDir, options.declarationDir) : options.outDir ? joinToRootIfNeeded(rootDir, options.outDir) : undefined; @@ -56,17 +56,20 @@ export function createIsolatedDeclarationsEmitter(rootDir: string, options: Comp if (!source) return; - const actualDeclaration = emitDeclarationsForFile(source, [], [], options); + const { code, diagnostics } = emitDeclarationsForFile(source, [], [], options); + if (diagnostics.length > 0) { + throw new Error(`Cannot transform file '${source.fileName}' due to ${diagnostics.length} diagnostics`); + } const output = declarationDir ? changeAnyExtension(file.replace(rootDir, declarationDir), ".d.ts") : changeAnyExtension(file, ".d.ts"); const dirPath = getDirectoryPath(output); ensureDirRecursive(dirPath, host); - host.writeFile(output, actualDeclaration.code, !!options.emitBOM); + host.writeFile(output, code, !!options.emitBOM); return output; }; } -export function emitDeclarationsForAllFiles(rootDir: string, files: string[], host: CompilerHost, options: CompilerOptions) { +function emitDeclarationsForAllFiles(rootDir: string, files: string[], host: CompilerHost, options: CompilerOptions) { const transformer = createIsolatedDeclarationsEmitter(rootDir, options); for (const file of files) { try { diff --git a/src/compiler/transformers/declarations/types.ts b/src/compiler/transformers/declarations/types.ts index 94775e51d3a0e..5133b5e9946d3 100644 --- a/src/compiler/transformers/declarations/types.ts +++ b/src/compiler/transformers/declarations/types.ts @@ -30,6 +30,7 @@ import { VariableDeclaration, } from "../../_namespaces/ts"; +/** @internal */ export interface IsolatedEmitHost extends ModuleResolutionHost { readonly redirectTargetsMap: RedirectTargetsMap; getCommonSourceDirectory(): string; @@ -43,6 +44,12 @@ export interface IsolatedEmitHost extends ModuleResolutionHost { useCaseSensitiveFileNames?(): boolean; } +/** @internal */ +export type MemberKey = string & { + __memberKey: void; +}; + +/** @internal */ export interface IsolatedEmitResolver { isLiteralComputedName(node: ComputedPropertyName): boolean; isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean; diff --git a/src/compiler/transformers/declarations/utils.ts b/src/compiler/transformers/declarations/utils.ts index 3f39d4519c095..9ae47e0368be1 100644 --- a/src/compiler/transformers/declarations/utils.ts +++ b/src/compiler/transformers/declarations/utils.ts @@ -14,10 +14,9 @@ import { PropertyName, SyntaxKind, } from "../../types"; - -export type MemberKey = string & { - __memberKey: void; -}; +import { + MemberKey, +} from "./types"; export function getMemberKey(name: string | Exclude | NoSubstitutionTemplateLiteral): MemberKey; export function getMemberKey(name: string | PropertyName | NoSubstitutionTemplateLiteral | undefined): MemberKey | undefined; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1f0ab667417c5..96c1a36045324 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -10486,6 +10486,7 @@ export function hasResolutionModeOverride(node: ImportTypeNode | ImportDeclarati return !!getResolutionModeOverride(node.attributes); } +/** @internal */ export function getDeclarationContainer(node: Node): Node { return findAncestor(getRootDeclaration(node), node => { switch (node.kind) { @@ -10501,10 +10502,13 @@ export function getDeclarationContainer(node: Node): Node { } })!.parent; } + +/** @internal */ export function isGlobalSourceFile(node: Node) { return node.kind === SyntaxKind.SourceFile && !isExternalOrCommonJsModule(node as SourceFile); } +/** @internal */ export function determineIfDeclarationIsVisible(node: Node, isDeclarationVisible: (node: Node) => boolean) { switch (node.kind) { case SyntaxKind.JSDocCallbackTag: diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 96b90b44696a5..bb6c36fe3516e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -8752,6 +8752,8 @@ declare namespace ts { readonly organizeImportsAccentCollation?: boolean; readonly organizeImportsCaseFirst?: "upper" | "lower" | false; readonly excludeLibrarySymbolsInNavTo?: boolean; + readonly includeInlineTypeFixes?: boolean; + readonly includeRelativeTypeFixes?: boolean; } /** Represents a bigint literal value without requiring bigint support */ interface PseudoBigInt { @@ -9827,6 +9829,11 @@ declare namespace ts { * @param context A lexical environment context for the visitor. */ function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; + function emitDeclarationsForProject(projectPath: string, files: string[] | undefined, options: CompilerOptions, host: CompilerHost): string; + function emitDeclarationsForFile(sourceFile: SourceFile, allProjectFiles: string[], tsLibFiles: string[], options: CompilerOptions): { + code: string; + diagnostics: Diagnostic[]; + }; function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined; function getOutputFileNames(commandLine: ParsedCommandLine, inputFileName: string, ignoreCase: boolean): readonly string[]; function createPrinter(printerOptions?: PrinterOptions, handlers?: PrintHandlers): Printer; @@ -10554,7 +10561,7 @@ declare namespace ts { getLinkedEditingRangeAtPosition(fileName: string, position: number): LinkedEditingInfo | undefined; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined; toLineColumnOffset?(fileName: string, position: number): LineAndCharacter; - getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: readonly number[], formatOptions: FormatCodeSettings, preferences: UserPreferences): readonly CodeFixAction[]; + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: readonly number[], formatOptions: FormatCodeSettings, preferences: UserPreferences, withDiagnostics?: Diagnostic[]): readonly CodeFixAction[]; getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions; applyCodeActionCommand(action: CodeActionCommand, formatSettings?: FormatCodeSettings): Promise; applyCodeActionCommand(action: CodeActionCommand[], formatSettings?: FormatCodeSettings): Promise; diff --git a/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.errors.txt b/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.errors.txt index 02e3da7fc0a3a..89a2e0e0c32e5 100644 --- a/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.errors.txt +++ b/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.errors.txt @@ -1,47 +1,47 @@ -tests/cases/conformance/classes/propertyMemberDeclarations/file3-2.ts(1,7): error TS2300: Duplicate identifier 'C3'. -tests/cases/conformance/classes/propertyMemberDeclarations/file3.ts(1,7): error TS2300: Duplicate identifier 'C3'. +file3-2.ts(1,7): error TS2300: Duplicate identifier 'C3'. +file3.ts(1,7): error TS2300: Duplicate identifier 'C3'. -==== tests/cases/conformance/classes/propertyMemberDeclarations/file1.ts (0 errors) ==== +==== file1.ts (0 errors) ==== // https://github.com/microsoft/TypeScript/issues/51528 class C1 { static accessor x = 0; } -==== tests/cases/conformance/classes/propertyMemberDeclarations/file2.ts (0 errors) ==== +==== file2.ts (0 errors) ==== class C2 { static accessor #x = 0; } -==== tests/cases/conformance/classes/propertyMemberDeclarations/file3.ts (1 errors) ==== +==== file3.ts (1 errors) ==== class C3 { ~~ !!! error TS2300: Duplicate identifier 'C3'. -!!! related TS6203 tests/cases/conformance/classes/propertyMemberDeclarations/file3-2.ts:1:7: 'C3' was also declared here. +!!! related TS6203 file3-2.ts:1:7: 'C3' was also declared here. static accessor #x = 0; accessor #y = 0; } -==== tests/cases/conformance/classes/propertyMemberDeclarations/file3-2.ts (1 errors) ==== +==== file3-2.ts (1 errors) ==== class C3 { ~~ !!! error TS2300: Duplicate identifier 'C3'. -!!! related TS6203 tests/cases/conformance/classes/propertyMemberDeclarations/file3.ts:1:7: 'C3' was also declared here. +!!! related TS6203 file3.ts:1:7: 'C3' was also declared here. accessor x = 0; } -==== tests/cases/conformance/classes/propertyMemberDeclarations/file4.ts (0 errors) ==== +==== file4.ts (0 errors) ==== class C4 { accessor #x = 0; } -==== tests/cases/conformance/classes/propertyMemberDeclarations/file5.ts (0 errors) ==== +==== file5.ts (0 errors) ==== class C5 { x = 0; accessor #x = 1; } -==== tests/cases/conformance/classes/propertyMemberDeclarations/file6.ts (0 errors) ==== +==== file6.ts (0 errors) ==== class C6 { accessor #x = 0; x = 1; diff --git a/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.symbols b/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.symbols index 4739c303d907a..2df26cb704247 100644 --- a/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.symbols +++ b/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.symbols @@ -22,17 +22,18 @@ class C3 { >C3 : Symbol(C3, Decl(file3.ts, 0, 0)) static accessor #x = 0; ->x : Symbol(C3.x, Decl(file3.ts, 0, 10)) +>#x : Symbol(C3.#x, Decl(file3.ts, 0, 10)) accessor #y = 0; +>#y : Symbol(C3.#y, Decl(file3.ts, 1, 27)) } -=== file3.ts === +=== file3-2.ts === class C3 { ->C3 : Symbol(C3, Decl(file3.ts, 0, 0)) +>C3 : Symbol(C3, Decl(file3-2.ts, 0, 0)) accessor x = 0; ->x : Symbol(C3.x, Decl(file3.ts, 0, 10)) +>x : Symbol(C3.x, Decl(file3-2.ts, 0, 10)) } === file4.ts === diff --git a/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.types b/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.types index c7ddf4f10e403..62a0c7691f7ab 100644 --- a/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.types +++ b/tests/baselines/reference/autoAccessorNoUseDefineForClassFields.types @@ -24,13 +24,15 @@ class C3 { >C3 : C3 static accessor #x = 0; ->x : number +>#x : number >0 : 0 accessor #y = 0; +>#y : number +>0 : 0 } -=== file3.ts === +=== file3-2.ts === class C3 { >C3 : C3 diff --git a/tests/baselines/reference/computedPropertiesNarrowed.errors.txt b/tests/baselines/reference/computedPropertiesNarrowed.errors.txt index d487673a3dceb..90be07ce96394 100644 --- a/tests/baselines/reference/computedPropertiesNarrowed.errors.txt +++ b/tests/baselines/reference/computedPropertiesNarrowed.errors.txt @@ -1,22 +1,20 @@ -tests/cases/compiler/computedPropertiesNarrowed.ts(4,16): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. -tests/cases/compiler/computedPropertiesNarrowed.ts(18,18): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. -tests/cases/compiler/computedPropertiesNarrowed.ts(21,17): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. -tests/cases/compiler/computedPropertiesNarrowed.ts(25,17): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. -tests/cases/compiler/computedPropertiesNarrowed.ts(36,17): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. -tests/cases/compiler/computedPropertiesNarrowed.ts(46,19): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. +computedPropertiesNarrowed.ts(5,5): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. +computedPropertiesNarrowed.ts(18,20): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. +computedPropertiesNarrowed.ts(22,5): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. +computedPropertiesNarrowed.ts(26,5): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. +computedPropertiesNarrowed.ts(37,5): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. +computedPropertiesNarrowed.ts(47,5): error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. -==== tests/cases/compiler/computedPropertiesNarrowed.ts (6 errors) ==== +==== computedPropertiesNarrowed.ts (6 errors) ==== const x: 0 | 1 = Math.random()? 0: 1; declare function assert(n: number): asserts n is 1; assert(x); export let o = { - ~ [x]: 1 // error narrow type !== declared type - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - } - ~ + ~~~ !!! error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. + } const y: 0 = 0 @@ -29,25 +27,21 @@ tests/cases/compiler/computedPropertiesNarrowed.ts(46,19): error TS9007: Declara export let o31 = { [-1]: 1 } export let o32 = { [1-1]: 1 } // error number - ~~~~~~~~~~~~ + ~~~~~ !!! error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. let u = Symbol(); export let o4 = { - ~ [u]: 1 // Should error, nut a unique symbol - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - } - ~ + ~~~ !!! error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. + } export let o5 ={ - ~ [Symbol()]: 1 // Should error - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - } - ~ + ~~~~~~~~~~ !!! error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. + } const uu: unique symbol = Symbol(); export let o6 = { @@ -57,12 +51,10 @@ tests/cases/compiler/computedPropertiesNarrowed.ts(46,19): error TS9007: Declara function foo (): 1 { return 1; } export let o7 = { - ~ [foo()]: 1 // Should error - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - }; - ~ + ~~~~~~~ !!! error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. + }; let E = { A: 1 } as const export const o8 = { @@ -71,10 +63,8 @@ tests/cases/compiler/computedPropertiesNarrowed.ts(46,19): error TS9007: Declara function ns() { return { v: 0 } as const } export const o9 = { - ~ [ns().v]: 1 - ~~~~~~~~~~~~~~~ - } - ~ + ~~~~~~~~ !!! error TS9007: Declaration emit for this file requires type resolution. An explicit type annotation may unblock declaration emit. + } \ No newline at end of file diff --git a/tests/baselines/reference/computedPropertiesNarrowed.js b/tests/baselines/reference/computedPropertiesNarrowed.js index d02723f3345d0..832b9aae4ac8c 100644 --- a/tests/baselines/reference/computedPropertiesNarrowed.js +++ b/tests/baselines/reference/computedPropertiesNarrowed.js @@ -1,3 +1,5 @@ +//// [tests/cases/compiler/computedPropertiesNarrowed.ts] //// + //// [computedPropertiesNarrowed.ts] const x: 0 | 1 = Math.random()? 0: 1; declare function assert(n: number): asserts n is 1; diff --git a/tests/baselines/reference/computedPropertiesNarrowed.symbols b/tests/baselines/reference/computedPropertiesNarrowed.symbols index 10f68a1bf3d46..0e46b6ff9ae97 100644 --- a/tests/baselines/reference/computedPropertiesNarrowed.symbols +++ b/tests/baselines/reference/computedPropertiesNarrowed.symbols @@ -1,4 +1,6 @@ -=== tests/cases/compiler/computedPropertiesNarrowed.ts === +//// [tests/cases/compiler/computedPropertiesNarrowed.ts] //// + +=== computedPropertiesNarrowed.ts === const x: 0 | 1 = Math.random()? 0: 1; >x : Symbol(x, Decl(computedPropertiesNarrowed.ts, 0, 5)) >Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) diff --git a/tests/baselines/reference/computedPropertiesNarrowed.types b/tests/baselines/reference/computedPropertiesNarrowed.types index d363ed47e7baa..82efb67ffb230 100644 --- a/tests/baselines/reference/computedPropertiesNarrowed.types +++ b/tests/baselines/reference/computedPropertiesNarrowed.types @@ -1,4 +1,6 @@ -=== tests/cases/compiler/computedPropertiesNarrowed.ts === +//// [tests/cases/compiler/computedPropertiesNarrowed.ts] //// + +=== computedPropertiesNarrowed.ts === const x: 0 | 1 = Math.random()? 0: 1; >x : 0 | 1 >Math.random()? 0: 1 : 0 | 1 diff --git a/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es2015).js b/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es2015).js index 23534aae989a0..961de87f1f567 100644 --- a/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es2015).js +++ b/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es2015).js @@ -62,7 +62,7 @@ let C = (() => { })(); export { C }; //// [c.js] -export default (() => { +let C = (() => { let _classDecorators = [dec]; let _classDescriptor; let _classExtraInitializers = []; @@ -71,12 +71,15 @@ export default (() => { }; __setFunctionName(_classThis, "C"); (() => { - __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name }, null, _classExtraInitializers); + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; + __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); C = _classThis = _classDescriptor.value; + if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); })(); return C = _classThis; })(); +export default C; //// [d.js] export default (() => { let _classDecorators = [dec]; diff --git a/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es2022).js b/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es2022).js index a0d7009e4e915..1d20151d0028e 100644 --- a/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es2022).js +++ b/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es2022).js @@ -62,20 +62,24 @@ let C = (() => { })(); export { C }; //// [c.js] -export default (() => { +let C = (() => { let _classDecorators = [dec]; let _classDescriptor; let _classExtraInitializers = []; let _classThis; var C = class { + static { _classThis = this; } static { - __esDecorate(null, _classDescriptor = { value: this }, _classDecorators, { kind: "class", name: this.name }, null, _classExtraInitializers); + const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; + __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); C = _classThis = _classDescriptor.value; + if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); } }; return C = _classThis; })(); +export default C; //// [d.js] export default (() => { let _classDecorators = [dec]; diff --git a/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es5).js b/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es5).js index 835f6c4893283..53320d7ba25a8 100644 --- a/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es5).js +++ b/tests/baselines/reference/esDecorators-classDeclaration-setFunctionName(target=es5).js @@ -86,8 +86,10 @@ var C = function () { }()); __setFunctionName(_classThis, "C"); (function () { - __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name }, null, _classExtraInitializers); + var _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0; + __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers); C = _classThis = _classDescriptor.value; + if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata }); __runInitializers(_classThis, _classExtraInitializers); })(); return C = _classThis; @@ -95,7 +97,6 @@ var C = function () { exports.default = C; //// [d.js] "use strict"; -var _this = this; Object.defineProperty(exports, "__esModule", { value: true }); var default_1 = function () { var _classDecorators = [dec]; diff --git a/tests/cases/fourslash/codeFixMissingTypeAnnotationOnExports29-fn-in-object-literal.ts b/tests/cases/fourslash/codeFixMissingTypeAnnotationOnExports29-fn-in-object-literal.ts index 458ccbc385d51..5a345c904e0a0 100644 --- a/tests/cases/fourslash/codeFixMissingTypeAnnotationOnExports29-fn-in-object-literal.ts +++ b/tests/cases/fourslash/codeFixMissingTypeAnnotationOnExports29-fn-in-object-literal.ts @@ -16,7 +16,7 @@ verify.codeFixAll({ fixId: "fixMissingTypeAnnotationOnExports", - fixAllDescription: ts.Diagnostics.Add_all_missing_tye_annotations.message, + fixAllDescription: ts.Diagnostics.Add_all_missing_type_annotations.message, newFileContent: `export const extensions = { /** diff --git a/tests/cases/fourslash/codeFixMissingTypeAnnotationOnExports30-non-exported-bidings.ts b/tests/cases/fourslash/codeFixMissingTypeAnnotationOnExports30-non-exported-bidings.ts index e7c70367baa6f..aaeaa5c4b6b95 100644 --- a/tests/cases/fourslash/codeFixMissingTypeAnnotationOnExports30-non-exported-bidings.ts +++ b/tests/cases/fourslash/codeFixMissingTypeAnnotationOnExports30-non-exported-bidings.ts @@ -10,7 +10,7 @@ verify.codeFixAll({ fixId: "fixMissingTypeAnnotationOnExports", - fixAllDescription: ts.Diagnostics.Add_all_missing_tye_annotations.message, + fixAllDescription: ts.Diagnostics.Add_all_missing_type_annotations.message, newFileContent: `let p = { x: 1, y: 2} const x: number = p.x;