From cd19de32c35d34f0d966586df3003ea5a2a163c4 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 16 Sep 2022 20:13:02 -0700 Subject: [PATCH 01/81] Fix some easy SFT problems --- src/compiler/checker.ts | 3 +- src/compiler/commandLineParser.ts | 5 +- src/compiler/core.ts | 23 +++--- src/compiler/factory/utilities.ts | 2 +- src/compiler/tsbuildPublic.ts | 128 +++++++++++++++--------------- src/compiler/utilities.ts | 10 +-- src/compiler/utilitiesPublic.ts | 34 ++++++-- src/compiler/watch.ts | 8 +- src/compiler/watchPublic.ts | 29 ++++++- src/tsconfig-base.json | 11 ++- 10 files changed, 156 insertions(+), 97 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 32cee9afa06da..6680344cc6768 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2930,7 +2930,8 @@ namespace ts { return valueSymbol; } const result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName); - result.declarations = deduplicate(concatenate(valueSymbol.declarations, typeSymbol.declarations), equateValues); + Debug.assert(valueSymbol.declarations || typeSymbol.declarations); + result.declarations = deduplicate(concatenate(valueSymbol.declarations!, typeSymbol.declarations), equateValues); result.parent = valueSymbol.parent || typeSymbol.parent; if (valueSymbol.valueDeclaration) result.valueDeclaration = valueSymbol.valueDeclaration; if (typeSymbol.members) result.members = new Map(typeSymbol.members); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 7ad3644970b6f..42c6b9f8f50a0 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -2668,7 +2668,7 @@ namespace ts { function convertToOptionValueWithAbsolutePaths(option: CommandLineOption | undefined, value: CompilerOptionsValue, toAbsolutePath: (path: string) => string) { if (option && !isNullOrUndefined(value)) { if (option.type === "list") { - const values = value as readonly (string | number)[]; + const values = value as readonly string[]; if (option.element.isFilePath && values.length) { return values.map(toAbsolutePath); } @@ -3560,7 +3560,8 @@ namespace ts { } } - function specToDiagnostic(spec: string, disallowTrailingRecursion?: boolean): [DiagnosticMessage, string] | undefined { + function specToDiagnostic(spec: CompilerOptionsValue, disallowTrailingRecursion?: boolean): [DiagnosticMessage, string] | undefined { + Debug.assert(typeof spec === "string"); if (disallowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { return [Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec]; } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 934f5ace84990..9401500bb2801 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -454,7 +454,7 @@ namespace ts { */ export function sameFlatMap(array: T[], mapfn: (x: T, i: number) => T | readonly T[]): T[]; export function sameFlatMap(array: readonly T[], mapfn: (x: T, i: number) => T | readonly T[]): readonly T[]; - export function sameFlatMap(array: T[], mapfn: (x: T, i: number) => T | T[]): T[] { + export function sameFlatMap(array: readonly T[], mapfn: (x: T, i: number) => T | readonly T[]): readonly T[] { let result: T[] | undefined; if (array) { for (let i = 0; i < array.length; i++) { @@ -685,9 +685,13 @@ namespace ts { export function concatenate(array1: T[], array2: T[]): T[]; export function concatenate(array1: readonly T[], array2: readonly T[]): readonly T[]; - export function concatenate(array1: T[] | undefined, array2: T[] | undefined): T[]; - export function concatenate(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[]; - export function concatenate(array1: T[], array2: T[]): T[] { + export function concatenate(array1: T[], array2: T[] | undefined): T[]; // eslint-disable-line @typescript-eslint/unified-signatures + export function concatenate(array1: T[] | undefined, array2: T[]): T[]; // eslint-disable-line @typescript-eslint/unified-signatures + export function concatenate(array1: readonly T[], array2: readonly T[] | undefined): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures + export function concatenate(array1: readonly T[] | undefined, array2: readonly T[]): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures + export function concatenate(array1: T[] | undefined, array2: T[] | undefined): T[] | undefined; + export function concatenate(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined; + export function concatenate(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined { if (!some(array2)) return array1; if (!some(array1)) return array2; return [...array1, ...array2]; @@ -842,7 +846,7 @@ namespace ts { // 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 export function compact(array: T[]): T[]; // eslint-disable-line @typescript-eslint/unified-signatures export function compact(array: readonly T[]): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures - export function compact(array: T[]): T[] { + export function compact(array: readonly T[]): readonly T[] { let result: T[] | undefined; if (array) { for (let i = 0; i < array.length; i++) { @@ -924,11 +928,12 @@ namespace ts { export function append(to: T[] | undefined, value: T): T[]; export function append(to: T[] | undefined, value: T | undefined): T[] | undefined; export function append(to: Push, value: T | undefined): void; - export function append(to: T[], value: T | undefined): T[] | undefined { - if (value === undefined) return to; + export function append(to: Push | T[] | undefined, value: T | undefined): T[] | undefined { + // If to is Push, return value is void, so safe to cast to T[]. + if (value === undefined) return to as T[]; if (to === undefined) return [value]; to.push(value); - return to; + return to as T[]; } /** @@ -1197,7 +1202,7 @@ namespace ts { export function reduceLeft(array: readonly T[] | undefined, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U; export function reduceLeft(array: readonly T[], f: (memo: T, value: T, i: number) => T): T | undefined; - export function reduceLeft(array: T[], f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T | undefined { + export function reduceLeft(array: readonly T[] | undefined, f: (memo: T, value: T, i: number) => T, initial?: T, start?: number, count?: number): T | undefined { if (array && array.length > 0) { const size = array.length; if (size > 0) { diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index 6c7f02c240f2e..c413ddc313762 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -1219,7 +1219,7 @@ namespace ts { const machine = new BinaryExpressionStateMachine(onEnter, onLeft, onOperator, onRight, onExit, foldState); return trampoline; - function trampoline(node: BinaryExpression, outerState?: TOuterState) { + function trampoline(node: BinaryExpression, outerState: TOuterState) { const resultHolder: { value: TResult } = { value: undefined! }; const stateStack: BinaryExpressionState[] = [BinaryExpressionState.enter]; const nodeStack: BinaryExpression[] = [node]; diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 0849c5921f29a..603774e63a131 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -227,7 +227,7 @@ namespace ts { latestChangedDtsTime?: Date | false; } - interface SolutionBuilderState extends WatchFactory { + interface SolutionBuilderState extends WatchFactory { readonly host: SolutionBuilderHost; readonly hostWithWatch: SolutionBuilderWithWatchHost; readonly currentDirectory: string; @@ -374,11 +374,11 @@ namespace ts { return state; } - function toPath(state: SolutionBuilderState, fileName: string) { + function toPath(state: SolutionBuilderState, fileName: string) { return ts.toPath(fileName, state.currentDirectory, state.getCanonicalFileName); } - function toResolvedConfigFilePath(state: SolutionBuilderState, fileName: ResolvedConfigFileName): ResolvedConfigFilePath { + function toResolvedConfigFilePath(state: SolutionBuilderState, fileName: ResolvedConfigFileName): ResolvedConfigFilePath { const { resolvedConfigFilePaths } = state; const path = resolvedConfigFilePaths.get(fileName); if (path !== undefined) return path; @@ -392,12 +392,12 @@ namespace ts { return !!(entry as ParsedCommandLine).options; } - function getCachedParsedConfigFile(state: SolutionBuilderState, configFilePath: ResolvedConfigFilePath): ParsedCommandLine | undefined { + function getCachedParsedConfigFile(state: SolutionBuilderState, configFilePath: ResolvedConfigFilePath): ParsedCommandLine | undefined { const value = state.configFileCache.get(configFilePath); return value && isParsedCommandLine(value) ? value : undefined; } - function parseConfigFile(state: SolutionBuilderState, configFileName: ResolvedConfigFileName, configFilePath: ResolvedConfigFilePath): ParsedCommandLine | undefined { + function parseConfigFile(state: SolutionBuilderState, configFileName: ResolvedConfigFileName, configFilePath: ResolvedConfigFilePath): ParsedCommandLine | undefined { const { configFileCache } = state; const value = configFileCache.get(configFilePath); if (value) { @@ -423,11 +423,11 @@ namespace ts { return parsed; } - function resolveProjectName(state: SolutionBuilderState, name: string): ResolvedConfigFileName { + function resolveProjectName(state: SolutionBuilderState, name: string): ResolvedConfigFileName { return resolveConfigFileProjectName(resolvePath(state.currentDirectory, name)); } - function createBuildOrder(state: SolutionBuilderState, roots: readonly ResolvedConfigFileName[]): AnyBuildOrder { + function createBuildOrder(state: SolutionBuilderState, roots: readonly ResolvedConfigFileName[]): AnyBuildOrder { const temporaryMarks = new Map(); const permanentMarks = new Map(); const circularityReportStack: string[] = []; @@ -474,11 +474,11 @@ namespace ts { } } - function getBuildOrder(state: SolutionBuilderState) { + function getBuildOrder(state: SolutionBuilderState) { return state.buildOrder || createStateBuildOrder(state); } - function createStateBuildOrder(state: SolutionBuilderState) { + function createStateBuildOrder(state: SolutionBuilderState) { const buildOrder = createBuildOrder(state, state.rootNames.map(f => resolveProjectName(state, f))); // Clear all to ResolvedConfigFilePaths cache to start fresh @@ -539,7 +539,7 @@ namespace ts { return state.buildOrder = buildOrder; } - function getBuildOrderFor(state: SolutionBuilderState, project: string | undefined, onlyReferences: boolean | undefined): AnyBuildOrder | undefined { + function getBuildOrderFor(state: SolutionBuilderState, project: string | undefined, onlyReferences: boolean | undefined): AnyBuildOrder | undefined { const resolvedProject = project && resolveProjectName(state, project); const buildOrderFromState = getBuildOrder(state); if (isCircularBuildOrder(buildOrderFromState)) return buildOrderFromState; @@ -558,7 +558,7 @@ namespace ts { return onlyReferences ? buildOrder.slice(0, buildOrder.length - 1) : buildOrder; } - function enableCache(state: SolutionBuilderState) { + function enableCache(state: SolutionBuilderState) { if (state.cache) { disableCache(state); } @@ -591,7 +591,7 @@ namespace ts { }; } - function disableCache(state: SolutionBuilderState) { + function disableCache(state: SolutionBuilderState) { if (!state.cache) return; const { cache, host, compilerHost, extendedConfigCache, moduleResolutionCache, typeReferenceDirectiveResolutionCache } = state; @@ -609,12 +609,12 @@ namespace ts { state.cache = undefined; } - function clearProjectStatus(state: SolutionBuilderState, resolved: ResolvedConfigFilePath) { + function clearProjectStatus(state: SolutionBuilderState, resolved: ResolvedConfigFilePath) { state.projectStatus.delete(resolved); state.diagnostics.delete(resolved); } - function addProjToQueue({ projectPendingBuild }: SolutionBuilderState, proj: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) { + function addProjToQueue({ projectPendingBuild }: SolutionBuilderState, proj: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) { const value = projectPendingBuild.get(proj); if (value === undefined) { projectPendingBuild.set(proj, reloadLevel); @@ -624,7 +624,7 @@ namespace ts { } } - function setupInitialBuild(state: SolutionBuilderState, cancellationToken: CancellationToken | undefined) { + function setupInitialBuild(state: SolutionBuilderState, cancellationToken: CancellationToken | undefined) { // Set initial build if not already built if (!state.allProjectBuildPending) return; state.allProjectBuildPending = false; @@ -704,8 +704,8 @@ namespace ts { export type InvalidatedProject = UpdateOutputFileStampsProject | BuildInvalidedProject | UpdateBundleProject; - function doneInvalidatedProject( - state: SolutionBuilderState, + function doneInvalidatedProject( + state: SolutionBuilderState, projectPath: ResolvedConfigFilePath ) { state.projectPendingBuild.delete(projectPath); @@ -714,8 +714,8 @@ namespace ts { ExitStatus.Success; } - function createUpdateOutputFileStampsProject( - state: SolutionBuilderState, + function createUpdateOutputFileStampsProject( + state: SolutionBuilderState, project: ResolvedConfigFileName, projectPath: ResolvedConfigFilePath, config: ParsedCommandLine, @@ -1186,7 +1186,7 @@ namespace ts { } } - function needsBuild({ options }: SolutionBuilderState, status: UpToDateStatus, config: ParsedCommandLine) { + function needsBuild({ options }: SolutionBuilderState, status: UpToDateStatus, config: ParsedCommandLine) { if (status.type !== UpToDateStatusType.OutOfDateWithPrepend || options.force) return true; return config.fileNames.length === 0 || !!getConfigFileParsingDiagnostics(config).length || @@ -1346,7 +1346,7 @@ namespace ts { return createInvalidatedProjectWithInfo(state, info, buildOrder); } - function listEmittedFile({ write }: SolutionBuilderState, proj: ParsedCommandLine, file: string) { + function listEmittedFile({ write }: SolutionBuilderState, proj: ParsedCommandLine, file: string) { if (write && proj.options.listEmittedFiles) { write(`TSFILE: ${file}`); } @@ -1400,7 +1400,7 @@ namespace ts { return !!(value as FileWatcherWithModifiedTime).watcher; } - function getModifiedTime(state: SolutionBuilderState, fileName: string): Date { + function getModifiedTime(state: SolutionBuilderState, fileName: string): Date { const path = toPath(state, fileName); const existing = state.filesWatched.get(path); if (state.watch && !!existing) { @@ -1418,7 +1418,7 @@ namespace ts { return result; } - function watchFile(state: SolutionBuilderState, file: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, options: WatchOptions | undefined, watchType: WatchType, project?: ResolvedConfigFileName): FileWatcher { + function watchFile(state: SolutionBuilderState, file: string, callback: FileWatcherCallback, pollingInterval: PollingInterval, options: WatchOptions | undefined, watchType: WatchType, project?: ResolvedConfigFileName): FileWatcher { const path = toPath(state, file); const existing = state.filesWatched.get(path); if (existing && isFileWatcherWithModifiedTime(existing)) { @@ -1456,7 +1456,7 @@ namespace ts { }; } - function getOutputTimeStampMap(state: SolutionBuilderState, resolvedConfigFilePath: ResolvedConfigFilePath) { + function getOutputTimeStampMap(state: SolutionBuilderState, resolvedConfigFilePath: ResolvedConfigFilePath) { // Output timestamps are stored only in watch mode if (!state.watch) return undefined; let result = state.outputTimeStamps.get(resolvedConfigFilePath); @@ -1464,8 +1464,8 @@ namespace ts { return result; } - function setBuildInfo( - state: SolutionBuilderState, + function setBuildInfo( + state: SolutionBuilderState, buildInfo: BuildInfo, resolvedConfigPath: ResolvedConfigFilePath, options: CompilerOptions, @@ -1489,13 +1489,13 @@ namespace ts { } } - function getBuildInfoCacheEntry(state: SolutionBuilderState, buildInfoPath: string, resolvedConfigPath: ResolvedConfigFilePath) { + function getBuildInfoCacheEntry(state: SolutionBuilderState, buildInfoPath: string, resolvedConfigPath: ResolvedConfigFilePath) { const path = toPath(state, buildInfoPath); const existing = state.buildInfoCache.get(resolvedConfigPath); return existing?.path === path ? existing : undefined; } - function getBuildInfo(state: SolutionBuilderState, buildInfoPath: string, resolvedConfigPath: ResolvedConfigFilePath, modifiedTime: Date | undefined): BuildInfo | undefined { + function getBuildInfo(state: SolutionBuilderState, buildInfoPath: string, resolvedConfigPath: ResolvedConfigFilePath, modifiedTime: Date | undefined): BuildInfo | undefined { const path = toPath(state, buildInfoPath); const existing = state.buildInfoCache.get(resolvedConfigPath); if (existing !== undefined && existing.path === path) { @@ -1507,7 +1507,7 @@ namespace ts { return buildInfo; } - function checkConfigFileUpToDateStatus(state: SolutionBuilderState, configFile: string, oldestOutputFileTime: Date, oldestOutputFileName: string): Status.OutOfDateWithSelf | undefined { + function checkConfigFileUpToDateStatus(state: SolutionBuilderState, configFile: string, oldestOutputFileTime: Date, oldestOutputFileName: string): Status.OutOfDateWithSelf | undefined { // Check tsconfig time const tsconfigTime = getModifiedTime(state, configFile); if (oldestOutputFileTime < tsconfigTime) { @@ -1519,7 +1519,7 @@ namespace ts { } } - function getUpToDateStatusWorker(state: SolutionBuilderState, project: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath): UpToDateStatus { + function getUpToDateStatusWorker(state: SolutionBuilderState, project: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath): UpToDateStatus { // Container if no files are specified in the project if (!project.fileNames.length && !canJsonReportNoInputFiles(project.raw)) { return { @@ -1784,12 +1784,12 @@ namespace ts { }; } - function hasSameBuildInfo(state: SolutionBuilderState, buildInfoCacheEntry: BuildInfoCacheEntry, resolvedRefPath: ResolvedConfigFilePath) { + function hasSameBuildInfo(state: SolutionBuilderState, buildInfoCacheEntry: BuildInfoCacheEntry, resolvedRefPath: ResolvedConfigFilePath) { const refBuildInfo = state.buildInfoCache.get(resolvedRefPath)!; return refBuildInfo.path === buildInfoCacheEntry.path; } - function getUpToDateStatus(state: SolutionBuilderState, project: ParsedCommandLine | undefined, resolvedPath: ResolvedConfigFilePath): UpToDateStatus { + function getUpToDateStatus(state: SolutionBuilderState, project: ParsedCommandLine | undefined, resolvedPath: ResolvedConfigFilePath): UpToDateStatus { if (project === undefined) { return { type: UpToDateStatusType.Unbuildable, reason: "File deleted mid-build" }; } @@ -1807,8 +1807,8 @@ namespace ts { return actual; } - function updateOutputTimestampsWorker( - state: SolutionBuilderState, + function updateOutputTimestampsWorker( + state: SolutionBuilderState, proj: ParsedCommandLine, projectPath: ResolvedConfigFilePath, verboseMessage: DiagnosticMessage, @@ -1857,7 +1857,7 @@ namespace ts { }); } - function getLatestChangedDtsTime(state: SolutionBuilderState, options: CompilerOptions, resolvedConfigPath: ResolvedConfigFilePath) { + function getLatestChangedDtsTime(state: SolutionBuilderState, options: CompilerOptions, resolvedConfigPath: ResolvedConfigFilePath) { if (!options.composite) return undefined; const entry = Debug.checkDefined(state.buildInfoCache.get(resolvedConfigPath)); if (entry.latestChangedDtsTime !== undefined) return entry.latestChangedDtsTime || undefined; @@ -1868,7 +1868,7 @@ namespace ts { return latestChangedDtsTime; } - function updateOutputTimestamps(state: SolutionBuilderState, proj: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath) { + function updateOutputTimestamps(state: SolutionBuilderState, proj: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath) { if (state.options.dry) { return reportStatus(state, Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath!); } @@ -1879,8 +1879,8 @@ namespace ts { }); } - function queueReferencingProjects( - state: SolutionBuilderState, + function queueReferencingProjects( + state: SolutionBuilderState, project: ResolvedConfigFileName, projectPath: ResolvedConfigFilePath, projectIndex: number, @@ -1950,7 +1950,7 @@ namespace ts { } } - function build(state: SolutionBuilderState, project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers, onlyReferences?: boolean): ExitStatus { + function build(state: SolutionBuilderState, project?: string, cancellationToken?: CancellationToken, writeFile?: WriteFileCallback, getCustomTransformers?: (project: string) => CustomTransformers, onlyReferences?: boolean): ExitStatus { performance.mark("SolutionBuilder::beforeBuild"); const result = buildWorker(state, project, cancellationToken, writeFile, getCustomTransformers, onlyReferences); performance.mark("SolutionBuilder::afterBuild"); @@ -1958,7 +1958,7 @@ namespace ts { return result; } - function buildWorker(state: SolutionBuilderState, project: string | undefined, cancellationToken: CancellationToken | undefined, writeFile: WriteFileCallback | undefined, getCustomTransformers: ((project: string) => CustomTransformers) | undefined, onlyReferences: boolean | undefined): ExitStatus { + function buildWorker(state: SolutionBuilderState, project: string | undefined, cancellationToken: CancellationToken | undefined, writeFile: WriteFileCallback | undefined, getCustomTransformers: ((project: string) => CustomTransformers) | undefined, onlyReferences: boolean | undefined): ExitStatus { const buildOrder = getBuildOrderFor(state, project, onlyReferences); if (!buildOrder) return ExitStatus.InvalidProject_OutputsSkipped; @@ -1987,7 +1987,7 @@ namespace ts { : ExitStatus.DiagnosticsPresent_OutputsSkipped; } - function clean(state: SolutionBuilderState, project?: string, onlyReferences?: boolean): ExitStatus { + function clean(state: SolutionBuilderState, project?: string, onlyReferences?: boolean): ExitStatus { performance.mark("SolutionBuilder::beforeClean"); const result = cleanWorker(state, project, onlyReferences); performance.mark("SolutionBuilder::afterClean"); @@ -1995,7 +1995,7 @@ namespace ts { return result; } - function cleanWorker(state: SolutionBuilderState, project: string | undefined, onlyReferences: boolean | undefined) { + function cleanWorker(state: SolutionBuilderState, project: string | undefined, onlyReferences: boolean | undefined) { const buildOrder = getBuildOrderFor(state, project, onlyReferences); if (!buildOrder) return ExitStatus.InvalidProject_OutputsSkipped; @@ -2039,7 +2039,7 @@ namespace ts { return ExitStatus.Success; } - function invalidateProject(state: SolutionBuilderState, resolved: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) { + function invalidateProject(state: SolutionBuilderState, resolved: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) { // If host implements getParsedCommandLine, we cant get list of files from parseConfigFileHost if (state.host.getParsedCommandLine && reloadLevel === ConfigFileProgramReloadLevel.Partial) { reloadLevel = ConfigFileProgramReloadLevel.Full; @@ -2054,13 +2054,13 @@ namespace ts { enableCache(state); } - function invalidateProjectAndScheduleBuilds(state: SolutionBuilderState, resolvedPath: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) { + function invalidateProjectAndScheduleBuilds(state: SolutionBuilderState, resolvedPath: ResolvedConfigFilePath, reloadLevel: ConfigFileProgramReloadLevel) { state.reportFileChangeDetected = true; invalidateProject(state, resolvedPath, reloadLevel); scheduleBuildInvalidatedProject(state, 250, /*changeDetected*/ true); } - function scheduleBuildInvalidatedProject(state: SolutionBuilderState, time: number, changeDetected: boolean) { + function scheduleBuildInvalidatedProject(state: SolutionBuilderState, time: number, changeDetected: boolean) { const { hostWithWatch } = state; if (!hostWithWatch.setTimeout || !hostWithWatch.clearTimeout) { return; @@ -2071,7 +2071,7 @@ namespace ts { state.timerToBuildInvalidatedProject = hostWithWatch.setTimeout(buildNextInvalidatedProject, time, state, changeDetected); } - function buildNextInvalidatedProject(state: SolutionBuilderState, changeDetected: boolean) { + function buildNextInvalidatedProject(state: SolutionBuilderState, changeDetected: boolean) { performance.mark("SolutionBuilder::beforeBuild"); const buildOrder = buildNextInvalidatedProjectWorker(state, changeDetected); performance.mark("SolutionBuilder::afterBuild"); @@ -2079,7 +2079,7 @@ namespace ts { if (buildOrder) reportErrorSummary(state, buildOrder); } - function buildNextInvalidatedProjectWorker(state: SolutionBuilderState, changeDetected: boolean) { + function buildNextInvalidatedProjectWorker(state: SolutionBuilderState, changeDetected: boolean) { state.timerToBuildInvalidatedProject = undefined; if (state.reportFileChangeDetected) { state.reportFileChangeDetected = false; @@ -2112,7 +2112,7 @@ namespace ts { return buildOrder; } - function watchConfigFile(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine | undefined) { + function watchConfigFile(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine | undefined) { if (!state.watch || state.allWatchedConfigFiles.has(resolvedPath)) return; state.allWatchedConfigFiles.set(resolvedPath, watchFile( state, @@ -2125,7 +2125,7 @@ namespace ts { )); } - function watchExtendedConfigFiles(state: SolutionBuilderState, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine | undefined) { + function watchExtendedConfigFiles(state: SolutionBuilderState, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine | undefined) { updateSharedExtendedConfigFileWatcher( resolvedPath, parsed?.options, @@ -2143,7 +2143,7 @@ namespace ts { ); } - function watchWildCardDirectories(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) { + function watchWildCardDirectories(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) { if (!state.watch) return; updateWatchingWildcardDirectories( getOrCreateValueMapFromConfigFileMap(state.allWatchedWildcardDirectories, resolvedPath), @@ -2174,7 +2174,7 @@ namespace ts { ); } - function watchInputFiles(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) { + function watchInputFiles(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) { if (!state.watch) return; mutateMap( getOrCreateValueMapFromConfigFileMap(state.allWatchedInputFiles, resolvedPath), @@ -2194,7 +2194,7 @@ namespace ts { ); } - function watchPackageJsonFiles(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) { + function watchPackageJsonFiles(state: SolutionBuilderState, resolved: ResolvedConfigFileName, resolvedPath: ResolvedConfigFilePath, parsed: ParsedCommandLine) { if (!state.watch || !state.lastCachedPackageJsonLookups) return; mutateMap( getOrCreateValueMapFromConfigFileMap(state.allWatchedPackageJsonFiles, resolvedPath), @@ -2214,7 +2214,7 @@ namespace ts { ); } - function startWatching(state: SolutionBuilderState, buildOrder: AnyBuildOrder) { + function startWatching(state: SolutionBuilderState, buildOrder: AnyBuildOrder) { if (!state.watchAllProjectsPending) return; performance.mark("SolutionBuilder::beforeWatcherCreation"); state.watchAllProjectsPending = false; @@ -2239,7 +2239,7 @@ namespace ts { performance.measure("SolutionBuilder::Watcher creation", "SolutionBuilder::beforeWatcherCreation", "SolutionBuilder::afterWatcherCreation"); } - function stopWatching(state: SolutionBuilderState) { + function stopWatching(state: SolutionBuilderState) { clearMap(state.allWatchedConfigFiles, closeFileWatcher); clearMap(state.allWatchedExtendedConfigFiles, closeFileWatcherOf); clearMap(state.allWatchedWildcardDirectories, watchedWildcardDirectories => clearMap(watchedWildcardDirectories, closeFileWatcherOf)); @@ -2275,23 +2275,23 @@ namespace ts { }; } - function relName(state: SolutionBuilderState, path: string): string { + function relName(state: SolutionBuilderState, path: string): string { return convertToRelativePath(path, state.currentDirectory, f => state.getCanonicalFileName(f)); } - function reportStatus(state: SolutionBuilderState, message: DiagnosticMessage, ...args: string[]) { + function reportStatus(state: SolutionBuilderState, message: DiagnosticMessage, ...args: string[]) { state.host.reportSolutionBuilderStatus(createCompilerDiagnostic(message, ...args)); } - function reportWatchStatus(state: SolutionBuilderState, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + function reportWatchStatus(state: SolutionBuilderState, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { state.hostWithWatch.onWatchStatusChange?.(createCompilerDiagnostic(message, ...args), state.host.getNewLine(), state.baseCompilerOptions); } - function reportErrors({ host }: SolutionBuilderState, errors: readonly Diagnostic[]) { + function reportErrors({ host }: SolutionBuilderState, errors: readonly Diagnostic[]) { errors.forEach(err => host.reportDiagnostic(err)); } - function reportAndStoreErrors(state: SolutionBuilderState, proj: ResolvedConfigFilePath, errors: readonly Diagnostic[]) { + function reportAndStoreErrors(state: SolutionBuilderState, proj: ResolvedConfigFilePath, errors: readonly Diagnostic[]) { reportErrors(state, errors); state.projectErrorsReported.set(proj, true); if (errors.length) { @@ -2299,11 +2299,11 @@ namespace ts { } } - function reportParseConfigFileDiagnostic(state: SolutionBuilderState, proj: ResolvedConfigFilePath) { + function reportParseConfigFileDiagnostic(state: SolutionBuilderState, proj: ResolvedConfigFilePath) { reportAndStoreErrors(state, proj, [state.configFileCache.get(proj) as Diagnostic]); } - function reportErrorSummary(state: SolutionBuilderState, buildOrder: AnyBuildOrder) { + function reportErrorSummary(state: SolutionBuilderState, buildOrder: AnyBuildOrder) { if (!state.needsSummary) return; state.needsSummary = false; const canReportSummary = state.watch || !!state.host.reportErrorSummary; @@ -2339,13 +2339,13 @@ namespace ts { /** * Report the build ordering inferred from the current project graph if we're in verbose mode */ - function reportBuildQueue(state: SolutionBuilderState, buildQueue: readonly ResolvedConfigFileName[]) { + function reportBuildQueue(state: SolutionBuilderState, buildQueue: readonly ResolvedConfigFileName[]) { if (state.options.verbose) { reportStatus(state, Diagnostics.Projects_in_this_build_Colon_0, buildQueue.map(s => "\r\n * " + relName(state, s)).join("")); } } - function reportUpToDateStatus(state: SolutionBuilderState, configFileName: string, status: UpToDateStatus) { + function reportUpToDateStatus(state: SolutionBuilderState, configFileName: string, status: UpToDateStatus) { switch (status.type) { case UpToDateStatusType.OutOfDateWithSelf: return reportStatus( @@ -2466,7 +2466,7 @@ namespace ts { /** * Report the up-to-date status of a project if we're in verbose mode */ - function verboseReportProjectStatus(state: SolutionBuilderState, configFileName: string, status: UpToDateStatus) { + function verboseReportProjectStatus(state: SolutionBuilderState, configFileName: string, status: UpToDateStatus) { if (state.options.verbose) { reportUpToDateStatus(state, configFileName, status); } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 792c7d1f5cb3c..9198cd7690b20 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -264,7 +264,7 @@ namespace ts { export function getSourceFileOfNode(node: Node): SourceFile; export function getSourceFileOfNode(node: Node | undefined): SourceFile | undefined; - export function getSourceFileOfNode(node: Node): SourceFile { + export function getSourceFileOfNode(node: Node | undefined): SourceFile | undefined { while (node && node.kind !== SyntaxKind.SourceFile) { node = node.parent; } @@ -886,8 +886,8 @@ namespace ts { return false; } - export function isDeclarationWithTypeParameters(node: Node): node is DeclarationWithTypeParameters; - export function isDeclarationWithTypeParameters(node: DeclarationWithTypeParameters): node is DeclarationWithTypeParameters { + export function isDeclarationWithTypeParameters(node: Node): node is DeclarationWithTypeParameters { + Debug.type(node); switch (node.kind) { case SyntaxKind.JSDocCallbackTag: case SyntaxKind.JSDocTypedefTag: @@ -899,8 +899,8 @@ namespace ts { } } - export function isDeclarationWithTypeParameterChildren(node: Node): node is DeclarationWithTypeParameterChildren; - export function isDeclarationWithTypeParameterChildren(node: DeclarationWithTypeParameterChildren): node is DeclarationWithTypeParameterChildren { + export function isDeclarationWithTypeParameterChildren(node: Node): node is DeclarationWithTypeParameterChildren { + Debug.type(node); switch (node.kind) { case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index c8b959eb8f87c..e317c1c261176 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -269,7 +269,9 @@ namespace ts { return false; } - export function isEmptyBindingElement(node: BindingElement): boolean { + // TODO(jakebailey): It is very weird that we have BindingElement and ArrayBindingElement; + // we should have ObjectBindingElement and ArrayBindingElement, which are both BindingElement. + export function isEmptyBindingElement(node: BindingElement | ArrayBindingElement): boolean { if (isOmittedExpression(node)) { return true; } @@ -397,18 +399,24 @@ namespace ts { } } + // TODO(jakebailey): I've changed this signature in an incompatible way. + // The original signatures didn't seem to make any sense, but I'm willing to be wrong. export function getOriginalNode(node: Node): Node; export function getOriginalNode(node: Node, nodeTest: (node: Node) => node is T): T; export function getOriginalNode(node: Node | undefined): Node | undefined; - export function getOriginalNode(node: Node | undefined, nodeTest: (node: Node | undefined) => node is T): T | undefined; - export function getOriginalNode(node: Node | undefined, nodeTest?: (node: Node | undefined) => boolean): Node | undefined { + export function getOriginalNode(node: Node | undefined, nodeTest: (node: Node) => node is T): T | undefined; + export function getOriginalNode(node: Node | undefined, nodeTest?: (node: Node) => node is T): T | undefined { if (node) { while (node.original !== undefined) { node = node.original; } } - return !nodeTest || nodeTest(node) ? node : undefined; + if (!node || !nodeTest) { + return node as T | undefined; + } + + return nodeTest(node) ? node : undefined; } /** @@ -419,7 +427,7 @@ namespace ts { */ export function findAncestor(node: Node | undefined, callback: (element: Node) => element is T): T | undefined; export function findAncestor(node: Node | undefined, callback: (element: Node) => boolean | "quit"): Node | undefined; - export function findAncestor(node: Node, callback: (element: Node) => boolean | "quit"): Node | undefined { + export function findAncestor(node: Node | undefined, callback: (element: Node) => boolean | "quit"): Node | undefined { while (node) { const result = callback(node); if (result === "quit") { @@ -1532,6 +1540,22 @@ namespace ts { return false; } + /* @internal */ + export function isArrayBindingOrAssignmentElement(node: Node): node is ArrayBindingOrAssignmentElement { + switch (node.kind) { + case SyntaxKind.BindingElement: + case SyntaxKind.OmittedExpression: // Elision + case SyntaxKind.SpreadElement: // AssignmentRestElement + case SyntaxKind.ArrayLiteralExpression: // ArrayAssignmentPattern + case SyntaxKind.ObjectLiteralExpression: // ObjectAssignmentPattern + case SyntaxKind.Identifier: // DestructuringAssignmentTarget + case SyntaxKind.PropertyAccessExpression: // DestructuringAssignmentTarget + case SyntaxKind.ElementAccessExpression: // DestructuringAssignmentTarget + return true; + } + return isAssignmentExpression(node, /*excludeCompoundAssignment*/ true); // AssignmentElement + } + /* @internal */ export function isPropertyAccessOrQualifiedNameOrImportTypeNode(node: Node): node is PropertyAccessExpression | QualifiedName | ImportTypeNode { const kind = node.kind; diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index d1851cd02cd08..17f73b716eb1a 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -109,7 +109,11 @@ namespace ts { if(errorDiagnostic.file === undefined) return; return `${errorDiagnostic.file.fileName}`; }); - return filesInError.map((fileName: string) => { + return filesInError.map((fileName) => { + if (fileName === undefined) { + return undefined; + } + const diagnosticForFileName = find(diagnostics, diagnostic => diagnostic.file !== undefined && diagnostic.file.fileName === fileName ); @@ -633,7 +637,7 @@ namespace ts { storeFilesChangingSignatureDuringEmit: host.storeFilesChangingSignatureDuringEmit, }; - function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, onError: (message: string) => void) { + function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, onError?: (message: string) => void) { try { performance.mark("beforeIOWrite"); diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index 51f58d396c59c..23fad3c09169b 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -254,6 +254,11 @@ namespace ts { reloadLevel?: ConfigFileProgramReloadLevel.Partial | ConfigFileProgramReloadLevel.Full; } + // All of one and partial of the other, or vice versa. + type WatchCompilerHostOfFilesAndCompilerOptionsOrConfigFile = + | WatchCompilerHostOfFilesAndCompilerOptions & Partial> + | WatchCompilerHostOfConfigFile & Partial>; + /** * Creates the watch from the host for root files and compiler options */ @@ -262,7 +267,7 @@ namespace ts { * Creates the watch from the host for config file */ export function createWatchProgram(host: WatchCompilerHostOfConfigFile): WatchOfConfigFile; - export function createWatchProgram(host: WatchCompilerHostOfFilesAndCompilerOptions & WatchCompilerHostOfConfigFile): WatchOfFilesAndCompilerOptions | WatchOfConfigFile { + export function createWatchProgram(host: WatchCompilerHostOfFilesAndCompilerOptionsOrConfigFile): WatchOfFilesAndCompilerOptions | WatchOfConfigFile { interface FilePresentOnHost { version: string; sourceFile: SourceFile; @@ -318,6 +323,9 @@ namespace ts { newLine = updateNewLine(); } + Debug.assert(compilerOptions); + Debug.assert(rootFileNames); + const { watchFile, watchDirectory, writeLog } = createWatchFactory(host, compilerOptions); const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); @@ -327,7 +335,7 @@ namespace ts { configFileWatcher = watchFile(configFileName, scheduleProgramReload, PollingInterval.High, watchOptions, WatchType.ConfigFile); } - const compilerHost = createCompilerHostFromProgramHost(host, () => compilerOptions, directoryStructureHost) as CompilerHost & ResolutionCacheHost; + const compilerHost = createCompilerHostFromProgramHost(host, () => compilerOptions!, directoryStructureHost) as CompilerHost & ResolutionCacheHost; setGetSourceFileAsHashVersioned(compilerHost, host); // Members for CompilerHost const getNewSourceFile = compilerHost.getSourceFile; @@ -339,7 +347,7 @@ namespace ts { compilerHost.onReleaseParsedCommandLine = onReleaseParsedCommandLine; // Members for ResolutionCacheHost compilerHost.toPath = toPath; - compilerHost.getCompilationSettings = () => compilerOptions; + compilerHost.getCompilationSettings = () => compilerOptions!; compilerHost.useSourceOfProjectReferenceRedirect = maybeBind(host, host.useSourceOfProjectReferenceRedirect); compilerHost.watchDirectoryOfFailedLookupLocation = (dir, cb, flags) => watchDirectory(dir, cb, flags, watchOptions, WatchType.FailedLookupLocations); compilerHost.watchAffectingFileLocation = (file, cb) => watchFile(file, cb, PollingInterval.High, watchOptions, WatchType.AffectingFileLocation); @@ -433,6 +441,10 @@ namespace ts { function synchronizeProgram() { writeLog(`Synchronizing program`); + + Debug.assert(compilerOptions); + Debug.assert(rootFileNames); + clearInvalidateResolutionsOfFailedLookupLocations(); const program = getCurrentBuilderProgram(); @@ -713,6 +725,10 @@ namespace ts { function reloadFileNamesFromConfigFile() { writeLog("Reloading new file names and options"); + + Debug.assert(compilerOptions); + Debug.assert(configFileName); + reloadLevel = ConfigFileProgramReloadLevel.None; rootFileNames = getFileNamesFromConfigSpecs(compilerOptions.configFile!.configFileSpecs!, getNormalizedAbsolutePath(getDirectoryPath(configFileName), currentDirectory), compilerOptions, parseConfigFileHost, extraFileExtensions); if (updateErrorForNoInputFiles(rootFileNames, getNormalizedAbsolutePath(configFileName, currentDirectory), compilerOptions.configFile!.configFileSpecs!, configFileParsingDiagnostics!, canConfigFileJsonReportNoInputFiles)) { @@ -724,6 +740,7 @@ namespace ts { } function reloadConfigFile() { + Debug.assert(configFileName); writeLog(`Reloading config file: ${configFileName}`); reloadLevel = ConfigFileProgramReloadLevel.None; @@ -742,6 +759,7 @@ namespace ts { } function parseConfigFile() { + Debug.assert(configFileName); setConfigFileParsingResult(getParsedCommandLineOfConfigFile( configFileName, optionsToExtendForConfigFile, @@ -771,6 +789,7 @@ namespace ts { // With host implementing getParsedCommandLine we cant just update file names if (config.parsedCommandLine && config.reloadLevel === ConfigFileProgramReloadLevel.Partial && !host.getParsedCommandLine) { writeLog("Reloading new file names and options"); + Debug.assert(compilerOptions); const fileNames = getFileNamesFromConfigSpecs( config.parsedCommandLine.options.configFile!.configFileSpecs!, getNormalizedAbsolutePath(getDirectoryPath(configFileName), currentDirectory), @@ -893,7 +912,8 @@ namespace ts { return watchDirectory( directory, fileOrDirectory => { - Debug.assert(!!configFileName); + Debug.assert(configFileName); + Debug.assert(compilerOptions); const fileOrDirectoryPath = toPath(fileOrDirectory); @@ -932,6 +952,7 @@ namespace ts { } function updateExtendedConfigFilesWatches(forProjectPath: Path, options: CompilerOptions | undefined, watchOptions: WatchOptions | undefined, watchType: WatchTypeRegistry["ExtendedConfigFile"] | WatchTypeRegistry["ExtendedConfigOfReferencedProject"]) { + Debug.assert(configFileName); updateSharedExtendedConfigFileWatcher( forProjectPath, options, diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index 51cf414728dc0..6bdfcd3096be4 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -12,14 +12,17 @@ "composite": true, "noEmitOnError": true, - "strictNullChecks": true, - "noImplicitAny": true, - "noImplicitThis": true, - "strictPropertyInitialization": true, + "strict": true, + "strictBindCallApply": false, + "useUnknownInCatchVariables": false, + // "strictFunctionTypes": false, + "noUnusedLocals": true, "noUnusedParameters": true, + "allowUnusedLabels": false, "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, "alwaysStrict": true, "preserveConstEnums": true, From 666fcf8cd81da1534945a21b25774444ca2b3954 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 16 Sep 2022 20:33:44 -0700 Subject: [PATCH 02/81] More SFT work --- src/compiler/transformers/legacyDecorators.ts | 10 +++++----- src/compiler/transformers/module/system.ts | 2 +- src/compiler/types.ts | 3 ++- src/compiler/utilities.ts | 4 ++++ src/compiler/visitorPublic.ts | 14 +++++++------- src/services/inlayHints.ts | 2 +- 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/compiler/transformers/legacyDecorators.ts b/src/compiler/transformers/legacyDecorators.ts index fac91f5f6f584..1dcb92125451c 100644 --- a/src/compiler/transformers/legacyDecorators.ts +++ b/src/compiler/transformers/legacyDecorators.ts @@ -303,7 +303,7 @@ namespace ts { return factory.updateConstructorDeclaration( node, visitNodes(node.modifiers, modifierVisitor, isModifier), - visitNodes(node.parameters, visitor, isParameterDeclaration), + visitNodes(node.parameters, visitor, isParameter), visitNode(node.body, visitor, isBlock)); } @@ -325,7 +325,7 @@ namespace ts { visitNode(node.name, visitor, isPropertyName), /*questionToken*/ undefined, /*typeParameters*/ undefined, - visitNodes(node.parameters, visitor, isParameterDeclaration), + visitNodes(node.parameters, visitor, isParameter), /*type*/ undefined, visitNode(node.body, visitor, isBlock) ), node); @@ -336,7 +336,7 @@ namespace ts { node, visitNodes(node.modifiers, modifierVisitor, isModifier), visitNode(node.name, visitor, isPropertyName), - visitNodes(node.parameters, visitor, isParameterDeclaration), + visitNodes(node.parameters, visitor, isParameter), /*type*/ undefined, visitNode(node.body, visitor, isBlock) ), node); @@ -347,7 +347,7 @@ namespace ts { node, visitNodes(node.modifiers, modifierVisitor, isModifier), visitNode(node.name, visitor, isPropertyName), - visitNodes(node.parameters, visitor, isParameterDeclaration), + visitNodes(node.parameters, visitor, isParameter), visitNode(node.body, visitor, isBlock) ), node); } @@ -707,4 +707,4 @@ namespace ts { return undefined; } } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index d541c3d3ad26a..69351f1276062 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -684,7 +684,7 @@ namespace ts { node.asteriskToken, factory.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), /*typeParameters*/ undefined, - visitNodes(node.parameters, visitor, isParameterDeclaration), + visitNodes(node.parameters, visitor, isParameter), /*type*/ undefined, visitNode(node.body, visitor, isBlock))); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c9a3590a4dbfb..79bc30cb25775 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8535,7 +8535,7 @@ namespace ts { /** * A function that transforms a node. */ - export type Transformer = (node: T) => T; + export type Transformer = (node: T) => T; // TODO(jakebailey): This signature is totally wrong. /** * A function that accepts and possibly transforms a node. @@ -8552,6 +8552,7 @@ namespace ts { (nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; } + // TODO(jakebailey): This should really be = T | readonly U[] | undefined. export type VisitResult = T | readonly T[] | undefined; export interface Printer { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 9198cd7690b20..63f38a28a66ee 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3446,6 +3446,10 @@ namespace ts { return node.escapedText === "push" || node.escapedText === "unshift"; } + // TODO(jakebailey): this function should not be named this. While it does technically + // return true if the argument is a ParameterDeclaration, it also returns true for nodes + // that are children of ParameterDeclarations inside binding elements. + // Probably, this should be called `rootDeclarationIsParameter`. export function isParameterDeclaration(node: VariableLikeDeclaration): boolean { const root = getRootDeclaration(node); return root.kind === SyntaxKind.Parameter; diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 4069b1f86164a..3d67d7d49258e 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -206,7 +206,7 @@ namespace ts { context.startLexicalEnvironment(); if (nodes) { context.setLexicalEnvironmentFlags(LexicalEnvironmentFlags.InParameters, true); - updated = nodesVisitor(nodes, visitor, isParameterDeclaration); + updated = nodesVisitor(nodes, visitor, isParameter); // As of ES2015, any runtime execution of that occurs in for a parameter (such as evaluating an // initializer or a binding pattern), occurs in its own lexical scope. As a result, any expression @@ -486,7 +486,7 @@ namespace ts { nodeVisitor(node.name, visitor, isPropertyName), nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), - nodesVisitor(node.parameters, visitor, isParameterDeclaration), + nodesVisitor(node.parameters, visitor, isParameter), nodeVisitor(node.type, visitor, isTypeNode)); }, @@ -536,21 +536,21 @@ namespace ts { [SyntaxKind.CallSignature]: function visitEachChildOfCallSignatureDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateCallSignature(node, nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), - nodesVisitor(node.parameters, visitor, isParameterDeclaration), + nodesVisitor(node.parameters, visitor, isParameter), nodeVisitor(node.type, visitor, isTypeNode)); }, [SyntaxKind.ConstructSignature]: function visitEachChildOfConstructSignatureDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateConstructSignature(node, nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), - nodesVisitor(node.parameters, visitor, isParameterDeclaration), + nodesVisitor(node.parameters, visitor, isParameter), nodeVisitor(node.type, visitor, isTypeNode)); }, [SyntaxKind.IndexSignature]: function visitEachChildOfIndexSignatureDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateIndexSignature(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodesVisitor(node.parameters, visitor, isParameterDeclaration), + nodesVisitor(node.parameters, visitor, isParameter), nodeVisitor(node.type, visitor, isTypeNode)); }, @@ -571,7 +571,7 @@ namespace ts { [SyntaxKind.FunctionType]: function visitEachChildOfFunctionTypeNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateFunctionTypeNode(node, nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), - nodesVisitor(node.parameters, visitor, isParameterDeclaration), + nodesVisitor(node.parameters, visitor, isParameter), nodeVisitor(node.type, visitor, isTypeNode)); }, @@ -579,7 +579,7 @@ namespace ts { return context.factory.updateConstructorTypeNode(node, nodesVisitor(node.modifiers, visitor, isModifier), nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), - nodesVisitor(node.parameters, visitor, isParameterDeclaration), + nodesVisitor(node.parameters, visitor, isParameter), nodeVisitor(node.type, visitor, isTypeNode)); }, diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index 7462a2c6f2c7c..6229d3c079529 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -328,7 +328,7 @@ namespace ts.InlayHints { } function isHintableDeclaration(node: VariableDeclaration | ParameterDeclaration) { - if ((isParameterDeclaration(node) || isVariableDeclaration(node) && isVarConst(node)) && node.initializer) { + if ((isParameter(node) || isVariableDeclaration(node) && isVarConst(node)) && node.initializer) { const initializer = skipParentheses(node.initializer); return !(isHintableLiteral(initializer) || isNewExpression(initializer) || isObjectLiteralExpression(initializer) || isAssertionExpression(initializer)); } From 9e58a390ea2b0bde5d0cc36aa85bb0c13ffe02cd Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Sep 2022 11:47:41 -0700 Subject: [PATCH 03/81] More fixes --- src/compiler/builder.ts | 2 +- src/compiler/checker.ts | 29 ++++++++++--------- src/compiler/core.ts | 10 +++++-- src/compiler/factory/baseNodeFactory.ts | 24 +++++++-------- src/compiler/factory/parenthesizerRules.ts | 16 ++++++---- src/compiler/symbolWalker.ts | 6 ++-- src/compiler/transformers/destructuring.ts | 8 +++-- src/compiler/transformers/legacyDecorators.ts | 2 +- 8 files changed, 56 insertions(+), 41 deletions(-) diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 6177713582859..42aca6753c640 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -995,7 +995,7 @@ namespace ts { function convertToReusableCompilerOptionValue(option: CommandLineOption | undefined, value: CompilerOptionsValue, relativeToBuildInfo: (path: string) => string) { if (option) { if (option.type === "list") { - const values = value as readonly (string | number)[]; + const values = value as readonly string[]; if (option.element.isFilePath && values.length) { return values.map(relativeToBuildInfo); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6680344cc6768..f4a5c85fa5353 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3797,7 +3797,7 @@ namespace ts { function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol; function resolveExternalModuleSymbol(moduleSymbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined; - function resolveExternalModuleSymbol(moduleSymbol: Symbol, dontResolveAlias?: boolean): Symbol | undefined { + function resolveExternalModuleSymbol(moduleSymbol: Symbol | undefined, dontResolveAlias?: boolean): Symbol | undefined { if (moduleSymbol?.exports) { const exportEquals = resolveSymbol(moduleSymbol.exports.get(InternalSymbolName.ExportEquals), dontResolveAlias); const exported = getCommonJsExportEquals(getMergedSymbol(exportEquals), getMergedSymbol(moduleSymbol)); @@ -5178,7 +5178,8 @@ namespace ts { if (objectFlags & ObjectFlags.Reference) { Debug.assert(!!(type.flags & TypeFlags.Object)); - return (type as TypeReference).node ? visitAndTransformType(type, typeReferenceToTypeNode) : typeReferenceToTypeNode(type as TypeReference); + Debug.type(type); + return type.node ? visitAndTransformType(type, typeReferenceToTypeNode) : typeReferenceToTypeNode(type); } if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) { if (type.flags & TypeFlags.TypeParameter && contains(context.inferTypeParameters, type)) { @@ -5432,11 +5433,11 @@ namespace ts { } } - function visitAndTransformType(type: Type, transform: (type: Type) => T) { + function visitAndTransformType(type: T, transform: (type: T) => TypeNode) { const typeId = type.id; const isConstructorObject = getObjectFlags(type) & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & SymbolFlags.Class; - const id = getObjectFlags(type) & ObjectFlags.Reference && (type as TypeReference).node ? "N" + getNodeId((type as TypeReference).node!) : - type.flags & TypeFlags.Conditional ? "N" + getNodeId((type as ConditionalType).root.node) : + const id = getObjectFlags(type) & ObjectFlags.Reference && (type as T & TypeReference).node ? "N" + getNodeId((type as T & TypeReference).node!) : + type.flags & TypeFlags.Conditional ? "N" + getNodeId((type as T & ConditionalType).root.node) : type.symbol ? (isConstructorObject ? "+" : "") + getSymbolId(type.symbol) : undefined; // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead @@ -5459,7 +5460,7 @@ namespace ts { context.truncating = true; } context.approximateLength += cachedResult.addedLength; - return deepCloneOrReuseNode(cachedResult) as TypeNode as T; + return deepCloneOrReuseNode(cachedResult); } let depth: number | undefined; @@ -5479,7 +5480,7 @@ namespace ts { (result as any).truncating = true; } (result as any).addedLength = addedLength; - links?.serializedTypes?.set(key, result as TypeNode as TypeNode & {truncating?: boolean, addedLength: number}); + links?.serializedTypes?.set(key, result as TypeNode & {truncating?: boolean, addedLength: number}); } context.visitedTypes.delete(typeId); if (id) { @@ -5487,7 +5488,7 @@ namespace ts { } return result; - function deepCloneOrReuseNode(node: Node): Node { + function deepCloneOrReuseNode(node: T): T { if (!nodeIsSynthesized(node) && getParseTreeNode(node) === node) { return node; } @@ -7412,7 +7413,7 @@ namespace ts { } function includePrivateSymbol(symbol: Symbol) { - if (some(symbol.declarations, isParameterDeclaration)) return; + if (some(symbol.declarations, isParameter)) return; Debug.assertIsDefined(deferredPrivatesStack[deferredPrivatesStack.length - 1]); getUnusedName(unescapeLeadingUnderscores(symbol.escapedName), symbol); // Call to cache unique name for symbol // Blanket moving (import) aliases into the root private context should work, since imports are not valid within namespaces @@ -7648,7 +7649,7 @@ namespace ts { /*isTypeOnly*/ false, factory.createNamedExports([factory.createExportSpecifier(/*isTypeOnly*/ false, d.expression, factory.createIdentifier(InternalSymbolName.Default))]) ) : d); - const exportModifierStripped = every(defaultReplaced, d => hasSyntacticModifier(d, ModifierFlags.Export)) ? map(defaultReplaced, removeExportModifier) : defaultReplaced; + const exportModifierStripped = every(defaultReplaced, d => hasSyntacticModifier(d, ModifierFlags.Export)) ? map(defaultReplaced as Extract[], removeExportModifier) : defaultReplaced; fakespace = factory.updateModuleDeclaration( fakespace, fakespace.modifiers, @@ -7866,7 +7867,7 @@ namespace ts { case SyntaxKind.ImportEqualsDeclaration: // This _specifically_ only exists to handle json declarations - where we make aliases, but since // we emit no declarations for the json document, must not refer to it in the declarations - if (target.escapedName === InternalSymbolName.ExportEquals && some(target.declarations, isJsonSourceFile)) { + if (target.escapedName === InternalSymbolName.ExportEquals && some(target.declarations, d => isSourceFile(d) && isJsonSourceFile(d))) { serializeMaybeAliasAssignment(symbol); break; } @@ -18872,7 +18873,7 @@ namespace ts { return true; } - function isRelatedToWorker(source: Type, target: Type, reportErrors: boolean) { + function isRelatedToWorker(source: Type, target: Type, reportErrors?: boolean) { return isRelatedTo(source, target, RecursionFlags.Both, reportErrors); } @@ -22737,7 +22738,7 @@ namespace ts { inferWithPriority(getSubstitutionIntersection(source as SubstitutionType), target, InferencePriority.SubstituteSource); // Make substitute inference at a lower priority } else if (target.flags & TypeFlags.Conditional) { - invokeOnce(source, target, inferToConditionalType); + invokeOnce(source, (target as ConditionalType), inferToConditionalType); } else if (target.flags & TypeFlags.UnionOrIntersection) { inferToMultipleTypes(source, (target as UnionOrIntersectionType).types, target.flags); @@ -22799,7 +22800,7 @@ namespace ts { priority = savePriority; } - function invokeOnce(source: Type, target: Type, action: (source: Type, target: Type) => void) { + function invokeOnce(source: Source, target: Target, action: (source: Source, target: Target) => void) { const key = source.id + "," + target.id; const status = visited && visited.get(key); if (status !== undefined) { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 9401500bb2801..90297963f41d7 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -150,6 +150,9 @@ namespace ts { * returns a falsey value, then returns false. * If no such value is found, the callback is applied to each element of array and `true` is returned. */ + export function every(array: readonly T[], callback: (element: T, index: number) => element is U): array is readonly U[]; + export function every(array: readonly T[] | undefined, callback: (element: T, index: number) => element is U): array is readonly U[] | undefined; + 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++) { @@ -1726,13 +1729,16 @@ namespace ts { return typeof x === "number"; } - export function tryCast(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut | undefined; + // TODO(jakebailey): This should be TOut <= TIn <= TParam, but this does not infer correctly. + // https://github.com/microsoft/TypeScript/issues/49924 + + export function tryCast(value: TIn | undefined, test: (value: TParam) => value is TOut): TOut | undefined; export function tryCast(value: T, test: (value: T) => boolean): T | undefined; export function tryCast(value: T, test: (value: T) => boolean): T | undefined { return value !== undefined && test(value) ? value : undefined; } - export function cast(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut { + export function cast(value: TIn | undefined, test: (value: TParam) => value is TOut): TOut { if (value !== undefined && test(value)) return value; return Debug.fail(`Invalid cast. The supplied value ${value} did not pass the test '${Debug.getFunctionName(test)}'.`); diff --git a/src/compiler/factory/baseNodeFactory.ts b/src/compiler/factory/baseNodeFactory.ts index 26be7e95ef237..435500e69563d 100644 --- a/src/compiler/factory/baseNodeFactory.ts +++ b/src/compiler/factory/baseNodeFactory.ts @@ -6,9 +6,9 @@ namespace ts { */ /* @internal */ export interface BaseNodeFactory { - createBaseSourceFileNode(kind: SyntaxKind): Node; - createBaseIdentifierNode(kind: SyntaxKind): Node; - createBasePrivateIdentifierNode(kind: SyntaxKind): Node; + createBaseSourceFileNode(kind: SyntaxKind.SourceFile): Node; + createBaseIdentifierNode(kind: SyntaxKind.Identifier): Node; + createBasePrivateIdentifierNode(kind: SyntaxKind.PrivateIdentifier): Node; createBaseTokenNode(kind: SyntaxKind): Node; createBaseNode(kind: SyntaxKind): Node; } @@ -18,11 +18,11 @@ namespace ts { */ export function createBaseNodeFactory(): BaseNodeFactory { // tslint:disable variable-name - let NodeConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let TokenConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let IdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; + let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + let IdentifierConstructor: new (kind: SyntaxKind.Identifier, pos: number, end: number) => Node; + let PrivateIdentifierConstructor: new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => Node; + let SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: number) => Node; // tslint:enable variable-name return { @@ -33,15 +33,15 @@ namespace ts { createBaseNode }; - function createBaseSourceFileNode(kind: SyntaxKind): Node { + function createBaseSourceFileNode(kind: SyntaxKind.SourceFile): Node { return new (SourceFileConstructor || (SourceFileConstructor = objectAllocator.getSourceFileConstructor()))(kind, /*pos*/ -1, /*end*/ -1); } - function createBaseIdentifierNode(kind: SyntaxKind): Node { + function createBaseIdentifierNode(kind: SyntaxKind.Identifier): Node { return new (IdentifierConstructor || (IdentifierConstructor = objectAllocator.getIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1); } - function createBasePrivateIdentifierNode(kind: SyntaxKind): Node { + function createBasePrivateIdentifierNode(kind: SyntaxKind.PrivateIdentifier): Node { return new (PrivateIdentifierConstructor || (PrivateIdentifierConstructor = objectAllocator.getPrivateIdentifierConstructor()))(kind, /*pos*/ -1, /*end*/ -1); } @@ -53,4 +53,4 @@ namespace ts { return new (NodeConstructor || (NodeConstructor = objectAllocator.getNodeConstructor()))(kind, /*pos*/ -1, /*end*/ -1); } } -} \ No newline at end of file +} diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts index 21422f2bc6fef..3e625168c6a19 100644 --- a/src/compiler/factory/parenthesizerRules.ts +++ b/src/compiler/factory/parenthesizerRules.ts @@ -602,6 +602,12 @@ namespace ts { } } + function castToNodeArray(nodes: readonly T[]): NodeArray { + // TODO(jakebailey): Why do we need this helper? GH#49924? + // Also, why can't I write `isNodeArray` as an expression? + return cast(nodes, isNodeArray as typeof isNodeArray); + } + export const nullParenthesizerRules: ParenthesizerRules = { getParenthesizeLeftSideOfBinaryForOperator: _ => identity, getParenthesizeRightSideOfBinaryForOperator: _ => identity, @@ -615,23 +621,23 @@ namespace ts { parenthesizeLeftSideOfAccess: expression => cast(expression, isLeftHandSideExpression), parenthesizeOperandOfPostfixUnary: operand => cast(operand, isLeftHandSideExpression), parenthesizeOperandOfPrefixUnary: operand => cast(operand, isUnaryExpression), - parenthesizeExpressionsOfCommaDelimitedList: nodes => cast(nodes, isNodeArray), + parenthesizeExpressionsOfCommaDelimitedList: castToNodeArray, parenthesizeExpressionForDisallowedComma: identity, parenthesizeExpressionOfExpressionStatement: identity, parenthesizeConciseBodyOfArrowFunction: identity, parenthesizeCheckTypeOfConditionalType: identity, parenthesizeExtendsTypeOfConditionalType: identity, - parenthesizeConstituentTypesOfUnionType: nodes => cast(nodes, isNodeArray), + parenthesizeConstituentTypesOfUnionType: castToNodeArray, parenthesizeConstituentTypeOfUnionType: identity, - parenthesizeConstituentTypesOfIntersectionType: nodes => cast(nodes, isNodeArray), + parenthesizeConstituentTypesOfIntersectionType: castToNodeArray, parenthesizeConstituentTypeOfIntersectionType: identity, parenthesizeOperandOfTypeOperator: identity, parenthesizeOperandOfReadonlyTypeOperator: identity, parenthesizeNonArrayTypeOfPostfixType: identity, - parenthesizeElementTypesOfTupleType: nodes => cast(nodes, isNodeArray), + parenthesizeElementTypesOfTupleType: castToNodeArray, parenthesizeElementTypeOfTupleType: identity, parenthesizeTypeOfOptionalType: identity, - parenthesizeTypeArguments: nodes => nodes && cast(nodes, isNodeArray), + parenthesizeTypeArguments: nodes => nodes && castToNodeArray(nodes), parenthesizeLeadingTypeArgument: identity, }; } diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index 4130d7fc84f9e..ae100823f73df 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -4,10 +4,10 @@ namespace ts { getRestTypeOfSignature: (sig: Signature) => Type, getTypePredicateOfSignature: (sig: Signature) => TypePredicate | undefined, getReturnTypeOfSignature: (sig: Signature) => Type, - getBaseTypes: (type: Type) => Type[], + getBaseTypes: (type: InterfaceType) => BaseType[], resolveStructuredTypeMembers: (type: ObjectType) => ResolvedType, getTypeOfSymbol: (sym: Symbol) => Type, - getResolvedSymbol: (node: Node) => Symbol, + getResolvedSymbol: (node: Identifier) => Symbol, getConstraintOfTypeParameter: (typeParameter: TypeParameter) => Type | undefined, getFirstIdentifier: (node: EntityNameOrEntityNameExpression) => Identifier, getTypeArguments: (type: TypeReference) => readonly Type[]) { @@ -187,4 +187,4 @@ namespace ts { } } } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 64900c56a887a..4c16e707348bc 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -111,7 +111,7 @@ namespace ts { expressions = append(expressions, expression); } - function emitBindingOrAssignment(target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node) { + function emitBindingOrAssignment(target: BindingOrAssignmentElementTarget, value: Expression, location: TextRange, original: Node | undefined) { Debug.assertNode(target, createAssignmentCallback ? isIdentifier : isExpression); const expression = createAssignmentCallback ? createAssignmentCallback(target as Identifier, value, location) @@ -518,19 +518,21 @@ namespace ts { function makeArrayBindingPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { Debug.assertEachNode(elements, isArrayBindingElement); - return factory.createArrayBindingPattern(elements as ArrayBindingElement[]); + return factory.createArrayBindingPattern(elements); } function makeArrayAssignmentPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { + Debug.assertEachNode(elements, isArrayBindingOrAssignmentElement); return factory.createArrayLiteralExpression(map(elements, factory.converters.convertToArrayAssignmentElement)); } function makeObjectBindingPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { Debug.assertEachNode(elements, isBindingElement); - return factory.createObjectBindingPattern(elements as BindingElement[]); + return factory.createObjectBindingPattern(elements); } function makeObjectAssignmentPattern(factory: NodeFactory, elements: BindingOrAssignmentElement[]) { + Debug.assertEachNode(elements, isObjectBindingOrAssignmentElement); return factory.createObjectLiteralExpression(map(elements, factory.converters.convertToObjectAssignmentElement)); } diff --git a/src/compiler/transformers/legacyDecorators.ts b/src/compiler/transformers/legacyDecorators.ts index 1dcb92125451c..4e241f20a1704 100644 --- a/src/compiler/transformers/legacyDecorators.ts +++ b/src/compiler/transformers/legacyDecorators.ts @@ -578,7 +578,7 @@ namespace ts { * @param decorators The decorators for the parameter at the provided offset. * @param parameterOffset The offset of the parameter. */ - function transformDecoratorsOfParameter(decorators: Decorator[], parameterOffset: number) { + function transformDecoratorsOfParameter(decorators: readonly Decorator[] | undefined, parameterOffset: number) { let expressions: Expression[] | undefined; if (decorators) { expressions = []; From 77be34618f97e83dfa7c7fe3c3f52cca48d29cb0 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Sep 2022 12:22:46 -0700 Subject: [PATCH 04/81] Fix emitter, checker --- src/compiler/checker.ts | 2 +- src/compiler/emitter.ts | 55 ++++++++++++++++++++++------------------- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f4a5c85fa5353..d032a134574a4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27723,7 +27723,7 @@ namespace ts { (left, right) => left === right || !left ? left : compareTypeParametersIdentical(left.typeParameters, right.typeParameters) ? combineSignaturesOfIntersectionMembers(left, right) - : undefined) + : undefined!) // TODO(jakebailey): This is suspect. Can't pass initialValue as reduceLeft checks argument length. : undefined; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 750f97f361530..c0590638e82b0 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -941,10 +941,10 @@ namespace ts { let hasWrittenComment = false; let commentsDisabled = !!printerOptions.removeComments; let lastSubstitution: Node | undefined; - let currentParenthesizerRule: ((node: Node) => Node) | undefined; + let currentParenthesizerRule: ParenthesizerRule | undefined; const { enter: enterComment, exit: exitComment } = performance.createTimerIf(extendedDiagnostics, "commentTime", "beforeComment", "afterComment"); const parenthesizer = factory.parenthesizer; - const typeArgumentParenthesizerRuleSelector: OrdinalParentheizerRuleSelector = { + const typeArgumentParenthesizerRuleSelector: OrdinalParentheizerRuleSelector = { select: index => index === 0 ? parenthesizer.parenthesizeLeadingTypeArgument : undefined }; const emitBinaryExpression = createEmitBinaryExpression(); @@ -1212,9 +1212,9 @@ namespace ts { return currentLineMap || (currentLineMap = getLineStarts(Debug.checkDefined(currentSourceFile))); } - function emit(node: Node, parenthesizerRule?: (node: Node) => Node): void; - function emit(node: Node | undefined, parenthesizerRule?: (node: Node) => Node): void; - function emit(node: Node | undefined, parenthesizerRule?: (node: Node) => Node) { + function emit(node: T, parenthesizerRule?: (node: T) => T): void; + function emit(node: T | undefined, parenthesizerRule?: (node: T) => T): void; + function emit(node: T | undefined, parenthesizerRule?: (node: T) => T) { if (node === undefined) return; const prevSourceFileTextKind = recordBundleFileInternalSectionStart(node); pipelineEmit(EmitHint.Unspecified, node, parenthesizerRule); @@ -1228,14 +1228,14 @@ namespace ts { pipelineEmit(EmitHint.IdentifierName, node, /*parenthesizerRule*/ undefined); } - function emitExpression(node: Expression, parenthesizerRule?: (node: Expression) => Expression): void; - function emitExpression(node: Expression | undefined, parenthesizerRule?: (node: Expression) => Expression): void; - function emitExpression(node: Expression | undefined, parenthesizerRule?: (node: Expression) => Expression) { + function emitExpression(node: T, parenthesizerRule?: (node: T) => T): void; + function emitExpression(node: T | undefined, parenthesizerRule?: (node: T) => T): void; + function emitExpression(node: T | undefined, parenthesizerRule?: (node: T) => T) { if (node === undefined) return; pipelineEmit(EmitHint.Expression, node, parenthesizerRule); } - function emitJsxAttributeValue(node: StringLiteral | JsxExpression): void { + function emitJsxAttributeValue(node: JsxAttributeValue): void { pipelineEmit(isStringLiteral(node) ? EmitHint.JsxAttributeValue : EmitHint.Unspecified, node); } @@ -1249,7 +1249,7 @@ namespace ts { preserveSourceNewlines = savedPreserveSourceNewlines; } - function pipelineEmit(emitHint: EmitHint, node: Node, parenthesizerRule?: (node: Node) => Node) { + function pipelineEmit(emitHint: EmitHint, node: T, parenthesizerRule?: (node: T) => T) { currentParenthesizerRule = parenthesizerRule; const pipelinePhase = getPipelinePhase(PipelinePhase.Notification, emitHint, node); pipelinePhase(emitHint, node); @@ -3186,7 +3186,7 @@ namespace ts { emitSignatureAndBody(node, emitSignatureHead); } - function emitSignatureAndBody(node: FunctionLikeDeclaration, emitSignatureHead: (node: SignatureDeclaration) => void) { + function emitSignatureAndBody(node: T, emitSignatureHead: (node: T) => void) { const body = node.body; if (body) { if (isBlock(body)) { @@ -3220,7 +3220,7 @@ namespace ts { } - function emitSignatureHead(node: FunctionDeclaration | FunctionExpression | MethodDeclaration | AccessorDeclaration | ConstructorDeclaration) { + function emitSignatureHead(node: SignatureDeclaration) { emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitTypeAnnotation(node.type); @@ -4408,15 +4408,15 @@ namespace ts { } } - function emitList(parentNode: Node | undefined, children: NodeArray | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { + function emitList>(parentNode: Parent | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { emitNodeList(emit, parentNode, children, format, parenthesizerRule, start, count); } - function emitExpressionList(parentNode: Node | undefined, children: NodeArray | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { + function emitExpressionList>(parentNode: Parent | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { emitNodeList(emitExpression, parentNode, children, format, parenthesizerRule, start, count); } - function emitNodeList(emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parentNode: Node | undefined, children: NodeArray | undefined, format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start = 0, count = children ? children.length - start : 0) { + function emitNodeList>(emit: EmitFunction, parentNode: Parent | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start = 0, count = children ? children.length - start : 0) { const isUndefined = children === undefined; if (isUndefined && format & ListFormat.OptionalIfUndefined) { return; @@ -4466,7 +4466,7 @@ namespace ts { * * NOTE: You probably don't want to call this directly and should be using `emitList` or `emitExpressionList` instead. */ - function emitNodeListItems(emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parentNode: Node | undefined, children: readonly Node[], format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start: number, count: number, hasTrailingComma: boolean, childrenTextRange: TextRange | undefined) { + function emitNodeListItems(emit: EmitFunction, parentNode: Parent | undefined, children: readonly Child[], format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start: number, count: number, hasTrailingComma: boolean, childrenTextRange: TextRange | undefined) { // Write the opening line terminator or leading whitespace. const mayEmitInterveningComments = (format & ListFormat.NoInterveningComments) === 0; let shouldEmitInterveningComments = mayEmitInterveningComments; @@ -5570,7 +5570,7 @@ namespace ts { : `//${comment.text}`; } - function emitBodyWithDetachedComments(node: Node, detachedRange: TextRange, emitCallback: (node: Node) => void) { + function emitBodyWithDetachedComments(node: T, detachedRange: TextRange, emitCallback: (node: T) => void) { enterComment(); const { pos, end } = detachedRange; const emitFlags = getEmitFlags(node); @@ -5803,7 +5803,7 @@ namespace ts { } } - function emitComment(text: string, lineMap: number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) { + function emitComment(text: string, lineMap: readonly number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) { if (!currentSourceFile || !shouldWriteComment(currentSourceFile.text, commentPos)) return; emitPos(commentPos); writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine); @@ -6029,21 +6029,24 @@ namespace ts { type ParenthesizerRuleOrSelector = OrdinalParentheizerRuleSelector | ParenthesizerRule; - function emitListItemNoParenthesizer(node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, _parenthesizerRule: ParenthesizerRuleOrSelector | undefined, _index: number) { + type EmitFunction = (node: T, parenthesizerRule?: ParenthesizerRule) => void; + type EmitListItemFunction = (node: Node, emit: EmitFunction, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, index: number) => void; + + function emitListItemNoParenthesizer(node: Node, emit: EmitFunction, _parenthesizerRule: ParenthesizerRuleOrSelector | undefined, _index: number) { emit(node); } - function emitListItemWithParenthesizerRuleSelector(node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRuleSelector: OrdinalParentheizerRuleSelector, index: number) { - emit(node, parenthesizerRuleSelector.select(index)); + function emitListItemWithParenthesizerRuleSelector(node: Node, emit: EmitFunction, parenthesizerRuleSelector: OrdinalParentheizerRuleSelector | undefined, index: number) { + emit(node, parenthesizerRuleSelector!.select(index)); } - function emitListItemWithParenthesizerRule(node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRule: ParenthesizerRule | undefined, _index: number) { + function emitListItemWithParenthesizerRule(node: Node, emit: EmitFunction, parenthesizerRule: ParenthesizerRule | undefined, _index: number) { emit(node, parenthesizerRule); } - function getEmitListItem | undefined>(emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRule: R): (node: Node, emit: (node: Node, parenthesizerRule?: ((node: Node) => Node) | undefined) => void, parenthesizerRule: R, index: number) => void { - return emit.length === 1 ? emitListItemNoParenthesizer : - typeof parenthesizerRule === "object" ? emitListItemWithParenthesizerRuleSelector : - emitListItemWithParenthesizerRule; + function getEmitListItem(emit: EmitFunction, parenthesizerRule: ParenthesizerRuleOrSelector | undefined): EmitListItemFunction { + return emit.length === 1 ? emitListItemNoParenthesizer as EmitListItemFunction : + typeof parenthesizerRule === "object" ? emitListItemWithParenthesizerRuleSelector as EmitListItemFunction : + emitListItemWithParenthesizerRule as EmitListItemFunction; } } From 7061fdbe92dee6874c849e36e800f122e1f4f597 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Sep 2022 12:32:35 -0700 Subject: [PATCH 05/81] Fix some more node problems --- src/compiler/parser.ts | 22 +++++++++++----------- src/compiler/program.ts | 2 +- src/compiler/types.ts | 8 ++++---- src/compiler/utilities.ts | 14 +++++++------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 85f13a159ca04..4fdcc34dbf4af 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -14,11 +14,11 @@ namespace ts { Reparse } - let NodeConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let TokenConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let IdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; - let SourceFileConstructor: new (kind: SyntaxKind, pos?: number, end?: number) => Node; + let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + let IdentifierConstructor: new (kind: SyntaxKind.Identifier, pos: number, end: number) => Node; + let PrivateIdentifierConstructor: new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => Node; + let SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: number) => Node; /** * NOTE: You should not use this, it is only exported to support `createNode` in `~/src/deprecatedCompat/deprecations.ts`. @@ -1030,9 +1030,9 @@ namespace ts { // tslint:disable variable-name let NodeConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; let TokenConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let IdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let PrivateIdentifierConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; - let SourceFileConstructor: new (kind: SyntaxKind, pos: number, end: number) => Node; + let IdentifierConstructor: new (kind: SyntaxKind.Identifier, pos: number, end: number) => Identifier; + let PrivateIdentifierConstructor: new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => PrivateIdentifier; + let SourceFileConstructor: new (kind: SyntaxKind.SourceFile, pos: number, end: number) => SourceFile; // tslint:enable variable-name function countNode(node: Node) { @@ -2150,9 +2150,9 @@ namespace ts { function createMissingNode(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: DiagnosticMessage, arg0?: any): T; function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T; - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T { + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage?: DiagnosticMessage, arg0?: any): T { if (reportAtCurrentPosition) { - parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0); + parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage!, arg0); } else if (diagnosticMessage) { parseErrorAtCurrentToken(diagnosticMessage, arg0); @@ -8364,7 +8364,7 @@ namespace ts { case "override": tag = parseSimpleTag(start, factory.createJSDocOverrideTag, tagName, margin, indentText); break; - case "deprecated": + case "deprecated": hasDeprecatedTag = true; tag = parseSimpleTag(start, factory.createJSDocDeprecatedTag, tagName, margin, indentText); break; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 412f307eae4bf..efe78939a2036 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -2523,7 +2523,7 @@ namespace ts { return result; } - function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): readonly DiagnosticWithLocation[] { + function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken | undefined): readonly DiagnosticWithLocation[] { return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 79bc30cb25775..88daadf709b6d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8093,10 +8093,10 @@ namespace ts { updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier | undefined, comment: string | NodeArray | undefined): JSDocReadonlyTag; createJSDocUnknownTag(tagName: Identifier, comment?: string | NodeArray): JSDocUnknownTag; updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | NodeArray | undefined): JSDocUnknownTag; - createJSDocDeprecatedTag(tagName: Identifier, comment?: string | NodeArray): JSDocDeprecatedTag; - updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment?: string | NodeArray): JSDocDeprecatedTag; - createJSDocOverrideTag(tagName: Identifier, comment?: string | NodeArray): JSDocOverrideTag; - updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment?: string | NodeArray): JSDocOverrideTag; + createJSDocDeprecatedTag(tagName: Identifier | undefined, comment?: string | NodeArray): JSDocDeprecatedTag; + updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier | undefined, comment?: string | NodeArray): JSDocDeprecatedTag; + createJSDocOverrideTag(tagName: Identifier | undefined, comment?: string | NodeArray): JSDocOverrideTag; + updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier | undefined, comment?: string | NodeArray): JSDocOverrideTag; createJSDocText(text: string): JSDocText; updateJSDocText(node: JSDocText, text: string): JSDocText; createJSDocComment(comment?: string | NodeArray | undefined, tags?: readonly JSDocTag[] | undefined): JSDoc; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 63f38a28a66ee..0a7c52216942f 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -212,8 +212,8 @@ namespace ts { export function hasChangesInResolutions( names: readonly string[] | readonly FileReference[], - newResolutions: readonly T[], - oldResolutions: ModeAwareCache | undefined, + newResolutions: readonly (T | undefined)[], + oldResolutions: ModeAwareCache | undefined, oldSourceFile: SourceFile | undefined, comparer: (oldResolution: T, newResolution: T) => boolean): boolean { Debug.assert(names.length === newResolutions.length); @@ -5954,11 +5954,11 @@ namespace ts { } export interface ObjectAllocator { - getNodeConstructor(): new (kind: SyntaxKind, pos?: number, end?: number) => Node; - getTokenConstructor(): new (kind: TKind, pos?: number, end?: number) => Token; - getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos?: number, end?: number) => Identifier; - getPrivateIdentifierConstructor(): new (kind: SyntaxKind.PrivateIdentifier, pos?: number, end?: number) => PrivateIdentifier; - getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos?: number, end?: number) => SourceFile; + getNodeConstructor(): new (kind: SyntaxKind, pos: number, end: number) => Node; + getTokenConstructor(): new (kind: TKind, pos: number, end: number) => Token; + getIdentifierConstructor(): new (kind: SyntaxKind.Identifier, pos: number, end: number) => Identifier; + getPrivateIdentifierConstructor(): new (kind: SyntaxKind.PrivateIdentifier, pos: number, end: number) => PrivateIdentifier; + getSourceFileConstructor(): new (kind: SyntaxKind.SourceFile, pos: number, end: number) => SourceFile; getSymbolConstructor(): new (flags: SymbolFlags, name: __String) => Symbol; getTypeConstructor(): new (checker: TypeChecker, flags: TypeFlags) => Type; getSignatureConstructor(): new (checker: TypeChecker, flags: SignatureFlags) => Signature; From 82bf75b9f8bf94acd8896e94941c9345f4406334 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Sep 2022 13:47:32 -0700 Subject: [PATCH 06/81] Parser tweaks --- src/compiler/parser.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4fdcc34dbf4af..4c88532ecc60d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -9219,6 +9219,7 @@ namespace ts { } function moveElementEntirelyPastChangeRange(element: IncrementalElement, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) { + // TODO(jakebailey): instead of isArray, use overloads and the just use isNodeArray. if (isArray) { visitArray(element as IncrementalNodeArray); } @@ -9227,7 +9228,8 @@ namespace ts { } return; - function visitNode(node: IncrementalNode) { + function visitNode(node: Node) { + Debug.type(node); let text = ""; if (aggressiveChecks && shouldCheckNode(node)) { text = oldText.substring(node.pos, node.end); @@ -9254,7 +9256,8 @@ namespace ts { checkNodePositions(node, aggressiveChecks); } - function visitArray(array: IncrementalNodeArray) { + function visitArray(array: NodeArray) { + Debug.type(array); array._children = undefined; setTextRangePosEnd(array, array.pos + delta, array.end + delta); @@ -9379,7 +9382,8 @@ namespace ts { visitNode(sourceFile); return; - function visitNode(child: IncrementalNode) { + function visitNode(child: Node) { + Debug.type(child); Debug.assert(child.pos <= child.end); if (child.pos > changeRangeOldEnd) { // Node is entirely past the change range. We need to move both its pos and @@ -9401,7 +9405,7 @@ namespace ts { forEachChild(child, visitNode, visitArray); if (hasJSDocNodes(child)) { for (const jsDocComment of child.jsDoc!) { - visitNode(jsDocComment as Node as IncrementalNode); + visitNode(jsDocComment); } } checkNodePositions(child, aggressiveChecks); @@ -9412,7 +9416,8 @@ namespace ts { Debug.assert(fullEnd < changeStart); } - function visitArray(array: IncrementalNodeArray) { + function visitArray(array: NodeArray) { + Debug.type(array); Debug.assert(array.pos <= array.end); if (array.pos > changeRangeOldEnd) { // Array is entirely after the change range. We need to move it, and move any of From 41c4a626e584495c70a14d1c53f6fbaf50480d79 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Sep 2022 14:18:55 -0700 Subject: [PATCH 07/81] Resolve TODO --- src/compiler/parser.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4c88532ecc60d..0ee2c3cdb03a4 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -9218,13 +9218,12 @@ namespace ts { } } - function moveElementEntirelyPastChangeRange(element: IncrementalElement, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) { - // TODO(jakebailey): instead of isArray, use overloads and the just use isNodeArray. - if (isArray) { - visitArray(element as IncrementalNodeArray); + function moveElementEntirelyPastChangeRange(element: IncrementalNode | IncrementalNodeArray, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) { + if (isArray(element)) { + visitArray(element); } else { - visitNode(element as IncrementalNode); + visitNode(element); } return; @@ -9388,7 +9387,7 @@ namespace ts { if (child.pos > changeRangeOldEnd) { // Node is entirely past the change range. We need to move both its pos and // end, forward or backward appropriately. - moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks); + moveElementEntirelyPastChangeRange(child, delta, oldText, newText, aggressiveChecks); return; } @@ -9422,7 +9421,7 @@ namespace ts { if (array.pos > changeRangeOldEnd) { // Array is entirely after the change range. We need to move it, and move any of // its children. - moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks); + moveElementEntirelyPastChangeRange(array, delta, oldText, newText, aggressiveChecks); return; } From 8bc26db9e827b3346d85fa1c24547d5aacc1e16b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Sep 2022 14:35:11 -0700 Subject: [PATCH 08/81] More fixes --- src/compiler/path.ts | 4 ++-- src/compiler/resolutionCache.ts | 2 +- src/compiler/scanner.ts | 14 +++++--------- src/compiler/transformers/classFields.ts | 2 +- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/compiler/path.ts b/src/compiler/path.ts index 86bafd8f785ce..68edbff9c5620 100644 --- a/src/compiler/path.ts +++ b/src/compiler/path.ts @@ -849,14 +849,14 @@ namespace ts { */ export function forEachAncestorDirectory(directory: Path, callback: (directory: Path) => T | undefined): T | undefined; export function forEachAncestorDirectory(directory: string, callback: (directory: string) => T | undefined): T | undefined; - export function forEachAncestorDirectory(directory: Path, callback: (directory: Path) => T | undefined): T | undefined { + export function forEachAncestorDirectory(directory: P, callback: (directory: P) => T | undefined): T | undefined { while (true) { const result = callback(directory); if (result !== undefined) { return result; } - const parentPath = getDirectoryPath(directory); + const parentPath = getDirectoryPath(directory) as P; if (parentPath === directory) { return undefined; } diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index 46130e35659f9..2ce3fd4ec4387 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -366,7 +366,7 @@ namespace ts { hasChangedAutomaticTypeDirectiveNames = false; } - function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, _containingSourceFile?: never, mode?: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): CachedResolvedModuleWithFailedLookupLocations { + function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference, _containingSourceFile?: SourceFile, mode?: ModuleKind.CommonJS | ModuleKind.ESNext | undefined): CachedResolvedModuleWithFailedLookupLocations { const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference, mode); // return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts if (!resolutionHost.getGlobalCache) { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index a54389fbb9474..686d31f3052f3 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -856,28 +856,24 @@ namespace ts { export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { - return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state); + return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state!); } export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { - return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state); + return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state!); } - export function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) { + export function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U) { return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial); } - export function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U) { + export function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U) { return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial); } - function appendCommentRange(pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) { - if (!comments) { - comments = []; - } - + function appendCommentRange(pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[] = []) { comments.push({ kind, pos, end, hasTrailingNewLine }); return comments; } diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 3ae7696d7c96e..307f61879e460 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -2473,7 +2473,7 @@ namespace ts { // [ { set value(x) { this.#myProp = x; } }.value ] = [ "hello" ]; return factory.updateArrayLiteralExpression( node, - visitNodes(node.elements, visitArrayAssignmentTarget, isExpression) + visitNodes(node.elements , visitArrayAssignmentTarget, isExpression) ); } else { From f985655a24bda62ce0718d4dbfce2bfdea754a9b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Sep 2022 14:45:56 -0700 Subject: [PATCH 09/81] Fix es2015 --- src/compiler/factory/nodeFactory.ts | 6 +++--- src/compiler/transformers/es2015.ts | 15 ++++++++------- src/compiler/types.ts | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 9d7a2fce604d5..43c2a234c329b 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -6141,9 +6141,9 @@ namespace ts { * @param statementOffset The offset at which to begin the copy. * @param visitor Optional callback used to visit any custom prologue directives. */ - function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number; - function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number | undefined; - function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter: (node: Node) => boolean = returnTrue): number | undefined { + function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Statement) => boolean): number; + function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Statement) => boolean): number | undefined; + function copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter: (node: Statement) => boolean = returnTrue): number | undefined { const numStatements = source.length; while (statementOffset !== undefined && statementOffset < numStatements) { const statement = source[statementOffset]; diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 9e3ef1b753b87..2a7176d3125d8 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -145,7 +145,7 @@ namespace ts { loopOutParameters: LoopOutParameter[]; } - type LoopConverter = (node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined, ancestorFacts: HierarchyFacts) => Statement; + type LoopConverter = (node: T, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined, ancestorFacts: HierarchyFacts) => Statement; // Facts we track as we traverse the tree const enum HierarchyFacts { @@ -2369,7 +2369,7 @@ namespace ts { } } - function visitIterationStatementWithFacts(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts, node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, convert?: LoopConverter) { + function visitIterationStatementWithFacts(excludeFacts: HierarchyFacts, includeFacts: HierarchyFacts, node: T, outermostLabeledStatement: LabeledStatement | undefined, convert?: LoopConverter) { const ancestorFacts = enterSubtree(excludeFacts, includeFacts); const updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, ancestorFacts, convert); exitSubtree(ancestorFacts, HierarchyFacts.None, HierarchyFacts.None); @@ -2419,7 +2419,7 @@ namespace ts { compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray); } - function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression, convertedLoopBodyStatements: Statement[]) { + function convertForOfStatementHead(node: ForOfStatement, boundValue: Expression, convertedLoopBodyStatements: Statement[] | undefined) { const statements: Statement[] = []; const initializer = node.initializer; if (isVariableDeclarationList(initializer)) { @@ -2518,7 +2518,7 @@ namespace ts { ); } - function convertForOfStatementForArray(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[]): Statement { + function convertForOfStatementForArray(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined): Statement { // The following ES6 code: // // for (let v of expr) { } @@ -2588,7 +2588,7 @@ namespace ts { return factory.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel); } - function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement, convertedLoopBodyStatements: Statement[], ancestorFacts: HierarchyFacts): Statement { + function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined, ancestorFacts: HierarchyFacts): Statement { const expression = visitNode(node.expression, visitor, isExpression); const iterator = isIdentifier(expression) ? factory.getGeneratedNameForNode(expression) : factory.createTempVariable(/*recordTempVariable*/ undefined); const result = isIdentifier(expression) ? factory.getGeneratedNameForNode(iterator) : factory.createTempVariable(/*recordTempVariable*/ undefined); @@ -2816,7 +2816,7 @@ namespace ts { } } - function convertIterationStatementBodyIfNecessary(node: IterationStatement, outermostLabeledStatement: LabeledStatement | undefined, ancestorFacts: HierarchyFacts, convert?: LoopConverter): VisitResult { + function convertIterationStatementBodyIfNecessary(node: T, outermostLabeledStatement: LabeledStatement | undefined, ancestorFacts: HierarchyFacts, convert?: LoopConverter): VisitResult { if (!shouldConvertIterationStatement(node)) { let saveAllowedNonLabeledJumps: Jump | undefined; if (convertedLoopState) { @@ -4075,7 +4075,8 @@ namespace ts { return map(chunk, visitExpressionOfSpread); } - function visitExpressionOfSpread(node: SpreadElement): SpreadSegment { + function visitExpressionOfSpread(node: Expression): SpreadSegment { + Debug.assertNode(node, isSpreadElement); let expression = visitNode(node.expression, visitor, isExpression); // We don't need to pack already packed array literals, or existing calls to the `__read` helper. diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 88daadf709b6d..ae913f4066a9f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8372,8 +8372,8 @@ namespace ts { * @param statementOffset The offset at which to begin the copy. * @param visitor Optional callback used to visit any custom prologue directives. */ - /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number; - /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Node) => boolean): number | undefined; + /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Statement) => boolean): number; + /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Statement) => boolean): number | undefined; /* @internal */ ensureUseStrict(statements: NodeArray): NodeArray; /* @internal */ liftToBlock(nodes: readonly Node[]): Statement; /** From 79740c8f47353cba77d06e150d56226d044008cb Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Sep 2022 15:05:15 -0700 Subject: [PATCH 10/81] Fix all except visitNodes problems --- src/compiler/transformers/jsx.ts | 4 ++-- src/compiler/transformers/ts.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 83a7f70d156a0..80a8fefe877d3 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -372,8 +372,8 @@ namespace ts { // of JsxSpreadAttribute nodes into expressions. const expressions = flatten( spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread - ? map(attrs, transformJsxSpreadAttributeToExpression) - : factory.createObjectLiteralExpression(map(attrs, transformJsxAttributeToObjectLiteralElement)) + ? map(attrs as JsxSpreadAttribute[], transformJsxSpreadAttributeToExpression) + : factory.createObjectLiteralExpression(map(attrs as JsxAttribute[], transformJsxAttributeToObjectLiteralElement)) ) ); diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 0f2725559067b..2bc148a986290 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -119,7 +119,7 @@ namespace ts { * * @param node The node to visit. */ - function saveStateAndInvoke(node: Node, f: (node: Node) => T): T { + function saveStateAndInvoke(node: U, f: (node: U) => T): T { // Save state const savedCurrentScope = currentLexicalScope; const savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName; @@ -813,7 +813,7 @@ namespace ts { * @param parameterDecorators The decorators for the parameter at the provided offset. * @param parameterOffset The offset of the parameter. */ - function transformDecoratorsOfParameter(parameterDecorators: Decorator[], parameterOffset: number) { + function transformDecoratorsOfParameter(parameterDecorators: readonly Decorator[] | undefined, parameterOffset: number) { if (parameterDecorators) { const decorators: Decorator[] = []; for (const parameterDecorator of parameterDecorators) { @@ -1895,7 +1895,7 @@ namespace ts { let blockLocation: TextRange | undefined; if (node.body) { if (node.body.kind === SyntaxKind.ModuleBlock) { - saveStateAndInvoke(node.body, body => addRange(statements, visitNodes((body as ModuleBlock).statements, namespaceElementVisitor, isStatement))); + saveStateAndInvoke(node.body, body => addRange(statements, visitNodes(body.statements, namespaceElementVisitor, isStatement))); statementsLocation = node.body.statements; blockLocation = node.body; } From 61fbef435108d4838c25a03e07709342be20be8e Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Sep 2022 15:13:56 -0700 Subject: [PATCH 11/81] Cast to fix type guard arrow function problem --- src/compiler/transformers/ts.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 2bc148a986290..831f63564a30a 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1068,7 +1068,7 @@ namespace ts { function transformConstructorBody(body: Block, constructor: ConstructorDeclaration) { const parametersWithPropertyAssignments = constructor && - filter(constructor.parameters, p => isParameterPropertyDeclaration(p, constructor)); + filter(constructor.parameters, p => isParameterPropertyDeclaration(p, constructor)) as readonly ParameterPropertyDeclaration[] | undefined; if (!some(parametersWithPropertyAssignments)) { return visitFunctionBody(body, visitor, context); } From 1b3bd51e4de553f58fed5ade30c240e94bf1c328 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Sep 2022 22:26:51 -0700 Subject: [PATCH 12/81] Completely overhaul node visitor stuff, untested --- src/compiler/checker.ts | 16 +-- src/compiler/debug.ts | 6 +- src/compiler/transformers/classFields.ts | 2 +- src/compiler/transformers/declarations.ts | 27 ++--- src/compiler/transformers/destructuring.ts | 2 +- src/compiler/transformers/es2015.ts | 2 + src/compiler/transformers/es2017.ts | 6 +- src/compiler/transformers/es2018.ts | 2 +- src/compiler/transformers/module/module.ts | 6 +- src/compiler/transformers/module/system.ts | 2 +- src/compiler/transformers/taggedTemplate.ts | 2 +- src/compiler/transformers/ts.ts | 6 +- src/compiler/types.ts | 18 +-- src/compiler/utilitiesPublic.ts | 23 ++++ src/compiler/visitorPublic.ts | 123 ++++++++++---------- 15 files changed, 138 insertions(+), 105 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d032a134574a4..6e09b094b5bc8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5495,13 +5495,13 @@ namespace ts { return setTextRange(factory.cloneNode(visitEachChild(node, deepCloneOrReuseNode, nullTransformationContext, deepCloneOrReuseNodes)), node); } - function deepCloneOrReuseNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; - function deepCloneOrReuseNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; - function deepCloneOrReuseNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined { + function deepCloneOrReuseNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray; + function deepCloneOrReuseNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | undefined; + function deepCloneOrReuseNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | undefined { if (nodes && nodes.length === 0) { // Ensure we explicitly make a copy of an empty array; visitNodes will not do this unless the array has elements, // which can lead to us reusing the same empty NodeArray more than once within the same AST during type noding. - return setTextRange(factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes); + return setTextRange(factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes); } return visitNodes(nodes, visitor, test, start, count); } @@ -6800,13 +6800,13 @@ namespace ts { } let hadError = false; const file = getSourceFileOfNode(existing); - const transformed = visitNode(existing, visitExistingNodeTreeSymbols); + const transformed = visitNode(existing, visitExistingNodeTreeSymbols, isTypeNode); if (hadError) { return undefined; } return transformed === existing ? setTextRange(factory.cloneNode(existing), existing) : transformed; - function visitExistingNodeTreeSymbols(node: T): Node { + function visitExistingNodeTreeSymbols(node: Node): Node { // We don't _actually_ support jsdoc namepath types, emit `any` instead if (isJSDocAllType(node) || node.kind === SyntaxKind.JSDocNamepathType) { return factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); @@ -6836,7 +6836,7 @@ namespace ts { /*modifiers*/ undefined, name, t.isBracketed || t.typeExpression && isJSDocOptionalType(t.typeExpression.type) ? factory.createToken(SyntaxKind.QuestionToken) : undefined, - overrideTypeNode || (t.typeExpression && visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols)) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) + overrideTypeNode || (t.typeExpression && visitNode(t.typeExpression.type, visitExistingNodeTreeSymbols, isTypeNode)) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ); })); } @@ -6851,7 +6851,7 @@ namespace ts { /*dotdotdotToken*/ undefined, "x", /*questionToken*/ undefined, - visitNode(node.typeArguments![0], visitExistingNodeTreeSymbols) + visitNode(node.typeArguments![0], visitExistingNodeTreeSymbols, isTypeNode) )], visitNode(node.typeArguments![1], visitExistingNodeTreeSymbols) )]); diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index d6edd94b3dc49..4119d1337017f 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -195,13 +195,13 @@ namespace ts { export function assertEachNode(nodes: readonly T[], test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is readonly U[]; export function assertEachNode(nodes: NodeArray | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is NodeArray | undefined; export function assertEachNode(nodes: readonly T[] | undefined, test: (node: T) => node is U, message?: string, stackCrawlMark?: AnyFunction): asserts nodes is readonly U[] | undefined; - export function assertEachNode(nodes: readonly Node[], test: (node: Node) => boolean, message?: string, stackCrawlMark?: AnyFunction): void; - export function assertEachNode(nodes: readonly Node[] | undefined, test: (node: Node) => boolean, message?: string, stackCrawlMark?: AnyFunction) { + export function assertEachNode(nodes: readonly Node[], test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction): void; + export function assertEachNode(nodes: readonly Node[] | undefined, test: ((node: Node) => boolean) | undefined, message?: string, stackCrawlMark?: AnyFunction) { if (shouldAssertFunction(AssertionLevel.Normal, "assertEachNode")) { assert( test === undefined || every(nodes, test), message || "Unexpected node.", - () => `Node array did not pass test '${getFunctionName(test)}'.`, + () => `Node array did not pass test '${getFunctionName(test!)}'.`, stackCrawlMark || assertEachNode); } } diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 307f61879e460..7958ee1daf917 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -2473,7 +2473,7 @@ namespace ts { // [ { set value(x) { this.#myProp = x; } }.value ] = [ "hello" ]; return factory.updateArrayLiteralExpression( node, - visitNodes(node.elements , visitArrayAssignmentTarget, isExpression) + visitNodes(node.elements as NodeArray>, visitArrayAssignmentTarget, isExpression) // TODO(jakebailey): the elements property's type looks to be wrong. ); } else { diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index d64c14b2e0b2c..268c2ae77d3d0 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -285,7 +285,7 @@ namespace ts { if (isExternalOrCommonJsModule(sourceFile) || isJsonSourceFile(sourceFile)) { resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules) needsDeclare = false; - const statements = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : visitNodes(sourceFile.statements, visitDeclarationStatements); + const statements = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile, /*bundled*/ true)) : visitNodes(sourceFile.statements, visitDeclarationStatements, isStatement); const newFile = factory.updateSourceFile(sourceFile, [factory.createModuleDeclaration( [factory.createModifier(SyntaxKind.DeclareKeyword)], factory.createStringLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), @@ -294,7 +294,7 @@ namespace ts { return newFile; } needsDeclare = true; - const updated = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile)) : visitNodes(sourceFile.statements, visitDeclarationStatements); + const updated = isSourceFileJS(sourceFile) ? factory.createNodeArray(transformDeclarationsForJS(sourceFile)) : visitNodes(sourceFile.statements, visitDeclarationStatements, isStatement); return factory.updateSourceFile(sourceFile, transformAndReplaceLatePaintedStatements(updated), /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []); } ), mapDefined(node.prepends, prepend => { @@ -343,7 +343,7 @@ namespace ts { emittedImports = filter(combinedStatements, isAnyImportSyntax); } else { - const statements = visitNodes(node.statements, visitDeclarationStatements); + const statements = visitNodes(node.statements, visitDeclarationStatements, isStatement); combinedStatements = setTextRange(factory.createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements); refs.forEach(referenceVisitor); emittedImports = filter(combinedStatements, isAnyImportSyntax); @@ -550,10 +550,10 @@ namespace ts { (resolver.isRequiredInitializedParameter(node) || resolver.isOptionalUninitializedParameterProperty(node)); if (type && !shouldUseResolverType) { - return visitNode(type, visitDeclarationSubtree); + return visitNode(type, visitDeclarationSubtree, isTypeNode); } if (!getParseTreeNode(node)) { - return type ? visitNode(type, visitDeclarationSubtree) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + return type ? visitNode(type, visitDeclarationSubtree, isTypeNode) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } if (node.kind === SyntaxKind.SetAccessor) { // Set accessors with no associated type node (from it's param or get accessor return) are `any` since they are never contextually typed right now @@ -674,7 +674,7 @@ namespace ts { } function ensureTypeParams(node: Node, params: NodeArray | undefined) { - return hasEffectiveModifier(node, ModifierFlags.Private) ? undefined : visitNodes(params, visitDeclarationSubtree); + return hasEffectiveModifier(node, ModifierFlags.Private) ? undefined : visitNodes(params, visitDeclarationSubtree, isTypeParameterDeclaration); } function isEnclosingDeclaration(node: Node) { @@ -851,6 +851,7 @@ namespace ts { const key = getOriginalNodeId(statement); if (lateStatementReplacementMap.has(key)) { const result = lateStatementReplacementMap.get(key); + Debug.type(result); lateStatementReplacementMap.delete(key); if (result) { if (isArray(result) ? some(result, needsScopeMarker) : needsScopeMarker(result)) { @@ -1057,13 +1058,13 @@ namespace ts { case SyntaxKind.ConditionalType: { // We have to process conditional types in a special way because for visibility purposes we need to push a new enclosingDeclaration // just for the `infer` types in the true branch. It's an implicit declaration scope that only applies to _part_ of the type. - const checkType = visitNode(input.checkType, visitDeclarationSubtree); - const extendsType = visitNode(input.extendsType, visitDeclarationSubtree); + const checkType = visitNode(input.checkType, visitDeclarationSubtree, isTypeNode); + const extendsType = visitNode(input.extendsType, visitDeclarationSubtree, isTypeNode); const oldEnclosingDecl = enclosingDeclaration; enclosingDeclaration = input.trueType; - const trueType = visitNode(input.trueType, visitDeclarationSubtree); + const trueType = visitNode(input.trueType, visitDeclarationSubtree, isTypeNode); enclosingDeclaration = oldEnclosingDecl; - const falseType = visitNode(input.falseType, visitDeclarationSubtree); + const falseType = visitNode(input.falseType, visitDeclarationSubtree, isTypeNode); return cleanup(factory.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType)); } case SyntaxKind.FunctionType: { @@ -1336,7 +1337,7 @@ namespace ts { const oldHasScopeFix = resultHasScopeMarker; resultHasScopeMarker = false; needsScopeFixMarker = false; - const statements = visitNodes(inner.statements, visitDeclarationStatements); + const statements = visitNodes(inner.statements, visitDeclarationStatements, isStatement); let lateStatements = transformAndReplaceLatePaintedStatements(statements); if (input.flags & NodeFlags.Ambient) { needsScopeFixMarker = false; // If it was `declare`'d everything is implicitly exported already, ignore late printed "privates" @@ -1441,7 +1442,7 @@ namespace ts { /*initializer*/ undefined ) ] : undefined; - const memberNodes = concatenate(concatenate(privateIdentifier, parameterProperties), visitNodes(input.members, visitDeclarationSubtree)); + const memberNodes = concatenate(concatenate(privateIdentifier, parameterProperties), visitNodes(input.members, visitDeclarationSubtree, isClassElement)); const members = factory.createNodeArray(memberNodes); const extendsClause = getEffectiveBaseTypeNode(input); @@ -1524,7 +1525,7 @@ namespace ts { function transformVariableStatement(input: VariableStatement) { if (!forEach(input.declarationList.declarations, getBindingNameVisible)) return; - const nodes = visitNodes(input.declarationList.declarations, visitDeclarationSubtree); + const nodes = visitNodes(input.declarationList.declarations, visitDeclarationSubtree, isVariableDeclaration); if (!length(nodes)) return; return factory.updateVariableStatement(input, factory.createNodeArray(ensureModifiers(input)), factory.updateVariableDeclarationList(input.declarationList, nodes)); } diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 4c16e707348bc..acbb5cc42739b 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -328,7 +328,7 @@ namespace ts { && !(element.transformFlags & (TransformFlags.ContainsRestOrSpread | TransformFlags.ContainsObjectRestOrSpread)) && !(getTargetOfBindingOrAssignmentElement(element)!.transformFlags & (TransformFlags.ContainsRestOrSpread | TransformFlags.ContainsObjectRestOrSpread)) && !isComputedPropertyName(propertyName)) { - bindingElements = append(bindingElements, visitNode(element, flattenContext.visitor)); + bindingElements = append(bindingElements, visitNode(element, flattenContext.visitor, isBindingOrAssignmentElement)); } else { if (bindingElements) { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 2a7176d3125d8..0e03843ad4ba5 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2195,6 +2195,8 @@ namespace ts { ? visitVariableDeclarationInLetDeclarationList : visitVariableDeclaration); + Debug.assertEachNode(declarations, isVariableDeclaration); // TODO(jakebailey): side effect of VisitResult. + const declarationList = factory.createVariableDeclarationList(declarations); setOriginalNode(declarationList, node); setTextRange(declarationList, node); diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 78d9f57ccdc9d..260f76f65d8db 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -232,7 +232,7 @@ namespace ts { function visitForOfStatementInAsyncBody(node: ForOfStatement) { return factory.updateForOfStatement( node, - visitNode(node.awaitModifier, visitor, isToken), + visitNode(node.awaitModifier, visitor, isAwaitKeyword), isVariableDeclarationListWithCollidingName(node.initializer) ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)! : visitNode(node.initializer, visitor, isForInitializer), @@ -336,7 +336,7 @@ namespace ts { function visitFunctionExpression(node: FunctionExpression): Expression { return factory.updateFunctionExpression( node, - visitNodes(node.modifiers, visitor, isModifierLike), + visitNodes(node.modifiers, visitor, isModifier), node.asteriskToken, node.name, /*typeParameters*/ undefined, @@ -359,7 +359,7 @@ namespace ts { function visitArrowFunction(node: ArrowFunction) { return factory.updateArrowFunction( node, - visitNodes(node.modifiers, visitor, isModifierLike), + visitNodes(node.modifiers, visitor, isModifier), /*typeParameters*/ undefined, visitParameterList(node.parameters, visitor, context), /*type*/ undefined, diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index aa1f4a5e6c4f1..302a8a705ac17 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -898,7 +898,7 @@ namespace ts { ? undefined : node.asteriskToken, visitNode(node.name, visitor, isPropertyName), - visitNode>(/*questionToken*/ undefined, visitor, isToken), + visitNode(/*questionToken*/ undefined, visitor, isQuestionToken), /*typeParameters*/ undefined, visitParameterList(node.parameters, parameterVisitor, context), /*type*/ undefined, diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 9b3b8e6ee1283..05767e78154f7 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -469,7 +469,7 @@ namespace ts { */ function addExportEqualsIfNeeded(statements: Statement[], emitAsReturn: boolean) { if (currentModuleInfo.exportEquals) { - const expressionResult = visitNode(currentModuleInfo.exportEquals.expression, visitor); + const expressionResult = visitNode(currentModuleInfo.exportEquals.expression, visitor, isExpression); if (expressionResult) { if (emitAsReturn) { const statement = factory.createReturnStatement(expressionResult); @@ -710,7 +710,7 @@ namespace ts { function visitImportCallExpression(node: ImportCall): Expression { const externalModuleName = getExternalModuleNameLiteral(factory, node, currentSourceFile, host, resolver, compilerOptions); - const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor); + const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor, isExpression); // Only use the external module name if it differs from the first argument. This allows us to preserve the quote style of the argument on output. const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName : firstArgument; const containsLexicalThis = !!(node.transformFlags & TransformFlags.ContainsLexicalThis); @@ -1337,7 +1337,7 @@ namespace ts { variable.name, variable.exclamationToken, variable.type, - visitNode(variable.initializer, visitor) + visitNode(variable.initializer, visitor, isExpression) ); variables = append(variables, updatedVariable); diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 69351f1276062..95c90eca0c836 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1545,7 +1545,7 @@ namespace ts { // }; // }); const externalModuleName = getExternalModuleNameLiteral(factory, node, currentSourceFile, host, resolver, compilerOptions); - const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor); + const firstArgument = visitNode(firstOrUndefined(node.arguments), visitor, isExpression); // Only use the external module name if it differs from the first argument. This allows us to preserve the quote style of the argument on output. const argument = externalModuleName && (!firstArgument || !isStringLiteral(firstArgument) || firstArgument.text !== externalModuleName.text) ? externalModuleName : firstArgument; return factory.createCallExpression( diff --git a/src/compiler/transformers/taggedTemplate.ts b/src/compiler/transformers/taggedTemplate.ts index 60b37c1018f49..8aa6d7bc10233 100644 --- a/src/compiler/transformers/taggedTemplate.ts +++ b/src/compiler/transformers/taggedTemplate.ts @@ -8,7 +8,7 @@ namespace ts { export function processTaggedTemplateExpression( context: TransformationContext, node: TaggedTemplateExpression, - visitor: Visitor, + visitor: Visitor, currentSourceFile: SourceFile, recordTaggedTemplateString: (temp: Identifier) => void, level: ProcessLevel) { diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 831f63564a30a..c882c5861e91e 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -333,7 +333,7 @@ namespace ts { } } - function getObjectLiteralElementVisitor(parent: ObjectLiteralExpression): (node: Node) => VisitResult { + function getObjectLiteralElementVisitor(parent: ObjectLiteralExpression): (node: T) => VisitResult { return node => saveStateAndInvoke(node, n => objectLiteralElementVisitorWorker(n, parent)); } @@ -589,7 +589,7 @@ namespace ts { function visitObjectLiteralExpression(node: ObjectLiteralExpression) { return factory.updateObjectLiteralExpression( node, - visitNodes(node.properties, getObjectLiteralElementVisitor(node), isObjectLiteralElement) + visitNodes(node.properties, getObjectLiteralElementVisitor(node), isObjectLiteralElementLike) ); } @@ -1450,7 +1450,7 @@ namespace ts { node, visitNode(node.tag, visitor, isExpression), /*typeArguments*/ undefined, - visitNode(node.template, visitor, isExpression)); + visitNode(node.template, visitor, isTemplateLiteral)); } function visitJsxSelfClosingElement(node: JsxSelfClosingElement) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ae913f4066a9f..1f1af05c2a85f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8537,23 +8537,27 @@ namespace ts { */ export type Transformer = (node: T) => T; // TODO(jakebailey): This signature is totally wrong. + // TODO(jakebailey): can we redefne NodeVisitor/NodesVisitor to not need overloads? + // Maybe along with NonNullable? + /** * A function that accepts and possibly transforms a node. */ - export type Visitor = (node: Node) => VisitResult; + export type Visitor = (node: TIn) => VisitResult; export interface NodeVisitor { - (nodes: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T; - (nodes: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined; + (node: TIn, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut; + (node: TIn | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | undefined; } export interface NodesVisitor { - (nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; - (nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + (nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray; + (nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | undefined; } - // TODO(jakebailey): This should really be = T | readonly U[] | undefined. - export type VisitResult = T | readonly T[] | undefined; + // Either a node, or a list of nodes to be be lifted via a lift function. + // TODO: + export type VisitResult = T | readonly Node[] | undefined; export interface Printer { /** diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index e317c1c261176..1393f842e1a29 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1491,6 +1491,13 @@ namespace ts { return false; } + export function isBindingOrAssignmentElement(node: Node): node is BindingOrAssignmentElement { + return isVariableDeclaration(node) + || isParameter(node) + || isObjectBindingOrAssignmentElement(node) + || isArrayBindingOrAssignmentElement(node); + } + /** * Determines whether a node is a BindingOrAssignmentPattern */ @@ -1672,6 +1679,22 @@ namespace ts { } } + /** + * See isExpression; not for use in transforms. + * @internal + */ + export function isLiteralTypeLiteral(node: Node): node is NullLiteral | BooleanLiteral | LiteralExpression | PrefixUnaryExpression { + node = skipPartiallyEmittedExpressions(node); + switch (skipPartiallyEmittedExpressions(node).kind) { + case SyntaxKind.NullKeyword: + case SyntaxKind.BooleanKeyword: + case SyntaxKind.PrefixUnaryExpression: + return true; + default: + return isLiteralExpression(node); + } + } + /* @internal */ /** * Determines whether a node is an expression based only on its kind. diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 3d67d7d49258e..c01b45975c8a0 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -1,4 +1,6 @@ namespace ts { + // TODO(jakebailey): include type guard and non-type guard variants on visitNode and visitNodes + /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -7,7 +9,7 @@ namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - export function visitNode(node: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T; + export function visitNode(node: TIn, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut; /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. @@ -17,17 +19,19 @@ namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - export function visitNode(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined; + export function visitNode(node: TIn | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | undefined; - export function visitNode(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined { - if (node === undefined || visitor === undefined) { + export function visitNode(node: TIn | undefined, visitor?: Visitor, test?: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | undefined { + if (node === undefined) { return node; } - const visited = visitor(node); - if (visited === node) { - return node; - } + const visited = visitor ? visitor(node) : node; + // TODO(jakebailey): With the modified type vars, it doesn't make sense to skip the node test, + // becuase the input type may not be the desired output type. + // if (visited === node) { + // return node; + // } let visitedNode: Node | undefined; if (visited === undefined) { @@ -41,11 +45,10 @@ namespace ts { } Debug.assertNode(visitedNode, test); - return visitedNode as T; + return visitedNode as TOut; } - /* @internal */ - export function visitNodes(nodes: NodeArray, visitor: Visitor, test: (node: Node) => node is U, start?: number, count?: number): NodeArray; + ((_: NodeVisitor) => {})(visitNode); // Check that visitNode is a NodeVisitor. /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. @@ -56,10 +59,7 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - export function visitNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; - - /* @internal */ - export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor, test: (node: Node) => node is U, start?: number, count?: number): NodeArray | undefined; + export function visitNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. @@ -70,7 +70,7 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | undefined; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. @@ -81,8 +81,8 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined { - if (nodes === undefined || visitor === undefined) { + export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | undefined { + if (nodes === undefined) { return nodes; } @@ -111,25 +111,26 @@ namespace ts { } const updated = visitArrayWorker(nodes, visitor, test, start, count); - if (updated !== nodes as readonly T[]) { + if (updated !== nodes as readonly Node[]) { // TODO(rbuckton): Remove dependency on `ts.factory` in favor of a provided factory. const updatedArray = factory.createNodeArray(updated, hasTrailingComma); setTextRangePosEnd(updatedArray, pos, end); return updatedArray; } - return nodes; + // If we are here, updated === nodes. This means that it's still a NodeArray, + // and also that its contents passed the tests in visitArrayWorker, so has contents + // of type TOut. + return nodes as NodeArray as NodeArray; } + ((_: NodesVisitor) => {})(visitNodes); // Check that visitNode is a NodeVisitor. + /* @internal */ - export function visitArray(nodes: T[] | undefined, visitor: Visitor, test: (node: Node) => node is U, start?: number, count?: number): U[] | undefined; - /* @internal */ - export function visitArray(nodes: readonly T[] | undefined, visitor: Visitor, test: (node: Node) => node is U, start?: number, count?: number): readonly U[] | undefined; - /* @internal */ - export function visitArray(nodes: T[] | undefined, visitor: Visitor, test: (node: Node) => node is T, start?: number, count?: number): T[] | undefined; + export function visitArray(nodes: readonly TIn[], visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): readonly TOut[]; /* @internal */ - export function visitArray(nodes: readonly T[] | undefined, visitor: Visitor, test: (node: Node) => node is T, start?: number, count?: number): readonly T[] | undefined; - export function visitArray(nodes: readonly T[] | undefined, visitor: Visitor, test: (node: Node) => node is U, start?: number, count?: number) { + export function visitArray(nodes: readonly TIn[] | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): readonly TOut[] | undefined; + export function visitArray(nodes: readonly TIn[] | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): readonly TOut[] | undefined { if (nodes === undefined) { return nodes; } @@ -144,12 +145,12 @@ namespace ts { count = length - start; } - return visitArrayWorker(nodes, visitor, test, start, count) as readonly U[]; + return visitArrayWorker(nodes, visitor, test, start, count); } /* @internal */ - function visitArrayWorker(nodes: readonly T[], visitor: Visitor, test: ((node: Node) => boolean) | undefined, start: number, count: number): readonly T[] | undefined { - let updated: T[] | undefined; + function visitArrayWorker(nodes: readonly TIn[], visitor: Visitor | undefined, test: ((node: Node) => node is TOut) | undefined, start: number, count: number): readonly TOut[] { + let updated: Node[] | undefined; const length = nodes.length; if (start > 0 || count < length) { @@ -159,9 +160,9 @@ namespace ts { // Visit each original node. for (let i = 0; i < count; i++) { - const node: T = nodes[i + start]; - const visited = node !== undefined ? visitor(node) : undefined; - if (updated !== undefined || visited === undefined || visited !== node) { + const node = nodes[i + start]; + const visited = node !== undefined ? (visitor ? visitor(node) : node) : undefined; + if (updated !== undefined || visited === undefined || visited !== node as VisitResult) { if (updated === undefined) { // Ensure we have a copy of `nodes`, up to the current index. updated = nodes.slice(0, i); @@ -169,26 +170,28 @@ namespace ts { if (visited) { if (isArray(visited)) { for (const visitedNode of visited) { - void Debug.assertNode(visitedNode, test); - updated.push(visitedNode as T); + // void Debug.assertNode(visitedNode, test); + updated.push(visitedNode); } } else { - void Debug.assertNode(visited, test); - updated.push(visited as T); + // void Debug.assertNode(visited, test); + updated.push(visited); } } } } - return updated ?? nodes; + const result: readonly Node[] = updated ?? nodes; + Debug.assertEachNode(result, test) + return result as readonly TOut[]; } /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - export function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor: NodesVisitor = visitNodes) { + export function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor: NodesVisitor = visitNodes) { context.startLexicalEnvironment(); statements = nodesVisitor(statements, visitor, isStatement, start); if (ensureUseStrict) statements = context.factory.ensureUseStrict(statements); @@ -199,9 +202,9 @@ namespace ts { * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; - export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; - export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) { + export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; + export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) { let updated: NodeArray | undefined; context.startLexicalEnvironment(); if (nodes) { @@ -324,21 +327,21 @@ namespace ts { * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; + export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; + export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; /** * Resumes a suspended lexical environment and visits a concise body, ending the lexical * environment and merging hoisted declarations upon completion. */ - export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; - /* @internal*/ export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody; // eslint-disable-line @typescript-eslint/unified-signatures - /* @internal*/ export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody | undefined; // eslint-disable-line @typescript-eslint/unified-signatures - /* @internal*/ export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): ConciseBody; // eslint-disable-line @typescript-eslint/unified-signatures - export function visitFunctionBody(node: ConciseBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): ConciseBody | undefined { + export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; + /* @internal*/ export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody; // eslint-disable-line @typescript-eslint/unified-signatures + /* @internal*/ export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + /* @internal*/ export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): ConciseBody; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitFunctionBody(node: ConciseBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): ConciseBody | undefined { context.resumeLexicalEnvironment(); const updated = nodeVisitor(node, visitor, isConciseBody); const declarations = context.endLexicalEnvironment(); @@ -356,10 +359,10 @@ namespace ts { /** * Visits an iteration body, adding any block-scoped variables required by the transformation. */ - export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; + export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; /* @internal */ - export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): Statement; // eslint-disable-line @typescript-eslint/unified-signatures - export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): Statement { + export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): Statement; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): Statement { context.startBlockScope(); const updated = nodeVisitor(body, visitor, isStatement, context.factory.liftToBlock); const declarations = context.endBlockScope(); @@ -381,9 +384,9 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; + export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; /* @internal */ - export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T; // eslint-disable-line @typescript-eslint/unified-signatures /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -391,10 +394,10 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; /* @internal */ - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T | undefined; // eslint-disable-line @typescript-eslint/unified-signatures - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor, nodeVisitor: NodeVisitor = visitNode): T | undefined { + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor, nodeVisitor: NodeVisitor = visitNode): T | undefined { if (node === undefined) { return undefined; } @@ -403,7 +406,7 @@ namespace ts { return fn === undefined ? node : fn(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor); } - type VisitEachChildFunction = (node: T, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor, nodeVisitor: NodeVisitor, tokenVisitor: Visitor | undefined) => T; + type VisitEachChildFunction = (node: T, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor, nodeVisitor: NodeVisitor, tokenVisitor: Visitor | undefined) => T; // A type that correlates a `SyntaxKind` to a `VisitEachChildFunction`, for nodes in the `HasChildren` union. // This looks something like: @@ -466,7 +469,7 @@ namespace ts { return context.factory.updatePropertySignature(node, nodesVisitor(node.modifiers, visitor, isModifier), nodeVisitor(node.name, visitor, isPropertyName), - nodeVisitor(node.questionToken, tokenVisitor, isToken), + nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), nodeVisitor(node.type, visitor, isTypeNode)); }, @@ -691,7 +694,7 @@ namespace ts { [SyntaxKind.LiteralType]: function visitEachChildOfLiteralTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateLiteralTypeNode(node, - nodeVisitor(node.literal, visitor, isExpression)); + nodeVisitor(node.literal, visitor, isLiteralTypeLiteral)); }, [SyntaxKind.TemplateLiteralType]: function visitEachChildOfTemplateLiteralType(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { From 9d3b85123c8911e4f8b645be41f3a87df98e0f57 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sun, 18 Sep 2022 11:01:38 -0700 Subject: [PATCH 13/81] Make non-API tests pass without SFT, found some bugs --- src/compiler/transformers/module/system.ts | 2 +- src/compiler/types.ts | 10 +++++----- src/compiler/utilities.ts | 1 + src/compiler/utilitiesPublic.ts | 3 ++- src/services/refactors/extractSymbol.ts | 2 +- src/services/textChanges.ts | 4 ++-- src/testRunner/unittests/transform.ts | 7 ++++--- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 95c90eca0c836..e475373694f4d 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1317,7 +1317,7 @@ namespace ts { return expressions ? factory.inlineExpressions(expressions) : factory.createOmittedExpression(); } else { - return visitNode(node, discardedValueVisitor, isExpression); + return visitNode(node, discardedValueVisitor, isForInitializer); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 1f1af05c2a85f..a8b2e6499eaa6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4506,11 +4506,11 @@ namespace ts { export interface CustomTransformers { /** Custom transformers to evaluate before built-in .js transformations. */ - before?: (TransformerFactory | CustomTransformerFactory)[]; + before?: (TransformerFactory | CustomTransformerFactory)[]; /** Custom transformers to evaluate after built-in .js transformations. */ - after?: (TransformerFactory | CustomTransformerFactory)[]; + after?: (TransformerFactory | CustomTransformerFactory)[]; /** Custom transformers to evaluate after built-in .d.ts transformations. */ - afterDeclarations?: (TransformerFactory | CustomTransformerFactory)[]; + afterDeclarations?: (TransformerFactory | CustomTransformerFactory)[]; } /*@internal*/ @@ -8530,12 +8530,12 @@ namespace ts { * A function that is used to initialize and return a `Transformer` callback, which in turn * will be used to transform one or more nodes. */ - export type TransformerFactory = (context: TransformationContext) => Transformer; + export type TransformerFactory = (context: TransformationContext) => Transformer; /** * A function that transforms a node. */ - export type Transformer = (node: T) => T; // TODO(jakebailey): This signature is totally wrong. + export type Transformer = (node: T) => U; // TODO(jakebailey): This signature was totally wrong. Is it right now? // TODO(jakebailey): can we redefne NodeVisitor/NodesVisitor to not need overloads? // Maybe along with NonNullable? diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0a7c52216942f..23076ff48d1df 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5833,6 +5833,7 @@ namespace ts { || kind === SyntaxKind.VoidKeyword || kind === SyntaxKind.UndefinedKeyword || kind === SyntaxKind.NeverKeyword + || kind === SyntaxKind.IntrinsicKeyword || kind === SyntaxKind.ExpressionWithTypeArguments || kind === SyntaxKind.JSDocAllType || kind === SyntaxKind.JSDocUnknownType diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 1393f842e1a29..58fe2897a809e 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1687,7 +1687,8 @@ namespace ts { node = skipPartiallyEmittedExpressions(node); switch (skipPartiallyEmittedExpressions(node).kind) { case SyntaxKind.NullKeyword: - case SyntaxKind.BooleanKeyword: + case SyntaxKind.TrueKeyword: + case SyntaxKind.FalseKeyword: case SyntaxKind.PrefixUnaryExpression: return true; default: diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 67435b4735456..59bfabcf4105f 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1425,7 +1425,7 @@ namespace ts.refactor.extractSymbol { const statements = factory.createNodeArray(isBlock(body) ? body.statements.slice(0) : [isStatement(body) ? body : factory.createReturnStatement(skipParentheses(body as Expression))]); // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions if (hasWritesOrVariableDeclarations || substitutions.size) { - const rewrittenStatements = visitNodes(statements, visitor).slice(); + const rewrittenStatements = visitNodes(statements, visitor, isStatement).slice(); if (hasWritesOrVariableDeclarations && !hasReturn && isStatement(body)) { // add return at the end to propagate writes back in case if control flow falls out of the function body // it is ok to know that range has at least one return since it we only allow unconditional returns diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 59f22c8a9fbe0..53bb5b6f546c0 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1136,8 +1136,8 @@ namespace ts.textChanges { return newNode; } - function assignPositionsToNodeArray(nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) { - const visited = visitNodes(nodes, visitor, test, start, count); + function assignPositionsToNodeArray(nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) { + const visited = visitNodes(nodes, visitor, test as (node: Node) => node is Node, start, count); // TODO(jakebailey): remove this once a non-guard signature is added to visitNode/visitNodes if (!visited) { return visited; } diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index dadf9ecd6ae71..08914006da2d1 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -41,13 +41,13 @@ namespace ts { } function replaceIdentifiersNamedOldNameWithNewName2(context: TransformationContext) { - const visitor: Visitor = (node) => { + const visitor: Visitor = (node) => { if (isIdentifier(node) && node.text === "oldName") { return factory.createIdentifier("newName"); } return visitEachChild(node, visitor, context); }; - return (node: SourceFile) => visitNode(node, visitor); + return (node: Node) => visitNode(node, visitor); } function createTaggedTemplateLiteral(): Transformer { @@ -539,6 +539,7 @@ module MyModule { const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true); const transformed = transform(createSourceFile("source.ts", "class X { echo(x: string) { return x; } }", ScriptTarget.ES3), [transformSourceFile]); const transformedSourceFile = transformed.transformed[0]; + Debug.assertNode(transformedSourceFile, isSourceFile); transformed.dispose(); const host = new fakes.CompilerHost(fs); host.getSourceFile = () => transformedSourceFile; @@ -551,7 +552,7 @@ module MyModule { return host.readFile("source.js")!.toString(); function transformSourceFile(context: TransformationContext) { - const visitor: Visitor = (node) => { + const visitor: Visitor = (node) => { if (isMethodDeclaration(node)) { return factory.updateMethodDeclaration( node, From 8bcad61c07adcf8fe2c7acebad2698cb13f87df8 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sun, 18 Sep 2022 22:17:32 -0700 Subject: [PATCH 14/81] Wacky Visitor types --- src/compiler/checker.ts | 29 ++- src/compiler/transformers/classFields.ts | 18 +- src/compiler/transformers/declarations.ts | 24 +-- src/compiler/transformers/destructuring.ts | 7 +- src/compiler/transformers/es2015.ts | 22 ++- src/compiler/transformers/es2017.ts | 6 +- src/compiler/transformers/es2018.ts | 2 +- src/compiler/transformers/generators.ts | 18 +- src/compiler/transformers/jsx.ts | 6 +- src/compiler/transformers/legacyDecorators.ts | 10 +- .../transformers/module/esnextAnd2015.ts | 6 +- src/compiler/transformers/module/module.ts | 24 +-- src/compiler/transformers/module/system.ts | 20 +-- src/compiler/transformers/taggedTemplate.ts | 3 +- src/compiler/transformers/ts.ts | 58 +++--- src/compiler/types.ts | 86 ++++++--- src/compiler/visitorPublic.ts | 165 ++++++++++-------- src/services/codefixes/helpers.ts | 5 +- src/services/textChanges.ts | 24 ++- src/services/utilities.ts | 4 +- src/testRunner/unittests/transform.ts | 8 +- 21 files changed, 325 insertions(+), 220 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6e09b094b5bc8..bf4e37975a68e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1096,7 +1096,7 @@ namespace ts { if (jsxFragmentPragma) { const chosenPragma = isArray(jsxFragmentPragma) ? jsxFragmentPragma[0] : jsxFragmentPragma; file.localJsxFragmentFactory = parseIsolatedEntityName(chosenPragma.arguments.factory, languageVersion); - visitNode(file.localJsxFragmentFactory, markAsSynthetic); + visitNode(file.localJsxFragmentFactory, markAsSynthetic, isEntityName); if (file.localJsxFragmentFactory) { return file.localJsxFragmentNamespace = getFirstIdentifier(file.localJsxFragmentFactory).escapedText; } @@ -1142,14 +1142,14 @@ namespace ts { if (jsxPragma) { const chosenPragma = isArray(jsxPragma) ? jsxPragma[0] : jsxPragma; file.localJsxFactory = parseIsolatedEntityName(chosenPragma.arguments.factory, languageVersion); - visitNode(file.localJsxFactory, markAsSynthetic); + visitNode(file.localJsxFactory, markAsSynthetic, isEntityName); if (file.localJsxFactory) { return file.localJsxNamespace = getFirstIdentifier(file.localJsxFactory).escapedText; } } } - function markAsSynthetic(node: Node): VisitResult { + function markAsSynthetic(node: T): VisitResult { setTextRangePosEnd(node, -1, -1); return visitEachChild(node, markAsSynthetic, nullTransformationContext); } @@ -5495,13 +5495,24 @@ namespace ts { return setTextRange(factory.cloneNode(visitEachChild(node, deepCloneOrReuseNode, nullTransformationContext, deepCloneOrReuseNodes)), node); } - function deepCloneOrReuseNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray; - function deepCloneOrReuseNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | undefined; - function deepCloneOrReuseNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | undefined { + function deepCloneOrReuseNodes< + TIn extends Node, + TArray extends NodeArray | undefined, + TVisited extends Node | undefined, + TAssert extends NonNullable, + TOut extends TArray extends undefined ? NodeArray | undefined + : NodeArray, + >( + nodes: TArray, + visitor: Visitor | undefined, + test?: (node: Node) => node is TAssert, + start?: number, + count?: number, + ): TOut { if (nodes && nodes.length === 0) { // Ensure we explicitly make a copy of an empty array; visitNodes will not do this unless the array has elements, // which can lead to us reusing the same empty NodeArray more than once within the same AST during type noding. - return setTextRange(factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes); + return setTextRange(factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes) as TOut; } return visitNodes(nodes, visitor, test, start, count); } @@ -6861,7 +6872,7 @@ namespace ts { let newTypeNode: TypeNode | undefined; return factory.createConstructorTypeNode( /*modifiers*/ undefined, - visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), + visitNodes(node.typeParameters, visitExistingNodeTreeSymbols, isTypeParameterDeclaration), mapDefined(node.parameters, (p, i) => p.name && isIdentifier(p.name) && p.name.escapedText === "new" ? (newTypeNode = p.type, undefined) : factory.createParameterDeclaration( /*modifiers*/ undefined, getEffectiveDotDotDotForParameter(p), @@ -6875,7 +6886,7 @@ namespace ts { } else { return factory.createFunctionTypeNode( - visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), + visitNodes(node.typeParameters, visitExistingNodeTreeSymbols, isTypeParameterDeclaration), map(node.parameters, (p, i) => factory.createParameterDeclaration( /*modifiers*/ undefined, getEffectiveDotDotDotForParameter(p), diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 7958ee1daf917..2ed292952e9ff 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -211,7 +211,7 @@ namespace ts { return visited; } - function visitor(node: Node): VisitResult { + function visitor(node: Node): VisitResult | undefined { if (!(node.transformFlags & TransformFlags.ContainsClassFields) && !(node.transformFlags & TransformFlags.ContainsLexicalThisOrSuper)) { return node; @@ -274,7 +274,7 @@ namespace ts { /** * Visits a node in an expression whose result is discarded. */ - function discardedValueVisitor(node: Node): VisitResult { + function discardedValueVisitor(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.PostfixUnaryExpression: @@ -289,7 +289,7 @@ namespace ts { /** * Visits a node in a {@link HeritageClause}. */ - function heritageClauseVisitor(node: Node): VisitResult { + function heritageClauseVisitor(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.HeritageClause: return visitEachChild(node, heritageClauseVisitor, context); @@ -303,7 +303,7 @@ namespace ts { /** * Visits the assignment target of a destructuring assignment. */ - function assignmentTargetVisitor(node: Node): VisitResult { + function assignmentTargetVisitor(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.ArrayLiteralExpression: @@ -316,7 +316,7 @@ namespace ts { /** * Visits a member of a class. */ - function classElementVisitor(node: Node): VisitResult { + function classElementVisitor(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.Constructor: return visitConstructorDeclaration(node as ConstructorDeclaration); @@ -387,6 +387,7 @@ namespace ts { const info = accessPrivateIdentifier(node.left); if (info) { const receiver = visitNode(node.right, visitor, isExpression); + Debug.assert(receiver); return setOriginalNode( context.getEmitHelperFactory().createClassPrivateFieldInHelper(info.brandCheckIdentifier, receiver), @@ -413,6 +414,7 @@ namespace ts { function visitComputedPropertyName(node: ComputedPropertyName) { let expression = visitNode(node.expression, visitor, isExpression); + Debug.assert(expression); if (some(pendingExpressions)) { if (isParenthesizedExpression(expression)) { expression = factory.updateParenthesizedExpression(expression, factory.inlineExpressions([...pendingExpressions, expression.expression])); @@ -521,6 +523,7 @@ namespace ts { const temp = factory.createTempVariable(hoistVariableDeclaration); setSourceMapRange(temp, name.expression); const expression = visitNode(name.expression, visitor, isExpression); + Debug.assert(expression); const assignment = factory.createAssignment(temp, expression); setSourceMapRange(assignment, name.expression); getterName = factory.updateComputedPropertyName(name, factory.inlineExpressions([assignment, temp])); @@ -731,6 +734,7 @@ namespace ts { let info: PrivateIdentifierInfo | undefined; if (info = accessPrivateIdentifier(operand.name)) { const receiver = visitNode(operand.expression, visitor, isExpression); + Debug.assert(receiver); const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); let expression: Expression = createPrivateIdentifierAccess(info, readExpression); @@ -1017,6 +1021,7 @@ namespace ts { setOriginalNode(superPropertyGet, node.left); setTextRange(superPropertyGet, node.left); + Debug.assert(expression); expression = factory.createBinaryExpression( superPropertyGet, getNonAssignmentOperatorForCompoundAssignment(node.operatorToken.kind), @@ -1027,10 +1032,12 @@ namespace ts { const temp = valueIsDiscarded ? undefined : factory.createTempVariable(hoistVariableDeclaration); if (temp) { + Debug.assert(expression); expression = factory.createAssignment(temp, expression); setTextRange(temp, node); } + Debug.assert(expression); expression = factory.createReflectSetCall( superClassReference, setterName, @@ -2010,6 +2017,7 @@ namespace ts { function getPropertyNameExpressionIfNeeded(name: PropertyName, shouldHoist: boolean): Expression | undefined { if (isComputedPropertyName(name)) { const expression = visitNode(name.expression, visitor, isExpression); + Debug.assert(expression); const innerExpression = skipPartiallyEmittedExpressions(expression); const inlinable = isSimpleInlineableExpression(innerExpression); const alreadyTransformed = isAssignmentExpression(innerExpression) && isGeneratedIdentifier(innerExpression.left); diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 268c2ae77d3d0..99d5133e94f51 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -60,7 +60,7 @@ namespace ts { let enclosingDeclaration: Node; let necessaryTypeReferences: Set<[specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined]> | undefined; let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined; - let lateStatementReplacementMap: ESMap>; + let lateStatementReplacementMap: ESMap | undefined>; let suppressNewDiagnosticContexts: boolean; let exportedModulesFromDeclarationEmit: Symbol[] | undefined; @@ -459,14 +459,14 @@ namespace ts { } else { if (name.kind === SyntaxKind.ArrayBindingPattern) { - return factory.updateArrayBindingPattern(name, visitNodes(name.elements, visitBindingElement)); + return factory.updateArrayBindingPattern(name, visitNodes(name.elements, visitBindingElement, isArrayBindingElement)); } else { - return factory.updateObjectBindingPattern(name, visitNodes(name.elements, visitBindingElement)); + return factory.updateObjectBindingPattern(name, visitNodes(name.elements, visitBindingElement, isBindingElement)); } } - function visitBindingElement(elem: T): T; + function visitBindingElement(elem: T): T; function visitBindingElement(elem: ArrayBindingElement): ArrayBindingElement { if (elem.kind === SyntaxKind.OmittedExpression) { return elem; @@ -869,7 +869,7 @@ namespace ts { } } - function visitDeclarationSubtree(input: Node): VisitResult { + function visitDeclarationSubtree(input: Node): VisitResult | undefined { if (shouldStripInternal(input)) return; if (isDeclaration(input)) { if (isDeclarationAndNotVisible(input)) return; @@ -1065,6 +1065,10 @@ namespace ts { const trueType = visitNode(input.trueType, visitDeclarationSubtree, isTypeNode); enclosingDeclaration = oldEnclosingDecl; const falseType = visitNode(input.falseType, visitDeclarationSubtree, isTypeNode); + Debug.assert(checkType); + Debug.assert(extendsType); + Debug.assert(trueType); + Debug.assert(falseType); return cleanup(factory.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType)); } case SyntaxKind.FunctionType: { @@ -1118,7 +1122,7 @@ namespace ts { return node.parent.kind === SyntaxKind.MethodDeclaration && hasEffectiveModifier(node.parent, ModifierFlags.Private); } - function visitDeclarationStatements(input: Node): VisitResult { + function visitDeclarationStatements(input: Node): VisitResult | undefined { if (!isPreservedDeclarationStatement(input)) { // return undefined for unmatched kinds to omit them from the tree return; @@ -1237,7 +1241,7 @@ namespace ts { input.name, ensureTypeParams(input, input.typeParameters), transformHeritageClauses(input.heritageClauses), - visitNodes(input.members, visitDeclarationSubtree) + visitNodes(input.members, visitDeclarationSubtree, isTypeElement) )); } case SyntaxKind.FunctionDeclaration: { @@ -1462,11 +1466,11 @@ namespace ts { if (clause.token === SyntaxKind.ExtendsKeyword) { const oldDiag = getSymbolAccessibilityDiagnostic; getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(clause.types[0]); - const newClause = factory.updateHeritageClause(clause, map(clause.types, t => factory.updateExpressionWithTypeArguments(t, newId, visitNodes(t.typeArguments, visitDeclarationSubtree)))); + const newClause = factory.updateHeritageClause(clause, map(clause.types, t => factory.updateExpressionWithTypeArguments(t, newId, visitNodes(t.typeArguments, visitDeclarationSubtree, isTypeNode)))); getSymbolAccessibilityDiagnostic = oldDiag; return newClause; } - return factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => isEntityNameExpression(t.expression) || t.expression.kind === SyntaxKind.NullKeyword)), visitDeclarationSubtree)); + return factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => isEntityNameExpression(t.expression) || t.expression.kind === SyntaxKind.NullKeyword)), visitDeclarationSubtree, isExpressionWithTypeArguments)); })); return [statement, cleanup(factory.updateClassDeclaration( input, @@ -1616,7 +1620,7 @@ namespace ts { function transformHeritageClauses(nodes: NodeArray | undefined) { return factory.createNodeArray(filter(map(nodes, clause => factory.updateHeritageClause(clause, visitNodes(factory.createNodeArray(filter(clause.types, t => { return isEntityNameExpression(t.expression) || (clause.token === SyntaxKind.ExtendsKeyword && t.expression.kind === SyntaxKind.NullKeyword); - })), visitDeclarationSubtree))), clause => clause.types && !!clause.types.length)); + })), visitDeclarationSubtree, isExpressionWithTypeArguments))), clause => clause.types && !!clause.types.length)); } } diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index acbb5cc42739b..530c01ff8569c 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -11,7 +11,7 @@ namespace ts { createArrayBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ArrayBindingOrAssignmentPattern; createObjectBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ObjectBindingOrAssignmentPattern; createArrayBindingOrAssignmentElement: (node: Identifier) => BindingOrAssignmentElement; - visitor?: (node: Node) => VisitResult; + visitor?: (node: Node) => VisitResult | undefined; } export const enum FlattenLevel { @@ -32,7 +32,7 @@ namespace ts { */ export function flattenDestructuringAssignment( node: VariableDeclaration | DestructuringAssignment, - visitor: ((node: Node) => VisitResult) | undefined, + visitor: ((node: Node) => VisitResult | undefined) | undefined, context: TransformationContext, level: FlattenLevel, needsValue?: boolean, @@ -68,6 +68,7 @@ namespace ts { if (value) { value = visitNode(value, visitor, isExpression); + Debug.assert(value); if (isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText) || bindingOrAssignmentElementContainsNonLiteralComputedName(node)) { @@ -171,7 +172,7 @@ namespace ts { */ export function flattenDestructuringBinding( node: VariableDeclaration | ParameterDeclaration, - visitor: (node: Node) => VisitResult, + visitor: (node: Node) => VisitResult | undefined, context: TransformationContext, level: FlattenLevel, rval?: Expression, diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 0e03843ad4ba5..d5bb4c1d0f643 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -374,15 +374,15 @@ namespace ts { || (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0; } - function visitor(node: Node): VisitResult { + function visitor(node: Node): VisitResult | undefined { return shouldVisitNode(node) ? visitorWorker(node, /*expressionResultIsUnused*/ false) : node; } - function visitorWithUnusedExpressionResult(node: Node): VisitResult { + function visitorWithUnusedExpressionResult(node: Node): VisitResult | undefined { return shouldVisitNode(node) ? visitorWorker(node, /*expressionResultIsUnused*/ true) : node; } - function classWrapperStatementVisitor(node: Node): VisitResult { + function classWrapperStatementVisitor(node: Node): VisitResult | undefined { if (shouldVisitNode(node)) { const original = getOriginalNode(node); if (isPropertyDeclaration(original) && hasStaticModifier(original)) { @@ -399,14 +399,14 @@ namespace ts { return node; } - function callExpressionVisitor(node: Node): VisitResult { + function callExpressionVisitor(node: Node): VisitResult | undefined { if (node.kind === SyntaxKind.SuperKeyword) { return visitSuperKeyword(/*isExpressionOfCall*/ true); } return visitor(node); } - function visitorWorker(node: Node, expressionResultIsUnused: boolean): VisitResult { + function visitorWorker(node: Node, expressionResultIsUnused: boolean): VisitResult | undefined { switch (node.kind) { case SyntaxKind.StaticKeyword: return undefined; // elide static keyword @@ -1715,6 +1715,7 @@ namespace ts { const sourceMapRange = getSourceMapRange(member); const memberFunction = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined, container); const propertyName = visitNode(member.name, visitor, isPropertyName); + Debug.assert(propertyName); let e: Expression; if (!isPrivateIdentifier(propertyName) && getUseDefineForClassFields(context.getCompilerOptions())) { const name = isComputedPropertyName(propertyName) ? propertyName.expression @@ -1771,6 +1772,7 @@ namespace ts { setSourceMapRange(target, firstAccessor.name); const visitedAccessorName = visitNode(firstAccessor.name, visitor, isPropertyName); + Debug.assert(visitedAccessorName); if (isPrivateIdentifier(visitedAccessorName)) { return Debug.failBadSyntaxKind(visitedAccessorName, "Encountered unhandled private identifier while transforming ES2015."); } @@ -2125,6 +2127,7 @@ namespace ts { const visited = visitNode(element, i < node.elements.length - 1 ? visitorWithUnusedExpressionResult : visitor, isExpression); if (result || visited !== element) { result ||= node.elements.slice(0, i); + Debug.assert(visited); result.push(visited); } } @@ -2347,7 +2350,7 @@ namespace ts { convertedLoopState!.labels!.set(idText(node.label), false); } - function visitLabeledStatement(node: LabeledStatement): VisitResult { + function visitLabeledStatement(node: LabeledStatement): VisitResult | undefined { if (convertedLoopState && !convertedLoopState.labels) { convertedLoopState.labels = new Map(); } @@ -2500,6 +2503,7 @@ namespace ts { } else { const statement = visitNode(node.statement, visitor, isStatement, factory.liftToBlock); + Debug.assert(statement); if (isBlock(statement)) { return factory.updateBlock(statement, setTextRange(factory.createNodeArray(concatenate(statements, statement.statements)), statement.statements)); } @@ -2543,6 +2547,7 @@ namespace ts { // for-of bodies are always emitted as blocks. const expression = visitNode(node.expression, visitor, isExpression); + Debug.assert(expression); // In the case where the user wrote an identifier as the RHS, like this: // @@ -2592,6 +2597,7 @@ namespace ts { function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined, ancestorFacts: HierarchyFacts): Statement { const expression = visitNode(node.expression, visitor, isExpression); + Debug.assert(expression); const iterator = isIdentifier(expression) ? factory.getGeneratedNameForNode(expression) : factory.createTempVariable(/*recordTempVariable*/ undefined); const result = isIdentifier(expression) ? factory.getGeneratedNameForNode(iterator) : factory.createTempVariable(/*recordTempVariable*/ undefined); const errorRecord = factory.createUniqueName("e"); @@ -3229,6 +3235,7 @@ namespace ts { } } + Debug.assert(statement); if (isBlock(statement)) { addRange(statements, statement.statements); } @@ -4080,6 +4087,7 @@ namespace ts { function visitExpressionOfSpread(node: Expression): SpreadSegment { Debug.assertNode(node, isSpreadElement); let expression = visitNode(node.expression, visitor, isExpression); + Debug.assert(expression); // We don't need to pack already packed array literals, or existing calls to the `__read` helper. const isCallToReadHelper = isCallToHelper(expression, "___read" as __String); @@ -4166,7 +4174,7 @@ namespace ts { function visitTemplateExpression(node: TemplateExpression): Expression { let expression: Expression = factory.createStringLiteral(node.head.text); for (const span of node.templateSpans) { - const args = [visitNode(span.expression, visitor, isExpression)]; + const args = [Debug.checkDefined(visitNode(span.expression, visitor, isExpression))]; if (span.literal.text.length > 0) { args.push(factory.createStringLiteral(span.literal.text)); diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 260f76f65d8db..98f389cde9b1f 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -103,7 +103,7 @@ namespace ts { return visitEachChild(node, visitor, context); } - function visitor(node: Node): VisitResult { + function visitor(node: Node): VisitResult | undefined { if ((node.transformFlags & TransformFlags.ContainsES2017) === 0) { return node; } @@ -151,7 +151,7 @@ namespace ts { } } - function asyncBodyVisitor(node: Node): VisitResult { + function asyncBodyVisitor(node: Node): VisitResult | undefined { if (isNodeWithPossibleHoistedDeclaration(node)) { switch (node.kind) { case SyntaxKind.VariableStatement: @@ -429,7 +429,7 @@ namespace ts { ), node ); - return visitNode(converted, visitor, isExpression); + return Debug.checkDefined(visitNode(converted, visitor, isExpression)); } function collidesWithParameterName({ name }: VariableDeclaration | BindingElement): boolean { diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 302a8a705ac17..acc01826f85b8 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -127,7 +127,7 @@ namespace ts { return visitorWorker(node, /*expressionResultIsUnused*/ true); } - function visitorNoAsyncModifier(node: Node): VisitResult { + function visitorNoAsyncModifier(node: Node): VisitResult | undefined { if (node.kind === SyntaxKind.AsyncKeyword) { return undefined; } diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index ee19c12c9aec6..9bbc8fdab75c8 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -310,7 +310,7 @@ namespace ts { * * @param node The node to visit. */ - function visitor(node: Node): VisitResult { + function visitor(node: Node): VisitResult | undefined { const transformFlags = node.transformFlags; if (inStatementContainingYield) { return visitJavaScriptInStatementContainingYield(node); @@ -334,7 +334,7 @@ namespace ts { * * @param node The node to visit. */ - function visitJavaScriptInStatementContainingYield(node: Node): VisitResult { + function visitJavaScriptInStatementContainingYield(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.DoStatement: return visitDoStatement(node as DoStatement); @@ -354,7 +354,7 @@ namespace ts { * * @param node The node to visit. */ - function visitJavaScriptInGeneratorFunctionBody(node: Node): VisitResult { + function visitJavaScriptInGeneratorFunctionBody(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.FunctionDeclaration: return visitFunctionDeclaration(node as FunctionDeclaration); @@ -423,7 +423,7 @@ namespace ts { * * @param node The node to visit. */ - function visitGenerator(node: Node): VisitResult { + function visitGenerator(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.FunctionDeclaration: return visitFunctionDeclaration(node as FunctionDeclaration); @@ -693,7 +693,7 @@ namespace ts { target = factory.updatePropertyAccessExpression( left as PropertyAccessExpression, - cacheExpression(visitNode((left as PropertyAccessExpression).expression, visitor, isLeftHandSideExpression)), + cacheExpression(Debug.checkDefined(visitNode((left as PropertyAccessExpression).expression, visitor, isLeftHandSideExpression))), (left as PropertyAccessExpression).name ); break; @@ -711,8 +711,8 @@ namespace ts { // _a[_b] = %sent%; target = factory.updateElementAccessExpression(left as ElementAccessExpression, - cacheExpression(visitNode((left as ElementAccessExpression).expression, visitor, isLeftHandSideExpression)), - cacheExpression(visitNode((left as ElementAccessExpression).argumentExpression, visitor, isExpression)) + cacheExpression(Debug.checkDefined(visitNode((left as ElementAccessExpression).expression, visitor, isLeftHandSideExpression))), + cacheExpression(Debug.checkDefined(visitNode((left as ElementAccessExpression).argumentExpression, visitor, isExpression))) ); break; @@ -1107,7 +1107,7 @@ namespace ts { // a = _a[%sent%] return factory.updateElementAccessExpression(node, - cacheExpression(visitNode(node.expression, visitor, isLeftHandSideExpression)), + cacheExpression(Debug.checkDefined(visitNode(node.expression, visitor, isLeftHandSideExpression))), visitNode(node.argumentExpression, visitor, isExpression)); } @@ -1130,7 +1130,7 @@ namespace ts { return setOriginalNode( setTextRange( factory.createFunctionApplyCall( - cacheExpression(visitNode(target, visitor, isLeftHandSideExpression)), + cacheExpression(Debug.checkDefined(visitNode(target, visitor, isLeftHandSideExpression))), thisArg, visitElements(node.arguments) ), diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 80a8fefe877d3..a330b09668ab1 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -114,7 +114,7 @@ namespace ts { return visited; } - function visitor(node: Node): VisitResult { + function visitor(node: Node): VisitResult | undefined { if (node.transformFlags & TransformFlags.ContainsJsx) { return visitorWorker(node); } @@ -123,7 +123,7 @@ namespace ts { } } - function visitorWorker(node: Node): VisitResult { + function visitorWorker(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.JsxElement: return visitJsxElement(node as JsxElement, /*isChild*/ false); @@ -391,7 +391,7 @@ namespace ts { } function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) { - return visitNode(node.expression, visitor, isExpression); + return Debug.checkDefined(visitNode(node.expression, visitor, isExpression)); } function transformJsxAttributeToObjectLiteralElement(node: JsxAttribute) { diff --git a/src/compiler/transformers/legacyDecorators.ts b/src/compiler/transformers/legacyDecorators.ts index 4e241f20a1704..438e25bc858b0 100644 --- a/src/compiler/transformers/legacyDecorators.ts +++ b/src/compiler/transformers/legacyDecorators.ts @@ -31,11 +31,11 @@ namespace ts { return visited; } - function modifierVisitor(node: Node): VisitResult { + function modifierVisitor(node: Node): VisitResult | undefined { return isDecorator(node) ? undefined : node; } - function visitor(node: Node): VisitResult { + function visitor(node: Node): VisitResult | undefined { if (!(node.transformFlags & TransformFlags.ContainsDecorators)) { return node; } @@ -360,7 +360,7 @@ namespace ts { return finishClassElement(factory.updatePropertyDeclaration( node, visitNodes(node.modifiers, modifierVisitor, isModifier), - visitNode(node.name, visitor, isPropertyName), + Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)), /*questionOrExclamationToken*/ undefined, /*type*/ undefined, visitNode(node.initializer, visitor, isExpression) @@ -372,7 +372,7 @@ namespace ts { node, elideNodes(factory, node.modifiers), node.dotDotDotToken, - visitNode(node.name, visitor, isBindingName), + Debug.checkDefined(visitNode(node.name, visitor, isBindingName)), /*questionToken*/ undefined, /*type*/ undefined, visitNode(node.initializer, visitor, isExpression) @@ -569,7 +569,7 @@ namespace ts { * @param decorator The decorator node. */ function transformDecorator(decorator: Decorator) { - return visitNode(decorator.expression, visitor, isExpression); + return Debug.checkDefined(visitNode(decorator.expression, visitor, isExpression)); } /** diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index 3ab66a565b7f4..b74a8400af150 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -66,7 +66,7 @@ namespace ts { } } - function visitor(node: Node): VisitResult { + function visitor(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.ImportEqualsDeclaration: // Though an error in es2020 modules, in node-flavor es2020 modules, we can helpfully transform this to a synthetic `require` call @@ -139,7 +139,7 @@ namespace ts { * * @param node The node to visit. */ - function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { + function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult | undefined { Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer."); let statements: Statement[] | undefined; @@ -181,7 +181,7 @@ namespace ts { return statements; } - function visitExportAssignment(node: ExportAssignment): VisitResult { + function visitExportAssignment(node: ExportAssignment): VisitResult | undefined { // Elide `export=` as it is not legal with --module ES6 return node.isExportEquals ? undefined : node; } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 05767e78154f7..06d17e11c67e5 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -505,7 +505,7 @@ namespace ts { * * @param node The node to visit. */ - function topLevelVisitor(node: Node): VisitResult { + function topLevelVisitor(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.ImportDeclaration: return visitImportDeclaration(node as ImportDeclaration); @@ -891,7 +891,7 @@ namespace ts { * * @param node The node to visit. */ - function visitImportDeclaration(node: ImportDeclaration): VisitResult { + function visitImportDeclaration(node: ImportDeclaration): VisitResult | undefined { let statements: Statement[] | undefined; const namespaceDeclaration = getNamespaceDeclarationNode(node); if (moduleKind !== ModuleKind.AMD) { @@ -1011,7 +1011,7 @@ namespace ts { * * @param node The node to visit. */ - function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { + function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult | undefined { Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer."); let statements: Statement[] | undefined; @@ -1087,7 +1087,7 @@ namespace ts { * * @param The node to visit. */ - function visitExportDeclaration(node: ExportDeclaration): VisitResult { + function visitExportDeclaration(node: ExportDeclaration): VisitResult | undefined { if (!node.moduleSpecifier) { // Elide export declarations with no module specifier as they are handled // elsewhere. @@ -1197,7 +1197,7 @@ namespace ts { * * @param node The node to visit. */ - function visitExportAssignment(node: ExportAssignment): VisitResult { + function visitExportAssignment(node: ExportAssignment): VisitResult | undefined { if (node.isExportEquals) { return undefined; } @@ -1221,7 +1221,7 @@ namespace ts { * * @param node The node to visit. */ - function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { + function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult | undefined { let statements: Statement[] | undefined; if (hasSyntacticModifier(node, ModifierFlags.Export)) { statements = append(statements, @@ -1232,7 +1232,7 @@ namespace ts { node.asteriskToken, factory.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), /*typeParameters*/ undefined, - visitNodes(node.parameters, visitor), + visitNodes(node.parameters, visitor, isParameter), /*type*/ undefined, visitEachChild(node.body, visitor, context) ), @@ -1263,7 +1263,7 @@ namespace ts { * * @param node The node to visit. */ - function visitClassDeclaration(node: ClassDeclaration): VisitResult { + function visitClassDeclaration(node: ClassDeclaration): VisitResult | undefined { let statements: Statement[] | undefined; if (hasSyntacticModifier(node, ModifierFlags.Export)) { statements = append(statements, @@ -1273,8 +1273,8 @@ namespace ts { visitNodes(node.modifiers, modifierVisitor, isModifierLike), factory.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), /*typeParameters*/ undefined, - visitNodes(node.heritageClauses, visitor), - visitNodes(node.members, visitor) + visitNodes(node.heritageClauses, visitor, isHeritageClause), + visitNodes(node.members, visitor, isClassElement) ), node ), @@ -1303,7 +1303,7 @@ namespace ts { * * @param node The node to visit. */ - function visitVariableStatement(node: VariableStatement): VisitResult { + function visitVariableStatement(node: VariableStatement): VisitResult | undefined { let statements: Statement[] | undefined; let variables: VariableDeclaration[] | undefined; let expressions: Expression[] | undefined; @@ -1743,7 +1743,7 @@ namespace ts { * * @param node The node to visit. */ - function modifierVisitor(node: Node): VisitResult { + function modifierVisitor(node: Node): VisitResult | undefined { // Elide module-specific modifiers. switch (node.kind) { case SyntaxKind.ExportKeyword: diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index e475373694f4d..8132686581938 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -577,7 +577,7 @@ namespace ts { * * @param node The node to visit. */ - function topLevelVisitor(node: Node): VisitResult { + function topLevelVisitor(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.ImportDeclaration: return visitImportDeclaration(node as ImportDeclaration); @@ -601,7 +601,7 @@ namespace ts { * * @param node The node to visit. */ - function visitImportDeclaration(node: ImportDeclaration): VisitResult { + function visitImportDeclaration(node: ImportDeclaration): VisitResult | undefined { let statements: Statement[] | undefined; if (node.importClause) { hoistVariableDeclaration(getLocalNameForExternalImport(factory, node, currentSourceFile)!); // TODO: GH#18217 @@ -619,7 +619,7 @@ namespace ts { return singleOrMany(statements); } - function visitExportDeclaration(node: ExportDeclaration): VisitResult { + function visitExportDeclaration(node: ExportDeclaration): VisitResult | undefined { Debug.assertIsDefined(node); return undefined; } @@ -629,7 +629,7 @@ namespace ts { * * @param node The node to visit. */ - function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { + function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult | undefined { Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer."); let statements: Statement[] | undefined; @@ -652,7 +652,7 @@ namespace ts { * * @param node The node to visit. */ - function visitExportAssignment(node: ExportAssignment): VisitResult { + function visitExportAssignment(node: ExportAssignment): VisitResult | undefined { if (node.isExportEquals) { // Elide `export=` as it is illegal in a SystemJS module. return undefined; @@ -675,7 +675,7 @@ namespace ts { * * @param node The node to visit. */ - function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { + function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult | undefined { if (hasSyntacticModifier(node, ModifierFlags.Export)) { hoistedStatements = append(hoistedStatements, factory.updateFunctionDeclaration( @@ -709,7 +709,7 @@ namespace ts { * * @param node The node to visit. */ - function visitClassDeclaration(node: ClassDeclaration): VisitResult { + function visitClassDeclaration(node: ClassDeclaration): VisitResult | undefined { let statements: Statement[] | undefined; // Hoist the name of the class declaration to the outer module body function. @@ -756,7 +756,7 @@ namespace ts { * * @param node The node to visit. */ - function visitVariableStatement(node: VariableStatement): VisitResult { + function visitVariableStatement(node: VariableStatement): VisitResult | undefined { if (!shouldHoistVariableDeclarationList(node.declarationList)) { return visitNode(node, visitor, isStatement); } @@ -1162,7 +1162,7 @@ namespace ts { * * @param node The node to visit. */ - function topLevelNestedVisitor(node: Node): VisitResult { + function topLevelNestedVisitor(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.VariableStatement: return visitVariableStatement(node as VariableStatement); @@ -1667,7 +1667,7 @@ namespace ts { * * @param node The node to visit. */ - function modifierVisitor(node: Node): VisitResult { + function modifierVisitor(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.ExportKeyword: case SyntaxKind.DefaultKeyword: diff --git a/src/compiler/transformers/taggedTemplate.ts b/src/compiler/transformers/taggedTemplate.ts index 8aa6d7bc10233..ce9669566e7a8 100644 --- a/src/compiler/transformers/taggedTemplate.ts +++ b/src/compiler/transformers/taggedTemplate.ts @@ -8,13 +8,14 @@ namespace ts { export function processTaggedTemplateExpression( context: TransformationContext, node: TaggedTemplateExpression, - visitor: Visitor, + visitor: Visitor, currentSourceFile: SourceFile, recordTaggedTemplateString: (temp: Identifier) => void, level: ProcessLevel) { // Visit the tag expression const tag = visitNode(node.tag, visitor, isExpression); + Debug.assert(tag); // Build up the template arguments and the raw and cooked strings for the template. // We start out with 'undefined' for the first argument and revisit later diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index c882c5861e91e..ab7db3f044d0f 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -181,7 +181,7 @@ namespace ts { * * @param node The node to visit. */ - function visitor(node: Node): VisitResult { + function visitor(node: Node): VisitResult | undefined { return saveStateAndInvoke(node, visitorWorker); } @@ -190,7 +190,7 @@ namespace ts { * * @param node The node to visit. */ - function visitorWorker(node: Node): VisitResult { + function visitorWorker(node: Node): VisitResult | undefined { if (node.transformFlags & TransformFlags.ContainsTypeScript) { return visitTypeScript(node); } @@ -202,7 +202,7 @@ namespace ts { * * @param node The node to visit. */ - function sourceElementVisitor(node: Node): VisitResult { + function sourceElementVisitor(node: Node): VisitResult | undefined { return saveStateAndInvoke(node, sourceElementVisitorWorker); } @@ -211,7 +211,7 @@ namespace ts { * * @param node The node to visit. */ - function sourceElementVisitorWorker(node: Node): VisitResult { + function sourceElementVisitorWorker(node: Node): VisitResult | undefined { switch (node.kind) { case SyntaxKind.ImportDeclaration: case SyntaxKind.ImportEqualsDeclaration: @@ -223,7 +223,7 @@ namespace ts { } } - function visitElidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult { + function visitElidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult | undefined { const parsed = getParseTreeNode(node); if (parsed !== node) { // If the node has been transformed by a `before` transformer, perform no ellision on it @@ -256,7 +256,7 @@ namespace ts { * * @param node The node to visit. */ - function namespaceElementVisitor(node: Node): VisitResult { + function namespaceElementVisitor(node: Node): VisitResult | undefined { return saveStateAndInvoke(node, namespaceElementVisitorWorker); } @@ -265,7 +265,7 @@ namespace ts { * * @param node The node to visit. */ - function namespaceElementVisitorWorker(node: Node): VisitResult { + function namespaceElementVisitorWorker(node: Node): VisitResult | undefined { if (node.kind === SyntaxKind.ExportDeclaration || node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportClause || @@ -286,7 +286,7 @@ namespace ts { * * @param parent The class containing the elements to visit. */ - function getClassElementVisitor(parent: ClassLikeDeclaration): (node: Node) => VisitResult { + function getClassElementVisitor(parent: ClassLikeDeclaration): (node: Node) => VisitResult | undefined { return node => saveStateAndInvoke(node, n => classElementVisitorWorker(n, parent)); } @@ -295,7 +295,7 @@ namespace ts { * * @param node The node to visit. */ - function classElementVisitorWorker(node: Node, parent: ClassLikeDeclaration): VisitResult { + function classElementVisitorWorker(node: Node, parent: ClassLikeDeclaration): VisitResult | undefined { switch (node.kind) { case SyntaxKind.Constructor: return visitConstructor(node as ConstructorDeclaration); @@ -333,11 +333,11 @@ namespace ts { } } - function getObjectLiteralElementVisitor(parent: ObjectLiteralExpression): (node: T) => VisitResult { + function getObjectLiteralElementVisitor(parent: ObjectLiteralExpression): (node: T) => VisitResult | undefined { return node => saveStateAndInvoke(node, n => objectLiteralElementVisitorWorker(n, parent)); } - function objectLiteralElementVisitorWorker(node: Node, parent: ObjectLiteralExpression): VisitResult { + function objectLiteralElementVisitorWorker(node: Node, parent: ObjectLiteralExpression): VisitResult | undefined { switch (node.kind) { case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: @@ -362,7 +362,7 @@ namespace ts { } } - function modifierVisitor(node: Node): VisitResult { + function modifierVisitor(node: Node): VisitResult | undefined { if (isDecorator(node)) return undefined; if (modifierToFlag(node.kind) & ModifierFlags.TypeScriptModifier) { return undefined; @@ -379,7 +379,7 @@ namespace ts { * * @param node The node to visit. */ - function visitTypeScript(node: Node): VisitResult { + function visitTypeScript(node: Node): VisitResult | undefined { if (isStatement(node) && hasSyntacticModifier(node, ModifierFlags.Ambient)) { // TypeScript ambient declarations are elided, but some comments may be preserved. // See the implementation of `getLeadingComments` in comments.ts for more details. @@ -818,6 +818,7 @@ namespace ts { const decorators: Decorator[] = []; for (const parameterDecorator of parameterDecorators) { const expression = visitNode(parameterDecorator.expression, visitor, isExpression); + Debug.assert(expression); const helper = emitHelpers().createParamHelper(expression, parameterOffset); setTextRange(helper, parameterDecorator.expression); setEmitFlags(helper, EmitFlags.NoComments); @@ -969,6 +970,7 @@ namespace ts { // - the property has a decorator. if (isComputedPropertyName(name) && ((!hasStaticModifier(member) && currentClassHasParameterProperties) || hasDecorators(member))) { const expression = visitNode(name.expression, visitor, isExpression); + Debug.assert(expression); const innerExpression = skipPartiallyEmittedExpressions(expression); if (!isSimpleInlineableExpression(innerExpression)) { const generatedName = factory.getGeneratedNameForNode(name); @@ -1007,7 +1009,7 @@ namespace ts { function visitExpressionWithTypeArguments(node: ExpressionWithTypeArguments): ExpressionWithTypeArguments { return factory.updateExpressionWithTypeArguments( node, - visitNode(node.expression, visitor, isLeftHandSideExpression), + Debug.checkDefined(visitNode(node.expression, visitor, isLeftHandSideExpression)), /*typeArguments*/ undefined ); } @@ -1036,7 +1038,7 @@ namespace ts { return factory.updatePropertyDeclaration( node, concatenate(decorators, factory.createModifiersFromModifierFlags(ModifierFlags.Ambient)), - visitNode(node.name, visitor, isPropertyName), + Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)), /*questionOrExclamationToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined @@ -1310,7 +1312,7 @@ namespace ts { node, elideNodes(factory, node.modifiers), // preserve positions, if available node.dotDotDotToken, - visitNode(node.name, visitor, isBindingName), + Debug.checkDefined(visitNode(node.name, visitor, isBindingName)), /*questionToken*/ undefined, /*type*/ undefined, visitNode(node.initializer, visitor, isExpression) @@ -1390,6 +1392,7 @@ namespace ts { // Make sure we consider all nested cast expressions, e.g.: // (-A).x; const expression = visitNode(node.expression, visitor, isExpression); + Debug.assert(expression); // We have an expression of the form: (SubExpr). Emitting this as (SubExpr) // is really not desirable. We would like to emit the subexpression as-is. Omitting @@ -1416,16 +1419,19 @@ namespace ts { function visitAssertionExpression(node: AssertionExpression): Expression { const expression = visitNode(node.expression, visitor, isExpression); + Debug.assert(expression); return factory.createPartiallyEmittedExpression(expression, node); } function visitNonNullExpression(node: NonNullExpression): Expression { const expression = visitNode(node.expression, visitor, isLeftHandSideExpression); + Debug.assert(expression); return factory.createPartiallyEmittedExpression(expression, node); } function visitSatisfiesExpression(node: SatisfiesExpression): Expression { const expression = visitNode(node.expression, visitor, isExpression); + Debug.assert(expression); return factory.createPartiallyEmittedExpression(expression, node); } @@ -1967,7 +1973,7 @@ namespace ts { * * @param node The import declaration node. */ - function visitImportDeclaration(node: ImportDeclaration): VisitResult { + function visitImportDeclaration(node: ImportDeclaration): VisitResult | undefined { if (!node.importClause) { // Do not elide a side-effect only import declaration. // import "foo"; @@ -1997,7 +2003,7 @@ namespace ts { * * @param node The import clause node. */ - function visitImportClause(node: ImportClause): VisitResult { + function visitImportClause(node: ImportClause): VisitResult | undefined { Debug.assert(!node.isTypeOnly); // Elide the import clause if we elide both its name and its named bindings. const name = shouldEmitAliasDeclaration(node) ? node.name : undefined; @@ -2010,7 +2016,7 @@ namespace ts { * * @param node The named import bindings node. */ - function visitNamedImportBindings(node: NamedImportBindings): VisitResult { + function visitNamedImportBindings(node: NamedImportBindings): VisitResult | undefined { if (node.kind === SyntaxKind.NamespaceImport) { // Elide a namespace import if it is not referenced. return shouldEmitAliasDeclaration(node) ? node : undefined; @@ -2030,7 +2036,7 @@ namespace ts { * * @param node The import specifier node. */ - function visitImportSpecifier(node: ImportSpecifier): VisitResult { + function visitImportSpecifier(node: ImportSpecifier): VisitResult | undefined { return !node.isTypeOnly && shouldEmitAliasDeclaration(node) ? node : undefined; } @@ -2040,7 +2046,7 @@ namespace ts { * * @param node The export assignment node. */ - function visitExportAssignment(node: ExportAssignment): VisitResult { + function visitExportAssignment(node: ExportAssignment): VisitResult | undefined { // Elide the export assignment if it does not reference a value. return resolver.isValueAliasDeclaration(node) ? visitEachChild(node, visitor, context) @@ -2052,7 +2058,7 @@ namespace ts { * * @param node The export declaration node. */ - function visitExportDeclaration(node: ExportDeclaration): VisitResult { + function visitExportDeclaration(node: ExportDeclaration): VisitResult | undefined { if (node.isTypeOnly) { return undefined; } @@ -2090,7 +2096,7 @@ namespace ts { * * @param node The named exports node. */ - function visitNamedExports(node: NamedExports, allowEmpty: boolean): VisitResult { + function visitNamedExports(node: NamedExports, allowEmpty: boolean): VisitResult | undefined { // Elide the named exports if all of its export specifiers were elided. const elements = visitNodes(node.elements, visitExportSpecifier, isExportSpecifier); return allowEmpty || some(elements) ? factory.updateNamedExports(node, elements) : undefined; @@ -2100,7 +2106,7 @@ namespace ts { return factory.updateNamespaceExport(node, visitNode(node.name, visitor, isIdentifier)); } - function visitNamedExportBindings(node: NamedExportBindings, allowEmpty: boolean): VisitResult { + function visitNamedExportBindings(node: NamedExportBindings, allowEmpty: boolean): VisitResult | undefined { return isNamespaceExport(node) ? visitNamespaceExports(node) : visitNamedExports(node, allowEmpty); } @@ -2109,7 +2115,7 @@ namespace ts { * * @param node The export specifier node. */ - function visitExportSpecifier(node: ExportSpecifier): VisitResult { + function visitExportSpecifier(node: ExportSpecifier): VisitResult | undefined { // Elide an export specifier if it does not reference a value. return !node.isTypeOnly && resolver.isValueAliasDeclaration(node) ? node : undefined; } @@ -2133,7 +2139,7 @@ namespace ts { * * @param node The import equals declaration node. */ - function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { + function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult | undefined { // Always elide type-only imports if (node.isTypeOnly) { return undefined; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a8b2e6499eaa6..38bd7d32bf7c4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4506,11 +4506,11 @@ namespace ts { export interface CustomTransformers { /** Custom transformers to evaluate before built-in .js transformations. */ - before?: (TransformerFactory | CustomTransformerFactory)[]; + before?: (TransformerFactory | CustomTransformerFactory)[]; /** Custom transformers to evaluate after built-in .js transformations. */ - after?: (TransformerFactory | CustomTransformerFactory)[]; + after?: (TransformerFactory | CustomTransformerFactory)[]; /** Custom transformers to evaluate after built-in .d.ts transformations. */ - afterDeclarations?: (TransformerFactory | CustomTransformerFactory)[]; + afterDeclarations?: (TransformerFactory | CustomTransformerFactory)[]; } /*@internal*/ @@ -8356,7 +8356,7 @@ namespace ts { * @param ensureUseStrict boolean determining whether the function need to add prologue-directives * @param visitor Optional callback used to visit any custom prologue directives. */ - /* @internal */ copyPrologue(source: readonly Statement[], target: Push, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number; + /* @internal */ copyPrologue(source: readonly Statement[], target: Push, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult | undefined): number; /** * Copies only the standard (string-expression) prologue-directives into the target statement-array. * @param source origin statements array @@ -8372,8 +8372,8 @@ namespace ts { * @param statementOffset The offset at which to begin the copy. * @param visitor Optional callback used to visit any custom prologue directives. */ - /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Statement) => boolean): number; - /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Statement) => boolean): number | undefined; + /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult | undefined, filter?: (node: Statement) => boolean): number; + /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult | undefined, filter?: (node: Statement) => boolean): number | undefined; /* @internal */ ensureUseStrict(statements: NodeArray): NodeArray; /* @internal */ liftToBlock(nodes: readonly Node[]): Statement; /** @@ -8530,35 +8530,75 @@ namespace ts { * A function that is used to initialize and return a `Transformer` callback, which in turn * will be used to transform one or more nodes. */ - export type TransformerFactory = (context: TransformationContext) => Transformer; + export type TransformerFactory = (context: TransformationContext) => Transformer /** * A function that transforms a node. */ - export type Transformer = (node: T) => U; // TODO(jakebailey): This signature was totally wrong. Is it right now? - - // TODO(jakebailey): can we redefne NodeVisitor/NodesVisitor to not need overloads? - // Maybe along with NonNullable? + export type Transformer = (node: T) => T; // TODO(jakebailey): This signature is totally wrong. + // Either a node, or a list of nodes to be be lifted via a lift function. + export type VisitResult> = T | readonly U[]; + /** * A function that accepts and possibly transforms a node. */ - export type Visitor = (node: TIn) => VisitResult; - + export type Visitor = (node: TIn) => VisitResult; + + /** + * @see {visitNode} + */ export interface NodeVisitor { - (node: TIn, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut; - (node: TIn | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | undefined; - } - + < + TIn extends Node | undefined, + TVisited extends Node | undefined, + TAssert extends NonNullable, + TOut extends TIn extends undefined ? TAssert | undefined + : TVisited extends undefined ? TAssert | undefined + : TAssert, + >( + node: TIn, + visitor: Visitor, TVisited> | undefined, + test?: (node: Node) => node is TAssert, + lift?: (node: readonly Node[]) => Node, + ): TOut; + } + + /** + * @see {visitNodes} + */ export interface NodesVisitor { - (nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray; - (nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | undefined; + < + TIn extends Node, + TArray extends NodeArray | undefined, + TVisited extends Node | undefined, + TAssert extends NonNullable, + TOut extends TArray extends undefined ? NodeArray | undefined + : NodeArray, + >( + nodes: TArray, + visitor: Visitor | undefined, + test?: (node: Node) => node is TAssert, + start?: number, + count?: number, + ): TOut; + } + + declare const testNodeVisitor2: NodeVisitor; + declare const testNodesVisitor2: NodesVisitor; + + export function _jakeTesting(node: Node, nodeVisitor: Visitor) { + const result = testNodeVisitor2(node, nodeVisitor, isAssertionExpression); + // ^? + return result; + } + + export function _jakeTesting2(nodes: NodeArray, nodeVisitor: Visitor) { + const result = testNodesVisitor2(nodes, nodeVisitor, isAssertionExpression); + // ^? + return result; } - // Either a node, or a list of nodes to be be lifted via a lift function. - // TODO: - export type VisitResult = T | readonly Node[] | undefined; - export interface Printer { /** * Print a node and its subtree as-is, without any emit transformations. diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index c01b45975c8a0..894acb0ab7ede 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -9,33 +9,32 @@ namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - export function visitNode(node: TIn, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut; - - /** - * Visits a Node using the supplied visitor, possibly returning a new Node in its place. - * - * @param node The Node to visit. - * @param visitor The callback used to visit the Node. - * @param test A callback to execute to verify the Node is valid. - * @param lift An optional callback to execute to lift a NodeArray into a valid Node. - */ - export function visitNode(node: TIn | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | undefined; - - export function visitNode(node: TIn | undefined, visitor?: Visitor, test?: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | undefined { + export function visitNode< + TIn extends Node | undefined, + TVisited extends Node | undefined, + TAssert extends NonNullable, + TOut extends TIn extends undefined ? TAssert | undefined + : TVisited extends undefined ? TAssert | undefined + : TAssert, + >( + node: TIn, + visitor: Visitor, TVisited> | undefined, + test?: (node: Node) => node is TAssert, + lift?: (node: readonly Node[]) => Node, + ): TOut { if (node === undefined) { - return node; + // If the input type is undefined, then the output type can be undefined. + return node as Node | undefined as TOut; } const visited = visitor ? visitor(node) : node; - // TODO(jakebailey): With the modified type vars, it doesn't make sense to skip the node test, - // becuase the input type may not be the desired output type. - // if (visited === node) { - // return node; - // } let visitedNode: Node | undefined; if (visited === undefined) { - return undefined; + // If the visited node is undefined, then the visitor must have returned undefined, + // so the visitor must have been declared as able to return undefined, so TOut must be + // potentially undefined. + return undefined as TOut; } else if (isArray(visited)) { visitedNode = (lift || extractSingleNode)(visited); @@ -59,31 +58,23 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - export function visitNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray; - - /** - * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. - * - * @param nodes The NodeArray to visit. - * @param visitor The callback used to visit a Node. - * @param test A node test to execute for each node. - * @param start An optional value indicating the starting offset at which to start visiting. - * @param count An optional value indicating the maximum number of nodes to visit. - */ - export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | undefined; - - /** - * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. - * - * @param nodes The NodeArray to visit. - * @param visitor The callback used to visit a Node. - * @param test A node test to execute for each node. - * @param start An optional value indicating the starting offset at which to start visiting. - * @param count An optional value indicating the maximum number of nodes to visit. - */ - export function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | undefined { + export function visitNodes< + TIn extends Node, + TArray extends NodeArray | undefined, + TVisited extends Node | undefined, + TAssert extends NonNullable, + TOut extends TArray extends undefined ? NodeArray | undefined + : NodeArray, + >( + nodes: TArray, + visitor: Visitor | undefined, + test?: (node: Node) => node is TAssert, + start?: number, + count?: number, + ): TOut { if (nodes === undefined) { - return nodes; + // If the input type is undefined, then the output type can be undefined. + return nodes as NodeArray | undefined as TOut; } // Ensure start and count have valid values @@ -115,24 +106,35 @@ namespace ts { // TODO(rbuckton): Remove dependency on `ts.factory` in favor of a provided factory. const updatedArray = factory.createNodeArray(updated, hasTrailingComma); setTextRangePosEnd(updatedArray, pos, end); - return updatedArray; + return updatedArray as TOut; } // If we are here, updated === nodes. This means that it's still a NodeArray, // and also that its contents passed the tests in visitArrayWorker, so has contents // of type TOut. - return nodes as NodeArray as NodeArray; + return nodes as NodeArray as TOut; } ((_: NodesVisitor) => {})(visitNodes); // Check that visitNode is a NodeVisitor. /* @internal */ - export function visitArray(nodes: readonly TIn[], visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): readonly TOut[]; - /* @internal */ - export function visitArray(nodes: readonly TIn[] | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): readonly TOut[] | undefined; - export function visitArray(nodes: readonly TIn[] | undefined, visitor: Visitor | undefined, test?: (node: Node) => node is TOut, start?: number, count?: number): readonly TOut[] | undefined { + export function visitArray< + TIn extends Node, + TArray extends readonly TIn[] | undefined, + TVisited extends Node | undefined, + TAssert extends NonNullable, + TOut extends TArray extends undefined ? readonly TAssert[] | undefined + : readonly TAssert[], + >( + nodes: TArray, + visitor: Visitor | undefined, + test?: (node: Node) => node is TAssert, + start?: number, + count?: number, + ): TOut { if (nodes === undefined) { - return nodes; + // If the input type is undefined, then the output type can be undefined. + return nodes as readonly Node[] | undefined as TOut; } // Ensure start and count have valid values @@ -145,11 +147,21 @@ namespace ts { count = length - start; } - return visitArrayWorker(nodes, visitor, test, start, count); + return visitArrayWorker(nodes, visitor, test, start, count) as TOut; } /* @internal */ - function visitArrayWorker(nodes: readonly TIn[], visitor: Visitor | undefined, test: ((node: Node) => node is TOut) | undefined, start: number, count: number): readonly TOut[] { + function visitArrayWorker< + TIn extends Node, + TVisited extends Node | undefined, + TAssert extends NonNullable, + >( + nodes: readonly TIn[], + visitor: Visitor | undefined, + test: ((node: Node) => node is TAssert) | undefined, + start: number, + count: number, + ): readonly TAssert[] { let updated: Node[] | undefined; const length = nodes.length; @@ -184,14 +196,14 @@ namespace ts { const result: readonly Node[] = updated ?? nodes; Debug.assertEachNode(result, test) - return result as readonly TOut[]; + return result as readonly TAssert[]; } /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - export function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor: NodesVisitor = visitNodes) { + export function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor: NodesVisitor = visitNodes) { context.startLexicalEnvironment(); statements = nodesVisitor(statements, visitor, isStatement, start); if (ensureUseStrict) statements = context.factory.ensureUseStrict(statements); @@ -202,9 +214,9 @@ namespace ts { * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; - export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; - export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) { + export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; + export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) { let updated: NodeArray | undefined; context.startLexicalEnvironment(); if (nodes) { @@ -327,21 +339,21 @@ namespace ts { * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; + export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; + export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; /** * Resumes a suspended lexical environment and visits a concise body, ending the lexical * environment and merging hoisted declarations upon completion. */ - export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; - /* @internal*/ export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody; // eslint-disable-line @typescript-eslint/unified-signatures - /* @internal*/ export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody | undefined; // eslint-disable-line @typescript-eslint/unified-signatures - /* @internal*/ export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): ConciseBody; // eslint-disable-line @typescript-eslint/unified-signatures - export function visitFunctionBody(node: ConciseBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): ConciseBody | undefined { + export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; + /* @internal*/ export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody; // eslint-disable-line @typescript-eslint/unified-signatures + /* @internal*/ export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + /* @internal*/ export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): ConciseBody; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitFunctionBody(node: ConciseBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): ConciseBody | undefined { context.resumeLexicalEnvironment(); const updated = nodeVisitor(node, visitor, isConciseBody); const declarations = context.endLexicalEnvironment(); @@ -359,12 +371,13 @@ namespace ts { /** * Visits an iteration body, adding any block-scoped variables required by the transformation. */ - export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; + export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; /* @internal */ - export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): Statement; // eslint-disable-line @typescript-eslint/unified-signatures - export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): Statement { + export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): Statement; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): Statement { context.startBlockScope(); const updated = nodeVisitor(body, visitor, isStatement, context.factory.liftToBlock); + Debug.assert(updated); const declarations = context.endBlockScope(); if (some(declarations)) { if (isBlock(updated)) { @@ -384,9 +397,9 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; + export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; /* @internal */ - export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T; // eslint-disable-line @typescript-eslint/unified-signatures /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -394,10 +407,10 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; /* @internal */ - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T | undefined; // eslint-disable-line @typescript-eslint/unified-signatures - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor, nodeVisitor: NodeVisitor = visitNode): T | undefined { + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor, nodeVisitor: NodeVisitor = visitNode): T | undefined { if (node === undefined) { return undefined; } @@ -406,7 +419,7 @@ namespace ts { return fn === undefined ? node : fn(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor); } - type VisitEachChildFunction = (node: T, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor, nodeVisitor: NodeVisitor, tokenVisitor: Visitor | undefined) => T; + type VisitEachChildFunction = (node: T, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor, nodeVisitor: NodeVisitor, tokenVisitor: Visitor | undefined) => T; // A type that correlates a `SyntaxKind` to a `VisitEachChildFunction`, for nodes in the `HasChildren` union. // This looks something like: @@ -453,7 +466,7 @@ namespace ts { return context.factory.updateParameterDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifierLike), nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken), - nodeVisitor(node.name, visitor, isBindingName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isBindingName)), nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), nodeVisitor(node.type, visitor, isTypeNode), nodeVisitor(node.initializer, visitor, isExpression)); @@ -476,7 +489,7 @@ namespace ts { [SyntaxKind.PropertyDeclaration]: function visitEachChildOfPropertyDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updatePropertyDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifierLike), - nodeVisitor(node.name, visitor, isPropertyName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), // QuestionToken and ExclamationToken are mutually exclusive in PropertyDeclaration nodeVisitor(node.questionToken ?? node.exclamationToken, tokenVisitor, isQuestionOrExclamationToken), nodeVisitor(node.type, visitor, isTypeNode), diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 6353834280970..9ed83cc2ce618 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -704,12 +704,11 @@ namespace ts.codefix { */ export function tryGetAutoImportableReferenceFromTypeNode(importTypeNode: TypeNode | undefined, scriptTarget: ScriptTarget) { let symbols: Symbol[] | undefined; - const typeNode = visitNode(importTypeNode, visit); + const typeNode = visitNode(importTypeNode, visit, isTypeNode); if (symbols && typeNode) { return { typeNode, symbols }; } - function visit(node: TypeNode): TypeNode; function visit(node: Node): Node { if (isLiteralImportTypeNode(node) && node.qualifier) { // Symbol for the left-most thing after the dot @@ -720,7 +719,7 @@ namespace ts.codefix { : node.qualifier; symbols = append(symbols, firstIdentifier.symbol); - const typeArguments = node.typeArguments?.map(visit); + const typeArguments = visitNodes(node.typeArguments, visit, isTypeNode); return factory.createTypeReferenceNode(qualifier, typeArguments); } return visitEachChild(node, visit, nullTransformationContext); diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 53bb5b6f546c0..ff5a4f496537f 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1136,15 +1136,29 @@ namespace ts.textChanges { return newNode; } - function assignPositionsToNodeArray(nodes: NodeArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number) { - const visited = visitNodes(nodes, visitor, test as (node: Node) => node is Node, start, count); // TODO(jakebailey): remove this once a non-guard signature is added to visitNode/visitNodes + function assignPositionsToNodeArray< + TIn extends Node, + TArray extends NodeArray | undefined, + TVisited extends Node | undefined, + TAssert extends NonNullable, + TOut extends TArray extends undefined ? NodeArray | undefined + : NodeArray, + >( + nodes: TArray, + visitor: Visitor | undefined, + test?: (node: Node) => node is TAssert, + start?: number, + count?: number, + ): TOut { + const visited = visitNodes(nodes, visitor, test, start, count); if (!visited) { - return visited; + return visited as TOut; } + Debug.assert(nodes); // clone nodearray if necessary - const nodeArray = visited === nodes ? factory.createNodeArray(visited.slice(0)) : visited; + const nodeArray = visited as NodeArray === nodes ? factory.createNodeArray(visited.slice(0)) : visited; setTextRangePosEnd(nodeArray, getPos(nodes), getEnd(nodes)); - return nodeArray; + return nodeArray as TOut; } interface TextChangesWriter extends EmitTextWriter, PrintHandlers {} diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 4d24e57d051ee..bd7f0de157a40 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2548,11 +2548,11 @@ namespace ts { const nodeClone: (n: T) => T = replaceNode ? n => getSynthesizedDeepCloneWithReplacements(n, /*includeTrivia*/ true, replaceNode) : getSynthesizedDeepClone; - const nodesClone: (ns: NodeArray) => NodeArray = replaceNode + const nodesClone: (ns: NodeArray | undefined) => (NodeArray | undefined) = replaceNode ? ns => ns && getSynthesizedDeepClonesWithReplacements(ns, /*includeTrivia*/ true, replaceNode) : ns => ns && getSynthesizedDeepClones(ns); const visited = - visitEachChild(node, nodeClone, nullTransformationContext, nodesClone, nodeClone); + visitEachChild(node, nodeClone, nullTransformationContext, nodesClone as NodesVisitor, nodeClone); // TODO(jakebailey): This is unfortunate. if (visited === node) { // This only happens for leaf nodes - internal nodes always see their children change. diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 08914006da2d1..5b7113e9c2266 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -24,7 +24,7 @@ namespace ts { } return visitEachChild(node, visitor, context); } - return (file: SourceFile) => visitNode(file, visitor); + return (file: SourceFile) => visitNode(file, visitor, isSourceFile); } function replaceIdentifiersNamedOldNameWithNewName(context: TransformationContext) { @@ -41,13 +41,13 @@ namespace ts { } function replaceIdentifiersNamedOldNameWithNewName2(context: TransformationContext) { - const visitor: Visitor = (node) => { + const visitor: Visitor = (node) => { if (isIdentifier(node) && node.text === "oldName") { return factory.createIdentifier("newName"); } return visitEachChild(node, visitor, context); }; - return (node: Node) => visitNode(node, visitor); + return (node: SourceFile) => visitNode(node, visitor, isSourceFile); } function createTaggedTemplateLiteral(): Transformer { @@ -552,7 +552,7 @@ module MyModule { return host.readFile("source.js")!.toString(); function transformSourceFile(context: TransformationContext) { - const visitor: Visitor = (node) => { + const visitor: Visitor = (node) => { if (isMethodDeclaration(node)) { return factory.updateMethodDeclaration( node, From f2e34f1e86706c9ffefd13cfef801588a6c89b50 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 09:18:49 -0700 Subject: [PATCH 15/81] It compiles --- src/compiler/core.ts | 9 + .../4.8/mergeDecoratorsAndModifiers.ts | 156 +++++++++--------- src/harness/fakesHosts.ts | 2 +- src/harness/fourslashImpl.ts | 7 +- src/server/editorServices.ts | 8 +- src/server/project.ts | 2 +- src/server/session.ts | 10 +- .../codefixes/annotateWithTypeFromJSDoc.ts | 18 +- src/services/documentHighlights.ts | 2 +- src/services/utilities.ts | 24 ++- src/testRunner/unittests/compilerCore.ts | 2 +- .../unittests/reuseProgramStructure.ts | 12 +- src/testRunner/unittests/transform.ts | 6 +- .../tsserver/cachingFileSystemInformation.ts | 4 +- .../unittests/tsserver/webServer.ts | 2 +- src/tsserver/nodeServer.ts | 2 +- src/tsserver/webServer.ts | 2 +- src/typingsInstallerCore/typingsInstaller.ts | 4 +- 18 files changed, 151 insertions(+), 121 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 90297963f41d7..4dfd7195119ed 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -165,6 +165,15 @@ namespace ts { return true; } + /** + * Equivalent to every, but can discriminate between unions of arrays. + */ + export function isArrayOf(array: readonly any[], callback: (element: any, index: number) => element is T): array is readonly T[]; + export function isArrayOf(array: readonly any[] | undefined, callback: (element: any, index: number) => element is T): array is readonly T[] | undefined; + export function isArrayOf(array: readonly any[] | undefined, callback: (element: any, index: number) => boolean): boolean { + return every(array, callback); + } + /** Works like Array.prototype.find, returning `undefined` if no element satisfying the predicate is found. */ export function find(array: readonly T[] | undefined, predicate: (element: T, index: number) => element is U, startIndex?: number): U | undefined; export function find(array: readonly T[] | undefined, predicate: (element: T, index: number) => boolean, startIndex?: number): T | undefined; diff --git a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts index d6cdbf2969e1c..f7a235c1b1f61 100644 --- a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts +++ b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts @@ -400,7 +400,7 @@ namespace ts { (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || typeof questionToken === "object" && isQuestionToken(questionToken)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || !some(parameters, isTypeParameterDeclaration)) && + (parameters === undefined || isArrayOf(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -409,7 +409,7 @@ namespace ts { (asteriskToken === undefined || typeof asteriskToken === "object" && isAsteriskToken(asteriskToken)) && (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || !isArray(questionToken)) && - (typeParameters === undefined || !some(typeParameters, isParameter)) && + (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -436,7 +436,7 @@ namespace ts { (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || typeof questionToken === "object" && isQuestionToken(questionToken)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || !some(parameters, isTypeParameterDeclaration)) && + (parameters === undefined || isArrayOf(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -445,7 +445,7 @@ namespace ts { (asteriskToken === undefined || typeof asteriskToken === "object" && isAsteriskToken(asteriskToken)) && (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || !isArray(questionToken)) && - (typeParameters === undefined || !some(typeParameters, isParameter)) && + (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -468,13 +468,13 @@ namespace ts { .bind({ 0: ([modifiers, parameters, body, other]) => (other === undefined) && - (modifiers === undefined || !some(modifiers, isDecorator)) && - (parameters === undefined || !some(parameters, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (parameters === undefined || isArrayOf(parameters, isParameter)) && (body === undefined || !isArray(body)), 1: ([decorators, modifiers, parameters, body]) => - (decorators === undefined || !some(decorators, isModifier)) && - (modifiers === undefined || !some(modifiers, isParameter)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (parameters === undefined || isArray(parameters)) && (body === undefined || isBlock(body)), }) @@ -496,13 +496,13 @@ namespace ts { .bind({ 0: ([, modifiers, parameters, body, other]) => (other === undefined) && - (modifiers === undefined || !some(modifiers, isDecorator)) && - (parameters === undefined || !some(parameters, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (parameters === undefined || isArrayOf(parameters, isParameter)) && (body === undefined || !isArray(body)), 1: ([, decorators, modifiers, parameters, body]) => - (decorators === undefined || !some(decorators, isModifier)) && - (modifiers === undefined || !some(modifiers, isParameter)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (parameters === undefined || isArray(parameters)) && (body === undefined || isBlock(body)), }) @@ -640,13 +640,13 @@ namespace ts { .bind({ 0: ([modifiers, parameters, type, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && - (parameters === undefined || every(parameters, isParameter)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (parameters === undefined || isArrayOf(parameters, isParameter)) && (type === undefined || !isArray(type)), 1: ([decorators, modifiers, parameters, type]) => - (decorators === undefined || every(decorators, isDecorator)) && - (modifiers === undefined || every(modifiers, isModifier)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)), }) @@ -668,13 +668,13 @@ namespace ts { .bind({ 0: ([, modifiers, parameters, type, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && - (parameters === undefined || every(parameters, isParameter)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (parameters === undefined || isArrayOf(parameters, isParameter)) && (type === undefined || !isArray(type)), 1: ([, decorators, modifiers, parameters, type]) => - (decorators === undefined || every(decorators, isDecorator)) && - (modifiers === undefined || every(modifiers, isModifier)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)), }) @@ -750,14 +750,14 @@ namespace ts { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (members === undefined || isArrayOf(members, isClassElement)), 1: ([, modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && (members === undefined || isArray(members)), }) .deprecate({ @@ -780,14 +780,14 @@ namespace ts { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (members === undefined || isArrayOf(members, isClassElement)), 1: ([, , modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && (members === undefined || isArray(members)), }) .deprecate({ @@ -811,7 +811,7 @@ namespace ts { (asteriskToken === undefined || !isArray(asteriskToken)) && (name === undefined || typeof name === "string" || isIdentifier(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || every(parameters, isParameter)) && + (parameters === undefined || isArrayOf(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -819,7 +819,7 @@ namespace ts { (modifiers === undefined || isArray(modifiers)) && (asteriskToken === undefined || typeof asteriskToken !== "string" && isAsteriskToken(asteriskToken)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -845,7 +845,7 @@ namespace ts { (asteriskToken === undefined || !isArray(asteriskToken)) && (name === undefined || isIdentifier(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || every(parameters, isParameter)) && + (parameters === undefined || isArrayOf(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -853,7 +853,7 @@ namespace ts { (modifiers === undefined || isArray(modifiers)) && (asteriskToken === undefined || typeof asteriskToken !== "string" && isAsteriskToken(asteriskToken)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -878,8 +878,8 @@ namespace ts { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (members === undefined || isArrayOf(members, isClassElement)), 1: () => true, }) @@ -903,14 +903,14 @@ namespace ts { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (members === undefined || isArrayOf(members, isClassElement)), 1: ([, , modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && (members === undefined || isArray(members)), }) .deprecate({ @@ -931,18 +931,18 @@ namespace ts { .bind({ 0: ([modifiers, name, typeParameters, heritageClauses, members, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (members === undefined || isArrayOf(members, isTypeElement)), 1: ([decorators, modifiers, name, typeParameters, heritageClauses, members]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && (members === undefined || every(members, isTypeElement)), }) .deprecate({ @@ -963,18 +963,18 @@ namespace ts { .bind({ 0: ([, modifiers, name, typeParameters, heritageClauses, members, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (members === undefined || isArrayOf(members, isTypeElement)), 1: ([, decorators, modifiers, name, typeParameters, heritageClauses, members]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && (members === undefined || every(members, isTypeElement)), }) .deprecate({ @@ -995,13 +995,13 @@ namespace ts { .bind({ 0: ([modifiers, name, typeParameters, type, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && (type === undefined || !isArray(type)), 1: ([decorators, modifiers, name, typeParameters, type]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && @@ -1025,13 +1025,13 @@ namespace ts { .bind({ 0: ([, modifiers, name, typeParameters, type, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && (type === undefined || !isArray(type)), 1: ([, decorators, modifiers, name, typeParameters, type]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && @@ -1055,12 +1055,12 @@ namespace ts { .bind({ 0: ([modifiers, name, members, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), 1: ([decorators, modifiers, name, members]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), @@ -1083,12 +1083,12 @@ namespace ts { .bind({ 0: ([, modifiers, name, members, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), 1: ([, decorators, modifiers, name, members]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), @@ -1111,13 +1111,13 @@ namespace ts { .bind({ 0: ([modifiers, name, body, flags, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (name !== undefined && !isArray(name)) && (body === undefined || isModuleBody(body)) && (flags === undefined || typeof flags === "number"), 1: ([decorators, modifiers, name, body, flags]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name !== undefined && isModuleName(name)) && (body === undefined || typeof body === "object") && @@ -1141,12 +1141,12 @@ namespace ts { .bind({ 0: ([, modifiers, name, body, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (body === undefined || isModuleBody(body)), 1: ([, decorators, modifiers, name, body]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name !== undefined && isModuleName(name)) && (body === undefined || isModuleBody(body)), @@ -1169,13 +1169,13 @@ namespace ts { .bind({ 0: ([modifiers, isTypeOnly, name, moduleReference, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name !== "boolean") && (typeof moduleReference !== "string"), 1: ([decorators, modifiers, isTypeOnly, name, moduleReference]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name === "string" || isIdentifier(name)) && @@ -1199,13 +1199,13 @@ namespace ts { .bind({ 0: ([, modifiers, isTypeOnly, name, moduleReference, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name !== "boolean") && (typeof moduleReference !== "string"), 1: ([, decorators, modifiers, isTypeOnly, name, moduleReference]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name === "string" || isIdentifier(name)) && @@ -1229,13 +1229,13 @@ namespace ts { .bind({ 0: ([modifiers, importClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (importClause === undefined || !isArray(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([decorators, modifiers, importClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (importClause === undefined || isImportClause(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && @@ -1259,13 +1259,13 @@ namespace ts { .bind({ 0: ([, modifiers, importClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (importClause === undefined || !isArray(importClause)) && (moduleSpecifier === undefined || isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([, decorators, modifiers, importClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (importClause === undefined || isImportClause(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && @@ -1289,12 +1289,12 @@ namespace ts { .bind({ 0: ([modifiers, isExportEquals, expression, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (isExportEquals === undefined || typeof isExportEquals === "boolean") && (typeof expression === "object"), 1: ([decorators, modifiers, isExportEquals, expression]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isExportEquals === undefined || typeof isExportEquals === "boolean") && (expression !== undefined && isExpression(expression)), @@ -1317,11 +1317,11 @@ namespace ts { .bind({ 0: ([, modifiers, expression, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (expression !== undefined && !isArray(expression)), 1: ([, decorators, modifiers, expression]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (expression !== undefined && isExpression(expression)), }) @@ -1343,14 +1343,14 @@ namespace ts { .bind({ 0: ([modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (typeof isTypeOnly === "boolean") && (typeof exportClause !== "boolean") && (moduleSpecifier === undefined || isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (typeof isTypeOnly === "boolean") && (exportClause === undefined || isNamedExportBindings(exportClause)) && @@ -1375,14 +1375,14 @@ namespace ts { .bind({ 0: ([, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || isArrayOf(modifiers, isModifier)) && (typeof isTypeOnly === "boolean") && (typeof exportClause !== "boolean") && (moduleSpecifier === undefined || isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([, decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || isArrayOf(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (typeof isTypeOnly === "boolean") && (exportClause === undefined || isNamedExportBindings(exportClause)) && diff --git a/src/harness/fakesHosts.ts b/src/harness/fakesHosts.ts index 1868561a34ccc..c1385ab21105c 100644 --- a/src/harness/fakesHosts.ts +++ b/src/harness/fakesHosts.ts @@ -537,7 +537,7 @@ ${indentText}${text}`; private constructor(sys: System | vfs.FileSystem, options?: ts.CompilerOptions, setParentNodes?: boolean, createProgram?: ts.CreateProgram) { super(sys, options, setParentNodes); - this.createProgram = createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram; + this.createProgram = createProgram || ts.createEmitAndSemanticDiagnosticsBuilderProgram as unknown as ts.CreateProgram; } static create(sys: System | vfs.FileSystem, options?: ts.CompilerOptions, setParentNodes?: boolean, createProgram?: ts.CreateProgram) { diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 46d2bc242e772..b3c5f2daa1ad1 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -518,7 +518,7 @@ namespace FourSlash { public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, shouldExist: boolean) { const startMarker = this.getMarkerByName(startMarkerName); const endMarker = this.getMarkerByName(endMarkerName); - const predicate = (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => + const predicate = (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number | undefined) => ((errorMinChar === startPos) && (errorLimChar === endPos)) ? true : false; const exists = this.anyErrorInRange(predicate, startMarker, endMarker); @@ -572,7 +572,7 @@ namespace FourSlash { public verifyErrorExistsAfterMarker(markerName: string, shouldExist: boolean, after: boolean) { const marker: Marker = this.getMarkerByName(markerName); - let predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean; + let predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number | undefined) => boolean; if (after) { predicate = (errorMinChar: number, errorLimChar: number, startPos: number) => @@ -857,7 +857,8 @@ namespace FourSlash { const hints = this.languageService.provideInlayHints(this.activeFile.fileName, span, preference); assert.equal(hints.length, expected.length, "Number of hints"); - const sortHints = (a: ts.InlayHint, b: ts.InlayHint) => { + interface HasPosition { position: number; } + const sortHints = (a: HasPosition, b: HasPosition) => { return a.position - b.position; }; ts.zipWith(hints.sort(sortHints), [...expected].sort(sortHints), (actual, expected) => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 3ab9f02741cc1..9b8d37e50a799 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -549,7 +549,7 @@ namespace ts.server { function forEachPotentialProjectReference( project: ConfiguredProject, - cb: (potentialProjectReference: Path) => T | undefined + cb: (potentialProjectReference: NormalizedPath) => T | undefined ): T | undefined { return project.potentialProjectReferences && forEachKey(project.potentialProjectReferences, cb); @@ -559,7 +559,7 @@ namespace ts.server { project: ConfiguredProject, cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined, cbProjectRef: (projectReference: ProjectReference) => T | undefined, - cbPotentialProjectRef: (potentialProjectReference: Path) => T | undefined + cbPotentialProjectRef: (potentialProjectReference: NormalizedPath) => T | undefined ): T | undefined { return project.getCurrentProgram() ? project.forEachResolvedProjectReference(cb) : @@ -568,10 +568,10 @@ namespace ts.server { forEach(project.getProjectReferences(), cbProjectRef); } - function callbackRefProject( + function callbackRefProject( project: ConfiguredProject, cb: (refProj: ConfiguredProject) => T | undefined, - refPath: Path | undefined + refPath: P | undefined ) { const refProject = refPath && project.projectService.configuredProjects.get(refPath); return refProject && cb(refProject); diff --git a/src/server/project.ts b/src/server/project.ts index 43b1c7128e005..6aab39c3f85ff 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2373,7 +2373,7 @@ namespace ts.server { /** Potential project references before the project is actually loaded (read config file) */ /*@internal*/ - potentialProjectReferences: Set | undefined; + potentialProjectReferences: Set | undefined; /*@internal*/ projectOptions?: ProjectOptions | true; diff --git a/src/server/session.ts b/src/server/session.ts index 4bdadd04a15fa..5f347aa71ceeb 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -14,7 +14,7 @@ namespace ts.server { resetRequest: () => void 0 }; - function hrTimeToMilliseconds(time: number[]): number { + function hrTimeToMilliseconds(time: [number, number]): number { const seconds = time[0]; const nanoseconds = time[1]; return ((1e9 * seconds) + nanoseconds) / 1000000.0; @@ -738,7 +738,7 @@ namespace ts.server { useInferredProjectPerProjectRoot: boolean; typingsInstaller: ITypingsInstaller; byteLength: (buf: string, encoding?: string) => number; - hrtime: (start?: number[]) => number[]; + hrtime: (start?: [number, number]) => [number, number]; logger: Logger; /** * If falsy, all events are suppressed. @@ -773,7 +773,7 @@ namespace ts.server { private readonly cancellationToken: ServerCancellationToken; protected readonly typingsInstaller: ITypingsInstaller; protected byteLength: (buf: string, encoding?: string) => number; - private hrtime: (start?: number[]) => number[]; + private hrtime: (start?: [number, number]) => [number, number]; protected logger: Logger; protected canUseEvents: boolean; @@ -2916,7 +2916,7 @@ namespace ts.server { return { response, responseRequired: true }; } - private handlers = new Map(getEntries<(request: protocol.Request) => HandlerResponse>({ + private handlers = new Map(getEntries<(request: any) => HandlerResponse>({ // TODO(jakebailey): correctly type the handlers [CommandNames.Status]: () => { const response: protocol.StatusResponseBody = { version: ts.version }; // eslint-disable-line @typescript-eslint/no-unnecessary-qualifier return this.requiredResponse(response); @@ -3361,7 +3361,7 @@ namespace ts.server { this.performanceData = undefined; - let start: number[] | undefined; + let start: [number, number] | undefined; if (this.logger.hasLevel(LogLevel.requestTime)) { start = this.hrtime(); if (this.logger.hasLevel(LogLevel.verbose)) { diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index 629006083af7e..4f94f423ed5f4 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -50,19 +50,29 @@ namespace ts.codefix { for (const param of decl.parameters) { if (!param.type) { const paramType = getJSDocType(param); - if (paramType) changes.tryInsertTypeAnnotation(sourceFile, param, transformJSDocType(paramType)); + if (paramType) { + const transformedType = transformJSDocType(paramType); + Debug.assertNode(transformedType, isTypeNode); + changes.tryInsertTypeAnnotation(sourceFile, param, transformedType); + } } } if (needParens) changes.insertNodeAfter(sourceFile, last(decl.parameters), factory.createToken(SyntaxKind.CloseParenToken)); if (!decl.type) { const returnType = getJSDocReturnType(decl); - if (returnType) changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(returnType)); + if (returnType) { + const transformedType = transformJSDocType(returnType); + Debug.assertNode(transformedType, isTypeNode); + changes.tryInsertTypeAnnotation(sourceFile, decl, transformedType); + }; } } else { const jsdocType = Debug.checkDefined(getJSDocType(decl), "A JSDocType for this declaration should exist"); // If not defined, shouldn't have been an error to fix Debug.assert(!decl.type, "The JSDocType decl should have a type"); // If defined, shouldn't have been an error to fix. - changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(jsdocType)); + const transformedType = transformJSDocType(jsdocType); + Debug.assertNode(transformedType, isTypeNode); + changes.tryInsertTypeAnnotation(sourceFile, decl, transformedType); } } @@ -73,7 +83,7 @@ namespace ts.codefix { node.kind === SyntaxKind.PropertyDeclaration; } - function transformJSDocType(node: TypeNode): TypeNode { + function transformJSDocType(node: Node): Node { switch (node.kind) { case SyntaxKind.JSDocAllType: case SyntaxKind.JSDocUnknownType: diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 698f82eda51b4..7b903cd1fcdb1 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -236,7 +236,7 @@ namespace ts { // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & (ModifierFlags.AccessibilityModifier | ModifierFlags.Readonly)) { - const constructor = find(container.members, isConstructorDeclaration); + const constructor = find(container.members, isConstructorDeclaration); // TODO(jakebailey): GH#49924 ??? if (constructor) { return [...nodes, ...constructor.parameters]; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index bd7f0de157a40..135a3b19e8006 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2545,14 +2545,8 @@ namespace ts { } function getSynthesizedDeepCloneWorker(node: T, replaceNode?: (node: Node) => Node | undefined): T { - const nodeClone: (n: T) => T = replaceNode - ? n => getSynthesizedDeepCloneWithReplacements(n, /*includeTrivia*/ true, replaceNode) - : getSynthesizedDeepClone; - const nodesClone: (ns: NodeArray | undefined) => (NodeArray | undefined) = replaceNode - ? ns => ns && getSynthesizedDeepClonesWithReplacements(ns, /*includeTrivia*/ true, replaceNode) - : ns => ns && getSynthesizedDeepClones(ns); const visited = - visitEachChild(node, nodeClone, nullTransformationContext, nodesClone as NodesVisitor, nodeClone); // TODO(jakebailey): This is unfortunate. + visitEachChild(node, nodeClone, nullTransformationContext, nodesClone, nodeClone); if (visited === node) { // This only happens for leaf nodes - internal nodes always see their children change. @@ -2568,6 +2562,20 @@ namespace ts { // would have made. (visited as Mutable).parent = undefined!; return visited; + + function nodeClone(node: T): T { + return replaceNode + ? getSynthesizedDeepCloneWithReplacements(node, /*includeTrivia*/ true, replaceNode) + : getSynthesizedDeepClone(node); + } + + function nodesClone(nodes: NodeArray): NodeArray; + function nodesClone(nodes: NodeArray | undefined): NodeArray | undefined; + function nodesClone(nodes: NodeArray | undefined): NodeArray | undefined { + return replaceNode + ? nodes && getSynthesizedDeepClonesWithReplacements(nodes, /*includeTrivia*/ true, replaceNode) + : nodes && getSynthesizedDeepClones(nodes); + } } export function getSynthesizedDeepClones(nodes: NodeArray, includeTrivia?: boolean): NodeArray; @@ -3378,7 +3386,7 @@ namespace ts { return false; } // If the file is a module written in TypeScript, it still might be in a `declare global` augmentation - return isInJSFile(declaration) || !findAncestor(declaration, isGlobalScopeAugmentation); + return isInJSFile(declaration) || !findAncestor(declaration, d => isModuleDeclaration(d) && isGlobalScopeAugmentation(d)); } export function isDeprecatedDeclaration(decl: Declaration) { diff --git a/src/testRunner/unittests/compilerCore.ts b/src/testRunner/unittests/compilerCore.ts index 49c9601a39241..eea8f595816eb 100644 --- a/src/testRunner/unittests/compilerCore.ts +++ b/src/testRunner/unittests/compilerCore.ts @@ -21,7 +21,7 @@ namespace ts { assert.isFalse(equalOwnProperties({}, { a: 0 }, trythyTest), "missing left falsey property"); assert.isFalse(equalOwnProperties({ a: 1 }, {}, trythyTest), "missing right truthy property"); assert.isFalse(equalOwnProperties({ a: 0 }, {}, trythyTest), "missing right falsey property"); - assert.isTrue(equalOwnProperties({ a: 1 }, { a: "foo" }, trythyTest), "valid equality"); + assert.isTrue(equalOwnProperties({ a: 1 }, { a: "foo" as any }, trythyTest), "valid equality"); // TODO(jakebailey): remove this test? we figure this out at compile time. }); it("all equal", () => { assert.isFalse(equalOwnProperties({}, { a: 1 }, () => true), "missing left property"); diff --git a/src/testRunner/unittests/reuseProgramStructure.ts b/src/testRunner/unittests/reuseProgramStructure.ts index 3e9e5f2313441..56fd41e4fc8da 100644 --- a/src/testRunner/unittests/reuseProgramStructure.ts +++ b/src/testRunner/unittests/reuseProgramStructure.ts @@ -169,13 +169,15 @@ namespace ts { file.text = file.text.updateProgram(newProgramText); } - function checkResolvedTypeDirective(actual: ResolvedTypeReferenceDirective, expected: ResolvedTypeReferenceDirective) { + function checkResolvedTypeDirective(actual: ResolvedTypeReferenceDirective | undefined, expected: ResolvedTypeReferenceDirective | undefined) { + assert(actual, "Actual ResolvedTypeReferenceDirective is undefined"); + assert(expected, "Resolved ResolvedTypeReferenceDirective is undefined"); assert.equal(actual.resolvedFileName, expected.resolvedFileName, `'resolvedFileName': expected '${actual.resolvedFileName}' to be equal to '${expected.resolvedFileName}'`); assert.equal(actual.primary, expected.primary, `'primary': expected '${actual.primary}' to be equal to '${expected.primary}'`); return true; } - function checkCache(caption: string, program: Program, fileName: string, expectedContent: ESMap | undefined, getCache: (f: SourceFile) => ModeAwareCache | undefined, entryChecker: (expected: T, original: T) => boolean): void { + function checkCache(caption: string, program: Program, fileName: string, expectedContent: ESMap | undefined, getCache: (f: SourceFile) => ModeAwareCache | undefined, entryChecker: (expected: T | undefined, original: T | undefined) => boolean): void { const file = program.getSourceFile(fileName); assert.isTrue(file !== undefined, `cannot find file ${fileName}`); const cache = getCache(file!); @@ -189,7 +191,7 @@ namespace ts { } /** True if the maps have the same keys and values. */ - function mapEqualToCache(left: ESMap, right: ModeAwareCache, valuesAreEqual?: (left: T, right: T) => boolean): boolean { + function mapEqualToCache(left: ESMap, right: ModeAwareCache, valuesAreEqual?: (left: T | undefined, right: T | undefined) => boolean): boolean { if (left as any === right) return true; // given the type mismatch (the tests never pass a cache), this'll never be true if (!left || !right) return false; const someInLeftHasNoMatch = forEachEntry(left, (leftValue, leftKey) => { @@ -203,11 +205,11 @@ namespace ts { return !someInRightHasNoMatch; } - function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: ESMap | undefined): void { + function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: ESMap | undefined): void { checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, checkResolvedModule); } - function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: ESMap | undefined): void { + function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: ESMap | undefined): void { checkCache("resolved type directives", program, fileName, expectedContent, f => f.resolvedTypeReferenceDirectiveNames, checkResolvedTypeDirective); } diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 5b7113e9c2266..3ec7c102500fc 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -27,7 +27,7 @@ namespace ts { return (file: SourceFile) => visitNode(file, visitor, isSourceFile); } - function replaceIdentifiersNamedOldNameWithNewName(context: TransformationContext) { + function replaceIdentifiersNamedOldNameWithNewName(context: TransformationContext) { const previousOnSubstituteNode = context.onSubstituteNode; context.enableSubstitution(SyntaxKind.Identifier); context.onSubstituteNode = (hint, node) => { @@ -37,7 +37,7 @@ namespace ts { } return node; }; - return (file: SourceFile) => file; + return (file: T) => file; } function replaceIdentifiersNamedOldNameWithNewName2(context: TransformationContext) { @@ -568,7 +568,7 @@ module MyModule { } return visitEachChild(node, visitor, context); }; - return (node: SourceFile) => visitNode(node, visitor); + return (node: SourceFile) => visitNode(node, visitor, isSourceFile); } }); diff --git a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts index 0f042ba32abee..2b09861578808 100644 --- a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts +++ b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts @@ -345,7 +345,7 @@ namespace ts.projectSystem { describe("Verify npm install in directory with tsconfig file works when", () => { function verifyNpmInstall(timeoutDuringPartialInstallation: boolean) { const root = "/user/username/rootfolder/otherfolder"; - const getRootedFileOrFolder = (fileOrFolder: File) => { + const getRootedFileOrFolder = (fileOrFolder: T) => { fileOrFolder.path = root + fileOrFolder.path; return fileOrFolder; }; @@ -390,7 +390,7 @@ namespace ts.projectSystem { let npmInstallComplete = false; // Simulate npm install - const filesAndFoldersToAdd: File[] = [ + const filesAndFoldersToAdd: (File | Folder)[] = [ { path: "/a/b/node_modules" }, { path: "/a/b/node_modules/.staging/@types" }, { path: "/a/b/node_modules/.staging/lodash-b0733faa" }, diff --git a/src/testRunner/unittests/tsserver/webServer.ts b/src/testRunner/unittests/tsserver/webServer.ts index 7a940abc68c58..4a10f4fa0bc00 100644 --- a/src/testRunner/unittests/tsserver/webServer.ts +++ b/src/testRunner/unittests/tsserver/webServer.ts @@ -20,7 +20,7 @@ namespace ts.projectSystem { }, logger, server.nullCancellationToken, - () => emptyArray + () => [0, 0] ); } diff --git a/src/tsserver/nodeServer.ts b/src/tsserver/nodeServer.ts index 0bfc5f5871931..d1e03d37ea45a 100644 --- a/src/tsserver/nodeServer.ts +++ b/src/tsserver/nodeServer.ts @@ -691,7 +691,7 @@ namespace ts.server { cancellationToken, ...options, typingsInstaller: typingsInstaller || nullTypingsInstaller, - byteLength: Buffer.byteLength, + byteLength: Buffer.byteLength as (buf: string, encoding?: string | undefined) => number, hrtime: process.hrtime, logger, canUseEvents: true, diff --git a/src/tsserver/webServer.ts b/src/tsserver/webServer.ts index 71beb5a8db92b..b552ac7b6c054 100644 --- a/src/tsserver/webServer.ts +++ b/src/tsserver/webServer.ts @@ -97,7 +97,7 @@ namespace ts.server { } } - function hrtime(previous?: [number, number]) { + function hrtime(previous?: [number, number]): [number, number] { const now = self.performance.now() * 1e-3; let seconds = Math.floor(now); let nanoseconds = Math.floor((now % 1) * 1e9); diff --git a/src/typingsInstallerCore/typingsInstaller.ts b/src/typingsInstallerCore/typingsInstaller.ts index d7600f2598a86..1595c34eabe45 100644 --- a/src/typingsInstallerCore/typingsInstaller.ts +++ b/src/typingsInstallerCore/typingsInstaller.ts @@ -86,8 +86,8 @@ namespace ts.server.typingsInstaller { type ProjectWatchers = ESMap & { isInvoked?: boolean; }; - function getDetailWatchInfo(projectName: string, watchers: ProjectWatchers) { - return `Project: ${projectName} watcher already invoked: ${watchers.isInvoked}`; + function getDetailWatchInfo(projectName: string, watchers: ProjectWatchers | undefined) { + return `Project: ${projectName} watcher already invoked: ${watchers?.isInvoked}`; } export abstract class TypingsInstaller { From e88bc11fb0dbb2c1e5791ae5e64eaf86bb1c5a05 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 09:30:15 -0700 Subject: [PATCH 16/81] Write some jsdoc, update baselines --- src/compiler/checker.ts | 6 +- src/compiler/types.ts | 21 +++- src/compiler/visitorPublic.ts | 10 +- src/services/textChanges.ts | 8 +- .../reference/api/tsserverlibrary.d.ts | 95 ++++++++++--------- tests/baselines/reference/api/typescript.d.ts | 93 +++++++++--------- 6 files changed, 130 insertions(+), 103 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bf4e37975a68e..95604a080ec11 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5500,7 +5500,7 @@ namespace ts { TArray extends NodeArray | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, - TOut extends TArray extends undefined ? NodeArray | undefined + TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray, >( nodes: TArray, @@ -5508,11 +5508,11 @@ namespace ts { test?: (node: Node) => node is TAssert, start?: number, count?: number, - ): TOut { + ): TOutArray { if (nodes && nodes.length === 0) { // Ensure we explicitly make a copy of an empty array; visitNodes will not do this unless the array has elements, // which can lead to us reusing the same empty NodeArray more than once within the same AST during type noding. - return setTextRange(factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes) as TOut; + return setTextRange(factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes) as TOutArray; } return visitNodes(nodes, visitor, test, start, count); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 38bd7d32bf7c4..e26f7c5100067 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8546,6 +8546,15 @@ namespace ts { export type Visitor = (node: TIn) => VisitResult; /** + * A function that walks a node using the given visitor, lifting node arrays into single nodes, + * returning an node which satisfies the test. + * + * This type is complicated, but intends to encode the following behaviors: + * + * - If the input node is potentially undefined, the output is potentially undefined. + * - If the visitor can return undefined, the output is potentially undefined. + * - If the output node is not undefined, then it will satisfy the test. + * * @see {visitNode} */ export interface NodeVisitor { @@ -8565,6 +8574,14 @@ namespace ts { } /** + * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. + * + * This type is complicated, but intends to encode the following behaviors: + * + * - If the input node array is potentially undefined, the output is potentially undefined. + * - If the visitor can return undefined, the output may not be undefined; these nodes will be left in the output. + * - If the output node array is not undefined, then its contents will satisfy the test. + * * @see {visitNodes} */ export interface NodesVisitor { @@ -8573,7 +8590,7 @@ namespace ts { TArray extends NodeArray | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, - TOut extends TArray extends undefined ? NodeArray | undefined + TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray, >( nodes: TArray, @@ -8581,7 +8598,7 @@ namespace ts { test?: (node: Node) => node is TAssert, start?: number, count?: number, - ): TOut; + ): TOutArray; } declare const testNodeVisitor2: NodeVisitor; diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 894acb0ab7ede..a09f1ce41fe80 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -63,7 +63,7 @@ namespace ts { TArray extends NodeArray | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, - TOut extends TArray extends undefined ? NodeArray | undefined + TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray, >( nodes: TArray, @@ -71,10 +71,10 @@ namespace ts { test?: (node: Node) => node is TAssert, start?: number, count?: number, - ): TOut { + ): TOutArray { if (nodes === undefined) { // If the input type is undefined, then the output type can be undefined. - return nodes as NodeArray | undefined as TOut; + return nodes as NodeArray | undefined as TOutArray; } // Ensure start and count have valid values @@ -106,13 +106,13 @@ namespace ts { // TODO(rbuckton): Remove dependency on `ts.factory` in favor of a provided factory. const updatedArray = factory.createNodeArray(updated, hasTrailingComma); setTextRangePosEnd(updatedArray, pos, end); - return updatedArray as TOut; + return updatedArray as TOutArray; } // If we are here, updated === nodes. This means that it's still a NodeArray, // and also that its contents passed the tests in visitArrayWorker, so has contents // of type TOut. - return nodes as NodeArray as TOut; + return nodes as NodeArray as TOutArray; } ((_: NodesVisitor) => {})(visitNodes); // Check that visitNode is a NodeVisitor. diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index ff5a4f496537f..860f9ef5df633 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1141,7 +1141,7 @@ namespace ts.textChanges { TArray extends NodeArray | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, - TOut extends TArray extends undefined ? NodeArray | undefined + TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray, >( nodes: TArray, @@ -1149,16 +1149,16 @@ namespace ts.textChanges { test?: (node: Node) => node is TAssert, start?: number, count?: number, - ): TOut { + ): TOutArray { const visited = visitNodes(nodes, visitor, test, start, count); if (!visited) { - return visited as TOut; + return visited as TOutArray; } Debug.assert(nodes); // clone nodearray if necessary const nodeArray = visited as NodeArray === nodes ? factory.createNodeArray(visited.slice(0)) : visited; setTextRangePosEnd(nodeArray, getPos(nodes), getEnd(nodes)); - return nodeArray as TOut; + return nodeArray as TOutArray; } interface TextChangesWriter extends EmitTextWriter, PrintHandlers {} diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 50fbd1d4dea72..cd543293f33b2 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3765,10 +3765,10 @@ declare namespace ts { updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier | undefined, comment: string | NodeArray | undefined): JSDocReadonlyTag; createJSDocUnknownTag(tagName: Identifier, comment?: string | NodeArray): JSDocUnknownTag; updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | NodeArray | undefined): JSDocUnknownTag; - createJSDocDeprecatedTag(tagName: Identifier, comment?: string | NodeArray): JSDocDeprecatedTag; - updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment?: string | NodeArray): JSDocDeprecatedTag; - createJSDocOverrideTag(tagName: Identifier, comment?: string | NodeArray): JSDocOverrideTag; - updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment?: string | NodeArray): JSDocOverrideTag; + createJSDocDeprecatedTag(tagName: Identifier | undefined, comment?: string | NodeArray): JSDocDeprecatedTag; + updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier | undefined, comment?: string | NodeArray): JSDocDeprecatedTag; + createJSDocOverrideTag(tagName: Identifier | undefined, comment?: string | NodeArray): JSDocOverrideTag; + updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier | undefined, comment?: string | NodeArray): JSDocOverrideTag; createJSDocText(text: string): JSDocText; updateJSDocText(node: JSDocText, text: string): JSDocText; createJSDocComment(comment?: string | NodeArray | undefined, tags?: readonly JSDocTag[] | undefined): JSDoc; @@ -3955,19 +3955,42 @@ declare namespace ts { * A function that transforms a node. */ export type Transformer = (node: T) => T; + export type VisitResult> = T | readonly U[]; /** * A function that accepts and possibly transforms a node. */ - export type Visitor = (node: Node) => VisitResult; + export type Visitor = (node: TIn) => VisitResult; + /** + * A function that walks a node using the given visitor, lifting node arrays into single nodes, + * returning an node which satisfies the test. + * + * This type is complicated, but intends to encode the following behaviors: + * + * - If the input node is potentially undefined, the output is potentially undefined. + * - If the visitor can return undefined, the output is potentially undefined. + * - If the output node is not undefined, then it will satisfy the test. + * + * @see {visitNode} + */ export interface NodeVisitor { - (nodes: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T; - (nodes: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined; + , TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => node is TAssert, lift?: (node: readonly Node[]) => Node): TOut; } + /** + * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. + * + * This type is complicated, but intends to encode the following behaviors: + * + * - If the input node array is potentially undefined, the output is potentially undefined. + * - If the visitor can return undefined, the output may not be undefined; these nodes will be left in the output. + * - If the output node array is not undefined, then its contents will satisfy the test. + * + * @see {visitNodes} + */ export interface NodesVisitor { - (nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; - (nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: (node: Node) => node is TAssert, start?: number, count?: number): TOutArray; } - export type VisitResult = T | readonly T[] | undefined; + export function _jakeTesting(node: Node, nodeVisitor: Visitor): AssertionExpression; + export function _jakeTesting2(nodes: NodeArray, nodeVisitor: Visitor): NodeArray; export interface Printer { /** * Print a node and its subtree as-is, without any emit transformations. @@ -4286,8 +4309,8 @@ declare namespace ts { function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; - function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U | undefined; - function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U | undefined; + function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U): U | undefined; + function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U): U | undefined; function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined; function getTrailingCommentRanges(text: string, pos: number): CommentRange[] | undefined; /** Optionally, get the shebang */ @@ -4333,7 +4356,7 @@ declare namespace ts { }; function isParameterPropertyDeclaration(node: Node, parent: Node): node is ParameterPropertyDeclaration; function isEmptyBindingPattern(node: BindingName): node is BindingPattern; - function isEmptyBindingElement(node: BindingElement): boolean; + function isEmptyBindingElement(node: BindingElement | ArrayBindingElement): boolean; function walkUpBindingElementsAndPatterns(binding: BindingElement): VariableDeclaration | ParameterDeclaration; function getCombinedModifierFlags(node: Declaration): ModifierFlags; function getCombinedNodeFlags(node: Node): NodeFlags; @@ -4350,7 +4373,7 @@ declare namespace ts { function getOriginalNode(node: Node): Node; function getOriginalNode(node: Node, nodeTest: (node: Node) => node is T): T; function getOriginalNode(node: Node | undefined): Node | undefined; - function getOriginalNode(node: Node | undefined, nodeTest: (node: Node | undefined) => node is T): T | undefined; + function getOriginalNode(node: Node | undefined, nodeTest: (node: Node) => node is T): T | undefined; /** * Iterates through the parent chain of a node and performs the callback on each parent until the callback * returns a truthy value, then returns that value. @@ -4546,6 +4569,7 @@ declare namespace ts { */ function isTypeNode(node: Node): node is TypeNode; function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode; + function isBindingOrAssignmentElement(node: Node): node is BindingOrAssignmentElement; function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName; function isCallLikeExpression(node: Node): node is CallLikeExpression; function isCallOrNewExpression(node: Node): node is CallExpression | NewExpression; @@ -5062,26 +5086,7 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode(node: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T; - /** - * Visits a Node using the supplied visitor, possibly returning a new Node in its place. - * - * @param node The Node to visit. - * @param visitor The callback used to visit the Node. - * @param test A callback to execute to verify the Node is valid. - * @param lift An optional callback to execute to lift a NodeArray into a valid Node. - */ - function visitNode(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined; - /** - * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. - * - * @param nodes The NodeArray to visit. - * @param visitor The callback used to visit a Node. - * @param test A node test to execute for each node. - * @param start An optional value indicating the starting offset at which to start visiting. - * @param count An optional value indicating the maximum number of nodes to visit. - */ - function visitNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; + function visitNode, TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => node is TAssert, lift?: (node: readonly Node[]) => Node): TOut; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -5091,37 +5096,37 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + function visitNodes | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: (node: Node) => node is TAssert, start?: number, count?: number): TOutArray; /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; + function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; /** * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; - function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; + function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; + function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; + function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; /** * Resumes a suspended lexical environment and visits a concise body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; + function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; /** * Visits an iteration body, adding any block-scoped variables required by the transformation. */ - function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; + function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -5129,7 +5134,7 @@ declare namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; + function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -5137,7 +5142,7 @@ declare namespace ts { * @param visitor The callback used to visit each child. * @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 visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; } declare namespace ts { function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined; @@ -10698,7 +10703,7 @@ declare namespace ts.server { useInferredProjectPerProjectRoot: boolean; typingsInstaller: ITypingsInstaller; byteLength: (buf: string, encoding?: string) => number; - hrtime: (start?: number[]) => number[]; + hrtime: (start?: [number, number]) => [number, number]; logger: Logger; /** * If falsy, all events are suppressed. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index d323d77c229dd..1bb302c441c83 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3765,10 +3765,10 @@ declare namespace ts { updateJSDocReadonlyTag(node: JSDocReadonlyTag, tagName: Identifier | undefined, comment: string | NodeArray | undefined): JSDocReadonlyTag; createJSDocUnknownTag(tagName: Identifier, comment?: string | NodeArray): JSDocUnknownTag; updateJSDocUnknownTag(node: JSDocUnknownTag, tagName: Identifier, comment: string | NodeArray | undefined): JSDocUnknownTag; - createJSDocDeprecatedTag(tagName: Identifier, comment?: string | NodeArray): JSDocDeprecatedTag; - updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier, comment?: string | NodeArray): JSDocDeprecatedTag; - createJSDocOverrideTag(tagName: Identifier, comment?: string | NodeArray): JSDocOverrideTag; - updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier, comment?: string | NodeArray): JSDocOverrideTag; + createJSDocDeprecatedTag(tagName: Identifier | undefined, comment?: string | NodeArray): JSDocDeprecatedTag; + updateJSDocDeprecatedTag(node: JSDocDeprecatedTag, tagName: Identifier | undefined, comment?: string | NodeArray): JSDocDeprecatedTag; + createJSDocOverrideTag(tagName: Identifier | undefined, comment?: string | NodeArray): JSDocOverrideTag; + updateJSDocOverrideTag(node: JSDocOverrideTag, tagName: Identifier | undefined, comment?: string | NodeArray): JSDocOverrideTag; createJSDocText(text: string): JSDocText; updateJSDocText(node: JSDocText, text: string): JSDocText; createJSDocComment(comment?: string | NodeArray | undefined, tags?: readonly JSDocTag[] | undefined): JSDoc; @@ -3955,19 +3955,42 @@ declare namespace ts { * A function that transforms a node. */ export type Transformer = (node: T) => T; + export type VisitResult> = T | readonly U[]; /** * A function that accepts and possibly transforms a node. */ - export type Visitor = (node: Node) => VisitResult; + export type Visitor = (node: TIn) => VisitResult; + /** + * A function that walks a node using the given visitor, lifting node arrays into single nodes, + * returning an node which satisfies the test. + * + * This type is complicated, but intends to encode the following behaviors: + * + * - If the input node is potentially undefined, the output is potentially undefined. + * - If the visitor can return undefined, the output is potentially undefined. + * - If the output node is not undefined, then it will satisfy the test. + * + * @see {visitNode} + */ export interface NodeVisitor { - (nodes: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T; - (nodes: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined; + , TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => node is TAssert, lift?: (node: readonly Node[]) => Node): TOut; } + /** + * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. + * + * This type is complicated, but intends to encode the following behaviors: + * + * - If the input node array is potentially undefined, the output is potentially undefined. + * - If the visitor can return undefined, the output may not be undefined; these nodes will be left in the output. + * - If the output node array is not undefined, then its contents will satisfy the test. + * + * @see {visitNodes} + */ export interface NodesVisitor { - (nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; - (nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: (node: Node) => node is TAssert, start?: number, count?: number): TOutArray; } - export type VisitResult = T | readonly T[] | undefined; + export function _jakeTesting(node: Node, nodeVisitor: Visitor): AssertionExpression; + export function _jakeTesting2(nodes: NodeArray, nodeVisitor: Visitor): NodeArray; export interface Printer { /** * Print a node and its subtree as-is, without any emit transformations. @@ -4286,8 +4309,8 @@ declare namespace ts { function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; - function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U | undefined; - function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U | undefined; + function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U): U | undefined; + function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T, initial: U): U | undefined; function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined; function getTrailingCommentRanges(text: string, pos: number): CommentRange[] | undefined; /** Optionally, get the shebang */ @@ -4333,7 +4356,7 @@ declare namespace ts { }; function isParameterPropertyDeclaration(node: Node, parent: Node): node is ParameterPropertyDeclaration; function isEmptyBindingPattern(node: BindingName): node is BindingPattern; - function isEmptyBindingElement(node: BindingElement): boolean; + function isEmptyBindingElement(node: BindingElement | ArrayBindingElement): boolean; function walkUpBindingElementsAndPatterns(binding: BindingElement): VariableDeclaration | ParameterDeclaration; function getCombinedModifierFlags(node: Declaration): ModifierFlags; function getCombinedNodeFlags(node: Node): NodeFlags; @@ -4350,7 +4373,7 @@ declare namespace ts { function getOriginalNode(node: Node): Node; function getOriginalNode(node: Node, nodeTest: (node: Node) => node is T): T; function getOriginalNode(node: Node | undefined): Node | undefined; - function getOriginalNode(node: Node | undefined, nodeTest: (node: Node | undefined) => node is T): T | undefined; + function getOriginalNode(node: Node | undefined, nodeTest: (node: Node) => node is T): T | undefined; /** * Iterates through the parent chain of a node and performs the callback on each parent until the callback * returns a truthy value, then returns that value. @@ -4546,6 +4569,7 @@ declare namespace ts { */ function isTypeNode(node: Node): node is TypeNode; function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode; + function isBindingOrAssignmentElement(node: Node): node is BindingOrAssignmentElement; function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName; function isCallLikeExpression(node: Node): node is CallLikeExpression; function isCallOrNewExpression(node: Node): node is CallExpression | NewExpression; @@ -5062,26 +5086,7 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode(node: T, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T; - /** - * Visits a Node using the supplied visitor, possibly returning a new Node in its place. - * - * @param node The Node to visit. - * @param visitor The callback used to visit the Node. - * @param test A callback to execute to verify the Node is valid. - * @param lift An optional callback to execute to lift a NodeArray into a valid Node. - */ - function visitNode(node: T | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => T): T | undefined; - /** - * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. - * - * @param nodes The NodeArray to visit. - * @param visitor The callback used to visit a Node. - * @param test A node test to execute for each node. - * @param start An optional value indicating the starting offset at which to start visiting. - * @param count An optional value indicating the maximum number of nodes to visit. - */ - function visitNodes(nodes: NodeArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray; + function visitNode, TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => node is TAssert, lift?: (node: readonly Node[]) => Node): TOut; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -5091,37 +5096,37 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes(nodes: NodeArray | undefined, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | undefined; + function visitNodes | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: (node: Node) => node is TAssert, start?: number, count?: number): TOutArray; /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; + function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; /** * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; - function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; + function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; + function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; + function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; /** * Resumes a suspended lexical environment and visits a concise body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; + function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; /** * Visits an iteration body, adding any block-scoped variables required by the transformation. */ - function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; + function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -5129,7 +5134,7 @@ declare namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; + function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -5137,7 +5142,7 @@ declare namespace ts { * @param visitor The callback used to visit each child. * @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 visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; } declare namespace ts { function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined; From c31d0a686238313019c8c2acf3adf87ab4484c44 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 09:46:43 -0700 Subject: [PATCH 17/81] Fix lint --- src/compiler/checker.ts | 2 +- src/compiler/core.ts | 2 +- src/compiler/parser.ts | 2 +- src/compiler/types.ts | 26 +++++++++++++++----------- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 95604a080ec11..a1118370a2f7e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6835,7 +6835,7 @@ namespace ts { return visitNode(node.type, visitExistingNodeTreeSymbols); } if (isJSDocVariadicType(node)) { - return factory.createArrayTypeNode(visitNode((node as JSDocVariadicType).type, visitExistingNodeTreeSymbols)); + return factory.createArrayTypeNode(visitNode(node.type, visitExistingNodeTreeSymbols)); } if (isJSDocTypeLiteral(node)) { return factory.createTypeLiteralNode(map(node.jsDocPropertyTags, t => { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 4dfd7195119ed..2325dbd21d377 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -165,7 +165,7 @@ namespace ts { return true; } - /** + /** * Equivalent to every, but can discriminate between unions of arrays. */ export function isArrayOf(array: readonly any[], callback: (element: any, index: number) => element is T): array is readonly T[]; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0ee2c3cdb03a4..617a88d9ae92d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -8364,7 +8364,7 @@ namespace ts { case "override": tag = parseSimpleTag(start, factory.createJSDocOverrideTag, tagName, margin, indentText); break; - case "deprecated": + case "deprecated": hasDeprecatedTag = true; tag = parseSimpleTag(start, factory.createJSDocDeprecatedTag, tagName, margin, indentText); break; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e26f7c5100067..b4707c9f049c4 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4506,7 +4506,7 @@ namespace ts { export interface CustomTransformers { /** Custom transformers to evaluate before built-in .js transformations. */ - before?: (TransformerFactory | CustomTransformerFactory)[]; + before?: (TransformerFactory | CustomTransformerFactory)[]; /** Custom transformers to evaluate after built-in .js transformations. */ after?: (TransformerFactory | CustomTransformerFactory)[]; /** Custom transformers to evaluate after built-in .d.ts transformations. */ @@ -8530,7 +8530,7 @@ namespace ts { * A function that is used to initialize and return a `Transformer` callback, which in turn * will be used to transform one or more nodes. */ - export type TransformerFactory = (context: TransformationContext) => Transformer + export type TransformerFactory = (context: TransformationContext) => Transformer; /** * A function that transforms a node. @@ -8539,25 +8539,28 @@ namespace ts { // Either a node, or a list of nodes to be be lifted via a lift function. export type VisitResult> = T | readonly U[]; - + /** * A function that accepts and possibly transforms a node. */ export type Visitor = (node: TIn) => VisitResult; - + /** * A function that walks a node using the given visitor, lifting node arrays into single nodes, * returning an node which satisfies the test. - * + * * This type is complicated, but intends to encode the following behaviors: - * + * * - If the input node is potentially undefined, the output is potentially undefined. * - If the visitor can return undefined, the output is potentially undefined. * - If the output node is not undefined, then it will satisfy the test. - * + * * @see {visitNode} */ export interface NodeVisitor { + // TODO(jakebailey): Was previously declared as an interface; I don't konw if changing it to a type is safe. Same for NodesVisitor. + // This form is nice, thuogh, because you can copy and paste the signature without changing the return `:` to `=>`. + // eslint-disable-next-line @typescript-eslint/prefer-function-type < TIn extends Node | undefined, TVisited extends Node | undefined, @@ -8572,19 +8575,20 @@ namespace ts { lift?: (node: readonly Node[]) => Node, ): TOut; } - + /** * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. - * + * * This type is complicated, but intends to encode the following behaviors: - * + * * - If the input node array is potentially undefined, the output is potentially undefined. * - If the visitor can return undefined, the output may not be undefined; these nodes will be left in the output. * - If the output node array is not undefined, then its contents will satisfy the test. - * + * * @see {visitNodes} */ export interface NodesVisitor { + // eslint-disable-next-line @typescript-eslint/prefer-function-type < TIn extends Node, TArray extends NodeArray | undefined, From 5df975bbed80471ef87e9bd7b4197c76d6d89711 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 10:06:10 -0700 Subject: [PATCH 18/81] Actually fix lint --- src/compiler/visitorPublic.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index a09f1ce41fe80..a324c18f23d06 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -195,7 +195,7 @@ namespace ts { } const result: readonly Node[] = updated ?? nodes; - Debug.assertEachNode(result, test) + Debug.assertEachNode(result, test); return result as readonly TAssert[]; } From b114ceac4124e9c1ac8ede9dacf868ea03b62c9a Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 10:49:53 -0700 Subject: [PATCH 19/81] PR feedback --- src/compiler/types.ts | 17 +---------------- .../reference/api/tsserverlibrary.d.ts | 4 +--- tests/baselines/reference/api/typescript.d.ts | 4 +--- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b4707c9f049c4..3fb271adb1cb9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8538,7 +8538,7 @@ namespace ts { export type Transformer = (node: T) => T; // TODO(jakebailey): This signature is totally wrong. // Either a node, or a list of nodes to be be lifted via a lift function. - export type VisitResult> = T | readonly U[]; + export type VisitResult = T | readonly Node[]; /** * A function that accepts and possibly transforms a node. @@ -8605,21 +8605,6 @@ namespace ts { ): TOutArray; } - declare const testNodeVisitor2: NodeVisitor; - declare const testNodesVisitor2: NodesVisitor; - - export function _jakeTesting(node: Node, nodeVisitor: Visitor) { - const result = testNodeVisitor2(node, nodeVisitor, isAssertionExpression); - // ^? - return result; - } - - export function _jakeTesting2(nodes: NodeArray, nodeVisitor: Visitor) { - const result = testNodesVisitor2(nodes, nodeVisitor, isAssertionExpression); - // ^? - return result; - } - export interface Printer { /** * Print a node and its subtree as-is, without any emit transformations. diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index cd543293f33b2..effa3bafb76fd 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3955,7 +3955,7 @@ declare namespace ts { * A function that transforms a node. */ export type Transformer = (node: T) => T; - export type VisitResult> = T | readonly U[]; + export type VisitResult = T | readonly Node[]; /** * A function that accepts and possibly transforms a node. */ @@ -3989,8 +3989,6 @@ declare namespace ts { export interface NodesVisitor { | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: (node: Node) => node is TAssert, start?: number, count?: number): TOutArray; } - export function _jakeTesting(node: Node, nodeVisitor: Visitor): AssertionExpression; - export function _jakeTesting2(nodes: NodeArray, nodeVisitor: Visitor): NodeArray; export interface Printer { /** * Print a node and its subtree as-is, without any emit transformations. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 1bb302c441c83..729cb4ab988b6 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3955,7 +3955,7 @@ declare namespace ts { * A function that transforms a node. */ export type Transformer = (node: T) => T; - export type VisitResult> = T | readonly U[]; + export type VisitResult = T | readonly Node[]; /** * A function that accepts and possibly transforms a node. */ @@ -3989,8 +3989,6 @@ declare namespace ts { export interface NodesVisitor { | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: (node: Node) => node is TAssert, start?: number, count?: number): TOutArray; } - export function _jakeTesting(node: Node, nodeVisitor: Visitor): AssertionExpression; - export function _jakeTesting2(nodes: NodeArray, nodeVisitor: Visitor): NodeArray; export interface Printer { /** * Print a node and its subtree as-is, without any emit transformations. From 88034eb142a520a963e8cb47f7eefa5d3f245014 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 11:01:35 -0700 Subject: [PATCH 20/81] Allow non-guards as test parameter --- src/compiler/checker.ts | 2 +- src/compiler/types.ts | 4 ++-- src/compiler/visitorPublic.ts | 6 +++--- src/services/textChanges.ts | 2 +- tests/baselines/reference/api/tsserverlibrary.d.ts | 8 ++++---- tests/baselines/reference/api/typescript.d.ts | 8 ++++---- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a1118370a2f7e..096d69920c27d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5505,7 +5505,7 @@ namespace ts { >( nodes: TArray, visitor: Visitor | undefined, - test?: (node: Node) => node is TAssert, + test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number, ): TOutArray { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 3fb271adb1cb9..491ff2536c843 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8571,7 +8571,7 @@ namespace ts { >( node: TIn, visitor: Visitor, TVisited> | undefined, - test?: (node: Node) => node is TAssert, + test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), lift?: (node: readonly Node[]) => Node, ): TOut; } @@ -8599,7 +8599,7 @@ namespace ts { >( nodes: TArray, visitor: Visitor | undefined, - test?: (node: Node) => node is TAssert, + test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number, ): TOutArray; diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index a324c18f23d06..5821bc25c5aa2 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -19,7 +19,7 @@ namespace ts { >( node: TIn, visitor: Visitor, TVisited> | undefined, - test?: (node: Node) => node is TAssert, + test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), lift?: (node: readonly Node[]) => Node, ): TOut { if (node === undefined) { @@ -68,7 +68,7 @@ namespace ts { >( nodes: TArray, visitor: Visitor | undefined, - test?: (node: Node) => node is TAssert, + test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number, ): TOutArray { @@ -158,7 +158,7 @@ namespace ts { >( nodes: readonly TIn[], visitor: Visitor | undefined, - test: ((node: Node) => node is TAssert) | undefined, + test: ((node: Node) => node is TAssert) | ((node: Node) => boolean) | undefined, start: number, count: number, ): readonly TAssert[] { diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 860f9ef5df633..e9d9ccf25d7dc 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1146,7 +1146,7 @@ namespace ts.textChanges { >( nodes: TArray, visitor: Visitor | undefined, - test?: (node: Node) => node is TAssert, + test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number, ): TOutArray { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index effa3bafb76fd..af78ebe403894 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3973,7 +3973,7 @@ declare namespace ts { * @see {visitNode} */ export interface NodeVisitor { - , TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => node is TAssert, lift?: (node: readonly Node[]) => Node): TOut; + , TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), lift?: (node: readonly Node[]) => Node): TOut; } /** * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. @@ -3987,7 +3987,7 @@ declare namespace ts { * @see {visitNodes} */ export interface NodesVisitor { - | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: (node: Node) => node is TAssert, start?: number, count?: number): TOutArray; + | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number): TOutArray; } export interface Printer { /** @@ -5084,7 +5084,7 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode, TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => node is TAssert, lift?: (node: readonly Node[]) => Node): TOut; + function visitNode, TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), lift?: (node: readonly Node[]) => Node): TOut; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -5094,7 +5094,7 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: (node: Node) => node is TAssert, start?: number, count?: number): TOutArray; + function visitNodes | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number): TOutArray; /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 729cb4ab988b6..f974f85bdef75 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3973,7 +3973,7 @@ declare namespace ts { * @see {visitNode} */ export interface NodeVisitor { - , TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => node is TAssert, lift?: (node: readonly Node[]) => Node): TOut; + , TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), lift?: (node: readonly Node[]) => Node): TOut; } /** * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. @@ -3987,7 +3987,7 @@ declare namespace ts { * @see {visitNodes} */ export interface NodesVisitor { - | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: (node: Node) => node is TAssert, start?: number, count?: number): TOutArray; + | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number): TOutArray; } export interface Printer { /** @@ -5084,7 +5084,7 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode, TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => node is TAssert, lift?: (node: readonly Node[]) => Node): TOut; + function visitNode, TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), lift?: (node: readonly Node[]) => Node): TOut; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -5094,7 +5094,7 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: (node: Node) => node is TAssert, start?: number, count?: number): TOutArray; + function visitNodes | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number): TOutArray; /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. From fcda16e8dd7a9b67b83187fc9e5dcf7086e7668c Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 14:03:37 -0700 Subject: [PATCH 21/81] Actually, maybe this does fix Transform --- src/compiler/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 491ff2536c843..77618650ba164 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8530,12 +8530,12 @@ namespace ts { * A function that is used to initialize and return a `Transformer` callback, which in turn * will be used to transform one or more nodes. */ - export type TransformerFactory = (context: TransformationContext) => Transformer; + export type TransformerFactory = (context: TransformationContext) => Transformer; /** * A function that transforms a node. */ - export type Transformer = (node: T) => T; // TODO(jakebailey): This signature is totally wrong. + export type Transformer = (node: TIn) => TOut; // Either a node, or a list of nodes to be be lifted via a lift function. export type VisitResult = T | readonly Node[]; From e7cf2139c079d5ef02bb0aaccd733ea22ade564e Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 14:04:21 -0700 Subject: [PATCH 22/81] Update baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 4 ++-- tests/baselines/reference/api/typescript.d.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index af78ebe403894..3f9fad1c0466d 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3950,11 +3950,11 @@ declare namespace ts { * A function that is used to initialize and return a `Transformer` callback, which in turn * will be used to transform one or more nodes. */ - export type TransformerFactory = (context: TransformationContext) => Transformer; + export type TransformerFactory = (context: TransformationContext) => Transformer; /** * A function that transforms a node. */ - export type Transformer = (node: T) => T; + export type Transformer = (node: TIn) => TOut; export type VisitResult = T | readonly Node[]; /** * A function that accepts and possibly transforms a node. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f974f85bdef75..300550f2993e1 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3950,11 +3950,11 @@ declare namespace ts { * A function that is used to initialize and return a `Transformer` callback, which in turn * will be used to transform one or more nodes. */ - export type TransformerFactory = (context: TransformationContext) => Transformer; + export type TransformerFactory = (context: TransformationContext) => Transformer; /** * A function that transforms a node. */ - export type Transformer = (node: T) => T; + export type Transformer = (node: TIn) => TOut; export type VisitResult = T | readonly Node[]; /** * A function that accepts and possibly transforms a node. From 2ed2e9250d9cfb76b43f5ffe81e9bc3bc0ae20cb Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 16:16:25 -0700 Subject: [PATCH 23/81] Update comment --- src/compiler/factory/parenthesizerRules.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts index 3e625168c6a19..b7a4428cc9b89 100644 --- a/src/compiler/factory/parenthesizerRules.ts +++ b/src/compiler/factory/parenthesizerRules.ts @@ -603,8 +603,9 @@ namespace ts { } function castToNodeArray(nodes: readonly T[]): NodeArray { - // TODO(jakebailey): Why do we need this helper? GH#49924? - // Also, why can't I write `isNodeArray` as an expression? + // TODO(jakebailey): Why do we need this helper? GH#49924? It seems like `cast(nodes, isNodeArray)` should be enough. + // Also, this typeof shouldn't be needed, but https://github.com/microsoft/TypeScript/issues/50161 + // makes any change to this file cause an error to appear. return cast(nodes, isNodeArray as typeof isNodeArray); } From 9ae68fd9263411a2a03f1e4003ace8a7293c7095 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 17:11:56 -0700 Subject: [PATCH 24/81] Resolve a TODO --- src/compiler/checker.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d77ae4772d9af..9dd09d642b8e4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27775,10 +27775,10 @@ namespace ts { return getStrictOptionValue(compilerOptions, "noImplicitAny") ? reduceLeft( signatures, - (left, right) => + (left: Signature | undefined, right) => left === right || !left ? left - : compareTypeParametersIdentical(left.typeParameters, right.typeParameters) ? combineSignaturesOfIntersectionMembers(left, right) - : undefined!) // TODO(jakebailey): This is suspect. Can't pass initialValue as reduceLeft checks argument length. + : compareTypeParametersIdentical(left.typeParameters, right!.typeParameters) ? combineSignaturesOfIntersectionMembers(left, right!) + : undefined) : undefined; } From 8b1efc1c5fd65fc24dd304d0ae8a185f7afea85a Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 17:16:05 -0700 Subject: [PATCH 25/81] Remove already resolved TODO --- src/compiler/visitorPublic.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 5821bc25c5aa2..04e0b68e841a7 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -1,6 +1,4 @@ namespace ts { - // TODO(jakebailey): include type guard and non-type guard variants on visitNode and visitNodes - /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * From eff9485932ddd913b40cfc870755d1656847ad41 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 17:17:15 -0700 Subject: [PATCH 26/81] More todo updats --- src/compiler/utilitiesPublic.ts | 2 -- src/services/documentHighlights.ts | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 58fe2897a809e..1a8e0f76eb1c0 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -399,8 +399,6 @@ namespace ts { } } - // TODO(jakebailey): I've changed this signature in an incompatible way. - // The original signatures didn't seem to make any sense, but I'm willing to be wrong. export function getOriginalNode(node: Node): Node; export function getOriginalNode(node: Node, nodeTest: (node: Node) => node is T): T; export function getOriginalNode(node: Node | undefined): Node | undefined; diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 7b903cd1fcdb1..004c57a3f5c65 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -236,7 +236,7 @@ namespace ts { // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & (ModifierFlags.AccessibilityModifier | ModifierFlags.Readonly)) { - const constructor = find(container.members, isConstructorDeclaration); // TODO(jakebailey): GH#49924 ??? + const constructor = find(container.members, isConstructorDeclaration); // TODO(jakebailey): `members` is a union of two arrays, so find doesn't work without help. if (constructor) { return [...nodes, ...constructor.parameters]; } From 3a5d135b409da1dc935631d36f8fc970ccf7e550 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 19 Sep 2022 18:37:03 -0700 Subject: [PATCH 27/81] Fix my lint oops --- src/services/codefixes/annotateWithTypeFromJSDoc.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index 4f94f423ed5f4..c5e7e11ef905f 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -64,7 +64,7 @@ namespace ts.codefix { const transformedType = transformJSDocType(returnType); Debug.assertNode(transformedType, isTypeNode); changes.tryInsertTypeAnnotation(sourceFile, decl, transformedType); - }; + } } } else { From 59a318956cfabbe6845b300edceaf5c583a4cf95 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 20 Sep 2022 21:10:30 -0700 Subject: [PATCH 28/81] Much improved NodeVisitor and NodesVisitor --- src/compiler/checker.ts | 51 ++- src/compiler/transformers/classFields.ts | 54 +-- src/compiler/transformers/declarations.ts | 12 +- src/compiler/transformers/destructuring.ts | 8 +- src/compiler/transformers/es2015.ts | 64 +-- src/compiler/transformers/es2017.ts | 10 +- src/compiler/transformers/generators.ts | 62 +-- src/compiler/transformers/jsx.ts | 4 +- src/compiler/transformers/legacyDecorators.ts | 6 +- src/compiler/transformers/module/module.ts | 8 +- src/compiler/transformers/module/system.ts | 8 +- src/compiler/transformers/taggedTemplate.ts | 2 +- src/compiler/transformers/ts.ts | 28 +- src/compiler/types.ts | 69 ++- src/compiler/utilities.ts | 4 +- src/compiler/visitorPublic.ts | 397 ++++++++++-------- .../codefixes/annotateWithTypeFromJSDoc.ts | 10 +- src/services/refactors/extractSymbol.ts | 2 +- src/services/textChanges.ts | 39 +- src/testRunner/unittests/customTransforms.ts | 6 +- src/testRunner/unittests/transform.ts | 4 +- .../reference/api/tsserverlibrary.d.ts | 38 +- tests/baselines/reference/api/typescript.d.ts | 38 +- 23 files changed, 490 insertions(+), 434 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a20d97aa57aa7..82c1f5969f24a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5503,24 +5503,35 @@ namespace ts { return setTextRange(factory.cloneNode(visitEachChild(node, deepCloneOrReuseNode, nullTransformationContext, deepCloneOrReuseNodes)), node); } - function deepCloneOrReuseNodes< - TIn extends Node, - TArray extends NodeArray | undefined, - TVisited extends Node | undefined, - TAssert extends NonNullable, - TOutArray extends TArray extends undefined ? NodeArray | undefined - : NodeArray, - >( - nodes: TArray, + /** + * @see {NodesVisitor} + * @see {visitNodes} + */ + function deepCloneOrReuseNodes | undefined, TVisited extends Node | undefined, TOut extends Node>( + nodes: TInArray, + visitor: Visitor | undefined, + test: (node: Node) => node is TOut, + start?: number, + count?: number, + ): NodeArray | (TInArray & undefined); + function deepCloneOrReuseNodes | undefined, TVisited extends Node | undefined>( + nodes: TInArray, + visitor: Visitor | undefined, + test?: (node: Node) => boolean, + start?: number, + count?: number, + ): NodeArray | (TInArray & undefined); + function deepCloneOrReuseNodes | undefined, TVisited extends Node | undefined>( + nodes: TInArray, visitor: Visitor | undefined, - test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), + test?: (node: Node) => boolean, start?: number, count?: number, - ): TOutArray { + ): NodeArray | undefined { if (nodes && nodes.length === 0) { // Ensure we explicitly make a copy of an empty array; visitNodes will not do this unless the array has elements, // which can lead to us reusing the same empty NodeArray more than once within the same AST during type noding. - return setTextRange(factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes) as TOutArray; + return setTextRange(factory.createNodeArray(/*nodes*/ undefined, nodes.hasTrailingComma), nodes); } return visitNodes(nodes, visitor, test, start, count); } @@ -6834,16 +6845,16 @@ namespace ts { return factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword); } if (isJSDocNullableType(node)) { - return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols), factory.createLiteralTypeNode(factory.createNull())]); + return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode), factory.createLiteralTypeNode(factory.createNull())]); } if (isJSDocOptionalType(node)) { - return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols), factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]); + return factory.createUnionTypeNode([visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode), factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword)]); } if (isJSDocNonNullableType(node)) { return visitNode(node.type, visitExistingNodeTreeSymbols); } if (isJSDocVariadicType(node)) { - return factory.createArrayTypeNode(visitNode(node.type, visitExistingNodeTreeSymbols)); + return factory.createArrayTypeNode(visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode)); } if (isJSDocTypeLiteral(node)) { return factory.createTypeLiteralNode(map(node.jsDocPropertyTags, t => { @@ -6872,7 +6883,7 @@ namespace ts { /*questionToken*/ undefined, visitNode(node.typeArguments![0], visitExistingNodeTreeSymbols, isTypeNode) )], - visitNode(node.typeArguments![1], visitExistingNodeTreeSymbols) + visitNode(node.typeArguments![1], visitExistingNodeTreeSymbols, isTypeNode) )]); } if (isJSDocFunctionType(node)) { @@ -6886,10 +6897,10 @@ namespace ts { getEffectiveDotDotDotForParameter(p), getNameForJSDocFunctionParameter(p, i), p.questionToken, - visitNode(p.type, visitExistingNodeTreeSymbols), + visitNode(p.type, visitExistingNodeTreeSymbols, isTypeNode), /*initializer*/ undefined )), - visitNode(newTypeNode || node.type, visitExistingNodeTreeSymbols) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) + visitNode(newTypeNode || node.type, visitExistingNodeTreeSymbols, isTypeNode) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ); } else { @@ -6900,10 +6911,10 @@ namespace ts { getEffectiveDotDotDotForParameter(p), getNameForJSDocFunctionParameter(p, i), p.questionToken, - visitNode(p.type, visitExistingNodeTreeSymbols), + visitNode(p.type, visitExistingNodeTreeSymbols, isTypeNode), /*initializer*/ undefined )), - visitNode(node.type, visitExistingNodeTreeSymbols) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) + visitNode(node.type, visitExistingNodeTreeSymbols, isTypeNode) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) ); } } diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 2ed292952e9ff..b4f38898f71fb 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -630,7 +630,7 @@ namespace ts { } function createPrivateIdentifierAccess(info: PrivateIdentifierInfo, receiver: Expression): Expression { - return createPrivateIdentifierAccessHelper(info, visitNode(receiver, visitor, isExpression)); + return createPrivateIdentifierAccessHelper(info, Debug.checkDefined(visitNode(receiver, visitor, isExpression))); } function createPrivateIdentifierAccessHelper(info: PrivateIdentifierInfo, receiver: Expression): Expression { @@ -714,7 +714,7 @@ namespace ts { // converts `super[x]` into `Reflect.get(_baseTemp, x, _classTemp)` const superProperty = factory.createReflectGetCall( superClassReference, - visitNode(node.argumentExpression, visitor, isExpression), + Debug.checkDefined(visitNode(node.argumentExpression, visitor, isExpression)), classConstructor ); setOriginalNode(superProperty, node.expression); @@ -788,7 +788,7 @@ namespace ts { } else { getterName = factory.createTempVariable(hoistVariableDeclaration); - setterName = factory.createAssignment(getterName, visitNode(operand.argumentExpression, visitor, isExpression)); + setterName = factory.createAssignment(getterName, Debug.checkDefined(visitNode(operand.argumentExpression, visitor, isExpression))); } } if (setterName && getterName) { @@ -825,7 +825,7 @@ namespace ts { function visitExpressionStatement(node: ExpressionStatement) { return factory.updateExpressionStatement( node, - visitNode(node.expression, discardedValueVisitor, isExpression) + Debug.checkDefined(visitNode(node.expression, discardedValueVisitor, isExpression)) ); } @@ -849,17 +849,17 @@ namespace ts { if (isCallChain(node)) { return factory.updateCallChain( node, - factory.createPropertyAccessChain(visitNode(target, visitor), node.questionDotToken, "call"), + factory.createPropertyAccessChain(Debug.checkDefined(visitNode(target, visitor, isExpression)), node.questionDotToken, "call"), /*questionDotToken*/ undefined, /*typeArguments*/ undefined, - [visitNode(thisArg, visitor, isExpression), ...visitNodes(node.arguments, visitor, isExpression)] + [Debug.checkDefined(visitNode(thisArg, visitor, isExpression)), ...visitNodes(node.arguments, visitor, isExpression)] ); } return factory.updateCallExpression( node, - factory.createPropertyAccessExpression(visitNode(target, visitor), "call"), + factory.createPropertyAccessExpression(Debug.checkDefined(visitNode(target, visitor, isExpression)), "call"), /*typeArguments*/ undefined, - [visitNode(thisArg, visitor, isExpression), ...visitNodes(node.arguments, visitor, isExpression)] + [Debug.checkDefined(visitNode(thisArg, visitor, isExpression)), ...visitNodes(node.arguments, visitor, isExpression)] ); } @@ -872,7 +872,7 @@ namespace ts { // converts `super.f(...)` into `Reflect.get(_baseTemp, "f", _classTemp).call(_classTemp, ...)` const invocation = factory.createFunctionCallCall( - visitNode(node.expression, visitor, isExpression), + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), currentClassLexicalEnvironment.classConstructor, visitNodes(node.arguments, visitor, isExpression) ); @@ -892,12 +892,12 @@ namespace ts { return factory.updateTaggedTemplateExpression( node, factory.createCallExpression( - factory.createPropertyAccessExpression(visitNode(target, visitor), "bind"), + factory.createPropertyAccessExpression(Debug.checkDefined(visitNode(target, visitor, isExpression)), "bind"), /*typeArguments*/ undefined, - [visitNode(thisArg, visitor, isExpression)] + [Debug.checkDefined(visitNode(thisArg, visitor, isExpression))] ), /*typeArguments*/ undefined, - visitNode(node.template, visitor, isTemplateLiteral) + Debug.checkDefined(visitNode(node.template, visitor, isTemplateLiteral)) ); } if (shouldTransformSuperInStaticInitializers && @@ -907,7 +907,7 @@ namespace ts { // converts `` super.f`x` `` into `` Reflect.get(_baseTemp, "f", _classTemp).bind(_classTemp)`x` `` const invocation = factory.createFunctionBindCall( - visitNode(node.tag, visitor, isExpression), + Debug.checkDefined(visitNode(node.tag, visitor, isExpression)), currentClassLexicalEnvironment.classConstructor, [] ); @@ -917,7 +917,7 @@ namespace ts { node, invocation, /*typeArguments*/ undefined, - visitNode(node.template, visitor, isTemplateLiteral) + Debug.checkDefined(visitNode(node.template, visitor, isTemplateLiteral)) ); } return visitEachChild(node, visitor, context); @@ -954,9 +954,9 @@ namespace ts { pendingExpressions = undefined; node = factory.updateBinaryExpression( node, - visitNode(node.left, assignmentTargetVisitor), + Debug.checkDefined(visitNode(node.left, assignmentTargetVisitor, isExpression)), node.operatorToken, - visitNode(node.right, visitor) + Debug.checkDefined(visitNode(node.right, visitor, isExpression)) ); const expr = some(pendingExpressions) ? factory.inlineExpressions(compact([...pendingExpressions, node])) : @@ -993,7 +993,7 @@ namespace ts { node, visitInvalidSuperProperty(node.left), node.operatorToken, - visitNode(node.right, visitor, isExpression)); + Debug.checkDefined(visitNode(node.right, visitor, isExpression))); } if (classConstructor && superClassReference) { let setterName = @@ -1066,8 +1066,8 @@ namespace ts { } function createPrivateIdentifierAssignment(info: PrivateIdentifierInfo, receiver: Expression, right: Expression, operator: AssignmentOperator): Expression { - receiver = visitNode(receiver, visitor, isExpression); - right = visitNode(right, visitor, isExpression); + receiver = Debug.checkDefined(visitNode(receiver, visitor, isExpression)); + right = Debug.checkDefined(visitNode(right, visitor, isExpression)); if (isCompoundAssignment(operator)) { const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); @@ -1152,7 +1152,7 @@ namespace ts { node, factory.createAssignment( temp, - visitNode(node.expression, visitor, isExpression) + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)) ), /*typeArguments*/ undefined ); @@ -1873,7 +1873,7 @@ namespace ts { factory.updateElementAccessExpression( node, factory.createVoidZero(), - visitNode(node.argumentExpression, visitor, isExpression)); + Debug.checkDefined(visitNode(node.argumentExpression, visitor, isExpression))); } function onEmitNode(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { @@ -2345,7 +2345,7 @@ namespace ts { // differently inside the function. if (isThisProperty(node) || isSuperProperty(node) || !isSimpleCopiableExpression(node.expression)) { receiver = factory.createTempVariable(hoistVariableDeclaration, /*reservedInNestedScopes*/ true); - getPendingExpressions().push(factory.createBinaryExpression(receiver, SyntaxKind.EqualsToken, visitNode(node.expression, visitor, isExpression))); + getPendingExpressions().push(factory.createBinaryExpression(receiver, SyntaxKind.EqualsToken, Debug.checkDefined(visitNode(node.expression, visitor, isExpression)))); } return factory.createAssignmentTargetWrapper( parameter, @@ -2398,7 +2398,7 @@ namespace ts { node, wrapped, node.operatorToken, - visitNode(node.right, visitor, isExpression) + Debug.checkDefined(visitNode(node.right, visitor, isExpression)) ); } else if (isSpreadElement(node)) { @@ -2452,16 +2452,16 @@ namespace ts { const initializer = getInitializerOfBindingOrAssignmentElement(node); return factory.updatePropertyAssignment( node, - visitNode(node.name, visitor, isPropertyName), + Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)), wrapped ? - initializer ? factory.createAssignment(wrapped, visitNode(initializer, visitor)) : wrapped : - visitNode(node.initializer, assignmentTargetVisitor, isExpression) + initializer ? factory.createAssignment(wrapped, Debug.checkDefined(visitNode(initializer, visitor, isExpression))) : wrapped : + Debug.checkDefined(visitNode(node.initializer, assignmentTargetVisitor, isExpression)) ); } if (isSpreadAssignment(node)) { return factory.updateSpreadAssignment( node, - wrapped || visitNode(node.expression, assignmentTargetVisitor, isExpression) + wrapped || Debug.checkDefined(visitNode(node.expression, assignmentTargetVisitor, isExpression)) ); } Debug.assert(wrapped === undefined, "Should not have generated a wrapped target"); diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index e6ca856ec918d..25be6ea75f618 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -844,7 +844,7 @@ namespace ts { // And lastly, we need to get the final form of all those indetermine import declarations from before and add them to the output list // (and remove them from the set to examine for outter declarations) - return visitNodes(statements, visitLateVisibilityMarkedStatements); + return visitNodes(statements, visitLateVisibilityMarkedStatements, isStatement); function visitLateVisibilityMarkedStatements(statement: Statement) { if (isLateVisibilityPaintedStatement(statement)) { @@ -1038,7 +1038,7 @@ namespace ts { input, ensureModifiers(input), updateParamsList(input, input.parameters), - visitNode(input.type, visitDeclarationSubtree) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) + visitNode(input.type, visitDeclarationSubtree, isTypeNode) || factory.createKeywordTypeNode(SyntaxKind.AnyKeyword) )); } case SyntaxKind.VariableDeclaration: { @@ -1072,10 +1072,10 @@ namespace ts { return cleanup(factory.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType)); } case SyntaxKind.FunctionType: { - return cleanup(factory.updateFunctionTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); + return cleanup(factory.updateFunctionTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration), updateParamsList(input, input.parameters), Debug.checkDefined(visitNode(input.type, visitDeclarationSubtree, isTypeNode)))); } case SyntaxKind.ConstructorType: { - return cleanup(factory.updateConstructorTypeNode(input, ensureModifiers(input), visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); + return cleanup(factory.updateConstructorTypeNode(input, ensureModifiers(input), visitNodes(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration), updateParamsList(input, input.parameters), Debug.checkDefined(visitNode(input.type, visitDeclarationSubtree, isTypeNode)))); } case SyntaxKind.ImportType: { if (!isLiteralImportTypeNode(input)) return cleanup(input); @@ -1229,7 +1229,7 @@ namespace ts { ensureModifiers(input), input.name, visitNodes(input.typeParameters, visitDeclarationSubtree, isTypeParameterDeclaration), - visitNode(input.type, visitDeclarationSubtree, isTypeNode) + Debug.checkDefined(visitNode(input.type, visitDeclarationSubtree, isTypeNode)) )); needsDeclare = previousNeedsDeclare; return clean; @@ -1355,7 +1355,7 @@ namespace ts { lateStatements = factory.createNodeArray([...lateStatements, createEmptyExports(factory)]); } else { - lateStatements = visitNodes(lateStatements, stripExportModifiers); + lateStatements = visitNodes(lateStatements, stripExportModifiers, isStatement); } } const body = factory.updateModuleBlock(inner, lateStatements); diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 530c01ff8569c..99fdc53a45013 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -47,7 +47,7 @@ namespace ts { value = node.right; } else { - return visitNode(value, visitor, isExpression); + return Debug.checkDefined(visitNode(value, visitor, isExpression)); } } } @@ -117,7 +117,7 @@ namespace ts { const expression = createAssignmentCallback ? createAssignmentCallback(target as Identifier, value, location) : setTextRange( - context.factory.createAssignment(visitNode(target as Expression, visitor, isExpression), value), + context.factory.createAssignment(Debug.checkDefined(visitNode(target as Expression, visitor, isExpression)), value), location ); expression.original = original; @@ -200,7 +200,7 @@ namespace ts { bindingOrAssignmentElementContainsNonLiteralComputedName(node))) { // If the right-hand value of the assignment is also an assignment target then // we need to cache the right-hand value. - initializer = ensureIdentifier(flattenContext, visitNode(initializer, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, initializer); + initializer = ensureIdentifier(flattenContext, Debug.checkDefined(visitNode(initializer, flattenContext.visitor, isExpression)), /*reuseIdentifierExpressions*/ false, initializer); node = context.factory.updateVariableDeclaration(node, node.name, /*exclamationToken*/ undefined, /*type*/ undefined, initializer); } } @@ -476,7 +476,7 @@ namespace ts { */ function createDestructuringPropertyAccess(flattenContext: FlattenContext, value: Expression, propertyName: PropertyName): LeftHandSideExpression { if (isComputedPropertyName(propertyName)) { - const argumentExpression = ensureIdentifier(flattenContext, visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName); + const argumentExpression = ensureIdentifier(flattenContext, Debug.checkDefined(visitNode(propertyName.expression, flattenContext.visitor, isExpression)), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName); return flattenContext.context.factory.createElementAccessExpression(value, argumentExpression); } else if (isStringOrNumericLiteralLike(propertyName)) { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index d5bb4c1d0f643..ac034d58826f2 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -610,7 +610,7 @@ namespace ts { factory.createPropertyAssignment( factory.createIdentifier("value"), node.expression - ? visitNode(node.expression, visitor, isExpression) + ? Debug.checkDefined(visitNode(node.expression, visitor, isExpression)) : factory.createVoidZero() ) ] @@ -844,7 +844,7 @@ namespace ts { outer, /*typeArguments*/ undefined, extendsClauseElement - ? [visitNode(extendsClauseElement.expression, visitor, isExpression)] + ? [Debug.checkDefined(visitNode(extendsClauseElement.expression, visitor, isExpression))] : [] ) ); @@ -1354,7 +1354,7 @@ namespace ts { factory.createExpressionStatement( factory.createAssignment( factory.getGeneratedNameForNode(parameter), - visitNode(initializer, visitor, isExpression) + Debug.checkDefined(visitNode(initializer, visitor, isExpression)) ) ), EmitFlags.CustomPrologue @@ -1374,7 +1374,7 @@ namespace ts { * @param initializer The initializer for the parameter. */ function insertDefaultValueAssignmentForInitializer(statements: Statement[], parameter: ParameterDeclaration, name: Identifier, initializer: Expression): void { - initializer = visitNode(initializer, visitor, isExpression); + initializer = Debug.checkDefined(visitNode(initializer, visitor, isExpression)); const statement = factory.createIfStatement( factory.createTypeCheck(factory.cloneNode(name), "undefined"), setEmitFlags( @@ -2105,9 +2105,9 @@ namespace ts { if (node.operatorToken.kind === SyntaxKind.CommaToken) { return factory.updateBinaryExpression( node, - visitNode(node.left, visitorWithUnusedExpressionResult, isExpression), + Debug.checkDefined(visitNode(node.left, visitorWithUnusedExpressionResult, isExpression)), node.operatorToken, - visitNode(node.right, expressionResultIsUnused ? visitorWithUnusedExpressionResult : visitor, isExpression) + Debug.checkDefined(visitNode(node.right, expressionResultIsUnused ? visitorWithUnusedExpressionResult : visitor, isExpression)) ); } return visitEachChild(node, visitor, context); @@ -2160,7 +2160,7 @@ namespace ts { ); } else { - assignment = factory.createBinaryExpression(decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression)); + assignment = factory.createBinaryExpression(decl.name, SyntaxKind.EqualsToken, Debug.checkDefined(visitNode(decl.initializer, visitor, isExpression))); setTextRange(assignment, decl); } @@ -2357,7 +2357,7 @@ namespace ts { const statement = unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel); return isIterationStatement(statement, /*lookInLabeledStatements*/ false) ? visitIterationStatement(statement, /*outermostLabeledStatement*/ node) - : factory.restoreEnclosingLabel(visitNode(statement, visitor, isStatement, factory.liftToBlock), node, convertedLoopState && resetLabel); + : factory.restoreEnclosingLabel(Debug.checkDefined(visitNode(statement, visitor, isStatement, factory.liftToBlock)), node, convertedLoopState && resetLabel); } function visitIterationStatement(node: IterationStatement, outermostLabeledStatement: LabeledStatement) { @@ -2403,7 +2403,7 @@ namespace ts { visitNode(node.initializer, visitorWithUnusedExpressionResult, isForInitializer), visitNode(node.condition, visitor, isExpression), visitNode(node.incrementor, visitorWithUnusedExpressionResult, isExpression), - visitNode(node.statement, visitor, isStatement, factory.liftToBlock) + Debug.checkDefined(visitNode(node.statement, visitor, isStatement, factory.liftToBlock)) ); } @@ -2494,7 +2494,7 @@ namespace ts { } else { setTextRangeEnd(assignment, initializer.end); - statements.push(setTextRange(factory.createExpressionStatement(visitNode(assignment, visitor, isExpression)), moveRangeEnd(initializer, -1))); + statements.push(setTextRange(factory.createExpressionStatement(Debug.checkDefined(visitNode(assignment, visitor, isExpression))), moveRangeEnd(initializer, -1))); } } @@ -2878,7 +2878,7 @@ namespace ts { } } else { - const clone = convertIterationStatementCore(node, initializerFunction, visitNode(node.statement, visitor, isStatement, factory.liftToBlock)); + const clone = convertIterationStatementCore(node, initializerFunction, Debug.checkDefined(visitNode(node.statement, visitor, isStatement, factory.liftToBlock))); loop = factory.restoreEnclosingLabel(clone, outermostLabeledStatement, convertedLoopState && resetLabel); } @@ -2913,16 +2913,16 @@ namespace ts { return factory.updateForOfStatement( node, /*awaitModifier*/ undefined, - visitNode(node.initializer, visitor, isForInitializer), - visitNode(node.expression, visitor, isExpression), + Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)), + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), convertedLoopBody); } function convertForInStatement(node: ForInStatement, convertedLoopBody: Statement) { return factory.updateForInStatement( node, - visitNode(node.initializer, visitor, isForInitializer), - visitNode(node.expression, visitor, isExpression), + Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)), + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), convertedLoopBody); } @@ -2930,13 +2930,13 @@ namespace ts { return factory.updateDoStatement( node, convertedLoopBody, - visitNode(node.expression, visitor, isExpression)); + Debug.checkDefined(visitNode(node.expression, visitor, isExpression))); } function convertWhileStatement(node: WhileStatement, convertedLoopBody: Statement) { return factory.updateWhileStatement( node, - visitNode(node.expression, visitor, isExpression), + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), convertedLoopBody); } @@ -3142,11 +3142,11 @@ namespace ts { /*typeParameters*/ undefined, /*parameters*/ undefined, /*type*/ undefined, - visitNode( + Debug.checkDefined(visitNode( factory.createBlock(statements, /*multiLine*/ true), visitor, isBlock - ) + )) ), emitFlags ) @@ -3216,7 +3216,7 @@ namespace ts { if (node.incrementor) { statements.push(factory.createIfStatement( currentState.conditionVariable, - factory.createExpressionStatement(visitNode(node.incrementor, visitor, isExpression)), + factory.createExpressionStatement(Debug.checkDefined(visitNode(node.incrementor, visitor, isExpression))), factory.createExpressionStatement(factory.createAssignment(currentState.conditionVariable, factory.createTrue())) )); } @@ -3229,8 +3229,8 @@ namespace ts { if (shouldConvertConditionOfForStatement(node)) { statements.push(factory.createIfStatement( - factory.createPrefixUnaryExpression(SyntaxKind.ExclamationToken, visitNode(node.condition, visitor, isExpression)), - visitNode(factory.createBreakStatement(), visitor, isStatement) + factory.createPrefixUnaryExpression(SyntaxKind.ExclamationToken, Debug.checkDefined(visitNode(node.condition, visitor, isExpression))), + Debug.checkDefined(visitNode(factory.createBreakStatement(), visitor, isStatement)) )); } } @@ -3528,9 +3528,9 @@ namespace ts { createMemberAccessForPropertyName( factory, receiver, - visitNode(property.name, visitor, isPropertyName) + Debug.checkDefined(visitNode(property.name, visitor, isPropertyName)) ), - visitNode(property.initializer, visitor, isExpression) + Debug.checkDefined(visitNode(property.initializer, visitor, isExpression)) ); setTextRange(expression, property); if (startsOnNewLine) { @@ -3551,7 +3551,7 @@ namespace ts { createMemberAccessForPropertyName( factory, receiver, - visitNode(property.name, visitor, isPropertyName) + Debug.checkDefined(visitNode(property.name, visitor, isPropertyName)) ), factory.cloneNode(property.name) ); @@ -3574,7 +3574,7 @@ namespace ts { createMemberAccessForPropertyName( factory, receiver, - visitNode(method.name, visitor, isPropertyName) + Debug.checkDefined(visitNode(method.name, visitor, isPropertyName)) ), transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container) ); @@ -3725,7 +3725,7 @@ namespace ts { return factory.updateCallExpression( node, - visitNode(node.expression, callExpressionVisitor, isExpression), + Debug.checkDefined(visitNode(node.expression, callExpressionVisitor, isExpression)), /*typeArguments*/ undefined, visitNodes(node.arguments, visitor, isExpression) ); @@ -3923,8 +3923,8 @@ namespace ts { // _super.prototype.m.apply(this, a.concat([b])) resultingCall = factory.createFunctionApplyCall( - visitNode(target, callExpressionVisitor, isExpression), - node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : visitNode(thisArg, visitor, isExpression), + Debug.checkDefined(visitNode(target, callExpressionVisitor, isExpression)), + node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : Debug.checkDefined(visitNode(thisArg, visitor, isExpression)), transformAndSpreadElements(node.arguments, /*isArgumentList*/ true, /*multiLine*/ false, /*hasTrailingComma*/ false) ); } @@ -3940,8 +3940,8 @@ namespace ts { // _super.prototype.m.call(this, a) resultingCall = setTextRange( factory.createFunctionCallCall( - visitNode(target, callExpressionVisitor, isExpression), - node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : visitNode(thisArg, visitor, isExpression), + Debug.checkDefined(visitNode(target, callExpressionVisitor, isExpression)), + node.expression.kind === SyntaxKind.SuperKeyword ? thisArg : Debug.checkDefined(visitNode(thisArg, visitor, isExpression)), visitNodes(node.arguments, visitor, isExpression) ), node @@ -3981,7 +3981,7 @@ namespace ts { const { target, thisArg } = factory.createCallBinding(factory.createPropertyAccessExpression(node.expression, "bind"), hoistVariableDeclaration); return factory.createNewExpression( factory.createFunctionApplyCall( - visitNode(target, visitor, isExpression), + Debug.checkDefined(visitNode(target, visitor, isExpression)), thisArg, transformAndSpreadElements(factory.createNodeArray([factory.createVoidZero(), ...node.arguments!]), /*isArgumentList*/ true, /*multiLine*/ false, /*hasTrailingComma*/ false) ), diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 98f389cde9b1f..9e1fc97bec1f1 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -223,8 +223,8 @@ namespace ts { node, isVariableDeclarationListWithCollidingName(node.initializer) ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)! - : visitNode(node.initializer, visitor, isForInitializer), - visitNode(node.expression, visitor, isExpression), + : Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)), + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), visitIterationBody(node.statement, asyncBodyVisitor, context) ); } @@ -235,8 +235,8 @@ namespace ts { visitNode(node.awaitModifier, visitor, isAwaitKeyword), isVariableDeclarationListWithCollidingName(node.initializer) ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true)! - : visitNode(node.initializer, visitor, isForInitializer), - visitNode(node.expression, visitor, isExpression), + : Debug.checkDefined(visitNode(node.initializer, visitor, isForInitializer)), + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), visitIterationBody(node.statement, asyncBodyVisitor, context) ); } @@ -552,7 +552,7 @@ namespace ts { return factory.updateBlock(body, visitNodes(body.statements, asyncBodyVisitor, isStatement, start)); } else { - return factory.converters.convertToFunctionBlock(visitNode(body, asyncBodyVisitor, isConciseBody)); + return factory.converters.convertToFunctionBlock(Debug.checkDefined(visitNode(body, asyncBodyVisitor, isConciseBody))); } } diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 9bbc8fdab75c8..255ae5bdcef23 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -717,7 +717,7 @@ namespace ts { break; default: - target = visitNode(left, visitor, isExpression); + target = Debug.checkDefined(visitNode(left, visitor, isExpression)); break; } @@ -730,7 +730,7 @@ namespace ts { factory.createBinaryExpression( cacheExpression(target), getNonAssignmentOperatorForCompoundAssignment(operator), - visitNode(right, visitor, isExpression) + Debug.checkDefined(visitNode(right, visitor, isExpression)) ), node ) @@ -739,7 +739,7 @@ namespace ts { ); } else { - return factory.updateBinaryExpression(node, target, node.operatorToken, visitNode(right, visitor, isExpression)); + return factory.updateBinaryExpression(node, target, node.operatorToken, Debug.checkDefined(visitNode(right, visitor, isExpression))); } } @@ -765,9 +765,9 @@ namespace ts { // _a + %sent% + c() return factory.updateBinaryExpression(node, - cacheExpression(visitNode(node.left, visitor, isExpression)), + cacheExpression(Debug.checkDefined(visitNode(node.left, visitor, isExpression))), node.operatorToken, - visitNode(node.right, visitor, isExpression)); + Debug.checkDefined(visitNode(node.right, visitor, isExpression))); } return visitEachChild(node, visitor, context); @@ -804,7 +804,7 @@ namespace ts { pendingExpressions = []; } - pendingExpressions.push(visitNode(node, visitor, isExpression)); + pendingExpressions.push(Debug.checkDefined(visitNode(node, visitor, isExpression))); } } } @@ -826,7 +826,7 @@ namespace ts { emitWorker(OpCode.Statement, [factory.createExpressionStatement(factory.inlineExpressions(pendingExpressions))]); pendingExpressions = []; } - pendingExpressions.push(visitNode(elem, visitor, isExpression)); + pendingExpressions.push(Debug.checkDefined(visitNode(elem, visitor, isExpression))); } } return factory.inlineExpressions(pendingExpressions); @@ -870,7 +870,7 @@ namespace ts { const resultLabel = defineLabel(); const resultLocal = declareLocal(); - emitAssignment(resultLocal, visitNode(node.left, visitor, isExpression), /*location*/ node.left); + emitAssignment(resultLocal, Debug.checkDefined(visitNode(node.left, visitor, isExpression)), /*location*/ node.left); if (node.operatorToken.kind === SyntaxKind.AmpersandAmpersandToken) { // Logical `&&` shortcuts when the left-hand operand is falsey. emitBreakWhenFalse(resultLabel, resultLocal, /*location*/ node.left); @@ -880,7 +880,7 @@ namespace ts { emitBreakWhenTrue(resultLabel, resultLocal, /*location*/ node.left); } - emitAssignment(resultLocal, visitNode(node.right, visitor, isExpression), /*location*/ node.right); + emitAssignment(resultLocal, Debug.checkDefined(visitNode(node.right, visitor, isExpression)), /*location*/ node.right); markLabel(resultLabel); return resultLocal; } @@ -913,11 +913,11 @@ namespace ts { const whenFalseLabel = defineLabel(); const resultLabel = defineLabel(); const resultLocal = declareLocal(); - emitBreakWhenFalse(whenFalseLabel, visitNode(node.condition, visitor, isExpression), /*location*/ node.condition); - emitAssignment(resultLocal, visitNode(node.whenTrue, visitor, isExpression), /*location*/ node.whenTrue); + emitBreakWhenFalse(whenFalseLabel, Debug.checkDefined(visitNode(node.condition, visitor, isExpression)), /*location*/ node.condition); + emitAssignment(resultLocal, Debug.checkDefined(visitNode(node.whenTrue, visitor, isExpression)), /*location*/ node.whenTrue); emitBreak(resultLabel); markLabel(whenFalseLabel); - emitAssignment(resultLocal, visitNode(node.whenFalse, visitor, isExpression), /*location*/ node.whenFalse); + emitAssignment(resultLocal, Debug.checkDefined(visitNode(node.whenFalse, visitor, isExpression)), /*location*/ node.whenFalse); markLabel(resultLabel); return resultLocal; } @@ -1030,7 +1030,7 @@ namespace ts { expressions = []; } - expressions.push(visitNode(element, visitor, isExpression)); + expressions.push(Debug.checkDefined(visitNode(element, visitor, isExpression))); return expressions; } } @@ -1108,7 +1108,7 @@ namespace ts { return factory.updateElementAccessExpression(node, cacheExpression(Debug.checkDefined(visitNode(node.expression, visitor, isLeftHandSideExpression))), - visitNode(node.argumentExpression, visitor, isExpression)); + Debug.checkDefined(visitNode(node.argumentExpression, visitor, isExpression))); } return visitEachChild(node, visitor, context); @@ -1161,7 +1161,7 @@ namespace ts { setTextRange( factory.createNewExpression( factory.createFunctionApplyCall( - cacheExpression(visitNode(target, visitor, isExpression)), + cacheExpression(Debug.checkDefined(visitNode(target, visitor, isExpression))), thisArg, visitElements( node.arguments!, @@ -1290,7 +1290,7 @@ namespace ts { return setSourceMapRange( factory.createAssignment( setSourceMapRange(factory.cloneNode(node.name) as Identifier, node.name), - visitNode(node.initializer, visitor, isExpression) + Debug.checkDefined(visitNode(node.initializer, visitor, isExpression)) ), node ); @@ -1315,7 +1315,7 @@ namespace ts { if (containsYield(node.thenStatement) || containsYield(node.elseStatement)) { const endLabel = defineLabel(); const elseLabel = node.elseStatement ? defineLabel() : undefined; - emitBreakWhenFalse(node.elseStatement ? elseLabel! : endLabel, visitNode(node.expression, visitor, isExpression), /*location*/ node.expression); + emitBreakWhenFalse(node.elseStatement ? elseLabel! : endLabel, Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), /*location*/ node.expression); transformAndEmitEmbeddedStatement(node.thenStatement); if (node.elseStatement) { emitBreak(endLabel); @@ -1356,7 +1356,7 @@ namespace ts { markLabel(loopLabel); transformAndEmitEmbeddedStatement(node.statement); markLabel(conditionLabel); - emitBreakWhenTrue(loopLabel, visitNode(node.expression, visitor, isExpression)); + emitBreakWhenTrue(loopLabel, Debug.checkDefined(visitNode(node.expression, visitor, isExpression))); endLoopBlock(); } else { @@ -1395,7 +1395,7 @@ namespace ts { const loopLabel = defineLabel(); const endLabel = beginLoopBlock(loopLabel); markLabel(loopLabel); - emitBreakWhenFalse(endLabel, visitNode(node.expression, visitor, isExpression)); + emitBreakWhenFalse(endLabel, Debug.checkDefined(visitNode(node.expression, visitor, isExpression))); transformAndEmitEmbeddedStatement(node.statement); emitBreak(loopLabel); endLoopBlock(); @@ -1449,7 +1449,7 @@ namespace ts { emitStatement( setTextRange( factory.createExpressionStatement( - visitNode(initializer, visitor, isExpression) + Debug.checkDefined(visitNode(initializer, visitor, isExpression)) ), initializer ) @@ -1459,7 +1459,7 @@ namespace ts { markLabel(conditionLabel); if (node.condition) { - emitBreakWhenFalse(endLabel, visitNode(node.condition, visitor, isExpression)); + emitBreakWhenFalse(endLabel, Debug.checkDefined(visitNode(node.condition, visitor, isExpression))); } transformAndEmitEmbeddedStatement(node.statement); @@ -1469,7 +1469,7 @@ namespace ts { emitStatement( setTextRange( factory.createExpressionStatement( - visitNode(node.incrementor, visitor, isExpression) + Debug.checkDefined(visitNode(node.incrementor, visitor, isExpression)) ), node.incrementor ) @@ -1549,7 +1549,7 @@ namespace ts { emitStatement( factory.createForInStatement( key, - visitNode(node.expression, visitor, isExpression), + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), factory.createExpressionStatement( factory.createCallExpression( factory.createPropertyAccessExpression(keysArray, "push"), @@ -1578,7 +1578,7 @@ namespace ts { variable = factory.cloneNode(initializer.declarations[0].name) as Identifier; } else { - variable = visitNode(initializer, visitor, isExpression); + variable = Debug.checkDefined(visitNode(initializer, visitor, isExpression)); Debug.assert(isLeftHandSideExpression(variable)); } @@ -1622,8 +1622,8 @@ namespace ts { node = factory.updateForInStatement(node, initializer.declarations[0].name as Identifier, - visitNode(node.expression, visitor, isExpression), - visitNode(node.statement, visitor, isStatement, factory.liftToBlock) + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), + Debug.checkDefined(visitNode(node.statement, visitor, isStatement, factory.liftToBlock)) ); } else { @@ -1706,7 +1706,7 @@ namespace ts { // .with (x) // /*body*/ // .endwith - beginWithBlock(cacheExpression(visitNode(node.expression, visitor, isExpression))); + beginWithBlock(cacheExpression(Debug.checkDefined(visitNode(node.expression, visitor, isExpression)))); transformAndEmitEmbeddedStatement(node.statement); endWithBlock(); } @@ -1753,7 +1753,7 @@ namespace ts { const numClauses = caseBlock.clauses.length; const endLabel = beginSwitchBlock(); - const expression = cacheExpression(visitNode(node.expression, visitor, isExpression)); + const expression = cacheExpression(Debug.checkDefined(visitNode(node.expression, visitor, isExpression))); // Create labels for each clause and find the index of the first default clause. const clauseLabels: Label[] = []; @@ -1782,7 +1782,7 @@ namespace ts { pendingClauses.push( factory.createCaseClause( - visitNode(clause.expression, visitor, isExpression), + Debug.checkDefined(visitNode(clause.expression, visitor, isExpression)), [ createInlineBreak(clauseLabels[i], /*location*/ clause.expression) ] @@ -1876,7 +1876,7 @@ namespace ts { function transformAndEmitThrowStatement(node: ThrowStatement): void { // TODO(rbuckton): `expression` should be required on `throw`. emitThrow( - visitNode(node.expression ?? factory.createVoidZero(), visitor, isExpression), + Debug.checkDefined(visitNode(node.expression ?? factory.createVoidZero(), visitor, isExpression)), /*location*/ node ); } @@ -2509,7 +2509,7 @@ namespace ts { * * @param node A statement. */ - function emitStatement(node: Statement): void { + function emitStatement(node: Statement | undefined): void { if (node) { emitWorker(OpCode.Statement, [node]); } diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index a330b09668ab1..f80189476fd70 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -349,7 +349,7 @@ namespace ts { } function transformJsxSpreadAttributeToSpreadAssignment(node: JsxSpreadAttribute) { - return factory.createSpreadAssignment(visitNode(node.expression, visitor, isExpression)); + return factory.createSpreadAssignment(Debug.checkDefined(visitNode(node.expression, visitor, isExpression))); } function transformJsxAttributesToObjectProps(attrs: readonly(JsxSpreadAttribute | JsxAttribute)[], children?: PropertyAssignment) { @@ -415,7 +415,7 @@ namespace ts { if (node.expression === undefined) { return factory.createTrue(); } - return visitNode(node.expression, visitor, isExpression); + return Debug.checkDefined(visitNode(node.expression, visitor, isExpression)); } if (isJsxElement(node)) { return visitJsxElement(node, /*isChild*/ false); diff --git a/src/compiler/transformers/legacyDecorators.ts b/src/compiler/transformers/legacyDecorators.ts index 438e25bc858b0..2ccf17a301a26 100644 --- a/src/compiler/transformers/legacyDecorators.ts +++ b/src/compiler/transformers/legacyDecorators.ts @@ -322,7 +322,7 @@ namespace ts { node, visitNodes(node.modifiers, modifierVisitor, isModifier), node.asteriskToken, - visitNode(node.name, visitor, isPropertyName), + Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)), /*questionToken*/ undefined, /*typeParameters*/ undefined, visitNodes(node.parameters, visitor, isParameter), @@ -335,7 +335,7 @@ namespace ts { return finishClassElement(factory.updateGetAccessorDeclaration( node, visitNodes(node.modifiers, modifierVisitor, isModifier), - visitNode(node.name, visitor, isPropertyName), + Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)), visitNodes(node.parameters, visitor, isParameter), /*type*/ undefined, visitNode(node.body, visitor, isBlock) @@ -346,7 +346,7 @@ namespace ts { return finishClassElement(factory.updateSetAccessorDeclaration( node, visitNodes(node.modifiers, modifierVisitor, isModifier), - visitNode(node.name, visitor, isPropertyName), + Debug.checkDefined(visitNode(node.name, visitor, isPropertyName)), visitNodes(node.parameters, visitor, isParameter), visitNode(node.body, visitor, isBlock) ), node); diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 06d17e11c67e5..b9d4ddcb823b8 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1207,10 +1207,10 @@ namespace ts { if (original && hasAssociatedEndOfDeclarationMarker(original)) { // Defer exports until we encounter an EndOfDeclarationMarker node const id = getOriginalNodeId(node); - deferredExports[id] = appendExportStatement(deferredExports[id], factory.createIdentifier("default"), visitNode(node.expression, visitor), /*location*/ node, /*allowComments*/ true); + deferredExports[id] = appendExportStatement(deferredExports[id], factory.createIdentifier("default"), visitNode(node.expression, visitor, isExpression), /*location*/ node, /*allowComments*/ true); } else { - statements = appendExportStatement(statements, factory.createIdentifier("default"), visitNode(node.expression, visitor), /*location*/ node, /*allowComments*/ true); + statements = appendExportStatement(statements, factory.createIdentifier("default"), visitNode(node.expression, visitor, isExpression), /*location*/ node, /*allowComments*/ true); } return singleOrMany(statements); @@ -1402,7 +1402,7 @@ namespace ts { function transformInitializedVariable(node: InitializedVariableDeclaration): Expression { if (isBindingPattern(node.name)) { return flattenDestructuringAssignment( - visitNode(node, visitor), + visitNode(node, visitor, isInitializedVariable), /*visitor*/ undefined, context, FlattenLevel.All, @@ -1419,7 +1419,7 @@ namespace ts { ), /*location*/ node.name ), - node.initializer ? visitNode(node.initializer, visitor) : factory.createVoidZero() + node.initializer ? visitNode(node.initializer, visitor, isExpression) : factory.createVoidZero() ); } } diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 8132686581938..5f09e6f7847fa 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -1356,7 +1356,7 @@ namespace ts { return factory.updateLabeledStatement( node, node.label, - visitNode(node.statement, topLevelNestedVisitor, isStatement, factory.liftToBlock) + Debug.checkDefined(visitNode(node.statement, topLevelNestedVisitor, isStatement, factory.liftToBlock)) ); } @@ -1369,7 +1369,7 @@ namespace ts { return factory.updateWithStatement( node, visitNode(node.expression, visitor, isExpression), - visitNode(node.statement, topLevelNestedVisitor, isStatement, factory.liftToBlock) + Debug.checkDefined(visitNode(node.statement, topLevelNestedVisitor, isStatement, factory.liftToBlock)) ); } @@ -1382,7 +1382,7 @@ namespace ts { return factory.updateSwitchStatement( node, visitNode(node.expression, visitor, isExpression), - visitNode(node.caseBlock, topLevelNestedVisitor, isCaseBlock) + Debug.checkDefined(visitNode(node.caseBlock, topLevelNestedVisitor, isCaseBlock)) ); } @@ -1447,7 +1447,7 @@ namespace ts { node = factory.updateCatchClause( node, node.variableDeclaration, - visitNode(node.block, topLevelNestedVisitor, isBlock) + Debug.checkDefined(visitNode(node.block, topLevelNestedVisitor, isBlock)) ); enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer; diff --git a/src/compiler/transformers/taggedTemplate.ts b/src/compiler/transformers/taggedTemplate.ts index ce9669566e7a8..dd82d74766d97 100644 --- a/src/compiler/transformers/taggedTemplate.ts +++ b/src/compiler/transformers/taggedTemplate.ts @@ -39,7 +39,7 @@ namespace ts { for (const templateSpan of template.templateSpans) { cookedStrings.push(createTemplateCooked(templateSpan.literal)); rawStrings.push(getRawLiteral(templateSpan.literal, currentSourceFile)); - templateArguments.push(visitNode(templateSpan.expression, visitor, isExpression)); + templateArguments.push(Debug.checkDefined(visitNode(templateSpan.expression, visitor, isExpression))); } } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 3484fbe3be097..57fad6e5a78bf 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -978,7 +978,7 @@ namespace ts { return factory.updateComputedPropertyName(name, factory.createAssignment(generatedName, expression)); } } - return visitNode(name, visitor, isPropertyName); + return Debug.checkDefined(visitNode(name, visitor, isPropertyName)); } /** @@ -1051,7 +1051,7 @@ namespace ts { visitPropertyNameOfClassElement(node), /*questionOrExclamationToken*/ undefined, /*type*/ undefined, - visitNode(node.initializer, visitor) + visitNode(node.initializer, visitor, isExpression) ); } @@ -1366,7 +1366,7 @@ namespace ts { return setTextRange( factory.createAssignment( getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), - visitNode(node.initializer, visitor, isExpression) + Debug.checkDefined(visitNode(node.initializer, visitor, isExpression)) ), /*location*/ node ); @@ -1376,7 +1376,7 @@ namespace ts { function visitVariableDeclaration(node: VariableDeclaration) { const updated = factory.updateVariableDeclaration( node, - visitNode(node.name, visitor, isBindingName), + Debug.checkDefined(visitNode(node.name, visitor, isBindingName)), /*exclamationToken*/ undefined, /*type*/ undefined, visitNode(node.initializer, visitor, isExpression)); @@ -1438,7 +1438,7 @@ namespace ts { function visitCallExpression(node: CallExpression) { return factory.updateCallExpression( node, - visitNode(node.expression, visitor, isExpression), + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), /*typeArguments*/ undefined, visitNodes(node.arguments, visitor, isExpression)); } @@ -1446,7 +1446,7 @@ namespace ts { function visitNewExpression(node: NewExpression) { return factory.updateNewExpression( node, - visitNode(node.expression, visitor, isExpression), + Debug.checkDefined(visitNode(node.expression, visitor, isExpression)), /*typeArguments*/ undefined, visitNodes(node.arguments, visitor, isExpression)); } @@ -1454,25 +1454,25 @@ namespace ts { function visitTaggedTemplateExpression(node: TaggedTemplateExpression) { return factory.updateTaggedTemplateExpression( node, - visitNode(node.tag, visitor, isExpression), + Debug.checkDefined(visitNode(node.tag, visitor, isExpression)), /*typeArguments*/ undefined, - visitNode(node.template, visitor, isTemplateLiteral)); + Debug.checkDefined(visitNode(node.template, visitor, isTemplateLiteral))); } function visitJsxSelfClosingElement(node: JsxSelfClosingElement) { return factory.updateJsxSelfClosingElement( node, - visitNode(node.tagName, visitor, isJsxTagNameExpression), + Debug.checkDefined(visitNode(node.tagName, visitor, isJsxTagNameExpression)), /*typeArguments*/ undefined, - visitNode(node.attributes, visitor, isJsxAttributes)); + Debug.checkDefined(visitNode(node.attributes, visitor, isJsxAttributes))); } function visitJsxJsxOpeningElement(node: JsxOpeningElement) { return factory.updateJsxOpeningElement( node, - visitNode(node.tagName, visitor, isJsxTagNameExpression), + Debug.checkDefined(visitNode(node.tagName, visitor, isJsxTagNameExpression)), /*typeArguments*/ undefined, - visitNode(node.attributes, visitor, isJsxAttributes)); + Debug.checkDefined(visitNode(node.attributes, visitor, isJsxAttributes))); } /** @@ -1653,7 +1653,7 @@ namespace ts { else { enableSubstitutionForNonQualifiedEnumMembers(); if (member.initializer) { - return visitNode(member.initializer, visitor, isExpression); + return Debug.checkDefined(visitNode(member.initializer, visitor, isExpression)); } else { return factory.createVoidZero(); @@ -2103,7 +2103,7 @@ namespace ts { } function visitNamespaceExports(node: NamespaceExport): VisitResult { - return factory.updateNamespaceExport(node, visitNode(node.name, visitor, isIdentifier)); + return factory.updateNamespaceExport(node, Debug.checkDefined(visitNode(node.name, visitor, isIdentifier))); } function visitNamedExportBindings(node: NamedExportBindings, allowEmpty: boolean): VisitResult | undefined { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d18b744fe055b..a0bed9756bd95 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8550,60 +8550,55 @@ namespace ts { * A function that walks a node using the given visitor, lifting node arrays into single nodes, * returning an node which satisfies the test. * - * This type is complicated, but intends to encode the following behaviors: + * - If the input node is undefined, then the output is undefined. + * - If the visitor returns undefined, then the output is undefined. + * - If the output node is not undefined, then it will satisfy the test function. + * - In order to obtain a return type that is more specific than `Node`, a test + * function _must_ be provided, and that function must be a type predicate. * - * - If the input node is potentially undefined, the output is potentially undefined. - * - If the visitor can return undefined, the output is potentially undefined. - * - If the output node is not undefined, then it will satisfy the test. - * - * @see {visitNode} + * For the canonical implementation of this type, @see {visitNode}. */ export interface NodeVisitor { - // TODO(jakebailey): Was previously declared as an interface; I don't konw if changing it to a type is safe. Same for NodesVisitor. - // This form is nice, thuogh, because you can copy and paste the signature without changing the return `:` to `=>`. - // eslint-disable-next-line @typescript-eslint/prefer-function-type - < - TIn extends Node | undefined, - TVisited extends Node | undefined, - TAssert extends NonNullable, - TOut extends TIn extends undefined ? TAssert | undefined - : TVisited extends undefined ? TAssert | undefined - : TAssert, - >( + ( + node: TIn, + visitor: Visitor, TVisited> | undefined, + test: (node: Node) => node is TOut, + lift?: (node: readonly Node[]) => Node, + ): TOut | (TIn & undefined) | (TVisited & undefined); + ( node: TIn, visitor: Visitor, TVisited> | undefined, - test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), + test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node, - ): TOut; + ): Node | (TIn & undefined)| (TVisited & undefined); } /** * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. * - * This type is complicated, but intends to encode the following behaviors: + * - If the input node array is undefined, the output is undefined. + * - If the visitor can return undefined, the node it visits in the array will be reused. + * - If the output node array is not undefined, then its contents will satisfy the test. + * - In order to obtain a return type that is more specific than `NodeArray`, a test + * function _must_ be provided, and that function must be a type predicate. * - * - If the input node array is potentially undefined, the output is potentially undefined. - * - If the visitor can return undefined, the output may not be undefined; these nodes will be left in the output. - * - If the output node array is not undefined, then its contents will satisfy the test. - * - * @see {visitNodes} + * For the canonical implementation of this type, @see {visitNodes}. */ export interface NodesVisitor { - // eslint-disable-next-line @typescript-eslint/prefer-function-type - < - TIn extends Node, - TArray extends NodeArray | undefined, - TVisited extends Node | undefined, - TAssert extends NonNullable, - TOutArray extends TArray extends undefined ? NodeArray | undefined - : NodeArray, - >( - nodes: TArray, + | undefined, TVisited extends Node | undefined, TOut extends Node>( + nodes: TInArray, + visitor: Visitor | undefined, + test: (node: Node) => node is TOut, + start?: number, + count?: number, + ): NodeArray | (TInArray & undefined); + | undefined, TVisited extends Node | undefined>( + nodes: TInArray, visitor: Visitor | undefined, - test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), + test?: (node: Node) => boolean, start?: number, count?: number, - ): TOutArray; + ): NodeArray | (TInArray & undefined); } export interface Printer { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b89a94fa2727d..590aed844ce45 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5556,8 +5556,8 @@ namespace ts { return filter(node.declarations, isInitializedVariable); } - function isInitializedVariable(node: VariableDeclaration): node is InitializedVariableDeclaration { - return node.initializer !== undefined; + export function isInitializedVariable(node: Node): node is InitializedVariableDeclaration { + return isVariableDeclaration(node) && node.initializer !== undefined; } export function isWatchSet(options: CompilerOptions) { diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 04e0b68e841a7..37d4d8d9c8c93 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -7,22 +7,27 @@ namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - export function visitNode< - TIn extends Node | undefined, - TVisited extends Node | undefined, - TAssert extends NonNullable, - TOut extends TIn extends undefined ? TAssert | undefined - : TVisited extends undefined ? TAssert | undefined - : TAssert, - >( + export function visitNode( node: TIn, visitor: Visitor, TVisited> | undefined, - test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), + test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node, - ): TOut { + ): TOut | (TIn & undefined) | (TVisited & undefined); + export function visitNode( + node: TIn, + visitor: Visitor, TVisited> | undefined, + test?: (node: Node) => boolean, + lift?: (node: readonly Node[]) => Node, + ): Node | (TIn & undefined)| (TVisited & undefined); + export function visitNode( + node: TIn, + visitor: Visitor, TVisited> | undefined, + test?: (node: Node) => boolean, + lift?: (node: readonly Node[]) => Node, + ): Node | undefined { if (node === undefined) { // If the input type is undefined, then the output type can be undefined. - return node as Node | undefined as TOut; + return node; } const visited = visitor ? visitor(node) : node; @@ -32,7 +37,7 @@ namespace ts { // If the visited node is undefined, then the visitor must have returned undefined, // so the visitor must have been declared as able to return undefined, so TOut must be // potentially undefined. - return undefined as TOut; + return undefined; } else if (isArray(visited)) { visitedNode = (lift || extractSingleNode)(visited); @@ -42,7 +47,7 @@ namespace ts { } Debug.assertNode(visitedNode, test); - return visitedNode as TOut; + return visitedNode; } ((_: NodeVisitor) => {})(visitNode); // Check that visitNode is a NodeVisitor. @@ -56,23 +61,30 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - export function visitNodes< - TIn extends Node, - TArray extends NodeArray | undefined, - TVisited extends Node | undefined, - TAssert extends NonNullable, - TOutArray extends TArray extends undefined ? NodeArray | undefined - : NodeArray, - >( - nodes: TArray, + export function visitNodes | undefined, TVisited extends Node | undefined, TOut extends Node>( + nodes: TInArray, + visitor: Visitor | undefined, + test: (node: Node) => node is TOut, + start?: number, + count?: number, + ): NodeArray | (TInArray & undefined); + export function visitNodes | undefined, TVisited extends Node | undefined>( + nodes: TInArray, visitor: Visitor | undefined, - test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), + test?: (node: Node) => boolean, start?: number, count?: number, - ): TOutArray { + ): NodeArray | (TInArray & undefined); + export function visitNodes | undefined, TVisited extends Node | undefined>( + nodes: TInArray, + visitor: Visitor | undefined, + test?: (node: Node) => boolean, + start?: number, + count?: number, + ): NodeArray | undefined { if (nodes === undefined) { // If the input type is undefined, then the output type can be undefined. - return nodes as NodeArray | undefined as TOutArray; + return nodes; } // Ensure start and count have valid values @@ -104,35 +116,42 @@ namespace ts { // TODO(rbuckton): Remove dependency on `ts.factory` in favor of a provided factory. const updatedArray = factory.createNodeArray(updated, hasTrailingComma); setTextRangePosEnd(updatedArray, pos, end); - return updatedArray as TOutArray; + return updatedArray; } // If we are here, updated === nodes. This means that it's still a NodeArray, // and also that its contents passed the tests in visitArrayWorker, so has contents // of type TOut. - return nodes as NodeArray as TOutArray; + return nodes; } ((_: NodesVisitor) => {})(visitNodes); // Check that visitNode is a NodeVisitor. /* @internal */ - export function visitArray< - TIn extends Node, - TArray extends readonly TIn[] | undefined, - TVisited extends Node | undefined, - TAssert extends NonNullable, - TOut extends TArray extends undefined ? readonly TAssert[] | undefined - : readonly TAssert[], - >( - nodes: TArray, + export function visitArray( + nodes: TInArray, + visitor: Visitor | undefined, + test: (node: Node) => node is TOut, + start?: number, + count?: number, + ): readonly TOut[] | (TInArray & undefined); + export function visitArray( + nodes: TInArray, visitor: Visitor | undefined, - test?: (node: Node) => node is TAssert, + test?: (node: Node) => boolean, start?: number, count?: number, - ): TOut { + ): readonly Node[] | (TInArray & undefined); + export function visitArray( + nodes: TInArray, + visitor: Visitor | undefined, + test?: (node: Node) => boolean, + start?: number, + count?: number, + ): readonly Node[] | undefined { if (nodes === undefined) { // If the input type is undefined, then the output type can be undefined. - return nodes as readonly Node[] | undefined as TOut; + return nodes; } // Ensure start and count have valid values @@ -145,21 +164,31 @@ namespace ts { count = length - start; } - return visitArrayWorker(nodes, visitor, test, start, count) as TOut; + return visitArrayWorker(nodes, visitor, test, start, count); } /* @internal */ - function visitArrayWorker< - TIn extends Node, - TVisited extends Node | undefined, - TAssert extends NonNullable, - >( - nodes: readonly TIn[], + export function visitArrayWorker( + nodes: TInArray, visitor: Visitor | undefined, - test: ((node: Node) => node is TAssert) | ((node: Node) => boolean) | undefined, + test: (node: Node) => node is TOut, start: number, count: number, - ): readonly TAssert[] { + ): readonly TOut[]; + export function visitArrayWorker( + nodes: TInArray, + visitor: Visitor | undefined, + test: ((node: Node) => boolean) | undefined, + start: number, + count: number, + ): readonly Node[]; + export function visitArrayWorker( + nodes: TInArray, + visitor: Visitor | undefined, + test: ((node: Node) => boolean) | undefined, + start: number, + count: number, + ): readonly Node[] { let updated: Node[] | undefined; const length = nodes.length; @@ -180,21 +209,19 @@ namespace ts { if (visited) { if (isArray(visited)) { for (const visitedNode of visited) { - // void Debug.assertNode(visitedNode, test); updated.push(visitedNode); } } else { - // void Debug.assertNode(visited, test); updated.push(visited); } } } } - const result: readonly Node[] = updated ?? nodes; + const result = updated ?? nodes; Debug.assertEachNode(result, test); - return result as readonly TAssert[]; + return result; } /** @@ -442,20 +469,20 @@ namespace ts { [SyntaxKind.QualifiedName]: function visitEachChildOfQualifiedName(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateQualifiedName(node, - nodeVisitor(node.left, visitor, isEntityName), - nodeVisitor(node.right, visitor, isIdentifier)); + Debug.checkDefined(nodeVisitor(node.left, visitor, isEntityName)), + Debug.checkDefined(nodeVisitor(node.right, visitor, isIdentifier))); }, [SyntaxKind.ComputedPropertyName]: function visitEachChildOfComputedPropertyName(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateComputedPropertyName(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, // Signature elements [SyntaxKind.TypeParameter]: function visitEachChildOfTypeParameterDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTypeParameterDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.name, visitor, isIdentifier), + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)), nodeVisitor(node.constraint, visitor, isTypeNode), nodeVisitor(node.default, visitor, isTypeNode)); }, @@ -472,14 +499,14 @@ namespace ts { [SyntaxKind.Decorator]: function visitEachChildOfDecorator(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateDecorator(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, // Type elements [SyntaxKind.PropertySignature]: function visitEachChildOfPropertySignature(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updatePropertySignature(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.name, visitor, isPropertyName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), nodeVisitor(node.type, visitor, isTypeNode)); }, @@ -497,7 +524,7 @@ namespace ts { [SyntaxKind.MethodSignature]: function visitEachChildOfMethodSignature(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateMethodSignature(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.name, visitor, isPropertyName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, isParameter), @@ -508,7 +535,7 @@ namespace ts { return context.factory.updateMethodDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifierLike), nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken), - nodeVisitor(node.name, visitor, isPropertyName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), @@ -526,7 +553,7 @@ namespace ts { [SyntaxKind.GetAccessor]: function visitEachChildOfGetAccessorDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateGetAccessorDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifierLike), - nodeVisitor(node.name, visitor, isPropertyName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), visitParameterList(node.parameters, visitor, context, nodesVisitor), nodeVisitor(node.type, visitor, isTypeNode), visitFunctionBody(node.body!, visitor, context, nodeVisitor)); @@ -535,7 +562,7 @@ namespace ts { [SyntaxKind.SetAccessor]: function visitEachChildOfSetAccessorDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateSetAccessorDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifierLike), - nodeVisitor(node.name, visitor, isPropertyName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body!, visitor, context, nodeVisitor)); }, @@ -565,20 +592,20 @@ namespace ts { return context.factory.updateIndexSignature(node, nodesVisitor(node.modifiers, visitor, isModifier), nodesVisitor(node.parameters, visitor, isParameter), - nodeVisitor(node.type, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))); }, // Types [SyntaxKind.TypePredicate]: function visitEachChildOfTypePredicateNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTypePredicateNode(node, nodeVisitor(node.assertsModifier, visitor, isAssertsKeyword), - nodeVisitor(node.parameterName, visitor, isIdentifierOrThisTypeNode), + Debug.checkDefined(nodeVisitor(node.parameterName, visitor, isIdentifierOrThisTypeNode)), nodeVisitor(node.type, visitor, isTypeNode)); }, [SyntaxKind.TypeReference]: function visitEachChildOfTypeReferenceNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTypeReferenceNode(node, - nodeVisitor(node.typeName, visitor, isEntityName), + Debug.checkDefined(nodeVisitor(node.typeName, visitor, isEntityName)), nodesVisitor(node.typeArguments, visitor, isTypeNode)); }, @@ -586,7 +613,7 @@ namespace ts { return context.factory.updateFunctionTypeNode(node, nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, isParameter), - nodeVisitor(node.type, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))); }, [SyntaxKind.ConstructorType]: function visitEachChildOfConstructorTypeNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { @@ -594,12 +621,12 @@ namespace ts { nodesVisitor(node.modifiers, visitor, isModifier), nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, isParameter), - nodeVisitor(node.type, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))); }, [SyntaxKind.TypeQuery]: function visitEachChildOfTypeQueryNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTypeQueryNode(node, - nodeVisitor(node.exprName, visitor, isEntityName), + Debug.checkDefined(nodeVisitor(node.exprName, visitor, isEntityName)), nodesVisitor(node.typeArguments, visitor, isTypeNode)); }, @@ -610,7 +637,7 @@ namespace ts { [SyntaxKind.ArrayType]: function visitEachChildOfArrayTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateArrayTypeNode(node, - nodeVisitor(node.elementType, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.elementType, visitor, isTypeNode))); }, [SyntaxKind.TupleType]: function visitEachChildOfTupleTypeNode(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) { @@ -620,12 +647,12 @@ namespace ts { [SyntaxKind.OptionalType]: function visitEachChildOfOptionalTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateOptionalTypeNode(node, - nodeVisitor(node.type, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))); }, [SyntaxKind.RestType]: function visitEachChildOfRestTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateRestTypeNode(node, - nodeVisitor(node.type, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))); }, [SyntaxKind.UnionType]: function visitEachChildOfUnionTypeNode(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) { @@ -640,20 +667,20 @@ namespace ts { [SyntaxKind.ConditionalType]: function visitEachChildOfConditionalTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateConditionalTypeNode(node, - nodeVisitor(node.checkType, visitor, isTypeNode), - nodeVisitor(node.extendsType, visitor, isTypeNode), - nodeVisitor(node.trueType, visitor, isTypeNode), - nodeVisitor(node.falseType, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.checkType, visitor, isTypeNode)), + Debug.checkDefined(nodeVisitor(node.extendsType, visitor, isTypeNode)), + Debug.checkDefined(nodeVisitor(node.trueType, visitor, isTypeNode)), + Debug.checkDefined(nodeVisitor(node.falseType, visitor, isTypeNode))); }, [SyntaxKind.InferType]: function visitEachChildOfInferTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateInferTypeNode(node, - nodeVisitor(node.typeParameter, visitor, isTypeParameterDeclaration)); + Debug.checkDefined(nodeVisitor(node.typeParameter, visitor, isTypeParameterDeclaration))); }, [SyntaxKind.ImportType]: function visitEachChildOfImportTypeNode(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateImportTypeNode(node, - nodeVisitor(node.argument, visitor, isTypeNode), + Debug.checkDefined(nodeVisitor(node.argument, visitor, isTypeNode)), nodeVisitor(node.assertions, visitor, isImportTypeAssertionContainer), nodeVisitor(node.qualifier, visitor, isEntityName), nodesVisitor(node.typeArguments, visitor, isTypeNode), @@ -663,7 +690,7 @@ namespace ts { [SyntaxKind.ImportTypeAssertionContainer]: function visitEachChildOfImportTypeAssertionContainer(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateImportTypeAssertionContainer(node, - nodeVisitor(node.assertClause, visitor, isAssertClause), + Debug.checkDefined(nodeVisitor(node.assertClause, visitor, isAssertClause)), node.multiLine ); }, @@ -671,32 +698,32 @@ namespace ts { [SyntaxKind.NamedTupleMember]: function visitEachChildOfNamedTupleMember(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateNamedTupleMember(node, nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken), - nodeVisitor(node.name, visitor, isIdentifier), + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)), nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), - nodeVisitor(node.type, visitor, isTypeNode), + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode)), ); }, [SyntaxKind.ParenthesizedType]: function visitEachChildOfParenthesizedType(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateParenthesizedType(node, - nodeVisitor(node.type, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))); }, [SyntaxKind.TypeOperator]: function visitEachChildOfTypeOperatorNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTypeOperatorNode(node, - nodeVisitor(node.type, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))); }, [SyntaxKind.IndexedAccessType]: function visitEachChildOfIndexedAccessType(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateIndexedAccessTypeNode(node, - nodeVisitor(node.objectType, visitor, isTypeNode), - nodeVisitor(node.indexType, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.objectType, visitor, isTypeNode)), + Debug.checkDefined(nodeVisitor(node.indexType, visitor, isTypeNode))); }, [SyntaxKind.MappedType]: function visitEachChildOfMappedType(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateMappedTypeNode(node, nodeVisitor(node.readonlyToken, tokenVisitor, isReadonlyKeywordOrPlusOrMinusToken), - nodeVisitor(node.typeParameter, visitor, isTypeParameterDeclaration), + Debug.checkDefined(nodeVisitor(node.typeParameter, visitor, isTypeParameterDeclaration)), nodeVisitor(node.nameType, visitor, isTypeNode), nodeVisitor(node.questionToken, tokenVisitor, isQuestionOrPlusOrMinusToken), nodeVisitor(node.type, visitor, isTypeNode), @@ -705,19 +732,19 @@ namespace ts { [SyntaxKind.LiteralType]: function visitEachChildOfLiteralTypeNode(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateLiteralTypeNode(node, - nodeVisitor(node.literal, visitor, isLiteralTypeLiteral)); + Debug.checkDefined(nodeVisitor(node.literal, visitor, isLiteralTypeLiteral))); }, [SyntaxKind.TemplateLiteralType]: function visitEachChildOfTemplateLiteralType(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTemplateLiteralType(node, - nodeVisitor(node.head, visitor, isTemplateHead), + Debug.checkDefined(nodeVisitor(node.head, visitor, isTemplateHead)), nodesVisitor(node.templateSpans, visitor, isTemplateLiteralTypeSpan)); }, [SyntaxKind.TemplateLiteralTypeSpan]: function visitEachChildOfTemplateLiteralTypeSpan(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTemplateLiteralTypeSpan(node, - nodeVisitor(node.type, visitor, isTypeNode), - nodeVisitor(node.literal, visitor, isTemplateMiddleOrTemplateTail)); + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode)), + Debug.checkDefined(nodeVisitor(node.literal, visitor, isTemplateMiddleOrTemplateTail))); }, // Binding patterns @@ -735,7 +762,7 @@ namespace ts { return context.factory.updateBindingElement(node, nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken), nodeVisitor(node.propertyName, visitor, isPropertyName), - nodeVisitor(node.name, visitor, isBindingName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isBindingName)), nodeVisitor(node.initializer, visitor, isExpression)); }, @@ -753,61 +780,61 @@ namespace ts { [SyntaxKind.PropertyAccessExpression]: function visitEachChildOfPropertyAccessExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return isPropertyAccessChain(node) ? context.factory.updatePropertyAccessChain(node, - nodeVisitor(node.expression, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken), - nodeVisitor(node.name, visitor, isMemberName)) : + Debug.checkDefined(nodeVisitor(node.name, visitor, isMemberName))) : context.factory.updatePropertyAccessExpression(node, - nodeVisitor(node.expression, visitor, isExpression), - nodeVisitor(node.name, visitor, isMemberName)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), + Debug.checkDefined(nodeVisitor(node.name, visitor, isMemberName))); }, [SyntaxKind.ElementAccessExpression]: function visitEachChildOfElementAccessExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return isElementAccessChain(node) ? context.factory.updateElementAccessChain(node, - nodeVisitor(node.expression, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken), - nodeVisitor(node.argumentExpression, visitor, isExpression)) : + Debug.checkDefined(nodeVisitor(node.argumentExpression, visitor, isExpression))) : context.factory.updateElementAccessExpression(node, - nodeVisitor(node.expression, visitor, isExpression), - nodeVisitor(node.argumentExpression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), + Debug.checkDefined(nodeVisitor(node.argumentExpression, visitor, isExpression))); }, [SyntaxKind.CallExpression]: function visitEachChildOfCallExpression(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { return isCallChain(node) ? context.factory.updateCallChain(node, - nodeVisitor(node.expression, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken), nodesVisitor(node.typeArguments, visitor, isTypeNode), nodesVisitor(node.arguments, visitor, isExpression)) : context.factory.updateCallExpression(node, - nodeVisitor(node.expression, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), nodesVisitor(node.typeArguments, visitor, isTypeNode), nodesVisitor(node.arguments, visitor, isExpression)); }, [SyntaxKind.NewExpression]: function visitEachChildOfNewExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateNewExpression(node, - nodeVisitor(node.expression, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), nodesVisitor(node.typeArguments, visitor, isTypeNode), nodesVisitor(node.arguments, visitor, isExpression)); }, [SyntaxKind.TaggedTemplateExpression]: function visitEachChildOfTaggedTemplateExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTaggedTemplateExpression(node, - nodeVisitor(node.tag, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.tag, visitor, isExpression)), nodesVisitor(node.typeArguments, visitor, isTypeNode), - nodeVisitor(node.template, visitor, isTemplateLiteral)); + Debug.checkDefined(nodeVisitor(node.template, visitor, isTemplateLiteral))); }, [SyntaxKind.TypeAssertionExpression]: function visitEachChildOfTypeAssertionExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTypeAssertion(node, - nodeVisitor(node.type, visitor, isTypeNode), - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode)), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.ParenthesizedExpression]: function visitEachChildOfParenthesizedExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateParenthesizedExpression(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.FunctionExpression]: function visitEachChildOfFunctionExpression(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { @@ -833,53 +860,53 @@ namespace ts { [SyntaxKind.DeleteExpression]: function visitEachChildOfDeleteExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateDeleteExpression(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.TypeOfExpression]: function visitEachChildOfTypeOfExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTypeOfExpression(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.VoidExpression]: function visitEachChildOfVoidExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateVoidExpression(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.AwaitExpression]: function visitEachChildOfAwaitExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateAwaitExpression(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.PrefixUnaryExpression]: function visitEachChildOfPrefixUnaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updatePrefixUnaryExpression(node, - nodeVisitor(node.operand, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.operand, visitor, isExpression))); }, [SyntaxKind.PostfixUnaryExpression]: function visitEachChildOfPostfixUnaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updatePostfixUnaryExpression(node, - nodeVisitor(node.operand, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.operand, visitor, isExpression))); }, [SyntaxKind.BinaryExpression]: function visitEachChildOfBinaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateBinaryExpression(node, - nodeVisitor(node.left, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.left, visitor, isExpression)), nodeVisitor(node.operatorToken, tokenVisitor, isBinaryOperatorToken), - nodeVisitor(node.right, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.right, visitor, isExpression))); }, [SyntaxKind.ConditionalExpression]: function visitEachChildOfConditionalExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateConditionalExpression(node, - nodeVisitor(node.condition, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.condition, visitor, isExpression)), nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), - nodeVisitor(node.whenTrue, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.whenTrue, visitor, isExpression)), nodeVisitor(node.colonToken, tokenVisitor, isColonToken), - nodeVisitor(node.whenFalse, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.whenFalse, visitor, isExpression))); }, [SyntaxKind.TemplateExpression]: function visitEachChildOfTemplateExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTemplateExpression(node, - nodeVisitor(node.head, visitor, isTemplateHead), + Debug.checkDefined(nodeVisitor(node.head, visitor, isTemplateHead)), nodesVisitor(node.templateSpans, visitor, isTemplateSpan)); }, @@ -891,7 +918,7 @@ namespace ts { [SyntaxKind.SpreadElement]: function visitEachChildOfSpreadElement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateSpreadElement(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.ClassExpression]: function visitEachChildOfClassExpression(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { @@ -905,40 +932,40 @@ namespace ts { [SyntaxKind.ExpressionWithTypeArguments]: function visitEachChildOfExpressionWithTypeArguments(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateExpressionWithTypeArguments(node, - nodeVisitor(node.expression, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), nodesVisitor(node.typeArguments, visitor, isTypeNode)); }, [SyntaxKind.AsExpression]: function visitEachChildOfAsExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateAsExpression(node, - nodeVisitor(node.expression, visitor, isExpression), - nodeVisitor(node.type, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))); }, [SyntaxKind.SatisfiesExpression]: function visitEachChildOfSatisfiesExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateSatisfiesExpression(node, - nodeVisitor(node.expression, visitor, isExpression), - nodeVisitor(node.type, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))); }, [SyntaxKind.NonNullExpression]: function visitEachChildOfNonNullExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return isOptionalChain(node) ? context.factory.updateNonNullChain(node, - nodeVisitor(node.expression, visitor, isExpression)) : + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))) : context.factory.updateNonNullExpression(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.MetaProperty]: function visitEachChildOfMetaProperty(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateMetaProperty(node, - nodeVisitor(node.name, visitor, isIdentifier)); + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))); }, // Misc [SyntaxKind.TemplateSpan]: function visitEachChildOfTemplateSpan(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTemplateSpan(node, - nodeVisitor(node.expression, visitor, isExpression), - nodeVisitor(node.literal, visitor, isTemplateMiddleOrTemplateTail)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), + Debug.checkDefined(nodeVisitor(node.literal, visitor, isTemplateMiddleOrTemplateTail))); }, // Element @@ -950,30 +977,30 @@ namespace ts { [SyntaxKind.VariableStatement]: function visitEachChildOfVariableStatement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateVariableStatement(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.declarationList, visitor, isVariableDeclarationList)); + Debug.checkDefined(nodeVisitor(node.declarationList, visitor, isVariableDeclarationList))); }, [SyntaxKind.ExpressionStatement]: function visitEachChildOfExpressionStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateExpressionStatement(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.IfStatement]: function visitEachChildOfIfStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateIfStatement(node, - nodeVisitor(node.expression, visitor, isExpression), - nodeVisitor(node.thenStatement, visitor, isStatement, context.factory.liftToBlock), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), + Debug.checkDefined(nodeVisitor(node.thenStatement, visitor, isStatement, context.factory.liftToBlock)), nodeVisitor(node.elseStatement, visitor, isStatement, context.factory.liftToBlock)); }, [SyntaxKind.DoStatement]: function visitEachChildOfDoStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateDoStatement(node, visitIterationBody(node.statement, visitor, context, nodeVisitor), - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.WhileStatement]: function visitEachChildOfWhileStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateWhileStatement(node, - nodeVisitor(node.expression, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), visitIterationBody(node.statement, visitor, context, nodeVisitor)); }, @@ -987,16 +1014,16 @@ namespace ts { [SyntaxKind.ForInStatement]: function visitEachChildOfForInStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateForInStatement(node, - nodeVisitor(node.initializer, visitor, isForInitializer), - nodeVisitor(node.expression, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.initializer, visitor, isForInitializer)), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), visitIterationBody(node.statement, visitor, context, nodeVisitor)); }, [SyntaxKind.ForOfStatement]: function visitEachChildOfForOfStatement(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateForOfStatement(node, nodeVisitor(node.awaitModifier, tokenVisitor, isAwaitKeyword), - nodeVisitor(node.initializer, visitor, isForInitializer), - nodeVisitor(node.expression, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.initializer, visitor, isForInitializer)), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), visitIterationBody(node.statement, visitor, context, nodeVisitor)); }, @@ -1017,37 +1044,37 @@ namespace ts { [SyntaxKind.WithStatement]: function visitEachChildOfWithStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateWithStatement(node, - nodeVisitor(node.expression, visitor, isExpression), - nodeVisitor(node.statement, visitor, isStatement, context.factory.liftToBlock)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), + Debug.checkDefined(nodeVisitor(node.statement, visitor, isStatement, context.factory.liftToBlock))); }, [SyntaxKind.SwitchStatement]: function visitEachChildOfSwitchStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateSwitchStatement(node, - nodeVisitor(node.expression, visitor, isExpression), - nodeVisitor(node.caseBlock, visitor, isCaseBlock)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), + Debug.checkDefined(nodeVisitor(node.caseBlock, visitor, isCaseBlock))); }, [SyntaxKind.LabeledStatement]: function visitEachChildOfLabeledStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateLabeledStatement(node, - nodeVisitor(node.label, visitor, isIdentifier), - nodeVisitor(node.statement, visitor, isStatement, context.factory.liftToBlock)); + Debug.checkDefined(nodeVisitor(node.label, visitor, isIdentifier)), + Debug.checkDefined(nodeVisitor(node.statement, visitor, isStatement, context.factory.liftToBlock))); }, [SyntaxKind.ThrowStatement]: function visitEachChildOfThrowStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateThrowStatement(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.TryStatement]: function visitEachChildOfTryStatement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTryStatement(node, - nodeVisitor(node.tryBlock, visitor, isBlock), + Debug.checkDefined(nodeVisitor(node.tryBlock, visitor, isBlock)), nodeVisitor(node.catchClause, visitor, isCatchClause), nodeVisitor(node.finallyBlock, visitor, isBlock)); }, [SyntaxKind.VariableDeclaration]: function visitEachChildOfVariableDeclaration(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateVariableDeclaration(node, - nodeVisitor(node.name, visitor, isBindingName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isBindingName)), nodeVisitor(node.exclamationToken, tokenVisitor, isExclamationToken), nodeVisitor(node.type, visitor, isTypeNode), nodeVisitor(node.initializer, visitor, isExpression)); @@ -1081,7 +1108,7 @@ namespace ts { [SyntaxKind.InterfaceDeclaration]: function visitEachChildOfInterfaceDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateInterfaceDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.name, visitor, isIdentifier), + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)), nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, isHeritageClause), nodesVisitor(node.members, visitor, isTypeElement)); @@ -1090,22 +1117,22 @@ namespace ts { [SyntaxKind.TypeAliasDeclaration]: function visitEachChildOfTypeAliasDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateTypeAliasDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.name, visitor, isIdentifier), + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)), nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), - nodeVisitor(node.type, visitor, isTypeNode)); + Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode))); }, [SyntaxKind.EnumDeclaration]: function visitEachChildOfEnumDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateEnumDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.name, visitor, isIdentifier), + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)), nodesVisitor(node.members, visitor, isEnumMember)); }, [SyntaxKind.ModuleDeclaration]: function visitEachChildOfModuleDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateModuleDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.name, visitor, isModuleName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isModuleName)), nodeVisitor(node.body, visitor, isModuleBody)); }, @@ -1121,22 +1148,22 @@ namespace ts { [SyntaxKind.NamespaceExportDeclaration]: function visitEachChildOfNamespaceExportDeclaration(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateNamespaceExportDeclaration(node, - nodeVisitor(node.name, visitor, isIdentifier)); + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))); }, [SyntaxKind.ImportEqualsDeclaration]: function visitEachChildOfImportEqualsDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateImportEqualsDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifier), node.isTypeOnly, - nodeVisitor(node.name, visitor, isIdentifier), - nodeVisitor(node.moduleReference, visitor, isModuleReference)); + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)), + Debug.checkDefined(nodeVisitor(node.moduleReference, visitor, isModuleReference))); }, [SyntaxKind.ImportDeclaration]: function visitEachChildOfImportDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateImportDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifier), nodeVisitor(node.importClause, visitor, isImportClause), - nodeVisitor(node.moduleSpecifier, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.moduleSpecifier, visitor, isExpression)), nodeVisitor(node.assertClause, visitor, isAssertClause)); }, @@ -1148,8 +1175,8 @@ namespace ts { [SyntaxKind.AssertEntry]: function visitEachChildOfAssertEntry(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateAssertEntry(node, - nodeVisitor(node.name, visitor, isAssertionKey), - nodeVisitor(node.value, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.name, visitor, isAssertionKey)), + Debug.checkDefined(nodeVisitor(node.value, visitor, isExpression))); }, [SyntaxKind.ImportClause]: function visitEachChildOfImportClause(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { @@ -1161,12 +1188,12 @@ namespace ts { [SyntaxKind.NamespaceImport]: function visitEachChildOfNamespaceImport(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateNamespaceImport(node, - nodeVisitor(node.name, visitor, isIdentifier)); + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))); }, [SyntaxKind.NamespaceExport]: function visitEachChildOfNamespaceExport(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateNamespaceExport(node, - nodeVisitor(node.name, visitor, isIdentifier)); + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))); }, [SyntaxKind.NamedImports]: function visitEachChildOfNamedImports(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) { @@ -1178,13 +1205,13 @@ namespace ts { return context.factory.updateImportSpecifier(node, node.isTypeOnly, nodeVisitor(node.propertyName, visitor, isIdentifier), - nodeVisitor(node.name, visitor, isIdentifier)); + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))); }, [SyntaxKind.ExportAssignment]: function visitEachChildOfExportAssignment(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateExportAssignment(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.ExportDeclaration]: function visitEachChildOfExportDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { @@ -1205,52 +1232,52 @@ namespace ts { return context.factory.updateExportSpecifier(node, node.isTypeOnly, nodeVisitor(node.propertyName, visitor, isIdentifier), - nodeVisitor(node.name, visitor, isIdentifier)); + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier))); }, // Module references [SyntaxKind.ExternalModuleReference]: function visitEachChildOfExternalModuleReference(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateExternalModuleReference(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, // JSX [SyntaxKind.JsxElement]: function visitEachChildOfJsxElement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateJsxElement(node, - nodeVisitor(node.openingElement, visitor, isJsxOpeningElement), + Debug.checkDefined(nodeVisitor(node.openingElement, visitor, isJsxOpeningElement)), nodesVisitor(node.children, visitor, isJsxChild), - nodeVisitor(node.closingElement, visitor, isJsxClosingElement)); + Debug.checkDefined(nodeVisitor(node.closingElement, visitor, isJsxClosingElement))); }, [SyntaxKind.JsxSelfClosingElement]: function visitEachChildOfJsxSelfClosingElement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateJsxSelfClosingElement(node, - nodeVisitor(node.tagName, visitor, isJsxTagNameExpression), + Debug.checkDefined(nodeVisitor(node.tagName, visitor, isJsxTagNameExpression)), nodesVisitor(node.typeArguments, visitor, isTypeNode), - nodeVisitor(node.attributes, visitor, isJsxAttributes)); + Debug.checkDefined(nodeVisitor(node.attributes, visitor, isJsxAttributes))); }, [SyntaxKind.JsxOpeningElement]: function visitEachChildOfJsxOpeningElement(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateJsxOpeningElement(node, - nodeVisitor(node.tagName, visitor, isJsxTagNameExpression), + Debug.checkDefined(nodeVisitor(node.tagName, visitor, isJsxTagNameExpression)), nodesVisitor(node.typeArguments, visitor, isTypeNode), - nodeVisitor(node.attributes, visitor, isJsxAttributes)); + Debug.checkDefined(nodeVisitor(node.attributes, visitor, isJsxAttributes))); }, [SyntaxKind.JsxClosingElement]: function visitEachChildOfJsxClosingElement(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateJsxClosingElement(node, - nodeVisitor(node.tagName, visitor, isJsxTagNameExpression)); + Debug.checkDefined(nodeVisitor(node.tagName, visitor, isJsxTagNameExpression))); }, [SyntaxKind.JsxFragment]: function visitEachChildOfJsxFragment(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateJsxFragment(node, - nodeVisitor(node.openingFragment, visitor, isJsxOpeningFragment), + Debug.checkDefined(nodeVisitor(node.openingFragment, visitor, isJsxOpeningFragment)), nodesVisitor(node.children, visitor, isJsxChild), - nodeVisitor(node.closingFragment, visitor, isJsxClosingFragment)); + Debug.checkDefined(nodeVisitor(node.closingFragment, visitor, isJsxClosingFragment))); }, [SyntaxKind.JsxAttribute]: function visitEachChildOfJsxAttribute(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateJsxAttribute(node, - nodeVisitor(node.name, visitor, isIdentifier), + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)), nodeVisitor(node.initializer, visitor, isStringLiteralOrJsxExpression)); }, @@ -1261,18 +1288,18 @@ namespace ts { [SyntaxKind.JsxSpreadAttribute]: function visitEachChildOfJsxSpreadAttribute(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateJsxSpreadAttribute(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.JsxExpression]: function visitEachChildOfJsxExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateJsxExpression(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, // Clauses [SyntaxKind.CaseClause]: function visitEachChildOfCaseClause(node, visitor, context, nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateCaseClause(node, - nodeVisitor(node.expression, visitor, isExpression), + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), nodesVisitor(node.statements, visitor, isStatement)); }, @@ -1289,31 +1316,31 @@ namespace ts { [SyntaxKind.CatchClause]: function visitEachChildOfCatchClause(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateCatchClause(node, nodeVisitor(node.variableDeclaration, visitor, isVariableDeclaration), - nodeVisitor(node.block, visitor, isBlock)); + Debug.checkDefined(nodeVisitor(node.block, visitor, isBlock))); }, // Property assignments [SyntaxKind.PropertyAssignment]: function visitEachChildOfPropertyAssignment(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updatePropertyAssignment(node, - nodeVisitor(node.name, visitor, isPropertyName), - nodeVisitor(node.initializer, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), + Debug.checkDefined(nodeVisitor(node.initializer, visitor, isExpression))); }, [SyntaxKind.ShorthandPropertyAssignment]: function visitEachChildOfShorthandPropertyAssignment(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateShorthandPropertyAssignment(node, - nodeVisitor(node.name, visitor, isIdentifier), + Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)), nodeVisitor(node.objectAssignmentInitializer, visitor, isExpression)); }, [SyntaxKind.SpreadAssignment]: function visitEachChildOfSpreadAssignment(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateSpreadAssignment(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, // Enum [SyntaxKind.EnumMember]: function visitEachChildOfEnumMember(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updateEnumMember(node, - nodeVisitor(node.name, visitor, isPropertyName), + Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), nodeVisitor(node.initializer, visitor, isExpression)); }, @@ -1326,7 +1353,7 @@ namespace ts { // Transformation nodes [SyntaxKind.PartiallyEmittedExpression]: function visitEachChildOfPartiallyEmittedExpression(node, visitor, context, _nodesVisitor, nodeVisitor, _tokenVisitor) { return context.factory.updatePartiallyEmittedExpression(node, - nodeVisitor(node.expression, visitor, isExpression)); + Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression))); }, [SyntaxKind.CommaListExpression]: function visitEachChildOfCommaListExpression(node, visitor, context, nodesVisitor, _nodeVisitor, _tokenVisitor) { diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index c5e7e11ef905f..811146dce44fd 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -108,15 +108,15 @@ namespace ts.codefix { } function transformJSDocOptionalType(node: JSDocOptionalType) { - return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType), factory.createTypeReferenceNode("undefined", emptyArray)]); + return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType, isTypeNode), factory.createTypeReferenceNode("undefined", emptyArray)]); } function transformJSDocNullableType(node: JSDocNullableType) { - return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType), factory.createTypeReferenceNode("null", emptyArray)]); + return factory.createUnionTypeNode([visitNode(node.type, transformJSDocType, isTypeNode), factory.createTypeReferenceNode("null", emptyArray)]); } function transformJSDocVariadicType(node: JSDocVariadicType) { - return factory.createArrayTypeNode(visitNode(node.type, transformJSDocType)); + return factory.createArrayTypeNode(visitNode(node.type, transformJSDocType, isTypeNode)); } function transformJSDocFunctionType(node: JSDocFunctionType) { @@ -130,7 +130,7 @@ namespace ts.codefix { const isRest = node.type!.kind === SyntaxKind.JSDocVariadicType && index === node.parent.parameters.length - 1; // TODO: GH#18217 const name = node.name || (isRest ? "rest" : "arg" + index); const dotdotdot = isRest ? factory.createToken(SyntaxKind.DotDotDotToken) : node.dotDotDotToken; - return factory.createParameterDeclaration(node.modifiers, dotdotdot, name, node.questionToken, visitNode(node.type, transformJSDocType), node.initializer); + return factory.createParameterDeclaration(node.modifiers, dotdotdot, name, node.questionToken, visitNode(node.type, transformJSDocType, isTypeNode), node.initializer); } function transformJSDocTypeReference(node: TypeReferenceNode) { @@ -159,7 +159,7 @@ namespace ts.codefix { args = factory.createNodeArray([factory.createTypeReferenceNode("any", emptyArray)]); } else { - args = visitNodes(node.typeArguments, transformJSDocType); + args = visitNodes(node.typeArguments, transformJSDocType, isTypeNode); } } return factory.createTypeReferenceNode(name, args); diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 59bfabcf4105f..ec15cedb41218 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -1450,7 +1450,7 @@ namespace ts.refactor.extractSymbol { if (!returnValueProperty) { returnValueProperty = "__return"; } - assignments.unshift(factory.createPropertyAssignment(returnValueProperty, visitNode(node.expression, visitor))); + assignments.unshift(factory.createPropertyAssignment(returnValueProperty, visitNode(node.expression, visitor, isExpression))); } if (assignments.length === 1) { return factory.createReturnStatement(assignments[0].name as Expression); diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index e9d9ccf25d7dc..1622dc23ec9be 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1136,29 +1136,40 @@ namespace ts.textChanges { return newNode; } - function assignPositionsToNodeArray< - TIn extends Node, - TArray extends NodeArray | undefined, - TVisited extends Node | undefined, - TAssert extends NonNullable, - TOutArray extends TArray extends undefined ? NodeArray | undefined - : NodeArray, - >( - nodes: TArray, + /** + * @see {NodesVisitor} + * @see {visitNodes} + */ + function assignPositionsToNodeArray | undefined, TVisited extends Node | undefined, TOut extends Node>( + nodes: TInArray, + visitor: Visitor | undefined, + test: (node: Node) => node is TOut, + start?: number, + count?: number, + ): NodeArray | (TInArray & undefined); + function assignPositionsToNodeArray | undefined, TVisited extends Node | undefined>( + nodes: TInArray, + visitor: Visitor | undefined, + test?: (node: Node) => boolean, + start?: number, + count?: number, + ): NodeArray | (TInArray & undefined); + function assignPositionsToNodeArray | undefined, TVisited extends Node | undefined>( + nodes: TInArray, visitor: Visitor | undefined, - test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), + test?: (node: Node) => boolean, start?: number, count?: number, - ): TOutArray { + ): NodeArray | undefined { const visited = visitNodes(nodes, visitor, test, start, count); if (!visited) { - return visited as TOutArray; + return visited; } Debug.assert(nodes); // clone nodearray if necessary - const nodeArray = visited as NodeArray === nodes ? factory.createNodeArray(visited.slice(0)) : visited; + const nodeArray = visited === nodes ? factory.createNodeArray(visited.slice(0)) : visited; setTextRangePosEnd(nodeArray, getPos(nodes), getEnd(nodes)); - return nodeArray as TOutArray; + return nodeArray; } interface TextChangesWriter extends EmitTextWriter, PrintHandlers {} diff --git a/src/testRunner/unittests/customTransforms.ts b/src/testRunner/unittests/customTransforms.ts index 0f65aba6e3408..8f7d19c828769 100644 --- a/src/testRunner/unittests/customTransforms.ts +++ b/src/testRunner/unittests/customTransforms.ts @@ -89,7 +89,7 @@ namespace ts { context => node => visitNode(node, function visitor(node: Node): Node { if (isStringLiteral(node) && node.text === "change") return factory.createStringLiteral("changed"); return visitEachChild(node, visitor, context); - }) + }, isSourceFile) ]}, { target: ScriptTarget.ES5, module: ModuleKind.ES2015, @@ -124,7 +124,7 @@ namespace ts { return node; } return visitEachChild(node, visitor, context); - }) + }, isSourceFile) ] }, { sourceMap: true } @@ -153,7 +153,7 @@ namespace ts { return newNode; } return visitEachChild(node, visitor, context); - }); + }, isSourceFile); return { transformSourceFile, transformBundle: node => factory.createBundle(map(node.sourceFiles, transformSourceFile), node.prepends), diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 3ec7c102500fc..e729821c7aa7b 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -103,7 +103,7 @@ namespace ts { return transformSourceFile(`let a: () => void`, [ context => file => visitNode(file, function visitor(node: Node): VisitResult { return visitEachChild(node, visitor, context); - }) + }, isSourceFile) ]); }); @@ -114,7 +114,7 @@ namespace ts { return factory.createKeywordTypeNode(SyntaxKind.UndefinedKeyword); } return visitEachChild(node, visitor, context); - }) + }, isSourceFile) ]); }); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 3f9fad1c0466d..41731b4c9384d 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3964,30 +3964,32 @@ declare namespace ts { * A function that walks a node using the given visitor, lifting node arrays into single nodes, * returning an node which satisfies the test. * - * This type is complicated, but intends to encode the following behaviors: + * - If the input node is undefined, then the output is undefined. + * - If the visitor returns undefined, then the output is undefined. + * - If the output node is not undefined, then it will satisfy the test function. + * - In order to obtain a return type that is more specific than `Node`, a test + * function _must_ be provided, and that function must be a type predicate. * - * - If the input node is potentially undefined, the output is potentially undefined. - * - If the visitor can return undefined, the output is potentially undefined. - * - If the output node is not undefined, then it will satisfy the test. - * - * @see {visitNode} + * For the canonical implementation of this type, @see {visitNode}. */ export interface NodeVisitor { - , TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), lift?: (node: readonly Node[]) => Node): TOut; + (node: TIn, visitor: Visitor, TVisited> | undefined, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); + (node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); } /** * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. * - * This type is complicated, but intends to encode the following behaviors: - * - * - If the input node array is potentially undefined, the output is potentially undefined. - * - If the visitor can return undefined, the output may not be undefined; these nodes will be left in the output. - * - If the output node array is not undefined, then its contents will satisfy the test. + * - If the input node array is undefined, the output is undefined. + * - If the visitor can return undefined, the node it visits in the array will be reused. + * - If the output node array is not undefined, then its contents will satisfy the test. + * - In order to obtain a return type that is more specific than `NodeArray`, a test + * function _must_ be provided, and that function must be a type predicate. * - * @see {visitNodes} + * For the canonical implementation of this type, @see {visitNodes}. */ export interface NodesVisitor { - | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number): TOutArray; + | undefined, TVisited extends Node | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + | undefined, TVisited extends Node | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); } export interface Printer { /** @@ -5084,7 +5086,8 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode, TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), lift?: (node: readonly Node[]) => Node): TOut; + function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); + function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -5094,7 +5097,10 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number): TOutArray; + function visitNodes | undefined, TVisited extends Node | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitNodes | undefined, TVisited extends Node | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); + function visitArrayWorker(nodes: TInArray, visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, start: number, count: number): readonly Node[]; /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 300550f2993e1..a6bb43d713c70 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3964,30 +3964,32 @@ declare namespace ts { * A function that walks a node using the given visitor, lifting node arrays into single nodes, * returning an node which satisfies the test. * - * This type is complicated, but intends to encode the following behaviors: + * - If the input node is undefined, then the output is undefined. + * - If the visitor returns undefined, then the output is undefined. + * - If the output node is not undefined, then it will satisfy the test function. + * - In order to obtain a return type that is more specific than `Node`, a test + * function _must_ be provided, and that function must be a type predicate. * - * - If the input node is potentially undefined, the output is potentially undefined. - * - If the visitor can return undefined, the output is potentially undefined. - * - If the output node is not undefined, then it will satisfy the test. - * - * @see {visitNode} + * For the canonical implementation of this type, @see {visitNode}. */ export interface NodeVisitor { - , TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), lift?: (node: readonly Node[]) => Node): TOut; + (node: TIn, visitor: Visitor, TVisited> | undefined, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); + (node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); } /** * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. * - * This type is complicated, but intends to encode the following behaviors: - * - * - If the input node array is potentially undefined, the output is potentially undefined. - * - If the visitor can return undefined, the output may not be undefined; these nodes will be left in the output. - * - If the output node array is not undefined, then its contents will satisfy the test. + * - If the input node array is undefined, the output is undefined. + * - If the visitor can return undefined, the node it visits in the array will be reused. + * - If the output node array is not undefined, then its contents will satisfy the test. + * - In order to obtain a return type that is more specific than `NodeArray`, a test + * function _must_ be provided, and that function must be a type predicate. * - * @see {visitNodes} + * For the canonical implementation of this type, @see {visitNodes}. */ export interface NodesVisitor { - | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number): TOutArray; + | undefined, TVisited extends Node | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + | undefined, TVisited extends Node | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); } export interface Printer { /** @@ -5084,7 +5086,8 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode, TOut extends TIn extends undefined ? TAssert | undefined : TVisited extends undefined ? TAssert | undefined : TAssert>(node: TIn, visitor: Visitor, TVisited> | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), lift?: (node: readonly Node[]) => Node): TOut; + function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); + function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -5094,7 +5097,10 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes | undefined, TVisited extends Node | undefined, TAssert extends NonNullable, TOutArray extends TArray extends undefined ? NodeArray | undefined : NodeArray>(nodes: TArray, visitor: Visitor | undefined, test?: ((node: Node) => node is TAssert) | ((node: Node) => boolean), start?: number, count?: number): TOutArray; + function visitNodes | undefined, TVisited extends Node | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitNodes | undefined, TVisited extends Node | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); + function visitArrayWorker(nodes: TInArray, visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, start: number, count: number): readonly Node[]; /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. From 5bf42facbbc4fa9c4c898dfd28ae019150f5e14f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 20 Sep 2022 21:27:59 -0700 Subject: [PATCH 29/81] Resolve some TODOs --- src/compiler/core.ts | 3 --- src/compiler/factory/parenthesizerRules.ts | 2 +- src/testRunner/unittests/compilerCore.ts | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 2325dbd21d377..61b4e3d9a541e 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1738,9 +1738,6 @@ namespace ts { return typeof x === "number"; } - // TODO(jakebailey): This should be TOut <= TIn <= TParam, but this does not infer correctly. - // https://github.com/microsoft/TypeScript/issues/49924 - export function tryCast(value: TIn | undefined, test: (value: TParam) => value is TOut): TOut | undefined; export function tryCast(value: T, test: (value: T) => boolean): T | undefined; export function tryCast(value: T, test: (value: T) => boolean): T | undefined { diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts index b7a4428cc9b89..d1abb81d20764 100644 --- a/src/compiler/factory/parenthesizerRules.ts +++ b/src/compiler/factory/parenthesizerRules.ts @@ -603,7 +603,7 @@ namespace ts { } function castToNodeArray(nodes: readonly T[]): NodeArray { - // TODO(jakebailey): Why do we need this helper? GH#49924? It seems like `cast(nodes, isNodeArray)` should be enough. + // TODO(jakebailey): Why do we need this helper? It seems like `cast(nodes, isNodeArray)` should be enough. // Also, this typeof shouldn't be needed, but https://github.com/microsoft/TypeScript/issues/50161 // makes any change to this file cause an error to appear. return cast(nodes, isNodeArray as typeof isNodeArray); diff --git a/src/testRunner/unittests/compilerCore.ts b/src/testRunner/unittests/compilerCore.ts index eea8f595816eb..c2ab8abd382d7 100644 --- a/src/testRunner/unittests/compilerCore.ts +++ b/src/testRunner/unittests/compilerCore.ts @@ -21,7 +21,7 @@ namespace ts { assert.isFalse(equalOwnProperties({}, { a: 0 }, trythyTest), "missing left falsey property"); assert.isFalse(equalOwnProperties({ a: 1 }, {}, trythyTest), "missing right truthy property"); assert.isFalse(equalOwnProperties({ a: 0 }, {}, trythyTest), "missing right falsey property"); - assert.isTrue(equalOwnProperties({ a: 1 }, { a: "foo" as any }, trythyTest), "valid equality"); // TODO(jakebailey): remove this test? we figure this out at compile time. + assert.isTrue(equalOwnProperties({ a: 1 }, { a: "foo" as any }, trythyTest), "valid equality"); }); it("all equal", () => { assert.isFalse(equalOwnProperties({}, { a: 1 }, () => true), "missing left property"); From 00a0f3ef19b84429c7ad4518593f9f9b93744b42 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 20 Sep 2022 21:44:23 -0700 Subject: [PATCH 30/81] Tweaks --- src/compiler/types.ts | 8 ++++---- src/compiler/visitorPublic.ts | 2 +- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a0bed9756bd95..4b480c7408608 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8538,9 +8538,6 @@ namespace ts { */ export type Transformer = (node: TIn) => TOut; - // Either a node, or a list of nodes to be be lifted via a lift function. - export type VisitResult = T | readonly Node[]; - /** * A function that accepts and possibly transforms a node. */ @@ -8570,7 +8567,7 @@ namespace ts { visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node, - ): Node | (TIn & undefined)| (TVisited & undefined); + ): Node | (TIn & undefined) | (TVisited & undefined); } /** @@ -8601,6 +8598,9 @@ namespace ts { ): NodeArray | (TInArray & undefined); } + // Either a node, or a list of nodes to be be lifted via a lift function. + export type VisitResult = T | readonly Node[]; + export interface Printer { /** * Print a node and its subtree as-is, without any emit transformations. diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 37d4d8d9c8c93..f65f539af7f6a 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -18,7 +18,7 @@ namespace ts { visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node, - ): Node | (TIn & undefined)| (TVisited & undefined); + ): Node | (TIn & undefined) | (TVisited & undefined); export function visitNode( node: TIn, visitor: Visitor, TVisited> | undefined, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 41731b4c9384d..c00634ac7a893 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3955,7 +3955,6 @@ declare namespace ts { * A function that transforms a node. */ export type Transformer = (node: TIn) => TOut; - export type VisitResult = T | readonly Node[]; /** * A function that accepts and possibly transforms a node. */ @@ -3991,6 +3990,7 @@ declare namespace ts { | undefined, TVisited extends Node | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); | undefined, TVisited extends Node | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); } + export type VisitResult = T | readonly Node[]; export interface Printer { /** * Print a node and its subtree as-is, without any emit transformations. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index a6bb43d713c70..fd9826c463d68 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3955,7 +3955,6 @@ declare namespace ts { * A function that transforms a node. */ export type Transformer = (node: TIn) => TOut; - export type VisitResult = T | readonly Node[]; /** * A function that accepts and possibly transforms a node. */ @@ -3991,6 +3990,7 @@ declare namespace ts { | undefined, TVisited extends Node | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); | undefined, TVisited extends Node | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); } + export type VisitResult = T | readonly Node[]; export interface Printer { /** * Print a node and its subtree as-is, without any emit transformations. From 693b9f0fd2c41aff210a27bd0d9a8e4fcc479931 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 21 Sep 2022 20:13:12 -0700 Subject: [PATCH 31/81] Remove TVisited for nodesVisitor --- src/compiler/checker.ts | 12 ++++++------ src/compiler/types.ts | 8 ++++---- src/compiler/visitorPublic.ts | 12 ++++++------ src/services/textChanges.ts | 12 ++++++------ tests/baselines/reference/api/tsserverlibrary.d.ts | 8 ++++---- tests/baselines/reference/api/typescript.d.ts | 8 ++++---- 6 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 66300449af3c2..9f652b22573a5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5508,23 +5508,23 @@ namespace ts { * @see {NodesVisitor} * @see {visitNodes} */ - function deepCloneOrReuseNodes | undefined, TVisited extends Node | undefined, TOut extends Node>( + function deepCloneOrReuseNodes | undefined, TOut extends Node>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number, ): NodeArray | (TInArray & undefined); - function deepCloneOrReuseNodes | undefined, TVisited extends Node | undefined>( + function deepCloneOrReuseNodes | undefined>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, ): NodeArray | (TInArray & undefined); - function deepCloneOrReuseNodes | undefined, TVisited extends Node | undefined>( + function deepCloneOrReuseNodes | undefined>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4b480c7408608..90b864afcdb9a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8582,16 +8582,16 @@ namespace ts { * For the canonical implementation of this type, @see {visitNodes}. */ export interface NodesVisitor { - | undefined, TVisited extends Node | undefined, TOut extends Node>( + | undefined, TOut extends Node>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number, ): NodeArray | (TInArray & undefined); - | undefined, TVisited extends Node | undefined>( + | undefined>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index f65f539af7f6a..ee4161ece42a5 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -61,23 +61,23 @@ namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - export function visitNodes | undefined, TVisited extends Node | undefined, TOut extends Node>( + export function visitNodes | undefined, TOut extends Node>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number, ): NodeArray | (TInArray & undefined); - export function visitNodes | undefined, TVisited extends Node | undefined>( + export function visitNodes | undefined>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, ): NodeArray | (TInArray & undefined); - export function visitNodes | undefined, TVisited extends Node | undefined>( + export function visitNodes | undefined>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 1622dc23ec9be..362b8ced15076 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1140,23 +1140,23 @@ namespace ts.textChanges { * @see {NodesVisitor} * @see {visitNodes} */ - function assignPositionsToNodeArray | undefined, TVisited extends Node | undefined, TOut extends Node>( + function assignPositionsToNodeArray | undefined, TOut extends Node>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number, ): NodeArray | (TInArray & undefined); - function assignPositionsToNodeArray | undefined, TVisited extends Node | undefined>( + function assignPositionsToNodeArray | undefined>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, ): NodeArray | (TInArray & undefined); - function assignPositionsToNodeArray | undefined, TVisited extends Node | undefined>( + function assignPositionsToNodeArray | undefined>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index c00634ac7a893..d9bf595a5f1db 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3987,8 +3987,8 @@ declare namespace ts { * For the canonical implementation of this type, @see {visitNodes}. */ export interface NodesVisitor { - | undefined, TVisited extends Node | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); - | undefined, TVisited extends Node | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); + | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); } export type VisitResult = T | readonly Node[]; export interface Printer { @@ -5097,8 +5097,8 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes | undefined, TVisited extends Node | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); - function visitNodes | undefined, TVisited extends Node | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitNodes | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitNodes | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); function visitArrayWorker(nodes: TInArray, visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, start: number, count: number): readonly Node[]; /** diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index fd9826c463d68..4b02e783bd7d6 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3987,8 +3987,8 @@ declare namespace ts { * For the canonical implementation of this type, @see {visitNodes}. */ export interface NodesVisitor { - | undefined, TVisited extends Node | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); - | undefined, TVisited extends Node | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); + | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); } export type VisitResult = T | readonly Node[]; export interface Printer { @@ -5097,8 +5097,8 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes | undefined, TVisited extends Node | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); - function visitNodes | undefined, TVisited extends Node | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitNodes | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitNodes | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); function visitArrayWorker(nodes: TInArray, visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, start: number, count: number): readonly Node[]; /** From 0d94fe05002e3f2269114a251848b44e4929c408 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 21 Sep 2022 20:18:57 -0700 Subject: [PATCH 32/81] Copy rules to visit functions --- src/compiler/visitorPublic.ts | 12 ++++++++++++ tests/baselines/reference/api/tsserverlibrary.d.ts | 12 ++++++++++++ tests/baselines/reference/api/typescript.d.ts | 12 ++++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index ee4161ece42a5..76a49960af5f7 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -2,6 +2,12 @@ namespace ts { /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * + * - If the input node is undefined, then the output is undefined. + * - If the visitor returns undefined, then the output is undefined. + * - If the output node is not undefined, then it will satisfy the test function. + * - In order to obtain a return type that is more specific than `Node`, a test + * function _must_ be provided, and that function must be a type predicate. + * * @param node The Node to visit. * @param visitor The callback used to visit the Node. * @param test A callback to execute to verify the Node is valid. @@ -54,6 +60,12 @@ namespace ts { /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. + * + * - If the input node array is undefined, the output is undefined. + * - If the visitor can return undefined, the node it visits in the array will be reused. + * - If the output node array is not undefined, then its contents will satisfy the test. + * - In order to obtain a return type that is more specific than `NodeArray`, a test + * function _must_ be provided, and that function must be a type predicate. * * @param nodes The NodeArray to visit. * @param visitor The callback used to visit a Node. diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index d9bf595a5f1db..721a98a5ad4e4 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -5081,6 +5081,12 @@ declare namespace ts { /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * + * - If the input node is undefined, then the output is undefined. + * - If the visitor returns undefined, then the output is undefined. + * - If the output node is not undefined, then it will satisfy the test function. + * - In order to obtain a return type that is more specific than `Node`, a test + * function _must_ be provided, and that function must be a type predicate. + * * @param node The Node to visit. * @param visitor The callback used to visit the Node. * @param test A callback to execute to verify the Node is valid. @@ -5091,6 +5097,12 @@ declare namespace ts { /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * + * - If the input node array is undefined, the output is undefined. + * - If the visitor can return undefined, the node it visits in the array will be reused. + * - If the output node array is not undefined, then its contents will satisfy the test. + * - In order to obtain a return type that is more specific than `NodeArray`, a test + * function _must_ be provided, and that function must be a type predicate. + * * @param nodes The NodeArray to visit. * @param visitor The callback used to visit a Node. * @param test A node test to execute for each node. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 4b02e783bd7d6..de415be2e7b98 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5081,6 +5081,12 @@ declare namespace ts { /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * + * - If the input node is undefined, then the output is undefined. + * - If the visitor returns undefined, then the output is undefined. + * - If the output node is not undefined, then it will satisfy the test function. + * - In order to obtain a return type that is more specific than `Node`, a test + * function _must_ be provided, and that function must be a type predicate. + * * @param node The Node to visit. * @param visitor The callback used to visit the Node. * @param test A callback to execute to verify the Node is valid. @@ -5091,6 +5097,12 @@ declare namespace ts { /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * + * - If the input node array is undefined, the output is undefined. + * - If the visitor can return undefined, the node it visits in the array will be reused. + * - If the output node array is not undefined, then its contents will satisfy the test. + * - In order to obtain a return type that is more specific than `NodeArray`, a test + * function _must_ be provided, and that function must be a type predicate. + * * @param nodes The NodeArray to visit. * @param visitor The callback used to visit a Node. * @param test A node test to execute for each node. From 9876a57403f2248ba6a116a720fb98d8c5bb9f81 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 21 Sep 2022 20:26:24 -0700 Subject: [PATCH 33/81] Fixups --- src/compiler/visitorPublic.ts | 41 ++++++++++--------- .../reference/api/tsserverlibrary.d.ts | 3 +- tests/baselines/reference/api/typescript.d.ts | 3 +- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 76a49960af5f7..6158b403b698f 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -25,9 +25,9 @@ namespace ts { test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node, ): Node | (TIn & undefined) | (TVisited & undefined); - export function visitNode( - node: TIn, - visitor: Visitor, TVisited> | undefined, + export function visitNode( + node: Node, + visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node, ): Node | undefined { @@ -87,9 +87,9 @@ namespace ts { start?: number, count?: number, ): NodeArray | (TInArray & undefined); - export function visitNodes | undefined>( - nodes: TInArray, - visitor: Visitor | undefined, + export function visitNodes( + nodes: NodeArray | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, @@ -140,23 +140,23 @@ namespace ts { ((_: NodesVisitor) => {})(visitNodes); // Check that visitNode is a NodeVisitor. /* @internal */ - export function visitArray( + export function visitArray( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number, ): readonly TOut[] | (TInArray & undefined); - export function visitArray( + export function visitArray( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, ): readonly Node[] | (TInArray & undefined); - export function visitArray( - nodes: TInArray, - visitor: Visitor | undefined, + export function visitArray( + nodes: readonly Node[] | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, @@ -180,23 +180,24 @@ namespace ts { } /* @internal */ - export function visitArrayWorker( + export function visitArrayWorker( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test: (node: Node) => node is TOut, start: number, count: number, ): readonly TOut[]; - export function visitArrayWorker( + /* @internal */ + export function visitArrayWorker( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, start: number, count: number, ): readonly Node[]; - export function visitArrayWorker( - nodes: TInArray, - visitor: Visitor | undefined, + export function visitArrayWorker( + nodes: readonly Node[], + visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, start: number, count: number, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 721a98a5ad4e4..0ec1283534e44 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -5111,8 +5111,7 @@ declare namespace ts { */ function visitNodes | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); function visitNodes | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); - function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); - function visitArrayWorker(nodes: TInArray, visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, start: number, count: number): readonly Node[]; + function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index de415be2e7b98..d02cebde736a6 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5111,8 +5111,7 @@ declare namespace ts { */ function visitNodes | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); function visitNodes | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); - function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); - function visitArrayWorker(nodes: TInArray, visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, start: number, count: number): readonly Node[]; + function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. From 721ed63dfc868ad98199b953edd60007ef691a94 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 21 Sep 2022 20:42:42 -0700 Subject: [PATCH 34/81] Simplify other implementations of NodeVisitor and NodesVisitor, now that the type is simpler --- src/compiler/checker.ts | 24 +++--------------------- src/services/textChanges.ts | 24 +++--------------------- 2 files changed, 6 insertions(+), 42 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9f652b22573a5..5b29910dc14af 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5504,27 +5504,9 @@ namespace ts { return setTextRange(factory.cloneNode(visitEachChild(node, deepCloneOrReuseNode, nullTransformationContext, deepCloneOrReuseNodes)), node); } - /** - * @see {NodesVisitor} - * @see {visitNodes} - */ - function deepCloneOrReuseNodes | undefined, TOut extends Node>( - nodes: TInArray, - visitor: Visitor | undefined, - test: (node: Node) => node is TOut, - start?: number, - count?: number, - ): NodeArray | (TInArray & undefined); - function deepCloneOrReuseNodes | undefined>( - nodes: TInArray, - visitor: Visitor | undefined, - test?: (node: Node) => boolean, - start?: number, - count?: number, - ): NodeArray | (TInArray & undefined); - function deepCloneOrReuseNodes | undefined>( - nodes: TInArray, - visitor: Visitor | undefined, + function deepCloneOrReuseNodes( + nodes: NodeArray | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 362b8ced15076..84cf7ccc62da8 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1136,27 +1136,9 @@ namespace ts.textChanges { return newNode; } - /** - * @see {NodesVisitor} - * @see {visitNodes} - */ - function assignPositionsToNodeArray | undefined, TOut extends Node>( - nodes: TInArray, - visitor: Visitor | undefined, - test: (node: Node) => node is TOut, - start?: number, - count?: number, - ): NodeArray | (TInArray & undefined); - function assignPositionsToNodeArray | undefined>( - nodes: TInArray, - visitor: Visitor | undefined, - test?: (node: Node) => boolean, - start?: number, - count?: number, - ): NodeArray | (TInArray & undefined); - function assignPositionsToNodeArray | undefined>( - nodes: TInArray, - visitor: Visitor | undefined, + function assignPositionsToNodeArray( + nodes: NodeArray | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, From 4329b73488c8db4bde671fbb5800c1267ac70755 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 21 Sep 2022 20:56:22 -0700 Subject: [PATCH 35/81] Restore undefined-ness of original Visitor type --- src/compiler/checker.ts | 2 +- src/compiler/transformers/taggedTemplate.ts | 2 +- src/compiler/types.ts | 2 +- src/compiler/visitorPublic.ts | 56 +++++++++---------- src/services/textChanges.ts | 2 +- src/testRunner/unittests/transform.ts | 4 +- .../reference/api/tsserverlibrary.d.ts | 20 +++---- tests/baselines/reference/api/typescript.d.ts | 20 +++---- 8 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5b29910dc14af..0c2179d35d1fd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5506,7 +5506,7 @@ namespace ts { function deepCloneOrReuseNodes( nodes: NodeArray | undefined, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, diff --git a/src/compiler/transformers/taggedTemplate.ts b/src/compiler/transformers/taggedTemplate.ts index dd82d74766d97..f5ac699cce356 100644 --- a/src/compiler/transformers/taggedTemplate.ts +++ b/src/compiler/transformers/taggedTemplate.ts @@ -8,7 +8,7 @@ namespace ts { export function processTaggedTemplateExpression( context: TransformationContext, node: TaggedTemplateExpression, - visitor: Visitor, + visitor: Visitor, currentSourceFile: SourceFile, recordTaggedTemplateString: (temp: Identifier) => void, level: ProcessLevel) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 90b864afcdb9a..17ee8ddb25037 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8541,7 +8541,7 @@ namespace ts { /** * A function that accepts and possibly transforms a node. */ - export type Visitor = (node: TIn) => VisitResult; + export type Visitor = (node: TIn) => VisitResult; /** * A function that walks a node using the given visitor, lifting node arrays into single nodes, diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 6158b403b698f..50ad78ef318c5 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -27,7 +27,7 @@ namespace ts { ): Node | (TIn & undefined) | (TVisited & undefined); export function visitNode( node: Node, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node, ): Node | undefined { @@ -89,7 +89,7 @@ namespace ts { ): NodeArray | (TInArray & undefined); export function visitNodes( nodes: NodeArray | undefined, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, @@ -156,7 +156,7 @@ namespace ts { ): readonly Node[] | (TInArray & undefined); export function visitArray( nodes: readonly Node[] | undefined, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, @@ -197,7 +197,7 @@ namespace ts { ): readonly Node[]; export function visitArrayWorker( nodes: readonly Node[], - visitor: Visitor | undefined, + visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, start: number, count: number, @@ -241,7 +241,7 @@ namespace ts { * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - export function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor: NodesVisitor = visitNodes) { + export function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor: NodesVisitor = visitNodes) { context.startLexicalEnvironment(); statements = nodesVisitor(statements, visitor, isStatement, start); if (ensureUseStrict) statements = context.factory.ensureUseStrict(statements); @@ -252,9 +252,9 @@ namespace ts { * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; - export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; - export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) { + export function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; + export function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes) { let updated: NodeArray | undefined; context.startLexicalEnvironment(); if (nodes) { @@ -377,21 +377,21 @@ namespace ts { * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; + export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; + export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; /** * Resumes a suspended lexical environment and visits a concise body, ending the lexical * environment and merging hoisted declarations upon completion. */ - export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; - /* @internal*/ export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody; // eslint-disable-line @typescript-eslint/unified-signatures - /* @internal*/ export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody | undefined; // eslint-disable-line @typescript-eslint/unified-signatures - /* @internal*/ export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): ConciseBody; // eslint-disable-line @typescript-eslint/unified-signatures - export function visitFunctionBody(node: ConciseBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): ConciseBody | undefined { + export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; + /* @internal*/ export function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody; // eslint-disable-line @typescript-eslint/unified-signatures + /* @internal*/ export function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): FunctionBody | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + /* @internal*/ export function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): ConciseBody; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitFunctionBody(node: ConciseBody | undefined, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): ConciseBody | undefined { context.resumeLexicalEnvironment(); const updated = nodeVisitor(node, visitor, isConciseBody); const declarations = context.endLexicalEnvironment(); @@ -409,10 +409,10 @@ namespace ts { /** * Visits an iteration body, adding any block-scoped variables required by the transformation. */ - export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; + export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; /* @internal */ - export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): Statement; // eslint-disable-line @typescript-eslint/unified-signatures - export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): Statement { + export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor?: NodeVisitor): Statement; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): Statement { context.startBlockScope(); const updated = nodeVisitor(body, visitor, isStatement, context.factory.liftToBlock); Debug.assert(updated); @@ -435,9 +435,9 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; + export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; /* @internal */ - export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitEachChild(node: T, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T; // eslint-disable-line @typescript-eslint/unified-signatures /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -445,10 +445,10 @@ namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; /* @internal */ - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T | undefined; // eslint-disable-line @typescript-eslint/unified-signatures - export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor, nodeVisitor: NodeVisitor = visitNode): T | undefined { + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor, tokenVisitor?: Visitor, nodeVisitor?: NodeVisitor): T | undefined; // eslint-disable-line @typescript-eslint/unified-signatures + export function visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor = visitNodes, tokenVisitor?: Visitor, nodeVisitor: NodeVisitor = visitNode): T | undefined { if (node === undefined) { return undefined; } @@ -457,7 +457,7 @@ namespace ts { return fn === undefined ? node : fn(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor); } - type VisitEachChildFunction = (node: T, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor, nodeVisitor: NodeVisitor, tokenVisitor: Visitor | undefined) => T; + type VisitEachChildFunction = (node: T, visitor: Visitor, context: TransformationContext, nodesVisitor: NodesVisitor, nodeVisitor: NodeVisitor, tokenVisitor: Visitor | undefined) => T; // A type that correlates a `SyntaxKind` to a `VisitEachChildFunction`, for nodes in the `HasChildren` union. // This looks something like: @@ -867,7 +867,7 @@ namespace ts { nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), nodeVisitor(node.type, visitor, isTypeNode), - nodeVisitor(node.equalsGreaterThanToken, tokenVisitor, isEqualsGreaterThanToken), + Debug.checkDefined(nodeVisitor(node.equalsGreaterThanToken, tokenVisitor, isEqualsGreaterThanToken)), visitFunctionBody(node.body, visitor, context, nodeVisitor)); }, @@ -904,16 +904,16 @@ namespace ts { [SyntaxKind.BinaryExpression]: function visitEachChildOfBinaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateBinaryExpression(node, Debug.checkDefined(nodeVisitor(node.left, visitor, isExpression)), - nodeVisitor(node.operatorToken, tokenVisitor, isBinaryOperatorToken), + Debug.checkDefined(nodeVisitor(node.operatorToken, tokenVisitor, isBinaryOperatorToken)), Debug.checkDefined(nodeVisitor(node.right, visitor, isExpression))); }, [SyntaxKind.ConditionalExpression]: function visitEachChildOfConditionalExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateConditionalExpression(node, Debug.checkDefined(nodeVisitor(node.condition, visitor, isExpression)), - nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), + Debug.checkDefined(nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken)), Debug.checkDefined(nodeVisitor(node.whenTrue, visitor, isExpression)), - nodeVisitor(node.colonToken, tokenVisitor, isColonToken), + Debug.checkDefined(nodeVisitor(node.colonToken, tokenVisitor, isColonToken)), Debug.checkDefined(nodeVisitor(node.whenFalse, visitor, isExpression))); }, diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 84cf7ccc62da8..f65bbe7a05de3 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1138,7 +1138,7 @@ namespace ts.textChanges { function assignPositionsToNodeArray( nodes: NodeArray | undefined, - visitor: Visitor | undefined, + visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number, diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index e729821c7aa7b..6616bee7bc24a 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -41,7 +41,7 @@ namespace ts { } function replaceIdentifiersNamedOldNameWithNewName2(context: TransformationContext) { - const visitor: Visitor = (node) => { + const visitor = (node: Node): Node => { if (isIdentifier(node) && node.text === "oldName") { return factory.createIdentifier("newName"); } @@ -552,7 +552,7 @@ module MyModule { return host.readFile("source.js")!.toString(); function transformSourceFile(context: TransformationContext) { - const visitor: Visitor = (node) => { + const visitor = (node: Node): Node => { if (isMethodDeclaration(node)) { return factory.updateMethodDeclaration( node, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 0ec1283534e44..5f10f8a85560e 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3958,7 +3958,7 @@ declare namespace ts { /** * A function that accepts and possibly transforms a node. */ - export type Visitor = (node: TIn) => VisitResult; + export type Visitor = (node: TIn) => VisitResult; /** * A function that walks a node using the given visitor, lifting node arrays into single nodes, * returning an node which satisfies the test. @@ -5116,32 +5116,32 @@ declare namespace ts { * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; + function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; /** * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; - function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; + function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; + function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; + function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; /** * Resumes a suspended lexical environment and visits a concise body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; + function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; /** * Visits an iteration body, adding any block-scoped variables required by the transformation. */ - function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; + function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -5149,7 +5149,7 @@ declare namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; + function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -5157,7 +5157,7 @@ declare namespace ts { * @param visitor The callback used to visit each child. * @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 visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; } declare namespace ts { function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index d02cebde736a6..3e5e77ae64201 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3958,7 +3958,7 @@ declare namespace ts { /** * A function that accepts and possibly transforms a node. */ - export type Visitor = (node: TIn) => VisitResult; + export type Visitor = (node: TIn) => VisitResult; /** * A function that walks a node using the given visitor, lifting node arrays into single nodes, * returning an node which satisfies the test. @@ -5116,32 +5116,32 @@ declare namespace ts { * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ - function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; + function visitLexicalEnvironment(statements: NodeArray, visitor: Visitor, context: TransformationContext, start?: number, ensureUseStrict?: boolean, nodesVisitor?: NodesVisitor): NodeArray; /** * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ - function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; - function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; + function visitParameterList(nodes: NodeArray, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray; + function visitParameterList(nodes: NodeArray | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: NodesVisitor): NodeArray | undefined; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; + function visitFunctionBody(node: FunctionBody, visitor: Visitor, context: TransformationContext): FunctionBody; /** * Resumes a suspended lexical environment and visits a function body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; + function visitFunctionBody(node: FunctionBody | undefined, visitor: Visitor, context: TransformationContext): FunctionBody | undefined; /** * Resumes a suspended lexical environment and visits a concise body, ending the lexical * environment and merging hoisted declarations upon completion. */ - function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; + function visitFunctionBody(node: ConciseBody, visitor: Visitor, context: TransformationContext): ConciseBody; /** * Visits an iteration body, adding any block-scoped variables required by the transformation. */ - function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; + function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext): Statement; /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -5149,7 +5149,7 @@ declare namespace ts { * @param visitor The callback used to visit each child. * @param context A lexical environment context for the visitor. */ - function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; + function visitEachChild(node: T, visitor: Visitor, context: TransformationContext): T; /** * Visits each child of a Node using the supplied visitor, possibly returning a new Node of the same kind in its place. * @@ -5157,7 +5157,7 @@ declare namespace ts { * @param visitor The callback used to visit each child. * @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 visitEachChild(node: T | undefined, visitor: Visitor, context: TransformationContext, nodesVisitor?: typeof visitNodes, tokenVisitor?: Visitor): T | undefined; } declare namespace ts { function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined; From 45c2ca8f0e7dc79a16c02df6031c493cb01b129f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 21 Sep 2022 21:24:51 -0700 Subject: [PATCH 36/81] Make fixes more consistent --- .../codefixes/annotateWithTypeFromJSDoc.ts | 16 +++------------- src/testRunner/unittests/transform.ts | 1 - 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index 811146dce44fd..409b6a454fcb5 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -50,29 +50,19 @@ namespace ts.codefix { for (const param of decl.parameters) { if (!param.type) { const paramType = getJSDocType(param); - if (paramType) { - const transformedType = transformJSDocType(paramType); - Debug.assertNode(transformedType, isTypeNode); - changes.tryInsertTypeAnnotation(sourceFile, param, transformedType); - } + if (paramType) changes.tryInsertTypeAnnotation(sourceFile, param, visitNode(paramType, transformJSDocType, isTypeNode)); } } if (needParens) changes.insertNodeAfter(sourceFile, last(decl.parameters), factory.createToken(SyntaxKind.CloseParenToken)); if (!decl.type) { const returnType = getJSDocReturnType(decl); - if (returnType) { - const transformedType = transformJSDocType(returnType); - Debug.assertNode(transformedType, isTypeNode); - changes.tryInsertTypeAnnotation(sourceFile, decl, transformedType); - } + if (returnType) changes.tryInsertTypeAnnotation(sourceFile, decl, visitNode(returnType, transformJSDocType, isTypeNode)); } } else { const jsdocType = Debug.checkDefined(getJSDocType(decl), "A JSDocType for this declaration should exist"); // If not defined, shouldn't have been an error to fix Debug.assert(!decl.type, "The JSDocType decl should have a type"); // If defined, shouldn't have been an error to fix. - const transformedType = transformJSDocType(jsdocType); - Debug.assertNode(transformedType, isTypeNode); - changes.tryInsertTypeAnnotation(sourceFile, decl, transformedType); + changes.tryInsertTypeAnnotation(sourceFile, decl, visitNode(jsdocType, transformJSDocType, isTypeNode)); } } diff --git a/src/testRunner/unittests/transform.ts b/src/testRunner/unittests/transform.ts index 6616bee7bc24a..2068b438933b5 100644 --- a/src/testRunner/unittests/transform.ts +++ b/src/testRunner/unittests/transform.ts @@ -539,7 +539,6 @@ module MyModule { const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true); const transformed = transform(createSourceFile("source.ts", "class X { echo(x: string) { return x; } }", ScriptTarget.ES3), [transformSourceFile]); const transformedSourceFile = transformed.transformed[0]; - Debug.assertNode(transformedSourceFile, isSourceFile); transformed.dispose(); const host = new fakes.CompilerHost(fs); host.getSourceFile = () => transformedSourceFile; From d1a95df83b6d23c69b2ad1a25034eee1edd893ef Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 21 Sep 2022 21:46:04 -0700 Subject: [PATCH 37/81] Lint fix --- src/compiler/visitorPublic.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 50ad78ef318c5..5f456bdae4ec3 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -7,7 +7,7 @@ namespace ts { * - If the output node is not undefined, then it will satisfy the test function. * - In order to obtain a return type that is more specific than `Node`, a test * function _must_ be provided, and that function must be a type predicate. - * + * * @param node The Node to visit. * @param visitor The callback used to visit the Node. * @param test A callback to execute to verify the Node is valid. @@ -60,7 +60,7 @@ namespace ts { /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. - * + * * - If the input node array is undefined, the output is undefined. * - If the visitor can return undefined, the node it visits in the array will be reused. * - If the output node array is not undefined, then its contents will satisfy the test. From 65ad1d3883d60146470cfba6bf97454efcec1439 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 21 Sep 2022 23:08:31 -0700 Subject: [PATCH 38/81] Address some TODOs --- src/compiler/transformers/classFields.ts | 4 ++-- src/compiler/transformers/es2015.ts | 7 ++++++- src/services/documentHighlights.ts | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index b4f38898f71fb..6d8ee0f80d77a 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -2358,7 +2358,7 @@ namespace ts { ); } - function visitArrayAssignmentTarget(node: BindingOrAssignmentElement) { + function visitArrayAssignmentTarget(node: ArrayBindingOrAssignmentElement) { const target = getTargetOfBindingOrAssignmentElement(node); if (target) { let wrapped: LeftHandSideExpression | undefined; @@ -2481,7 +2481,7 @@ namespace ts { // [ { set value(x) { this.#myProp = x; } }.value ] = [ "hello" ]; return factory.updateArrayLiteralExpression( node, - visitNodes(node.elements as NodeArray>, visitArrayAssignmentTarget, isExpression) // TODO(jakebailey): the elements property's type looks to be wrong. + visitNodes(node.elements as NodeArray, visitArrayAssignmentTarget, isExpression) // TODO(jakebailey): Should elements be NodeArray? ); } else { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index ac034d58826f2..9301f12ff52c2 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2194,11 +2194,16 @@ namespace ts { enableSubstitutionsForBlockScopedBindings(); } + // TODO(jakebailey): should this be... + // const declarations = visitNodes(node.declarations, node.flags & NodeFlags.Let + // ? visitVariableDeclarationInLetDeclarationList + // : visitVariableDeclaration, isVariableDeclaration); + const declarations = flatMap(node.declarations, node.flags & NodeFlags.Let ? visitVariableDeclarationInLetDeclarationList : visitVariableDeclaration); - Debug.assertEachNode(declarations, isVariableDeclaration); // TODO(jakebailey): side effect of VisitResult. + Debug.assertEachNode(declarations, isVariableDeclaration); const declarationList = factory.createVariableDeclarationList(declarations); setOriginalNode(declarationList, node); diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 004c57a3f5c65..368965328851b 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -236,7 +236,7 @@ namespace ts { // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & (ModifierFlags.AccessibilityModifier | ModifierFlags.Readonly)) { - const constructor = find(container.members, isConstructorDeclaration); // TODO(jakebailey): `members` is a union of two arrays, so find doesn't work without help. + const constructor = find(container.members, isConstructorDeclaration); if (constructor) { return [...nodes, ...constructor.parameters]; } From 7a4a2c219d3c55c3516d6a90ca50e4da65151fa0 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 21 Sep 2022 23:14:30 -0700 Subject: [PATCH 39/81] Shift around TODO --- src/compiler/transformers/classFields.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 6d8ee0f80d77a..6771ce407a2cc 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -2358,7 +2358,8 @@ namespace ts { ); } - function visitArrayAssignmentTarget(node: ArrayBindingOrAssignmentElement) { + function visitArrayAssignmentTarget(node: Node) { + Debug.assertNode(node, isBindingOrAssignmentElement); // TODO(jakebailey): assertNode does not work on Expressions due to branding, so param is Node. const target = getTargetOfBindingOrAssignmentElement(node); if (target) { let wrapped: LeftHandSideExpression | undefined; @@ -2481,7 +2482,7 @@ namespace ts { // [ { set value(x) { this.#myProp = x; } }.value ] = [ "hello" ]; return factory.updateArrayLiteralExpression( node, - visitNodes(node.elements as NodeArray, visitArrayAssignmentTarget, isExpression) // TODO(jakebailey): Should elements be NodeArray? + visitNodes(node.elements, visitArrayAssignmentTarget, isExpression) ); } else { From 52ca3a60df5a097e2166273fff9be82838505ba7 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 09:33:08 -0700 Subject: [PATCH 40/81] Add a clarifying JSDoc comment to isParameterDeclaration --- src/compiler/utilities.ts | 7 +++++++ src/compiler/utilitiesPublic.ts | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 590aed844ce45..8a3a0b5888a41 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3450,6 +3450,13 @@ namespace ts { // return true if the argument is a ParameterDeclaration, it also returns true for nodes // that are children of ParameterDeclarations inside binding elements. // Probably, this should be called `rootDeclarationIsParameter`. + /** + * This function returns true if the this node's root declaration is a parameter. + * For example, passing a `ParameterDeclaration` will return true, as will passing a + * binding element that is a child of a `ParameterDeclaration`. + * + * If you are looking to test that a `Node` is a `ParameterDeclaration`, use `isParameter`. + */ export function isParameterDeclaration(node: VariableLikeDeclaration): boolean { const root = getRootDeclaration(node); return root.kind === SyntaxKind.Parameter; diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 446f05c810b74..96a6a5f749687 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -270,7 +270,8 @@ namespace ts { } // TODO(jakebailey): It is very weird that we have BindingElement and ArrayBindingElement; - // we should have ObjectBindingElement and ArrayBindingElement, which are both BindingElement. + // we should have ObjectBindingElement and ArrayBindingElement, which are both BindingElement, + // just like BindingPattern is a ObjectBindingPattern or a ArrayBindingPattern. export function isEmptyBindingElement(node: BindingElement | ArrayBindingElement): boolean { if (isOmittedExpression(node)) { return true; From a0af83b90c66a2c906338cf584e3c58360d41368 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 09:48:23 -0700 Subject: [PATCH 41/81] Cleanups and reverts --- src/compiler/checker.ts | 5 ++--- src/compiler/utilities.ts | 2 +- src/compiler/visitorPublic.ts | 2 +- src/services/inlayHints.ts | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0c2179d35d1fd..7e00463893092 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5187,8 +5187,7 @@ namespace ts { if (objectFlags & ObjectFlags.Reference) { Debug.assert(!!(type.flags & TypeFlags.Object)); - Debug.type(type); - return type.node ? visitAndTransformType(type, typeReferenceToTypeNode) : typeReferenceToTypeNode(type); + return (type as TypeReference).node ? visitAndTransformType(type as TypeReference, typeReferenceToTypeNode) : typeReferenceToTypeNode(type as TypeReference); } if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) { if (type.flags & TypeFlags.TypeParameter && contains(context.inferTypeParameters, type)) { @@ -7426,7 +7425,7 @@ namespace ts { } function includePrivateSymbol(symbol: Symbol) { - if (some(symbol.declarations, isParameter)) return; + if (some(symbol.declarations, isParameterDeclaration)) return; Debug.assertIsDefined(deferredPrivatesStack[deferredPrivatesStack.length - 1]); getUnusedName(unescapeLeadingUnderscores(symbol.escapedName), symbol); // Call to cache unique name for symbol // Blanket moving (import) aliases into the root private context should work, since imports are not valid within namespaces diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8a3a0b5888a41..fb9560ba5ca7c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3457,7 +3457,7 @@ namespace ts { * * If you are looking to test that a `Node` is a `ParameterDeclaration`, use `isParameter`. */ - export function isParameterDeclaration(node: VariableLikeDeclaration): boolean { + export function isParameterDeclaration(node: Declaration): boolean { const root = getRootDeclaration(node); return root.kind === SyntaxKind.Parameter; } diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 5f456bdae4ec3..f26a74f1751f8 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -214,7 +214,7 @@ namespace ts { for (let i = 0; i < count; i++) { const node = nodes[i + start]; const visited = node !== undefined ? (visitor ? visitor(node) : node) : undefined; - if (updated !== undefined || visited === undefined || visited !== node as VisitResult) { + if (updated !== undefined || visited === undefined || visited !== node) { if (updated === undefined) { // Ensure we have a copy of `nodes`, up to the current index. updated = nodes.slice(0, i); diff --git a/src/services/inlayHints.ts b/src/services/inlayHints.ts index 6229d3c079529..7462a2c6f2c7c 100644 --- a/src/services/inlayHints.ts +++ b/src/services/inlayHints.ts @@ -328,7 +328,7 @@ namespace ts.InlayHints { } function isHintableDeclaration(node: VariableDeclaration | ParameterDeclaration) { - if ((isParameter(node) || isVariableDeclaration(node) && isVarConst(node)) && node.initializer) { + if ((isParameterDeclaration(node) || isVariableDeclaration(node) && isVarConst(node)) && node.initializer) { const initializer = skipParentheses(node.initializer); return !(isHintableLiteral(initializer) || isNewExpression(initializer) || isObjectLiteralExpression(initializer) || isAssertionExpression(initializer)); } From d263e9bd50a9434ab92043d1ed8a4308e4a532c2 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 10:18:19 -0700 Subject: [PATCH 42/81] Move the undefined into the VisitResult --- src/compiler/transformers/classFields.ts | 10 +++---- src/compiler/transformers/declarations.ts | 4 +-- src/compiler/transformers/destructuring.ts | 6 ++--- src/compiler/transformers/es2015.ts | 10 +++---- src/compiler/transformers/es2017.ts | 4 +-- src/compiler/transformers/es2018.ts | 2 +- src/compiler/transformers/generators.ts | 8 +++--- src/compiler/transformers/jsx.ts | 4 +-- src/compiler/transformers/legacyDecorators.ts | 4 +-- .../transformers/module/esnextAnd2015.ts | 2 +- src/compiler/transformers/module/module.ts | 4 +-- src/compiler/transformers/module/system.ts | 6 ++--- src/compiler/transformers/ts.ts | 26 +++++++++---------- src/compiler/types.ts | 6 ++--- 14 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 6771ce407a2cc..4f2e324cfca14 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -211,7 +211,7 @@ namespace ts { return visited; } - function visitor(node: Node): VisitResult | undefined { + function visitor(node: Node): VisitResult { if (!(node.transformFlags & TransformFlags.ContainsClassFields) && !(node.transformFlags & TransformFlags.ContainsLexicalThisOrSuper)) { return node; @@ -274,7 +274,7 @@ namespace ts { /** * Visits a node in an expression whose result is discarded. */ - function discardedValueVisitor(node: Node): VisitResult | undefined { + function discardedValueVisitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.PostfixUnaryExpression: @@ -289,7 +289,7 @@ namespace ts { /** * Visits a node in a {@link HeritageClause}. */ - function heritageClauseVisitor(node: Node): VisitResult | undefined { + function heritageClauseVisitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.HeritageClause: return visitEachChild(node, heritageClauseVisitor, context); @@ -303,7 +303,7 @@ namespace ts { /** * Visits the assignment target of a destructuring assignment. */ - function assignmentTargetVisitor(node: Node): VisitResult | undefined { + function assignmentTargetVisitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.ArrayLiteralExpression: @@ -316,7 +316,7 @@ namespace ts { /** * Visits a member of a class. */ - function classElementVisitor(node: Node): VisitResult | undefined { + function classElementVisitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.Constructor: return visitConstructorDeclaration(node as ConstructorDeclaration); diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 25be6ea75f618..faf03fe5fda62 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -869,7 +869,7 @@ namespace ts { } } - function visitDeclarationSubtree(input: Node): VisitResult | undefined { + function visitDeclarationSubtree(input: Node): VisitResult { if (shouldStripInternal(input)) return; if (isDeclaration(input)) { if (isDeclarationAndNotVisible(input)) return; @@ -1122,7 +1122,7 @@ namespace ts { return node.parent.kind === SyntaxKind.MethodDeclaration && hasEffectiveModifier(node.parent, ModifierFlags.Private); } - function visitDeclarationStatements(input: Node): VisitResult | undefined { + function visitDeclarationStatements(input: Node): VisitResult { if (!isPreservedDeclarationStatement(input)) { // return undefined for unmatched kinds to omit them from the tree return; diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 99fdc53a45013..fd68010cdfc33 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -11,7 +11,7 @@ namespace ts { createArrayBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ArrayBindingOrAssignmentPattern; createObjectBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ObjectBindingOrAssignmentPattern; createArrayBindingOrAssignmentElement: (node: Identifier) => BindingOrAssignmentElement; - visitor?: (node: Node) => VisitResult | undefined; + visitor?: (node: Node) => VisitResult; } export const enum FlattenLevel { @@ -32,7 +32,7 @@ namespace ts { */ export function flattenDestructuringAssignment( node: VariableDeclaration | DestructuringAssignment, - visitor: ((node: Node) => VisitResult | undefined) | undefined, + visitor: ((node: Node) => VisitResult) | undefined, context: TransformationContext, level: FlattenLevel, needsValue?: boolean, @@ -172,7 +172,7 @@ namespace ts { */ export function flattenDestructuringBinding( node: VariableDeclaration | ParameterDeclaration, - visitor: (node: Node) => VisitResult | undefined, + visitor: (node: Node) => VisitResult, context: TransformationContext, level: FlattenLevel, rval?: Expression, diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 9301f12ff52c2..962b1343a36d4 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -374,15 +374,15 @@ namespace ts { || (getEmitFlags(node) & EmitFlags.TypeScriptClassWrapper) !== 0; } - function visitor(node: Node): VisitResult | undefined { + function visitor(node: Node): VisitResult { return shouldVisitNode(node) ? visitorWorker(node, /*expressionResultIsUnused*/ false) : node; } - function visitorWithUnusedExpressionResult(node: Node): VisitResult | undefined { + function visitorWithUnusedExpressionResult(node: Node): VisitResult { return shouldVisitNode(node) ? visitorWorker(node, /*expressionResultIsUnused*/ true) : node; } - function classWrapperStatementVisitor(node: Node): VisitResult | undefined { + function classWrapperStatementVisitor(node: Node): VisitResult { if (shouldVisitNode(node)) { const original = getOriginalNode(node); if (isPropertyDeclaration(original) && hasStaticModifier(original)) { @@ -399,14 +399,14 @@ namespace ts { return node; } - function callExpressionVisitor(node: Node): VisitResult | undefined { + function callExpressionVisitor(node: Node): VisitResult { if (node.kind === SyntaxKind.SuperKeyword) { return visitSuperKeyword(/*isExpressionOfCall*/ true); } return visitor(node); } - function visitorWorker(node: Node, expressionResultIsUnused: boolean): VisitResult | undefined { + function visitorWorker(node: Node, expressionResultIsUnused: boolean): VisitResult { switch (node.kind) { case SyntaxKind.StaticKeyword: return undefined; // elide static keyword diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 9e1fc97bec1f1..06a308bf2bddd 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -103,7 +103,7 @@ namespace ts { return visitEachChild(node, visitor, context); } - function visitor(node: Node): VisitResult | undefined { + function visitor(node: Node): VisitResult { if ((node.transformFlags & TransformFlags.ContainsES2017) === 0) { return node; } @@ -151,7 +151,7 @@ namespace ts { } } - function asyncBodyVisitor(node: Node): VisitResult | undefined { + function asyncBodyVisitor(node: Node): VisitResult { if (isNodeWithPossibleHoistedDeclaration(node)) { switch (node.kind) { case SyntaxKind.VariableStatement: diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index acc01826f85b8..a7b5d0a0555b1 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -127,7 +127,7 @@ namespace ts { return visitorWorker(node, /*expressionResultIsUnused*/ true); } - function visitorNoAsyncModifier(node: Node): VisitResult | undefined { + function visitorNoAsyncModifier(node: Node): VisitResult { if (node.kind === SyntaxKind.AsyncKeyword) { return undefined; } diff --git a/src/compiler/transformers/generators.ts b/src/compiler/transformers/generators.ts index 255ae5bdcef23..26ff5e31497d6 100644 --- a/src/compiler/transformers/generators.ts +++ b/src/compiler/transformers/generators.ts @@ -310,7 +310,7 @@ namespace ts { * * @param node The node to visit. */ - function visitor(node: Node): VisitResult | undefined { + function visitor(node: Node): VisitResult { const transformFlags = node.transformFlags; if (inStatementContainingYield) { return visitJavaScriptInStatementContainingYield(node); @@ -334,7 +334,7 @@ namespace ts { * * @param node The node to visit. */ - function visitJavaScriptInStatementContainingYield(node: Node): VisitResult | undefined { + function visitJavaScriptInStatementContainingYield(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.DoStatement: return visitDoStatement(node as DoStatement); @@ -354,7 +354,7 @@ namespace ts { * * @param node The node to visit. */ - function visitJavaScriptInGeneratorFunctionBody(node: Node): VisitResult | undefined { + function visitJavaScriptInGeneratorFunctionBody(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.FunctionDeclaration: return visitFunctionDeclaration(node as FunctionDeclaration); @@ -423,7 +423,7 @@ namespace ts { * * @param node The node to visit. */ - function visitGenerator(node: Node): VisitResult | undefined { + function visitGenerator(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.FunctionDeclaration: return visitFunctionDeclaration(node as FunctionDeclaration); diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index f80189476fd70..c10f279a2445b 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -114,7 +114,7 @@ namespace ts { return visited; } - function visitor(node: Node): VisitResult | undefined { + function visitor(node: Node): VisitResult { if (node.transformFlags & TransformFlags.ContainsJsx) { return visitorWorker(node); } @@ -123,7 +123,7 @@ namespace ts { } } - function visitorWorker(node: Node): VisitResult | undefined { + function visitorWorker(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.JsxElement: return visitJsxElement(node as JsxElement, /*isChild*/ false); diff --git a/src/compiler/transformers/legacyDecorators.ts b/src/compiler/transformers/legacyDecorators.ts index 2ccf17a301a26..3d85fa4ef5e71 100644 --- a/src/compiler/transformers/legacyDecorators.ts +++ b/src/compiler/transformers/legacyDecorators.ts @@ -31,11 +31,11 @@ namespace ts { return visited; } - function modifierVisitor(node: Node): VisitResult | undefined { + function modifierVisitor(node: Node): VisitResult { return isDecorator(node) ? undefined : node; } - function visitor(node: Node): VisitResult | undefined { + function visitor(node: Node): VisitResult { if (!(node.transformFlags & TransformFlags.ContainsDecorators)) { return node; } diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index b74a8400af150..d57378899e393 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -66,7 +66,7 @@ namespace ts { } } - function visitor(node: Node): VisitResult | undefined { + function visitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.ImportEqualsDeclaration: // Though an error in es2020 modules, in node-flavor es2020 modules, we can helpfully transform this to a synthetic `require` call diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index b9d4ddcb823b8..4862a27607ab7 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -505,7 +505,7 @@ namespace ts { * * @param node The node to visit. */ - function topLevelVisitor(node: Node): VisitResult | undefined { + function topLevelVisitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.ImportDeclaration: return visitImportDeclaration(node as ImportDeclaration); @@ -1743,7 +1743,7 @@ namespace ts { * * @param node The node to visit. */ - function modifierVisitor(node: Node): VisitResult | undefined { + function modifierVisitor(node: Node): VisitResult { // Elide module-specific modifiers. switch (node.kind) { case SyntaxKind.ExportKeyword: diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 5f09e6f7847fa..8e1f9e6118e74 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -577,7 +577,7 @@ namespace ts { * * @param node The node to visit. */ - function topLevelVisitor(node: Node): VisitResult | undefined { + function topLevelVisitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.ImportDeclaration: return visitImportDeclaration(node as ImportDeclaration); @@ -1162,7 +1162,7 @@ namespace ts { * * @param node The node to visit. */ - function topLevelNestedVisitor(node: Node): VisitResult | undefined { + function topLevelNestedVisitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.VariableStatement: return visitVariableStatement(node as VariableStatement); @@ -1667,7 +1667,7 @@ namespace ts { * * @param node The node to visit. */ - function modifierVisitor(node: Node): VisitResult | undefined { + function modifierVisitor(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.ExportKeyword: case SyntaxKind.DefaultKeyword: diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 57fad6e5a78bf..1a86061b6f9d4 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -181,7 +181,7 @@ namespace ts { * * @param node The node to visit. */ - function visitor(node: Node): VisitResult | undefined { + function visitor(node: Node): VisitResult { return saveStateAndInvoke(node, visitorWorker); } @@ -190,7 +190,7 @@ namespace ts { * * @param node The node to visit. */ - function visitorWorker(node: Node): VisitResult | undefined { + function visitorWorker(node: Node): VisitResult { if (node.transformFlags & TransformFlags.ContainsTypeScript) { return visitTypeScript(node); } @@ -202,7 +202,7 @@ namespace ts { * * @param node The node to visit. */ - function sourceElementVisitor(node: Node): VisitResult | undefined { + function sourceElementVisitor(node: Node): VisitResult { return saveStateAndInvoke(node, sourceElementVisitorWorker); } @@ -211,7 +211,7 @@ namespace ts { * * @param node The node to visit. */ - function sourceElementVisitorWorker(node: Node): VisitResult | undefined { + function sourceElementVisitorWorker(node: Node): VisitResult { switch (node.kind) { case SyntaxKind.ImportDeclaration: case SyntaxKind.ImportEqualsDeclaration: @@ -223,7 +223,7 @@ namespace ts { } } - function visitElidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult | undefined { + function visitElidableStatement(node: ImportDeclaration | ImportEqualsDeclaration | ExportAssignment | ExportDeclaration): VisitResult { const parsed = getParseTreeNode(node); if (parsed !== node) { // If the node has been transformed by a `before` transformer, perform no ellision on it @@ -256,7 +256,7 @@ namespace ts { * * @param node The node to visit. */ - function namespaceElementVisitor(node: Node): VisitResult | undefined { + function namespaceElementVisitor(node: Node): VisitResult { return saveStateAndInvoke(node, namespaceElementVisitorWorker); } @@ -265,7 +265,7 @@ namespace ts { * * @param node The node to visit. */ - function namespaceElementVisitorWorker(node: Node): VisitResult | undefined { + function namespaceElementVisitorWorker(node: Node): VisitResult { if (node.kind === SyntaxKind.ExportDeclaration || node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportClause || @@ -286,7 +286,7 @@ namespace ts { * * @param parent The class containing the elements to visit. */ - function getClassElementVisitor(parent: ClassLikeDeclaration): (node: Node) => VisitResult | undefined { + function getClassElementVisitor(parent: ClassLikeDeclaration): (node: Node) => VisitResult { return node => saveStateAndInvoke(node, n => classElementVisitorWorker(n, parent)); } @@ -295,7 +295,7 @@ namespace ts { * * @param node The node to visit. */ - function classElementVisitorWorker(node: Node, parent: ClassLikeDeclaration): VisitResult | undefined { + function classElementVisitorWorker(node: Node, parent: ClassLikeDeclaration): VisitResult { switch (node.kind) { case SyntaxKind.Constructor: return visitConstructor(node as ConstructorDeclaration); @@ -333,11 +333,11 @@ namespace ts { } } - function getObjectLiteralElementVisitor(parent: ObjectLiteralExpression): (node: T) => VisitResult | undefined { + function getObjectLiteralElementVisitor(parent: ObjectLiteralExpression): (node: T) => VisitResult { return node => saveStateAndInvoke(node, n => objectLiteralElementVisitorWorker(n, parent)); } - function objectLiteralElementVisitorWorker(node: Node, parent: ObjectLiteralExpression): VisitResult | undefined { + function objectLiteralElementVisitorWorker(node: Node, parent: ObjectLiteralExpression): VisitResult { switch (node.kind) { case SyntaxKind.PropertyAssignment: case SyntaxKind.ShorthandPropertyAssignment: @@ -362,7 +362,7 @@ namespace ts { } } - function modifierVisitor(node: Node): VisitResult | undefined { + function modifierVisitor(node: Node): VisitResult { if (isDecorator(node)) return undefined; if (modifierToFlag(node.kind) & ModifierFlags.TypeScriptModifier) { return undefined; @@ -379,7 +379,7 @@ namespace ts { * * @param node The node to visit. */ - function visitTypeScript(node: Node): VisitResult | undefined { + function visitTypeScript(node: Node): VisitResult { if (isStatement(node) && hasSyntacticModifier(node, ModifierFlags.Ambient)) { // TypeScript ambient declarations are elided, but some comments may be preserved. // See the implementation of `getLeadingComments` in comments.ts for more details. diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 17ee8ddb25037..da1476cb22170 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8357,7 +8357,7 @@ namespace ts { * @param ensureUseStrict boolean determining whether the function need to add prologue-directives * @param visitor Optional callback used to visit any custom prologue directives. */ - /* @internal */ copyPrologue(source: readonly Statement[], target: Push, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult | undefined): number; + /* @internal */ copyPrologue(source: readonly Statement[], target: Push, ensureUseStrict?: boolean, visitor?: (node: Node) => VisitResult): number; /** * Copies only the standard (string-expression) prologue-directives into the target statement-array. * @param source origin statements array @@ -8373,8 +8373,8 @@ namespace ts { * @param statementOffset The offset at which to begin the copy. * @param visitor Optional callback used to visit any custom prologue directives. */ - /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult | undefined, filter?: (node: Statement) => boolean): number; - /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult | undefined, filter?: (node: Statement) => boolean): number | undefined; + /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number, visitor?: (node: Node) => VisitResult, filter?: (node: Statement) => boolean): number; + /* @internal */ copyCustomPrologue(source: readonly Statement[], target: Push, statementOffset: number | undefined, visitor?: (node: Node) => VisitResult, filter?: (node: Statement) => boolean): number | undefined; /* @internal */ ensureUseStrict(statements: NodeArray): NodeArray; /* @internal */ liftToBlock(nodes: readonly Node[]): Statement; /** From 982c70675ea86b4bb54e8655fd6f8a889fa43317 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 10:27:03 -0700 Subject: [PATCH 43/81] Resolve a TODO --- src/compiler/transformers/es2015.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 962b1343a36d4..1219d1108cea7 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2194,16 +2194,9 @@ namespace ts { enableSubstitutionsForBlockScopedBindings(); } - // TODO(jakebailey): should this be... - // const declarations = visitNodes(node.declarations, node.flags & NodeFlags.Let - // ? visitVariableDeclarationInLetDeclarationList - // : visitVariableDeclaration, isVariableDeclaration); - - const declarations = flatMap(node.declarations, node.flags & NodeFlags.Let + const declarations = visitNodes(node.declarations, node.flags & NodeFlags.Let ? visitVariableDeclarationInLetDeclarationList - : visitVariableDeclaration); - - Debug.assertEachNode(declarations, isVariableDeclaration); + : visitVariableDeclaration, isVariableDeclaration); const declarationList = factory.createVariableDeclarationList(declarations); setOriginalNode(declarationList, node); From fce72fe95f183f211ce7326a72b5c02929e66f61 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 10:34:02 -0700 Subject: [PATCH 44/81] Change the other VisitResult uses for consistency --- src/compiler/transformers/declarations.ts | 2 +- src/compiler/transformers/es2015.ts | 2 +- src/compiler/transformers/module/esnextAnd2015.ts | 4 ++-- src/compiler/transformers/module/module.ts | 14 +++++++------- src/compiler/transformers/module/system.ts | 14 +++++++------- src/compiler/transformers/ts.ts | 8 ++++---- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index faf03fe5fda62..2f54dd765ac34 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -60,7 +60,7 @@ namespace ts { let enclosingDeclaration: Node; let necessaryTypeReferences: Set<[specifier: string, mode: SourceFile["impliedNodeFormat"] | undefined]> | undefined; let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined; - let lateStatementReplacementMap: ESMap | undefined>; + let lateStatementReplacementMap: ESMap>; let suppressNewDiagnosticContexts: boolean; let exportedModulesFromDeclarationEmit: Symbol[] | undefined; diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 1219d1108cea7..435aa444f18e7 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2348,7 +2348,7 @@ namespace ts { convertedLoopState!.labels!.set(idText(node.label), false); } - function visitLabeledStatement(node: LabeledStatement): VisitResult | undefined { + function visitLabeledStatement(node: LabeledStatement): VisitResult { if (convertedLoopState && !convertedLoopState.labels) { convertedLoopState.labels = new Map(); } diff --git a/src/compiler/transformers/module/esnextAnd2015.ts b/src/compiler/transformers/module/esnextAnd2015.ts index d57378899e393..b321fc74cefb3 100644 --- a/src/compiler/transformers/module/esnextAnd2015.ts +++ b/src/compiler/transformers/module/esnextAnd2015.ts @@ -139,7 +139,7 @@ namespace ts { * * @param node The node to visit. */ - function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult | undefined { + function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer."); let statements: Statement[] | undefined; @@ -181,7 +181,7 @@ namespace ts { return statements; } - function visitExportAssignment(node: ExportAssignment): VisitResult | undefined { + function visitExportAssignment(node: ExportAssignment): VisitResult { // Elide `export=` as it is not legal with --module ES6 return node.isExportEquals ? undefined : node; } diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 4862a27607ab7..6b6f0a482c1ee 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -891,7 +891,7 @@ namespace ts { * * @param node The node to visit. */ - function visitImportDeclaration(node: ImportDeclaration): VisitResult | undefined { + function visitImportDeclaration(node: ImportDeclaration): VisitResult { let statements: Statement[] | undefined; const namespaceDeclaration = getNamespaceDeclarationNode(node); if (moduleKind !== ModuleKind.AMD) { @@ -1011,7 +1011,7 @@ namespace ts { * * @param node The node to visit. */ - function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult | undefined { + function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer."); let statements: Statement[] | undefined; @@ -1087,7 +1087,7 @@ namespace ts { * * @param The node to visit. */ - function visitExportDeclaration(node: ExportDeclaration): VisitResult | undefined { + function visitExportDeclaration(node: ExportDeclaration): VisitResult { if (!node.moduleSpecifier) { // Elide export declarations with no module specifier as they are handled // elsewhere. @@ -1197,7 +1197,7 @@ namespace ts { * * @param node The node to visit. */ - function visitExportAssignment(node: ExportAssignment): VisitResult | undefined { + function visitExportAssignment(node: ExportAssignment): VisitResult { if (node.isExportEquals) { return undefined; } @@ -1221,7 +1221,7 @@ namespace ts { * * @param node The node to visit. */ - function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult | undefined { + function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { let statements: Statement[] | undefined; if (hasSyntacticModifier(node, ModifierFlags.Export)) { statements = append(statements, @@ -1263,7 +1263,7 @@ namespace ts { * * @param node The node to visit. */ - function visitClassDeclaration(node: ClassDeclaration): VisitResult | undefined { + function visitClassDeclaration(node: ClassDeclaration): VisitResult { let statements: Statement[] | undefined; if (hasSyntacticModifier(node, ModifierFlags.Export)) { statements = append(statements, @@ -1303,7 +1303,7 @@ namespace ts { * * @param node The node to visit. */ - function visitVariableStatement(node: VariableStatement): VisitResult | undefined { + function visitVariableStatement(node: VariableStatement): VisitResult { let statements: Statement[] | undefined; let variables: VariableDeclaration[] | undefined; let expressions: Expression[] | undefined; diff --git a/src/compiler/transformers/module/system.ts b/src/compiler/transformers/module/system.ts index 8e1f9e6118e74..3820317453361 100644 --- a/src/compiler/transformers/module/system.ts +++ b/src/compiler/transformers/module/system.ts @@ -601,7 +601,7 @@ namespace ts { * * @param node The node to visit. */ - function visitImportDeclaration(node: ImportDeclaration): VisitResult | undefined { + function visitImportDeclaration(node: ImportDeclaration): VisitResult { let statements: Statement[] | undefined; if (node.importClause) { hoistVariableDeclaration(getLocalNameForExternalImport(factory, node, currentSourceFile)!); // TODO: GH#18217 @@ -619,7 +619,7 @@ namespace ts { return singleOrMany(statements); } - function visitExportDeclaration(node: ExportDeclaration): VisitResult | undefined { + function visitExportDeclaration(node: ExportDeclaration): VisitResult { Debug.assertIsDefined(node); return undefined; } @@ -629,7 +629,7 @@ namespace ts { * * @param node The node to visit. */ - function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult | undefined { + function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { Debug.assert(isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer."); let statements: Statement[] | undefined; @@ -652,7 +652,7 @@ namespace ts { * * @param node The node to visit. */ - function visitExportAssignment(node: ExportAssignment): VisitResult | undefined { + function visitExportAssignment(node: ExportAssignment): VisitResult { if (node.isExportEquals) { // Elide `export=` as it is illegal in a SystemJS module. return undefined; @@ -675,7 +675,7 @@ namespace ts { * * @param node The node to visit. */ - function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult | undefined { + function visitFunctionDeclaration(node: FunctionDeclaration): VisitResult { if (hasSyntacticModifier(node, ModifierFlags.Export)) { hoistedStatements = append(hoistedStatements, factory.updateFunctionDeclaration( @@ -709,7 +709,7 @@ namespace ts { * * @param node The node to visit. */ - function visitClassDeclaration(node: ClassDeclaration): VisitResult | undefined { + function visitClassDeclaration(node: ClassDeclaration): VisitResult { let statements: Statement[] | undefined; // Hoist the name of the class declaration to the outer module body function. @@ -756,7 +756,7 @@ namespace ts { * * @param node The node to visit. */ - function visitVariableStatement(node: VariableStatement): VisitResult | undefined { + function visitVariableStatement(node: VariableStatement): VisitResult { if (!shouldHoistVariableDeclarationList(node.declarationList)) { return visitNode(node, visitor, isStatement); } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 1a86061b6f9d4..8a4b69c2d757f 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1973,7 +1973,7 @@ namespace ts { * * @param node The import declaration node. */ - function visitImportDeclaration(node: ImportDeclaration): VisitResult | undefined { + function visitImportDeclaration(node: ImportDeclaration): VisitResult { if (!node.importClause) { // Do not elide a side-effect only import declaration. // import "foo"; @@ -2046,7 +2046,7 @@ namespace ts { * * @param node The export assignment node. */ - function visitExportAssignment(node: ExportAssignment): VisitResult | undefined { + function visitExportAssignment(node: ExportAssignment): VisitResult { // Elide the export assignment if it does not reference a value. return resolver.isValueAliasDeclaration(node) ? visitEachChild(node, visitor, context) @@ -2058,7 +2058,7 @@ namespace ts { * * @param node The export declaration node. */ - function visitExportDeclaration(node: ExportDeclaration): VisitResult | undefined { + function visitExportDeclaration(node: ExportDeclaration): VisitResult { if (node.isTypeOnly) { return undefined; } @@ -2139,7 +2139,7 @@ namespace ts { * * @param node The import equals declaration node. */ - function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult | undefined { + function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult { // Always elide type-only imports if (node.isTypeOnly) { return undefined; From cd4aa3c6d57b47ecd3752fdd2aab195ccc1318f1 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 10:53:46 -0700 Subject: [PATCH 45/81] Cleanups --- src/compiler/transformers/declarations.ts | 3 +-- src/services/utilities.ts | 20 ++++++-------------- src/tsconfig-base.json | 2 -- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 2f54dd765ac34..f35a6c5279b6f 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -850,8 +850,7 @@ namespace ts { if (isLateVisibilityPaintedStatement(statement)) { const key = getOriginalNodeId(statement); if (lateStatementReplacementMap.has(key)) { - const result = lateStatementReplacementMap.get(key); - Debug.type(result); + const result = lateStatementReplacementMap.get(key) as Statement | readonly Statement[] | undefined; lateStatementReplacementMap.delete(key); if (result) { if (isArray(result) ? some(result, needsScopeMarker) : needsScopeMarker(result)) { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 135a3b19e8006..0758740af4fa9 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2545,6 +2545,12 @@ namespace ts { } function getSynthesizedDeepCloneWorker(node: T, replaceNode?: (node: Node) => Node | undefined): T { + const nodeClone: (n: T) => T = replaceNode + ? n => getSynthesizedDeepCloneWithReplacements(n, /*includeTrivia*/ true, replaceNode) + : getSynthesizedDeepClone; + const nodesClone: (ns: NodeArray | undefined) => NodeArray | undefined = replaceNode + ? ns => ns && getSynthesizedDeepClonesWithReplacements(ns, /*includeTrivia*/ true, replaceNode) + : ns => ns && getSynthesizedDeepClones(ns); const visited = visitEachChild(node, nodeClone, nullTransformationContext, nodesClone, nodeClone); @@ -2562,20 +2568,6 @@ namespace ts { // would have made. (visited as Mutable).parent = undefined!; return visited; - - function nodeClone(node: T): T { - return replaceNode - ? getSynthesizedDeepCloneWithReplacements(node, /*includeTrivia*/ true, replaceNode) - : getSynthesizedDeepClone(node); - } - - function nodesClone(nodes: NodeArray): NodeArray; - function nodesClone(nodes: NodeArray | undefined): NodeArray | undefined; - function nodesClone(nodes: NodeArray | undefined): NodeArray | undefined { - return replaceNode - ? nodes && getSynthesizedDeepClonesWithReplacements(nodes, /*includeTrivia*/ true, replaceNode) - : nodes && getSynthesizedDeepClones(nodes); - } } export function getSynthesizedDeepClones(nodes: NodeArray, includeTrivia?: boolean): NodeArray; diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index 6bdfcd3096be4..4ff7b1ec84d22 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -15,14 +15,12 @@ "strict": true, "strictBindCallApply": false, "useUnknownInCatchVariables": false, - // "strictFunctionTypes": false, "noUnusedLocals": true, "noUnusedParameters": true, "allowUnusedLabels": false, "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, "alwaysStrict": true, "preserveConstEnums": true, From 734c58f8d955e3e34090fb53e0653f778e72cc9b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 11:00:31 -0700 Subject: [PATCH 46/81] Eliminate isArrayOf --- src/compiler/core.ts | 9 - .../4.8/mergeDecoratorsAndModifiers.ts | 156 +++++++++--------- 2 files changed, 78 insertions(+), 87 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 28b4882a4c321..c055dc1a6f927 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -165,15 +165,6 @@ namespace ts { return true; } - /** - * Equivalent to every, but can discriminate between unions of arrays. - */ - export function isArrayOf(array: readonly any[], callback: (element: any, index: number) => element is T): array is readonly T[]; - export function isArrayOf(array: readonly any[] | undefined, callback: (element: any, index: number) => element is T): array is readonly T[] | undefined; - export function isArrayOf(array: readonly any[] | undefined, callback: (element: any, index: number) => boolean): boolean { - return every(array, callback); - } - /** Works like Array.prototype.find, returning `undefined` if no element satisfying the predicate is found. */ export function find(array: readonly T[] | undefined, predicate: (element: T, index: number) => element is U, startIndex?: number): U | undefined; export function find(array: readonly T[] | undefined, predicate: (element: T, index: number) => boolean, startIndex?: number): T | undefined; diff --git a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts index f7a235c1b1f61..a50bc0bed2419 100644 --- a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts +++ b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts @@ -400,7 +400,7 @@ namespace ts { (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || typeof questionToken === "object" && isQuestionToken(questionToken)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || isArrayOf(parameters, isParameter)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -409,7 +409,7 @@ namespace ts { (asteriskToken === undefined || typeof asteriskToken === "object" && isAsteriskToken(asteriskToken)) && (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || !isArray(questionToken)) && - (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -436,7 +436,7 @@ namespace ts { (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || typeof questionToken === "object" && isQuestionToken(questionToken)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || isArrayOf(parameters, isParameter)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -445,7 +445,7 @@ namespace ts { (asteriskToken === undefined || typeof asteriskToken === "object" && isAsteriskToken(asteriskToken)) && (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || !isArray(questionToken)) && - (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -468,13 +468,13 @@ namespace ts { .bind({ 0: ([modifiers, parameters, body, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && - (parameters === undefined || isArrayOf(parameters, isParameter)) && + (modifiers === undefined || every(modifiers, isModifier)) && + (parameters === undefined || every(parameters, isParameter)) && (body === undefined || !isArray(body)), 1: ([decorators, modifiers, parameters, body]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (decorators === undefined || every(decorators, isDecorator)) && + (modifiers === undefined || every(modifiers, isModifier)) && (parameters === undefined || isArray(parameters)) && (body === undefined || isBlock(body)), }) @@ -496,13 +496,13 @@ namespace ts { .bind({ 0: ([, modifiers, parameters, body, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && - (parameters === undefined || isArrayOf(parameters, isParameter)) && + (modifiers === undefined || every(modifiers, isModifier)) && + (parameters === undefined || every(parameters, isParameter)) && (body === undefined || !isArray(body)), 1: ([, decorators, modifiers, parameters, body]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (decorators === undefined || every(decorators, isDecorator)) && + (modifiers === undefined || every(modifiers, isModifier)) && (parameters === undefined || isArray(parameters)) && (body === undefined || isBlock(body)), }) @@ -640,13 +640,13 @@ namespace ts { .bind({ 0: ([modifiers, parameters, type, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && - (parameters === undefined || isArrayOf(parameters, isParameter)) && + (modifiers === undefined || every(modifiers, isModifier)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)), 1: ([decorators, modifiers, parameters, type]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (decorators === undefined || every(decorators, isDecorator)) && + (modifiers === undefined || every(modifiers, isModifier)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)), }) @@ -668,13 +668,13 @@ namespace ts { .bind({ 0: ([, modifiers, parameters, type, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && - (parameters === undefined || isArrayOf(parameters, isParameter)) && + (modifiers === undefined || every(modifiers, isModifier)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)), 1: ([, decorators, modifiers, parameters, type]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (decorators === undefined || every(decorators, isDecorator)) && + (modifiers === undefined || every(modifiers, isModifier)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)), }) @@ -750,14 +750,14 @@ namespace ts { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && - (members === undefined || isArrayOf(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && (members === undefined || isArray(members)), }) .deprecate({ @@ -780,14 +780,14 @@ namespace ts { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && - (members === undefined || isArrayOf(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, , modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && (members === undefined || isArray(members)), }) .deprecate({ @@ -811,7 +811,7 @@ namespace ts { (asteriskToken === undefined || !isArray(asteriskToken)) && (name === undefined || typeof name === "string" || isIdentifier(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || isArrayOf(parameters, isParameter)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -819,7 +819,7 @@ namespace ts { (modifiers === undefined || isArray(modifiers)) && (asteriskToken === undefined || typeof asteriskToken !== "string" && isAsteriskToken(asteriskToken)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -845,7 +845,7 @@ namespace ts { (asteriskToken === undefined || !isArray(asteriskToken)) && (name === undefined || isIdentifier(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || isArrayOf(parameters, isParameter)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -853,7 +853,7 @@ namespace ts { (modifiers === undefined || isArray(modifiers)) && (asteriskToken === undefined || typeof asteriskToken !== "string" && isAsteriskToken(asteriskToken)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -878,8 +878,8 @@ namespace ts { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && - (members === undefined || isArrayOf(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: () => true, }) @@ -903,14 +903,14 @@ namespace ts { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && - (members === undefined || isArrayOf(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, , modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && (members === undefined || isArray(members)), }) .deprecate({ @@ -931,18 +931,18 @@ namespace ts { .bind({ 0: ([modifiers, name, typeParameters, heritageClauses, members, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && - (members === undefined || isArrayOf(members, isTypeElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isTypeElement)), 1: ([decorators, modifiers, name, typeParameters, heritageClauses, members]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && (members === undefined || every(members, isTypeElement)), }) .deprecate({ @@ -963,18 +963,18 @@ namespace ts { .bind({ 0: ([, modifiers, name, typeParameters, heritageClauses, members, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && - (members === undefined || isArrayOf(members, isTypeElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isTypeElement)), 1: ([, decorators, modifiers, name, typeParameters, heritageClauses, members]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || isArrayOf(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || isArrayOf(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && (members === undefined || every(members, isTypeElement)), }) .deprecate({ @@ -995,13 +995,13 @@ namespace ts { .bind({ 0: ([modifiers, name, typeParameters, type, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && (type === undefined || !isArray(type)), 1: ([decorators, modifiers, name, typeParameters, type]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && @@ -1025,13 +1025,13 @@ namespace ts { .bind({ 0: ([, modifiers, name, typeParameters, type, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && (type === undefined || !isArray(type)), 1: ([, decorators, modifiers, name, typeParameters, type]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && @@ -1055,12 +1055,12 @@ namespace ts { .bind({ 0: ([modifiers, name, members, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), 1: ([decorators, modifiers, name, members]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), @@ -1083,12 +1083,12 @@ namespace ts { .bind({ 0: ([, modifiers, name, members, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), 1: ([, decorators, modifiers, name, members]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), @@ -1111,13 +1111,13 @@ namespace ts { .bind({ 0: ([modifiers, name, body, flags, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name !== undefined && !isArray(name)) && (body === undefined || isModuleBody(body)) && (flags === undefined || typeof flags === "number"), 1: ([decorators, modifiers, name, body, flags]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name !== undefined && isModuleName(name)) && (body === undefined || typeof body === "object") && @@ -1141,12 +1141,12 @@ namespace ts { .bind({ 0: ([, modifiers, name, body, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (body === undefined || isModuleBody(body)), 1: ([, decorators, modifiers, name, body]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name !== undefined && isModuleName(name)) && (body === undefined || isModuleBody(body)), @@ -1169,13 +1169,13 @@ namespace ts { .bind({ 0: ([modifiers, isTypeOnly, name, moduleReference, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name !== "boolean") && (typeof moduleReference !== "string"), 1: ([decorators, modifiers, isTypeOnly, name, moduleReference]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name === "string" || isIdentifier(name)) && @@ -1199,13 +1199,13 @@ namespace ts { .bind({ 0: ([, modifiers, isTypeOnly, name, moduleReference, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name !== "boolean") && (typeof moduleReference !== "string"), 1: ([, decorators, modifiers, isTypeOnly, name, moduleReference]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name === "string" || isIdentifier(name)) && @@ -1229,13 +1229,13 @@ namespace ts { .bind({ 0: ([modifiers, importClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (importClause === undefined || !isArray(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([decorators, modifiers, importClause, moduleSpecifier, assertClause]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (importClause === undefined || isImportClause(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && @@ -1259,13 +1259,13 @@ namespace ts { .bind({ 0: ([, modifiers, importClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (importClause === undefined || !isArray(importClause)) && (moduleSpecifier === undefined || isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([, decorators, modifiers, importClause, moduleSpecifier, assertClause]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (importClause === undefined || isImportClause(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && @@ -1289,12 +1289,12 @@ namespace ts { .bind({ 0: ([modifiers, isExportEquals, expression, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (isExportEquals === undefined || typeof isExportEquals === "boolean") && (typeof expression === "object"), 1: ([decorators, modifiers, isExportEquals, expression]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isExportEquals === undefined || typeof isExportEquals === "boolean") && (expression !== undefined && isExpression(expression)), @@ -1317,11 +1317,11 @@ namespace ts { .bind({ 0: ([, modifiers, expression, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (expression !== undefined && !isArray(expression)), 1: ([, decorators, modifiers, expression]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (expression !== undefined && isExpression(expression)), }) @@ -1343,14 +1343,14 @@ namespace ts { .bind({ 0: ([modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (typeof isTypeOnly === "boolean") && (typeof exportClause !== "boolean") && (moduleSpecifier === undefined || isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (typeof isTypeOnly === "boolean") && (exportClause === undefined || isNamedExportBindings(exportClause)) && @@ -1375,14 +1375,14 @@ namespace ts { .bind({ 0: ([, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || isArrayOf(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (typeof isTypeOnly === "boolean") && (typeof exportClause !== "boolean") && (moduleSpecifier === undefined || isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([, decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause]) => - (decorators === undefined || isArrayOf(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (typeof isTypeOnly === "boolean") && (exportClause === undefined || isNamedExportBindings(exportClause)) && From 1b7fbebad6f52345da2f1e8fc2c79120c13ec991 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 11:21:14 -0700 Subject: [PATCH 47/81] Remove cast for byteLength by using BufferEncoding type --- src/compiler/sys.ts | 1 - src/harness/harnessLanguageService.ts | 2 +- src/harness/harnessUtils.ts | 5 ----- src/server/session.ts | 6 +++--- src/testRunner/unittests/tsserver/helpers.ts | 2 +- src/testRunner/unittests/tsserver/session.ts | 10 +++++----- src/tsserver/nodeServer.ts | 2 +- tests/baselines/reference/api/tsserverlibrary.d.ts | 7 ++++--- tests/baselines/reference/api/typescript.d.ts | 1 + 9 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index bcc37fcd5a857..0a82092db4217 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -1246,7 +1246,6 @@ namespace ts { path => sys.directoryExists(path)); } - /*@internal*/ export type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex"; /*@internal*/ diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 6003a2ad6ce2a..36e1c7b3ac4c2 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -1001,7 +1001,7 @@ namespace Harness.LanguageService { useSingleInferredProject: false, useInferredProjectPerProjectRoot: false, typingsInstaller: { ...ts.server.nullTypingsInstaller, globalTypingsCacheLocation: "/Library/Caches/typescript" }, - byteLength: Utils.byteLength, + byteLength: Buffer.byteLength, hrtime: process.hrtime, logger: serverHost, canUseEvents: true diff --git a/src/harness/harnessUtils.ts b/src/harness/harnessUtils.ts index 5ac968035346d..c2124700158db 100644 --- a/src/harness/harnessUtils.ts +++ b/src/harness/harnessUtils.ts @@ -3,11 +3,6 @@ namespace Utils { return ts.sys.bufferFrom!(s).toString("utf8"); } - export function byteLength(s: string, encoding?: string): number { - // stub implementation if Buffer is not available (in-browser case) - return Buffer.byteLength(s, encoding as ts.BufferEncoding | undefined); - } - export function evalFile(fileContents: string, fileName: string, nodeContext?: any) { const vm = require("vm"); if (nodeContext) { diff --git a/src/server/session.ts b/src/server/session.ts index bb60da3106cd8..f95b0e938c4ce 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -127,7 +127,7 @@ namespace ts.server { export type CommandNames = protocol.CommandTypes; export const CommandNames = (protocol as any).CommandTypes; - export function formatMessage(msg: T, logger: Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string { + export function formatMessage(msg: T, logger: Logger, byteLength: (s: string, encoding: BufferEncoding) => number, newLine: string): string { const verboseLogging = logger.hasLevel(LogLevel.verbose); const json = JSON.stringify(msg); @@ -737,7 +737,7 @@ namespace ts.server { useSingleInferredProject: boolean; useInferredProjectPerProjectRoot: boolean; typingsInstaller: ITypingsInstaller; - byteLength: (buf: string, encoding?: string) => number; + byteLength: (buf: string, encoding?: BufferEncoding) => number; hrtime: (start?: [number, number]) => [number, number]; logger: Logger; /** @@ -772,7 +772,7 @@ namespace ts.server { protected host: ServerHost; private readonly cancellationToken: ServerCancellationToken; protected readonly typingsInstaller: ITypingsInstaller; - protected byteLength: (buf: string, encoding?: string) => number; + protected byteLength: (buf: string, encoding?: BufferEncoding) => number; private hrtime: (start?: [number, number]) => [number, number]; protected logger: Logger; diff --git a/src/testRunner/unittests/tsserver/helpers.ts b/src/testRunner/unittests/tsserver/helpers.ts index 323e07a876d1a..1dcc52ad83276 100644 --- a/src/testRunner/unittests/tsserver/helpers.ts +++ b/src/testRunner/unittests/tsserver/helpers.ts @@ -461,7 +461,7 @@ namespace ts.projectSystem { useSingleInferredProject: false, useInferredProjectPerProjectRoot: false, typingsInstaller: undefined!, // TODO: GH#18217 - byteLength: Utils.byteLength, + byteLength: Buffer.byteLength, hrtime: process.hrtime, logger: opts.logger || createHasErrorMessageLogger(), canUseEvents: false diff --git a/src/testRunner/unittests/tsserver/session.ts b/src/testRunner/unittests/tsserver/session.ts index 77daa4c813bf2..03f3dcf64dbed 100644 --- a/src/testRunner/unittests/tsserver/session.ts +++ b/src/testRunner/unittests/tsserver/session.ts @@ -46,7 +46,7 @@ namespace ts.server { useSingleInferredProject: false, useInferredProjectPerProjectRoot: false, typingsInstaller: undefined!, // TODO: GH#18217 - byteLength: Utils.byteLength, + byteLength: Buffer.byteLength, hrtime: process.hrtime, logger: projectSystem.nullLogger(), canUseEvents: true @@ -345,7 +345,7 @@ namespace ts.server { it("is an overrideable handle which sends protocol messages over the wire", () => { const msg: protocol.Request = { seq: 0, type: "request", command: "" }; const strmsg = JSON.stringify(msg); - const len = 1 + Utils.byteLength(strmsg, "utf8"); + const len = 1 + Buffer.byteLength(strmsg, "utf8"); const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`; session.send = Session.prototype.send; @@ -468,7 +468,7 @@ namespace ts.server { useSingleInferredProject: false, useInferredProjectPerProjectRoot: false, typingsInstaller: undefined!, // TODO: GH#18217 - byteLength: Utils.byteLength, + byteLength: Buffer.byteLength, hrtime: process.hrtime, logger: projectSystem.nullLogger(), canUseEvents: true @@ -515,7 +515,7 @@ namespace ts.server { useSingleInferredProject: false, useInferredProjectPerProjectRoot: false, typingsInstaller: undefined!, // TODO: GH#18217 - byteLength: Utils.byteLength, + byteLength: Buffer.byteLength, hrtime: process.hrtime, logger: projectSystem.createHasErrorMessageLogger(), canUseEvents: true @@ -583,7 +583,7 @@ namespace ts.server { useSingleInferredProject: false, useInferredProjectPerProjectRoot: false, typingsInstaller: undefined!, // TODO: GH#18217 - byteLength: Utils.byteLength, + byteLength: Buffer.byteLength, hrtime: process.hrtime, logger: projectSystem.createHasErrorMessageLogger(), canUseEvents: true diff --git a/src/tsserver/nodeServer.ts b/src/tsserver/nodeServer.ts index d1e03d37ea45a..0bfc5f5871931 100644 --- a/src/tsserver/nodeServer.ts +++ b/src/tsserver/nodeServer.ts @@ -691,7 +691,7 @@ namespace ts.server { cancellationToken, ...options, typingsInstaller: typingsInstaller || nullTypingsInstaller, - byteLength: Buffer.byteLength as (buf: string, encoding?: string | undefined) => number, + byteLength: Buffer.byteLength, hrtime: process.hrtime, logger, canUseEvents: true, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5f10f8a85560e..96d6c71a02b27 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4207,6 +4207,7 @@ declare namespace ts { } export type FileWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, modifiedTime?: Date) => void; export type DirectoryWatcherCallback = (fileName: string) => void; + export type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex"; export interface System { args: string[]; newLine: string; @@ -10706,7 +10707,7 @@ declare namespace ts.server { } type CommandNames = protocol.CommandTypes; const CommandNames: any; - function formatMessage(msg: T, logger: Logger, byteLength: (s: string, encoding: string) => number, newLine: string): string; + function formatMessage(msg: T, logger: Logger, byteLength: (s: string, encoding: BufferEncoding) => number, newLine: string): string; type Event = (body: T, eventName: string) => void; interface EventSender { event: Event; @@ -10717,7 +10718,7 @@ declare namespace ts.server { useSingleInferredProject: boolean; useInferredProjectPerProjectRoot: boolean; typingsInstaller: ITypingsInstaller; - byteLength: (buf: string, encoding?: string) => number; + byteLength: (buf: string, encoding?: BufferEncoding) => number; hrtime: (start?: [number, number]) => [number, number]; logger: Logger; /** @@ -10747,7 +10748,7 @@ declare namespace ts.server { protected host: ServerHost; private readonly cancellationToken; protected readonly typingsInstaller: ITypingsInstaller; - protected byteLength: (buf: string, encoding?: string) => number; + protected byteLength: (buf: string, encoding?: BufferEncoding) => number; private hrtime; protected logger: Logger; protected canUseEvents: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3e5e77ae64201..5ad5f614663d4 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4207,6 +4207,7 @@ declare namespace ts { } export type FileWatcherCallback = (fileName: string, eventKind: FileWatcherEventKind, modifiedTime?: Date) => void; export type DirectoryWatcherCallback = (fileName: string) => void; + export type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex"; export interface System { args: string[]; newLine: string; From a4874b185a54ea7cdcf444a03df1be4609297f2f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 11:41:04 -0700 Subject: [PATCH 48/81] Remove checks --- src/compiler/visitorPublic.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index f26a74f1751f8..76cd576a47112 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -56,8 +56,6 @@ namespace ts { return visitedNode; } - ((_: NodeVisitor) => {})(visitNode); // Check that visitNode is a NodeVisitor. - /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -137,8 +135,6 @@ namespace ts { return nodes; } - ((_: NodesVisitor) => {})(visitNodes); // Check that visitNode is a NodeVisitor. - /* @internal */ export function visitArray( nodes: TInArray, From d3c8231e26acbc39fb4715441710f9bbe7acdd52 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 12:23:25 -0700 Subject: [PATCH 49/81] Resolve some TODOs --- src/compiler/factory/parenthesizerRules.ts | 5 +---- src/compiler/transformers/classFields.ts | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts index d1abb81d20764..ee5edf4fe303f 100644 --- a/src/compiler/factory/parenthesizerRules.ts +++ b/src/compiler/factory/parenthesizerRules.ts @@ -603,10 +603,7 @@ namespace ts { } function castToNodeArray(nodes: readonly T[]): NodeArray { - // TODO(jakebailey): Why do we need this helper? It seems like `cast(nodes, isNodeArray)` should be enough. - // Also, this typeof shouldn't be needed, but https://github.com/microsoft/TypeScript/issues/50161 - // makes any change to this file cause an error to appear. - return cast(nodes, isNodeArray as typeof isNodeArray); + return cast, readonly T[]>(nodes, isNodeArray); } export const nullParenthesizerRules: ParenthesizerRules = { diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index 4f2e324cfca14..3172e73dc6461 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -2359,7 +2359,7 @@ namespace ts { } function visitArrayAssignmentTarget(node: Node) { - Debug.assertNode(node, isBindingOrAssignmentElement); // TODO(jakebailey): assertNode does not work on Expressions due to branding, so param is Node. + Debug.assertNode(node, isBindingOrAssignmentElement); const target = getTargetOfBindingOrAssignmentElement(node); if (target) { let wrapped: LeftHandSideExpression | undefined; From 76ca9626c907c9b29f8d2a092769475c39760f99 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 22 Sep 2022 12:24:23 -0700 Subject: [PATCH 50/81] Fix lint --- src/compiler/utilities.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index fb9560ba5ca7c..d651a909414c2 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3454,7 +3454,7 @@ namespace ts { * This function returns true if the this node's root declaration is a parameter. * For example, passing a `ParameterDeclaration` will return true, as will passing a * binding element that is a child of a `ParameterDeclaration`. - * + * * If you are looking to test that a `Node` is a `ParameterDeclaration`, use `isParameter`. */ export function isParameterDeclaration(node: Declaration): boolean { From b95dc388987339fac07dc4095c2a438c62ab831a Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 26 Sep 2022 15:17:16 -0700 Subject: [PATCH 51/81] Mark new helper as internal --- src/compiler/utilitiesPublic.ts | 1 + tests/baselines/reference/api/tsserverlibrary.d.ts | 1 - tests/baselines/reference/api/typescript.d.ts | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 96a6a5f749687..3b483b98a15de 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1490,6 +1490,7 @@ namespace ts { return false; } + /* @internal */ export function isBindingOrAssignmentElement(node: Node): node is BindingOrAssignmentElement { return isVariableDeclaration(node) || isParameter(node) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 9bdb01079954f..9e0a33917f70b 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4572,7 +4572,6 @@ declare namespace ts { */ function isTypeNode(node: Node): node is TypeNode; function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode; - function isBindingOrAssignmentElement(node: Node): node is BindingOrAssignmentElement; function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName; function isCallLikeExpression(node: Node): node is CallLikeExpression; function isCallOrNewExpression(node: Node): node is CallExpression | NewExpression; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c440caf64bc45..6b2a37386b89b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4572,7 +4572,6 @@ declare namespace ts { */ function isTypeNode(node: Node): node is TypeNode; function isFunctionOrConstructorTypeNode(node: Node): node is FunctionTypeNode | ConstructorTypeNode; - function isBindingOrAssignmentElement(node: Node): node is BindingOrAssignmentElement; function isPropertyAccessOrQualifiedName(node: Node): node is PropertyAccessExpression | QualifiedName; function isCallLikeExpression(node: Node): node is CallLikeExpression; function isCallOrNewExpression(node: Node): node is CallExpression | NewExpression; From 46a5d919b46af7df40669e05ee4fc92cd3ab17f5 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 20 Oct 2022 11:53:37 -0700 Subject: [PATCH 52/81] Duplicate jsdoc --- src/compiler/visitorPublic.ts | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 76cd576a47112..e7f7450a7bfa8 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -19,6 +19,20 @@ namespace ts { test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node, ): TOut | (TIn & undefined) | (TVisited & undefined); + /** + * Visits a Node using the supplied visitor, possibly returning a new Node in its place. + * + * - If the input node is undefined, then the output is undefined. + * - If the visitor returns undefined, then the output is undefined. + * - If the output node is not undefined, then it will satisfy the test function. + * - In order to obtain a return type that is more specific than `Node`, a test + * function _must_ be provided, and that function must be a type predicate. + * + * @param node The Node to visit. + * @param visitor The callback used to visit the Node. + * @param test A callback to execute to verify the Node is valid. + * @param lift An optional callback to execute to lift a NodeArray into a valid Node. + */ export function visitNode( node: TIn, visitor: Visitor, TVisited> | undefined, @@ -78,6 +92,21 @@ namespace ts { start?: number, count?: number, ): NodeArray | (TInArray & undefined); + /** + * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. + * + * - If the input node array is undefined, the output is undefined. + * - If the visitor can return undefined, the node it visits in the array will be reused. + * - If the output node array is not undefined, then its contents will satisfy the test. + * - In order to obtain a return type that is more specific than `NodeArray`, a test + * function _must_ be provided, and that function must be a type predicate. + * + * @param nodes The NodeArray to visit. + * @param visitor The callback used to visit a Node. + * @param test A node test to execute for each node. + * @param start An optional value indicating the starting offset at which to start visiting. + * @param count An optional value indicating the maximum number of nodes to visit. + */ export function visitNodes | undefined>( nodes: TInArray, visitor: Visitor | undefined, From f89c0c426546d41b30570f3cb20d82184018f551 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 20 Oct 2022 12:20:45 -0700 Subject: [PATCH 53/81] Accept baselines --- .../reference/api/tsserverlibrary.d.ts | 29 +++++++++++++++++++ tests/baselines/reference/api/typescript.d.ts | 29 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index e699e1d18b85f..49d0c86b32ef9 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -5095,6 +5095,20 @@ declare namespace ts { * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); + /** + * Visits a Node using the supplied visitor, possibly returning a new Node in its place. + * + * - If the input node is undefined, then the output is undefined. + * - If the visitor returns undefined, then the output is undefined. + * - If the output node is not undefined, then it will satisfy the test function. + * - In order to obtain a return type that is more specific than `Node`, a test + * function _must_ be provided, and that function must be a type predicate. + * + * @param node The Node to visit. + * @param visitor The callback used to visit the Node. + * @param test A callback to execute to verify the Node is valid. + * @param lift An optional callback to execute to lift a NodeArray into a valid Node. + */ function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. @@ -5112,6 +5126,21 @@ declare namespace ts { * @param count An optional value indicating the maximum number of nodes to visit. */ function visitNodes | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + /** + * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. + * + * - If the input node array is undefined, the output is undefined. + * - If the visitor can return undefined, the node it visits in the array will be reused. + * - If the output node array is not undefined, then its contents will satisfy the test. + * - In order to obtain a return type that is more specific than `NodeArray`, a test + * function _must_ be provided, and that function must be a type predicate. + * + * @param nodes The NodeArray to visit. + * @param visitor The callback used to visit a Node. + * @param test A node test to execute for each node. + * @param start An optional value indicating the starting offset at which to start visiting. + * @param count An optional value indicating the maximum number of nodes to visit. + */ function visitNodes | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); /** diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index e5475b7ec9acf..d1bf2134a596d 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5095,6 +5095,20 @@ declare namespace ts { * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); + /** + * Visits a Node using the supplied visitor, possibly returning a new Node in its place. + * + * - If the input node is undefined, then the output is undefined. + * - If the visitor returns undefined, then the output is undefined. + * - If the output node is not undefined, then it will satisfy the test function. + * - In order to obtain a return type that is more specific than `Node`, a test + * function _must_ be provided, and that function must be a type predicate. + * + * @param node The Node to visit. + * @param visitor The callback used to visit the Node. + * @param test A callback to execute to verify the Node is valid. + * @param lift An optional callback to execute to lift a NodeArray into a valid Node. + */ function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. @@ -5112,6 +5126,21 @@ declare namespace ts { * @param count An optional value indicating the maximum number of nodes to visit. */ function visitNodes | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + /** + * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. + * + * - If the input node array is undefined, the output is undefined. + * - If the visitor can return undefined, the node it visits in the array will be reused. + * - If the output node array is not undefined, then its contents will satisfy the test. + * - In order to obtain a return type that is more specific than `NodeArray`, a test + * function _must_ be provided, and that function must be a type predicate. + * + * @param nodes The NodeArray to visit. + * @param visitor The callback used to visit a Node. + * @param test A node test to execute for each node. + * @param start An optional value indicating the starting offset at which to start visiting. + * @param count An optional value indicating the maximum number of nodes to visit. + */ function visitNodes | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); /** From 56f36a56974d47b2d65f4b893aa63e9938a70c67 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 26 Oct 2022 22:32:35 -0700 Subject: [PATCH 54/81] Fix recent bug found by SFT --- src/compiler/transformers/es2017.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index d1ac4529651c7..2d2392a0f3b46 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -284,7 +284,7 @@ namespace ts { function visitConstructorDeclaration(node: ConstructorDeclaration) { return factory.updateConstructorDeclaration( node, - visitNodes(node.modifiers, visitor, isModifierLike), + visitNodes(node.modifiers, visitor, isModifier), visitParameterList(node.parameters, visitor, context), transformMethodBody(node) ); From 8e8d706cab78516178e669509f59169ca3013543 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 4 Nov 2022 21:46:10 -0700 Subject: [PATCH 55/81] Fix compiler error --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3e6cdfbaf3dff..8d5c77db221ee 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21482,7 +21482,7 @@ namespace ts { } function getCombinedTypeFlags(types: Type[]): TypeFlags { - return reduceLeft(types, (flags, t) => flags | (t.flags & TypeFlags.Union ? getCombinedTypeFlags((t as UnionType).types) : t.flags), 0); + return reduceLeft(types, (flags, t) => flags | (t.flags & TypeFlags.Union ? getCombinedTypeFlags((t as UnionType).types) : t.flags), 0 as TypeFlags); } function getCommonSupertype(types: Type[]): Type { From 9eb27201054fc541489f5fe0978bb7dce9c40b82 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 7 Nov 2022 12:02:17 -0800 Subject: [PATCH 56/81] Remove unused Parent type param --- src/compiler/emitter.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index c1ef0211197db..4cb07269b63ea 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4406,15 +4406,15 @@ namespace ts { } } - function emitList>(parentNode: Parent | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { + function emitList>(parentNode: Node | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { emitNodeList(emit, parentNode, children, format, parenthesizerRule, start, count); } - function emitExpressionList>(parentNode: Parent | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { + function emitExpressionList>(parentNode: Node | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule?: ParenthesizerRuleOrSelector, start?: number, count?: number) { emitNodeList(emitExpression, parentNode, children, format, parenthesizerRule, start, count); } - function emitNodeList>(emit: EmitFunction, parentNode: Parent | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start = 0, count = children ? children.length - start : 0) { + function emitNodeList>(emit: EmitFunction, parentNode: Node | undefined, children: Children | undefined, format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start = 0, count = children ? children.length - start : 0) { const isUndefined = children === undefined; if (isUndefined && format & ListFormat.OptionalIfUndefined) { return; @@ -4464,7 +4464,7 @@ namespace ts { * * NOTE: You probably don't want to call this directly and should be using `emitList` or `emitExpressionList` instead. */ - function emitNodeListItems(emit: EmitFunction, parentNode: Parent | undefined, children: readonly Child[], format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start: number, count: number, hasTrailingComma: boolean, childrenTextRange: TextRange | undefined) { + function emitNodeListItems(emit: EmitFunction, parentNode: Node | undefined, children: readonly Child[], format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start: number, count: number, hasTrailingComma: boolean, childrenTextRange: TextRange | undefined) { // Write the opening line terminator or leading whitespace. const mayEmitInterveningComments = (format & ListFormat.NoInterveningComments) === 0; let shouldEmitInterveningComments = mayEmitInterveningComments; From 8d17434c4e3d162beb92eb12f4ea64d8d6a001ca Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 7 Nov 2022 22:24:26 -0800 Subject: [PATCH 57/81] Fix merge issues --- src/compiler/checker.ts | 2 +- src/compiler/commandLineParser.ts | 2 +- src/compiler/core.ts | 20 ++++++++++++------- src/compiler/emitter.ts | 2 +- src/compiler/parser.ts | 8 ++++---- src/compiler/transformers/classFields.ts | 10 +++++----- src/compiler/transformers/declarations.ts | 8 ++++---- src/compiler/transformers/es2015.ts | 4 ++-- src/compiler/transformers/ts.ts | 6 +++--- src/compiler/utilitiesPublic.ts | 6 +++--- src/compiler/visitorPublic.ts | 12 +++++------ src/compiler/watch.ts | 6 +++--- src/harness/fourslashImpl.ts | 2 +- src/services/textChanges.ts | 14 ++++++------- .../reference/api/tsserverlibrary.d.ts | 7 ------- tests/baselines/reference/api/typescript.d.ts | 7 ------- 16 files changed, 54 insertions(+), 62 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5292d9ae0d114..34884bfa06b83 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3149,7 +3149,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return valueSymbol; } const result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName); - Debug.assert(valueSymbol.declarations || typeSymbol.declarations); + Debug.assert(valueSymbol.declarations || typeSymbol.declarations); result.declarations = deduplicate(concatenate(valueSymbol.declarations!, typeSymbol.declarations), equateValues); result.parent = valueSymbol.parent || typeSymbol.parent; if (valueSymbol.valueDeclaration) result.valueDeclaration = valueSymbol.valueDeclaration; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 66e5bdfe9c812..936e637ffb897 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -3592,7 +3592,7 @@ function validateSpecs(specs: readonly string[], errors: Push, disal } function specToDiagnostic(spec: CompilerOptionsValue, disallowTrailingRecursion?: boolean): [DiagnosticMessage, string] | undefined { - Debug.assert(typeof spec === "string"); + Debug.assert(typeof spec === "string"); if (disallowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { return [Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec]; } diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 1a819a5a76dc1..a686bb49613d8 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -181,9 +181,11 @@ export function intersperse(input: T[], element: T): T[] { * * @internal */ - export function every(array: readonly T[], callback: (element: T, index: number) => element is U): array is readonly U[]; - export function every(array: readonly T[] | undefined, callback: (element: T, index: number) => element is U): array is readonly U[] | undefined; - export function every(array: readonly T[] | undefined, callback: (element: T, index: number) => boolean): boolean; +export function every(array: readonly T[], callback: (element: T, index: number) => element is U): array is readonly U[]; +/** @internal */ +export function every(array: readonly T[] | undefined, callback: (element: T, index: number) => element is U): array is readonly U[] | undefined; +/** @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++) { @@ -805,12 +807,16 @@ export function concatenate(array1: T[], array2: T[]): T[]; export function concatenate(array1: readonly T[], array2: readonly T[]): readonly T[]; /** @internal */ export function concatenate(array1: T[], array2: T[] | undefined): T[]; // eslint-disable-line @typescript-eslint/unified-signatures - export function concatenate(array1: T[] | undefined, array2: T[]): T[]; // eslint-disable-line @typescript-eslint/unified-signatures - export function concatenate(array1: readonly T[], array2: readonly T[] | undefined): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures +/** @internal */ +export function concatenate(array1: T[] | undefined, array2: T[]): T[]; // eslint-disable-line @typescript-eslint/unified-signatures +/** @internal */ +export function concatenate(array1: readonly T[], array2: readonly T[] | undefined): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures /** @internal */ export function concatenate(array1: readonly T[] | undefined, array2: readonly T[]): readonly T[]; // eslint-disable-line @typescript-eslint/unified-signatures - export function concatenate(array1: T[] | undefined, array2: T[] | undefined): T[] | undefined; - export function concatenate(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined; +/** @internal */ +export function concatenate(array1: T[] | undefined, array2: T[] | undefined): T[] | undefined; +/** @internal */ +export function concatenate(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined; /** @internal */ export function concatenate(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined { if (!some(array2)) return array1; diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 9562d912c0693..ebad41654c903 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -6120,7 +6120,7 @@ type ParenthesizerRule = (node: T) => T; type ParenthesizerRuleOrSelector = OrdinalParentheizerRuleSelector | ParenthesizerRule; type EmitFunction = (node: T, parenthesizerRule?: ParenthesizerRule) => void; - type EmitListItemFunction = (node: Node, emit: EmitFunction, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, index: number) => void; +type EmitListItemFunction = (node: Node, emit: EmitFunction, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, index: number) => void; function emitListItemNoParenthesizer(node: Node, emit: EmitFunction, _parenthesizerRule: ParenthesizerRuleOrSelector | undefined, _index: number) { emit(node); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 0ae81db456df8..98728706180a6 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -9297,7 +9297,7 @@ namespace IncrementalParser { return; function visitNode(node: Node) { - Debug.type(node); + Debug.type(node); let text = ""; if (aggressiveChecks && shouldCheckNode(node)) { text = oldText.substring(node.pos, node.end); @@ -9325,7 +9325,7 @@ namespace IncrementalParser { } function visitArray(array: NodeArray) { - Debug.type(array); + Debug.type(array); array._children = undefined; setTextRangePosEnd(array, array.pos + delta, array.end + delta); @@ -9451,7 +9451,7 @@ namespace IncrementalParser { return; function visitNode(child: Node) { - Debug.type(child); + Debug.type(child); Debug.assert(child.pos <= child.end); if (child.pos > changeRangeOldEnd) { // Node is entirely past the change range. We need to move both its pos and @@ -9485,7 +9485,7 @@ namespace IncrementalParser { } function visitArray(array: NodeArray) { - Debug.type(array); + Debug.type(array); Debug.assert(array.pos <= array.end); if (array.pos > changeRangeOldEnd) { // Array is entirely after the change range. We need to move it, and move any of diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index a97af40cf37b8..79570d48d04ac 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -426,7 +426,7 @@ export function transformClassFields(context: TransformationContext): (x: Source const info = accessPrivateIdentifier(node.left); if (info) { const receiver = visitNode(node.right, visitor, isExpression); - Debug.assert(receiver); + Debug.assert(receiver); return setOriginalNode( context.getEmitHelperFactory().createClassPrivateFieldInHelper(info.brandCheckIdentifier, receiver), @@ -773,7 +773,7 @@ export function transformClassFields(context: TransformationContext): (x: Source let info: PrivateIdentifierInfo | undefined; if (info = accessPrivateIdentifier(operand.name)) { const receiver = visitNode(operand.expression, visitor, isExpression); - Debug.assert(receiver); + Debug.assert(receiver); const { readExpression, initializeExpression } = createCopiableReceiverExpr(receiver); let expression: Expression = createPrivateIdentifierAccess(info, readExpression); @@ -1060,7 +1060,7 @@ export function transformClassFields(context: TransformationContext): (x: Source setOriginalNode(superPropertyGet, node.left); setTextRange(superPropertyGet, node.left); - Debug.assert(expression); + Debug.assert(expression); expression = factory.createBinaryExpression( superPropertyGet, getNonAssignmentOperatorForCompoundAssignment(node.operatorToken.kind), @@ -1071,12 +1071,12 @@ export function transformClassFields(context: TransformationContext): (x: Source const temp = valueIsDiscarded ? undefined : factory.createTempVariable(hoistVariableDeclaration); if (temp) { - Debug.assert(expression); + Debug.assert(expression); expression = factory.createAssignment(temp, expression); setTextRange(temp, node); } - Debug.assert(expression); + Debug.assert(expression); expression = factory.createReflectSetCall( superClassReference, setterName, diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 68d7f7171f8d7..40dcc770f17b8 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1111,10 +1111,10 @@ export function transformDeclarations(context: TransformationContext) { const trueType = visitNode(input.trueType, visitDeclarationSubtree, isTypeNode); enclosingDeclaration = oldEnclosingDecl; const falseType = visitNode(input.falseType, visitDeclarationSubtree, isTypeNode); - Debug.assert(checkType); - Debug.assert(extendsType); - Debug.assert(trueType); - Debug.assert(falseType); + Debug.assert(checkType); + Debug.assert(extendsType); + Debug.assert(trueType); + Debug.assert(falseType); return cleanup(factory.updateConditionalTypeNode(input, checkType, extendsType, trueType, falseType)); } case SyntaxKind.FunctionType: { diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 55d43139a5a38..76bc52958e793 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -2543,7 +2543,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile } else { const statement = visitNode(node.statement, visitor, isStatement, factory.liftToBlock); - Debug.assert(statement); + Debug.assert(statement); if (isBlock(statement)) { return factory.updateBlock(statement, setTextRange(factory.createNodeArray(concatenate(statements, statement.statements)), statement.statements)); } @@ -2637,7 +2637,7 @@ export function transformES2015(context: TransformationContext): (x: SourceFile function convertForOfStatementForIterable(node: ForOfStatement, outermostLabeledStatement: LabeledStatement | undefined, convertedLoopBodyStatements: Statement[] | undefined, ancestorFacts: HierarchyFacts): Statement { const expression = visitNode(node.expression, visitor, isExpression); - Debug.assert(expression); + Debug.assert(expression); const iterator = isIdentifier(expression) ? factory.getGeneratedNameForNode(expression) : factory.createTempVariable(/*recordTempVariable*/ undefined); const result = isIdentifier(expression) ? factory.getGeneratedNameForNode(iterator) : factory.createTempVariable(/*recordTempVariable*/ undefined); const errorRecord = factory.createUniqueName("e"); diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 2d234f6776919..a944665b7f5ff 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -855,7 +855,7 @@ export function transformTypeScript(context: TransformationContext) { const decorators: Decorator[] = []; for (const parameterDecorator of parameterDecorators) { const expression = visitNode(parameterDecorator.expression, visitor, isExpression); - Debug.assert(expression); + Debug.assert(expression); const helper = emitHelpers().createParamHelper(expression, parameterOffset); setTextRange(helper, parameterDecorator.expression); setEmitFlags(helper, EmitFlags.NoComments); @@ -1007,7 +1007,7 @@ export function transformTypeScript(context: TransformationContext) { // - the property has a decorator. if (isComputedPropertyName(name) && ((!hasStaticModifier(member) && currentClassHasParameterProperties) || hasDecorators(member))) { const expression = visitNode(name.expression, visitor, isExpression); - Debug.assert(expression); + Debug.assert(expression); const innerExpression = skipPartiallyEmittedExpressions(expression); if (!isSimpleInlineableExpression(innerExpression)) { const generatedName = factory.getGeneratedNameForNode(name); @@ -1429,7 +1429,7 @@ export function transformTypeScript(context: TransformationContext) { // Make sure we consider all nested cast expressions, e.g.: // (-A).x; const expression = visitNode(node.expression, visitor, isExpression); - Debug.assert(expression); + Debug.assert(expression); // We have an expression of the form: (SubExpr). Emitting this as (SubExpr) // is really not desirable. We would like to emit the subexpression as-is. Omitting diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 86cf909a41f6f..562150c80ed94 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -461,11 +461,11 @@ export function getOriginalNode(node: Node | undefined, nodeTest } if (!node || !nodeTest) { - return node as T | undefined; + return node as T | undefined; } - return nodeTest(node) ? node : undefined; - } + return nodeTest(node) ? node : undefined; +} /** * Iterates through the parent chain of a node and performs the callback on each parent until the callback diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index f5ee7013090a5..34e8ba9f6b124 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -74,9 +74,9 @@ export function visitNode( let visitedNode: Node | undefined; if (visited === undefined) { - // If the visited node is undefined, then the visitor must have returned undefined, - // so the visitor must have been declared as able to return undefined, so TOut must be - // potentially undefined. + // If the visited node is undefined, then the visitor must have returned undefined, + // so the visitor must have been declared as able to return undefined, so TOut must be + // potentially undefined. return undefined; } else if (isArray(visited)) { @@ -178,9 +178,9 @@ export function visitNodes( return updatedArray; } - // If we are here, updated === nodes. This means that it's still a NodeArray, - // and also that its contents passed the tests in visitArrayWorker, so has contents - // of type TOut. + // If we are here, updated === nodes. This means that it's still a NodeArray, + // and also that its contents passed the tests in visitArrayWorker, so has contents + // of type TOut. return nodes; } diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 8c975542f0abb..a376884b1ae37 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -143,9 +143,9 @@ export function getFilesInErrorForSummary(diagnostics: readonly Diagnostic[]): ( return `${errorDiagnostic.file.fileName}`; }); return filesInError.map((fileName) => { - if (fileName === undefined) { - return undefined; - } + if (fileName === undefined) { + return undefined; + } const diagnosticForFileName = find(diagnostics, diagnostic => diagnostic.file !== undefined && diagnostic.file.fileName === fileName diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 4789b3bf96a2b..68d725be6600f 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -863,7 +863,7 @@ export class TestState { const hints = this.languageService.provideInlayHints(this.activeFile.fileName, span, preference); assert.equal(hints.length, expected.length, "Number of hints"); - interface HasPosition { position: number; } + interface HasPosition { position: number; } const sortHints = (a: HasPosition, b: HasPosition) => { return a.position - b.position; }; diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 73deb02be57ed..4f81d9edf6090 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1203,17 +1203,17 @@ export function assignPositionsToNode(node: Node): Node { } function assignPositionsToNodeArray( - nodes: NodeArray | undefined, - visitor: Visitor | undefined, - test?: (node: Node) => boolean, - start?: number, - count?: number, - ): NodeArray | undefined { + nodes: NodeArray | undefined, + visitor: Visitor | undefined, + test?: (node: Node) => boolean, + start?: number, + count?: number, +): NodeArray | undefined { const visited = visitNodes(nodes, visitor, test, start, count); if (!visited) { return visited; } - Debug.assert(nodes); + Debug.assert(nodes); // clone nodearray if necessary const nodeArray = visited === nodes ? factory.createNodeArray(visited.slice(0)) : visited; setTextRangePosEnd(nodeArray, getPos(nodes), getEnd(nodes)); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 6db9b4f0d6d29..f20c02da6ac39 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4049,12 +4049,6 @@ declare namespace ts { interface Push { push(...values: T[]): void; } - function every(array: readonly T[] | undefined, callback: (element: T, index: number) => element is U): array is readonly U[] | undefined; - function every(array: readonly T[] | undefined, callback: (element: T, index: number) => boolean): boolean; - function concatenate(array1: T[] | undefined, array2: T[]): T[]; - function concatenate(array1: readonly T[], array2: readonly T[] | undefined): readonly T[]; - function concatenate(array1: T[] | undefined, array2: T[] | undefined): T[] | undefined; - function concatenate(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined; type Path = string & { __pathBrand: any; }; @@ -8854,7 +8848,6 @@ declare namespace ts { parent: ConstructorDeclaration; name: Identifier; }; - function isInitializedVariable(node: Node): node is InitializedVariableDeclaration; function createUnparsedSourceFile(text: string): UnparsedSource; function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f13b9a55fb360..a1d0b10304fc2 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -105,12 +105,6 @@ declare namespace ts { interface Push { push(...values: T[]): void; } - function every(array: readonly T[] | undefined, callback: (element: T, index: number) => element is U): array is readonly U[] | undefined; - function every(array: readonly T[] | undefined, callback: (element: T, index: number) => boolean): boolean; - function concatenate(array1: T[] | undefined, array2: T[]): T[]; - function concatenate(array1: readonly T[], array2: readonly T[] | undefined): readonly T[]; - function concatenate(array1: T[] | undefined, array2: T[] | undefined): T[] | undefined; - function concatenate(array1: readonly T[] | undefined, array2: readonly T[] | undefined): readonly T[] | undefined; type Path = string & { __pathBrand: any; }; @@ -4910,7 +4904,6 @@ declare namespace ts { parent: ConstructorDeclaration; name: Identifier; }; - function isInitializedVariable(node: Node): node is InitializedVariableDeclaration; function createUnparsedSourceFile(text: string): UnparsedSource; function createUnparsedSourceFile(inputFile: InputFiles, type: "js" | "dts", stripInternal?: boolean): UnparsedSource; function createUnparsedSourceFile(text: string, mapPath: string | undefined, map: string | undefined): UnparsedSource; From a1c5eca331148216e6a9fe6a41e0cab6ffb95e86 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 8 Nov 2022 19:12:59 -0800 Subject: [PATCH 58/81] Fix test --- src/server/session.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/session.ts b/src/server/session.ts index c77de3792d0da..bdfd6a7aa538e 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -22,7 +22,7 @@ import { RenameInfo, RenameLocation, ScriptKind, SelectionRange, SemanticClassificationFormat, Set, SignatureHelpItem, SignatureHelpItems, singleIterator, some, SourceFile, startsWith, stringContains, SymbolDisplayPart, SyntaxKind, TextChange, TextInsertion, TextRange, TextSpan, textSpanEnd, toArray, toFileNameLowerCase, tracing, - unmangleScopedPackageName, UserPreferences, version, WithMetadata, + unmangleScopedPackageName, UserPreferences, version, WithMetadata, BufferEncoding } from "./_namespaces/ts"; import { ConfigFileDiagEvent, ConfiguredProject, convertFormatOptions, convertScriptKindName, convertUserPreferences, From 1accebd6109ba6d1eee321ac9948766e8439f90d Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 9 Nov 2022 12:45:29 -0800 Subject: [PATCH 59/81] Fix merge --- .../unittests/tsserver/cachingFileSystemInformation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts index 7b8eb235af96d..40fed1e778712 100644 --- a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts +++ b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts @@ -1,5 +1,5 @@ import * as ts from "../../_namespaces/ts"; -import { createServerHost, File, libFile, SymLink, TestServerHost } from "../virtualFileSystemWithWatch"; +import { createServerHost, File, Folder, libFile, SymLink, TestServerHost } from "../virtualFileSystemWithWatch"; import { Logger, createProjectService, createLoggerWithInMemoryLogs, baselineTsserverLogs, createSession, openFilesForSession, makeSessionRequest, checkProjectActualFiles, checkNumberOfProjects } from "./helpers"; describe("unittests:: tsserver:: CachingFileSystemInformation:: tsserverProjectSystem CachingFileSystemInformation", () => { From 096bf30d82652d7a5e0c5da7ccc4f9a690eca279 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 14 Nov 2022 17:31:31 -0800 Subject: [PATCH 60/81] Fix old merge oops --- src/compiler/utilities.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8a58943d2cf1b..0da74d133d05a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1080,7 +1080,6 @@ export function isBlockScope(node: Node, parentNode: Node | undefined): boolean /** @internal */ export function isDeclarationWithTypeParameters(node: Node): node is DeclarationWithTypeParameters { -/** @internal */ Debug.type(node); switch (node.kind) { case SyntaxKind.JSDocCallbackTag: @@ -1095,7 +1094,6 @@ export function isDeclarationWithTypeParameters(node: Node): node is Declaration /** @internal */ export function isDeclarationWithTypeParameterChildren(node: Node): node is DeclarationWithTypeParameterChildren { -/** @internal */ Debug.type(node); switch (node.kind) { case SyntaxKind.CallSignature: From a4012178dffef6181fff056069490c6f47bd9913 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 15 Nov 2022 18:12:47 -0800 Subject: [PATCH 61/81] Fix spacing problems caused by merge oops --- src/compiler/checker.ts | 8 ++++---- src/compiler/emitter.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e316578c6d465..a7f589177568b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5772,12 +5772,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function deepCloneOrReuseNodes( - nodes: NodeArray | undefined, + nodes: NodeArray | undefined, visitor: Visitor | undefined, - test?: (node: Node) => boolean, - start?: number, + test?: (node: Node) => boolean, + start?: number, count?: number, - ): NodeArray | undefined { + ): NodeArray | undefined { if (nodes && nodes.length === 0) { // Ensure we explicitly make a copy of an empty array; visitNodes will not do this unless the array has elements, // which can lead to us reusing the same empty NodeArray more than once within the same AST during type noding. diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8a7de5560642f..13310bca3b899 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -4556,7 +4556,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri * * NOTE: You probably don't want to call this directly and should be using `emitList` or `emitExpressionList` instead. */ - function emitNodeListItems(emit: EmitFunction, parentNode: Node | undefined, children: readonly Child[], format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start: number, count: number, hasTrailingComma: boolean, childrenTextRange: TextRange | undefined) { + function emitNodeListItems(emit: EmitFunction, parentNode: Node | undefined, children: readonly Child[], format: ListFormat, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, start: number, count: number, hasTrailingComma: boolean, childrenTextRange: TextRange | undefined) { // Write the opening line terminator or leading whitespace. const mayEmitInterveningComments = (format & ListFormat.NoInterveningComments) === 0; let shouldEmitInterveningComments = mayEmitInterveningComments; @@ -6122,7 +6122,7 @@ type ParenthesizerRuleOrSelector = OrdinalParentheizerRuleSelect type EmitFunction = (node: T, parenthesizerRule?: ParenthesizerRule) => void; type EmitListItemFunction = (node: Node, emit: EmitFunction, parenthesizerRule: ParenthesizerRuleOrSelector | undefined, index: number) => void; - function emitListItemNoParenthesizer(node: Node, emit: EmitFunction, _parenthesizerRule: ParenthesizerRuleOrSelector | undefined, _index: number) { +function emitListItemNoParenthesizer(node: Node, emit: EmitFunction, _parenthesizerRule: ParenthesizerRuleOrSelector | undefined, _index: number) { emit(node); } From ba87ccf132377a41e446cdbf560d0cfec47601f1 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 17 Nov 2022 13:03:20 -0800 Subject: [PATCH 62/81] Drop some new calls to Debug.type --- src/compiler/parser.ts | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e4972375fb771..77efcf11cc25a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -9287,17 +9287,18 @@ namespace IncrementalParser { } } - function moveElementEntirelyPastChangeRange(element: IncrementalNode | IncrementalNodeArray, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) { - if (isArray(element)) { - visitArray(element); + function moveElementEntirelyPastChangeRange(element: IncrementalNode, isArray: false, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void; + function moveElementEntirelyPastChangeRange(element: IncrementalNodeArray, isArray: true, delta: number, oldText: string, newText: string, aggressiveChecks: boolean): void; + function moveElementEntirelyPastChangeRange(element: IncrementalNode | IncrementalNodeArray, isArray: boolean, delta: number, oldText: string, newText: string, aggressiveChecks: boolean) { + if (isArray) { + visitArray(element as IncrementalNodeArray); } else { - visitNode(element); + visitNode(element as IncrementalNode); } return; - function visitNode(node: Node) { - Debug.type(node); + function visitNode(node: IncrementalNode) { let text = ""; if (aggressiveChecks && shouldCheckNode(node)) { text = oldText.substring(node.pos, node.end); @@ -9315,7 +9316,7 @@ namespace IncrementalParser { Debug.assert(text === newText.substring(node.pos, node.end)); } - forEachChild(node, visitNode, visitArray); + forEachChild(node, visitNode as (node: Node) => void, visitArray as (nodes: NodeArray) => void); if (hasJSDocNodes(node)) { for (const jsDocComment of node.jsDoc!) { visitNode(jsDocComment as Node as IncrementalNode); @@ -9324,8 +9325,7 @@ namespace IncrementalParser { checkNodePositions(node, aggressiveChecks); } - function visitArray(array: NodeArray) { - Debug.type(array); + function visitArray(array: IncrementalNodeArray) { array._children = undefined; setTextRangePosEnd(array, array.pos + delta, array.end + delta); @@ -9450,13 +9450,13 @@ namespace IncrementalParser { visitNode(sourceFile); return; - function visitNode(child: Node) { - Debug.type(child); + function visitNode(child: IncrementalNode) { + // Debug.type(child); Debug.assert(child.pos <= child.end); if (child.pos > changeRangeOldEnd) { // Node is entirely past the change range. We need to move both its pos and // end, forward or backward appropriately. - moveElementEntirelyPastChangeRange(child, delta, oldText, newText, aggressiveChecks); + moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks); return; } @@ -9470,10 +9470,10 @@ namespace IncrementalParser { // Adjust the pos or end (or both) of the intersecting element accordingly. adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); - forEachChild(child, visitNode, visitArray); + forEachChild(child, visitNode as (node: Node) => void, visitArray as (nodes: NodeArray) => void); if (hasJSDocNodes(child)) { for (const jsDocComment of child.jsDoc!) { - visitNode(jsDocComment); + visitNode(jsDocComment as IncrementalNode); } } checkNodePositions(child, aggressiveChecks); @@ -9484,13 +9484,12 @@ namespace IncrementalParser { Debug.assert(fullEnd < changeStart); } - function visitArray(array: NodeArray) { - Debug.type(array); + function visitArray(array: IncrementalNodeArray) { Debug.assert(array.pos <= array.end); if (array.pos > changeRangeOldEnd) { // Array is entirely after the change range. We need to move it, and move any of // its children. - moveElementEntirelyPastChangeRange(array, delta, oldText, newText, aggressiveChecks); + moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks); return; } From 2f192b9b2b256674d29798b99f26ed5651d144a3 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 17 Nov 2022 13:05:05 -0800 Subject: [PATCH 63/81] Remove my leftover comment --- src/compiler/parser.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 77efcf11cc25a..6921df7c81649 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -9451,7 +9451,6 @@ namespace IncrementalParser { return; function visitNode(child: IncrementalNode) { - // Debug.type(child); Debug.assert(child.pos <= child.end); if (child.pos > changeRangeOldEnd) { // Node is entirely past the change range. We need to move both its pos and From e0dcfb1f97e589272d59efa3200ae9b7101bbf2d Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 17 Nov 2022 14:36:12 -0800 Subject: [PATCH 64/81] Fix formatting and export oops --- src/compiler/visitorPublic.ts | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index f7ec3a2cfbe97..dae1938b91f01 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -66,7 +66,7 @@ export function visitNode( lift?: (node: readonly Node[]) => Node, ): Node | undefined { if (node === undefined) { - // If the input type is undefined, then the output type can be undefined. + // If the input type is undefined, then the output type can be undefined. return node; } @@ -224,23 +224,21 @@ export function visitArray( return visitArrayWorker(nodes, visitor, test, start, count); } -/** @internal */ -export function visitArrayWorker( +function visitArrayWorker( nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start: number, count: number, ): readonly TOut[]; -/** @internal */ -export function visitArrayWorker( +function visitArrayWorker( nodes: TInArray, visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, start: number, count: number, ): readonly Node[]; -export function visitArrayWorker( +function visitArrayWorker( nodes: readonly Node[], visitor: Visitor | undefined, test: ((node: Node) => boolean) | undefined, @@ -460,7 +458,7 @@ export function visitIterationBody(body: Statement, visitor: Visitor, context: T export function visitIterationBody(body: Statement, visitor: Visitor, context: TransformationContext, nodeVisitor: NodeVisitor = visitNode): Statement { context.startBlockScope(); const updated = nodeVisitor(body, visitor, isStatement, context.factory.liftToBlock); - Debug.assert(updated); + Debug.assert(updated); const declarations = context.endBlockScope(); if (some(declarations)) { if (isBlock(updated)) { From e52a85a268cf1aa3de3d4c2d03d2c0a66b588e15 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 17 Nov 2022 14:41:17 -0800 Subject: [PATCH 65/81] More PR fixups --- src/compiler/visitorPublic.ts | 1 + tests/baselines/reference/api/tsserverlibrary.d.ts | 1 - tests/baselines/reference/api/typescript.d.ts | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index dae1938b91f01..aa740cac4190f 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -192,6 +192,7 @@ export function visitArray( nodes: TInArray, visitor: Visitor | undefined, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 89b2167affdf1..4d86986ab9bbd 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -9323,7 +9323,6 @@ declare namespace ts { * @param count An optional value indicating the maximum number of nodes to visit. */ function visitNodes | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); - function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index cec8341f4c598..61c11c65baae9 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -5381,7 +5381,6 @@ declare namespace ts { * @param count An optional value indicating the maximum number of nodes to visit. */ function visitNodes | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); - function visitArray(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): readonly Node[] | (TInArray & undefined); /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. From 5b5471214be222341f95348217035bc39e3c02e4 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 17 Nov 2022 14:59:09 -0800 Subject: [PATCH 66/81] fix missed lint --- src/compiler/transformers/classFields.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/transformers/classFields.ts b/src/compiler/transformers/classFields.ts index f8959f06b094e..3edc253584fc1 100644 --- a/src/compiler/transformers/classFields.ts +++ b/src/compiler/transformers/classFields.ts @@ -97,6 +97,7 @@ import { isArrowFunction, isAssignmentExpression, isAutoAccessorPropertyDeclaration, + isBindingOrAssignmentElement, isCallChain, isClassDeclaration, isClassElement, @@ -169,7 +170,6 @@ import { visitNode, visitNodes, visitParameterList, - isBindingOrAssignmentElement, } from "../_namespaces/ts"; const enum ClassPropertySubstitutionFlags { From 2bb155467064e56beeb1d333a6950b2332624b1d Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 17 Nov 2022 15:12:38 -0800 Subject: [PATCH 67/81] Fix dts --- src/server/session.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/session.ts b/src/server/session.ts index 988957c70df96..b3ab5f89518f8 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1,4 +1,5 @@ import { + BufferEncoding, CallHierarchyIncomingCall, CallHierarchyItem, CallHierarchyOutgoingCall, From e14a8a619c298461e0a95256264614dd193ccc93 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 17 Nov 2022 15:13:23 -0800 Subject: [PATCH 68/81] Restore old transformer signatures --- src/compiler/types.ts | 4 ++-- tests/baselines/reference/api/tsserverlibrary.d.ts | 4 ++-- tests/baselines/reference/api/typescript.d.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 445fd678848e8..ca456b5698d2e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8697,12 +8697,12 @@ export interface TransformationResult { * A function that is used to initialize and return a `Transformer` callback, which in turn * will be used to transform one or more nodes. */ -export type TransformerFactory = (context: TransformationContext) => Transformer; +export type TransformerFactory = (context: TransformationContext) => Transformer; /** * A function that transforms a node. */ -export type Transformer = (node: TIn) => TOut; +export type Transformer = (node: T) => T; /** * A function that accepts and possibly transforms a node. diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 4d86986ab9bbd..1d1e11913b0c9 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -8162,11 +8162,11 @@ declare namespace ts { * A function that is used to initialize and return a `Transformer` callback, which in turn * will be used to transform one or more nodes. */ - type TransformerFactory = (context: TransformationContext) => Transformer; + type TransformerFactory = (context: TransformationContext) => Transformer; /** * A function that transforms a node. */ - type Transformer = (node: TIn) => TOut; + type Transformer = (node: T) => T; /** * A function that accepts and possibly transforms a node. */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 61c11c65baae9..6328568b8afab 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4220,11 +4220,11 @@ declare namespace ts { * A function that is used to initialize and return a `Transformer` callback, which in turn * will be used to transform one or more nodes. */ - type TransformerFactory = (context: TransformationContext) => Transformer; + type TransformerFactory = (context: TransformationContext) => Transformer; /** * A function that transforms a node. */ - type Transformer = (node: TIn) => TOut; + type Transformer = (node: T) => T; /** * A function that accepts and possibly transforms a node. */ From cd58e0f271d9f78535cb2e54ad782bf7ba8c0296 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 17 Nov 2022 15:40:22 -0800 Subject: [PATCH 69/81] Fix post merge --- src/compiler/emitter.ts | 1 + src/compiler/factory/parenthesizerRules.ts | 1 + src/compiler/symbolWalker.ts | 1 + src/compiler/transformers/destructuring.ts | 1 - src/compiler/transformers/es2015.ts | 1 - src/compiler/transformers/es2018.ts | 1 - src/compiler/transformers/ts.ts | 1 + src/compiler/utilitiesPublic.ts | 3 ++- src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts | 2 +- src/harness/harnessLanguageService.ts | 1 - src/server/session.ts | 1 + src/services/codefixes/annotateWithTypeFromJSDoc.ts | 2 +- src/services/documentHighlights.ts | 2 ++ .../unittests/tsserver/cachingFileSystemInformation.ts | 1 + src/testRunner/unittests/tsserver/helpers.ts | 1 - src/testRunner/unittests/tsserver/session.ts | 1 - 16 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 95e22464d7646..27aa2bea1436e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -273,6 +273,7 @@ import { JSDocVariadicType, JsxAttribute, JsxAttributes, + JsxAttributeValue, JsxClosingElement, JsxClosingFragment, JsxElement, diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts index 394a88bac2981..4dec4f8be686e 100644 --- a/src/compiler/factory/parenthesizerRules.ts +++ b/src/compiler/factory/parenthesizerRules.ts @@ -36,6 +36,7 @@ import { LeftHandSideExpression, NamedTupleMember, NewExpression, + Node, NodeArray, NodeFactory, OperatorPrecedence, diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index 75c19a9652674..09853623cc5db 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -1,4 +1,5 @@ import { + BaseType, clear, EntityNameOrEntityNameExpression, forEach, diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 248f4d373d72a..905d5d45f9d44 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -2,7 +2,6 @@ import { __String, addRange, append, - ArrayBindingElement, ArrayBindingOrAssignmentPattern, BindingName, BindingOrAssignmentElement, diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 618f22c312ef4..ec2f7ef397255 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -46,7 +46,6 @@ import { filter, first, firstOrUndefined, - flatMap, flatten, flattenDestructuringAssignment, flattenDestructuringBinding, diff --git a/src/compiler/transformers/es2018.ts b/src/compiler/transformers/es2018.ts index 3840d138a7ee9..35f28a2ee8d6b 100644 --- a/src/compiler/transformers/es2018.ts +++ b/src/compiler/transformers/es2018.ts @@ -95,7 +95,6 @@ import { SyntaxKind, TaggedTemplateExpression, TextRange, - Token, TransformationContext, TransformFlags, unwrapInnermostStatementOfLabel, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 023e1195db9a5..d47ada78383fb 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -119,6 +119,7 @@ import { isSimpleInlineableExpression, isSourceFile, isStatement, + isTemplateLiteral, JsxOpeningElement, JsxSelfClosingElement, lastOrUndefined, diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index c1bfb6d21bc89..a6a722b3a17b6 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -78,8 +78,8 @@ import { getJSDocCommentsAndTags, getJSDocTypeParameterDeclarations, hasAccessorModifier, - hasDecorators, HasDecorators, + hasDecorators, HasExpressionInitializer, HasInitializer, HasJSDoc, @@ -214,6 +214,7 @@ import { NonNullChain, normalizePath, NotEmittedStatement, + NullLiteral, ObjectBindingOrAssignmentElement, ObjectBindingOrAssignmentPattern, ObjectLiteralElement, diff --git a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts index 437396784161f..25441c42fe912 100644 --- a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts +++ b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts @@ -63,6 +63,7 @@ import { ModuleName, ModuleReference, NamedExportBindings, + Node, NodeFactory, NodeFlags, ParameterDeclaration, @@ -70,7 +71,6 @@ import { PropertyName, QuestionToken, SetAccessorDeclaration, - some, TypeAliasDeclaration, TypeElement, TypeNode, diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index dfc32ccedc93f..952931c1c514a 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -3,7 +3,6 @@ import * as fakes from "./_namespaces/fakes"; import * as vfs from "./_namespaces/vfs"; import * as collections from "./_namespaces/collections"; import * as vpath from "./_namespaces/vpath"; -import * as Utils from "./_namespaces/Utils"; import { Compiler, harnessNewLine, diff --git a/src/server/session.ts b/src/server/session.ts index 20f81f4e22873..30a3abe4772ab 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2,6 +2,7 @@ import { arrayFrom, arrayIterator, arrayReverseIterator, + BufferEncoding, CallHierarchyIncomingCall, CallHierarchyItem, CallHierarchyOutgoingCall, diff --git a/src/services/codefixes/annotateWithTypeFromJSDoc.ts b/src/services/codefixes/annotateWithTypeFromJSDoc.ts index ed89af6e2eae4..a2cfc5e97224c 100644 --- a/src/services/codefixes/annotateWithTypeFromJSDoc.ts +++ b/src/services/codefixes/annotateWithTypeFromJSDoc.ts @@ -17,6 +17,7 @@ import { isJSDocIndexSignature, isOptionalJSDocPropertyLikeTag, isParameter, + isTypeNode, JSDocFunctionType, JSDocNonNullableType, JSDocNullableType, @@ -35,7 +36,6 @@ import { SyntaxKind, textChanges, tryCast, - TypeNode, TypeReferenceNode, VariableDeclaration, visitEachChild, diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index a3e21643bf3c5..07d7d87a7d511 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -7,6 +7,7 @@ import { CancellationToken, CaseClause, cast, + ClassElement, concatenate, ConstructorDeclaration, contains, @@ -79,6 +80,7 @@ import { toArray, toPath, TryStatement, + TypeElement, } from "./_namespaces/ts"; export interface DocumentHighlights { diff --git a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts index 79fed496dc7e9..f040329355c10 100644 --- a/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts +++ b/src/testRunner/unittests/tsserver/cachingFileSystemInformation.ts @@ -2,6 +2,7 @@ import * as ts from "../../_namespaces/ts"; import { createServerHost, File, + Folder, libFile, SymLink, TestServerHost, diff --git a/src/testRunner/unittests/tsserver/helpers.ts b/src/testRunner/unittests/tsserver/helpers.ts index 5b1122f1e9cca..e6a2ee6968ab7 100644 --- a/src/testRunner/unittests/tsserver/helpers.ts +++ b/src/testRunner/unittests/tsserver/helpers.ts @@ -1,6 +1,5 @@ import * as ts from "../../_namespaces/ts"; import * as Harness from "../../_namespaces/Harness"; -import * as Utils from "../../_namespaces/Utils"; import { changeToHostTrackingWrittenFiles, checkArray, diff --git a/src/testRunner/unittests/tsserver/session.ts b/src/testRunner/unittests/tsserver/session.ts index 810b3a57fe371..e45af1926dc71 100644 --- a/src/testRunner/unittests/tsserver/session.ts +++ b/src/testRunner/unittests/tsserver/session.ts @@ -2,7 +2,6 @@ import { expect } from "chai"; import * as ts from "../../_namespaces/ts"; import * as Harness from "../../_namespaces/Harness"; -import * as Utils from "../../_namespaces/Utils"; import { createHasErrorMessageLogger, nullLogger, From 2a1c1f10bdb149a0df6ea31862a88f9fa72525e0 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 6 Dec 2022 11:17:44 -0800 Subject: [PATCH 70/81] Fix bad merge --- src/compiler/program.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/program.ts b/src/compiler/program.ts index c066f8feed0e6..82cd4afd1ff35 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1534,7 +1534,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } let actualResolveTypeReferenceDirectiveNamesWorker: ( - typeDirectiveNames: T[], + typeDirectiveNames: readonly T[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, options: CompilerOptions, @@ -1872,7 +1872,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg return result; } - function resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames: T[], containingFile: string | SourceFile, reusedNames: readonly T[] | undefined): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[] { + function resolveTypeReferenceDirectiveNamesWorker(typeDirectiveNames: readonly T[], containingFile: string | SourceFile, reusedNames: readonly T[] | undefined): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[] { if (!typeDirectiveNames.length) return []; const containingSourceFile = !isString(containingFile) ? containingFile : undefined; const containingFileName = !isString(containingFile) ? getNormalizedAbsolutePath(containingFile.originalFileName, currentDirectory) : containingFile; @@ -2106,7 +2106,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg function resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectiveNames: readonly FileReference[], containingFile: SourceFile): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[]; function resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectiveNames: string[], containingFile: string): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[]; - function resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectiveNames: T[], containingFile: string | SourceFile): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[] { + function resolveTypeReferenceDirectiveNamesReusingOldState(typeDirectiveNames: readonly T[], containingFile: string | SourceFile): readonly ResolvedTypeReferenceDirectiveWithFailedLookupLocations[] { if (structureIsReused === StructureIsReused.Not) { // If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules, // the best we can do is fallback to the default logic. From 71d3eac329a31bd2d680f2483cac9aceecfb3e49 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Dec 2022 16:16:22 -0800 Subject: [PATCH 71/81] Restore old cast and tryCast --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 2 +- src/compiler/core.ts | 8 ++------ src/compiler/emitter.ts | 2 +- src/compiler/factory/nodeConverters.ts | 7 ++++--- src/services/codefixes/fixImportNonExportedMember.ts | 3 ++- src/services/codefixes/importFixes.ts | 10 +++++++--- src/services/completions.ts | 2 +- src/services/documentHighlights.ts | 3 ++- src/services/findAllReferences.ts | 2 +- src/services/importTracker.ts | 5 +++-- src/services/refactors/moveToNewFile.ts | 2 +- 12 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index a974c5b324681..e6a3b66a3eadb 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3298,7 +3298,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { addLateBoundAssignmentDeclarationToSymbol(node, sym); } else { - bindStaticPropertyAssignment(cast(node.left, isBindableStaticNameExpression)); + bindStaticPropertyAssignment(cast(node.left, isBindableStaticNameExpression)); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 61a3f1fb5a410..4a5c32d603765 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4105,7 +4105,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function reportNonExportedMember(node: Node, name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void { - const localSymbol = tryCast(moduleSymbol.valueDeclaration, canHaveLocals)?.locals?.get(name.escapedText); + const localSymbol = tryCast(moduleSymbol.valueDeclaration, canHaveLocals)?.locals?.get(name.escapedText); const exports = moduleSymbol.exports; if (localSymbol) { const exportedEqualsSymbol = exports?.get(InternalSymbolName.ExportEquals); diff --git a/src/compiler/core.ts b/src/compiler/core.ts index fe168d1dbcae2..4c127ac19206b 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2004,16 +2004,12 @@ export function isNumber(x: unknown): x is number { } /** @internal */ -export function tryCast(value: TIn | undefined, test: (value: TParam) => value is TOut): TOut | undefined; -/** @internal */ -export function tryCast(value: T, test: (value: T) => boolean): T | undefined; -/** @internal */ -export function tryCast(value: T, test: (value: T) => boolean): T | undefined { +export function tryCast(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut | undefined { return value !== undefined && test(value) ? value : undefined; } /** @internal */ -export function cast(value: TIn | undefined, test: (value: TParam) => value is TOut): TOut { +export function cast(value: TIn | undefined, test: (value: TIn) => value is TOut): TOut { if (value !== undefined && test(value)) return value; return Debug.fail(`Invalid cast. The supplied value ${value} did not pass the test '${Debug.getFunctionName(test)}'.`); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5f55767bdb8ff..1d956481565cc 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5801,7 +5801,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) { const name = getTextOfNode(node.name); // Use module/enum name itself if it is unique, otherwise make a unique variation - return isUniqueLocalName(name, tryCast(node, canHaveLocals)) ? name : makeUniqueName(name, isUniqueName, /*optimistic*/ false, /*scoped*/ false, /*privateName*/ false, /*prefix*/ "", /*suffix*/ ""); + return isUniqueLocalName(name, tryCast(node, canHaveLocals)) ? name : makeUniqueName(name, isUniqueName, /*optimistic*/ false, /*scoped*/ false, /*privateName*/ false, /*prefix*/ "", /*suffix*/ ""); } /** diff --git a/src/compiler/factory/nodeConverters.ts b/src/compiler/factory/nodeConverters.ts index e506391a78b78..412dbe5d62cd8 100644 --- a/src/compiler/factory/nodeConverters.ts +++ b/src/compiler/factory/nodeConverters.ts @@ -27,6 +27,7 @@ import { notImplemented, ObjectBindingOrAssignmentElement, ObjectBindingOrAssignmentPattern, + ObjectLiteralElementLike, setOriginalNode, setStartsOnNewLine, setTextRange, @@ -91,7 +92,7 @@ export function createNodeConverters(factory: NodeFactory): NodeConverters { ) : expression; } - return cast(element, isExpression); + return cast(element, isExpression); } function convertToObjectAssignmentElement(element: ObjectBindingOrAssignmentElement) { @@ -108,7 +109,7 @@ export function createNodeConverters(factory: NodeFactory): NodeConverters { return setOriginalNode(setTextRange(factory.createShorthandPropertyAssignment(element.name, element.initializer), element), element); } - return cast(element, isObjectLiteralElementLike); + return cast(element, isObjectLiteralElementLike); } function convertToAssignmentPattern(node: BindingOrAssignmentPattern): AssignmentPattern { @@ -154,7 +155,7 @@ export function createNodeConverters(factory: NodeFactory): NodeConverters { return convertToAssignmentPattern(node); } - return cast(node, isExpression); + return cast(node, isExpression); } } diff --git a/src/services/codefixes/fixImportNonExportedMember.ts b/src/services/codefixes/fixImportNonExportedMember.ts index 23731400a1601..a54704ec6d959 100644 --- a/src/services/codefixes/fixImportNonExportedMember.ts +++ b/src/services/codefixes/fixImportNonExportedMember.ts @@ -11,6 +11,7 @@ import { firstOrUndefined, getResolvedModule, getTokenAtPosition, + HasLocals, Identifier, isExportDeclaration, isIdentifier, @@ -126,7 +127,7 @@ function getInfo(sourceFile: SourceFile, pos: number, program: Program): Info | if (moduleSourceFile === undefined || isSourceFileFromLibrary(program, moduleSourceFile)) return undefined; const moduleSymbol = moduleSourceFile.symbol; - const locals = tryCast(moduleSymbol.valueDeclaration, canHaveLocals)?.locals; + const locals = tryCast(moduleSymbol.valueDeclaration, canHaveLocals)?.locals; if (locals === undefined) return undefined; const localSymbol = locals.get(token.escapedText); diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 2f0c90737549a..9d9b5429f6438 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -999,9 +999,13 @@ function getUmdSymbol(token: Node, checker: TypeChecker): Symbol | undefined { // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. const { parent } = token; - return (isJsxOpeningLikeElement(parent) && parent.tagName === token) || isJsxOpeningFragment(parent) - ? tryCast(checker.resolveName(checker.getJsxNamespace(parent), isJsxOpeningLikeElement(parent) ? token : parent, SymbolFlags.Value, /*excludeGlobals*/ false), isUMDExportSymbol) - : undefined; + if ((isJsxOpeningLikeElement(parent) && parent.tagName === token) || isJsxOpeningFragment(parent)) { + const parnetSymbol = checker.resolveName(checker.getJsxNamespace(parent), isJsxOpeningLikeElement(parent) ? token : parent, SymbolFlags.Value, /*excludeGlobals*/ false); + if (isUMDExportSymbol(parnetSymbol)) { + return parnetSymbol; + } + } + return undefined; } /** diff --git a/src/services/completions.ts b/src/services/completions.ts index 6e02fd1e567a4..72f5f5691ee73 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -4787,7 +4787,7 @@ function tryGetObjectTypeDeclarationCompletionContainer(sourceFile: SourceFile, case SyntaxKind.SyntaxList: return tryCast(location.parent, isObjectTypeDeclaration); case SyntaxKind.EndOfFileToken: - const cls = tryCast(lastOrUndefined(cast(location.parent, isSourceFile).statements), isObjectTypeDeclaration); + const cls = tryCast(lastOrUndefined(cast(location.parent, isSourceFile).statements), isObjectTypeDeclaration); if (cls && !findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile)) { return cls; } diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 1e35092ff3199..31d340b5b616a 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -16,6 +16,7 @@ import { createTextSpanFromBounds, createTextSpanFromNode, Debug, + Declaration, DefaultClause, find, FindAllReferences, @@ -188,7 +189,7 @@ export namespace DocumentHighlights { } function getFromAllDeclarations(nodeTest: (node: Node) => node is T, keywords: readonly SyntaxKind[]): HighlightSpan[] | undefined { - return useParent(node.parent, nodeTest, decl => mapDefined(tryCast(decl, canHaveSymbol)?.symbol.declarations, d => + return useParent(node.parent, nodeTest, decl => mapDefined(tryCast(decl, canHaveSymbol)?.symbol.declarations, d => nodeTest(d) ? find(d.getChildren(sourceFile), c => contains(keywords, c.kind)) : undefined)); } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 01ad83b784169..3b8df608c14d7 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -2478,7 +2478,7 @@ export namespace Core { if (symbol.valueDeclaration && isParameterPropertyDeclaration(symbol.valueDeclaration, symbol.valueDeclaration.parent)) { // For a parameter property, now try on the other symbol (property if this was a parameter, parameter if this was a property). - const paramProps = checker.getSymbolsOfParameterPropertyDeclaration(cast(symbol.valueDeclaration, isParameter), symbol.name); + const paramProps = checker.getSymbolsOfParameterPropertyDeclaration(cast(symbol.valueDeclaration, isParameter), symbol.name); Debug.assert(paramProps.length === 2 && !!(paramProps[0].flags & SymbolFlags.FunctionScopedVariable) && !!(paramProps[1].flags & SymbolFlags.Property)); // is [parameter, property] return fromRoot(symbol.flags & SymbolFlags.FunctionScopedVariable ? paramProps[1] : paramProps[0]); } diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index 1d59846a2a8f5..69828925d4e7e 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -10,6 +10,7 @@ import { canHaveSymbol, cast, Debug, + Declaration, ExportAssignment, ExportDeclaration, FileReference, @@ -685,10 +686,10 @@ function getExportEqualsLocalSymbol(importedSymbol: Symbol, checker: TypeChecker const decl = Debug.checkDefined(importedSymbol.valueDeclaration); if (isExportAssignment(decl)) { // `export = class {}` - return tryCast(decl.expression, canHaveSymbol)?.symbol; + return tryCast(decl.expression, canHaveSymbol)?.symbol; } else if (isBinaryExpression(decl)) { // `module.exports = class {}` - return tryCast(decl.right, canHaveSymbol)?.symbol; + return tryCast(decl.right, canHaveSymbol)?.symbol; } else if (isSourceFile(decl)) { // json module return decl.symbol; diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 7950f25f5a6cf..f3bd8de63abb4 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -505,7 +505,7 @@ function addExports(sourceFile: SourceFile, toMove: readonly Statement[], needEx return flatMap(toMove, statement => { if (isTopLevelDeclarationStatement(statement) && !isExported(sourceFile, statement, useEs6Exports) && - forEachTopLevelDeclaration(statement, d => needExport.has(Debug.checkDefined(tryCast(d, canHaveSymbol)?.symbol)))) { + forEachTopLevelDeclaration(statement, d => needExport.has(Debug.checkDefined(tryCast(d, canHaveSymbol)?.symbol)))) { const exports = addExport(statement, useEs6Exports); if (exports) return exports; } From 828abf2680d44746e60f40daf4b0bc993bf13098 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 17 Dec 2022 16:20:27 -0800 Subject: [PATCH 72/81] Fix new error --- src/compiler/core.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 14116797f38dc..a6ee959e11818 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -978,7 +978,7 @@ export function detectSortCaseSensitivity(array: readonly string[], useEslintOrd /** @internal */ export function detectSortCaseSensitivity(array: readonly T[], useEslintOrdering: boolean, getString: (element: T) => string): SortKind; /** @internal */ -export function detectSortCaseSensitivity(array: readonly T[], useEslintOrdering: boolean, getString?: (element: T) => string): SortKind { +export function detectSortCaseSensitivity(array: readonly T[], useEslintOrdering?: boolean, getString?: (element: T) => string): SortKind { let kind = SortKind.Both; if (array.length < 2) return kind; const caseSensitiveComparer = getString From cd92e049a7aee677105e907f614f62d2bf736f98 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 4 Jan 2023 16:56:56 -0800 Subject: [PATCH 73/81] Eagerly test visited nodes during visitArray --- src/compiler/visitorPublic.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 7fb55ff224940..a26e8abef601e 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -346,23 +346,31 @@ function visitArrayWorker( if (updated === undefined) { // Ensure we have a copy of `nodes`, up to the current index. updated = nodes.slice(0, i); + Debug.assertEachNode(updated, test); } if (visited) { if (isArray(visited)) { for (const visitedNode of visited) { + Debug.assertNode(visitedNode, test); updated.push(visitedNode); } } else { + Debug.assertNode(visited, test); updated.push(visited); } } } } - const result = updated ?? nodes; - Debug.assertEachNode(result, test); - return result; + if (updated) { + // If we have an updated array, then all items will have been tested. + return updated; + } + + // If we are going to return the original array, ensure it passes the test. + Debug.assertEachNode(nodes, test); + return nodes; } /** From a6f6ebb6a516f7a24a33ffadde519b9b207c3083 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sun, 8 Jan 2023 13:59:20 -0800 Subject: [PATCH 74/81] Remove parameters fixed by future LKG --- src/compiler/binder.ts | 2 +- src/compiler/checker.ts | 2 +- src/compiler/emitter.ts | 2 +- src/compiler/factory/nodeConverters.ts | 7 +++---- src/services/codefixes/fixImportNonExportedMember.ts | 3 +-- src/services/completions.ts | 2 +- src/services/documentHighlights.ts | 3 +-- src/services/findAllReferences.ts | 2 +- src/services/importTracker.ts | 5 ++--- src/services/refactors/moveToNewFile.ts | 2 +- 10 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 91f13ca1a3e5d..b011e550269f1 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -3303,7 +3303,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { addLateBoundAssignmentDeclarationToSymbol(node, sym); } else { - bindStaticPropertyAssignment(cast(node.left, isBindableStaticNameExpression)); + bindStaticPropertyAssignment(cast(node.left, isBindableStaticNameExpression)); } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5fa4652ba2b8f..a7186c8e99130 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4112,7 +4112,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function reportNonExportedMember(node: Node, name: Identifier, declarationName: string, moduleSymbol: Symbol, moduleName: string): void { - const localSymbol = tryCast(moduleSymbol.valueDeclaration, canHaveLocals)?.locals?.get(name.escapedText); + const localSymbol = tryCast(moduleSymbol.valueDeclaration, canHaveLocals)?.locals?.get(name.escapedText); const exports = moduleSymbol.exports; if (localSymbol) { const exportedEqualsSymbol = exports?.get(InternalSymbolName.ExportEquals); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index c300e9141444c..c5f0e0ace45a0 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5880,7 +5880,7 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri function generateNameForModuleOrEnum(node: ModuleDeclaration | EnumDeclaration) { const name = getTextOfNode(node.name); // Use module/enum name itself if it is unique, otherwise make a unique variation - return isUniqueLocalName(name, tryCast(node, canHaveLocals)) ? name : makeUniqueName(name, isUniqueName, /*optimistic*/ false, /*scoped*/ false, /*privateName*/ false, /*prefix*/ "", /*suffix*/ ""); + return isUniqueLocalName(name, tryCast(node, canHaveLocals)) ? name : makeUniqueName(name, isUniqueName, /*optimistic*/ false, /*scoped*/ false, /*privateName*/ false, /*prefix*/ "", /*suffix*/ ""); } /** diff --git a/src/compiler/factory/nodeConverters.ts b/src/compiler/factory/nodeConverters.ts index 412dbe5d62cd8..e506391a78b78 100644 --- a/src/compiler/factory/nodeConverters.ts +++ b/src/compiler/factory/nodeConverters.ts @@ -27,7 +27,6 @@ import { notImplemented, ObjectBindingOrAssignmentElement, ObjectBindingOrAssignmentPattern, - ObjectLiteralElementLike, setOriginalNode, setStartsOnNewLine, setTextRange, @@ -92,7 +91,7 @@ export function createNodeConverters(factory: NodeFactory): NodeConverters { ) : expression; } - return cast(element, isExpression); + return cast(element, isExpression); } function convertToObjectAssignmentElement(element: ObjectBindingOrAssignmentElement) { @@ -109,7 +108,7 @@ export function createNodeConverters(factory: NodeFactory): NodeConverters { return setOriginalNode(setTextRange(factory.createShorthandPropertyAssignment(element.name, element.initializer), element), element); } - return cast(element, isObjectLiteralElementLike); + return cast(element, isObjectLiteralElementLike); } function convertToAssignmentPattern(node: BindingOrAssignmentPattern): AssignmentPattern { @@ -155,7 +154,7 @@ export function createNodeConverters(factory: NodeFactory): NodeConverters { return convertToAssignmentPattern(node); } - return cast(node, isExpression); + return cast(node, isExpression); } } diff --git a/src/services/codefixes/fixImportNonExportedMember.ts b/src/services/codefixes/fixImportNonExportedMember.ts index a54704ec6d959..23731400a1601 100644 --- a/src/services/codefixes/fixImportNonExportedMember.ts +++ b/src/services/codefixes/fixImportNonExportedMember.ts @@ -11,7 +11,6 @@ import { firstOrUndefined, getResolvedModule, getTokenAtPosition, - HasLocals, Identifier, isExportDeclaration, isIdentifier, @@ -127,7 +126,7 @@ function getInfo(sourceFile: SourceFile, pos: number, program: Program): Info | if (moduleSourceFile === undefined || isSourceFileFromLibrary(program, moduleSourceFile)) return undefined; const moduleSymbol = moduleSourceFile.symbol; - const locals = tryCast(moduleSymbol.valueDeclaration, canHaveLocals)?.locals; + const locals = tryCast(moduleSymbol.valueDeclaration, canHaveLocals)?.locals; if (locals === undefined) return undefined; const localSymbol = locals.get(token.escapedText); diff --git a/src/services/completions.ts b/src/services/completions.ts index f4defbe1dc688..cec01139bef9d 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -4818,7 +4818,7 @@ function tryGetObjectTypeDeclarationCompletionContainer(sourceFile: SourceFile, case SyntaxKind.SyntaxList: return tryCast(location.parent, isObjectTypeDeclaration); case SyntaxKind.EndOfFileToken: - const cls = tryCast(lastOrUndefined(cast(location.parent, isSourceFile).statements), isObjectTypeDeclaration); + const cls = tryCast(lastOrUndefined(cast(location.parent, isSourceFile).statements), isObjectTypeDeclaration); if (cls && !findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile)) { return cls; } diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index cc23429329aa7..29ca62c2c4f19 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -16,7 +16,6 @@ import { createTextSpanFromBounds, createTextSpanFromNode, Debug, - Declaration, DefaultClause, find, FindAllReferences, @@ -190,7 +189,7 @@ export namespace DocumentHighlights { } function getFromAllDeclarations(nodeTest: (node: Node) => node is T, keywords: readonly SyntaxKind[]): HighlightSpan[] | undefined { - return useParent(node.parent, nodeTest, decl => mapDefined(tryCast(decl, canHaveSymbol)?.symbol.declarations, d => + return useParent(node.parent, nodeTest, decl => mapDefined(tryCast(decl, canHaveSymbol)?.symbol.declarations, d => nodeTest(d) ? find(d.getChildren(sourceFile), c => contains(keywords, c.kind)) : undefined)); } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 3b8df608c14d7..01ad83b784169 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -2478,7 +2478,7 @@ export namespace Core { if (symbol.valueDeclaration && isParameterPropertyDeclaration(symbol.valueDeclaration, symbol.valueDeclaration.parent)) { // For a parameter property, now try on the other symbol (property if this was a parameter, parameter if this was a property). - const paramProps = checker.getSymbolsOfParameterPropertyDeclaration(cast(symbol.valueDeclaration, isParameter), symbol.name); + const paramProps = checker.getSymbolsOfParameterPropertyDeclaration(cast(symbol.valueDeclaration, isParameter), symbol.name); Debug.assert(paramProps.length === 2 && !!(paramProps[0].flags & SymbolFlags.FunctionScopedVariable) && !!(paramProps[1].flags & SymbolFlags.Property)); // is [parameter, property] return fromRoot(symbol.flags & SymbolFlags.FunctionScopedVariable ? paramProps[1] : paramProps[0]); } diff --git a/src/services/importTracker.ts b/src/services/importTracker.ts index df83cb839f17a..aa763fc48e3df 100644 --- a/src/services/importTracker.ts +++ b/src/services/importTracker.ts @@ -10,7 +10,6 @@ import { canHaveSymbol, cast, Debug, - Declaration, ExportAssignment, ExportDeclaration, FileReference, @@ -687,10 +686,10 @@ function getExportEqualsLocalSymbol(importedSymbol: Symbol, checker: TypeChecker const decl = Debug.checkDefined(importedSymbol.valueDeclaration); if (isExportAssignment(decl)) { // `export = class {}` - return tryCast(decl.expression, canHaveSymbol)?.symbol; + return tryCast(decl.expression, canHaveSymbol)?.symbol; } else if (isBinaryExpression(decl)) { // `module.exports = class {}` - return tryCast(decl.right, canHaveSymbol)?.symbol; + return tryCast(decl.right, canHaveSymbol)?.symbol; } else if (isSourceFile(decl)) { // json module return decl.symbol; diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index f3bd8de63abb4..7950f25f5a6cf 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -505,7 +505,7 @@ function addExports(sourceFile: SourceFile, toMove: readonly Statement[], needEx return flatMap(toMove, statement => { if (isTopLevelDeclarationStatement(statement) && !isExported(sourceFile, statement, useEs6Exports) && - forEachTopLevelDeclaration(statement, d => needExport.has(Debug.checkDefined(tryCast(d, canHaveSymbol)?.symbol)))) { + forEachTopLevelDeclaration(statement, d => needExport.has(Debug.checkDefined(tryCast(d, canHaveSymbol)?.symbol)))) { const exports = addExport(statement, useEs6Exports); if (exports) return exports; } From e446399fb2ec036f75c6310038e0cf2da6d1dd21 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sun, 8 Jan 2023 14:01:32 -0800 Subject: [PATCH 75/81] Remove assertNode params --- src/compiler/binder.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b011e550269f1..fc23222eb520b 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -867,7 +867,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); } else { - Debug.assertNode(container, canHaveLocals); + Debug.assertNode(container, canHaveLocals); return declareSymbol(container.locals!, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } } @@ -899,7 +899,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { return local; } else { - Debug.assertNode(container, canHaveLocals); + Debug.assertNode(container, canHaveLocals); return declareSymbol(container.locals!, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } } @@ -2331,7 +2331,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { } // falls through default: - Debug.assertNode(blockScopeContainer, canHaveLocals); + Debug.assertNode(blockScopeContainer, canHaveLocals); if (!blockScopeContainer.locals) { blockScopeContainer.locals = createSymbolTable(); addToContainerChain(blockScopeContainer); From a0199a35b6e88e7166be579f589c99e8b1e72863 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sun, 8 Jan 2023 14:26:10 -0800 Subject: [PATCH 76/81] Attempt to revert some changes in deprecatedcompat --- .../4.8/mergeDecoratorsAndModifiers.ts | 63 ++++++++++--------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts index 25441c42fe912..fd65fe68cb413 100644 --- a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts +++ b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts @@ -71,6 +71,7 @@ import { PropertyName, QuestionToken, SetAccessorDeclaration, + some, TypeAliasDeclaration, TypeElement, TypeNode, @@ -496,7 +497,7 @@ function patchNodeFactory(factory: NodeFactory) { (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || typeof questionToken === "object" && isQuestionToken(questionToken)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || every(parameters, isParameter)) && + (parameters === undefined || !some(parameters, isTypeParameterDeclaration)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -505,7 +506,7 @@ function patchNodeFactory(factory: NodeFactory) { (asteriskToken === undefined || typeof asteriskToken === "object" && isAsteriskToken(asteriskToken)) && (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || !isArray(questionToken)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (typeParameters === undefined || !some(typeParameters, isParameter)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -532,7 +533,7 @@ function patchNodeFactory(factory: NodeFactory) { (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || typeof questionToken === "object" && isQuestionToken(questionToken)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || every(parameters, isParameter)) && + (parameters === undefined || !some(parameters, isTypeParameterDeclaration)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -541,7 +542,7 @@ function patchNodeFactory(factory: NodeFactory) { (asteriskToken === undefined || typeof asteriskToken === "object" && isAsteriskToken(asteriskToken)) && (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || !isArray(questionToken)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (typeParameters === undefined || !some(typeParameters, isParameter)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -564,13 +565,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, parameters, body, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && - (parameters === undefined || every(parameters, isParameter)) && + (modifiers === undefined || !some(modifiers, isDecorator)) && + (parameters === undefined || !some(parameters, isModifier)) && (body === undefined || !isArray(body)), 1: ([decorators, modifiers, parameters, body]) => - (decorators === undefined || every(decorators, isDecorator)) && - (modifiers === undefined || every(modifiers, isModifier)) && + (decorators === undefined || !some(decorators, isModifier)) && + (modifiers === undefined || !some(modifiers, isParameter)) && (parameters === undefined || isArray(parameters)) && (body === undefined || isBlock(body)), }) @@ -592,13 +593,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, parameters, body, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && - (parameters === undefined || every(parameters, isParameter)) && + (modifiers === undefined || !some(modifiers, isDecorator)) && + (parameters === undefined || !some(parameters, isModifier)) && (body === undefined || !isArray(body)), 1: ([, decorators, modifiers, parameters, body]) => - (decorators === undefined || every(decorators, isDecorator)) && - (modifiers === undefined || every(modifiers, isModifier)) && + (decorators === undefined || !some(decorators, isModifier)) && + (modifiers === undefined || !some(modifiers, isParameter)) && (parameters === undefined || isArray(parameters)) && (body === undefined || isBlock(body)), }) @@ -765,7 +766,7 @@ function patchNodeFactory(factory: NodeFactory) { 0: ([, modifiers, parameters, type, other]) => (other === undefined) && (modifiers === undefined || every(modifiers, isModifier)) && - (parameters === undefined || every(parameters, isParameter)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)), 1: ([, decorators, modifiers, parameters, type]) => @@ -846,8 +847,8 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && @@ -876,8 +877,8 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, , modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && @@ -941,7 +942,7 @@ function patchNodeFactory(factory: NodeFactory) { (asteriskToken === undefined || !isArray(asteriskToken)) && (name === undefined || isIdentifier(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || every(parameters, isParameter)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -974,8 +975,8 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: () => true, }) @@ -999,8 +1000,8 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, , modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && @@ -1030,8 +1031,8 @@ function patchNodeFactory(factory: NodeFactory) { (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isTypeElement)), 1: ([decorators, modifiers, name, typeParameters, heritageClauses, members]) => (decorators === undefined || every(decorators, isDecorator)) && @@ -1062,8 +1063,8 @@ function patchNodeFactory(factory: NodeFactory) { (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isTypeElement)), 1: ([, decorators, modifiers, name, typeParameters, heritageClauses, members]) => (decorators === undefined || every(decorators, isDecorator)) && @@ -1331,7 +1332,7 @@ function patchNodeFactory(factory: NodeFactory) { (assertClause === undefined || isAssertClause(assertClause)), 1: ([decorators, modifiers, importClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (importClause === undefined || isImportClause(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && @@ -1361,7 +1362,7 @@ function patchNodeFactory(factory: NodeFactory) { (assertClause === undefined || isAssertClause(assertClause)), 1: ([, decorators, modifiers, importClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (importClause === undefined || isImportClause(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && @@ -1390,7 +1391,7 @@ function patchNodeFactory(factory: NodeFactory) { (typeof expression === "object"), 1: ([decorators, modifiers, isExportEquals, expression]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isExportEquals === undefined || typeof isExportEquals === "boolean") && (expression !== undefined && isExpression(expression)), @@ -1417,7 +1418,7 @@ function patchNodeFactory(factory: NodeFactory) { (expression !== undefined && !isArray(expression)), 1: ([, decorators, modifiers, expression]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (expression !== undefined && isExpression(expression)), }) @@ -1446,7 +1447,7 @@ function patchNodeFactory(factory: NodeFactory) { (assertClause === undefined || isAssertClause(assertClause)), 1: ([decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (typeof isTypeOnly === "boolean") && (exportClause === undefined || isNamedExportBindings(exportClause)) && From 41cb1fce2722e5ce139255d5424ff80906d8425d Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:45:02 -0800 Subject: [PATCH 77/81] For now, just fully specify all every/some in this file --- .../4.8/mergeDecoratorsAndModifiers.ts | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts index fd65fe68cb413..312f4050f4a6a 100644 --- a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts +++ b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts @@ -766,7 +766,7 @@ function patchNodeFactory(factory: NodeFactory) { 0: ([, modifiers, parameters, type, other]) => (other === undefined) && (modifiers === undefined || every(modifiers, isModifier)) && - (parameters === undefined || every(parameters, isParameter)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)), 1: ([, decorators, modifiers, parameters, type]) => @@ -847,8 +847,8 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && @@ -877,8 +877,8 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, , modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && @@ -942,7 +942,7 @@ function patchNodeFactory(factory: NodeFactory) { (asteriskToken === undefined || !isArray(asteriskToken)) && (name === undefined || isIdentifier(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || every(parameters, isParameter)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -975,8 +975,8 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: () => true, }) @@ -1000,8 +1000,8 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, , modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && @@ -1031,8 +1031,8 @@ function patchNodeFactory(factory: NodeFactory) { (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isTypeElement)), 1: ([decorators, modifiers, name, typeParameters, heritageClauses, members]) => (decorators === undefined || every(decorators, isDecorator)) && @@ -1040,7 +1040,7 @@ function patchNodeFactory(factory: NodeFactory) { (name === undefined || !isArray(name)) && (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (members === undefined || every(members, isTypeElement)), }) .deprecate({ 1: DISALLOW_DECORATORS @@ -1063,8 +1063,8 @@ function patchNodeFactory(factory: NodeFactory) { (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isTypeElement)), 1: ([, decorators, modifiers, name, typeParameters, heritageClauses, members]) => (decorators === undefined || every(decorators, isDecorator)) && @@ -1072,7 +1072,7 @@ function patchNodeFactory(factory: NodeFactory) { (name === undefined || !isArray(name)) && (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (members === undefined || every(members, isTypeElement)), }) .deprecate({ 1: DISALLOW_DECORATORS @@ -1332,7 +1332,7 @@ function patchNodeFactory(factory: NodeFactory) { (assertClause === undefined || isAssertClause(assertClause)), 1: ([decorators, modifiers, importClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (importClause === undefined || isImportClause(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && @@ -1362,7 +1362,7 @@ function patchNodeFactory(factory: NodeFactory) { (assertClause === undefined || isAssertClause(assertClause)), 1: ([, decorators, modifiers, importClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (importClause === undefined || isImportClause(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && @@ -1391,7 +1391,7 @@ function patchNodeFactory(factory: NodeFactory) { (typeof expression === "object"), 1: ([decorators, modifiers, isExportEquals, expression]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isExportEquals === undefined || typeof isExportEquals === "boolean") && (expression !== undefined && isExpression(expression)), @@ -1418,7 +1418,7 @@ function patchNodeFactory(factory: NodeFactory) { (expression !== undefined && !isArray(expression)), 1: ([, decorators, modifiers, expression]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (expression !== undefined && isExpression(expression)), }) @@ -1447,7 +1447,7 @@ function patchNodeFactory(factory: NodeFactory) { (assertClause === undefined || isAssertClause(assertClause)), 1: ([decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (typeof isTypeOnly === "boolean") && (exportClause === undefined || isNamedExportBindings(exportClause)) && From ae4be6ba5629ddb42ddc7f9b4deb86573c6ccddb Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 9 Jan 2023 16:50:08 -0800 Subject: [PATCH 78/81] Fix typo --- src/services/codefixes/importFixes.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 053aa33236219..5b8cef4f560ce 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -1003,9 +1003,9 @@ function getUmdSymbol(token: Node, checker: TypeChecker): Symbol | undefined { // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. const { parent } = token; if ((isJsxOpeningLikeElement(parent) && parent.tagName === token) || isJsxOpeningFragment(parent)) { - const parnetSymbol = checker.resolveName(checker.getJsxNamespace(parent), isJsxOpeningLikeElement(parent) ? token : parent, SymbolFlags.Value, /*excludeGlobals*/ false); - if (isUMDExportSymbol(parnetSymbol)) { - return parnetSymbol; + const parentSymbol = checker.resolveName(checker.getJsxNamespace(parent), isJsxOpeningLikeElement(parent) ? token : parent, SymbolFlags.Value, /*excludeGlobals*/ false); + if (isUMDExportSymbol(parentSymbol)) { + return parentSymbol; } } return undefined; From 00261cba71b8d582228a1a4a833492548c30a37b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 10 Jan 2023 16:34:25 -0800 Subject: [PATCH 79/81] Revert some explicit type parameters fixed by inference tweak PRs in main --- src/compiler/factory/parenthesizerRules.ts | 15 +- src/compiler/utilities.ts | 2 +- .../4.8/mergeDecoratorsAndModifiers.ts | 161 +++++++++--------- src/services/documentHighlights.ts | 4 +- .../unittests/services/textChanges.ts | 2 +- 5 files changed, 88 insertions(+), 96 deletions(-) diff --git a/src/compiler/factory/parenthesizerRules.ts b/src/compiler/factory/parenthesizerRules.ts index 4dec4f8be686e..119ad2953a195 100644 --- a/src/compiler/factory/parenthesizerRules.ts +++ b/src/compiler/factory/parenthesizerRules.ts @@ -36,7 +36,6 @@ import { LeftHandSideExpression, NamedTupleMember, NewExpression, - Node, NodeArray, NodeFactory, OperatorPrecedence, @@ -654,10 +653,6 @@ export function createParenthesizerRules(factory: NodeFactory): ParenthesizerRul } } -function castToNodeArray(nodes: readonly T[]): NodeArray { - return cast, readonly T[]>(nodes, isNodeArray); -} - /** @internal */ export const nullParenthesizerRules: ParenthesizerRules = { getParenthesizeLeftSideOfBinaryForOperator: _ => identity, @@ -672,22 +667,22 @@ export const nullParenthesizerRules: ParenthesizerRules = { parenthesizeLeftSideOfAccess: expression => cast(expression, isLeftHandSideExpression), parenthesizeOperandOfPostfixUnary: operand => cast(operand, isLeftHandSideExpression), parenthesizeOperandOfPrefixUnary: operand => cast(operand, isUnaryExpression), - parenthesizeExpressionsOfCommaDelimitedList: castToNodeArray, + parenthesizeExpressionsOfCommaDelimitedList: nodes => cast(nodes, isNodeArray), parenthesizeExpressionForDisallowedComma: identity, parenthesizeExpressionOfExpressionStatement: identity, parenthesizeConciseBodyOfArrowFunction: identity, parenthesizeCheckTypeOfConditionalType: identity, parenthesizeExtendsTypeOfConditionalType: identity, - parenthesizeConstituentTypesOfUnionType: castToNodeArray, + parenthesizeConstituentTypesOfUnionType: nodes => cast(nodes, isNodeArray), parenthesizeConstituentTypeOfUnionType: identity, - parenthesizeConstituentTypesOfIntersectionType: castToNodeArray, + parenthesizeConstituentTypesOfIntersectionType: nodes => cast(nodes, isNodeArray), parenthesizeConstituentTypeOfIntersectionType: identity, parenthesizeOperandOfTypeOperator: identity, parenthesizeOperandOfReadonlyTypeOperator: identity, parenthesizeNonArrayTypeOfPostfixType: identity, - parenthesizeElementTypesOfTupleType: castToNodeArray, + parenthesizeElementTypesOfTupleType: nodes => cast(nodes, isNodeArray), parenthesizeElementTypeOfTupleType: identity, parenthesizeTypeOfOptionalType: identity, - parenthesizeTypeArguments: nodes => nodes && castToNodeArray(nodes), + parenthesizeTypeArguments: nodes => nodes && cast(nodes, isNodeArray), parenthesizeLeadingTypeArgument: identity, }; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index ed214bf49037f..810c8e04299b9 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -8711,7 +8711,7 @@ export function isAnySupportedFileExtension(path: string): boolean { /** @internal */ export function tryGetExtensionFromPath(path: string): Extension | undefined { - return find(extensionsToRemove, e => fileExtensionIs(path, e)); + return find(extensionsToRemove, e => fileExtensionIs(path, e)); } /** @internal */ diff --git a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts index 312f4050f4a6a..d23969ccda6be 100644 --- a/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts +++ b/src/deprecatedCompat/4.8/mergeDecoratorsAndModifiers.ts @@ -63,7 +63,6 @@ import { ModuleName, ModuleReference, NamedExportBindings, - Node, NodeFactory, NodeFlags, ParameterDeclaration, @@ -497,7 +496,7 @@ function patchNodeFactory(factory: NodeFactory) { (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || typeof questionToken === "object" && isQuestionToken(questionToken)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || !some(parameters, isTypeParameterDeclaration)) && + (parameters === undefined || !some(parameters, isTypeParameterDeclaration)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -506,7 +505,7 @@ function patchNodeFactory(factory: NodeFactory) { (asteriskToken === undefined || typeof asteriskToken === "object" && isAsteriskToken(asteriskToken)) && (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || !isArray(questionToken)) && - (typeParameters === undefined || !some(typeParameters, isParameter)) && + (typeParameters === undefined || !some(typeParameters, isParameter)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -533,7 +532,7 @@ function patchNodeFactory(factory: NodeFactory) { (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || typeof questionToken === "object" && isQuestionToken(questionToken)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || !some(parameters, isTypeParameterDeclaration)) && + (parameters === undefined || !some(parameters, isTypeParameterDeclaration)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -542,7 +541,7 @@ function patchNodeFactory(factory: NodeFactory) { (asteriskToken === undefined || typeof asteriskToken === "object" && isAsteriskToken(asteriskToken)) && (name === undefined || typeof name === "string" || isPropertyName(name)) && (questionToken === undefined || !isArray(questionToken)) && - (typeParameters === undefined || !some(typeParameters, isParameter)) && + (typeParameters === undefined || !some(typeParameters, isParameter)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -565,13 +564,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, parameters, body, other]) => (other === undefined) && - (modifiers === undefined || !some(modifiers, isDecorator)) && - (parameters === undefined || !some(parameters, isModifier)) && + (modifiers === undefined || !some(modifiers, isDecorator)) && + (parameters === undefined || !some(parameters, isModifier)) && (body === undefined || !isArray(body)), 1: ([decorators, modifiers, parameters, body]) => - (decorators === undefined || !some(decorators, isModifier)) && - (modifiers === undefined || !some(modifiers, isParameter)) && + (decorators === undefined || !some(decorators, isModifier)) && + (modifiers === undefined || !some(modifiers, isParameter)) && (parameters === undefined || isArray(parameters)) && (body === undefined || isBlock(body)), }) @@ -593,13 +592,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, parameters, body, other]) => (other === undefined) && - (modifiers === undefined || !some(modifiers, isDecorator)) && - (parameters === undefined || !some(parameters, isModifier)) && + (modifiers === undefined || !some(modifiers, isDecorator)) && + (parameters === undefined || !some(parameters, isModifier)) && (body === undefined || !isArray(body)), 1: ([, decorators, modifiers, parameters, body]) => - (decorators === undefined || !some(decorators, isModifier)) && - (modifiers === undefined || !some(modifiers, isParameter)) && + (decorators === undefined || !some(decorators, isModifier)) && + (modifiers === undefined || !some(modifiers, isParameter)) && (parameters === undefined || isArray(parameters)) && (body === undefined || isBlock(body)), }) @@ -737,13 +736,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, parameters, type, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && - (parameters === undefined || every(parameters, isParameter)) && + (modifiers === undefined || every(modifiers, isModifier)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)), 1: ([decorators, modifiers, parameters, type]) => - (decorators === undefined || every(decorators, isDecorator)) && - (modifiers === undefined || every(modifiers, isModifier)) && + (decorators === undefined || every(decorators, isDecorator)) && + (modifiers === undefined || every(modifiers, isModifier)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)), }) @@ -765,13 +764,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, parameters, type, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && - (parameters === undefined || every(parameters, isParameter)) && + (modifiers === undefined || every(modifiers, isModifier)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)), 1: ([, decorators, modifiers, parameters, type]) => - (decorators === undefined || every(decorators, isDecorator)) && - (modifiers === undefined || every(modifiers, isModifier)) && + (decorators === undefined || every(decorators, isDecorator)) && + (modifiers === undefined || every(modifiers, isModifier)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)), }) @@ -847,14 +846,14 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && (members === undefined || isArray(members)), }) .deprecate({ @@ -877,14 +876,14 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, , modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && (members === undefined || isArray(members)), }) .deprecate({ @@ -908,7 +907,7 @@ function patchNodeFactory(factory: NodeFactory) { (asteriskToken === undefined || !isArray(asteriskToken)) && (name === undefined || typeof name === "string" || isIdentifier(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || every(parameters, isParameter)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -916,7 +915,7 @@ function patchNodeFactory(factory: NodeFactory) { (modifiers === undefined || isArray(modifiers)) && (asteriskToken === undefined || typeof asteriskToken !== "string" && isAsteriskToken(asteriskToken)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -942,7 +941,7 @@ function patchNodeFactory(factory: NodeFactory) { (asteriskToken === undefined || !isArray(asteriskToken)) && (name === undefined || isIdentifier(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (parameters === undefined || every(parameters, isParameter)) && + (parameters === undefined || every(parameters, isParameter)) && (type === undefined || !isArray(type)) && (body === undefined || isBlock(body)), @@ -950,7 +949,7 @@ function patchNodeFactory(factory: NodeFactory) { (modifiers === undefined || isArray(modifiers)) && (asteriskToken === undefined || typeof asteriskToken !== "string" && isAsteriskToken(asteriskToken)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && (parameters === undefined || isArray(parameters)) && (type === undefined || isTypeNode(type)) && (body === undefined || isBlock(body)), @@ -975,8 +974,8 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: () => true, }) @@ -1000,14 +999,14 @@ function patchNodeFactory(factory: NodeFactory) { (other === undefined) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isClassElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isClassElement)), 1: ([, , modifiers, name, typeParameters, heritageClauses, members]) => (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && (members === undefined || isArray(members)), }) .deprecate({ @@ -1028,19 +1027,19 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, name, typeParameters, heritageClauses, members, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isTypeElement)), 1: ([decorators, modifiers, name, typeParameters, heritageClauses, members]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isTypeElement)), }) .deprecate({ 1: DISALLOW_DECORATORS @@ -1060,19 +1059,19 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, name, typeParameters, heritageClauses, members, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isTypeElement)), 1: ([, decorators, modifiers, name, typeParameters, heritageClauses, members]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && - (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && - (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && - (members === undefined || every(members, isTypeElement)), + (typeParameters === undefined || every(typeParameters, isTypeParameterDeclaration)) && + (heritageClauses === undefined || every(heritageClauses, isHeritageClause)) && + (members === undefined || every(members, isTypeElement)), }) .deprecate({ 1: DISALLOW_DECORATORS @@ -1092,13 +1091,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, name, typeParameters, type, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && (type === undefined || !isArray(type)), 1: ([decorators, modifiers, name, typeParameters, type]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && @@ -1122,13 +1121,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, name, typeParameters, type, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && (type === undefined || !isArray(type)), 1: ([, decorators, modifiers, name, typeParameters, type]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (typeParameters === undefined || isArray(typeParameters)) && @@ -1152,12 +1151,12 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, name, members, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), 1: ([decorators, modifiers, name, members]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), @@ -1180,12 +1179,12 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, name, members, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), 1: ([, decorators, modifiers, name, members]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name === undefined || !isArray(name)) && (members === undefined || isArray(members)), @@ -1208,13 +1207,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, name, body, flags, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name !== undefined && !isArray(name)) && (body === undefined || isModuleBody(body)) && (flags === undefined || typeof flags === "number"), 1: ([decorators, modifiers, name, body, flags]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name !== undefined && isModuleName(name)) && (body === undefined || typeof body === "object") && @@ -1238,12 +1237,12 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, name, body, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (name === undefined || !isArray(name)) && (body === undefined || isModuleBody(body)), 1: ([, decorators, modifiers, name, body]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (name !== undefined && isModuleName(name)) && (body === undefined || isModuleBody(body)), @@ -1266,13 +1265,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, isTypeOnly, name, moduleReference, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name !== "boolean") && (typeof moduleReference !== "string"), 1: ([decorators, modifiers, isTypeOnly, name, moduleReference]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name === "string" || isIdentifier(name)) && @@ -1296,13 +1295,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, isTypeOnly, name, moduleReference, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name !== "boolean") && (typeof moduleReference !== "string"), 1: ([, decorators, modifiers, isTypeOnly, name, moduleReference]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isTypeOnly === undefined || typeof isTypeOnly === "boolean") && (typeof name === "string" || isIdentifier(name)) && @@ -1326,13 +1325,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, importClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (importClause === undefined || !isArray(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([decorators, modifiers, importClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (importClause === undefined || isImportClause(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && @@ -1356,13 +1355,13 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, importClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (importClause === undefined || !isArray(importClause)) && (moduleSpecifier === undefined || isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([, decorators, modifiers, importClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (importClause === undefined || isImportClause(importClause)) && (moduleSpecifier !== undefined && isExpression(moduleSpecifier)) && @@ -1386,12 +1385,12 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, isExportEquals, expression, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (isExportEquals === undefined || typeof isExportEquals === "boolean") && (typeof expression === "object"), 1: ([decorators, modifiers, isExportEquals, expression]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (isExportEquals === undefined || typeof isExportEquals === "boolean") && (expression !== undefined && isExpression(expression)), @@ -1414,11 +1413,11 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, expression, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (expression !== undefined && !isArray(expression)), 1: ([, decorators, modifiers, expression]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (expression !== undefined && isExpression(expression)), }) @@ -1440,14 +1439,14 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (typeof isTypeOnly === "boolean") && (typeof exportClause !== "boolean") && (moduleSpecifier === undefined || isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (typeof isTypeOnly === "boolean") && (exportClause === undefined || isNamedExportBindings(exportClause)) && @@ -1472,14 +1471,14 @@ function patchNodeFactory(factory: NodeFactory) { .bind({ 0: ([, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause, other]) => (other === undefined) && - (modifiers === undefined || every(modifiers, isModifier)) && + (modifiers === undefined || every(modifiers, isModifier)) && (typeof isTypeOnly === "boolean") && (typeof exportClause !== "boolean") && (moduleSpecifier === undefined || isExpression(moduleSpecifier)) && (assertClause === undefined || isAssertClause(assertClause)), 1: ([, decorators, modifiers, isTypeOnly, exportClause, moduleSpecifier, assertClause]) => - (decorators === undefined || every(decorators, isDecorator)) && + (decorators === undefined || every(decorators, isDecorator)) && (modifiers === undefined || isArray(modifiers)) && (typeof isTypeOnly === "boolean") && (exportClause === undefined || isNamedExportBindings(exportClause)) && diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index 29ca62c2c4f19..ab021d575aaf7 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -8,7 +8,6 @@ import { canHaveSymbol, CaseClause, cast, - ClassElement, concatenate, ConstructorDeclaration, contains, @@ -83,7 +82,6 @@ import { toPath, tryCast, TryStatement, - TypeElement, } from "./_namespaces/ts"; export interface DocumentHighlights { @@ -323,7 +321,7 @@ export namespace DocumentHighlights { // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & (ModifierFlags.AccessibilityModifier | ModifierFlags.Readonly)) { - const constructor = find(container.members, isConstructorDeclaration); + const constructor = find(container.members, isConstructorDeclaration); if (constructor) { return [...nodes, ...constructor.parameters]; } diff --git a/src/testRunner/unittests/services/textChanges.ts b/src/testRunner/unittests/services/textChanges.ts index a761083145999..5013a5d994ad1 100644 --- a/src/testRunner/unittests/services/textChanges.ts +++ b/src/testRunner/unittests/services/textChanges.ts @@ -330,7 +330,7 @@ namespace M { function findConstructor(sourceFile: ts.SourceFile): ts.ConstructorDeclaration { const classDecl = sourceFile.statements[0] as ts.ClassDeclaration; - return ts.find(classDecl.members, (m): m is ts.ConstructorDeclaration => ts.isConstructorDeclaration(m) && !!m.body)!; + return ts.find(classDecl.members, (m): m is ts.ConstructorDeclaration => ts.isConstructorDeclaration(m) && !!m.body)!; } function createTestSuperCall() { const superCall = ts.factory.createCallExpression( From 837c3d5ed0093032935059a706aff22f01cd76e6 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 12 Jan 2023 20:36:09 -0800 Subject: [PATCH 80/81] Make visitor required in API --- src/compiler/checker.ts | 2 +- src/compiler/transformers/destructuring.ts | 4 +- src/compiler/transformers/module/module.ts | 2 +- src/compiler/types.ts | 8 +-- src/compiler/visitorPublic.ts | 71 ++++++++++--------- src/services/textChanges.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 16 ++--- tests/baselines/reference/api/typescript.d.ts | 16 ++--- 8 files changed, 61 insertions(+), 60 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5a375daa46460..ba53210327cd3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6637,7 +6637,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function deepCloneOrReuseNodes( nodes: NodeArray | undefined, - visitor: Visitor | undefined, + visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number, diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 905d5d45f9d44..f95c9fabab7b2 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -74,7 +74,7 @@ interface FlattenContext { createArrayBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ArrayBindingOrAssignmentPattern; createObjectBindingOrAssignmentPattern: (elements: BindingOrAssignmentElement[]) => ObjectBindingOrAssignmentPattern; createArrayBindingOrAssignmentElement: (node: Identifier) => BindingOrAssignmentElement; - visitor?: (node: Node) => VisitResult; + visitor: (node: Node) => VisitResult; } /** @internal */ @@ -98,7 +98,7 @@ export const enum FlattenLevel { */ export function flattenDestructuringAssignment( node: VariableDeclaration | DestructuringAssignment, - visitor: ((node: Node) => VisitResult) | undefined, + visitor: ((node: Node) => VisitResult), context: TransformationContext, level: FlattenLevel, needsValue?: boolean, diff --git a/src/compiler/transformers/module/module.ts b/src/compiler/transformers/module/module.ts index 099c3838d58a6..cdcb78401c126 100644 --- a/src/compiler/transformers/module/module.ts +++ b/src/compiler/transformers/module/module.ts @@ -1573,7 +1573,7 @@ export function transformModule(context: TransformationContext): (x: SourceFile if (isBindingPattern(node.name)) { return flattenDestructuringAssignment( visitNode(node, visitor, isInitializedVariable), - /*visitor*/ undefined, + visitor, context, FlattenLevel.All, /*needsValue*/ false, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index ee0a35f5f4d0c..4ca0ed6e54d5f 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -9071,13 +9071,13 @@ export type Visitor( node: TIn, - visitor: Visitor, TVisited> | undefined, + visitor: Visitor, TVisited>, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node, ): TOut | (TIn & undefined) | (TVisited & undefined); ( node: TIn, - visitor: Visitor, TVisited> | undefined, + visitor: Visitor, TVisited>, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node, ): Node | (TIn & undefined) | (TVisited & undefined); @@ -9097,14 +9097,14 @@ export interface NodeVisitor { export interface NodesVisitor { | undefined, TOut extends Node>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor, test: (node: Node) => node is TOut, start?: number, count?: number, ): NodeArray | (TInArray & undefined); | undefined>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number, diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index a078c4a43f9b5..468b8278d1d25 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -118,7 +118,7 @@ import { */ export function visitNode( node: TIn, - visitor: Visitor, TVisited> | undefined, + visitor: Visitor, TVisited>, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node, ): TOut | (TIn & undefined) | (TVisited & undefined); @@ -138,13 +138,13 @@ export function visitNode( node: TIn, - visitor: Visitor, TVisited> | undefined, + visitor: Visitor, TVisited>, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node, ): Node | (TIn & undefined) | (TVisited & undefined); export function visitNode( node: Node, - visitor: Visitor | undefined, + visitor: Visitor, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node, ): Node | undefined { @@ -153,6 +153,7 @@ export function visitNode( return node; } + // TODO(jakebailey): remove this check? const visited = visitor ? visitor(node) : node; let visitedNode: Node | undefined; @@ -190,7 +191,7 @@ export function visitNode( */ export function visitNodes | undefined, TOut extends Node>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor, test: (node: Node) => node is TOut, start?: number, count?: number, @@ -212,14 +213,14 @@ export function visitNodes | u */ export function visitNodes | undefined>( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number, ): NodeArray | (TInArray & undefined); export function visitNodes( nodes: NodeArray | undefined, - visitor: Visitor | undefined, + visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number, @@ -270,7 +271,7 @@ export function visitNodes( /** @internal */ export function visitArray( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor, test: (node: Node) => node is TOut, start?: number, count?: number, @@ -278,14 +279,14 @@ export function visitArray( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number, ): readonly Node[] | (TInArray & undefined); export function visitArray( nodes: readonly Node[] | undefined, - visitor: Visitor | undefined, + visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number, @@ -310,14 +311,14 @@ export function visitArray( function visitArrayWorker( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor, test: (node: Node) => node is TOut, start: number, count: number, ): readonly TOut[]; function visitArrayWorker( nodes: TInArray, - visitor: Visitor | undefined, + visitor: Visitor, test: ((node: Node) => boolean) | undefined, start: number, count: number, @@ -632,9 +633,9 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.Parameter]: function visitEachChildOfParameterDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateParameterDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifierLike), - nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken), + tokenVisitor ? nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken) : node.dotDotDotToken, Debug.checkDefined(nodeVisitor(node.name, visitor, isBindingName)), - nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), + tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken) : node.questionToken, nodeVisitor(node.type, visitor, isTypeNode), nodeVisitor(node.initializer, visitor, isExpression)); }, @@ -649,7 +650,7 @@ const visitEachChildTable: VisitEachChildTable = { return context.factory.updatePropertySignature(node, nodesVisitor(node.modifiers, visitor, isModifier), Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), - nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), + tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken) : node.questionToken, nodeVisitor(node.type, visitor, isTypeNode)); }, @@ -658,7 +659,7 @@ const visitEachChildTable: VisitEachChildTable = { nodesVisitor(node.modifiers, visitor, isModifierLike), Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), // QuestionToken and ExclamationToken are mutually exclusive in PropertyDeclaration - nodeVisitor(node.questionToken ?? node.exclamationToken, tokenVisitor, isQuestionOrExclamationToken), + tokenVisitor ? nodeVisitor(node.questionToken ?? node.exclamationToken, tokenVisitor, isQuestionOrExclamationToken) : node.questionToken ?? node.exclamationToken, nodeVisitor(node.type, visitor, isTypeNode), nodeVisitor(node.initializer, visitor, isExpression)); }, @@ -667,7 +668,7 @@ const visitEachChildTable: VisitEachChildTable = { return context.factory.updateMethodSignature(node, nodesVisitor(node.modifiers, visitor, isModifier), Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), - nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), + tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken) : node.questionToken, nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, isParameter), nodeVisitor(node.type, visitor, isTypeNode)); @@ -676,9 +677,9 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.MethodDeclaration]: function visitEachChildOfMethodDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateMethodDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifierLike), - nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken), + tokenVisitor ? nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken) : node.asteriskToken, Debug.checkDefined(nodeVisitor(node.name, visitor, isPropertyName)), - nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), + tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken) : node.questionToken, nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), nodeVisitor(node.type, visitor, isTypeNode), @@ -839,9 +840,9 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.NamedTupleMember]: function visitEachChildOfNamedTupleMember(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateNamedTupleMember(node, - nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken), + tokenVisitor ? nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken) : node.dotDotDotToken, Debug.checkDefined(nodeVisitor(node.name, visitor, isIdentifier)), - nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken), + tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken) : node.questionToken, Debug.checkDefined(nodeVisitor(node.type, visitor, isTypeNode)), ); }, @@ -864,10 +865,10 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.MappedType]: function visitEachChildOfMappedType(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateMappedTypeNode(node, - nodeVisitor(node.readonlyToken, tokenVisitor, isReadonlyKeywordOrPlusOrMinusToken), + tokenVisitor ? nodeVisitor(node.readonlyToken, tokenVisitor, isReadonlyKeywordOrPlusOrMinusToken) : node.readonlyToken, Debug.checkDefined(nodeVisitor(node.typeParameter, visitor, isTypeParameterDeclaration)), nodeVisitor(node.nameType, visitor, isTypeNode), - nodeVisitor(node.questionToken, tokenVisitor, isQuestionOrPlusOrMinusToken), + tokenVisitor ? nodeVisitor(node.questionToken, tokenVisitor, isQuestionOrPlusOrMinusToken) : node.questionToken, nodeVisitor(node.type, visitor, isTypeNode), nodesVisitor(node.members, visitor, isTypeElement)); }, @@ -902,7 +903,7 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.BindingElement]: function visitEachChildOfBindingElement(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateBindingElement(node, - nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken), + tokenVisitor ? nodeVisitor(node.dotDotDotToken, tokenVisitor, isDotDotDotToken) : node.dotDotDotToken, nodeVisitor(node.propertyName, visitor, isPropertyName), Debug.checkDefined(nodeVisitor(node.name, visitor, isBindingName)), nodeVisitor(node.initializer, visitor, isExpression)); @@ -923,7 +924,7 @@ const visitEachChildTable: VisitEachChildTable = { return isPropertyAccessChain(node) ? context.factory.updatePropertyAccessChain(node, Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), - nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken), + tokenVisitor ? nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken) : node.questionDotToken, Debug.checkDefined(nodeVisitor(node.name, visitor, isMemberName))) : context.factory.updatePropertyAccessExpression(node, Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), @@ -934,7 +935,7 @@ const visitEachChildTable: VisitEachChildTable = { return isElementAccessChain(node) ? context.factory.updateElementAccessChain(node, Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), - nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken), + tokenVisitor ? nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken) : node.questionDotToken, Debug.checkDefined(nodeVisitor(node.argumentExpression, visitor, isExpression))) : context.factory.updateElementAccessExpression(node, Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), @@ -945,7 +946,7 @@ const visitEachChildTable: VisitEachChildTable = { return isCallChain(node) ? context.factory.updateCallChain(node, Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), - nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken), + tokenVisitor ? nodeVisitor(node.questionDotToken, tokenVisitor, isQuestionDotToken) : node.questionDotToken, nodesVisitor(node.typeArguments, visitor, isTypeNode), nodesVisitor(node.arguments, visitor, isExpression)) : context.factory.updateCallExpression(node, @@ -982,7 +983,7 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.FunctionExpression]: function visitEachChildOfFunctionExpression(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken), + tokenVisitor ? nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken) : node.asteriskToken, nodeVisitor(node.name, visitor, isIdentifier), nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), @@ -996,7 +997,7 @@ const visitEachChildTable: VisitEachChildTable = { nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), nodeVisitor(node.type, visitor, isTypeNode), - Debug.checkDefined(nodeVisitor(node.equalsGreaterThanToken, tokenVisitor, isEqualsGreaterThanToken)), + tokenVisitor ? Debug.checkDefined(nodeVisitor(node.equalsGreaterThanToken, tokenVisitor, isEqualsGreaterThanToken)) : node.equalsGreaterThanToken, visitFunctionBody(node.body, visitor, context, nodeVisitor)); }, @@ -1033,16 +1034,16 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.BinaryExpression]: function visitEachChildOfBinaryExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateBinaryExpression(node, Debug.checkDefined(nodeVisitor(node.left, visitor, isExpression)), - Debug.checkDefined(nodeVisitor(node.operatorToken, tokenVisitor, isBinaryOperatorToken)), + tokenVisitor ? Debug.checkDefined(nodeVisitor(node.operatorToken, tokenVisitor, isBinaryOperatorToken)) : node.operatorToken, Debug.checkDefined(nodeVisitor(node.right, visitor, isExpression))); }, [SyntaxKind.ConditionalExpression]: function visitEachChildOfConditionalExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateConditionalExpression(node, Debug.checkDefined(nodeVisitor(node.condition, visitor, isExpression)), - Debug.checkDefined(nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken)), + tokenVisitor ? Debug.checkDefined(nodeVisitor(node.questionToken, tokenVisitor, isQuestionToken)) : node.questionToken, Debug.checkDefined(nodeVisitor(node.whenTrue, visitor, isExpression)), - Debug.checkDefined(nodeVisitor(node.colonToken, tokenVisitor, isColonToken)), + tokenVisitor ? Debug.checkDefined(nodeVisitor(node.colonToken, tokenVisitor, isColonToken)) : node.colonToken, Debug.checkDefined(nodeVisitor(node.whenFalse, visitor, isExpression))); }, @@ -1054,7 +1055,7 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.YieldExpression]: function visitEachChildOfYieldExpression(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateYieldExpression(node, - nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken), + tokenVisitor ? nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken) : node.asteriskToken, nodeVisitor(node.expression, visitor, isExpression)); }, @@ -1163,7 +1164,7 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.ForOfStatement]: function visitEachChildOfForOfStatement(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateForOfStatement(node, - nodeVisitor(node.awaitModifier, tokenVisitor, isAwaitKeyword), + tokenVisitor ? nodeVisitor(node.awaitModifier, tokenVisitor, isAwaitKeyword) : node.awaitModifier, Debug.checkDefined(nodeVisitor(node.initializer, visitor, isForInitializer)), Debug.checkDefined(nodeVisitor(node.expression, visitor, isExpression)), visitIterationBody(node.statement, visitor, context, nodeVisitor)); @@ -1217,7 +1218,7 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.VariableDeclaration]: function visitEachChildOfVariableDeclaration(node, visitor, context, _nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateVariableDeclaration(node, Debug.checkDefined(nodeVisitor(node.name, visitor, isBindingName)), - nodeVisitor(node.exclamationToken, tokenVisitor, isExclamationToken), + tokenVisitor ? nodeVisitor(node.exclamationToken, tokenVisitor, isExclamationToken) : node.exclamationToken, nodeVisitor(node.type, visitor, isTypeNode), nodeVisitor(node.initializer, visitor, isExpression)); }, @@ -1230,7 +1231,7 @@ const visitEachChildTable: VisitEachChildTable = { [SyntaxKind.FunctionDeclaration]: function visitEachChildOfFunctionDeclaration(node, visitor, context, nodesVisitor, nodeVisitor, tokenVisitor) { return context.factory.updateFunctionDeclaration(node, nodesVisitor(node.modifiers, visitor, isModifier), - nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken), + tokenVisitor ? nodeVisitor(node.asteriskToken, tokenVisitor, isAsteriskToken) : node.asteriskToken, nodeVisitor(node.name, visitor, isIdentifier), nodesVisitor(node.typeParameters, visitor, isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 7cd4f825c417d..50621f641601d 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1344,7 +1344,7 @@ export function assignPositionsToNode(node: Node): Node { function assignPositionsToNodeArray( nodes: NodeArray | undefined, - visitor: Visitor | undefined, + visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 0fa4bbab33cca..9148799b72697 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -8205,8 +8205,8 @@ declare namespace ts { * For the canonical implementation of this type, @see {visitNode}. */ interface NodeVisitor { - (node: TIn, visitor: Visitor, TVisited> | undefined, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); - (node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); + (node: TIn, visitor: Visitor, TVisited>, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); + (node: TIn, visitor: Visitor, TVisited>, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); } /** * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. @@ -8220,8 +8220,8 @@ declare namespace ts { * For the canonical implementation of this type, @see {visitNodes}. */ interface NodesVisitor { - | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); - | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); + | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + | undefined>(nodes: TInArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); } type VisitResult = T | readonly Node[]; interface Printer { @@ -9320,7 +9320,7 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); + function visitNode(node: TIn, visitor: Visitor, TVisited>, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -9335,7 +9335,7 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); + function visitNode(node: TIn, visitor: Visitor, TVisited>, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -9351,7 +9351,7 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitNodes | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -9367,7 +9367,7 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitNodes | undefined>(nodes: TInArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index b785b596b57f1..8a7ddc2d73739 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4264,8 +4264,8 @@ declare namespace ts { * For the canonical implementation of this type, @see {visitNode}. */ interface NodeVisitor { - (node: TIn, visitor: Visitor, TVisited> | undefined, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); - (node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); + (node: TIn, visitor: Visitor, TVisited>, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); + (node: TIn, visitor: Visitor, TVisited>, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); } /** * A function that walks a node array using the given visitor, returning an array whose contents satisfy the test. @@ -4279,8 +4279,8 @@ declare namespace ts { * For the canonical implementation of this type, @see {visitNodes}. */ interface NodesVisitor { - | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); - | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); + | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + | undefined>(nodes: TInArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); } type VisitResult = T | readonly Node[]; interface Printer { @@ -5379,7 +5379,7 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); + function visitNode(node: TIn, visitor: Visitor, TVisited>, test: (node: Node) => node is TOut, lift?: (node: readonly Node[]) => Node): TOut | (TIn & undefined) | (TVisited & undefined); /** * Visits a Node using the supplied visitor, possibly returning a new Node in its place. * @@ -5394,7 +5394,7 @@ declare namespace ts { * @param test A callback to execute to verify the Node is valid. * @param lift An optional callback to execute to lift a NodeArray into a valid Node. */ - function visitNode(node: TIn, visitor: Visitor, TVisited> | undefined, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); + function visitNode(node: TIn, visitor: Visitor, TVisited>, test?: (node: Node) => boolean, lift?: (node: readonly Node[]) => Node): Node | (TIn & undefined) | (TVisited & undefined); /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -5410,7 +5410,7 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor | undefined, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitNodes | undefined, TOut extends Node>(nodes: TInArray, visitor: Visitor, test: (node: Node) => node is TOut, start?: number, count?: number): NodeArray | (TInArray & undefined); /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * @@ -5426,7 +5426,7 @@ declare namespace ts { * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ - function visitNodes | undefined>(nodes: TInArray, visitor: Visitor | undefined, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); + function visitNodes | undefined>(nodes: TInArray, visitor: Visitor, test?: (node: Node) => boolean, start?: number, count?: number): NodeArray | (TInArray & undefined); /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. From 4ff34cb1de17017621b113f5554b9832df14824b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 12 Jan 2023 20:43:00 -0800 Subject: [PATCH 81/81] meh, just remove the check, it's easy to re-add if someone crashes --- src/compiler/visitorPublic.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 468b8278d1d25..67e9dc5965954 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -153,8 +153,7 @@ export function visitNode( return node; } - // TODO(jakebailey): remove this check? - const visited = visitor ? visitor(node) : node; + const visited = visitor(node); let visitedNode: Node | undefined; if (visited === undefined) {