diff --git a/eslint.config.mjs b/eslint.config.mjs index 9fd6276e584fc..bc30b791311be 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -118,6 +118,7 @@ export default tseslint.config( "@typescript-eslint/ban-ts-comment": "off", "@typescript-eslint/class-literal-property-style": "off", "@typescript-eslint/consistent-indexed-object-style": "off", + "@typescript-eslint/consistent-generic-constructors": "off", "@typescript-eslint/no-duplicate-enum-values": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-namespace": "off", diff --git a/scripts/processDiagnosticMessages.mjs b/scripts/processDiagnosticMessages.mjs index 85f029e1d3765..33d373936a4b7 100644 --- a/scripts/processDiagnosticMessages.mjs +++ b/scripts/processDiagnosticMessages.mjs @@ -92,6 +92,7 @@ function buildInfoFileOutput(messageTable, inputFilePathRel) { " return { code, category, key, message, reportsUnnecessary, elidedInCompatabilityPyramid, reportsDeprecated };", "}", "", + "/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion*/", // type assertions are needed for isolatedDeclarations "/** @internal */", "export const Diagnostics = {", ]; @@ -101,7 +102,7 @@ function buildInfoFileOutput(messageTable, inputFilePathRel) { const argElidedInCompatabilityPyramid = elidedInCompatabilityPyramid ? `${!reportsUnnecessary ? ", /*reportsUnnecessary*/ undefined" : ""}, /*elidedInCompatabilityPyramid*/ ${elidedInCompatabilityPyramid}` : ""; const argReportsDeprecated = reportsDeprecated ? `${!argElidedInCompatabilityPyramid ? ", /*reportsUnnecessary*/ undefined, /*elidedInCompatabilityPyramid*/ undefined" : ""}, /*reportsDeprecated*/ ${reportsDeprecated}` : ""; - result.push(` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}${argReportsUnnecessary}${argElidedInCompatabilityPyramid}${argReportsDeprecated}),`); + result.push(` ${propName}: diag(${code}, DiagnosticCategory.${category}, "${createKey(propName, code)}", ${JSON.stringify(name)}${argReportsUnnecessary}${argElidedInCompatabilityPyramid}${argReportsDeprecated}) as DiagnosticMessage,`); }); result.push("};"); diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 1666c90883e80..7f61986a80fb8 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -509,7 +509,7 @@ export function createFlowNode(flags: FlowFlags, node: unknown, antecedent: Flow const binder = /* @__PURE__ */ createBinder(); /** @internal */ -export function bindSourceFile(file: SourceFile, options: CompilerOptions) { +export function bindSourceFile(file: SourceFile, options: CompilerOptions): void { performance.mark("beforeBind"); binder(file, options); performance.mark("afterBind"); diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index 6b0d7a24b3f2f..1c472cebead0d 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -8,6 +8,7 @@ import { BuilderProgramHost, BuilderState, BuildInfo, + BuildInfoFileVersionMap, CancellationToken, CommandLineOption, compareStringsCaseSensitive, @@ -277,7 +278,7 @@ function toBuilderProgramStateWithDefinedProgram(state: ReusableBuilderProgramSt * * @internal */ -export function getBuilderFileEmit(options: CompilerOptions) { +export function getBuilderFileEmit(options: CompilerOptions): BuilderFileEmit { let result = BuilderFileEmit.Js; if (options.sourceMap) result = result | BuilderFileEmit.JsMap; if (options.inlineSourceMap) result = result | BuilderFileEmit.JsInlineMap; @@ -733,7 +734,7 @@ export function getPendingEmitKindWithSeen( seenOldOptionsOrEmitKind: CompilerOptions | BuilderFileEmit | undefined, emitOnlyDtsFiles: boolean | undefined, isForDtsErrors: boolean, -) { +): BuilderFileEmit { let pendingKind = getPendingEmitKind(optionsOrEmitKind, seenOldOptionsOrEmitKind); if (emitOnlyDtsFiles) pendingKind = pendingKind & BuilderFileEmit.AllDts; if (isForDtsErrors) pendingKind = pendingKind & BuilderFileEmit.DtsErrors; @@ -1623,7 +1624,7 @@ export function computeSignatureWithDiagnostics( text: string, host: HostForComputeHash, data: WriteFileCallbackData | undefined, -) { +): string { text = getTextHandlingSourceMapForSignature(text, data); let sourceFileDirectory: string | undefined; if (data?.diagnostics?.length) { @@ -2395,7 +2396,7 @@ export function getBuildInfoFileVersionMap( program: IncrementalBuildInfo, buildInfoPath: string, host: Pick, -) { +): BuildInfoFileVersionMap { const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory())); const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames()); const fileInfos = new Map(); @@ -2440,7 +2441,7 @@ export function getNonIncrementalBuildInfoRoots( buildInfo: BuildInfo, buildInfoPath: string, host: Pick, -) { +): Path[] | undefined { if (!isNonIncrementalBuildInfo(buildInfo)) return undefined; const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(buildInfoPath, host.getCurrentDirectory())); const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames()); diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts index 0e571d233d7e8..cf9932e94631b 100644 --- a/src/compiler/builderState.ts +++ b/src/compiler/builderState.ts @@ -292,11 +292,11 @@ export namespace BuilderState { /** * Returns true if oldState is reusable, that is the emitKind = module/non module has not changed */ - export function canReuseOldState(newReferencedMap: ReadonlyManyToManyPathMap | undefined, oldState: BuilderState | undefined) { + export function canReuseOldState(newReferencedMap: ReadonlyManyToManyPathMap | undefined, oldState: BuilderState | undefined): boolean | undefined { return oldState && !oldState.referencedMap === !newReferencedMap; } - export function createReferencedMap(options: CompilerOptions) { + export function createReferencedMap(options: CompilerOptions): ManyToManyPathMap | undefined { return options.module !== ModuleKind.None && !options.outFile ? createManyToManyPathMap() : undefined; @@ -346,7 +346,7 @@ export namespace BuilderState { /** * Releases needed properties */ - export function releaseCache(state: BuilderState) { + export function releaseCache(state: BuilderState): void { state.allFilesExcludingDefaultLibraryFile = undefined; state.allFileNames = undefined; } @@ -391,7 +391,7 @@ export namespace BuilderState { return (state.referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit)(state, programOfThisState, sourceFile, cancellationToken, host); } - export function updateSignatureOfFile(state: BuilderState, signature: string | undefined, path: Path) { + export function updateSignatureOfFile(state: BuilderState, signature: string | undefined, path: Path): void { state.fileInfos.get(path)!.signature = signature; (state.hasCalledUpdateShapeSignature ||= new Set()).add(path); } @@ -402,7 +402,7 @@ export namespace BuilderState { cancellationToken: CancellationToken | undefined, host: HostForComputeHash, onNewSignature: (signature: string, sourceFiles: readonly SourceFile[]) => void, - ) { + ): void { programOfThisState.emit( sourceFile, (fileName, text, _writeByteOrderMark, _onError, sourceFiles, data) => { @@ -434,8 +434,8 @@ export namespace BuilderState { sourceFile: SourceFile, cancellationToken: CancellationToken | undefined, host: HostForComputeHash, - useFileVersionAsSignature = state.useFileVersionAsSignature, - ) { + useFileVersionAsSignature: boolean | undefined = state.useFileVersionAsSignature, + ): boolean { // If we have cached the result for this file, that means hence forth we should assume file shape is uptodate if (state.hasCalledUpdateShapeSignature?.has(sourceFile.resolvedPath)) return false; @@ -507,7 +507,7 @@ export namespace BuilderState { /** * Gets the files referenced by the the file path */ - export function getReferencedByPaths(state: Readonly, referencedFilePath: Path) { + export function getReferencedByPaths(state: Readonly, referencedFilePath: Path): Path[] { const keys = state.referencedMap!.getKeys(referencedFilePath); return keys ? arrayFrom(keys.keys()) : []; } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4d4f1bf69a808..06b519ff4b898 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1450,7 +1450,7 @@ export function getSymbolId(symbol: Symbol): SymbolId { } /** @internal */ -export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean) { +export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums: boolean): boolean { const moduleState = getModuleInstanceState(node); return moduleState === ModuleInstanceState.Instantiated || (preserveConstEnums && moduleState === ModuleInstanceState.ConstEnumOnly); @@ -52709,7 +52709,7 @@ function getIterationTypesKeyFromIterationTypeKind(typeKind: IterationTypeKind) } /** @internal */ -export function signatureHasRestParameter(s: Signature) { +export function signatureHasRestParameter(s: Signature): boolean { return !!(s.flags & SignatureFlags.HasRestParameter); } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 902c235c25f01..830fb26370426 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -138,7 +138,7 @@ const jsxOptionMap = new Map(Object.entries({ })); /** @internal */ -export const inverseJsxOptionMap = new Map(mapIterator(jsxOptionMap.entries(), ([key, value]: [string, JsxEmit]) => ["" + value, key] as const)); +export const inverseJsxOptionMap: Map = new Map(mapIterator(jsxOptionMap.entries(), ([key, value]: [string, JsxEmit]) => ["" + value, key] as const)); // NOTE: The order here is important to default lib ordering as entries will have the same // order in the generated program (see `getDefaultLibPriority` in program.ts). This @@ -248,7 +248,7 @@ const libEntries: [string, string][] = [ * * @internal */ -export const libs = libEntries.map(entry => entry[0]); +export const libs: string[] = libEntries.map(entry => entry[0]); /** * A map of lib names to lib files. This map is used both for parsing the "lib" command line @@ -256,7 +256,7 @@ export const libs = libEntries.map(entry => entry[0]); * * @internal */ -export const libMap = new Map(libEntries); +export const libMap: Map = new Map(libEntries); // Watch related options @@ -1800,7 +1800,7 @@ function createDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType } /** @internal */ -export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string | undefined, errors: Diagnostic[]) { +export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string | undefined, errors: Diagnostic[]): string | number | undefined { return convertJsonOptionOfCustomType(opt, (value ?? "").trim(), errors); } @@ -1835,6 +1835,14 @@ export interface OptionsBase { [option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined; } +/** @internal */ +export interface BaseParsedCommandLine { + options: OptionsBase; + watchOptions: WatchOptions | undefined; + fileNames: string[]; + errors: Diagnostic[]; +} + /** @internal */ export interface ParseCommandLineWorkerDiagnostics extends DidYouMeanOptionsDiagnostics { getOptionsNameMap: () => OptionsNameMap; @@ -1875,7 +1883,7 @@ export function parseCommandLineWorker( diagnostics: ParseCommandLineWorkerDiagnostics, commandLine: readonly string[], readFile?: (path: string) => string | undefined, -) { +): BaseParsedCommandLine { const options = {} as OptionsBase; let watchOptions: WatchOptions | undefined; const fileNames: string[] = []; @@ -2602,11 +2610,11 @@ export function convertToTSConfig(configParseResult: ParsedCommandLine, configFi const providedKeys = new Set(optionMap.keys()); const impliedCompilerOptions: Record = {}; for (const option in computedOptions) { - if (!providedKeys.has(option) && some(computedOptions[option as keyof typeof computedOptions].dependencies, dep => providedKeys.has(dep))) { - const implied = computedOptions[option as keyof typeof computedOptions].computeValue(configParseResult.options); - const defaultValue = computedOptions[option as keyof typeof computedOptions].computeValue({}); + if (!providedKeys.has(option) && some(computedOptions[option].dependencies, dep => providedKeys.has(dep))) { + const implied = computedOptions[option].computeValue(configParseResult.options); + const defaultValue = computedOptions[option].computeValue({}); if (implied !== defaultValue) { - impliedCompilerOptions[option] = computedOptions[option as keyof typeof computedOptions].computeValue(configParseResult.options); + impliedCompilerOptions[option] = computedOptions[option].computeValue(configParseResult.options); } } } @@ -2866,7 +2874,7 @@ export function generateTSConfig(options: CompilerOptions, fileNames: readonly s } /** @internal */ -export function convertToOptionsWithAbsolutePaths(options: CompilerOptions, toAbsolutePath: (path: string) => string) { +export function convertToOptionsWithAbsolutePaths(options: CompilerOptions, toAbsolutePath: (path: string) => string): CompilerOptions { const result: CompilerOptions = {}; const optionsNameMap = getOptionsNameMap().optionsNameMap; @@ -2927,7 +2935,7 @@ export function parseJsonSourceFileConfigFileContent(sourceFile: TsConfigSourceF } /** @internal */ -export function setConfigFileInOptions(options: CompilerOptions, configFile: TsConfigSourceFile | undefined) { +export function setConfigFileInOptions(options: CompilerOptions, configFile: TsConfigSourceFile | undefined): void { if (configFile) { Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile }); } @@ -3243,12 +3251,12 @@ function shouldReportNoInputFiles(fileNames: string[], canJsonReportNoInutFiles: } /** @internal */ -export function canJsonReportNoInputFiles(raw: any) { +export function canJsonReportNoInputFiles(raw: any): boolean { return !hasProperty(raw, "files") && !hasProperty(raw, "references"); } /** @internal */ -export function updateErrorForNoInputFiles(fileNames: string[], configFileName: string, configFileSpecs: ConfigFileSpecs, configParseDiagnostics: Diagnostic[], canJsonReportNoInutFiles: boolean) { +export function updateErrorForNoInputFiles(fileNames: string[], configFileName: string, configFileSpecs: ConfigFileSpecs, configParseDiagnostics: Diagnostic[], canJsonReportNoInutFiles: boolean): boolean { const existingErrors = configParseDiagnostics.length; if (shouldReportNoInputFiles(fileNames, canJsonReportNoInutFiles)) { configParseDiagnostics.push(getErrorForNoInputFiles(configFileSpecs, configFileName)); @@ -3943,7 +3951,7 @@ export function matchesExclude( excludeSpecs: readonly string[] | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, -) { +): boolean { return matchesExcludeWorker( pathToCheck, filter(excludeSpecs, spec => !invalidDotDotAfterRecursiveWildcard(spec)), diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 40b58adfdeba6..ef83fefd533e0 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -329,7 +329,7 @@ export function map(array: readonly T[] | undefined, f: (x: T, i: number) } /** @internal */ -export function* mapIterator(iter: Iterable, mapFn: (x: T) => U) { +export function* mapIterator(iter: Iterable, mapFn: (x: T) => U): Generator { for (const x of iter) { yield mapFn(x); } @@ -434,7 +434,7 @@ export function flatMapToMutable(array: readonly T[] | undefined, mapfn: ( } /** @internal */ -export function* flatMapIterator(iter: Iterable, mapfn: (x: T) => readonly U[] | Iterable | undefined) { +export function* flatMapIterator(iter: Iterable, mapfn: (x: T) => readonly U[] | Iterable | undefined): Generator { for (const x of iter) { const iter2 = mapfn(x); if (!iter2) continue; @@ -505,7 +505,8 @@ export function mapDefined(array: readonly T[] | undefined, mapFn: (x: T, } /** @internal */ -export function* mapDefinedIterator(iter: Iterable, mapFn: (x: T) => U | undefined) { +// eslint-disable-next-line no-restricted-syntax +export function* mapDefinedIterator(iter: Iterable, mapFn: (x: T) => U | undefined): Generator { for (const x of iter) { const value = mapFn(x); if (value !== undefined) { @@ -515,7 +516,7 @@ export function* mapDefinedIterator(iter: Iterable, mapFn: (x: T) => U } /** @internal */ -export function getOrUpdate(map: Map, key: K, callback: () => V) { +export function getOrUpdate(map: Map, key: K, callback: () => V): V { if (map.has(key)) { return map.get(key)!; } @@ -525,7 +526,7 @@ export function getOrUpdate(map: Map, key: K, callback: () => V) { } /** @internal */ -export function tryAddToSet(set: Set, value: T) { +export function tryAddToSet(set: Set, value: T): boolean { if (!set.has(value)) { set.add(value); return true; @@ -534,7 +535,7 @@ export function tryAddToSet(set: Set, value: T) { } /** @internal */ -export function* singleIterator(value: T) { +export function* singleIterator(value: T): Generator { yield value; } @@ -1039,14 +1040,14 @@ export function toSorted(array: readonly T[], comparer?: Comparer): Sorted } /** @internal */ -export function* arrayReverseIterator(array: readonly T[]) { +export function* arrayReverseIterator(array: readonly T[]): Generator { for (let i = array.length - 1; i >= 0; i--) { yield array[i]; } } /** @internal */ -export function rangeEquals(array1: readonly T[], array2: readonly T[], pos: number, end: number) { +export function rangeEquals(array1: readonly T[], array2: readonly T[], pos: number, end: number): boolean { while (pos < end) { if (array1[pos] !== array2[pos]) { return false; @@ -1346,7 +1347,7 @@ export function arrayFrom(iterator: Iterable, map?: (t: T) => U): (T | } /** @internal */ -export function assign(t: T, ...args: (T | undefined)[]) { +export function assign(t: T, ...args: (T | undefined)[]): T { for (const arg of args) { if (arg === undefined) continue; for (const p in arg) { @@ -1366,7 +1367,7 @@ export function assign(t: T, ...args: (T | undefined)[]) { * * @internal */ -export function equalOwnProperties(left: MapLike | undefined, right: MapLike | undefined, equalityComparer: EqualityComparer = equateValues) { +export function equalOwnProperties(left: MapLike | undefined, right: MapLike | undefined, equalityComparer: EqualityComparer = equateValues): boolean { if (left === right) return true; if (!left || !right) return false; for (const key in left) { @@ -1509,7 +1510,7 @@ export function extend(first: T1, second: T2): T1 & T2 { } /** @internal */ -export function copyProperties(first: T1, second: T2) { +export function copyProperties(first: T1, second: T2): void { for (const id in second) { if (hasOwnProperty.call(second, id)) { (first as any)[id] = second[id]; @@ -1824,7 +1825,7 @@ export function returnUndefined(): undefined { * * @internal */ -export function identity(x: T) { +export function identity(x: T): T { return x; } @@ -1871,7 +1872,7 @@ const fileNameLowerCaseRegExp = /[^\u0130\u0131\u00DFa-z0-9\\/:\-_. ]+/g; * * @internal */ -export function toFileNameLowerCase(x: string) { +export function toFileNameLowerCase(x: string): string { return fileNameLowerCaseRegExp.test(x) ? x.replace(fileNameLowerCaseRegExp, toLowerCase) : x; @@ -1933,7 +1934,7 @@ export const enum AssertionLevel { export type AnyFunction = (...args: never[]) => void; /** @internal */ -export function equateValues(a: T, b: T) { +export function equateValues(a: T, b: T): boolean { return a === b; } @@ -1947,7 +1948,7 @@ export function equateValues(a: T, b: T) { * * @internal */ -export function equateStringsCaseInsensitive(a: string, b: string) { +export function equateStringsCaseInsensitive(a: string, b: string): boolean { return a === b || a !== undefined && b !== undefined @@ -1962,7 +1963,7 @@ export function equateStringsCaseInsensitive(a: string, b: string) { * * @internal */ -export function equateStringsCaseSensitive(a: string, b: string) { +export function equateStringsCaseSensitive(a: string, b: string): boolean { return equateValues(a, b); } @@ -2026,7 +2027,7 @@ export function min(items: readonly T[], compare: Comparer): T | undefined * * @internal */ -export function compareStringsCaseInsensitive(a: string, b: string) { +export function compareStringsCaseInsensitive(a: string, b: string): Comparison { if (a === b) return Comparison.EqualTo; if (a === undefined) return Comparison.LessThan; if (b === undefined) return Comparison.GreaterThan; @@ -2047,7 +2048,7 @@ export function compareStringsCaseInsensitive(a: string, b: string) { * * @internal */ -export function compareStringsCaseInsensitiveEslintCompatible(a: string, b: string) { +export function compareStringsCaseInsensitiveEslintCompatible(a: string, b: string): Comparison { if (a === b) return Comparison.EqualTo; if (a === undefined) return Comparison.LessThan; if (b === undefined) return Comparison.GreaterThan; @@ -2073,7 +2074,7 @@ export function compareStringsCaseSensitive(a: string | undefined, b: string | u } /** @internal */ -export function getStringComparer(ignoreCase?: boolean) { +export function getStringComparer(ignoreCase?: boolean): typeof compareStringsCaseInsensitive { return ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; } @@ -2103,12 +2104,12 @@ let uiComparerCaseSensitive: Comparer | undefined; let uiLocale: string | undefined; /** @internal */ -export function getUILocale() { +export function getUILocale(): string | undefined { return uiLocale; } /** @internal */ -export function setUILocale(value: string | undefined) { +export function setUILocale(value: string | undefined): void { if (uiLocale !== value) { uiLocale = value; uiComparerCaseSensitive = undefined; @@ -2127,7 +2128,7 @@ export function setUILocale(value: string | undefined) { * * @internal */ -export function compareStringsCaseSensitiveUI(a: string, b: string) { +export function compareStringsCaseSensitiveUI(a: string, b: string): Comparison { uiComparerCaseSensitive ??= createUIStringComparer(uiLocale); return uiComparerCaseSensitive(a, b); } @@ -2265,7 +2266,7 @@ export function tryRemoveSuffix(str: string, suffix: string): string | undefined * * @internal */ -export function removeMinAndVersionNumbers(fileName: string) { +export function removeMinAndVersionNumbers(fileName: string): string { // We used to use the regex /[.-]((min)|(\d+(\.\d+)*))$/ and would just .replace it twice. // Unfortunately, that regex has O(n^2) performance because v8 doesn't match from the end of the string. // Instead, we now essentially scan the filename (backwards) ourselves. @@ -2353,7 +2354,7 @@ function unorderedRemoveItemAt(array: T[], index: number): void { * * @internal */ -export function unorderedRemoveItem(array: T[], item: T) { +export function unorderedRemoveItem(array: T[], item: T): boolean { return unorderedRemoveFirstItemWhere(array, element => element === item); } @@ -2441,7 +2442,7 @@ export function tryRemovePrefix(str: string, prefix: string, getCanonicalFileNam } /** @internal */ -export function isPatternMatch({ prefix, suffix }: Pattern, candidate: string) { +export function isPatternMatch({ prefix, suffix }: Pattern, candidate: string): boolean { return candidate.length >= prefix.length + suffix.length && startsWith(candidate, prefix) && endsWith(candidate, suffix); @@ -2449,7 +2450,7 @@ export function isPatternMatch({ prefix, suffix }: Pattern, candidate: string) { /** @internal */ export function and(f: (arg: T) => boolean, g: (arg: T) => boolean) { - return (arg: T) => f(arg) && g(arg); + return (arg: T): boolean => f(arg) && g(arg); } /** @internal */ @@ -2486,7 +2487,7 @@ export function singleElementArray(t: T | undefined): T[] | undefined { } /** @internal */ -export function enumerateInsertsAndDeletes(newItems: readonly T[], oldItems: readonly U[], comparer: (a: T, b: U) => Comparison, inserted: (newItem: T) => void, deleted: (oldItem: U) => void, unchanged?: (oldItem: U, newItem: T) => void) { +export function enumerateInsertsAndDeletes(newItems: readonly T[], oldItems: readonly U[], comparer: (a: T, b: U) => Comparison, inserted: (newItem: T) => void, deleted: (oldItem: U) => void, unchanged?: (oldItem: U, newItem: T) => void): boolean { unchanged ??= noop; let newIndex = 0; let oldIndex = 0; @@ -2525,7 +2526,7 @@ export function enumerateInsertsAndDeletes(newItems: readonly T[], oldItem } /** @internal */ -export function cartesianProduct(arrays: readonly T[][]) { +export function cartesianProduct(arrays: readonly T[][]): T[][] { const result: T[][] = []; cartesianProductWorker(arrays, result, /*outer*/ undefined, 0); return result; diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index 7468b2aeceaaa..42e8637ac178a 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -113,7 +113,7 @@ export interface LoggingHost { export namespace Debug { /* eslint-disable prefer-const */ let currentAssertionLevel = AssertionLevel.None; - export let currentLogLevel = LogLevel.Warning; + export let currentLogLevel: LogLevel = LogLevel.Warning; export let isDebugging = false; export let loggingHost: LoggingHost | undefined; /* eslint-enable prefer-const */ @@ -154,11 +154,11 @@ export namespace Debug { const assertionCache: Partial> = {}; - export function getAssertionLevel() { + export function getAssertionLevel(): AssertionLevel { return currentAssertionLevel; } - export function setAssertionLevel(level: AssertionLevel) { + export function setAssertionLevel(level: AssertionLevel): void { const prevAssertionLevel = currentAssertionLevel; currentAssertionLevel = level; @@ -365,7 +365,7 @@ export namespace Debug { export function type(value: unknown): asserts value is T; export function type(_value: unknown) {} - export function getFunctionName(func: AnyFunction) { + export function getFunctionName(func: AnyFunction): string { if (typeof func !== "function") { return ""; } @@ -386,7 +386,7 @@ export namespace Debug { /** * Formats an enum value as a string for debugging and debug assertions. */ - export function formatEnum(value = 0, enumObject: any, isFlags?: boolean) { + export function formatEnum(value = 0, enumObject: any, isFlags?: boolean): string { const members = getEnumMembers(enumObject); if (value === 0) { return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0"; @@ -549,7 +549,7 @@ export namespace Debug { } } - export function attachFlowNodeDebugInfo(flowNode: FlowNode) { + export function attachFlowNodeDebugInfo(flowNode: FlowNode): FlowNode { if (isDebugInfoEnabled) { if (typeof Object.setPrototypeOf === "function") { // if we're in es2015, attach the method to a shared prototype for `FlowNode` @@ -589,7 +589,7 @@ export namespace Debug { } } - export function attachNodeArrayDebugInfo(array: NodeArray) { + export function attachNodeArrayDebugInfo(array: NodeArray): void { if (isDebugInfoEnabled) { if (typeof Object.setPrototypeOf === "function") { // if we're in es2015, attach the method to a shared prototype for `NodeArray` @@ -610,7 +610,7 @@ export namespace Debug { /** * Injects debug information into frequently used types. */ - export function enableDebugInfo() { + export function enableDebugInfo(): void { if (isDebugInfoEnabled) return; // avoid recomputing @@ -806,7 +806,7 @@ export namespace Debug { isDebugInfoEnabled = true; } - export function formatVariance(varianceFlags: VarianceFlags) { + export function formatVariance(varianceFlags: VarianceFlags): string { const variance = varianceFlags & VarianceFlags.VarianceMask; let result = variance === VarianceFlags.Invariant ? "in out" : variance === VarianceFlags.Bivariant ? "[bivariant]" : @@ -861,11 +861,11 @@ m2: ${(this.mapper2 as unknown as DebugTypeMapper).__debugToString().split("\n") return mapper; } - export function printControlFlowGraph(flowNode: FlowNode) { + export function printControlFlowGraph(flowNode: FlowNode): void { return console.log(formatControlFlowGraph(flowNode)); } - export function formatControlFlowGraph(flowNode: FlowNode) { + export function formatControlFlowGraph(flowNode: FlowNode): string { let nextDebugFlowId = -1; function getDebugFlowNodeId(f: FlowNode) { diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 98f42996cc86c..e63bfd783ced2 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -428,7 +428,7 @@ import * as performance from "./_namespaces/ts.performance.js"; const brackets = createBracketsMap(); /** @internal */ -export function isBuildInfoFile(file: string) { +export function isBuildInfoFile(file: string): boolean { return fileExtensionIs(file, Extension.TsBuildInfo); } @@ -450,7 +450,7 @@ export function forEachEmittedFile( forceDtsEmit = false, onlyBuildInfo?: boolean, includeBuildInfo?: boolean, -) { +): T | undefined { const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile, forceDtsEmit); const options = host.getCompilerOptions(); if (!onlyBuildInfo) { @@ -478,7 +478,7 @@ export function forEachEmittedFile( } } -export function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions) { +export function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions): string | undefined { const configFile = options.configFilePath; if (!canEmitTsBuildInfo(options)) return undefined; if (options.tsBuildInfoFile) return options.tsBuildInfoFile; @@ -500,7 +500,7 @@ export function getTsBuildInfoEmitOutputFilePath(options: CompilerOptions) { } /** @internal */ -export function canEmitTsBuildInfo(options: CompilerOptions) { +export function canEmitTsBuildInfo(options: CompilerOptions): boolean { return isIncrementalCompilation(options) || !!options.tscBuild; } @@ -561,12 +561,17 @@ function getOutputPathWithoutChangingExt( } /** @internal */ -export function getOutputDeclarationFileName(inputFileName: string, configFile: ParsedCommandLine, ignoreCase: boolean, getCommonSourceDirectory = () => getCommonSourceDirectoryOfConfig(configFile, ignoreCase)) { +export function getOutputDeclarationFileName( + inputFileName: string, + configFile: ParsedCommandLine, + ignoreCase: boolean, + getCommonSourceDirectory = (): string => getCommonSourceDirectoryOfConfig(configFile, ignoreCase), +): string { return getOutputDeclarationFileNameWorker(inputFileName, configFile.options, ignoreCase, getCommonSourceDirectory); } /** @internal */ -export function getOutputDeclarationFileNameWorker(inputFileName: string, options: CompilerOptions, ignoreCase: boolean, getCommonSourceDirectory: () => string) { +export function getOutputDeclarationFileNameWorker(inputFileName: string, options: CompilerOptions, ignoreCase: boolean, getCommonSourceDirectory: () => string): string { return changeExtension( getOutputPathWithoutChangingExt(inputFileName, ignoreCase, options.declarationDir || options.outDir, getCommonSourceDirectory), getDeclarationEmitExtensionForPath(inputFileName), @@ -722,7 +727,7 @@ export function getFirstProjectOutput(configFile: ParsedCommandLine, ignoreCase: } /** @internal */ -export function emitResolverSkipsTypeChecking(emitOnly: boolean | EmitOnly | undefined, forceDtsEmit: boolean | undefined) { +export function emitResolverSkipsTypeChecking(emitOnly: boolean | EmitOnly | undefined, forceDtsEmit: boolean | undefined): boolean { return !!forceDtsEmit && !!emitOnly; } @@ -1113,7 +1118,7 @@ export function emitFiles( } /** @internal */ -export function getBuildInfoText(buildInfo: BuildInfo) { +export function getBuildInfoText(buildInfo: BuildInfo): string { return JSON.stringify(buildInfo); } @@ -1174,16 +1179,16 @@ const enum PipelinePhase { } /** @internal */ -export const createPrinterWithDefaults = /* @__PURE__ */ memoize(() => createPrinter({})); +export const createPrinterWithDefaults: () => Printer = /* @__PURE__ */ memoize(() => createPrinter({})); /** @internal */ -export const createPrinterWithRemoveComments = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true })); +export const createPrinterWithRemoveComments: () => Printer = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true })); /** @internal */ -export const createPrinterWithRemoveCommentsNeverAsciiEscape = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true, neverAsciiEscape: true })); +export const createPrinterWithRemoveCommentsNeverAsciiEscape: () => Printer = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true, neverAsciiEscape: true })); /** @internal */ -export const createPrinterWithRemoveCommentsOmitTrailingSemicolon = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true, omitTrailingSemicolon: true })); +export const createPrinterWithRemoveCommentsOmitTrailingSemicolon: () => Printer = /* @__PURE__ */ memoize(() => createPrinter({ removeComments: true, omitTrailingSemicolon: true })); export function createPrinter(printerOptions: PrinterOptions = {}, handlers: PrintHandlers = {}): Printer { // Why var? It avoids TDZ checks in the runtime which can be costly. diff --git a/src/compiler/executeCommandLine.ts b/src/compiler/executeCommandLine.ts index c65564ababfcb..ca166635ac5c1 100644 --- a/src/compiler/executeCommandLine.ts +++ b/src/compiler/executeCommandLine.ts @@ -729,7 +729,7 @@ function executeCommandLineWorker( } /** Returns true if commandline is --build and needs to be parsed useing parseBuildCommand */ -export function isBuildCommand(commandLineArgs: readonly string[]) { +export function isBuildCommand(commandLineArgs: readonly string[]): boolean { if (commandLineArgs.length > 0 && commandLineArgs[0].charCodeAt(0) === CharacterCodes.minus) { const firstOption = commandLineArgs[0].slice(commandLineArgs[0].charCodeAt(1) === CharacterCodes.minus ? 2 : 1).toLowerCase(); return firstOption === tscBuildOption.name || firstOption === tscBuildOption.shortName; diff --git a/src/compiler/expressionToTypeNode.ts b/src/compiler/expressionToTypeNode.ts index 047611a5d45f7..1c6e045f0f0bd 100644 --- a/src/compiler/expressionToTypeNode.ts +++ b/src/compiler/expressionToTypeNode.ts @@ -55,6 +55,7 @@ import { PropertySignature, SetAccessorDeclaration, SignatureDeclaration, + SyntacticNodeBuilder, SyntacticTypeNodeBuilderContext, SyntacticTypeNodeBuilderResolver, SyntaxKind, @@ -66,7 +67,10 @@ import { } from "./_namespaces/ts.js"; /** @internal */ -export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolver: SyntacticTypeNodeBuilderResolver) { +export function createSyntacticTypeNodeBuilder( + options: CompilerOptions, + resolver: SyntacticTypeNodeBuilderResolver, +): SyntacticNodeBuilder { const strictNullChecks = getStrictOptionValue(options, "strictNullChecks"); return { diff --git a/src/compiler/factory/emitHelpers.ts b/src/compiler/factory/emitHelpers.ts index 8cc453299e3f8..722e408e0743b 100644 --- a/src/compiler/factory/emitHelpers.ts +++ b/src/compiler/factory/emitHelpers.ts @@ -685,7 +685,7 @@ export function createEmitHelperFactory(context: TransformationContext): EmitHel } /** @internal */ -export function compareEmitHelpers(x: EmitHelper, y: EmitHelper) { +export function compareEmitHelpers(x: EmitHelper, y: EmitHelper): Comparison { if (x === y) return Comparison.EqualTo; if (x.priority === y.priority) return Comparison.EqualTo; if (x.priority === undefined) return Comparison.GreaterThan; diff --git a/src/compiler/factory/emitNode.ts b/src/compiler/factory/emitNode.ts index 5b90c578148d1..beadc29d4ca6b 100644 --- a/src/compiler/factory/emitNode.ts +++ b/src/compiler/factory/emitNode.ts @@ -59,7 +59,7 @@ export function getOrCreateEmitNode(node: Node): EmitNode { * Clears any `EmitNode` entries from parse-tree nodes. * @param sourceFile A source file. */ -export function disposeEmitNodes(sourceFile: SourceFile | undefined) { +export function disposeEmitNodes(sourceFile: SourceFile | undefined): void { // During transformation we may need to annotate a parse tree node with transient // transformation properties. As parse tree nodes live longer than transformation // nodes, we need to make sure we reclaim any memory allocated for custom ranges @@ -89,7 +89,7 @@ export function removeAllComments(node: T): T { /** * Sets flags that control emit behavior of a node. */ -export function setEmitFlags(node: T, emitFlags: EmitFlags) { +export function setEmitFlags(node: T, emitFlags: EmitFlags): T { getOrCreateEmitNode(node).flags = emitFlags; return node; } @@ -99,7 +99,7 @@ export function setEmitFlags(node: T, emitFlags: EmitFlags) { * * @internal */ -export function addEmitFlags(node: T, emitFlags: EmitFlags) { +export function addEmitFlags(node: T, emitFlags: EmitFlags): T { const emitNode = getOrCreateEmitNode(node); emitNode.flags = emitNode.flags | emitFlags; return node; @@ -110,7 +110,7 @@ export function addEmitFlags(node: T, emitFlags: EmitFlags) { * * @internal */ -export function setInternalEmitFlags(node: T, emitFlags: InternalEmitFlags) { +export function setInternalEmitFlags(node: T, emitFlags: InternalEmitFlags): T { getOrCreateEmitNode(node).internalFlags = emitFlags; return node; } @@ -120,7 +120,7 @@ export function setInternalEmitFlags(node: T, emitFlags: Interna * * @internal */ -export function addInternalEmitFlags(node: T, emitFlags: InternalEmitFlags) { +export function addInternalEmitFlags(node: T, emitFlags: InternalEmitFlags): T { const emitNode = getOrCreateEmitNode(node); emitNode.internalFlags = emitNode.internalFlags | emitFlags; return node; @@ -136,7 +136,7 @@ export function getSourceMapRange(node: Node): SourceMapRange { /** * Sets a custom text range to use when emitting source maps. */ -export function setSourceMapRange(node: T, range: SourceMapRange | undefined) { +export function setSourceMapRange(node: T, range: SourceMapRange | undefined): T { getOrCreateEmitNode(node).sourceMapRange = range; return node; } @@ -151,7 +151,7 @@ export function getTokenSourceMapRange(node: Node, token: SyntaxKind): SourceMap /** * Sets the TextRange to use for source maps for a token of a node. */ -export function setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange | undefined) { +export function setTokenSourceMapRange(node: T, token: SyntaxKind, range: SourceMapRange | undefined): T { const emitNode = getOrCreateEmitNode(node); const tokenSourceMapRanges = emitNode.tokenSourceMapRanges ?? (emitNode.tokenSourceMapRanges = []); tokenSourceMapRanges[token] = range; @@ -163,7 +163,7 @@ export function setTokenSourceMapRange(node: T, token: SyntaxKin * * @internal */ -export function getStartsOnNewLine(node: Node) { +export function getStartsOnNewLine(node: Node): boolean | undefined { return node.emitNode?.startsOnNewLine; } @@ -172,7 +172,7 @@ export function getStartsOnNewLine(node: Node) { * * @internal */ -export function setStartsOnNewLine(node: T, newLine: boolean) { +export function setStartsOnNewLine(node: T, newLine: boolean): T { getOrCreateEmitNode(node).startsOnNewLine = newLine; return node; } @@ -187,7 +187,7 @@ export function getCommentRange(node: Node): TextRange { /** * Sets a custom text range to use when emitting comments. */ -export function setCommentRange(node: T, range: TextRange) { +export function setCommentRange(node: T, range: TextRange): T { getOrCreateEmitNode(node).commentRange = range; return node; } @@ -196,12 +196,12 @@ export function getSyntheticLeadingComments(node: Node): SynthesizedComment[] | return node.emitNode?.leadingComments; } -export function setSyntheticLeadingComments(node: T, comments: SynthesizedComment[] | undefined) { +export function setSyntheticLeadingComments(node: T, comments: SynthesizedComment[] | undefined): T { getOrCreateEmitNode(node).leadingComments = comments; return node; } -export function addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { +export function addSyntheticLeadingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T { return setSyntheticLeadingComments(node, append(getSyntheticLeadingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); } @@ -209,12 +209,12 @@ export function getSyntheticTrailingComments(node: Node): SynthesizedComment[] | return node.emitNode?.trailingComments; } -export function setSyntheticTrailingComments(node: T, comments: SynthesizedComment[] | undefined) { +export function setSyntheticTrailingComments(node: T, comments: SynthesizedComment[] | undefined): T { getOrCreateEmitNode(node).trailingComments = comments; return node; } -export function addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean) { +export function addSyntheticTrailingComment(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T { return setSyntheticTrailingComments(node, append(getSyntheticTrailingComments(node), { kind, pos: -1, end: -1, hasTrailingNewLine, text })); } @@ -286,7 +286,7 @@ export function getEmitHelpers(node: Node): EmitHelper[] | undefined { /** * Moves matching emit helpers from a source node to a target node. */ -export function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean) { +export function moveEmitHelpers(source: Node, target: Node, predicate: (helper: EmitHelper) => boolean): void { const sourceEmitNode = source.emitNode; const sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers; if (!some(sourceEmitHelpers)) return; @@ -348,7 +348,7 @@ export function getTypeNode(node: T): TypeNode | undefined { } /** @internal */ -export function setIdentifierTypeArguments(node: T, typeArguments: NodeArray | undefined) { +export function setIdentifierTypeArguments(node: T, typeArguments: NodeArray | undefined): T { getOrCreateEmitNode(node).identifierTypeArguments = typeArguments; return node; } @@ -359,7 +359,7 @@ export function getIdentifierTypeArguments(node: Identifier): NodeArray(node: T, autoGenerate: AutoGenerateInfo | undefined) { +export function setIdentifierAutoGenerate(node: T, autoGenerate: AutoGenerateInfo | undefined): T { getOrCreateEmitNode(node).autoGenerate = autoGenerate; return node; } @@ -370,7 +370,7 @@ export function getIdentifierAutoGenerate(node: Identifier | PrivateIdentifier): } /** @internal */ -export function setIdentifierGeneratedImportReference(node: T, value: ImportSpecifier | undefined) { +export function setIdentifierGeneratedImportReference(node: T, value: ImportSpecifier | undefined): T { getOrCreateEmitNode(node).generatedImportReference = value; return node; } diff --git a/src/compiler/factory/nodeChildren.ts b/src/compiler/factory/nodeChildren.ts index 3946ee89417bc..da8e074415e00 100644 --- a/src/compiler/factory/nodeChildren.ts +++ b/src/compiler/factory/nodeChildren.ts @@ -41,7 +41,7 @@ export function setNodeChildren(node: Node, sourceFile: SourceFileLike, children } /** @internal */ -export function unsetNodeChildren(node: Node, origSourceFile: SourceFileLike) { +export function unsetNodeChildren(node: Node, origSourceFile: SourceFileLike): void { if (node.kind === SyntaxKind.SyntaxList) { // Syntax lists are synthesized and we store their children directly on them. // They are a special case where we expect incremental parsing to toss them away entirely @@ -52,7 +52,7 @@ export function unsetNodeChildren(node: Node, origSourceFile: SourceFileLike) { } /** @internal */ -export function transferSourceFileChildren(sourceFile: SourceFileLike, targetSourceFile: SourceFileLike) { +export function transferSourceFileChildren(sourceFile: SourceFileLike, targetSourceFile: SourceFileLike): void { const map = sourceFileToNodeChildren.get(sourceFile); if (map !== undefined) { sourceFileToNodeChildren.delete(sourceFile); diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 9c26d5dcfff51..fbc97d9aa4d9c 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -477,7 +477,7 @@ export const enum NodeFactoryFlags { const nodeFactoryPatchers: ((factory: NodeFactory) => void)[] = []; /** @internal @knipignore */ -export function addNodeFactoryPatcher(fn: (factory: NodeFactory) => void) { +export function addNodeFactoryPatcher(fn: (factory: NodeFactory) => void): void { nodeFactoryPatchers.push(fn); } @@ -7396,7 +7396,7 @@ const syntheticFactory: BaseNodeFactory = { createBaseNode: kind => makeSynthetic(baseFactory.createBaseNode(kind)), }; -export const factory = createNodeFactory(NodeFactoryFlags.NoIndentationOnFreshPropertyAccess, syntheticFactory); +export const factory: NodeFactory = createNodeFactory(NodeFactoryFlags.NoIndentationOnFreshPropertyAccess, syntheticFactory); let SourceMapSource: new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; diff --git a/src/compiler/factory/utilities.ts b/src/compiler/factory/utilities.ts index b4bedf4aa2e03..9f7cc54ef7508 100644 --- a/src/compiler/factory/utilities.ts +++ b/src/compiler/factory/utilities.ts @@ -180,7 +180,7 @@ import { // Compound nodes /** @internal */ -export function createEmptyExports(factory: NodeFactory) { +export function createEmptyExports(factory: NodeFactory): ExportDeclaration { return factory.createExportDeclaration(/*modifiers*/ undefined, /*isTypeOnly*/ false, factory.createNamedExports([]), /*moduleSpecifier*/ undefined); } @@ -513,7 +513,13 @@ export function createExpressionForObjectLiteralElementLike(factory: NodeFactory * * @internal */ -export function expandPreOrPostfixIncrementOrDecrementExpression(factory: NodeFactory, node: PrefixUnaryExpression | PostfixUnaryExpression, expression: Expression, recordTempVariable: (node: Identifier) => void, resultVariable: Identifier | undefined) { +export function expandPreOrPostfixIncrementOrDecrementExpression( + factory: NodeFactory, + node: PrefixUnaryExpression | PostfixUnaryExpression, + expression: Expression, + recordTempVariable: (node: Identifier) => void, + resultVariable: Identifier | undefined, +): Expression { const operator = node.operator; Debug.assert(operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken, "Expected 'node' to be a pre- or post-increment or pre- or post-decrement expression"); @@ -547,7 +553,7 @@ export function expandPreOrPostfixIncrementOrDecrementExpression(factory: NodeFa * * @internal */ -export function isInternalName(node: Identifier) { +export function isInternalName(node: Identifier): boolean { return (getEmitFlags(node) & EmitFlags.InternalName) !== 0; } @@ -556,7 +562,7 @@ export function isInternalName(node: Identifier) { * * @internal */ -export function isLocalName(node: Identifier) { +export function isLocalName(node: Identifier): boolean { return (getEmitFlags(node) & EmitFlags.LocalName) !== 0; } @@ -566,7 +572,7 @@ export function isLocalName(node: Identifier) { * * @internal */ -export function isExportName(node: Identifier) { +export function isExportName(node: Identifier): boolean { return (getEmitFlags(node) & EmitFlags.ExportName) !== 0; } @@ -590,7 +596,7 @@ export function findUseStrictPrologue(statements: readonly Statement[]): Stateme } /** @internal */ -export function startsWithUseStrict(statements: readonly Statement[]) { +export function startsWithUseStrict(statements: readonly Statement[]): boolean { const firstStatement = firstOrUndefined(statements); return firstStatement !== undefined && isPrologueDirective(firstStatement) @@ -622,7 +628,7 @@ export function getJSDocTypeAssertionType(node: JSDocTypeAssertion): TypeNode { } /** @internal */ -export function isOuterExpression(node: Node, kinds = OuterExpressionKinds.All): node is OuterExpression { +export function isOuterExpression(node: Node, kinds: OuterExpressionKinds = OuterExpressionKinds.All): node is OuterExpression { switch (node.kind) { case SyntaxKind.ParenthesizedExpression: if (kinds & OuterExpressionKinds.ExcludeJSDocTypeAssertion && isJSDocTypeAssertion(node)) { @@ -658,7 +664,7 @@ export function skipOuterExpressions(node: Node, kinds = OuterExpressionKinds.Al } /** @internal */ -export function walkUpOuterExpressions(node: Expression, kinds = OuterExpressionKinds.All): Node { +export function walkUpOuterExpressions(node: Expression, kinds: OuterExpressionKinds = OuterExpressionKinds.All): Node { let parent = node.parent; while (isOuterExpression(parent, kinds)) { parent = parent.parent; @@ -673,21 +679,21 @@ export function startOnNewLine(node: T): T { } /** @internal */ -export function getExternalHelpersModuleName(node: SourceFile) { +export function getExternalHelpersModuleName(node: SourceFile): Identifier | undefined { const parseNode = getOriginalNode(node, isSourceFile); const emitNode = parseNode && parseNode.emitNode; return emitNode && emitNode.externalHelpersModuleName; } /** @internal */ -export function hasRecordedExternalHelpers(sourceFile: SourceFile) { +export function hasRecordedExternalHelpers(sourceFile: SourceFile): boolean { const parseNode = getOriginalNode(sourceFile, isSourceFile); const emitNode = parseNode && parseNode.emitNode; return !!emitNode && (!!emitNode.externalHelpersModuleName || !!emitNode.externalHelpers); } /** @internal */ -export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: NodeFactory, helperFactory: EmitHelperFactory, sourceFile: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStar?: boolean, hasImportDefault?: boolean) { +export function createExternalHelpersImportDeclarationIfNeeded(nodeFactory: NodeFactory, helperFactory: EmitHelperFactory, sourceFile: SourceFile, compilerOptions: CompilerOptions, hasExportStarsToExportValues?: boolean, hasImportStar?: boolean, hasImportDefault?: boolean): ImportDeclaration | ImportEqualsDeclaration | undefined { if (compilerOptions.importHelpers && isEffectiveExternalModule(sourceFile, compilerOptions)) { const moduleKind = getEmitModuleKind(compilerOptions); const impliedModuleKind = getImpliedNodeFormatForEmitWorker(sourceFile, compilerOptions); @@ -803,7 +809,7 @@ export function getLocalNameForExternalImport(factory: NodeFactory, node: Import * * @internal */ -export function getExternalModuleNameLiteral(factory: NodeFactory, importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration | ImportCall, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions) { +export function getExternalModuleNameLiteral(factory: NodeFactory, importNode: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration | ImportCall, sourceFile: SourceFile, host: EmitHost, resolver: EmitResolver, compilerOptions: CompilerOptions): StringLiteral | undefined { const moduleName = getExternalModuleName(importNode); if (moduleName && isStringLiteral(moduleName)) { return tryGetModuleNameFromDeclaration(importNode, host, factory, resolver, compilerOptions) @@ -1081,7 +1087,7 @@ export function getElementsOfBindingOrAssignmentPattern(name: BindingOrAssignmen } /** @internal */ -export function getJSDocTypeAliasName(fullName: JSDocNamespaceBody | undefined) { +export function getJSDocTypeAliasName(fullName: JSDocNamespaceBody | undefined): Identifier | undefined { if (fullName) { let rightNode = fullName; while (true) { @@ -1507,7 +1513,7 @@ export function elideNodes(factory: NodeFactory, nodes: NodeArra * * @internal */ -export function getNodeForGeneratedName(name: GeneratedIdentifier | GeneratedPrivateIdentifier) { +export function getNodeForGeneratedName(name: GeneratedIdentifier | GeneratedPrivateIdentifier): Node | GeneratedIdentifier | GeneratedPrivateIdentifier { const autoGenerate = name.emitNode.autoGenerate; if (autoGenerate.flags & GeneratedIdentifierFlags.Node) { const autoGenerateId = autoGenerate.id; @@ -1600,7 +1606,7 @@ export function formatGeneratedName(privateName: boolean, prefix: string | Gener * * @internal */ -export function createAccessorPropertyBackingField(factory: NodeFactory, node: PropertyDeclaration, modifiers: ModifiersArray | undefined, initializer: Expression | undefined) { +export function createAccessorPropertyBackingField(factory: NodeFactory, node: PropertyDeclaration, modifiers: ModifiersArray | undefined, initializer: Expression | undefined): PropertyDeclaration { return factory.updatePropertyDeclaration( node, modifiers, @@ -1714,7 +1720,7 @@ function flattenCommaListWorker(node: Expression, expressions: Expression[]) { * * @internal */ -export function flattenCommaList(node: Expression) { +export function flattenCommaList(node: Expression): Expression[] { const expressions: Expression[] = []; flattenCommaListWorker(node, expressions); return expressions; diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index caaf573fd26fe..aedc7beca8c47 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -297,7 +297,7 @@ function initializeResolutionField(value: T[]): T[] | undefined { return value.length ? value : undefined; } /** @internal */ -export function updateResolutionField(to: T[] | undefined, value: T[] | undefined) { +export function updateResolutionField(to: T[] | undefined, value: T[] | undefined): T[] | undefined { if (!value?.length) return to; if (!to?.length) return value; to.push(...value); @@ -454,7 +454,7 @@ function readPackageJsonTypesVersionPaths(jsonContent: PackageJson, state: Modul let typeScriptVersion: Version | undefined; /** @internal */ -export function getPackageJsonTypesVersionsPaths(typesVersions: MapLike>) { +export function getPackageJsonTypesVersionsPaths(typesVersions: MapLike>): VersionPaths | undefined { if (!typeScriptVersion) typeScriptVersion = new Version(version); for (const key in typesVersions) { @@ -748,7 +748,7 @@ function getNodeResolutionFeatures(options: CompilerOptions) { } /** @internal */ -export function getConditions(options: CompilerOptions, resolutionMode?: ResolutionMode) { +export function getConditions(options: CompilerOptions, resolutionMode?: ResolutionMode): string[] { const moduleResolution = getEmitModuleResolutionKind(options); if (resolutionMode === undefined) { if (moduleResolution === ModuleResolutionKind.Bundler) { @@ -952,7 +952,7 @@ function compilerOptionValueToString(value: unknown): string { } /** @internal */ -export function getKeyForCompilerOptions(options: CompilerOptions, affectingOptionDeclarations: readonly CommandLineOption[]) { +export function getKeyForCompilerOptions(options: CompilerOptions, affectingOptionDeclarations: readonly CommandLineOption[]): string { return affectingOptionDeclarations.map(option => compilerOptionValueToString(getCompilerOptionValue(options, option))).join("|") + `|${options.pathsBasePath}`; } @@ -1383,7 +1383,7 @@ export function createTypeReferenceDirectiveResolutionCache( } /** @internal */ -export function getOptionsForLibraryResolution(options: CompilerOptions) { +export function getOptionsForLibraryResolution(options: CompilerOptions): CompilerOptions { return { moduleResolution: ModuleResolutionKind.Node10, traceResolution: options.traceResolution }; } @@ -2556,7 +2556,7 @@ export function parsePackageName(moduleName: string): { packageName: string; res } /** @internal */ -export function allKeysStartWithDot(obj: MapLike) { +export function allKeysStartWithDot(obj: MapLike): boolean { return every(getOwnKeys(obj), k => startsWith(k, ".")); } @@ -2677,18 +2677,18 @@ function loadModuleFromImports(extensions: Extensions, moduleName: string, direc * From https://github.com/nodejs/node/blob/8f39f51cbbd3b2de14b9ee896e26421cc5b20121/lib/internal/modules/esm/resolve.js#L722 - * "longest" has some nuance as to what "longest" means in the presence of pattern trailers */ -export function comparePatternKeys(a: string, b: string) { +export function comparePatternKeys(a: string, b: string): Comparison { const aPatternIndex = a.indexOf("*"); const bPatternIndex = b.indexOf("*"); const baseLenA = aPatternIndex === -1 ? a.length : aPatternIndex + 1; const baseLenB = bPatternIndex === -1 ? b.length : bPatternIndex + 1; - if (baseLenA > baseLenB) return -1; - if (baseLenB > baseLenA) return 1; - if (aPatternIndex === -1) return 1; - if (bPatternIndex === -1) return -1; - if (a.length > b.length) return -1; - if (b.length > a.length) return 1; - return 0; + if (baseLenA > baseLenB) return Comparison.LessThan; + if (baseLenB > baseLenA) return Comparison.GreaterThan; + if (aPatternIndex === -1) return Comparison.GreaterThan; + if (bPatternIndex === -1) return Comparison.LessThan; + if (a.length > b.length) return Comparison.LessThan; + if (b.length > a.length) return Comparison.GreaterThan; + return Comparison.EqualTo; } function loadModuleFromImportsOrExports(extensions: Extensions, state: ModuleResolutionState, cache: ModuleResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined, moduleName: string, lookupTable: object, scope: PackageJsonInfo, isImports: boolean): SearchResult | undefined { @@ -2965,7 +2965,7 @@ function getLoadModuleFromTargetImportOrExport(extensions: Extensions, state: Mo } /** @internal */ -export function isApplicableVersionedTypesKey(conditions: readonly string[], key: string) { +export function isApplicableVersionedTypesKey(conditions: readonly string[], key: string): boolean { if (!conditions.includes("types")) return false; // only apply versioned types conditions if the types condition is applied if (!startsWith(key, "types@")) return false; const range = VersionRange.tryParse(key.substring("types@".length)); @@ -3332,8 +3332,8 @@ function resolveFromTypeRoot(moduleName: string, state: ModuleResolutionState) { // Program errors validate that `noEmit` or `emitDeclarationOnly` is also set, // so this function doesn't check them to avoid propagating errors. /** @internal */ -export function shouldAllowImportingTsExtension(compilerOptions: CompilerOptions, fromFileName?: string) { - return !!compilerOptions.allowImportingTsExtensions || fromFileName && isDeclarationFileName(fromFileName); +export function shouldAllowImportingTsExtension(compilerOptions: CompilerOptions, fromFileName?: string): boolean { + return !!compilerOptions.allowImportingTsExtensions || !!fromFileName && isDeclarationFileName(fromFileName); } /** diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 9dd63591eef57..ac433ba8fed10 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -390,7 +390,7 @@ export function getModuleSpecifiersWithCacheInfo( importingSourceFile: SourceFile | FutureSourceFile, host: ModuleSpecifierResolutionHost, userPreferences: UserPreferences, - options: ModuleSpecifierOptions = {}, + options: ModuleSpecifierOptions | undefined = {}, forAutoImport: boolean, ): ModuleSpecifierResult { let computedWithoutCache = false; @@ -1412,7 +1412,7 @@ function processEnding(fileName: string, allowedEndings: readonly ModuleSpecifie } /** @internal */ -export function tryGetRealFileNameForNonJsDeclarationFileName(fileName: string) { +export function tryGetRealFileNameForNonJsDeclarationFileName(fileName: string): string | undefined { const baseName = getBaseFileName(fileName); if (!endsWith(fileName, Extension.Ts) || !baseName.includes(".d.") || fileExtensionIsOneOf(baseName, [Extension.Dts])) return undefined; const noExtension = removeExtension(fileName, Extension.Ts); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c95c4759b9c12..1f007410f11c5 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -458,14 +458,14 @@ function visitNodes(cbNode: (node: Node) => T, cbNodes: ((node: NodeArray 0; } @@ -66,7 +66,7 @@ export function isRootedDiskPath(path: string) { * * @internal */ -export function isDiskPathRoot(path: string) { +export function isDiskPathRoot(path: string): boolean { const rootLength = getEncodedRootLength(path); return rootLength > 0 && rootLength === path.length; } @@ -137,7 +137,7 @@ export function fileExtensionIsOneOf(path: string, extensions: readonly string[] * * @internal */ -export function hasTrailingDirectorySeparator(path: string) { +export function hasTrailingDirectorySeparator(path: string): boolean { return path.length > 0 && isAnyDirectorySeparator(path.charCodeAt(path.length - 1)); } @@ -247,7 +247,7 @@ function getEncodedRootLength(path: string): number { * * @internal */ -export function getRootLength(path: string) { +export function getRootLength(path: string): number { const rootLength = getEncodedRootLength(path); return rootLength < 0 ? ~rootLength : rootLength; } @@ -509,7 +509,7 @@ export function getPathComponents(path: string, currentDirectory = "") { * * @internal */ -export function getPathFromPathComponents(pathComponents: readonly T[], length?: number) { +export function getPathFromPathComponents(pathComponents: readonly T[], length?: number): T { if (pathComponents.length === 0) return "" as T; const root = pathComponents[0] && ensureTrailingDirectorySeparator(pathComponents[0]); @@ -535,7 +535,7 @@ export function normalizeSlashes(path: string): string { * * @internal */ -export function reducePathComponents(components: readonly string[]) { +export function reducePathComponents(components: readonly string[]): string[] { if (!some(components)) return []; const reduced = [components[0]]; for (let i = 1; i < components.length; i++) { @@ -619,12 +619,12 @@ export function resolvePath(path: string, ...paths: (string | undefined)[]): str * * @internal */ -export function getNormalizedPathComponents(path: string, currentDirectory: string | undefined) { +export function getNormalizedPathComponents(path: string, currentDirectory: string | undefined): string[] { return reducePathComponents(getPathComponents(path, currentDirectory)); } /** @internal */ -export function getNormalizedAbsolutePath(fileName: string, currentDirectory: string | undefined) { +export function getNormalizedAbsolutePath(fileName: string, currentDirectory: string | undefined): string { return getPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory)); } @@ -654,7 +654,7 @@ function getPathWithoutRoot(pathComponents: readonly string[]) { } /** @internal */ -export function getNormalizedAbsolutePathWithoutRoot(fileName: string, currentDirectory: string | undefined) { +export function getNormalizedAbsolutePathWithoutRoot(fileName: string, currentDirectory: string | undefined): string { return getPathWithoutRoot(getNormalizedPathComponents(fileName, currentDirectory)); } @@ -767,7 +767,7 @@ export function changeAnyExtension(path: string, ext: string, extensions?: strin * changeFullExtension("file.d.ts", ".js") === "file.js" * ``` */ -export function changeFullExtension(path: string, newExtension: string) { +export function changeFullExtension(path: string, newExtension: string): string { const declarationExtension = getDeclarationFileExtension(path); if (declarationExtension) { return path.slice(0, path.length - declarationExtension.length) + @@ -822,7 +822,7 @@ function comparePathsWorker(a: string, b: string, componentComparer: (a: string, * * @internal */ -export function comparePathsCaseSensitive(a: string, b: string) { +export function comparePathsCaseSensitive(a: string, b: string): Comparison { return comparePathsWorker(a, b, compareStringsCaseSensitive); } @@ -831,7 +831,7 @@ export function comparePathsCaseSensitive(a: string, b: string) { * * @internal */ -export function comparePathsCaseInsensitive(a: string, b: string) { +export function comparePathsCaseInsensitive(a: string, b: string): Comparison { return comparePathsWorker(a, b, compareStringsCaseInsensitive); } @@ -960,12 +960,12 @@ export function convertToRelativePath(absoluteOrRelativePath: string, basePath: } /** @internal */ -export function getRelativePathFromFile(from: string, to: string, getCanonicalFileName: GetCanonicalFileName) { +export function getRelativePathFromFile(from: string, to: string, getCanonicalFileName: GetCanonicalFileName): string { return ensurePathIsNonModuleName(getRelativePathFromDirectory(getDirectoryPath(from), to, getCanonicalFileName)); } /** @internal */ -export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, isAbsolutePathAnUrl: boolean) { +export function getRelativePathToDirectoryOrUrl(directoryPathOrUrl: string, relativeOrAbsolutePath: string, currentDirectory: string, getCanonicalFileName: GetCanonicalFileName, isAbsolutePathAnUrl: boolean): string { const pathComponents = getPathComponentsRelativeTo( resolvePath(currentDirectory, directoryPathOrUrl), resolvePath(currentDirectory, relativeOrAbsolutePath), @@ -1010,6 +1010,6 @@ export function forEachAncestorDirectory(directory: P, call } /** @internal */ -export function isNodeModulesDirectory(dirPath: Path) { +export function isNodeModulesDirectory(dirPath: Path): boolean { return endsWith(dirPath, "/node_modules"); } diff --git a/src/compiler/performance.ts b/src/compiler/performance.ts index 6784d1d0f7dce..e176474b37ba8 100644 --- a/src/compiler/performance.ts +++ b/src/compiler/performance.ts @@ -26,7 +26,7 @@ export interface Timer { } /** @internal */ -export function createTimerIf(condition: boolean, measureName: string, startMarkName: string, endMarkName: string) { +export function createTimerIf(condition: boolean, measureName: string, startMarkName: string, endMarkName: string): Timer { return condition ? createTimer(measureName, startMarkName, endMarkName) : nullTimer; } @@ -71,7 +71,7 @@ const durations = new Map(); * * @internal */ -export function mark(markName: string) { +export function mark(markName: string): void { if (enabled) { const count = counts.get(markName) ?? 0; counts.set(markName, count + 1); @@ -94,7 +94,7 @@ export function mark(markName: string) { * * @internal */ -export function measure(measureName: string, startMarkName?: string, endMarkName?: string) { +export function measure(measureName: string, startMarkName?: string, endMarkName?: string): void { if (enabled) { const end = (endMarkName !== undefined ? marks.get(endMarkName) : undefined) ?? timestamp(); const start = (startMarkName !== undefined ? marks.get(startMarkName) : undefined) ?? timeorigin; @@ -111,7 +111,7 @@ export function measure(measureName: string, startMarkName?: string, endMarkName * * @internal */ -export function getCount(markName: string) { +export function getCount(markName: string): number { return counts.get(markName) || 0; } @@ -122,7 +122,7 @@ export function getCount(markName: string) { * * @internal */ -export function getDuration(measureName: string) { +export function getDuration(measureName: string): number { return durations.get(measureName) || 0; } @@ -133,24 +133,24 @@ export function getDuration(measureName: string) { * * @internal */ -export function forEachMeasure(cb: (measureName: string, duration: number) => void) { +export function forEachMeasure(cb: (measureName: string, duration: number) => void): void { durations.forEach((duration, measureName) => cb(measureName, duration)); } /** @internal */ -export function forEachMark(cb: (markName: string) => void) { +export function forEachMark(cb: (markName: string) => void): void { marks.forEach((_time, markName) => cb(markName)); } /** @internal */ -export function clearMeasures(name?: string) { +export function clearMeasures(name?: string): void { if (name !== undefined) durations.delete(name); else durations.clear(); performanceImpl?.clearMeasures(name); } /** @internal */ -export function clearMarks(name?: string) { +export function clearMarks(name?: string): void { if (name !== undefined) { counts.delete(name); marks.delete(name); @@ -167,7 +167,7 @@ export function clearMarks(name?: string) { * * @internal */ -export function isEnabled() { +export function isEnabled(): boolean { return enabled; } @@ -199,7 +199,7 @@ export function enable(system: System = sys) { * * @internal */ -export function disable() { +export function disable(): void { if (enabled) { marks.clear(); counts.clear(); diff --git a/src/compiler/performanceCore.ts b/src/compiler/performanceCore.ts index ba03e7a3314b9..38d8badace719 100644 --- a/src/compiler/performanceCore.ts +++ b/src/compiler/performanceCore.ts @@ -90,7 +90,7 @@ const nativePerformanceHooks = tryGetPerformanceHooks(); const nativePerformanceTime = nativePerformanceHooks?.performanceTime; /** @internal */ -export function tryGetNativePerformanceHooks() { +export function tryGetNativePerformanceHooks(): PerformanceHooks | undefined { return nativePerformanceHooks; } @@ -99,4 +99,4 @@ export function tryGetNativePerformanceHooks() { * * @internal */ -export const timestamp = nativePerformanceTime ? () => nativePerformanceTime.now() : Date.now; +export const timestamp: () => number = nativePerformanceTime ? () => nativePerformanceTime.now() : Date.now; diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 7367f5e6a9ddf..ad18f43b29e35 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -516,12 +516,23 @@ export interface CompilerHostLikeForCache { writeFile?: WriteFileCallback; } +/** @internal */ +export interface CompilerHostLikeWithCache { + originalReadFile: (fileName: string, encoding?: string) => string | undefined; + originalFileExists: (fileName: string) => boolean; + originalDirectoryExists: ((directory: string) => boolean) | undefined; + originalCreateDirectory: ((directory: string) => void) | undefined; + originalWriteFile: WriteFileCallback | undefined; + getSourceFileWithCache: ((fileName: string, languageVersionOrOptions: ScriptTarget | CreateSourceFileOptions, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean) => SourceFile | undefined) | undefined; + readFileWithCache: (fileName: string) => string | undefined; +} + /** @internal */ export function changeCompilerHostLikeToUseCache( host: CompilerHostLikeForCache, toPath: (fileName: string) => Path, getSourceFile?: CompilerHost["getSourceFile"], -) { +): CompilerHostLikeWithCache { const originalReadFile = host.readFile; const originalFileExists = host.fileExists; const originalDirectoryExists = host.directoryExists; @@ -704,7 +715,7 @@ function getCategoryFormat(category: DiagnosticCategory): ForegroundColorEscapeS } /** @internal */ -export function formatColorAndReset(text: string, formatStyle: string) { +export function formatColorAndReset(text: string, formatStyle: string): string { return formatStyle + text + resetEscapeSequence; } @@ -763,7 +774,7 @@ function formatCodeSpan(file: SourceFile, start: number, length: number, indent: } /** @internal */ -export function formatLocation(file: SourceFile, start: number, host: FormatDiagnosticsHost, color = formatColorAndReset) { +export function formatLocation(file: SourceFile, start: number, host: FormatDiagnosticsHost, color: typeof formatColorAndReset = formatColorAndReset): string { const { line: firstLine, character: firstLineChar } = getLineAndCharacterOfPosition(file, start); // TODO: GH#18217 const relativeFileName = host ? convertToRelativePath(file.fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName)) : file.fileName; @@ -854,7 +865,7 @@ export interface SourceFileImportsList { * Calculates the resulting resolution mode for some reference in some file - this is generally the explicitly * provided resolution mode in the reference, unless one is not present, in which case it is the mode of the containing file. */ -export function getModeForFileReference(ref: FileReference | string, containingFileMode: ResolutionMode) { +export function getModeForFileReference(ref: FileReference | string, containingFileMode: ResolutionMode): ResolutionMode { return (isString(ref) ? containingFileMode : ref.resolutionMode) || containingFileMode; } @@ -881,7 +892,7 @@ export function getModeForResolutionAtIndex(file: SourceFileImportsList, index: } /** @internal */ -export function isExclusivelyTypeOnlyImportOrExport(decl: ImportDeclaration | ExportDeclaration | JSDocImportTag) { +export function isExclusivelyTypeOnlyImportOrExport(decl: ImportDeclaration | ExportDeclaration | JSDocImportTag): boolean { if (isExportDeclaration(decl)) { return decl.isTypeOnly; } @@ -929,7 +940,7 @@ export function isExclusivelyTypeOnlyImportOrExport(decl: ImportDeclaration | Ex * should be the options of the referenced project, not the referencing project. * @returns The final resolution mode of the import */ -export function getModeForUsageLocation(file: SourceFile, usage: StringLiteralLike, compilerOptions: CompilerOptions) { +export function getModeForUsageLocation(file: SourceFile, usage: StringLiteralLike, compilerOptions: CompilerOptions): ResolutionMode { return getModeForUsageLocationWorker(file, usage, compilerOptions); } @@ -982,7 +993,7 @@ function getEmitSyntaxForUsageLocationWorker(file: Pick void) { +export function getResolutionModeOverride(node: ImportAttributes | undefined, grammarErrorOnNode?: (node: Node, diagnostic: DiagnosticMessage) => void): ResolutionMode | undefined { if (!node) return undefined; if (length(node.elements) !== 1) { grammarErrorOnNode?.( @@ -1182,13 +1193,13 @@ function forEachProjectReference( export const inferredTypesContainingFile = "__inferred type names__.ts"; /** @internal */ -export function getInferredLibraryNameResolveFrom(options: CompilerOptions, currentDirectory: string, libFileName: string) { +export function getInferredLibraryNameResolveFrom(options: CompilerOptions, currentDirectory: string, libFileName: string): string { const containingDirectory = options.configFilePath ? getDirectoryPath(options.configFilePath) : currentDirectory; return combinePaths(containingDirectory, `__lib_node_modules_lookup_${libFileName}__.ts`); } /** @internal */ -export function getLibraryNameFromLibFileName(libFileName: string) { +export function getLibraryNameFromLibFileName(libFileName: string): string { // Support resolving to lib.dom.d.ts -> @typescript/lib-dom, and // lib.dom.iterable.d.ts -> @typescript/lib-dom/iterable // lib.es2015.symbol.wellknown.d.ts -> @typescript/lib-es2015/symbol-wellknown @@ -1393,7 +1404,7 @@ export function getImpliedNodeFormatForFileWorker( packageJsonInfoCache: PackageJsonInfoCache | undefined, host: ModuleResolutionHost, options: CompilerOptions, -) { +): ResolutionMode | Partial | undefined { const moduleResolution = getEmitModuleResolutionKind(options); const shouldLookupFromPackageJson = ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext || pathContainsNodeModules(fileName); diff --git a/src/compiler/resolutionCache.ts b/src/compiler/resolutionCache.ts index ee055456a7646..7c69055ec1f66 100644 --- a/src/compiler/resolutionCache.ts +++ b/src/compiler/resolutionCache.ts @@ -303,7 +303,7 @@ function perceivedOsRootLengthForWatching(pathComponents: Readonly, length?: number) { +export function canWatchDirectoryOrFile(pathComponents: Readonly, length?: number): boolean { if (length === undefined) length = pathComponents.length; // Ignore "/", "c:/" // ignore "/user", "c:/users" or "c:/folderAtRoot" @@ -313,12 +313,12 @@ export function canWatchDirectoryOrFile(pathComponents: Readonly string | undefined) { +export function getRootDirectoryOfResolutionCache(rootDirForResolution: string, getCurrentDirectory: () => string | undefined): string { const normalized = getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory()); return !isDiskPathRoot(normalized) ? removeTrailingDirectorySeparator(normalized) : diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index ce01171fcaafe..50e827c17bd24 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -21,6 +21,7 @@ import { KeywordSyntaxKind, LanguageFeatureMinimumTarget, LanguageVariant, + LanugageFeatures, LineAndCharacter, MapLike, parsePseudoBigInt, @@ -295,7 +296,7 @@ const charCodeToRegExpFlag = new Map([ [CharacterCodes.y, RegularExpressionFlags.Sticky], ]); -const regExpFlagToFirstAvailableLanguageVersion = new Map([ +const regExpFlagToFirstAvailableLanguageVersion = new Map([ [RegularExpressionFlags.HasIndices, LanguageFeatureMinimumTarget.RegularExpressionFlagsHasIndices], [RegularExpressionFlags.DotAll, LanguageFeatureMinimumTarget.RegularExpressionFlagsDotAll], [RegularExpressionFlags.Unicode, LanguageFeatureMinimumTarget.RegularExpressionFlagsUnicode], @@ -384,7 +385,7 @@ function lookupInUnicodeMap(code: number, map: readonly number[]): boolean { } /** @internal */ -export function isUnicodeIdentifierStart(code: number, languageVersion: ScriptTarget | undefined) { +export function isUnicodeIdentifierStart(code: number, languageVersion: ScriptTarget | undefined): boolean { return languageVersion! >= ScriptTarget.ES2015 ? lookupInUnicodeMap(code, unicodeESNextIdentifierStart) : lookupInUnicodeMap(code, unicodeES5IdentifierStart); @@ -515,7 +516,7 @@ export function computeLineAndCharacterOfPosition(lineStarts: readonly number[], * @internal * We assume the first line starts at position 0 and 'position' is non-negative. */ -export function computeLineOfPosition(lineStarts: readonly number[], position: number, lowerBound?: number) { +export function computeLineOfPosition(lineStarts: readonly number[], position: number, lowerBound?: number): number { let lineNumber = binarySearch(lineStarts, position, identity, compareValues, lowerBound); if (lineNumber < 0) { // If the actual position was not found, @@ -532,7 +533,7 @@ export function computeLineOfPosition(lineStarts: readonly number[], position: n } /** @internal */ -export function getLinesBetweenPositions(sourceFile: SourceFileLike, pos1: number, pos2: number) { +export function getLinesBetweenPositions(sourceFile: SourceFileLike, pos1: number, pos2: number): number { if (pos1 === pos2) return 0; const lineStarts = getLineStarts(sourceFile); const lower = Math.min(pos1, pos2); @@ -939,11 +940,11 @@ export function forEachTrailingCommentRange(text: string, pos: number, cb: 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) => 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): U | undefined { 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) => 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): U | undefined { return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial); } @@ -1017,7 +1018,15 @@ const enum ClassSetExpressionType { } // Creates a scanner over a (possibly unspecified) range of a piece of text. -export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, languageVariant = LanguageVariant.Standard, textInitial?: string, onError?: ErrorCallback, start?: number, length?: number): Scanner { +export function createScanner( + languageVersion: ScriptTarget, + skipTrivia: boolean, + languageVariant: LanguageVariant = LanguageVariant.Standard, + textInitial?: string, + onError?: ErrorCallback, + start?: number, + length?: number, +): Scanner { // Why var? It avoids TDZ checks in the runtime which can be costly. // See: https://github.com/microsoft/TypeScript/issues/52924 /* eslint-disable no-var */ @@ -3599,7 +3608,7 @@ export function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean } function checkRegularExpressionFlagAvailability(flag: RegularExpressionFlags, size: number) { - const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag) as ScriptTarget | undefined; + const availableFrom = regExpFlagToFirstAvailableLanguageVersion.get(flag); if (availableFrom && languageVersion < availableFrom) { error(Diagnostics.This_regular_expression_flag_is_only_available_when_targeting_0_or_later, pos, size, getNameOfScriptTarget(availableFrom)); } @@ -4053,7 +4062,7 @@ function utf16EncodeAsStringFallback(codePoint: number) { const utf16EncodeAsStringWorker: (codePoint: number) => string = (String as any).fromCodePoint ? codePoint => (String as any).fromCodePoint(codePoint) : utf16EncodeAsStringFallback; /** @internal */ -export function utf16EncodeAsString(codePoint: number) { +export function utf16EncodeAsString(codePoint: number): string { return utf16EncodeAsStringWorker(codePoint); } diff --git a/src/compiler/semver.ts b/src/compiler/semver.ts index 2232d48b691cc..f9423d77f5232 100644 --- a/src/compiler/semver.ts +++ b/src/compiler/semver.ts @@ -44,7 +44,7 @@ const numericIdentifierRegExp = /^(?:0|[1-9]\d*)$/; * @internal */ export class Version { - static readonly zero = new Version(0, 0, 0, ["0"]); + static readonly zero: Version = new Version(0, 0, 0, ["0"]); readonly major: number; readonly minor: number; @@ -77,7 +77,7 @@ export class Version { this.build = buildArray; } - static tryParse(text: string) { + static tryParse(text: string): Version | undefined { const result = tryParseComponents(text); if (!result) return undefined; @@ -85,7 +85,7 @@ export class Version { return new Version(major, minor, patch, prerelease, build); } - compareTo(other: Version | undefined) { + compareTo(other: Version | undefined): Comparison { // https://semver.org/#spec-item-11 // > Precedence is determined by the first difference when comparing each of these // > identifiers from left to right as follows: Major, minor, and patch versions are @@ -106,7 +106,7 @@ export class Version { || comparePrereleaseIdentifiers(this.prerelease, other.prerelease); } - increment(field: "major" | "minor" | "patch") { + increment(field: "major" | "minor" | "patch"): Version { switch (field) { case "major": return new Version(this.major + 1, 0, 0); @@ -119,7 +119,7 @@ export class Version { } } - with(fields: { major?: number; minor?: number; patch?: number; prerelease?: string | readonly string[]; build?: string | readonly string[]; }) { + with(fields: { major?: number; minor?: number; patch?: number; prerelease?: string | readonly string[]; build?: string | readonly string[]; }): Version { const { major = this.major, minor = this.minor, @@ -130,7 +130,7 @@ export class Version { return new Version(major, minor, patch, prerelease, build); } - toString() { + toString(): string { let result = `${this.major}.${this.minor}.${this.patch}`; if (some(this.prerelease)) result += `-${this.prerelease.join(".")}`; if (some(this.build)) result += `+${this.build.join(".")}`; @@ -210,7 +210,7 @@ export class VersionRange { this._alternatives = spec ? Debug.checkDefined(parseRange(spec), "Invalid range spec.") : emptyArray; } - static tryParse(text: string) { + static tryParse(text: string): VersionRange | undefined { const sets = parseRange(text); if (sets) { const range = new VersionRange(""); @@ -224,12 +224,12 @@ export class VersionRange { * Tests whether a version matches the range. This is equivalent to `satisfies(version, range, { includePrerelease: true })`. * in `node-semver`. */ - test(version: Version | string) { + test(version: Version | string): boolean { if (typeof version === "string") version = new Version(version); return testDisjunction(version, this._alternatives); } - toString() { + toString(): string { return formatDisjunction(this._alternatives); } } diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index 9f3c5a05d4266..1ce989b250af7 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -360,12 +360,12 @@ export function createSourceMapGenerator(host: EmitHost, file: string, sourceRoo // Sometimes tools can see the following line as a source mapping url comment, so we mangle it a bit (the [M]) /** @internal */ -export const sourceMapCommentRegExpDontCareLineStart = /\/\/[@#] source[M]appingURL=(.+)\r?\n?$/; // eslint-disable-line regexp/no-useless-character-class +export const sourceMapCommentRegExpDontCareLineStart: RegExp = /\/\/[@#] source[M]appingURL=(.+)\r?\n?$/; // eslint-disable-line regexp/no-useless-character-class /** @internal */ -export const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\r?\n?$/; // eslint-disable-line regexp/no-useless-character-class +export const sourceMapCommentRegExp: RegExp = /^\/\/[@#] source[M]appingURL=(.+)\r?\n?$/; // eslint-disable-line regexp/no-useless-character-class /** @internal */ -export const whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/; +export const whitespaceOrMapCommentRegExp: RegExp = /^\s*(\/\/[@#] .*)?$/; /** @internal */ export interface LineInfo { @@ -386,7 +386,7 @@ export function getLineInfo(text: string, lineStarts: readonly number[]): LineIn * * @internal */ -export function tryGetSourceMappingURL(lineInfo: LineInfo) { +export function tryGetSourceMappingURL(lineInfo: LineInfo): string | undefined { for (let index = lineInfo.getLineCount() - 1; index >= 0; index--) { const line = lineInfo.getLineText(index); const comment = sourceMapCommentRegExp.exec(line); @@ -419,7 +419,7 @@ function isRawSourceMap(x: any): x is RawSourceMap { /* eslint-enable no-restricted-syntax */ /** @internal */ -export function tryParseRawSourceMap(text: string) { +export function tryParseRawSourceMap(text: string): RawSourceMap | undefined { try { const parsed = JSON.parse(text); if (isRawSourceMap(parsed)) { @@ -616,7 +616,7 @@ export function decodeMappings(mappings: string): MappingsDecoder { } /** @internal */ -export function sameMapping(left: T, right: T) { +export function sameMapping(left: T, right: T): boolean { return left === right || left.generatedLine === right.generatedLine && left.generatedCharacter === right.generatedCharacter diff --git a/src/compiler/symbolWalker.ts b/src/compiler/symbolWalker.ts index 6942028d9af79..3f1181236f90a 100644 --- a/src/compiler/symbolWalker.ts +++ b/src/compiler/symbolWalker.ts @@ -38,7 +38,7 @@ export function createGetSymbolWalker( getConstraintOfTypeParameter: (typeParameter: TypeParameter) => Type | undefined, getFirstIdentifier: (node: EntityNameOrEntityNameExpression) => Identifier, getTypeArguments: (type: TypeReference) => readonly Type[], -) { +): (accept?: (symbol: Symbol) => boolean) => SymbolWalker { return getSymbolWalker; function getSymbolWalker(accept: (symbol: Symbol) => boolean = () => true): SymbolWalker { diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index a5b24bf854319..f0414f26d24db 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -71,7 +71,7 @@ export function generateDjb2Hash(data: string): string { * * @internal */ -export function setStackTraceLimit() { +export function setStackTraceLimit(): void { if ((Error as any).stackTraceLimit < 100) { // Also tests that we won't set the property if it doesn't exist. (Error as any).stackTraceLimit = 100; } @@ -104,10 +104,10 @@ export type HostWatchFile = (fileName: string, callback: FileWatcherCallback, po export type HostWatchDirectory = (fileName: string, callback: DirectoryWatcherCallback, recursive: boolean, options: WatchOptions | undefined) => FileWatcher; /** @internal */ -export const missingFileModifiedTime = new Date(0); // Any subsequent modification will occur after this time +export const missingFileModifiedTime: Date = new Date(0); // Any subsequent modification will occur after this time /** @internal */ -export function getModifiedTime(host: { getModifiedTime: NonNullable; }, fileName: string) { +export function getModifiedTime(host: { getModifiedTime: NonNullable; }, fileName: string): Date { return host.getModifiedTime(fileName) || missingFileModifiedTime; } @@ -128,7 +128,7 @@ function createPollingIntervalBasedLevels(levels: Levels) { const defaultChunkLevels: Levels = { Low: 32, Medium: 64, High: 256 }; let pollingChunkSize = createPollingIntervalBasedLevels(defaultChunkLevels); /** @internal */ -export let unchangedPollThresholds = createPollingIntervalBasedLevels(defaultChunkLevels); +export let unchangedPollThresholds: { [K in PollingInterval]: number; } = createPollingIntervalBasedLevels(defaultChunkLevels); function setCustomPollingValues(system: System) { if (!system.getEnvironmentVariable) { @@ -550,7 +550,7 @@ function onWatchedFileStat(watchedFile: WatchedFile, modifiedTime: Date): boolea } /** @internal */ -export function getFileWatcherEventKind(oldTime: number, newTime: number) { +export function getFileWatcherEventKind(oldTime: number, newTime: number): FileWatcherEventKind { return oldTime === 0 ? FileWatcherEventKind.Created : newTime === 0 @@ -559,17 +559,17 @@ export function getFileWatcherEventKind(oldTime: number, newTime: number) { } /** @internal */ -export const ignoredPaths = ["/node_modules/.", "/.git", "/.#"]; +export const ignoredPaths: readonly string[] = ["/node_modules/.", "/.git", "/.#"]; let curSysLog: (s: string) => void = noop; /** @internal */ -export function sysLog(s: string) { +export function sysLog(s: string): void { return curSysLog(s); } /** @internal */ -export function setSysLog(logger: typeof sysLog) { +export function setSysLog(logger: typeof sysLog): void { curSysLog = logger; } @@ -1375,7 +1375,7 @@ export function createSystemWatchFunctions({ * * @internal */ -export function patchWriteFileEnsuringDirectory(sys: System) { +export function patchWriteFileEnsuringDirectory(sys: System): void { // patch writefile to create folder before writing the file const originalWriteFile = sys.writeFile; sys.writeFile = (path, data, writeBom) => @@ -1997,7 +1997,7 @@ export let sys: System = (() => { })(); /** @internal @knipignore */ -export function setSys(s: System) { +export function setSys(s: System): void { sys = s; } diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts index 94e9bd57c83b6..5d7138d1c22eb 100644 --- a/src/compiler/tracing.ts +++ b/src/compiler/tracing.ts @@ -55,7 +55,7 @@ export namespace tracingEnabled { } /** Starts tracing for the given project. */ - export function startTracing(tracingMode: Mode, traceDir: string, configFilePath?: string) { + export function startTracing(tracingMode: Mode, traceDir: string, configFilePath?: string): void { Debug.assert(!tracing, "Tracing already started"); if (fs === undefined) { @@ -105,7 +105,7 @@ export namespace tracingEnabled { } /** Stops tracing for the in-progress project and dumps the type catalog. */ - export function stopTracing() { + export function stopTracing(): void { Debug.assert(tracing, "Tracing is not in progress"); Debug.assert(!!typeCatalog.length === (mode !== "server")); // Have a type catalog iff not in server mode @@ -139,7 +139,7 @@ export namespace tracingEnabled { Session = "session", } - export function instant(phase: Phase, name: string, args?: Args) { + export function instant(phase: Phase, name: string, args?: Args): void { writeEvent("I", phase, name, args, `"s":"g"`); } @@ -151,18 +151,18 @@ export namespace tracingEnabled { * In the future we might implement an exit handler to dump unfinished events which would deprecate * these operations. */ - export function push(phase: Phase, name: string, args?: Args, separateBeginAndEnd = false) { + export function push(phase: Phase, name: string, args?: Args, separateBeginAndEnd = false): void { if (separateBeginAndEnd) { writeEvent("B", phase, name, args); } eventStack.push({ phase, name, args, time: 1000 * timestamp(), separateBeginAndEnd }); } - export function pop(results?: Args) { + export function pop(results?: Args): void { Debug.assert(eventStack.length > 0); writeStackEvent(eventStack.length - 1, 1000 * timestamp(), results); eventStack.length--; } - export function popAll() { + export function popAll(): void { const endTime = 1000 * timestamp(); for (let i = eventStack.length - 1; i >= 0; i--) { writeStackEvent(i, endTime); @@ -348,7 +348,7 @@ export namespace tracingEnabled { performance.measure("Dump types", "beginDumpTypes", "endDumpTypes"); } - export function dumpLegend() { + export function dumpLegend(): void { if (!legendPath) { return; } @@ -365,9 +365,9 @@ export namespace tracingEnabled { // define after tracingEnabled is initialized /** @internal */ -export const startTracing = tracingEnabled.startTracing; +export const startTracing: typeof tracingEnabled.startTracing = tracingEnabled.startTracing; /** @internal */ -export const dumpTracingLegend = tracingEnabled.dumpLegend; +export const dumpTracingLegend: typeof tracingEnabled.dumpLegend = tracingEnabled.dumpLegend; /** @internal */ export interface TracingNode { diff --git a/src/compiler/transformer.ts b/src/compiler/transformer.ts index bd181e5f3c028..0d499f3a08298 100644 --- a/src/compiler/transformer.ts +++ b/src/compiler/transformer.ts @@ -222,12 +222,12 @@ function wrapDeclarationTransformerFactory(transformer: TransformerFactory void) { +export function noEmitNotification(hint: EmitHint, node: Node, callback: (hint: EmitHint, node: Node) => void): void { callback(hint, node); } diff --git a/src/compiler/transformers/classThis.ts b/src/compiler/transformers/classThis.ts index e357c9b6e4f8b..86eb48346e50e 100644 --- a/src/compiler/transformers/classThis.ts +++ b/src/compiler/transformers/classThis.ts @@ -87,7 +87,7 @@ export function isClassThisAssignmentBlock(node: Node): node is ClassThisAssignm * `_classThis` (or similar) variable. * @internal */ -export function classHasClassThisAssignment(node: ClassLikeDeclaration) { +export function classHasClassThisAssignment(node: ClassLikeDeclaration): boolean { return !!node.emitNode?.classThis && some(node.members, isClassThisAssignmentBlock); } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index b12c3acf84c3e..ba19f34fe0af9 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -196,6 +196,7 @@ import { SymbolTracker, SyntaxKind, TransformationContext, + Transformer, transformNodes, tryCast, TypeAliasDeclaration, @@ -253,7 +254,7 @@ const declarationEmitInternalNodeBuilderFlags = InternalNodeBuilderFlags.AllowUn * * @internal */ -export function transformDeclarations(context: TransformationContext) { +export function transformDeclarations(context: TransformationContext): Transformer { const throwDiagnostic = () => Debug.fail("Diagnostic emitted without context"); let getSymbolAccessibilityDiagnostic: GetSymbolAccessibilityDiagnostic = throwDiagnostic; let needsDeclare = true; @@ -436,10 +437,7 @@ export function transformDeclarations(context: TransformationContext) { return result; } - function transformRoot(node: Bundle): Bundle; - function transformRoot(node: SourceFile): SourceFile; - function transformRoot(node: SourceFile | Bundle): SourceFile | Bundle; - function transformRoot(node: SourceFile | Bundle) { + function transformRoot(node: SourceFile | Bundle): SourceFile | Bundle { if (node.kind === SyntaxKind.SourceFile && node.isDeclarationFile) { return node; } diff --git a/src/compiler/transformers/declarations/diagnostics.ts b/src/compiler/transformers/declarations/diagnostics.ts index d7a6c54f5eaf0..7e2978d9c59b8 100644 --- a/src/compiler/transformers/declarations/diagnostics.ts +++ b/src/compiler/transformers/declarations/diagnostics.ts @@ -161,7 +161,7 @@ export function canProduceDiagnostics(node: Node): node is DeclarationDiagnostic } /** @internal */ -export function createGetSymbolAccessibilityDiagnosticForNodeName(node: DeclarationDiagnosticProducing) { +export function createGetSymbolAccessibilityDiagnosticForNodeName(node: DeclarationDiagnosticProducing): (symbolAccessibilityResult: SymbolAccessibilityResult) => SymbolAccessibilityDiagnostic | undefined { if (isSetAccessor(node) || isGetAccessor(node)) { return getAccessorNameVisibilityError; } @@ -603,7 +603,7 @@ export function createGetSymbolAccessibilityDiagnosticForNode(node: DeclarationD } /** @internal */ -export function createGetIsolatedDeclarationErrors(resolver: EmitResolver) { +export function createGetIsolatedDeclarationErrors(resolver: EmitResolver): (node: Node) => DiagnosticWithLocation { const relatedSuggestionByDeclarationKind = { [SyntaxKind.ArrowFunction]: Diagnostics.Add_a_return_type_to_the_function_expression, [SyntaxKind.FunctionExpression]: Diagnostics.Add_a_return_type_to_the_function_expression, diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 8947a94a079f4..3a80a84334eef 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -1056,7 +1056,7 @@ export function transformES2017(context: TransformationContext): (x: SourceFile * * @internal */ -export function createSuperAccessVariableStatement(factory: NodeFactory, resolver: EmitResolver, node: FunctionLikeDeclaration, names: Set<__String>) { +export function createSuperAccessVariableStatement(factory: NodeFactory, resolver: EmitResolver, node: FunctionLikeDeclaration, names: Set<__String>): VariableStatement { // Create a variable declaration with a getter/setter (if binding) definition for each name: // const _super = Object.create(null, { x: { get: () => super.x, set: (v) => super.x = v }, ... }); const hasBinding = resolver.hasNodeCheckFlag(node, NodeCheckFlags.MethodWithSuperPropertyAssignmentInAsync); diff --git a/src/compiler/transformers/module/impliedNodeFormatDependent.ts b/src/compiler/transformers/module/impliedNodeFormatDependent.ts index 7a5bf9e210fcd..c793c3abe3c54 100644 --- a/src/compiler/transformers/module/impliedNodeFormatDependent.ts +++ b/src/compiler/transformers/module/impliedNodeFormatDependent.ts @@ -10,11 +10,12 @@ import { SyntaxKind, TransformationContext, transformECMAScriptModule, + Transformer, transformModule, } from "../../_namespaces/ts.js"; /** @internal */ -export function transformImpliedNodeFormatDependentModule(context: TransformationContext) { +export function transformImpliedNodeFormatDependentModule(context: TransformationContext): Transformer { const previousOnSubstituteNode = context.onSubstituteNode; const previousOnEmitNode = context.onEmitNode; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 036b8d60f9f27..75a6a34a55b1c 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -190,6 +190,7 @@ import { takeWhile, TextRange, TransformationContext, + Transformer, TransformFlags, VariableDeclaration, VariableStatement, @@ -231,7 +232,7 @@ const enum ClassFacts { } /** @internal */ -export function transformTypeScript(context: TransformationContext) { +export function transformTypeScript(context: TransformationContext): Transformer { const { factory, getEmitHelperFactory: emitHelpers, diff --git a/src/compiler/transformers/utilities.ts b/src/compiler/transformers/utilities.ts index 241728903dbe3..0079aa25aab16 100644 --- a/src/compiler/transformers/utilities.ts +++ b/src/compiler/transformers/utilities.ts @@ -96,7 +96,7 @@ import { } from "../_namespaces/ts.js"; /** @internal */ -export function getOriginalNodeId(node: Node) { +export function getOriginalNodeId(node: Node): number { node = getOriginalNode(node); return node ? getNodeId(node) : 0; } @@ -381,19 +381,19 @@ function multiMapSparseArrayAdd(map: V[][], key: number, value: V): V[] { export class IdentifierNameMap { private readonly _map = new Map(); - get size() { + get size(): number { return this._map.size; } - has(key: Identifier) { + has(key: Identifier): boolean { return this._map.has(IdentifierNameMap.toKey(key)); } - get(key: Identifier) { + get(key: Identifier): V | undefined { return this._map.get(IdentifierNameMap.toKey(key)); } - set(key: Identifier, value: V) { + set(key: Identifier, value: V): this { this._map.set(IdentifierNameMap.toKey(key), value); return this; } @@ -406,7 +406,7 @@ export class IdentifierNameMap { this._map.clear(); } - values() { + values(): MapIterator { return this._map.values(); } @@ -460,7 +460,7 @@ class IdentifierNameMultiMap extends IdentifierNameMap { * * @internal */ -export function isSimpleCopiableExpression(expression: Expression) { +export function isSimpleCopiableExpression(expression: Expression): boolean { return isStringLiteralLike(expression) || expression.kind === SyntaxKind.NumericLiteral || isKeyword(expression.kind) || @@ -474,7 +474,7 @@ export function isSimpleCopiableExpression(expression: Expression) { * * @internal */ -export function isSimpleInlineableExpression(expression: Expression) { +export function isSimpleInlineableExpression(expression: Expression): boolean { return !isIdentifier(expression) && isSimpleCopiableExpression(expression); } @@ -560,7 +560,7 @@ function findSuperStatementIndexPathWorker(statements: NodeArray, sta * * @internal */ -export function findSuperStatementIndexPath(statements: NodeArray, start: number) { +export function findSuperStatementIndexPath(statements: NodeArray, start: number): number[] { const indices: number[] = []; findSuperStatementIndexPathWorker(statements, start, indices); return indices; @@ -821,7 +821,7 @@ export function newPrivateEnvironment(data: TData): PrivateEnviro export function getPrivateIdentifier( privateEnv: PrivateEnvironment | undefined, name: PrivateIdentifier, -) { +): TEntry | undefined { return isGeneratedPrivateIdentifier(name) ? privateEnv?.generatedIdentifiers?.get(getNodeForGeneratedName(name)) : privateEnv?.identifiers?.get(name.escapedText); @@ -832,7 +832,7 @@ export function setPrivateIdentifier( privateEnv: PrivateEnvironment, name: PrivateIdentifier, entry: TEntry, -) { +): void { if (isGeneratedPrivateIdentifier(name)) { privateEnv.generatedIdentifiers ??= new Map(); privateEnv.generatedIdentifiers.set(getNodeForGeneratedName(name), entry); @@ -851,7 +851,7 @@ export function accessPrivateIdentifier< >( env: LexicalEnvironment | undefined, name: PrivateIdentifier, -) { +): TPrivateEntry | undefined { return walkUpLexicalEnvironments(env, env => getPrivateIdentifier(env.privateEnv, name)); } @@ -860,6 +860,6 @@ function isSimpleParameter(node: ParameterDeclaration) { } /** @internal */ -export function isSimpleParameterList(nodes: NodeArray) { +export function isSimpleParameterList(nodes: NodeArray): boolean { return every(nodes, isSimpleParameter); } diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 3230699eba3c0..be2074ed22d28 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -4,6 +4,7 @@ import { assertType, BuilderProgram, BuildInfo, + BuildInfoFileVersionMap, CancellationToken, canJsonReportNoInputFiles, changeCompilerHostLikeToUseCache, @@ -301,13 +302,25 @@ function createSolutionBuilderHostBase(system: System, return host; } -export function createSolutionBuilderHost(system = sys, createProgram?: CreateProgram, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportErrorSummary?: ReportEmitErrorSummary) { +export function createSolutionBuilderHost( + system: System = sys, + createProgram?: CreateProgram, + reportDiagnostic?: DiagnosticReporter, + reportSolutionBuilderStatus?: DiagnosticReporter, + reportErrorSummary?: ReportEmitErrorSummary, +): SolutionBuilderHost { const host = createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus) as SolutionBuilderHost; host.reportErrorSummary = reportErrorSummary; return host; } -export function createSolutionBuilderWithWatchHost(system = sys, createProgram?: CreateProgram, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter) { +export function createSolutionBuilderWithWatchHost( + system: System = sys, + createProgram?: CreateProgram, + reportDiagnostic?: DiagnosticReporter, + reportSolutionBuilderStatus?: DiagnosticReporter, + reportWatchStatus?: WatchStatusReporter, +): SolutionBuilderWithWatchHost { const host = createSolutionBuilderHostBase(system, createProgram, reportDiagnostic, reportSolutionBuilderStatus) as SolutionBuilderWithWatchHost; const watchHost = createWatchHost(system, reportWatchStatus); copyProperties(host, watchHost); @@ -1601,7 +1614,7 @@ function getUpToDateStatusWorker(state: SolutionBuilde /** True if input file has changed timestamp but text is not changed, we can then do only timestamp updates on output to make it look up-to-date later */ let pseudoInputUpToDate = false; const seenRoots = new Set(); - let buildInfoVersionMap: ReturnType | undefined; + let buildInfoVersionMap: BuildInfoFileVersionMap | undefined; // Get timestamps of input files for (const inputFile of project.fileNames) { const inputTime = getModifiedTime(state, inputFile); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 65d12a87cf2c3..590911b3f6e99 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -8334,69 +8334,98 @@ export type EmitHelper = ScopedEmitHelper | UnscopedEmitHelper; export type EmitHelperUniqueNameCallback = (name: string) => string; -/** - * Indicates the minimum `ScriptTarget` (inclusive) after which a specific language feature is no longer transpiled. - * - * @internal - */ -export const enum LanguageFeatureMinimumTarget { +/** @internal */ +export type LanugageFeatures = // ES2015 Features - Classes = ScriptTarget.ES2015, - ForOf = ScriptTarget.ES2015, - Generators = ScriptTarget.ES2015, - Iteration = ScriptTarget.ES2015, - SpreadElements = ScriptTarget.ES2015, - RestElements = ScriptTarget.ES2015, - TaggedTemplates = ScriptTarget.ES2015, - DestructuringAssignment = ScriptTarget.ES2015, - BindingPatterns = ScriptTarget.ES2015, - ArrowFunctions = ScriptTarget.ES2015, - BlockScopedVariables = ScriptTarget.ES2015, - ObjectAssign = ScriptTarget.ES2015, - RegularExpressionFlagsUnicode = ScriptTarget.ES2015, - RegularExpressionFlagsSticky = ScriptTarget.ES2015, - + | "Classes" + | "ForOf" + | "Generators" + | "Iteration" + | "SpreadElements" + | "RestElements" + | "TaggedTemplates" + | "DestructuringAssignment" + | "BindingPatterns" + | "ArrowFunctions" + | "BlockScopedVariables" + | "ObjectAssign" + | "RegularExpressionFlagsUnicode" + | "RegularExpressionFlagsSticky" // ES2016 Features - Exponentiation = ScriptTarget.ES2016, // `x ** y` - + | "Exponentiation" // `x ** y` // ES2017 Features - AsyncFunctions = ScriptTarget.ES2017, // `async function f() {}` - + | "AsyncFunctions" // `async function f() {}` // ES2018 Features - ForAwaitOf = ScriptTarget.ES2018, // `for await (const x of y)` - AsyncGenerators = ScriptTarget.ES2018, // `async function * f() { }` - AsyncIteration = ScriptTarget.ES2018, // `Symbol.asyncIterator` - ObjectSpreadRest = ScriptTarget.ES2018, // `{ ...obj }` - RegularExpressionFlagsDotAll = ScriptTarget.ES2018, - + | "ForAwaitOf" // `for await (const x of y)` + | "AsyncGenerators" // `async function * f() { }` + | "AsyncIteration" // `Symbol.asyncIterator` + | "ObjectSpreadRest" // `{ ...obj }` + | "RegularExpressionFlagsDotAll" // ES2019 Features - BindinglessCatch = ScriptTarget.ES2019, // `try { } catch { }` - + | "BindinglessCatch" // `try { } catch { }` // ES2020 Features - BigInt = ScriptTarget.ES2020, // `0n` - NullishCoalesce = ScriptTarget.ES2020, // `a ?? b` - OptionalChaining = ScriptTarget.ES2020, // `a?.b` - + | "BigInt" // `0n` + | "NullishCoalesce" // `a ?? b` + | "OptionalChaining" // `a?.b` // ES2021 Features - LogicalAssignment = ScriptTarget.ES2021, // `a ||= b`, `a &&= b`, `a ??= b` - + | "LogicalAssignment" // `a ||= b`| `a &&= b`| `a ??= b` // ES2022 Features - TopLevelAwait = ScriptTarget.ES2022, - ClassFields = ScriptTarget.ES2022, - PrivateNamesAndClassStaticBlocks = ScriptTarget.ES2022, // `class C { static {} #x = y, #m() {} }`, `#x in y` - RegularExpressionFlagsHasIndices = ScriptTarget.ES2022, - + | "TopLevelAwait" + | "ClassFields" + | "PrivateNamesAndClassStaticBlocks" // `class C { static {} #x = y| #m() {} }`| `#x in y` + | "RegularExpressionFlagsHasIndices" // ES2023 Features - ShebangComments = ScriptTarget.ESNext, - + | "ShebangComments" // Upcoming Features // NOTE: We must reevaluate the target for upcoming features when each successive TC39 edition is ratified in // June of each year. This includes changes to `LanguageFeatureMinimumTarget`, `ScriptTarget`, // transformers/esnext.ts, commandLineParser.ts, and the contents of each lib/esnext.*.d.ts file. - UsingAndAwaitUsing = ScriptTarget.ESNext, // `using x = y`, `await using x = y` - ClassAndClassElementDecorators = ScriptTarget.ESNext, // `@dec class C {}`, `class C { @dec m() {} }` - RegularExpressionFlagsUnicodeSets = ScriptTarget.ESNext, -} + | "UsingAndAwaitUsing" + | "ClassAndClassElementDecorators" // `using x = y`, `await using x = y` + | "RegularExpressionFlagsUnicodeSets" // `@dec class C {}`, `class C { @dec m() {} }` +; + +/** + * Indicates the minimum `ScriptTarget` (inclusive) after which a specific language feature is no longer transpiled. + * + * @internal + */ +export const LanguageFeatureMinimumTarget: Record = { + Classes: ScriptTarget.ES2015, + ForOf: ScriptTarget.ES2015, + Generators: ScriptTarget.ES2015, + Iteration: ScriptTarget.ES2015, + SpreadElements: ScriptTarget.ES2015, + RestElements: ScriptTarget.ES2015, + TaggedTemplates: ScriptTarget.ES2015, + DestructuringAssignment: ScriptTarget.ES2015, + BindingPatterns: ScriptTarget.ES2015, + ArrowFunctions: ScriptTarget.ES2015, + BlockScopedVariables: ScriptTarget.ES2015, + ObjectAssign: ScriptTarget.ES2015, + RegularExpressionFlagsUnicode: ScriptTarget.ES2015, + RegularExpressionFlagsSticky: ScriptTarget.ES2015, + Exponentiation: ScriptTarget.ES2016, + AsyncFunctions: ScriptTarget.ES2017, + ForAwaitOf: ScriptTarget.ES2018, + AsyncGenerators: ScriptTarget.ES2018, + AsyncIteration: ScriptTarget.ES2018, + ObjectSpreadRest: ScriptTarget.ES2018, + RegularExpressionFlagsDotAll: ScriptTarget.ES2018, + BindinglessCatch: ScriptTarget.ES2019, + BigInt: ScriptTarget.ES2020, + NullishCoalesce: ScriptTarget.ES2020, + OptionalChaining: ScriptTarget.ES2020, + LogicalAssignment: ScriptTarget.ES2021, + TopLevelAwait: ScriptTarget.ES2022, + ClassFields: ScriptTarget.ES2022, + PrivateNamesAndClassStaticBlocks: ScriptTarget.ES2022, + RegularExpressionFlagsHasIndices: ScriptTarget.ES2022, + ShebangComments: ScriptTarget.ESNext, + UsingAndAwaitUsing: ScriptTarget.ESNext, + ClassAndClassElementDecorators: ScriptTarget.ESNext, + RegularExpressionFlagsUnicodeSets: ScriptTarget.ESNext, +}; // dprint-ignore /** @@ -9664,6 +9693,12 @@ export interface BuildInfo { version: string; } +/** @internal */ +export interface BuildInfoFileVersionMap { + fileInfos: Map; + roots: Map; +} + export interface PrintHandlers { /** * A hook used by the Printer when generating unique names to avoid collisions with @@ -10093,7 +10128,7 @@ export interface PragmaDefinition = Concre : never; /** @internal */ -export type ConcretePragmaSpecs = typeof commentPragmas; +export interface ConcretePragmaSpecs { + readonly "reference": { + readonly args: readonly [{ + readonly name: "types"; + readonly optional: true; + readonly captureSpan: true; + }, { + readonly name: "lib"; + readonly optional: true; + readonly captureSpan: true; + }, { + readonly name: "path"; + readonly optional: true; + readonly captureSpan: true; + }, { + readonly name: "no-default-lib"; + readonly optional: true; + }, { + readonly name: "resolution-mode"; + readonly optional: true; + }, { + readonly name: "preserve"; + readonly optional: true; + }]; + readonly kind: PragmaKindFlags.TripleSlashXML; + }; + readonly "amd-dependency": { + readonly args: readonly [{ + readonly name: "path"; + }, { + readonly name: "name"; + readonly optional: true; + }]; + readonly kind: PragmaKindFlags.TripleSlashXML; + }; + readonly "amd-module": { + readonly args: readonly [{ + readonly name: "name"; + }]; + readonly kind: PragmaKindFlags.TripleSlashXML; + }; + readonly "ts-check": { + readonly kind: PragmaKindFlags.SingleLine; + }; + readonly "ts-nocheck": { + readonly kind: PragmaKindFlags.SingleLine; + }; + readonly "jsx": { + readonly args: readonly [{ + readonly name: "factory"; + }]; + readonly kind: PragmaKindFlags.MultiLine; + }; + readonly "jsxfrag": { + readonly args: readonly [{ + readonly name: "factory"; + }]; + readonly kind: PragmaKindFlags.MultiLine; + }; + readonly "jsximportsource": { + readonly args: readonly [{ + readonly name: "factory"; + }]; + readonly kind: PragmaKindFlags.MultiLine; + }; + readonly "jsxruntime": { + readonly args: readonly [{ + readonly name: "factory"; + }]; + readonly kind: PragmaKindFlags.MultiLine; + }; +} /** @internal */ export type PragmaPseudoMap = { [K in keyof ConcretePragmaSpecs]: { arguments: PragmaArgumentType; range: CommentRange; }; }; @@ -10410,3 +10516,11 @@ export interface SyntacticTypeNodeBuilderResolver { requiresAddingImplicitUndefined(parameter: ParameterDeclaration | JSDocParameterTag, enclosingDeclaration: Node | undefined): boolean; isDefinitelyReferenceToGlobalSymbolObject(node: Node): boolean; } + +/** @internal */ +export interface SyntacticNodeBuilder { + typeFromExpression: (node: Expression, context: SyntacticTypeNodeBuilderContext, isConstContext?: boolean, requiresAddingUndefined?: boolean, preserveLiterals?: boolean) => boolean | undefined; + serializeTypeOfDeclaration: (node: HasInferredType, context: SyntacticTypeNodeBuilderContext) => boolean | undefined; + serializeReturnTypeForSignature: (node: SignatureDeclaration | JSDocSignature, context: SyntacticTypeNodeBuilderContext) => boolean | undefined; + serializeTypeOfExpression: (expr: Expression, context: SyntacticTypeNodeBuilderContext, addUndefined?: boolean, preserveLiterals?: boolean) => boolean; +} diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 673c0b38c156d..c7ade289737ca 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -67,6 +67,7 @@ import { compareValues, Comparison, CompilerOptions, + CompilerOptionsValue, ComputedPropertyName, computeLineAndCharacterOfPosition, computeLineOfPosition, @@ -697,12 +698,12 @@ function optionsHaveModuleResolutionChanges(oldOptions: CompilerOptions, newOpti } /** @internal */ -export function changesAffectingProgramStructure(oldOptions: CompilerOptions, newOptions: CompilerOptions) { +export function changesAffectingProgramStructure(oldOptions: CompilerOptions, newOptions: CompilerOptions): boolean { return optionsHaveChanges(oldOptions, newOptions, optionsAffectingProgramStructure); } /** @internal */ -export function optionsHaveChanges(oldOptions: CompilerOptions, newOptions: CompilerOptions, optionDeclarations: readonly CommandLineOption[]) { +export function optionsHaveChanges(oldOptions: CompilerOptions, newOptions: CompilerOptions, optionDeclarations: readonly CommandLineOption[]): boolean { return oldOptions !== newOptions && optionDeclarations.some(o => !isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(newOptions, o))); } @@ -775,12 +776,12 @@ export function usingSingleLineStringWriter(action: (writer: EmitTextWriter) => } /** @internal */ -export function getFullWidth(node: Node) { +export function getFullWidth(node: Node): number { return node.end - node.pos; } /** @internal */ -export function projectReferenceIsEqualTo(oldRef: ProjectReference, newRef: ProjectReference) { +export function projectReferenceIsEqualTo(oldRef: ProjectReference, newRef: ProjectReference): boolean { return oldRef.path === newRef.path && !oldRef.prepend === !newRef.prepend && !oldRef.circular === !newRef.circular; @@ -801,17 +802,17 @@ export function moduleResolutionIsEqualTo(oldResolution: ResolvedModuleWithFaile } /** @internal */ -export function getResolvedModuleFromResolution(resolution: ResolvedModuleWithFailedLookupLocations) { +export function getResolvedModuleFromResolution(resolution: ResolvedModuleWithFailedLookupLocations): ResolvedModuleFull | undefined { return resolution.resolvedModule; } /** @internal */ -export function getResolvedTypeReferenceDirectiveFromResolution(resolution: ResolvedTypeReferenceDirectiveWithFailedLookupLocations) { +export function getResolvedTypeReferenceDirectiveFromResolution(resolution: ResolvedTypeReferenceDirectiveWithFailedLookupLocations): ResolvedTypeReferenceDirective | undefined { return resolution.resolvedTypeReferenceDirective; } /** @internal */ -export function createModuleNotFoundChain(sourceFile: SourceFile, host: TypeCheckerHost, moduleReference: string, mode: ResolutionMode, packageName: string) { +export function createModuleNotFoundChain(sourceFile: SourceFile, host: TypeCheckerHost, moduleReference: string, mode: ResolutionMode, packageName: string): DiagnosticMessageChain { const alternateResult = host.getResolvedModule(sourceFile, moduleReference, mode)?.alternateResult; const alternateResultMessage = alternateResult && (getEmitModuleResolutionKind(host.getCompilerOptions()) === ModuleResolutionKind.Node10 ? [Diagnostics.There_are_types_at_0_but_this_result_could_not_be_resolved_under_your_current_moduleResolution_setting_Consider_updating_to_node16_nodenext_or_bundler, [alternateResult]] as const @@ -850,7 +851,7 @@ export function createModuleNotFoundChain(sourceFile: SourceFile, host: TypeChec } /** @internal */ -export function createModeMismatchDetails(currentSourceFile: SourceFile) { +export function createModeMismatchDetails(currentSourceFile: SourceFile): DiagnosticMessageChain { const ext = tryGetExtensionFromPath(currentSourceFile.fileName); const scope = currentSourceFile.packageJsonScope; const targetExt = ext === Extension.Ts ? Extension.Mts : ext === Extension.Js ? Extension.Mjs : undefined; @@ -969,7 +970,7 @@ export function getSourceFileOfNode(node: Node | undefined): SourceFile | undefi } /** @internal */ -export function getSourceFileOfModule(module: Symbol) { +export function getSourceFileOfModule(module: Symbol): SourceFile | undefined { return getSourceFileOfNode(module.valueDeclaration || getNonAugmentationDeclaration(module)); } @@ -979,7 +980,7 @@ export function isPlainJsFile(file: SourceFile | undefined, checkJs: boolean | u } /** @internal */ -export function isStatementWithLocals(node: Node) { +export function isStatementWithLocals(node: Node): boolean { switch (node.kind) { case SyntaxKind.Block: case SyntaxKind.CaseBlock: @@ -1073,7 +1074,7 @@ export function nodeIsPresent(node: Node | undefined): boolean { * Tests whether `child` is a grammar error on `parent`. * @internal */ -export function isGrammarError(parent: Node, child: Node | NodeArray) { +export function isGrammarError(parent: Node, child: Node | NodeArray): boolean { if (isTypeParameterDeclaration(parent)) return child === parent.expression; if (isClassStaticBlockDeclaration(parent)) return child === parent.modifiers; if (isPropertySignature(parent)) return child === parent.initializer; @@ -1159,7 +1160,7 @@ export function insertStatementAfterCustomPrologue(to: T[], * * @internal */ -export function isRecognizedTripleSlashComment(text: string, commentPos: number, commentEnd: number) { +export function isRecognizedTripleSlashComment(text: string, commentPos: number, commentEnd: number): boolean { // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text // so that we don't end up computing comment string and doing match for all // comments if ( @@ -1180,7 +1181,7 @@ export function isRecognizedTripleSlashComment(text: string, commentPos: number, } /** @internal */ -export function isPinnedComment(text: string, start: number) { +export function isPinnedComment(text: string, start: number): boolean { return text.charCodeAt(start + 1) === CharacterCodes.asterisk && text.charCodeAt(start + 2) === CharacterCodes.exclamation; } @@ -1338,7 +1339,7 @@ function getPos(range: Node) { * * @internal */ -export function indexOfNode(nodeArray: readonly Node[], node: Node) { +export function indexOfNode(nodeArray: readonly Node[], node: Node): number { return binarySearch(nodeArray, node, getPos, compareValues); } @@ -1367,7 +1368,7 @@ export function getInternalEmitFlags(node: Node): InternalEmitFlags { export type ScriptTargetFeatures = ReadonlyMap>; /** @internal */ -export const getScriptTargetFeatures = /* @__PURE__ */ memoize((): ScriptTargetFeatures => +export const getScriptTargetFeatures: () => ScriptTargetFeatures = /* @__PURE__ */ memoize((): ScriptTargetFeatures => new Map(Object.entries({ Array: new Map(Object.entries({ es2015: [ @@ -1829,7 +1830,7 @@ export const enum GetLiteralTextFlags { } /** @internal */ -export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile | undefined, flags: GetLiteralTextFlags) { +export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile | undefined, flags: GetLiteralTextFlags): string { // If we don't need to downlevel and we can reach the original source text using // the node's parent reference, then simply get the text as it was originally written. if (sourceFile && canUseOriginalText(node, flags)) { @@ -1903,7 +1904,7 @@ function canUseOriginalText(node: LiteralLikeNode, flags: GetLiteralTextFlags): } /** @internal */ -export function getTextOfConstantValue(value: string | number) { +export function getTextOfConstantValue(value: string | number): string { return isString(value) ? `"${escapeString(value)}"` : "" + value; } @@ -1915,13 +1916,13 @@ export function makeIdentifierFromModuleName(moduleName: string): string { } /** @internal */ -export function isBlockOrCatchScoped(declaration: Declaration) { +export function isBlockOrCatchScoped(declaration: Declaration): boolean { return (getCombinedNodeFlags(declaration) & NodeFlags.BlockScoped) !== 0 || isCatchClauseVariableDeclarationOrBindingElement(declaration); } /** @internal */ -export function isCatchClauseVariableDeclarationOrBindingElement(declaration: Declaration) { +export function isCatchClauseVariableDeclarationOrBindingElement(declaration: Declaration): boolean { const node = getRootDeclaration(declaration); return node.kind === SyntaxKind.VariableDeclaration && node.parent.kind === SyntaxKind.CatchClause; } @@ -1983,7 +1984,7 @@ export function isExternalModuleAugmentation(node: Node): node is AmbientModuleD } /** @internal */ -export function isModuleAugmentationExternal(node: AmbientModuleDeclaration) { +export function isModuleAugmentationExternal(node: AmbientModuleDeclaration): boolean { // external module augmentation is a ambient module declaration that is either: // - defined in the top level scope and source file is an external module // - defined inside ambient module declaration located in the top level scope and source file not an external module @@ -1997,7 +1998,7 @@ export function isModuleAugmentationExternal(node: AmbientModuleDeclaration) { } /** @internal */ -export function getNonAugmentationDeclaration(symbol: Symbol) { +export function getNonAugmentationDeclaration(symbol: Symbol): Declaration | undefined { return symbol.declarations?.find(d => !isExternalModuleAugmentation(d) && !(isModuleDeclaration(d) && isGlobalScopeAugmentation(d))); } @@ -2006,7 +2007,7 @@ function isCommonJSContainingModuleKind(kind: ModuleKind) { } /** @internal */ -export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions) { +export function isEffectiveExternalModule(node: SourceFile, compilerOptions: CompilerOptions): boolean { return isExternalModule(node) || (isCommonJSContainingModuleKind(getEmitModuleKind(compilerOptions)) && !!node.commonJsModuleIndicator); } @@ -2015,7 +2016,7 @@ export function isEffectiveExternalModule(node: SourceFile, compilerOptions: Com * * @internal */ -export function isEffectiveStrictModeSourceFile(node: SourceFile, compilerOptions: CompilerOptions) { +export function isEffectiveStrictModeSourceFile(node: SourceFile, compilerOptions: CompilerOptions): boolean { // We can only verify strict mode for JS/TS files switch (node.scriptKind) { case ScriptKind.JS: @@ -2046,7 +2047,7 @@ export function isEffectiveStrictModeSourceFile(node: SourceFile, compilerOption } /** @internal */ -export function isAmbientPropertyDeclaration(node: PropertyDeclaration) { +export function isAmbientPropertyDeclaration(node: PropertyDeclaration): boolean { return !!(node.flags & NodeFlags.Ambient) || hasSyntacticModifier(node, ModifierFlags.Ambient); } @@ -2198,7 +2199,7 @@ export function forEachEnclosingBlockScopeContainer(node: Node, cb: (container: // Computed property names will just be emitted as "[]", where is the source // text of the expression in the computed property. /** @internal */ -export function declarationNameToString(name: DeclarationName | QualifiedName | undefined) { +export function declarationNameToString(name: DeclarationName | QualifiedName | undefined): string { return !name || getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name); } @@ -2368,7 +2369,7 @@ export function getSpanOfTokenAtPosition(sourceFile: SourceFile, pos: number): T } /** @internal */ -export function scanTokenAtPosition(sourceFile: SourceFile, pos: number) { +export function scanTokenAtPosition(sourceFile: SourceFile, pos: number): SyntaxKind { const scanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError*/ undefined, pos); scanner.scan(); return scanner.getToken(); @@ -2482,7 +2483,7 @@ export function getErrorSpanForNode(sourceFile: SourceFile, node: Node): TextSpa } /** @internal */ -export function isGlobalSourceFile(node: Node) { +export function isGlobalSourceFile(node: Node): boolean { return node.kind === SyntaxKind.SourceFile && !isExternalOrCommonJsModule(node as SourceFile); } @@ -2534,7 +2535,7 @@ export function isVarConst(node: VariableDeclaration | VariableDeclarationList): * Gets whether a bound `VariableDeclaration` or `VariableDeclarationList` is part of a `const`, `using` or `await using` declaration. * @internal */ -export function isVarConstLike(node: VariableDeclaration | VariableDeclarationList) { +export function isVarConstLike(node: VariableDeclaration | VariableDeclarationList): boolean { const blockScopeKind = getCombinedNodeFlags(node) & NodeFlags.BlockScoped; return blockScopeKind === NodeFlags.Const || blockScopeKind === NodeFlags.Using || @@ -2578,12 +2579,12 @@ export function isPrologueDirective(node: Node): node is PrologueDirective { } /** @internal */ -export function isCustomPrologue(node: Statement) { +export function isCustomPrologue(node: Statement): boolean { return !!(getEmitFlags(node) & EmitFlags.CustomPrologue); } /** @internal */ -export function isHoistedFunction(node: Statement) { +export function isHoistedFunction(node: Statement): boolean { return isCustomPrologue(node) && isFunctionDeclaration(node); } @@ -2594,19 +2595,19 @@ function isHoistedVariable(node: VariableDeclaration) { } /** @internal */ -export function isHoistedVariableStatement(node: Statement) { +export function isHoistedVariableStatement(node: Statement): boolean { return isCustomPrologue(node) && isVariableStatement(node) && every(node.declarationList.declarations, isHoistedVariable); } /** @internal */ -export function getLeadingCommentRangesOfNode(node: Node, sourceFileOfNode: SourceFile) { +export function getLeadingCommentRangesOfNode(node: Node, sourceFileOfNode: SourceFile): CommentRange[] | undefined { return node.kind !== SyntaxKind.JsxText ? getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined; } /** @internal */ -export function getJSDocCommentRanges(node: Node, text: string) { +export function getJSDocCommentRanges(node: Node, text: string): CommentRange[] | undefined { const commentRanges = (node.kind === SyntaxKind.Parameter || node.kind === SyntaxKind.TypeParameter || node.kind === SyntaxKind.FunctionExpression || @@ -2809,7 +2810,7 @@ export function forEachYieldExpression(body: Block, visitor: (expr: YieldExpress * * @internal */ -export function getRestParameterElementType(node: TypeNode | undefined) { +export function getRestParameterElementType(node: TypeNode | undefined): TypeNode | undefined { if (node && node.kind === SyntaxKind.ArrayType) { return (node as ArrayTypeNode).elementType; } @@ -2858,20 +2859,20 @@ export function isVariableLikeOrAccessor(node: Node): node is AccessorDeclaratio } /** @internal */ -export function isVariableDeclarationInVariableStatement(node: VariableDeclaration) { +export function isVariableDeclarationInVariableStatement(node: VariableDeclaration): boolean { return node.parent.kind === SyntaxKind.VariableDeclarationList && node.parent.parent.kind === SyntaxKind.VariableStatement; } /** @internal */ -export function isCommonJsExportedExpression(node: Node) { +export function isCommonJsExportedExpression(node: Node): boolean { if (!isInJSFile(node)) return false; return (isObjectLiteralExpression(node.parent) && isBinaryExpression(node.parent.parent) && getAssignmentDeclarationKind(node.parent.parent) === AssignmentDeclarationKind.ModuleExports) || isCommonJsExportPropertyAssignment(node.parent); } /** @internal */ -export function isCommonJsExportPropertyAssignment(node: Node) { +export function isCommonJsExportPropertyAssignment(node: Node): boolean { if (!isInJSFile(node)) return false; return (isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ExportsProperty); } @@ -2884,7 +2885,7 @@ export function isValidESSymbolDeclaration(node: Node): boolean { } /** @internal */ -export function introducesArgumentsExoticObject(node: Node) { +export function introducesArgumentsExoticObject(node: Node): boolean { switch (node.kind) { case SyntaxKind.MethodDeclaration: case SyntaxKind.MethodSignature: @@ -2939,7 +2940,7 @@ export function isThisTypePredicate(predicate: TypePredicate): predicate is This } /** @internal */ -export function forEachPropertyAssignment(objectLiteral: ObjectLiteralExpression | undefined, key: string, callback: (property: PropertyAssignment) => T | undefined, key2?: string) { +export function forEachPropertyAssignment(objectLiteral: ObjectLiteralExpression | undefined, key: string, callback: (property: PropertyAssignment) => T | undefined, key2?: string): T | undefined { return forEach(objectLiteral?.properties, property => { if (!isPropertyAssignment(property)) return undefined; const propName = tryGetTextOfPropertyName(property.name); @@ -2974,7 +2975,7 @@ export function getTsConfigPropArrayElementValue(tsConfigSourceFile: TsConfigSou } /** @internal */ -export function forEachTsConfigPropArray(tsConfigSourceFile: TsConfigSourceFile | undefined, propKey: string, callback: (property: PropertyAssignment) => T | undefined) { +export function forEachTsConfigPropArray(tsConfigSourceFile: TsConfigSourceFile | undefined, propKey: string, callback: (property: PropertyAssignment) => T | undefined): T | undefined { return forEachPropertyAssignment(getTsConfigObjectLiteralExpression(tsConfigSourceFile), propKey, callback); } @@ -3135,7 +3136,7 @@ export function isThisContainerOrFunctionBlock(node: Node): boolean { } /** @internal */ -export function isInTopLevelContext(node: Node) { +export function isInTopLevelContext(node: Node): boolean { // The name of a class or function declaration is a BindingIdentifier in its surrounding scope. if (isIdentifier(node) && (isClassDeclaration(node.parent) || isFunctionDeclaration(node.parent)) && node.parent.name === node) { node = node.parent; @@ -3145,7 +3146,7 @@ export function isInTopLevelContext(node: Node) { } /** @internal */ -export function getNewTargetContainer(node: Node) { +export function getNewTargetContainer(node: Node): FunctionDeclaration | ConstructorDeclaration | FunctionExpression | undefined { const container = getThisContainer(node, /*includeArrowFunctions*/ false, /*includeClassComputedPropertyName*/ false); if (container) { switch (container.kind) { @@ -3468,7 +3469,7 @@ export function isEmptyStringLiteral(node: StringLiteral): boolean { } /** @internal */ -export function isJSXTagName(node: Node) { +export function isJSXTagName(node: Node): boolean { const { parent } = node; if ( parent.kind === SyntaxKind.JsxOpeningElement || @@ -3608,7 +3609,7 @@ export function isInExpressionContext(node: Node): boolean { } /** @internal */ -export function isPartOfTypeQuery(node: Node) { +export function isPartOfTypeQuery(node: Node): boolean { while (node.kind === SyntaxKind.QualifiedName || node.kind === SyntaxKind.Identifier) { node = node.parent; } @@ -3626,13 +3627,13 @@ export function isExternalModuleImportEqualsDeclaration(node: Node): node is Imp } /** @internal */ -export function getExternalModuleImportEqualsDeclarationExpression(node: Node) { +export function getExternalModuleImportEqualsDeclarationExpression(node: Node): Expression { Debug.assert(isExternalModuleImportEqualsDeclaration(node)); return ((node as ImportEqualsDeclaration).moduleReference as ExternalModuleReference).expression; } /** @internal */ -export function getExternalModuleRequireArgument(node: Node) { +export function getExternalModuleRequireArgument(node: Node): false | StringLiteral { return isVariableDeclarationInitializedToBareOrAccessedRequire(node) && (getLeftmostAccessExpression(node.initializer) as CallExpression).arguments[0] as StringLiteral; } @@ -3662,7 +3663,7 @@ export function isInJsonFile(node: Node | undefined): boolean { } /** @internal */ -export function isSourceFileNotJson(file: SourceFile) { +export function isSourceFileNotJson(file: SourceFile): boolean { return !isJsonSourceFile(file); } @@ -3672,7 +3673,7 @@ export function isInJSDoc(node: Node | undefined): boolean { } /** @internal */ -export function isJSDocIndexSignature(node: TypeReferenceNode | ExpressionWithTypeArguments) { +export function isJSDocIndexSignature(node: TypeReferenceNode | ExpressionWithTypeArguments): boolean | undefined { return isTypeReferenceNode(node) && isIdentifier(node.typeName) && node.typeName.escapedText === "Object" && @@ -3746,7 +3747,7 @@ export function isRequireVariableStatement(node: Node): node is RequireVariableS } /** @internal */ -export function isSingleOrDoubleQuote(charCode: number) { +export function isSingleOrDoubleQuote(charCode: number): boolean { return charCode === CharacterCodes.singleQuote || charCode === CharacterCodes.doubleQuote; } @@ -3756,7 +3757,7 @@ export function isStringDoubleQuoted(str: StringLiteralLike, sourceFile: SourceF } /** @internal */ -export function isAssignmentDeclaration(decl: Declaration) { +export function isAssignmentDeclaration(decl: Declaration): boolean { return isBinaryExpression(decl) || isAccessExpression(decl) || isIdentifier(decl) || isCallExpression(decl); } @@ -3765,7 +3766,7 @@ export function isAssignmentDeclaration(decl: Declaration) { * * @internal */ -export function getEffectiveInitializer(node: HasExpressionInitializer) { +export function getEffectiveInitializer(node: HasExpressionInitializer): Expression | undefined { if ( isInJSFile(node) && node.initializer && isBinaryExpression(node.initializer) && @@ -3782,7 +3783,7 @@ export function getEffectiveInitializer(node: HasExpressionInitializer) { * * @internal */ -export function getDeclaredExpandoInitializer(node: HasExpressionInitializer) { +export function getDeclaredExpandoInitializer(node: HasExpressionInitializer): Expression | undefined { const init = getEffectiveInitializer(node); return init && getExpandoInitializer(init, isPrototypeAccess(node.name)); } @@ -3863,7 +3864,7 @@ function getDefaultedExpandoInitializer(name: Expression, initializer: Expressio } /** @internal */ -export function isDefaultedExpandoInitializer(node: BinaryExpression) { +export function isDefaultedExpandoInitializer(node: BinaryExpression): boolean | undefined { const name = isVariableDeclaration(node.parent) ? node.parent.name : isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.EqualsToken ? node.parent.left : undefined; @@ -3928,12 +3929,12 @@ export function getRightMostAssignedExpression(node: Expression): Expression { } /** @internal */ -export function isExportsIdentifier(node: Node) { +export function isExportsIdentifier(node: Node): boolean { return isIdentifier(node) && node.escapedText === "exports"; } /** @internal */ -export function isModuleIdentifier(node: Node) { +export function isModuleIdentifier(node: Node): boolean { return isIdentifier(node) && node.escapedText === "module"; } @@ -4005,7 +4006,7 @@ export function isBindableStaticNameExpression(node: Node, excludeThisKeyword?: } /** @internal */ -export function getNameOrArgument(expr: PropertyAccessExpression | LiteralLikeElementAccessExpression) { +export function getNameOrArgument(expr: PropertyAccessExpression | LiteralLikeElementAccessExpression): MemberName | (Expression & (NumericLiteral | StringLiteralLike)) { if (isPropertyAccessExpression(expr)) { return expr.name; } @@ -4114,7 +4115,7 @@ export function getAssignmentDeclarationPropertyAccessKind(lhs: AccessExpression } /** @internal */ -export function getInitializerOfBinaryExpression(expr: BinaryExpression) { +export function getInitializerOfBinaryExpression(expr: BinaryExpression): Expression { while (isBinaryExpression(expr.right)) { expr = expr.right; } @@ -4155,7 +4156,7 @@ export function setValueDeclaration(symbol: Symbol, node: Declaration): void { } /** @internal */ -export function isFunctionSymbol(symbol: Symbol | undefined) { +export function isFunctionSymbol(symbol: Symbol | undefined): boolean | undefined { if (!symbol || !symbol.valueDeclaration) { return false; } @@ -4287,25 +4288,22 @@ export function forEachImportClauseDeclaration(node: ImportClause, action: (d } /** @internal */ -export function hasQuestionToken(node: Node) { - if (node) { - switch (node.kind) { - case SyntaxKind.Parameter: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.MethodSignature: - case SyntaxKind.ShorthandPropertyAssignment: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - return (node as ParameterDeclaration | MethodDeclaration | PropertyDeclaration).questionToken !== undefined; - } +export function hasQuestionToken(node: Node): boolean { + switch (node.kind) { + case SyntaxKind.Parameter: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.MethodSignature: + case SyntaxKind.ShorthandPropertyAssignment: + case SyntaxKind.PropertyAssignment: + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.PropertySignature: + return (node as ParameterDeclaration | MethodDeclaration | PropertyDeclaration).questionToken !== undefined; } - return false; } /** @internal */ -export function isJSDocConstructSignature(node: Node) { +export function isJSDocConstructSignature(node: Node): boolean { const param = isJSDocFunctionType(node) ? firstOrUndefined(node.parameters) : undefined; const name = tryCast(param && param.name, isIdentifier); return !!name && name.escapedText === "new"; @@ -4540,7 +4538,7 @@ function ownsJSDocTag(hostNode: Node, tag: JSDocTag) { } /** @internal */ -export function getNextJSDocCommentLocation(node: Node) { +export function getNextJSDocCommentLocation(node: Node): Node | undefined { const parent = node.parent; if ( parent.kind === SyntaxKind.PropertyAssignment || @@ -4597,7 +4595,7 @@ export function getParameterSymbolFromJSDoc(node: JSDocParameterTag): Symbol | u } /** @internal */ -export function getEffectiveContainerForJSDocTemplateTag(node: JSDocTemplateTag) { +export function getEffectiveContainerForJSDocTemplateTag(node: JSDocTemplateTag): SignatureDeclaration | JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag | undefined { if (isJSDoc(node.parent) && node.parent.tags) { // A @template tag belongs to any @typedef, @callback, or @enum tags in the same comment block, if they exist. const typeAlias = find(node.parent.tags, isJSDocTypeAlias); @@ -4839,12 +4837,12 @@ function walkUp(node: Node, kind: SyntaxKind) { } /** @internal */ -export function walkUpParenthesizedTypes(node: Node) { +export function walkUpParenthesizedTypes(node: Node): Node { return walkUp(node, SyntaxKind.ParenthesizedType); } /** @internal */ -export function walkUpParenthesizedExpressions(node: Node) { +export function walkUpParenthesizedExpressions(node: Node): Node { return walkUp(node, SyntaxKind.ParenthesizedExpression); } @@ -4942,7 +4940,7 @@ export function getDeclarationFromName(name: Node): Declaration | undefined { } /** @internal */ -export function isLiteralComputedPropertyDeclarationName(node: Node) { +export function isLiteralComputedPropertyDeclarationName(node: Node): boolean { return isStringOrNumericLiteralLike(node) && node.parent.kind === SyntaxKind.ComputedPropertyName && isDeclaration(node.parent.parent); @@ -5003,7 +5001,7 @@ export function getAliasDeclarationFromName(node: EntityName): Declaration | und } /** @internal */ -export function isAliasableExpression(e: Expression) { +export function isAliasableExpression(e: Expression): boolean { return isEntityNameExpression(e) || isClassExpression(e); } @@ -5025,7 +5023,7 @@ export function getPropertyAssignmentAliasLikeExpression(node: PropertyAssignmen } /** @internal */ -export function getEffectiveBaseTypeNode(node: ClassLikeDeclaration | InterfaceDeclaration) { +export function getEffectiveBaseTypeNode(node: ClassLikeDeclaration | InterfaceDeclaration): ExpressionWithTypeArguments | undefined { const baseType = getClassExtendsHeritageElement(node); if (baseType && isInJSFile(node)) { // Prefer an @augments tag because it may have type parameters. @@ -5038,7 +5036,7 @@ export function getEffectiveBaseTypeNode(node: ClassLikeDeclaration | InterfaceD } /** @internal */ -export function getClassExtendsHeritageElement(node: ClassLikeDeclaration | InterfaceDeclaration) { +export function getClassExtendsHeritageElement(node: ClassLikeDeclaration | InterfaceDeclaration): ExpressionWithTypeArguments | undefined { const heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ExtendsKeyword); return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined; } @@ -5066,13 +5064,13 @@ export function getAllSuperTypeNodes(node: Node): readonly TypeNode[] { } /** @internal */ -export function getInterfaceBaseTypeNodes(node: InterfaceDeclaration) { +export function getInterfaceBaseTypeNodes(node: InterfaceDeclaration): NodeArray | undefined { const heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ExtendsKeyword); return heritageClause ? heritageClause.types : undefined; } /** @internal */ -export function getHeritageClause(clauses: NodeArray | undefined, kind: SyntaxKind) { +export function getHeritageClause(clauses: NodeArray | undefined, kind: SyntaxKind): HeritageClause | undefined { if (clauses) { for (const clause of clauses) { if (clause.token === kind) { @@ -5121,7 +5119,7 @@ export function isNonContextualKeyword(token: SyntaxKind): boolean { } /** @internal */ -export function isStringANonContextualKeyword(name: string) { +export function isStringANonContextualKeyword(name: string): boolean { const token = stringToToken(name); return token !== undefined && isNonContextualKeyword(token); } @@ -5148,7 +5146,7 @@ export const enum FunctionFlags { } /** @internal */ -export function getFunctionFlags(node: SignatureDeclaration | undefined) { +export function getFunctionFlags(node: SignatureDeclaration | undefined): FunctionFlags { if (!node) { return FunctionFlags.Invalid; } @@ -5414,7 +5412,7 @@ export function isNamedEvaluation(node: Node, cb?: (node: AnonymousFunctionDefin } /** @internal */ -export function isPushOrUnshiftIdentifier(node: Identifier) { +export function isPushOrUnshiftIdentifier(node: Identifier): boolean { return node.escapedText === "push" || node.escapedText === "unshift"; } @@ -5467,14 +5465,14 @@ export const enum Associativity { } /** @internal */ -export function getExpressionAssociativity(expression: Expression) { +export function getExpressionAssociativity(expression: Expression): Associativity { const operator = getOperator(expression); const hasArguments = expression.kind === SyntaxKind.NewExpression && (expression as NewExpression).arguments !== undefined; return getOperatorAssociativity(expression.kind, operator, hasArguments); } /** @internal */ -export function getOperatorAssociativity(kind: SyntaxKind, operator: SyntaxKind, hasArguments?: boolean) { +export function getOperatorAssociativity(kind: SyntaxKind, operator: SyntaxKind, hasArguments?: boolean): Associativity { switch (kind) { case SyntaxKind.NewExpression: return hasArguments ? Associativity.Left : Associativity.Right; @@ -5514,7 +5512,7 @@ export function getOperatorAssociativity(kind: SyntaxKind, operator: SyntaxKind, } /** @internal */ -export function getExpressionPrecedence(expression: Expression) { +export function getExpressionPrecedence(expression: Expression): OperatorPrecedence { const operator = getOperator(expression); const hasArguments = expression.kind === SyntaxKind.NewExpression && (expression as NewExpression).arguments !== undefined; return getOperatorPrecedence(expression.kind, operator, hasArguments); @@ -5726,7 +5724,7 @@ export const enum OperatorPrecedence { } /** @internal */ -export function getOperatorPrecedence(nodeKind: SyntaxKind, operatorKind: SyntaxKind, hasArguments?: boolean) { +export function getOperatorPrecedence(nodeKind: SyntaxKind, operatorKind: SyntaxKind, hasArguments?: boolean): OperatorPrecedence { switch (nodeKind) { case SyntaxKind.CommaListExpression: return OperatorPrecedence.Comma; @@ -5876,7 +5874,7 @@ export function getBinaryOperatorPrecedence(kind: SyntaxKind): OperatorPrecedenc } /** @internal */ -export function getSemanticJsxChildren(children: readonly JsxChild[]) { +export function getSemanticJsxChildren(children: readonly JsxChild[]): readonly JsxChild[] { return filter(children, i => { switch (i.kind) { case SyntaxKind.JsxExpression: @@ -6079,7 +6077,7 @@ function getJsxAttributeStringReplacement(c: string) { } /** @internal */ -export function escapeJsxAttributeString(s: string, quoteChar?: CharacterCodes.doubleQuote | CharacterCodes.singleQuote) { +export function escapeJsxAttributeString(s: string, quoteChar?: CharacterCodes.doubleQuote | CharacterCodes.singleQuote): string { const escapedCharsRegExp = quoteChar === CharacterCodes.singleQuote ? jsxSingleQuoteEscapedCharsRegExp : jsxDoubleQuoteEscapedCharsRegExp; return s.replace(escapedCharsRegExp, getJsxAttributeStringReplacement); @@ -6092,7 +6090,7 @@ export function escapeJsxAttributeString(s: string, quoteChar?: CharacterCodes.d * * @internal */ -export function stripQuotes(name: string) { +export function stripQuotes(name: string): string { const length = name.length; if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && isQuoteOrBacktick(name.charCodeAt(0))) { return name.substring(1, length - 1); @@ -6107,14 +6105,14 @@ function isQuoteOrBacktick(charCode: number) { } /** @internal */ -export function isIntrinsicJsxName(name: __String | string) { +export function isIntrinsicJsxName(name: __String | string): boolean { const ch = (name as string).charCodeAt(0); return (ch >= CharacterCodes.a && ch <= CharacterCodes.z) || (name as string).includes("-"); } const indentStrings: string[] = ["", " "]; /** @internal */ -export function getIndentString(level: number) { +export function getIndentString(level: number): string { // prepopulate cache const singleLevel = indentStrings[1]; for (let current = indentStrings.length; current <= level; current++) { @@ -6370,7 +6368,7 @@ export function getExternalModuleNameFromPath(host: ResolveModuleNameResolutionH } /** @internal */ -export function getOwnEmitOutputFilePath(fileName: string, host: EmitHost, extension: string) { +export function getOwnEmitOutputFilePath(fileName: string, host: EmitHost, extension: string): string { const compilerOptions = host.getCompilerOptions(); let emitOutputFilePathWithoutExtension: string; if (compilerOptions.outDir) { @@ -6384,7 +6382,7 @@ export function getOwnEmitOutputFilePath(fileName: string, host: EmitHost, exten } /** @internal */ -export function getDeclarationEmitOutputFilePath(fileName: string, host: EmitHost) { +export function getDeclarationEmitOutputFilePath(fileName: string, host: EmitHost): string { return getDeclarationEmitOutputFilePathWorker(fileName, host.getCompilerOptions(), host); } @@ -6400,7 +6398,7 @@ export function getDeclarationEmitOutputFilePathWorker(fileName: string, options } /** @internal */ -export function getDeclarationEmitExtensionForPath(path: string) { +export function getDeclarationEmitExtensionForPath(path: string): Extension.Dts | Extension.Dmts | Extension.Dcts | ".d.json.ts" { return fileExtensionIsOneOf(path, [Extension.Mjs, Extension.Mts]) ? Extension.Dmts : fileExtensionIsOneOf(path, [Extension.Cjs, Extension.Cts]) ? Extension.Dcts : fileExtensionIsOneOf(path, [Extension.Json]) ? `.d.json.ts` : // Drive-by redefinition of json declaration file output name so if it's ever enabled, it behaves well @@ -6412,7 +6410,7 @@ export function getDeclarationEmitExtensionForPath(path: string) { * * @internal */ -export function getPossibleOriginalInputExtensionForExtension(path: string) { +export function getPossibleOriginalInputExtensionForExtension(path: string): Extension[] { return fileExtensionIsOneOf(path, [Extension.Dmts, Extension.Mjs, Extension.Mts]) ? [Extension.Mts, Extension.Mjs] : fileExtensionIsOneOf(path, [Extension.Dcts, Extension.Cjs, Extension.Cts]) ? [Extension.Cts, Extension.Cjs] : fileExtensionIsOneOf(path, [`.d.json.ts`]) ? [Extension.Json] : @@ -6424,7 +6422,7 @@ export function getPossibleOriginalInputExtensionForExtension(path: string) { * * @internal */ -export function getPathsBasePath(options: CompilerOptions, host: { getCurrentDirectory?(): string; }) { +export function getPathsBasePath(options: CompilerOptions, host: { getCurrentDirectory?(): string; }): string | undefined { if (!options.paths) return undefined; return options.baseUrl ?? Debug.checkDefined(options.pathsBasePath || host.getCurrentDirectory?.(), "Encountered 'paths' without a 'baseUrl', config file, or host 'getCurrentDirectory'."); } @@ -6476,7 +6474,7 @@ export function getSourceFilesToEmit(host: EmitHost, targetSourceFile?: SourceFi * * @internal */ -export function sourceFileMayBeEmitted(sourceFile: SourceFile, host: SourceFileMayBeEmittedHost, forceDtsEmit?: boolean) { +export function sourceFileMayBeEmitted(sourceFile: SourceFile, host: SourceFileMayBeEmittedHost, forceDtsEmit?: boolean): boolean { const options = host.getCompilerOptions(); // Js files are emitted only if option is enabled if (options.noEmitForJsFiles && isSourceFileJS(sourceFile)) return false; @@ -6518,7 +6516,7 @@ function getSourceFilePathInNewDirWorker(fileName: string, newDirPath: string, c } /** @internal */ -export function writeFile(host: { writeFile: WriteFileCallback; }, diagnostics: DiagnosticCollection, fileName: string, text: string, writeByteOrderMark: boolean, sourceFiles?: readonly SourceFile[], data?: WriteFileCallbackData) { +export function writeFile(host: { writeFile: WriteFileCallback; }, diagnostics: DiagnosticCollection, fileName: string, text: string, writeByteOrderMark: boolean, sourceFiles?: readonly SourceFile[], data?: WriteFileCallbackData): void { host.writeFile( fileName, text, @@ -6564,7 +6562,7 @@ export function writeFileEnsuringDirectories( } /** @internal */ -export function getLineOfLocalPosition(sourceFile: SourceFile, pos: number) { +export function getLineOfLocalPosition(sourceFile: SourceFile, pos: number): number { const lineStarts = getLineStarts(sourceFile); return computeLineOfPosition(lineStarts, pos); } @@ -6768,7 +6766,7 @@ function emitNewLineBeforeLeadingCommentsOfPosition(lineMap: readonly number[], } /** @internal */ -export function emitNewLineBeforeLeadingCommentOfPosition(lineMap: readonly number[], writer: EmitTextWriter, pos: number, commentPos: number) { +export function emitNewLineBeforeLeadingCommentOfPosition(lineMap: readonly number[], writer: EmitTextWriter, pos: number, commentPos: number): void { // If the leading comments start on different line than the start of node, write new line if ( pos !== commentPos && @@ -6815,13 +6813,27 @@ function emitComments( } } +/** @internal */ +export interface DetachedCommentInfo { + nodePos: number; + detachedCommentEndPos: number; +} + /** * Detached comment is a comment at the top of file or function body that is separated from * the next statement by space. * * @internal */ -export function emitDetachedComments(text: string, lineMap: readonly number[], writer: EmitTextWriter, writeComment: (text: string, lineMap: readonly number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) => void, node: TextRange, newLine: string, removeComments: boolean) { +export function emitDetachedComments( + text: string, + lineMap: readonly number[], + writer: EmitTextWriter, + writeComment: (text: string, lineMap: readonly number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) => void, + node: TextRange, + newLine: string, + removeComments: boolean, +): DetachedCommentInfo | undefined { let leadingComments: CommentRange[] | undefined; let currentDetachedCommentInfo: { nodePos: number; detachedCommentEndPos: number; } | undefined; if (removeComments) { @@ -6883,7 +6895,7 @@ export function emitDetachedComments(text: string, lineMap: readonly number[], w } /** @internal */ -export function writeCommentRange(text: string, lineMap: readonly number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string) { +export function writeCommentRange(text: string, lineMap: readonly number[], writer: EmitTextWriter, commentPos: number, commentEnd: number, newLine: string): void { if (text.charCodeAt(commentPos + 1) === CharacterCodes.asterisk) { const firstCommentLineAndCharacter = computeLineAndCharacterOfPosition(lineMap, commentPos); const lineCount = lineMap.length; @@ -6981,12 +6993,12 @@ function calculateIndent(text: string, pos: number, end: number) { } /** @internal */ -export function hasEffectiveModifiers(node: Node) { +export function hasEffectiveModifiers(node: Node): boolean { return getEffectiveModifierFlags(node) !== ModifierFlags.None; } /** @internal */ -export function hasSyntacticModifiers(node: Node) { +export function hasSyntacticModifiers(node: Node): boolean { return getSyntacticModifierFlags(node) !== ModifierFlags.None; } @@ -7001,7 +7013,7 @@ export function hasSyntacticModifier(node: Node, flags: ModifierFlags): boolean } /** @internal */ -export function isStatic(node: Node) { +export function isStatic(node: Node): boolean { // https://tc39.es/ecma262/#sec-static-semantics-isstatic return isClassElement(node) && hasStaticModifier(node) || isClassStaticBlockDeclaration(node); } @@ -7154,7 +7166,7 @@ export function getSyntacticModifierFlagsNoCache(node: Node): ModifierFlags { } /** @internal */ -export function modifiersToFlags(modifiers: readonly ModifierLike[] | undefined) { +export function modifiersToFlags(modifiers: readonly ModifierLike[] | undefined): ModifierFlags { let flags = ModifierFlags.None; if (modifiers) { for (const modifier of modifiers) { @@ -7369,20 +7381,20 @@ export function isPrototypeAccess(node: Node): node is BindableStaticAccessExpre } /** @internal */ -export function isRightSideOfQualifiedNameOrPropertyAccess(node: Node) { +export function isRightSideOfQualifiedNameOrPropertyAccess(node: Node): boolean { return (node.parent.kind === SyntaxKind.QualifiedName && (node.parent as QualifiedName).right === node) || (node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent as PropertyAccessExpression).name === node) || (node.parent.kind === SyntaxKind.MetaProperty && (node.parent as MetaProperty).name === node); } /** @internal */ -export function isRightSideOfAccessExpression(node: Node) { +export function isRightSideOfAccessExpression(node: Node): boolean { return !!node.parent && (isPropertyAccessExpression(node.parent) && node.parent.name === node || isElementAccessExpression(node.parent) && node.parent.argumentExpression === node); } /** @internal */ -export function isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName(node: Node) { +export function isRightSideOfQualifiedNameOrPropertyAccessOrJSDocMemberName(node: Node): boolean { return isQualifiedName(node.parent) && node.parent.right === node || isPropertyAccessExpression(node.parent) && node.parent.name === node || isJSDocMemberName(node.parent) && node.parent.right === node; @@ -7393,7 +7405,7 @@ export function isInstanceOfExpression(node: Node): node is InstanceofExpression } /** @internal */ -export function isRightSideOfInstanceofExpression(node: Node) { +export function isRightSideOfInstanceofExpression(node: Node): boolean { return isInstanceOfExpression(node.parent) && node === node.parent.right; } @@ -7410,7 +7422,7 @@ export function isEmptyArrayLiteral(expression: Node): boolean { } /** @internal */ -export function getLocalSymbolForExportDefault(symbol: Symbol) { +export function getLocalSymbolForExportDefault(symbol: Symbol): Symbol | undefined { if (!isExportDefaultSymbol(symbol) || !symbol.declarations) return undefined; for (const decl of symbol.declarations) { if (decl.localSymbol) return decl.localSymbol; @@ -7601,7 +7613,7 @@ export function readJson(path: string, host: { readFile(fileName: string): strin } /** @internal */ -export function tryParseJson(text: string) { +export function tryParseJson(text: string): any { try { return JSON.parse(text); } @@ -7707,12 +7719,12 @@ export function createTokenRange(pos: number, token: SyntaxKind): TextRange { } /** @internal */ -export function rangeIsOnSingleLine(range: TextRange, sourceFile: SourceFile) { +export function rangeIsOnSingleLine(range: TextRange, sourceFile: SourceFile): boolean { return rangeStartIsOnSameLineAsRangeEnd(range, range, sourceFile); } /** @internal */ -export function rangeStartPositionsAreOnSameLine(range1: TextRange, range2: TextRange, sourceFile: SourceFile) { +export function rangeStartPositionsAreOnSameLine(range1: TextRange, range2: TextRange, sourceFile: SourceFile): boolean { return positionsAreOnSameLine( getStartPositionOfRange(range1, sourceFile, /*includeComments*/ false), getStartPositionOfRange(range2, sourceFile, /*includeComments*/ false), @@ -7721,28 +7733,28 @@ export function rangeStartPositionsAreOnSameLine(range1: TextRange, range2: Text } /** @internal */ -export function rangeEndPositionsAreOnSameLine(range1: TextRange, range2: TextRange, sourceFile: SourceFile) { +export function rangeEndPositionsAreOnSameLine(range1: TextRange, range2: TextRange, sourceFile: SourceFile): boolean { return positionsAreOnSameLine(range1.end, range2.end, sourceFile); } /** @internal @knipignore */ -export function rangeStartIsOnSameLineAsRangeEnd(range1: TextRange, range2: TextRange, sourceFile: SourceFile) { +export function rangeStartIsOnSameLineAsRangeEnd(range1: TextRange, range2: TextRange, sourceFile: SourceFile): boolean { return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile, /*includeComments*/ false), range2.end, sourceFile); } /** @internal */ -export function rangeEndIsOnSameLineAsRangeStart(range1: TextRange, range2: TextRange, sourceFile: SourceFile) { +export function rangeEndIsOnSameLineAsRangeStart(range1: TextRange, range2: TextRange, sourceFile: SourceFile): boolean { return positionsAreOnSameLine(range1.end, getStartPositionOfRange(range2, sourceFile, /*includeComments*/ false), sourceFile); } /** @internal */ -export function getLinesBetweenRangeEndAndRangeStart(range1: TextRange, range2: TextRange, sourceFile: SourceFile, includeSecondRangeComments: boolean) { +export function getLinesBetweenRangeEndAndRangeStart(range1: TextRange, range2: TextRange, sourceFile: SourceFile, includeSecondRangeComments: boolean): number { const range2Start = getStartPositionOfRange(range2, sourceFile, includeSecondRangeComments); return getLinesBetweenPositions(sourceFile, range1.end, range2Start); } /** @internal @knipignore */ -export function getLinesBetweenRangeEndPositions(range1: TextRange, range2: TextRange, sourceFile: SourceFile) { +export function getLinesBetweenRangeEndPositions(range1: TextRange, range2: TextRange, sourceFile: SourceFile): number { return getLinesBetweenPositions(sourceFile, range1.end, range2.end); } @@ -7752,24 +7764,24 @@ export function isNodeArrayMultiLine(list: NodeArray, sourceFile: SourceFi } /** @internal */ -export function positionsAreOnSameLine(pos1: number, pos2: number, sourceFile: SourceFile) { +export function positionsAreOnSameLine(pos1: number, pos2: number, sourceFile: SourceFile): boolean { return getLinesBetweenPositions(sourceFile, pos1, pos2) === 0; } /** @internal @knipignore */ -export function getStartPositionOfRange(range: TextRange, sourceFile: SourceFile, includeComments: boolean) { +export function getStartPositionOfRange(range: TextRange, sourceFile: SourceFile, includeComments: boolean): number { return positionIsSynthesized(range.pos) ? -1 : skipTrivia(sourceFile.text, range.pos, /*stopAfterLineBreak*/ false, includeComments); } /** @internal */ -export function getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(pos: number, stopPos: number, sourceFile: SourceFile, includeComments?: boolean) { +export function getLinesBetweenPositionAndPrecedingNonWhitespaceCharacter(pos: number, stopPos: number, sourceFile: SourceFile, includeComments?: boolean): number { const startPos = skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments); const prevPos = getPreviousNonWhitespacePosition(startPos, stopPos, sourceFile); return getLinesBetweenPositions(sourceFile, prevPos ?? stopPos, startPos); } /** @internal */ -export function getLinesBetweenPositionAndNextNonWhitespaceCharacter(pos: number, stopPos: number, sourceFile: SourceFile, includeComments?: boolean) { +export function getLinesBetweenPositionAndNextNonWhitespaceCharacter(pos: number, stopPos: number, sourceFile: SourceFile, includeComments?: boolean): number { const nextPos = skipTrivia(sourceFile.text, pos, /*stopAfterLineBreak*/ false, includeComments); return getLinesBetweenPositions(sourceFile, pos, Math.min(stopPos, nextPos)); } @@ -7788,7 +7800,7 @@ function getPreviousNonWhitespacePosition(pos: number, stopPos = 0, sourceFile: * * @internal */ -export function isDeclarationNameOfEnumOrNamespace(node: Identifier) { +export function isDeclarationNameOfEnumOrNamespace(node: Identifier): boolean { const parseNode = getParseTreeNode(node); if (parseNode) { switch (parseNode.parent.kind) { @@ -7801,7 +7813,7 @@ export function isDeclarationNameOfEnumOrNamespace(node: Identifier) { } /** @internal */ -export function getInitializedVariables(node: VariableDeclarationList) { +export function getInitializedVariables(node: VariableDeclarationList): readonly InitializedVariableDeclaration[] { return filter(node.declarations, isInitializedVariable); } @@ -7811,13 +7823,13 @@ export function isInitializedVariable(node: Node): node is InitializedVariableDe } /** @internal */ -export function isWatchSet(options: CompilerOptions) { +export function isWatchSet(options: CompilerOptions): boolean | undefined { // Firefox has Object.prototype.watch return options.watch && hasProperty(options, "watch"); } /** @internal */ -export function closeFileWatcher(watcher: FileWatcher) { +export function closeFileWatcher(watcher: FileWatcher): void { watcher.close(); } @@ -7850,7 +7862,7 @@ export function getDeclarationModifierFlagsFromSymbol(s: Symbol, isWrite = false } /** @internal */ -export function skipAlias(symbol: Symbol, checker: TypeChecker) { +export function skipAlias(symbol: Symbol, checker: TypeChecker): Symbol { return symbol.flags & SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol; } @@ -7864,12 +7876,12 @@ export function getCombinedLocalAndExportSymbolFlags(symbol: Symbol): SymbolFlag } /** @internal */ -export function isWriteOnlyAccess(node: Node) { +export function isWriteOnlyAccess(node: Node): boolean { return accessKind(node) === AccessKind.Write; } /** @internal */ -export function isWriteAccess(node: Node) { +export function isWriteAccess(node: Node): boolean { return accessKind(node) !== AccessKind.Read; } @@ -7954,7 +7966,7 @@ export function compareDataObjects(dst: any, src: any): boolean { * * @internal */ -export function clearMap(map: { forEach: Map["forEach"]; clear: Map["clear"]; }, onDeleteValue: (valueInMap: T, key: K) => void) { +export function clearMap(map: { forEach: Map["forEach"]; clear: Map["clear"]; }, onDeleteValue: (valueInMap: T, key: K) => void): void { // Remove all map.forEach(onDeleteValue); map.clear(); @@ -8146,7 +8158,7 @@ export function isAccessExpression(node: Node): node is AccessExpression { } /** @internal */ -export function getNameOfAccessExpression(node: AccessExpression) { +export function getNameOfAccessExpression(node: AccessExpression): Expression { if (node.kind === SyntaxKind.PropertyAccessExpression) { return node.name; } @@ -8206,7 +8218,7 @@ export function forEachNameInAccessChainWalkingLeft(name: MemberName | String } /** @internal */ -export function getLeftmostExpression(node: Expression, stopAtCallExpressions: boolean) { +export function getLeftmostExpression(node: Expression, stopAtCallExpressions: boolean): Expression { while (true) { switch (node.kind) { case SyntaxKind.PostfixUnaryExpression: @@ -8257,7 +8269,7 @@ export interface ObjectAllocator { getSourceMapSourceConstructor(): new (fileName: string, text: string, skipTrivia?: (pos: number) => number) => SourceMapSource; } -function Symbol(this: Symbol, flags: SymbolFlags, name: __String) { +function Symbol(this: Symbol, flags: SymbolFlags, name: __String): void { // Note: if modifying this, be sure to update SymbolObject in src/services/services.ts this.flags = flags; this.escapedName = name; @@ -8275,7 +8287,7 @@ function Symbol(this: Symbol, flags: SymbolFlags, name: __String) { (this as any).links = undefined; // used by TransientSymbol } -function Type(this: Type, checker: TypeChecker, flags: TypeFlags) { +function Type(this: Type, checker: TypeChecker, flags: TypeFlags): void { // Note: if modifying this, be sure to update TypeObject in src/services/services.ts this.flags = flags; if (Debug.isDebugging || tracing) { @@ -8283,7 +8295,7 @@ function Type(this: Type, checker: TypeChecker, flags: TypeFlags) { } } -function Signature(this: Signature, checker: TypeChecker, flags: SignatureFlags) { +function Signature(this: Signature, checker: TypeChecker, flags: SignatureFlags): void { // Note: if modifying this, be sure to update SignatureObject in src/services/services.ts this.flags = flags; if (Debug.isDebugging) { @@ -8291,7 +8303,7 @@ function Signature(this: Signature, checker: TypeChecker, flags: SignatureFlags) } } -function Node(this: Mutable, kind: SyntaxKind, pos: number, end: number) { +function Node(this: Mutable, kind: SyntaxKind, pos: number, end: number): void { // Note: if modifying this, be sure to update NodeObject in src/services/services.ts this.pos = pos; this.end = end; @@ -8305,7 +8317,7 @@ function Node(this: Mutable, kind: SyntaxKind, pos: number, end: number) { this.emitNode = undefined; } -function Token(this: Mutable, kind: SyntaxKind, pos: number, end: number) { +function Token(this: Mutable, kind: SyntaxKind, pos: number, end: number): void { // Note: if modifying this, be sure to update TokenOrIdentifierObject in src/services/services.ts this.pos = pos; this.end = end; @@ -8317,7 +8329,7 @@ function Token(this: Mutable, kind: SyntaxKind, pos: number, end: number) this.emitNode = undefined; } -function Identifier(this: Mutable, kind: SyntaxKind, pos: number, end: number) { +function Identifier(this: Mutable, kind: SyntaxKind, pos: number, end: number): void { // Note: if modifying this, be sure to update TokenOrIdentifierObject in src/services/services.ts this.pos = pos; this.end = end; @@ -8330,7 +8342,7 @@ function Identifier(this: Mutable, kind: SyntaxKind, pos: number, end: num this.emitNode = undefined; } -function SourceMapSource(this: SourceMapSource, fileName: string, text: string, skipTrivia?: (pos: number) => number) { +function SourceMapSource(this: SourceMapSource, fileName: string, text: string, skipTrivia?: (pos: number) => number): void { // Note: if modifying this, be sure to update SourceMapSourceObject in src/services/services.ts this.fileName = fileName; this.text = text; @@ -8357,13 +8369,13 @@ const objectAllocatorPatchers: ((objectAllocator: ObjectAllocator) => void)[] = * @internal * @knipignore */ -export function addObjectAllocatorPatcher(fn: (objectAllocator: ObjectAllocator) => void) { +export function addObjectAllocatorPatcher(fn: (objectAllocator: ObjectAllocator) => void): void { objectAllocatorPatchers.push(fn); fn(objectAllocator); } /** @internal */ -export function setObjectAllocator(alloc: ObjectAllocator) { +export function setObjectAllocator(alloc: ObjectAllocator): void { Object.assign(objectAllocator, alloc); forEach(objectAllocatorPatchers, fn => fn(objectAllocator)); } @@ -8376,21 +8388,21 @@ export function formatStringFromArgs(text: string, args: DiagnosticArguments): s let localizedDiagnosticMessages: MapLike | undefined; /** @internal */ -export function setLocalizedDiagnosticMessages(messages: MapLike | undefined) { +export function setLocalizedDiagnosticMessages(messages: MapLike | undefined): void { localizedDiagnosticMessages = messages; } /** @internal */ // If the localized messages json is unset, and if given function use it to set the json -export function maybeSetLocalizedDiagnosticMessages(getMessages: undefined | (() => MapLike | undefined)) { +export function maybeSetLocalizedDiagnosticMessages(getMessages: undefined | (() => MapLike | undefined)): void { if (!localizedDiagnosticMessages && getMessages) { localizedDiagnosticMessages = getMessages(); } } /** @internal */ -export function getLocaleSpecificMessage(message: DiagnosticMessage) { +export function getLocaleSpecificMessage(message: DiagnosticMessage): string { return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message; } @@ -8734,7 +8746,7 @@ function messageTextEqualityComparer(m1: string | DiagnosticMessageChain, m2: st } /** @internal */ -export function getLanguageVariant(scriptKind: ScriptKind) { +export function getLanguageVariant(scriptKind: ScriptKind): LanguageVariant { // .tsx and .jsx files are treated as jsx language variant. return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard; } @@ -8800,7 +8812,7 @@ export function getSetExternalModuleIndicator(options: CompilerOptions): (file: * Returns true if an `import` and a `require` of the same module specifier * can resolve to a different file. */ -export function importSyntaxAffectsModuleResolution(options: CompilerOptions) { +export function importSyntaxAffectsModuleResolution(options: CompilerOptions): boolean { const moduleResolution = getEmitModuleResolutionKind(options); return ModuleResolutionKind.Node16 <= moduleResolution && moduleResolution <= ModuleResolutionKind.NodeNext || getResolvePackageJsonExports(options) @@ -8819,8 +8831,7 @@ function createComputedCompilerOptions { @@ -8836,7 +8847,7 @@ export const computedOptions = createComputedCompilerOptions({ computeValue: (compilerOptions): ModuleKind => { return typeof compilerOptions.module === "number" ? compilerOptions.module : - computedOptions.target.computeValue(compilerOptions) >= ScriptTarget.ES2015 ? ModuleKind.ES2015 : ModuleKind.CommonJS; + _computedOptions.target.computeValue(compilerOptions) >= ScriptTarget.ES2015 ? ModuleKind.ES2015 : ModuleKind.CommonJS; }, }, moduleResolution: { @@ -8844,7 +8855,7 @@ export const computedOptions = createComputedCompilerOptions({ computeValue: (compilerOptions): ModuleResolutionKind => { let moduleResolution = compilerOptions.moduleResolution; if (moduleResolution === undefined) { - switch (computedOptions.module.computeValue(compilerOptions)) { + switch (_computedOptions.module.computeValue(compilerOptions)) { case ModuleKind.CommonJS: moduleResolution = ModuleResolutionKind.Node10; break; @@ -8869,8 +8880,8 @@ export const computedOptions = createComputedCompilerOptions({ dependencies: ["module", "target"], computeValue: (compilerOptions): ModuleDetectionKind => { return compilerOptions.moduleDetection || - (computedOptions.module.computeValue(compilerOptions) === ModuleKind.Node16 || - computedOptions.module.computeValue(compilerOptions) === ModuleKind.NodeNext ? ModuleDetectionKind.Force : ModuleDetectionKind.Auto); + (_computedOptions.module.computeValue(compilerOptions) === ModuleKind.Node16 || + _computedOptions.module.computeValue(compilerOptions) === ModuleKind.NodeNext ? ModuleDetectionKind.Force : ModuleDetectionKind.Auto); }, }, isolatedModules: { @@ -8885,7 +8896,7 @@ export const computedOptions = createComputedCompilerOptions({ if (compilerOptions.esModuleInterop !== undefined) { return compilerOptions.esModuleInterop; } - switch (computedOptions.module.computeValue(compilerOptions)) { + switch (_computedOptions.module.computeValue(compilerOptions)) { case ModuleKind.Node16: case ModuleKind.NodeNext: case ModuleKind.Preserve: @@ -8900,15 +8911,15 @@ export const computedOptions = createComputedCompilerOptions({ if (compilerOptions.allowSyntheticDefaultImports !== undefined) { return compilerOptions.allowSyntheticDefaultImports; } - return computedOptions.esModuleInterop.computeValue(compilerOptions) - || computedOptions.module.computeValue(compilerOptions) === ModuleKind.System - || computedOptions.moduleResolution.computeValue(compilerOptions) === ModuleResolutionKind.Bundler; + return _computedOptions.esModuleInterop.computeValue(compilerOptions) + || _computedOptions.module.computeValue(compilerOptions) === ModuleKind.System + || _computedOptions.moduleResolution.computeValue(compilerOptions) === ModuleResolutionKind.Bundler; }, }, resolvePackageJsonExports: { dependencies: ["moduleResolution"], computeValue: (compilerOptions): boolean => { - const moduleResolution = computedOptions.moduleResolution.computeValue(compilerOptions); + const moduleResolution = _computedOptions.moduleResolution.computeValue(compilerOptions); if (!moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution)) { return false; } @@ -8927,7 +8938,7 @@ export const computedOptions = createComputedCompilerOptions({ resolvePackageJsonImports: { dependencies: ["moduleResolution", "resolvePackageJsonExports"], computeValue: (compilerOptions): boolean => { - const moduleResolution = computedOptions.moduleResolution.computeValue(compilerOptions); + const moduleResolution = _computedOptions.moduleResolution.computeValue(compilerOptions); if (!moduleResolutionSupportsPackageJsonExportsAndImports(moduleResolution)) { return false; } @@ -8949,7 +8960,7 @@ export const computedOptions = createComputedCompilerOptions({ if (compilerOptions.resolveJsonModule !== undefined) { return compilerOptions.resolveJsonModule; } - return computedOptions.moduleResolution.computeValue(compilerOptions) === ModuleResolutionKind.Bundler; + return _computedOptions.moduleResolution.computeValue(compilerOptions) === ModuleResolutionKind.Bundler; }, }, declaration: { @@ -8961,7 +8972,7 @@ export const computedOptions = createComputedCompilerOptions({ preserveConstEnums: { dependencies: ["isolatedModules", "verbatimModuleSyntax"], computeValue: (compilerOptions): boolean => { - return !!(compilerOptions.preserveConstEnums || computedOptions.isolatedModules.computeValue(compilerOptions)); + return !!(compilerOptions.preserveConstEnums || _computedOptions.isolatedModules.computeValue(compilerOptions)); }, }, incremental: { @@ -8973,7 +8984,7 @@ export const computedOptions = createComputedCompilerOptions({ declarationMap: { dependencies: ["declaration", "composite"], computeValue: (compilerOptions): boolean => { - return !!(compilerOptions.declarationMap && computedOptions.declaration.computeValue(compilerOptions)); + return !!(compilerOptions.declarationMap && _computedOptions.declaration.computeValue(compilerOptions)); }, }, allowJs: { @@ -8986,7 +8997,7 @@ export const computedOptions = createComputedCompilerOptions({ dependencies: ["target", "module"], computeValue: (compilerOptions): boolean => { return compilerOptions.useDefineForClassFields === undefined - ? computedOptions.target.computeValue(compilerOptions) >= ScriptTarget.ES2022 + ? _computedOptions.target.computeValue(compilerOptions) >= ScriptTarget.ES2022 : compilerOptions.useDefineForClassFields; }, }, @@ -9047,45 +9058,48 @@ export const computedOptions = createComputedCompilerOptions({ }); /** @internal */ -export const getEmitScriptTarget = computedOptions.target.computeValue; +export const computedOptions: Record CompilerOptionsValue; }> = _computedOptions; + +/** @internal */ +export const getEmitScriptTarget: (compilerOptions: CompilerOptions) => ScriptTarget = _computedOptions.target.computeValue; /** @internal */ -export const getEmitModuleKind = computedOptions.module.computeValue; +export const getEmitModuleKind: (compilerOptions: Pick) => ModuleKind = _computedOptions.module.computeValue; /** @internal */ -export const getEmitModuleResolutionKind = computedOptions.moduleResolution.computeValue; +export const getEmitModuleResolutionKind: (compilerOptions: CompilerOptions) => ModuleResolutionKind = _computedOptions.moduleResolution.computeValue; /** @internal @knipignore */ -export const getEmitModuleDetectionKind = computedOptions.moduleDetection.computeValue; +export const getEmitModuleDetectionKind: (compilerOptions: CompilerOptions) => ModuleDetectionKind = _computedOptions.moduleDetection.computeValue; /** @internal */ -export const getIsolatedModules = computedOptions.isolatedModules.computeValue; +export const getIsolatedModules: (compilerOptions: CompilerOptions) => boolean = _computedOptions.isolatedModules.computeValue; /** @internal */ -export const getESModuleInterop = computedOptions.esModuleInterop.computeValue; +export const getESModuleInterop: (compilerOptions: CompilerOptions) => boolean = _computedOptions.esModuleInterop.computeValue; /** @internal */ -export const getAllowSyntheticDefaultImports = computedOptions.allowSyntheticDefaultImports.computeValue; +export const getAllowSyntheticDefaultImports: (compilerOptions: CompilerOptions) => boolean = _computedOptions.allowSyntheticDefaultImports.computeValue; /** @internal */ -export const getResolvePackageJsonExports = computedOptions.resolvePackageJsonExports.computeValue; +export const getResolvePackageJsonExports: (compilerOptions: CompilerOptions) => boolean = _computedOptions.resolvePackageJsonExports.computeValue; /** @internal */ -export const getResolvePackageJsonImports = computedOptions.resolvePackageJsonImports.computeValue; +export const getResolvePackageJsonImports: (compilerOptions: CompilerOptions) => boolean = _computedOptions.resolvePackageJsonImports.computeValue; /** @internal */ -export const getResolveJsonModule = computedOptions.resolveJsonModule.computeValue; +export const getResolveJsonModule: (compilerOptions: CompilerOptions) => boolean = _computedOptions.resolveJsonModule.computeValue; /** @internal */ -export const getEmitDeclarations = computedOptions.declaration.computeValue; +export const getEmitDeclarations: (compilerOptions: CompilerOptions) => boolean = _computedOptions.declaration.computeValue; /** @internal */ -export const shouldPreserveConstEnums = computedOptions.preserveConstEnums.computeValue; +export const shouldPreserveConstEnums: (compilerOptions: CompilerOptions) => boolean = _computedOptions.preserveConstEnums.computeValue; /** @internal */ -export const isIncrementalCompilation = computedOptions.incremental.computeValue; +export const isIncrementalCompilation: (compilerOptions: CompilerOptions) => boolean = _computedOptions.incremental.computeValue; /** @internal */ -export const getAreDeclarationMapsEnabled = computedOptions.declarationMap.computeValue; +export const getAreDeclarationMapsEnabled: (compilerOptions: CompilerOptions) => boolean = _computedOptions.declarationMap.computeValue; /** @internal */ -export const getAllowJSCompilerOption = computedOptions.allowJs.computeValue; +export const getAllowJSCompilerOption: (compilerOptions: CompilerOptions) => boolean = _computedOptions.allowJs.computeValue; /** @internal */ -export const getUseDefineForClassFields = computedOptions.useDefineForClassFields.computeValue; +export const getUseDefineForClassFields: (compilerOptions: CompilerOptions) => boolean = _computedOptions.useDefineForClassFields.computeValue; /** @internal */ -export function emitModuleKindIsNonNodeESM(moduleKind: ModuleKind) { +export function emitModuleKindIsNonNodeESM(moduleKind: ModuleKind): boolean { return moduleKind >= ModuleKind.ES2015 && moduleKind <= ModuleKind.ESNext; } /** @internal */ -export function hasJsonModuleEmitEnabled(options: CompilerOptions) { +export function hasJsonModuleEmitEnabled(options: CompilerOptions): boolean { switch (getEmitModuleKind(options)) { case ModuleKind.None: case ModuleKind.System: @@ -9134,7 +9148,7 @@ export function getNameOfScriptTarget(scriptTarget: ScriptTarget): string | unde } /** @internal */ -export function getEmitStandardClassFields(compilerOptions: CompilerOptions) { +export function getEmitStandardClassFields(compilerOptions: CompilerOptions): boolean { return compilerOptions.useDefineForClassFields !== false && getEmitScriptTarget(compilerOptions) >= ScriptTarget.ES2022; } @@ -9185,7 +9199,7 @@ export function getJSXImplicitImportBase(compilerOptions: CompilerOptions, file? } /** @internal */ -export function getJSXRuntimeImport(base: string | undefined, options: CompilerOptions) { +export function getJSXRuntimeImport(base: string | undefined, options: CompilerOptions): string | undefined { return base ? `${base}/${options.jsx === JsxEmit.ReactJSXDev ? "jsx-dev-runtime" : "jsx-runtime"}` : undefined; } @@ -9352,7 +9366,7 @@ export function tryRemoveDirectoryPrefix(path: string, dirPath: string, getCanon const reservedCharacterPattern = /[^\w\s/]/g; /** @internal */ -export function regExpEscape(text: string) { +export function regExpEscape(text: string): string { return text.replace(reservedCharacterPattern, escapeRegExpCharacter); } @@ -9444,7 +9458,7 @@ export function isImplicitGlob(lastPathComponent: string): boolean { } /** @internal */ -export function getPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude") { +export function getPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude"): string | undefined { const pattern = spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]); return pattern && `^(${pattern})${usage === "exclude" ? "($|/)" : "$"}`; } @@ -9900,7 +9914,7 @@ function getRequiresAtTopOfFile(sourceFile: SourceFile): readonly RequireOrImpor } /** @internal */ -export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]) { +export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: readonly FileExtensionInfo[]): boolean { if (!fileName) return false; const supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions); @@ -9918,7 +9932,7 @@ function numberOfDirectorySeparators(str: string) { } /** @internal */ -export function compareNumberOfDirectorySeparators(path1: string, path2: string) { +export function compareNumberOfDirectorySeparators(path1: string, path2: string): Comparison { return compareValues( numberOfDirectorySeparators(path1), numberOfDirectorySeparators(path2), @@ -10036,7 +10050,7 @@ export function extensionIsTS(ext: string): boolean { } /** @internal */ -export function resolutionExtensionIsTSOrJson(ext: string) { +export function resolutionExtensionIsTSOrJson(ext: string): boolean { return extensionIsTS(ext) || ext === Extension.Json; } @@ -10062,7 +10076,7 @@ export function tryGetExtensionFromPath(path: string): Extension | undefined { } /** @internal */ -export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { +export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions): boolean | undefined { return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; } @@ -10155,7 +10169,7 @@ export function skipTypeChecking( sourceFile: SourceFile, options: CompilerOptions, host: HostWithIsSourceOfProjectReferenceRedirect, -) { +): boolean { return skipTypeCheckingWorker(sourceFile, options, host, /*ignoreNoCheck*/ false); } @@ -10164,7 +10178,7 @@ export function skipTypeCheckingIgnoringNoCheck( sourceFile: SourceFile, options: CompilerOptions, host: HostWithIsSourceOfProjectReferenceRedirect, -) { +): boolean { return skipTypeCheckingWorker(sourceFile, options, host, /*ignoreNoCheck*/ true); } @@ -10185,7 +10199,7 @@ function skipTypeCheckingWorker( } /** @internal */ -export function canIncludeBindAndCheckDiagnostics(sourceFile: SourceFile, options: CompilerOptions) { +export function canIncludeBindAndCheckDiagnostics(sourceFile: SourceFile, options: CompilerOptions): boolean { if (!!sourceFile.checkJsDirective && sourceFile.checkJsDirective.enabled === false) return false; if ( sourceFile.scriptKind === ScriptKind.TS || @@ -10383,7 +10397,7 @@ export function isIdentifierTypeReference(node: Node): node is TypeReferenceNode } /** @internal */ -export function arrayIsHomogeneous(array: readonly T[], comparer: EqualityComparer = equateValues) { +export function arrayIsHomogeneous(array: readonly T[], comparer: EqualityComparer = equateValues): boolean { if (array.length < 2) return true; const first = array[0]; for (let i = 1, length = array.length; i < length; i++) { @@ -10398,7 +10412,7 @@ export function arrayIsHomogeneous(array: readonly T[], comparer: EqualityCom * * @internal */ -export function setTextRangePos(range: T, pos: number) { +export function setTextRangePos(range: T, pos: number): T { (range as TextRange).pos = pos; return range; } @@ -10408,7 +10422,7 @@ export function setTextRangePos(range: T, pos: numb * * @internal */ -export function setTextRangeEnd(range: T, end: number) { +export function setTextRangeEnd(range: T, end: number): T { (range as TextRange).end = end; return range; } @@ -10418,7 +10432,7 @@ export function setTextRangeEnd(range: T, end: numb * * @internal */ -export function setTextRangePosEnd(range: T, pos: number, end: number) { +export function setTextRangePosEnd(range: T, pos: number, end: number): T { return setTextRangeEnd(setTextRangePos(range, pos), end); } @@ -10428,7 +10442,7 @@ export function setTextRangePosEnd(range: T, pos: n * * @internal */ -export function setTextRangePosWidth(range: T, pos: number, width: number) { +export function setTextRangePosWidth(range: T, pos: number, width: number): T { return setTextRangePosEnd(range, pos, pos + width); } @@ -10511,7 +10525,7 @@ function isPackedElement(node: Expression) { * * @internal */ -export function isPackedArrayLiteral(node: Expression) { +export function isPackedArrayLiteral(node: Expression): boolean { return isArrayLiteralExpression(node) && every(node.elements, isPackedElement); } @@ -10558,7 +10572,7 @@ export function expressionResultIsUnused(node: Expression): boolean { } /** @internal */ -export function containsIgnoredPath(path: string) { +export function containsIgnoredPath(path: string): boolean { return some(ignoredPaths, p => path.includes(p)); } @@ -10634,7 +10648,7 @@ export function getContainingNodeArray(node: Node): NodeArray | undefined } /** @internal */ -export function hasContextSensitiveParameters(node: FunctionLikeDeclaration) { +export function hasContextSensitiveParameters(node: FunctionLikeDeclaration): boolean { // Functions with type parameters are not context sensitive. if (!node.typeParameters) { // Functions with any parameters that lack type annotations are context sensitive. @@ -10659,7 +10673,7 @@ export function isInfinityOrNaNString(name: string | __String): boolean { } /** @internal */ -export function isCatchClauseVariableDeclaration(node: Node) { +export function isCatchClauseVariableDeclaration(node: Node): boolean { return node.kind === SyntaxKind.VariableDeclaration && node.parent.kind === SyntaxKind.CatchClause; } @@ -10674,7 +10688,7 @@ export function escapeSnippetText(text: string): string { } /** @internal */ -export function isNumericLiteralName(name: string | __String) { +export function isNumericLiteralName(name: string | __String): boolean { // The intent of numeric names is that // - they are names with text in a numeric form, and that // - setting properties/indexing with them is always equivalent to doing so with the numeric literal 'numLit', @@ -10700,7 +10714,7 @@ export function isNumericLiteralName(name: string | __String) { } /** @internal */ -export function createPropertyNameNodeForIdentifierOrLiteral(name: string, target: ScriptTarget, singleQuote: boolean, stringNamed: boolean, isMethod: boolean) { +export function createPropertyNameNodeForIdentifierOrLiteral(name: string, target: ScriptTarget, singleQuote: boolean, stringNamed: boolean, isMethod: boolean): Identifier | StringLiteral | NumericLiteral { const isMethodNamedNew = isMethod && name === "new"; return !isMethodNamedNew && isIdentifierText(name, target) ? factory.createIdentifier(name) : !stringNamed && !isMethodNamedNew && isNumericLiteralName(name) && +name >= 0 ? factory.createNumericLiteral(+name) : @@ -10832,7 +10846,7 @@ export function hasTabstop(node: Node): boolean { } /** @internal */ -export function isJSDocOptionalParameter(node: ParameterDeclaration) { +export function isJSDocOptionalParameter(node: ParameterDeclaration): boolean { return isInJSFile(node) && ( // node.type should only be a JSDocOptionalType when node is a parameter of a JSDocFunctionType node.type && node.type.kind === SyntaxKind.JSDocOptionalType @@ -10869,12 +10883,12 @@ export function isJSDocSatisfiesExpression(node: Node): node is JSDocSatisfiesEx } /** @internal */ -export function getJSDocSatisfiesExpressionType(node: JSDocSatisfiesExpression) { +export function getJSDocSatisfiesExpressionType(node: JSDocSatisfiesExpression): TypeNode { return Debug.checkDefined(tryGetJSDocSatisfiesTypeNode(node)); } /** @internal */ -export function tryGetJSDocSatisfiesTypeNode(node: Node) { +export function tryGetJSDocSatisfiesTypeNode(node: Node): TypeNode | undefined { const tag = getJSDocSatisfiesTag(node); return tag && tag.typeExpression && tag.typeExpression.type; } @@ -10907,7 +10921,7 @@ export function getTextOfJsxNamespacedName(node: JsxNamespacedName) { } /** @internal */ -export function intrinsicTagNameToString(node: Identifier | JsxNamespacedName) { +export function intrinsicTagNameToString(node: Identifier | JsxNamespacedName): string { return isIdentifier(node) ? idText(node) : getTextOfJsxNamespacedName(node); } @@ -10939,7 +10953,7 @@ export function isExpandoPropertyDeclaration(declaration: Declaration | undefine } /** @internal */ -export function hasResolutionModeOverride(node: ImportTypeNode | ImportDeclaration | ExportDeclaration | JSDocImportTag | undefined) { +export function hasResolutionModeOverride(node: ImportTypeNode | ImportDeclaration | ExportDeclaration | JSDocImportTag | undefined): boolean { if (node === undefined) { return false; } @@ -10958,7 +10972,7 @@ export function replaceFirstStar(s: string, replacement: string): string { } /** @internal */ -export function getNameFromImportAttribute(node: ImportAttribute) { +export function getNameFromImportAttribute(node: ImportAttribute): __String { return isIdentifier(node.name) ? node.name.escapedText : escapeLeadingUnderscores(node.name.text); } @@ -11069,7 +11083,10 @@ export function evaluatorResult(value: T, } /** @internal */ -export function createEvaluator({ evaluateElementAccessExpression, evaluateEntityNameExpression }: EvaluationResolver) { +export function createEvaluator({ evaluateElementAccessExpression, evaluateEntityNameExpression }: EvaluationResolver): { + (expr: TemplateExpression, location?: Declaration): EvaluatorResult; + (expr: Expression, location?: Declaration): EvaluatorResult; +} { function evaluate(expr: TemplateExpression, location?: Declaration): EvaluatorResult; function evaluate(expr: Expression, location?: Declaration): EvaluatorResult; function evaluate(expr: Expression, location?: Declaration): EvaluatorResult { @@ -11199,7 +11216,7 @@ export function createEvaluator({ evaluateElementAccessExpression, evaluateEntit } /** @internal */ -export function isConstAssertion(location: Node) { +export function isConstAssertion(location: Node): boolean { return (isAssertionExpression(location) && isConstTypeReference(location.type)) || (isJSDocTypeTag(location) && isConstTypeReference(location.typeExpression)); } @@ -11214,6 +11231,32 @@ export function findConstructorDeclaration(node: ClassLikeDeclaration): Construc } } +/** @internal */ +export interface NameResolverOptions { + compilerOptions: CompilerOptions; + getSymbolOfDeclaration: (node: Declaration) => Symbol; + error: (location: Node | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments) => void; + globals: SymbolTable; + argumentsSymbol: Symbol; + requireSymbol: Symbol; + lookup: (symbols: SymbolTable, name: __String, meaning: SymbolFlags) => Symbol | undefined; + setRequiresScopeChangeCache: undefined | ((node: FunctionLikeDeclaration, value: boolean) => void); + getRequiresScopeChangeCache: undefined | ((node: FunctionLikeDeclaration) => boolean | undefined); + onPropertyWithInvalidInitializer?: (location: Node | undefined, name: __String, declaration: PropertyDeclaration, result: Symbol | undefined) => boolean; + onFailedToResolveSymbol?: (location: Node | undefined, name: __String | Identifier, meaning: SymbolFlags, nameNotFoundMessage: DiagnosticMessage) => void; + onSuccessfullyResolvedSymbol?: (location: Node | undefined, result: Symbol, meaning: SymbolFlags, lastLocation: Node | undefined, associatedDeclarationForContainingInitializerOrBindingName: ParameterDeclaration | BindingElement | undefined, withinDeferredContext: boolean) => void; +} + +/** @internal */ +export type NameResolver = ( + location: Node | undefined, + nameArg: __String | Identifier, + meaning: SymbolFlags, + nameNotFoundMessage: DiagnosticMessage | undefined, + isUse: boolean, + excludeGlobals?: boolean, +) => Symbol | undefined; + /** @internal */ export function createNameResolver({ compilerOptions, @@ -11228,32 +11271,7 @@ export function createNameResolver({ onPropertyWithInvalidInitializer = returnFalse, onFailedToResolveSymbol = returnUndefined, onSuccessfullyResolvedSymbol = returnUndefined, -}: { - compilerOptions: CompilerOptions; - getSymbolOfDeclaration: (node: Declaration) => Symbol; - error: (location: Node | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments) => void; - globals: SymbolTable; - argumentsSymbol: Symbol; - requireSymbol: Symbol; - lookup: (symbols: SymbolTable, name: __String, meaning: SymbolFlags) => Symbol | undefined; - setRequiresScopeChangeCache: undefined | ((node: FunctionLikeDeclaration, value: boolean) => void); - getRequiresScopeChangeCache: undefined | ((node: FunctionLikeDeclaration) => boolean | undefined); - onPropertyWithInvalidInitializer?: (location: Node | undefined, name: __String, declaration: PropertyDeclaration, result: Symbol | undefined) => boolean; - onFailedToResolveSymbol?: ( - location: Node | undefined, - name: __String | Identifier, - meaning: SymbolFlags, - nameNotFoundMessage: DiagnosticMessage, - ) => void; - onSuccessfullyResolvedSymbol?: ( - location: Node | undefined, - result: Symbol, - meaning: SymbolFlags, - lastLocation: Node | undefined, - associatedDeclarationForContainingInitializerOrBindingName: ParameterDeclaration | BindingElement | undefined, - withinDeferredContext: boolean, - ) => void; -}) { +}: NameResolverOptions): NameResolver { /* eslint-disable no-var */ var isolatedModulesLikeFlagName = compilerOptions.verbatimModuleSyntax ? "verbatimModuleSyntax" : "isolatedModules"; /* eslint-disable no-var */ @@ -11805,7 +11823,7 @@ export function isPrimitiveLiteralValue(node: Expression, includeBigInt = true): } /** @internal */ -export function unwrapParenthesizedExpression(o: Expression) { +export function unwrapParenthesizedExpression(o: Expression): Expression { while (o.kind === SyntaxKind.ParenthesizedExpression) { o = (o as ParenthesizedExpression).expression; } @@ -11899,13 +11917,13 @@ const unprefixedNodeCoreModulesList = [ ]; /** @internal */ -export const unprefixedNodeCoreModules = new Set(unprefixedNodeCoreModulesList); +export const unprefixedNodeCoreModules: Set = new Set(unprefixedNodeCoreModulesList); // await fetch('https://nodejs.org/docs/latest/api/all.json').then(r => r.text()).then(t => // new Set(t.match(/(?<=')node:.+?(?=')/g)) // .difference(new Set(require('module').builtinModules.map(x => `node:${x}`)))) /** @internal */ -export const exclusivelyPrefixedNodeCoreModules = new Set([ +export const exclusivelyPrefixedNodeCoreModules: Set = new Set([ "node:sea", "node:sqlite", "node:test", @@ -11913,7 +11931,7 @@ export const exclusivelyPrefixedNodeCoreModules = new Set([ ]); /** @internal */ -export const nodeCoreModules = new Set([ +export const nodeCoreModules: Set = new Set([ ...unprefixedNodeCoreModulesList, ...unprefixedNodeCoreModulesList.map(name => `node:${name}`), ...exclusivelyPrefixedNodeCoreModules, diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 65d1482263d17..462ebc6da06d4 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -304,7 +304,7 @@ export function sortAndDeduplicateDiagnostics(diagnostics: } /** @internal */ -export const targetToLibMap = new Map([ +export const targetToLibMap: Map = new Map([ [ScriptTarget.ESNext, "lib.esnext.full.d.ts"], [ScriptTarget.ES2023, "lib.es2023.full.d.ts"], [ScriptTarget.ES2022, "lib.es2022.full.d.ts"], @@ -336,15 +336,15 @@ export function getDefaultLibFileName(options: CompilerOptions): string { } } -export function textSpanEnd(span: TextSpan) { +export function textSpanEnd(span: TextSpan): number { return span.start + span.length; } -export function textSpanIsEmpty(span: TextSpan) { +export function textSpanIsEmpty(span: TextSpan): boolean { return span.length === 0; } -export function textSpanContainsPosition(span: TextSpan, position: number) { +export function textSpanContainsPosition(span: TextSpan, position: number): boolean { return position >= span.start && position < textSpanEnd(span); } @@ -354,21 +354,21 @@ export function textRangeContainsPositionInclusive(range: TextRange, position: n } // Returns true if 'span' contains 'other'. -export function textSpanContainsTextSpan(span: TextSpan, other: TextSpan) { +export function textSpanContainsTextSpan(span: TextSpan, other: TextSpan): boolean { return other.start >= span.start && textSpanEnd(other) <= textSpanEnd(span); } /** @internal */ -export function textSpanContainsTextRange(span: TextSpan, range: TextRange) { +export function textSpanContainsTextRange(span: TextSpan, range: TextRange): boolean { return range.pos >= span.start && range.end <= textSpanEnd(span); } /** @internal */ -export function textRangeContainsTextSpan(range: TextRange, span: TextSpan) { +export function textRangeContainsTextSpan(range: TextRange, span: TextSpan): boolean { return span.start >= range.pos && textSpanEnd(span) <= range.end; } -export function textSpanOverlapsWith(span: TextSpan, other: TextSpan) { +export function textSpanOverlapsWith(span: TextSpan, other: TextSpan): boolean { return textSpanOverlap(span, other) !== undefined; } @@ -445,15 +445,15 @@ export function createTextSpan(start: number, length: number): TextSpan { return { start, length }; } -export function createTextSpanFromBounds(start: number, end: number) { +export function createTextSpanFromBounds(start: number, end: number): TextSpan { return createTextSpan(start, end - start); } -export function textChangeRangeNewSpan(range: TextChangeRange) { +export function textChangeRangeNewSpan(range: TextChangeRange): TextSpan { return createTextSpan(range.span.start, range.newLength); } -export function textChangeRangeIsUnchanged(range: TextChangeRange) { +export function textChangeRangeIsUnchanged(range: TextChangeRange): boolean { return textSpanIsEmpty(range.span) && range.newLength === 0; } @@ -465,7 +465,7 @@ export function createTextChangeRange(span: TextSpan, newLength: number): TextCh return { span, newLength }; } -export const unchangedTextChangeRange = createTextChangeRange(createTextSpan(0, 0), 0); +export const unchangedTextChangeRange: TextChangeRange = createTextChangeRange(createTextSpan(0, 0), 0); /** * Called to merge all the changes that occurred across several versions of a script snapshot @@ -675,7 +675,7 @@ function getNodeFlags(node: Node) { } /** @internal */ -export const supportedLocaleDirectories = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"]; +export const supportedLocaleDirectories = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"] as const; /** * Checks to see if the locale is in the appropriate format, @@ -685,7 +685,7 @@ export function validateLocaleAndSetLanguage( locale: string, sys: { getExecutingFilePath(): string; resolvePath(path: string): string; fileExists(fileName: string): boolean; readFile(fileName: string): string | undefined; }, errors?: Diagnostic[], -) { +): void { const lowerCaseLocale = locale.toLowerCase(); const matchResult = /^([a-z]+)(?:[_-]([a-z]+))?$/.exec(lowerCaseLocale); @@ -919,7 +919,7 @@ function getDeclarationIdentifier(node: Declaration | Expression): Identifier | } /** @internal */ -export function nodeHasName(statement: Node, name: Identifier) { +export function nodeHasName(statement: Node, name: Identifier): boolean { if (isNamedDeclaration(statement) && isIdentifier(statement.name) && idText(statement.name as Identifier) === idText(name)) { return true; } @@ -1282,7 +1282,7 @@ export function getAllJSDocTagsOfKind(node: Node, kind: SyntaxKind): readonly JS } /** Gets the text of a jsdoc comment, flattening links to their text. */ -export function getTextOfJSDocComment(comment?: string | NodeArray) { +export function getTextOfJSDocComment(comment?: string | NodeArray): string | undefined { return typeof comment === "string" ? comment : comment?.map(c => c.kind === SyntaxKind.JSDocText ? c.text : formatJSDocLink(c)).join(""); } @@ -1404,17 +1404,17 @@ export function isExpressionOfOptionalChainRoot(node: Node): node is Expression * * @internal */ -export function isOutermostOptionalChain(node: OptionalChain) { +export function isOutermostOptionalChain(node: OptionalChain): boolean { return !isOptionalChain(node.parent) // cases 1, 2, and 3 || isOptionalChainRoot(node.parent) // case 4 || node !== node.parent.expression; // case 5 } -export function isNullishCoalesce(node: Node) { +export function isNullishCoalesce(node: Node): boolean { return node.kind === SyntaxKind.BinaryExpression && (node as BinaryExpression).operatorToken.kind === SyntaxKind.QuestionQuestionToken; } -export function isConstTypeReference(node: Node) { +export function isConstTypeReference(node: Node): boolean { return isTypeReferenceNode(node) && isIdentifier(node.typeName) && node.typeName.escapedText === "const" && !node.typeArguments; } @@ -1450,7 +1450,7 @@ export function isJSDocPropertyLikeTag(node: Node): node is JSDocPropertyLikeTag // they may be used with transformations. /** @internal */ -export function isNodeKind(kind: SyntaxKind) { +export function isNodeKind(kind: SyntaxKind): boolean { return kind >= SyntaxKind.FirstNode; } @@ -1491,7 +1491,7 @@ export function isLiteralExpression(node: Node): node is LiteralExpression { } /** @internal */ -export function isLiteralExpressionOfObject(node: Node) { +export function isLiteralExpressionOfObject(node: Node): boolean { switch (node.kind) { case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.ArrayLiteralExpression: @@ -1574,7 +1574,7 @@ export function isGeneratedPrivateIdentifier(node: Node): node is GeneratedPriva } /** @internal */ -export function isFileLevelReservedGeneratedIdentifier(node: GeneratedIdentifier) { +export function isFileLevelReservedGeneratedIdentifier(node: GeneratedIdentifier): boolean { const flags = node.emitNode.autoGenerate.flags; return !!(flags & GeneratedIdentifierFlags.FileLevel) && !!(flags & GeneratedIdentifierFlags.Optimistic) @@ -2118,17 +2118,17 @@ function isScopeMarker(node: Node) { } /** @internal */ -export function hasScopeMarker(statements: readonly Statement[]) { +export function hasScopeMarker(statements: readonly Statement[]): boolean { return some(statements, isScopeMarker); } /** @internal */ -export function needsScopeMarker(result: Statement) { +export function needsScopeMarker(result: Statement): boolean { return !isAnyImportOrReExport(result) && !isExportAssignment(result) && !hasSyntacticModifier(result, ModifierFlags.Export) && !isAmbientModule(result); } /** @internal */ -export function isExternalModuleIndicator(result: Statement) { +export function isExternalModuleIndicator(result: Statement): boolean { // Exported top-level member indicates moduleness return isAnyImportOrReExport(result) || isExportAssignment(result) || hasSyntacticModifier(result, ModifierFlags.Export); } @@ -2576,7 +2576,7 @@ export function isTypeReferenceType(node: Node): node is TypeReferenceType { const MAX_SMI_X86 = 0x3fff_ffff; /** @internal */ -export function guessIndentation(lines: string[]) { +export function guessIndentation(lines: string[]): number | undefined { let indentation = MAX_SMI_X86; for (const line of lines) { if (!line.length) { @@ -2621,7 +2621,7 @@ function hasInternalAnnotation(range: CommentRange, sourceFile: SourceFile) { return comment.includes("@internal"); } -export function isInternalDeclaration(node: Node, sourceFile?: SourceFile) { +export function isInternalDeclaration(node: Node, sourceFile?: SourceFile): boolean { sourceFile ??= getSourceFileOfNode(node); const parseTreeNode = getParseTreeNode(node); if (parseTreeNode && parseTreeNode.kind === SyntaxKind.Parameter) { diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index f3e71e026d9be..dbd49379e5750 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -379,7 +379,7 @@ function visitArrayWorker( * 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): NodeArray { context.startLexicalEnvironment(); statements = nodesVisitor(statements, visitor, isStatement, start); if (ensureUseStrict) statements = context.factory.ensureUseStrict(statements); @@ -561,7 +561,7 @@ export function visitIterationBody(body: Statement, visitor: Visitor, context: T * @param visitor The visitor to use when visiting expressions whose result will not be discarded at runtime. * @param discardVisitor The visitor to use when visiting expressions whose result will be discarded at runtime. Defaults to {@link visitor}. */ -export function visitCommaListElements(elements: NodeArray, visitor: Visitor, discardVisitor = visitor): NodeArray { +export function visitCommaListElements(elements: NodeArray, visitor: Visitor, discardVisitor: Visitor = visitor): NodeArray { if (discardVisitor === visitor || elements.length <= 1) { return visitNodes(elements, visitor, isExpression); } diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 89c6f13b102c7..a859bcc60009d 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -173,7 +173,7 @@ function getPlainDiagnosticFollowingNewLines(diagnostic: Diagnostic, newLine: st * * @internal */ -export function getLocaleTimeString(system: System) { +export function getLocaleTimeString(system: System): string { return !system.now ? new Date().toLocaleTimeString() : // On some systems / builds of Node, there's a non-breaking space between the time and AM/PM. @@ -225,7 +225,7 @@ export function parseConfigFileWithSystem(configFileName: string, optionsToExten } /** @internal */ -export function getErrorCountForSummary(diagnostics: readonly Diagnostic[]) { +export function getErrorCountForSummary(diagnostics: readonly Diagnostic[]): number { return countWhere(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error); } @@ -256,7 +256,7 @@ export function getFilesInErrorForSummary(diagnostics: readonly Diagnostic[]): ( } /** @internal */ -export function getWatchErrorSummaryDiagnosticMessage(errorCount: number) { +export function getWatchErrorSummaryDiagnosticMessage(errorCount: number): DiagnosticMessage { return errorCount === 1 ? Diagnostics.Found_1_error_Watching_for_file_changes : Diagnostics.Found_0_errors_Watching_for_file_changes; @@ -277,7 +277,7 @@ export function getErrorSummaryText( filesInError: readonly (ReportFileInError | undefined)[], newLine: string, host: HasCurrentDirectory, -) { +): string { if (errorCount === 0) return ""; const nonNilFiles = filesInError.filter(fileInError => fileInError !== undefined); const distinctFileNamesWithLines = nonNilFiles.map(fileInError => `${fileInError.fileName}:${fileInError.line}`) @@ -347,7 +347,7 @@ function listFiles(program: Program | T, write: (s: st } /** @internal */ -export function explainFiles(program: Program, write: (s: string) => void) { +export function explainFiles(program: Program, write: (s: string) => void): void { const reasons = program.getFileIncludeReasons(); const relativeFileName = (fileName: string) => convertToRelativePath(fileName, program.getCurrentDirectory(), program.getCanonicalFileName); for (const file of program.getSourceFiles()) { @@ -412,7 +412,7 @@ export function explainIfFileIsRedirectAndImpliedFormat( } /** @internal */ -export function getMatchedFileSpec(program: Program, fileName: string) { +export function getMatchedFileSpec(program: Program, fileName: string): string | undefined { const configFile = program.getCompilerOptions().configFile; if (!configFile?.configFileSpecs?.validatedFilesSpec) return undefined; @@ -423,7 +423,7 @@ export function getMatchedFileSpec(program: Program, fileName: string) { } /** @internal */ -export function getMatchedIncludeSpec(program: Program, fileName: string) { +export function getMatchedIncludeSpec(program: Program, fileName: string): string | true | undefined { const configFile = program.getCompilerOptions().configFile; if (!configFile?.configFileSpecs?.validatedIncludeSpecs) return undefined; @@ -639,7 +639,7 @@ export function emitFilesAndReportErrorsAndGetExitStatus noopFileWatcher; +export const returnNoopFileWatcher = (): FileWatcher => noopFileWatcher; /** @internal */ -export function createWatchHost(system = sys, reportWatchStatus?: WatchStatusReporter): WatchHost { +export function createWatchHost(system: System = sys, reportWatchStatus?: WatchStatusReporter): WatchHost { const onWatchStatusChange = reportWatchStatus || createWatchStatusReporter(system); return { onWatchStatusChange, @@ -741,7 +741,7 @@ export interface WatchFactoryWithLog extends WatchFactory(host: WatchFactoryHost & { trace?(s: string): void; }, options: { extendedDiagnostics?: boolean; diagnostics?: boolean; }) { +export function createWatchFactory(host: WatchFactoryHost & { trace?(s: string): void; }, options: { extendedDiagnostics?: boolean; diagnostics?: boolean; }): WatchFactoryWithLog { const watchLogLevel = host.trace ? options.extendedDiagnostics ? WatchLogLevel.Verbose : options.diagnostics ? WatchLogLevel.TriggerOnly : WatchLogLevel.None : WatchLogLevel.None; const writeLog: (s: string) => void = watchLogLevel !== WatchLogLevel.None ? (s => host.trace!(s)) : noop; const result = getWatchFactory(host, watchLogLevel, writeLog) as WatchFactoryWithLog; @@ -784,7 +784,7 @@ export function createCompilerHostFromProgramHost(host: ProgramHost, getCom } /** @internal */ -export function getSourceFileVersionAsHashFromText(host: Pick, text: string) { +export function getSourceFileVersionAsHashFromText(host: Pick, text: string): string { // If text can contain the sourceMapUrl ignore sourceMapUrl for calcualting hash if (text.match(sourceMapCommentRegExpDontCareLineStart)) { let lineEnd = text.length; @@ -823,7 +823,7 @@ export function getSourceFileVersionAsHashFromText(host: Pick { const result = originalGetSourceFile.call(compilerHost, ...args); @@ -981,8 +981,9 @@ export interface IncrementalCompilationOptions { afterProgramEmitAndDiagnostics?(program: EmitAndSemanticDiagnosticsBuilderProgram): void; system?: System; } + /** @internal */ -export function performIncrementalCompilation(input: IncrementalCompilationOptions) { +export function performIncrementalCompilation(input: IncrementalCompilationOptions): ExitStatus { const system = input.system || sys; const host = input.host || (input.host = createIncrementalCompilerHost(input.options, system)); const builderProgram = createIncrementalProgram(input); diff --git a/src/compiler/watchPublic.ts b/src/compiler/watchPublic.ts index 0e77ead8d6af8..24723481e000a 100644 --- a/src/compiler/watchPublic.ts +++ b/src/compiler/watchPublic.ts @@ -103,7 +103,7 @@ export interface ReadBuildProgramHost { /** @internal */ getBuildInfo?(fileName: string, configFilePath: string | undefined): BuildInfo | undefined; } -export function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost) { +export function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost): EmitAndSemanticDiagnosticsBuilderProgram | undefined { const buildInfoPath = getTsBuildInfoEmitOutputFilePath(compilerOptions); if (!buildInfoPath) return undefined; let buildInfo; @@ -120,7 +120,7 @@ export function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadB return createBuilderProgramUsingIncrementalBuildInfo(buildInfo, buildInfoPath, host); } -export function createIncrementalCompilerHost(options: CompilerOptions, system = sys): CompilerHost { +export function createIncrementalCompilerHost(options: CompilerOptions, system: System = sys): CompilerHost { const host = createCompilerHostWorker(options, /*setParentNodes*/ undefined, system); host.createHash = maybeBind(system, system.createHash); host.storeSignatureInfo = system.storeSignatureInfo; diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index cbeceed07fd6e..82c9dbf32e28c 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -410,7 +410,7 @@ export function updateSharedExtendedConfigFileWatcher( extendedConfigFilesMap: Map>, createExtendedConfigFileWatch: (extendedConfigPath: string, extendedConfigFilePath: Path) => FileWatcher, toPath: (fileName: string) => Path, -) { +): void { const extendedConfigs = arrayToMap(options?.configFile?.extendedSourceFiles || emptyArray, toPath); // remove project from all unrelated watchers extendedConfigFilesMap.forEach((watcher, extendedConfigFilePath) => { @@ -449,7 +449,7 @@ export function updateSharedExtendedConfigFileWatcher( export function clearSharedExtendedConfigFileWatcher( projectPath: T, extendedConfigFilesMap: Map>, -) { +): void { extendedConfigFilesMap.forEach(watcher => { if (watcher.projects.delete(projectPath)) watcher.close(); }); @@ -464,7 +464,7 @@ export function cleanExtendedConfigCache( extendedConfigCache: Map, extendedConfigFilePath: Path, toPath: (fileName: string) => Path, -) { +): void { if (!extendedConfigCache.delete(extendedConfigFilePath)) return; extendedConfigCache.forEach(({ extendedResult }, key) => { if (extendedResult.extendedSourceFiles?.some(extendedFile => toPath(extendedFile) === extendedConfigFilePath)) { @@ -482,7 +482,7 @@ export function updateMissingFilePathsWatch( program: Program, missingFileWatches: Map, createMissingFileWatch: (missingFilePath: Path, missingFileName: string) => FileWatcher, -) { +): void { // Update the missing file paths watcher mutateMap( missingFileWatches, @@ -515,7 +515,7 @@ export function updateWatchingWildcardDirectories( existingWatchedForWildcards: Map>, wildcardDirectories: MapLike | undefined, watchDirectory: (directory: string, flags: WatchDirectoryFlags) => T, -) { +): void { if (wildcardDirectories) { mutateMap( existingWatchedForWildcards, @@ -665,7 +665,7 @@ export function isIgnoredFileFromWildCardWatching({ } /** @internal */ -export function isEmittedFileOfProgram(program: Program | undefined, file: string) { +export function isEmittedFileOfProgram(program: Program | undefined, file: string): boolean { if (!program) { return false; } @@ -842,6 +842,6 @@ export function getFallbackOptions(options: WatchOptions | undefined): WatchOpti } /** @internal */ -export function closeFileWatcherOf(objWithWatcher: T) { +export function closeFileWatcherOf(objWithWatcher: T): void { objWithWatcher.watcher.close(); } diff --git a/src/deprecatedCompat/deprecate.ts b/src/deprecatedCompat/deprecate.ts index 595376a5222d1..634c6e89a58c4 100644 --- a/src/deprecatedCompat/deprecate.ts +++ b/src/deprecatedCompat/deprecate.ts @@ -9,7 +9,7 @@ import { export let enableDeprecationWarnings = true; -export function setEnableDeprecationWarnings(value: boolean) { +export function setEnableDeprecationWarnings(value: boolean): void { enableDeprecationWarnings = value; } diff --git a/src/harness/client.ts b/src/harness/client.ts index e1daecdc82dec..fed95404d6abb 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -40,6 +40,7 @@ import { JSDocTagInfo, LanguageService, LanguageServiceHost, + LineAndCharacter, map, mapOneOrMany, NavigateToItem, @@ -203,7 +204,7 @@ export class SessionClient implements LanguageService { } /** @internal */ - configure(preferences: UserPreferences) { + configure(preferences: UserPreferences): void { this.preferences = preferences; const args: protocol.ConfigureRequestArguments = { preferences }; const request = this.processRequest(protocol.CommandTypes.Configure, args); @@ -211,14 +212,14 @@ export class SessionClient implements LanguageService { } /** @internal */ - setFormattingOptions(formatOptions: FormatCodeSettings) { + setFormattingOptions(formatOptions: FormatCodeSettings): void { const args: protocol.ConfigureRequestArguments = { formatOptions }; const request = this.processRequest(protocol.CommandTypes.Configure, args); this.processResponse(request, /*expectEmptyBody*/ true); } /** @internal */ - setCompilerOptionsForInferredProjects(options: protocol.CompilerOptions) { + setCompilerOptionsForInferredProjects(options: protocol.CompilerOptions): void { const args: protocol.SetCompilerOptionsForInferredProjectsArgs = { options }; const request = this.processRequest(protocol.CommandTypes.CompilerOptionsForInferredProjects, args); this.processResponse(request, /*expectEmptyBody*/ false); @@ -247,7 +248,7 @@ export class SessionClient implements LanguageService { this.processResponse(request, /*expectEmptyBody*/ true); } - toLineColumnOffset(fileName: string, position: number) { + toLineColumnOffset(fileName: string, position: number): LineAndCharacter { const { line, offset } = this.positionToOneBasedLineOffset(fileName, position); return { line, character: offset }; } @@ -580,7 +581,7 @@ export class SessionClient implements LanguageService { return renameInfo; } - getSmartSelectionRange() { + getSmartSelectionRange(): never { return notImplemented(); } @@ -766,9 +767,9 @@ export class SessionClient implements LanguageService { ({ fixName, description, changes: this.convertChanges(changes, file), commands: commands as CodeActionCommand[], fixId, fixAllDescription })); } - getCombinedCodeFix = notImplemented; + getCombinedCodeFix: typeof notImplemented = notImplemented; - applyCodeActionCommand = notImplemented; + applyCodeActionCommand: typeof notImplemented = notImplemented; provideInlayHints(file: string, span: TextSpan): InlayHint[] { const { start, length } = span; @@ -796,7 +797,7 @@ export class SessionClient implements LanguageService { }); } - mapCode = notImplemented; + mapCode: typeof notImplemented = notImplemented; private createFileLocationOrRangeRequestArgs(positionOrRange: number | TextRange, fileName: string): protocol.FileLocationOrRangeRequestArgs { return typeof positionOrRange === "number" @@ -902,7 +903,7 @@ export class SessionClient implements LanguageService { return notImplemented(); } - getEditsForFileRename() { + getEditsForFileRename(): never { return notImplemented(); } @@ -992,7 +993,7 @@ export class SessionClient implements LanguageService { }; } - provideCallHierarchyIncomingCalls(fileName: string, position: number) { + provideCallHierarchyIncomingCalls(fileName: string, position: number): CallHierarchyIncomingCall[] { const args = this.createFileLocationRequestArgs(fileName, position); const request = this.processRequest(protocol.CommandTypes.ProvideCallHierarchyIncomingCalls, args); const response = this.processResponse(request); @@ -1006,7 +1007,7 @@ export class SessionClient implements LanguageService { }; } - provideCallHierarchyOutgoingCalls(fileName: string, position: number) { + provideCallHierarchyOutgoingCalls(fileName: string, position: number): CallHierarchyOutgoingCall[] { const args = this.createFileLocationRequestArgs(fileName, position); const request = this.processRequest(protocol.CommandTypes.ProvideCallHierarchyOutgoingCalls, args); const response = this.processResponse(request); diff --git a/src/harness/collectionsImpl.ts b/src/harness/collectionsImpl.ts index 6c0da4353a987..9f8fe7399acd7 100644 --- a/src/harness/collectionsImpl.ts +++ b/src/harness/collectionsImpl.ts @@ -23,11 +23,11 @@ export class SortedMap { } } - public get size() { + public get size(): number { return this._keys.length; } - public get comparer() { + public get comparer(): (a: K, b: K) => number { return this._comparer; } @@ -35,11 +35,11 @@ export class SortedMap { return "SortedMap"; } - public has(key: K) { + public has(key: K): boolean { return ts.binarySearch(this._keys, key, ts.identity, this._comparer) >= 0; } - public get(key: K) { + public get(key: K): V | undefined { const index = ts.binarySearch(this._keys, key, ts.identity, this._comparer); return index >= 0 ? this._values[index] : undefined; } @@ -49,7 +49,7 @@ export class SortedMap { return index >= 0 ? [this._keys[index], this._values[index]] : undefined; } - public set(key: K, value: V) { + public set(key: K, value: V): this { const index = ts.binarySearch(this._keys, key, ts.identity, this._comparer); if (index >= 0) { this._values[index] = value; @@ -64,7 +64,7 @@ export class SortedMap { return this; } - public delete(key: K) { + public delete(key: K): boolean { const index = ts.binarySearch(this._keys, key, ts.identity, this._comparer); if (index >= 0) { this.writePreamble(); @@ -77,7 +77,7 @@ export class SortedMap { return false; } - public clear() { + public clear(): void { if (this.size > 0) { this.writePreamble(); this._keys.length = 0; @@ -87,7 +87,7 @@ export class SortedMap { } } - public forEach(callback: (value: V, key: K, collection: this) => void, thisArg?: any) { + public forEach(callback: (value: V, key: K, collection: this) => void, thisArg?: any): void { const keys = this._keys; const values = this._values; const indices = this.getIterationOrder(); @@ -112,7 +112,7 @@ export class SortedMap { } } - public *keys() { + public *keys(): Generator { const keys = this._keys; const indices = this.getIterationOrder(); const version = this._version; @@ -135,7 +135,7 @@ export class SortedMap { return undefined; } - public *values() { + public *values(): Generator { const values = this._values; const indices = this.getIterationOrder(); const version = this._version; @@ -158,7 +158,7 @@ export class SortedMap { return undefined; } - public *entries() { + public *entries(): Generator<[K, V], undefined, unknown> { const keys = this._keys; const values = this._values; const indices = this.getIterationOrder(); @@ -184,7 +184,7 @@ export class SortedMap { return undefined; } - public [Symbol.iterator]() { + public [Symbol.iterator](): Generator<[K, V], undefined, unknown> { return this.entries(); } @@ -255,7 +255,7 @@ export class Metadata { return this._size; } - public get parent() { + public get parent(): Metadata | undefined { return this._parent; } @@ -292,7 +292,7 @@ export class Metadata { this._version++; } - public forEach(callback: (value: any, key: string, map: this) => void) { + public forEach(callback: (value: any, key: string, map: this) => void): void { for (const key in this._map) { callback(this._map[key], Metadata._unescapeKey(key), this); } diff --git a/src/harness/compilerImpl.ts b/src/harness/compilerImpl.ts index 4e19b1443aea3..700eda6420bce 100644 --- a/src/harness/compilerImpl.ts +++ b/src/harness/compilerImpl.ts @@ -225,7 +225,7 @@ export class CompilationResult { return vpath.changeExtension(path, ext); } - public getNumberOfJsFiles(includeJson: boolean) { + public getNumberOfJsFiles(includeJson: boolean): number { if (includeJson) { return this.js.size; } diff --git a/src/harness/documentsUtil.ts b/src/harness/documentsUtil.ts index cf3d7c7f08184..529d423ec775f 100644 --- a/src/harness/documentsUtil.ts +++ b/src/harness/documentsUtil.ts @@ -22,7 +22,7 @@ export class TextDocument { return this._lineStarts || (this._lineStarts = ts.computeLineStarts(this.text)); } - public static fromTestFile(file: Harness.Compiler.TestFile) { + public static fromTestFile(file: Harness.Compiler.TestFile): TextDocument { return new TextDocument( file.unitName, file.content, @@ -31,7 +31,7 @@ export class TextDocument { ); } - public asTestFile() { + public asTestFile(): Harness.Compiler.TestFile { return this._testFile || (this._testFile = { unitName: this.file, content: this.text, @@ -140,7 +140,7 @@ export class SourceMap { this.mappings = mappings; } - public static getUrl(text: string) { + public static getUrl(text: string): string | undefined { let match: RegExpExecArray | null; // eslint-disable-line no-restricted-syntax let lastMatch: RegExpExecArray | undefined; while (match = SourceMap._sourceMappingURLRegExp.exec(text)) { @@ -149,7 +149,7 @@ export class SourceMap { return lastMatch ? lastMatch[1] : undefined; } - public static fromUrl(url: string) { + public static fromUrl(url: string): SourceMap | undefined { const match = SourceMap._dataURLRegExp.exec(url); return match ? new SourceMap(/*mapFile*/ undefined, ts.sys.base64decode!(match[1])) : undefined; } diff --git a/src/harness/evaluatorImpl.ts b/src/harness/evaluatorImpl.ts index 706e613aa5dcc..2e2124b64e068 100644 --- a/src/harness/evaluatorImpl.ts +++ b/src/harness/evaluatorImpl.ts @@ -33,7 +33,7 @@ for (const symbolName of symbolNames) { } } -export function evaluateTypeScript(source: string | { files: vfs.FileSet; rootFiles: string[]; main: string; }, options?: ts.CompilerOptions, globals?: Record) { +export function evaluateTypeScript(source: string | { files: vfs.FileSet; rootFiles: string[]; main: string; }, options?: ts.CompilerOptions, globals?: Record): any { if (typeof source === "string") source = { files: { [sourceFile]: source }, rootFiles: [sourceFile], main: sourceFile }; const fs = vfs.createFromFileSystem(Harness.IO, /*ignoreCase*/ false, { files: source.files }); const compilerOptions: ts.CompilerOptions = { @@ -62,7 +62,7 @@ export function evaluateTypeScript(source: string | { files: vfs.FileSet; rootFi return loader.import(output.file); } -export function evaluateJavaScript(sourceText: string, globals?: Record, sourceFile = sourceFileJs) { +export function evaluateJavaScript(sourceText: string, globals?: Record, sourceFile: string = sourceFileJs): any { globals = { Symbol: FakeSymbol, ...globals }; const fs = new vfs.FileSystem(/*ignoreCase*/ false, { files: { [sourceFile]: sourceText } }); return new CommonJsLoader(fs, globals).import(sourceFile); diff --git a/src/harness/fakesHosts.ts b/src/harness/fakesHosts.ts index ff5bceea34790..37dab2eadbadd 100644 --- a/src/harness/fakesHosts.ts +++ b/src/harness/fakesHosts.ts @@ -41,19 +41,19 @@ export class System implements ts.System { } private testTerminalWidth = Number.parseInt(this.getEnvironmentVariable("TS_TEST_TERMINAL_WIDTH")); - getWidthOfTerminal = Number.isNaN(this.testTerminalWidth) ? undefined : () => this.testTerminalWidth; + getWidthOfTerminal: (() => number) | undefined = Number.isNaN(this.testTerminalWidth) ? undefined : () => this.testTerminalWidth; // Pretty output writeOutputIsTTY() { return true; } - public write(message: string) { + public write(message: string): void { if (ts.Debug.isDebugging) console.log(message); this.output.push(message); } - public readFile(path: string) { + public readFile(path: string): string | undefined { try { const content = this.vfs.readFileSync(path, "utf8"); return content === undefined ? undefined : Utils.removeByteOrderMark(content); @@ -68,16 +68,16 @@ export class System implements ts.System { this.vfs.writeFileSync(path, writeByteOrderMark ? Utils.addUTF8ByteOrderMark(data) : data); } - public deleteFile(path: string) { + public deleteFile(path: string): void { this.vfs.unlinkSync(path); } - public fileExists(path: string) { + public fileExists(path: string): boolean { const stats = this._getStats(path); return stats ? stats.isFile() : false; } - public directoryExists(path: string) { + public directoryExists(path: string): boolean { const stats = this._getStats(path); return stats ? stats.isDirectory() : false; } @@ -86,11 +86,11 @@ export class System implements ts.System { this.vfs.mkdirpSync(path); } - public getCurrentDirectory() { + public getCurrentDirectory(): string { return this.vfs.cwd(); } - public getDirectories(path: string) { + public getDirectories(path: string): string[] { const result: string[] = []; try { for (const file of this.vfs.readdirSync(path)) { @@ -128,31 +128,31 @@ export class System implements ts.System { return { files, directories }; } - public exit(exitCode?: number) { + public exit(exitCode?: number): void { this.exitCode = exitCode; throw processExitSentinel; } - public getFileSize(path: string) { + public getFileSize(path: string): number { const stats = this._getStats(path); return stats && stats.isFile() ? stats.size : 0; } - public resolvePath(path: string) { + public resolvePath(path: string): string { return vpath.resolve(this.vfs.cwd(), path); } - public getExecutingFilePath() { + public getExecutingFilePath(): string { if (this._executingFilePath === undefined) return ts.notImplemented(); return this._executingFilePath; } - public getModifiedTime(path: string) { + public getModifiedTime(path: string): Date { const stats = this._getStats(path); return stats ? stats.mtime : undefined!; // TODO: GH#18217 } - public setModifiedTime(path: string, time: Date) { + public setModifiedTime(path: string, time: Date): void { try { this.vfs.utimesSync(path, time, time); } @@ -163,7 +163,7 @@ export class System implements ts.System { return `${ts.generateDjb2Hash(data)}-${data}`; } - public realpath(path: string) { + public realpath(path: string): string { try { return this.vfs.realpathSync(path); } @@ -185,7 +185,7 @@ export class System implements ts.System { } } - now() { + now(): Date { return new Date(this.vfs.time()); } } @@ -201,11 +201,11 @@ export class ParseConfigHost implements ts.ParseConfigHost { this.sys = sys; } - public get vfs() { + public get vfs(): vfs.FileSystem { return this.sys.vfs; } - public get useCaseSensitiveFileNames() { + public get useCaseSensitiveFileNames(): boolean { return this.sys.useCaseSensitiveFileNames; } @@ -247,7 +247,7 @@ export class CompilerHost implements ts.CompilerHost { public readonly outputs: documents.TextDocument[] = []; private readonly _outputsMap: collections.SortedMap; public readonly traces: string[] = []; - public readonly shouldAssertInvariants = !Harness.lightMode; + public readonly shouldAssertInvariants: boolean = !Harness.lightMode; public readonly jsDocParsingMode: ts.JSDocParsingMode | undefined; private _setParentNodes: boolean; @@ -255,7 +255,7 @@ export class CompilerHost implements ts.CompilerHost { private _parseConfigHost: ParseConfigHost | undefined; private _newLine: string; - constructor(sys: System | vfs.FileSystem, options = ts.getDefaultCompilerOptions(), setParentNodes = false, jsDocParsingMode?: ts.JSDocParsingMode) { + constructor(sys: System | vfs.FileSystem, options: ts.CompilerOptions = ts.getDefaultCompilerOptions(), setParentNodes = false, jsDocParsingMode?: ts.JSDocParsingMode) { if (sys instanceof vfs.FileSystem) sys = new System(sys); this.sys = sys; this.defaultLibLocation = sys.vfs.meta.get("defaultLibLocation") || ""; @@ -266,11 +266,11 @@ export class CompilerHost implements ts.CompilerHost { this.jsDocParsingMode = jsDocParsingMode; } - public get vfs() { + public get vfs(): vfs.FileSystem { return this.sys.vfs; } - public get parseConfigHost() { + public get parseConfigHost(): ParseConfigHost { return this._parseConfigHost || (this._parseConfigHost = new ParseConfigHost(this.sys)); } @@ -290,7 +290,7 @@ export class CompilerHost implements ts.CompilerHost { return this.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); } - public deleteFile(fileName: string) { + public deleteFile(fileName: string): void { this.sys.deleteFile(fileName); } @@ -302,11 +302,11 @@ export class CompilerHost implements ts.CompilerHost { return this.sys.directoryExists(directoryName); } - public getModifiedTime(fileName: string) { + public getModifiedTime(fileName: string): Date { return this.sys.getModifiedTime(fileName); } - public setModifiedTime(fileName: string, time: Date) { + public setModifiedTime(fileName: string, time: Date): void { return this.sys.setModifiedTime(fileName, time); } @@ -322,7 +322,7 @@ export class CompilerHost implements ts.CompilerHost { return this.sys.readFile(path); } - public writeFile(fileName: string, content: string, writeByteOrderMark: boolean) { + public writeFile(fileName: string, content: string, writeByteOrderMark: boolean): void { if (writeByteOrderMark) content = Utils.addUTF8ByteOrderMark(content); this.sys.writeFile(fileName, content); diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index a2f37b035079a..4e8695d78b734 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -178,7 +178,7 @@ export class TestCancellationToken implements ts.HostCancellationToken { } } -export function verifyOperationIsCancelled(f: () => void) { +export function verifyOperationIsCancelled(f: () => void): void { try { f(); } @@ -533,7 +533,7 @@ export class TestState { else this.baselineFromTest.push({ command, actual, ext }); } - baselineTest() { + baselineTest(): void { if (this.baselineFromTest) { Harness.Baseline.runBaseline( this.getBaselineFileNameForContainingTestFile(this.baselineFromTest[0].ext), @@ -542,7 +542,7 @@ export class TestState { } } - baselineTsserverLog() { + baselineTsserverLog(): void { if (this.logger) { Harness.Baseline.runBaseline( `tsserver/fourslashServer/${ts.getBaseFileName(this.originalInputFileName).replace(".ts", ".js")}`, @@ -560,7 +560,7 @@ export class TestState { } // Entry points from fourslash.ts - public goToMarker(name: string | Marker = "") { + public goToMarker(name: string | Marker = ""): void { const marker = ts.isString(name) ? this.getMarkerByName(name) : name; if (this.activeFile.fileName !== marker.fileName) { this.openFile(marker.fileName); @@ -581,7 +581,7 @@ export class TestState { this.goToRangeStart(markerOrRange); } - public goToEachMarker(markers: readonly Marker[], action: (marker: Marker, index: number) => void) { + public goToEachMarker(markers: readonly Marker[], action: (marker: Marker, index: number) => void): void { assert(markers.length); for (let i = 0; i < markers.length; i++) { this.goToMarker(markers[i]); @@ -589,7 +589,7 @@ export class TestState { } } - public goToEachRange(action: (range: Range) => void) { + public goToEachRange(action: (range: Range) => void): void { const ranges = this.getRanges(); assert(ranges.length); for (const range of ranges) { @@ -606,7 +606,7 @@ export class TestState { })!; } - public goToPosition(positionOrLineAndCharacter: number | ts.LineAndCharacter) { + public goToPosition(positionOrLineAndCharacter: number | ts.LineAndCharacter): void { const pos = typeof positionOrLineAndCharacter === "number" ? positionOrLineAndCharacter : this.languageServiceAdapterHost.lineAndCharacterToPosition(this.activeFile.fileName, positionOrLineAndCharacter); @@ -614,7 +614,7 @@ export class TestState { this.selectionEnd = -1; } - public select(startMarker: string, endMarker: string) { + public select(startMarker: string, endMarker: string): void { const start = this.getMarkerByName(startMarker), end = this.getMarkerByName(endMarker); ts.Debug.assert(start.fileName === end.fileName); if (this.activeFile.fileName !== start.fileName) { @@ -624,7 +624,7 @@ export class TestState { this.selectionEnd = end.position; } - public selectAllInFile(fileName: string) { + public selectAllInFile(fileName: string): void { this.openFile(fileName); this.goToPosition(0); this.selectionEnd = this.activeFile.content.length; @@ -635,13 +635,13 @@ export class TestState { this.selectionEnd = range.end; } - public selectLine(index: number) { + public selectLine(index: number): void { const lineStart = this.languageServiceAdapterHost.lineAndCharacterToPosition(this.activeFile.fileName, { line: index, character: 0 }); const lineEnd = lineStart + this.getLineContent(index).length; this.selectRange({ fileName: this.activeFile.fileName, pos: lineStart, end: lineEnd }); } - public moveCaretRight(count = 1) { + public moveCaretRight(count = 1): void { this.currentCaretPosition += count; this.currentCaretPosition = Math.min(this.currentCaretPosition, this.getFileContent(this.activeFile.fileName).length); this.selectionEnd = -1; @@ -656,7 +656,7 @@ export class TestState { this.languageServiceAdapterHost.openFile(fileToOpen.fileName, content, scriptKindName); } - public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, shouldExist: boolean) { + public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, shouldExist: boolean): void { const startMarker = this.getMarkerByName(startMarkerName); const endMarker = this.getMarkerByName(endMarkerName); const predicate = (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number | undefined) => ((errorMinChar === startPos) && (errorLimChar === endPos)) ? true : false; @@ -669,7 +669,7 @@ export class TestState { } } - public verifyOrganizeImports(newContent: string, mode?: ts.OrganizeImportsMode, preferences?: ts.UserPreferences) { + public verifyOrganizeImports(newContent: string, mode?: ts.OrganizeImportsMode, preferences?: ts.UserPreferences): void { const changes = this.languageService.organizeImports({ fileName: this.activeFile.fileName, type: "file", mode }, this.formatCodeSettings, preferences); this.applyChanges(changes); this.verifyFileContent(this.activeFile.fileName, newContent); @@ -710,7 +710,7 @@ export class TestState { }); } - public verifyErrorExistsAfterMarker(markerName: string, shouldExist: boolean, after: boolean) { + public verifyErrorExistsAfterMarker(markerName: string, shouldExist: boolean, after: boolean): void { const marker: Marker = this.getMarkerByName(markerName); let predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number | undefined) => boolean; @@ -772,7 +772,7 @@ export class TestState { return "global"; } - public verifyNoErrors() { + public verifyNoErrors(): void { ts.forEachKey(this.inputFiles, fileName => { if ( !ts.isAnySupportedFileExtension(fileName) @@ -791,7 +791,7 @@ export class TestState { }); } - public verifyErrorExistsAtRange(range: Range, code: number, expectedMessage?: string) { + public verifyErrorExistsAtRange(range: Range, code: number, expectedMessage?: string): void { const span = ts.createTextSpanFromRange(range); const hasMatchingError = ts.some( this.getDiagnostics(range.fileName), @@ -807,7 +807,7 @@ export class TestState { } } - public verifyNumberOfErrorsInCurrentFile(expected: number) { + public verifyNumberOfErrorsInCurrentFile(expected: number): void { const errors = this.getDiagnostics(this.activeFile.fileName); const actual = errors.length; @@ -819,7 +819,7 @@ export class TestState { } } - public verifyEval(expr: string, value: any) { + public verifyEval(expr: string, value: any): void { const emit = this.languageService.getEmitOutput(this.activeFile.fileName); if (emit.outputFiles.length !== 1) { throw new Error("Expected exactly one output from emit of " + this.activeFile.fileName); @@ -899,7 +899,7 @@ export class TestState { public baselineGoToDefinition( markerOrRange: MarkerOrNameOrRange[] | undefined, rangeText: string[] | undefined, - ) { + ): void { this.baselineEachMarkerOrRange("goToDefinition", markerOrRange, rangeText, markerOrRange => this.baselineGoToDefs( "/*GOTO DEF*/", @@ -911,7 +911,7 @@ export class TestState { public baselineGetDefinitionAtPosition( markerOrRange: MarkerOrNameOrRange[] | undefined, rangeText: string[] | undefined, - ) { + ): void { this.baselineEachMarkerOrRange("getDefinitionAtPosition", markerOrRange, rangeText, markerOrRange => this.baselineGoToDefs( "/*GOTO DEF POS*/", @@ -923,7 +923,7 @@ export class TestState { public baselineGoToSourceDefinition( markerOrRange: MarkerOrNameOrRange[] | undefined, rangeText: string[] | undefined, - ) { + ): void { if (this.testType !== FourSlashTestType.Server) { this.raiseError("goToSourceDefinition may only be used in fourslash/server tests."); } @@ -940,7 +940,7 @@ export class TestState { public baselineGoToType( markerOrRange: MarkerOrNameOrRange[] | undefined, rangeText: string[] | undefined, - ) { + ): void { this.baselineEachMarkerOrRange("goToType", markerOrRange, rangeText, markerOrRange => this.baselineGoToDefs( "/*GOTO TYPE*/", @@ -952,7 +952,7 @@ export class TestState { public baselineGoToImplementation( markerOrRange: MarkerOrNameOrRange[] | undefined, rangeText: string[] | undefined, - ) { + ): void { this.baselineEachMarkerOrRange("goToImplementation", markerOrRange, rangeText, markerOrRange => this.baselineGoToDefs( "/*GOTO IMPL*/", @@ -1016,7 +1016,7 @@ export class TestState { this.baseline("Inlay Hints", annotations.join("\n\n")); } - public verifyCompletions(options: FourSlashInterface.VerifyCompletionsOptions) { + public verifyCompletions(options: FourSlashInterface.VerifyCompletionsOptions): FourSlashInterface.CompletionsResult | undefined { if (options.marker === undefined) { return this.verifyCompletionsWorker(options); } @@ -1410,7 +1410,7 @@ export class TestState { public baselineFindAllReferences( markerOrRange: MarkerOrNameOrRange[] | undefined, rangeText: string[] | undefined, - ) { + ): void { this.baselineEachMarkerOrRange("findAllReferences", markerOrRange, rangeText, markerOrRange => { this.goToMarkerOrNameOrRange(markerOrRange); const references = this.findReferencesAtCaret(); @@ -1460,7 +1460,7 @@ export class TestState { }); } - public baselineGetFileReferences(fileNames: string[]) { + public baselineGetFileReferences(fileNames: string[]): void { this.baselineArray("getFileReferences", fileNames, fileName => { const references = this.languageService.getFileReferences(fileName); return `// fileName: ${fileName}\n\n` + this.getBaselineForDocumentSpansWithFileContents( @@ -1838,7 +1838,7 @@ export class TestState { return this.languageService.findReferences(this.activeFile.fileName, this.currentCaretPosition); } - public getSyntacticDiagnostics(expected: readonly FourSlashInterface.Diagnostic[]) { + public getSyntacticDiagnostics(expected: readonly FourSlashInterface.Diagnostic[]): void { const diagnostics = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); this.testDiagnostics(expected, diagnostics, "error"); } @@ -1847,7 +1847,7 @@ export class TestState { return this.languageService.getSemanticDiagnostics(this.activeFile.fileName); } - public verifySemanticDiagnostics(expected: readonly FourSlashInterface.Diagnostic[]) { + public verifySemanticDiagnostics(expected: readonly FourSlashInterface.Diagnostic[]): void { const diagnostics = this.getSemanticDiagnostics(); this.testDiagnostics(expected, diagnostics, "error"); } @@ -1860,7 +1860,7 @@ export class TestState { ranges: ts.TextRange[], expectedDiagnostics: readonly FourSlashInterface.Diagnostic[] | undefined, expectedRanges: ts.TextRange[] | undefined, - ) { + ): void { const diagnosticsResult = this.languageService.getRegionSemanticDiagnostics(this.activeFile.fileName, ranges); if (diagnosticsResult && expectedDiagnostics) { this.testDiagnostics(expectedDiagnostics, diagnosticsResult.diagnostics, "error"); @@ -1903,14 +1903,14 @@ export class TestState { ); } - public verifyQuickInfoAt(markerName: string | Range, expectedText: string, expectedDocumentation?: string, expectedTags?: { name: string; text: string; }[]) { + public verifyQuickInfoAt(markerName: string | Range, expectedText: string, expectedDocumentation?: string, expectedTags?: { name: string; text: string; }[]): void { if (typeof markerName === "string") this.goToMarker(markerName); else this.goToRangeStart(markerName); this.verifyQuickInfoString(expectedText, expectedDocumentation, expectedTags); } - public verifyQuickInfos(namesAndTexts: { [name: string]: string | [string, string]; }) { + public verifyQuickInfos(namesAndTexts: { [name: string]: string | [string, string]; }): void { for (const name in namesAndTexts) { if (ts.hasProperty(namesAndTexts, name)) { const text = namesAndTexts[name]; @@ -1926,7 +1926,7 @@ export class TestState { } } - public verifyQuickInfoString(expectedText: string, expectedDocumentation?: string, expectedTags?: { name: string; text: string; }[]) { + public verifyQuickInfoString(expectedText: string, expectedDocumentation?: string, expectedTags?: { name: string; text: string; }[]): void { if (expectedDocumentation === "") { throw new Error("Use 'undefined' instead of empty string for `expectedDocumentation`"); } @@ -1951,7 +1951,7 @@ export class TestState { } } - public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: TextSpan, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: ts.JSDocTagInfo[] | undefined) { + public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: TextSpan, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: ts.JSDocTagInfo[] | undefined): void { const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition)!; assert.equal(actualQuickInfo.kind, kind, this.messageAtLastKnownMarker("QuickInfo kind")); assert.equal(actualQuickInfo.kindModifiers, kindModifiers, this.messageAtLastKnownMarker("QuickInfo kindModifiers")); @@ -1974,7 +1974,7 @@ export class TestState { markerOrRange: ArrayOrSingle | undefined, rangeText: ArrayOrSingle | undefined, options: FourSlashInterface.RenameOptions | undefined, - ) { + ): void { this.baselineEachMarkerOrRangeArrayOrSingle("findRenameLocations", markerOrRange, rangeText, markerOrRange => { const { fileName, position } = ts.isString(markerOrRange) ? this.getMarkerByName(markerOrRange) : @@ -2019,7 +2019,7 @@ export class TestState { }); } - public verifyQuickInfoExists(negative: boolean) { + public verifyQuickInfoExists(negative: boolean): void { const actualQuickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition); if (negative) { if (actualQuickInfo) { @@ -2033,7 +2033,7 @@ export class TestState { } } - public verifySignatureHelpPresence(expectPresent: boolean, triggerReason: ts.SignatureHelpTriggerReason | undefined, markers: readonly (string | Marker)[]) { + public verifySignatureHelpPresence(expectPresent: boolean, triggerReason: ts.SignatureHelpTriggerReason | undefined, markers: readonly (string | Marker)[]): void { if (markers.length) { for (const marker of markers) { this.goToMarker(marker); @@ -2052,7 +2052,7 @@ export class TestState { } } - public verifySignatureHelp(optionses: readonly FourSlashInterface.VerifySignatureHelpOptions[]) { + public verifySignatureHelp(optionses: readonly FourSlashInterface.VerifySignatureHelpOptions[]): void { for (const options of optionses) { if (options.marker === undefined) { this.verifySignatureHelpWorker(options); @@ -2179,7 +2179,7 @@ export class TestState { } } - public verifyRenameInfoFailed(message?: string, preferences?: ts.UserPreferences) { + public verifyRenameInfoFailed(message?: string, preferences?: ts.UserPreferences): void { const allowRenameOfImportPath = preferences?.allowRenameOfImportPath === undefined ? true : preferences.allowRenameOfImportPath; const renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition, { ...preferences, allowRenameOfImportPath }); if (renameInfo.canRename) { @@ -2330,11 +2330,11 @@ export class TestState { return resultString; } - public getBreakpointStatementLocation(pos: number) { + public getBreakpointStatementLocation(pos: number): ts.TextSpan | undefined { return this.languageService.getBreakpointStatementAtPosition(this.activeFile.fileName, pos); } - public baselineCurrentFileBreakpointLocations() { + public baselineCurrentFileBreakpointLocations(): void { this.baseline("breakpoints", this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos)!)); } @@ -2413,7 +2413,7 @@ export class TestState { return result; } - public baselineSyntacticDiagnostics() { + public baselineSyntacticDiagnostics(): void { const files = this.getCompilerTestFiles(); const result = this.getSyntacticDiagnosticBaselineText(files); this.baseline("Syntax Diagnostics", result); @@ -2426,7 +2426,7 @@ export class TestState { })); } - public baselineSyntacticAndSemanticDiagnostics() { + public baselineSyntacticAndSemanticDiagnostics(): void { const files = ts.filter(this.getCompilerTestFiles(), f => !ts.endsWith(f.unitName, ".json")); const result = this.getSyntacticDiagnosticBaselineText(files) + Harness.IO.newLine() @@ -2451,7 +2451,7 @@ export class TestState { return result; } - public baselineQuickInfo() { + public baselineQuickInfo(): void { const result = ts.arrayFrom(this.testData.markerPositions.entries(), ([name, marker]) => ({ marker: { ...marker, name }, item: this.languageService.getQuickInfoAtPosition(marker.fileName, marker.position), @@ -2469,7 +2469,7 @@ export class TestState { this.baseline("QuickInfo", annotations + "\n\n" + stringify(result)); } - public baselineSignatureHelp() { + public baselineSignatureHelp(): void { const result = ts.arrayFrom(this.testData.markerPositions.entries(), ([name, marker]) => ({ marker: { ...marker, name }, item: this.languageService.getSignatureHelpItems(marker.fileName, marker.position, /*options*/ undefined), @@ -2503,7 +2503,7 @@ export class TestState { this.baseline("SignatureHelp", annotations + "\n\n" + stringify(result)); } - public baselineCompletions(preferences?: ts.UserPreferences) { + public baselineCompletions(preferences?: ts.UserPreferences): void { const result = ts.arrayFrom(this.testData.markerPositions.entries(), ([name, marker]) => { this.goToMarker(marker); const completions = this.getCompletionListAtCaret(preferences); @@ -2610,7 +2610,7 @@ export class TestState { .join("\n\n"); } - public baselineSmartSelection() { + public baselineSmartSelection(): void { const n = "\n"; const markers = this.getMarkers(); const fileContent = this.activeFile.content; @@ -2642,25 +2642,25 @@ export class TestState { this.baseline("Smart Selection", text); } - public printBreakpointLocation(pos: number) { + public printBreakpointLocation(pos: number): void { Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(this.getBreakpointStatementLocation(pos)!, " ")); } - public printBreakpointAtCurrentLocation() { + public printBreakpointAtCurrentLocation(): void { this.printBreakpointLocation(this.currentCaretPosition); } - public printCurrentParameterHelp() { + public printCurrentParameterHelp(): void { const help = this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition, /*options*/ undefined); Harness.IO.log(stringify(help)); } - public printCurrentQuickInfo() { + public printCurrentQuickInfo(): void { const quickInfo = this.languageService.getQuickInfoAtPosition(this.activeFile.fileName, this.currentCaretPosition)!; Harness.IO.log("Quick Info: " + quickInfo.displayParts!.map(part => part.text).join("")); } - public printErrorList() { + public printErrorList(): void { const syntacticErrors = this.languageService.getSyntacticDiagnostics(this.activeFile.fileName); const semanticErrors = this.languageService.getSemanticDiagnostics(this.activeFile.fileName); const errorList = ts.concatenate(syntacticErrors, semanticErrors); @@ -2677,7 +2677,7 @@ export class TestState { } } - public printCurrentFileState(showWhitespace: boolean, makeCaretVisible: boolean) { + public printCurrentFileState(showWhitespace: boolean, makeCaretVisible: boolean): void { for (const file of this.testData.files) { const active = this.activeFile === file; Harness.IO.log(`=== Script (${file.fileName}) ${(active ? "(active, cursor at |)" : "")} ===`); @@ -2692,7 +2692,7 @@ export class TestState { } } - public printCurrentSignatureHelp() { + public printCurrentSignatureHelp(): void { const help = this.getSignatureHelp(ts.emptyOptions)!; Harness.IO.log(stringify(help.items[help.selectedItemIndex])); } @@ -2708,7 +2708,7 @@ export class TestState { }); } - public printCompletionListMembers(preferences: ts.UserPreferences | undefined) { + public printCompletionListMembers(preferences: ts.UserPreferences | undefined): void { const completions = this.getCompletionListAtCaret(preferences); this.printMembersOrCompletions(completions); } @@ -2725,11 +2725,11 @@ export class TestState { Harness.IO.log(formattedEntries.join("\n")); } - public printContext() { + public printContext(): void { ts.forEach(this.languageServiceAdapterHost.getFilenames(), Harness.IO.log); } - public deleteChar(count = 1) { + public deleteChar(count = 1): void { let offset = this.currentCaretPosition; const ch = ""; @@ -2754,12 +2754,12 @@ export class TestState { this.checkPostEditInvariants(); } - public replace(start: number, length: number, text: string) { + public replace(start: number, length: number, text: string): void { this.editScriptAndUpdateMarkers(this.activeFile.fileName, start, start + length, text); this.checkPostEditInvariants(); } - public deleteLineRange(startIndex: number, endIndexInclusive: number) { + public deleteLineRange(startIndex: number, endIndexInclusive: number): void { const startPos = this.languageServiceAdapterHost.lineAndCharacterToPosition(this.activeFile.fileName, { line: startIndex, character: 0 }); const endPos = this.languageServiceAdapterHost.lineAndCharacterToPosition(this.activeFile.fileName, { line: endIndexInclusive + 1, character: 0 }); this.replace(startPos, endPos - startPos, ""); @@ -2769,7 +2769,7 @@ export class TestState { return { fileName: this.activeFile.fileName, position: this.currentCaretPosition }; } - public deleteCharBehindMarker(count = 1) { + public deleteCharBehindMarker(count = 1): void { let offset = this.currentCaretPosition; const ch = ""; const checkCadence = (count >> 2) + 1; @@ -2790,7 +2790,7 @@ export class TestState { } // Enters lines of text at the current caret position - public type(text: string, highFidelity = false) { + public type(text: string, highFidelity = false): void { let offset = this.currentCaretPosition; const prevChar = " "; const checkCadence = (text.length >> 2) + 1; @@ -2840,7 +2840,7 @@ export class TestState { } // Enters text as if the user had pasted it - public paste(text: string) { + public paste(text: string): void { const start = this.currentCaretPosition; this.editScriptAndUpdateMarkers(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition, text); this.checkPostEditInvariants(); @@ -2937,17 +2937,17 @@ export class TestState { return oldFormatCodeOptions; } - public formatDocument() { + public formatDocument(): void { const edits = this.languageService.getFormattingEditsForDocument(this.activeFile.fileName, this.formatCodeSettings); this.applyEdits(this.activeFile.fileName, edits); } - public formatSelection(start: number, end: number) { + public formatSelection(start: number, end: number): void { const edits = this.languageService.getFormattingEditsForRange(this.activeFile.fileName, start, end, this.formatCodeSettings); this.applyEdits(this.activeFile.fileName, edits); } - public formatOnType(pos: number, key: string) { + public formatOnType(pos: number, key: string): void { const edits = this.languageService.getFormattingEditsAfterKeystroke(this.activeFile.fileName, pos, key, this.formatCodeSettings); this.applyEdits(this.activeFile.fileName, edits); } @@ -2976,16 +2976,16 @@ export class TestState { return text.replace(/\s/g, ""); } - public goToBOF() { + public goToBOF(): void { this.goToPosition(0); } - public goToEOF() { + public goToEOF(): void { const len = this.getFileContent(this.activeFile.fileName).length; this.goToPosition(len); } - public goToRangeStart({ fileName, pos }: Range) { + public goToRangeStart({ fileName, pos }: Range): void { this.openFile(fileName); this.goToPosition(pos); } @@ -3003,7 +3003,7 @@ export class TestState { return this.testData.ranges; } - public getRangesInFile(fileName = this.activeFile.fileName) { + public getRangesInFile(fileName: string = this.activeFile.fileName): Range[] { return this.getRanges().filter(r => r.fileName === fileName); } @@ -3022,7 +3022,7 @@ export class TestState { return this.getFileContent(fileName).slice(pos, end); } - public verifyCaretAtMarker(markerName = "") { + public verifyCaretAtMarker(markerName = ""): void { const pos = this.getMarkerByName(markerName); if (pos.fileName !== this.activeFile.fileName) { throw new Error(`verifyCaretAtMarker failed - expected to be in file "${pos.fileName}", but was in file "${this.activeFile.fileName}"`); @@ -3039,7 +3039,7 @@ export class TestState { return this.languageService.getIndentationAtPosition(fileName, position, formatOptions); } - public verifyIndentationAtCurrentPosition(numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart, baseIndentSize = 0) { + public verifyIndentationAtCurrentPosition(numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart, baseIndentSize = 0): void { const actual = this.getIndentation(this.activeFile.fileName, this.currentCaretPosition, indentStyle, baseIndentSize); const lineCol = this.getLineColStringAtPosition(this.currentCaretPosition); if (actual !== numberOfSpaces) { @@ -3047,7 +3047,7 @@ export class TestState { } } - public verifyIndentationAtPosition(fileName: string, position: number, numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart, baseIndentSize = 0) { + public verifyIndentationAtPosition(fileName: string, position: number, numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart, baseIndentSize = 0): void { const actual = this.getIndentation(fileName, position, indentStyle, baseIndentSize); const lineCol = this.getLineColStringAtPosition(position); if (actual !== numberOfSpaces) { @@ -3055,14 +3055,14 @@ export class TestState { } } - public verifyCurrentLineContent(text: string) { + public verifyCurrentLineContent(text: string): void { const actual = this.getCurrentLineContent(); if (actual !== text) { throw new Error("verifyCurrentLineContent\n" + displayExpectedAndActualString(text, actual, /*quoted*/ true)); } } - public verifyCurrentFileContent(text: string) { + public verifyCurrentFileContent(text: string): void { this.verifyFileContent(this.activeFile.fileName, text); } @@ -3080,14 +3080,14 @@ export class TestState { this.verifyFileContent(fileName, before); } - public verifyTextAtCaretIs(text: string) { + public verifyTextAtCaretIs(text: string): void { const actual = this.getFileContent(this.activeFile.fileName).substring(this.currentCaretPosition, this.currentCaretPosition + text.length); if (actual !== text) { throw new Error("verifyTextAtCaretIs\n" + displayExpectedAndActualString(text, actual, /*quoted*/ true)); } } - public verifyCurrentNameOrDottedNameSpanText(text: string) { + public verifyCurrentNameOrDottedNameSpanText(text: string): undefined { const span = this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, this.currentCaretPosition, this.currentCaretPosition); if (!span) { return this.raiseError("verifyCurrentNameOrDottedNameSpanText\n" + displayExpectedAndActualString('"' + text + '"', "undefined")); @@ -3103,14 +3103,14 @@ export class TestState { return this.languageService.getNameOrDottedNameSpan(this.activeFile.fileName, pos, pos); } - public baselineCurrentFileNameOrDottedNameSpans() { + public baselineCurrentFileNameOrDottedNameSpans(): void { this.baseline( "NameOrDottedNameSpans", this.baselineCurrentFileLocations(pos => this.getNameOrDottedNameSpan(pos)!), ); } - public printNameOrDottedNameSpans(pos: number) { + public printNameOrDottedNameSpans(pos: number): void { Harness.IO.log(this.spanInfoToString(this.getNameOrDottedNameSpan(pos)!, "**")); } @@ -3211,7 +3211,7 @@ export class TestState { } } - public verifyProjectInfo(expected: string[]) { + public verifyProjectInfo(expected: string[]): void { if (this.testType === FourSlashTestType.Server) { const actual = (this.languageService as ts.server.SessionClient).getProjectInfo( this.activeFile.fileName, @@ -3226,7 +3226,7 @@ export class TestState { } } - public replaceWithSemanticClassifications(format: ts.SemanticClassificationFormat.TwentyTwenty) { + public replaceWithSemanticClassifications(format: ts.SemanticClassificationFormat.TwentyTwenty): void { const actual = this.languageService.getSemanticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length), format); const replacement = [`const c2 = classification("2020");`, `verify.semanticClassificationsAre("2020",`]; for (const a of actual) { @@ -3245,32 +3245,32 @@ export class TestState { // fs.writeFileSync(testfilePath, newfile); } - public verifyEncodedSyntacticClassificationsLength(expected: number) { + public verifyEncodedSyntacticClassificationsLength(expected: number): void { const actual = this.languageService.getEncodedSyntacticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length)); if (actual.spans.length !== expected) { this.raiseError(`encodedSyntacticClassificationsLength failed - expected total spans to be ${expected} got ${actual.spans.length}`); } } - public verifyEncodedSemanticClassificationsLength(format: ts.SemanticClassificationFormat, expected: number) { + public verifyEncodedSemanticClassificationsLength(format: ts.SemanticClassificationFormat, expected: number): void { const actual = this.languageService.getEncodedSemanticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length), format); if (actual.spans.length !== expected) { this.raiseError(`encodedSemanticClassificationsLength failed - expected total spans to be ${expected} got ${actual.spans.length}`); } } - public verifySemanticClassifications(format: ts.SemanticClassificationFormat, expected: { classificationType: string | number; text?: string; }[]) { + public verifySemanticClassifications(format: ts.SemanticClassificationFormat, expected: { classificationType: string | number; text?: string; }[]): void { const actual = this.languageService.getSemanticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length), format); this.verifyClassifications(expected, actual, this.activeFile.content); } - public verifySyntacticClassifications(expected: { classificationType: string; text: string; }[]) { + public verifySyntacticClassifications(expected: { classificationType: string; text: string; }[]): void { const actual = this.languageService.getSyntacticClassifications(this.activeFile.fileName, ts.createTextSpan(0, this.activeFile.content.length)); this.verifyClassifications(expected, actual, this.activeFile.content); } - public printOutliningSpans() { + public printOutliningSpans(): void { const spans = this.languageService.getOutliningSpans(this.activeFile.fileName); Harness.IO.log(`Outlining spans (${spans.length} items)\nResults:`); Harness.IO.log(stringify(spans)); @@ -3292,7 +3292,7 @@ export class TestState { Harness.IO.log(`\nMockup:\n${annotated}`); } - public verifyOutliningSpans(spans: Range[], kind?: "comment" | "region" | "code" | "imports") { + public verifyOutliningSpans(spans: Range[], kind?: "comment" | "region" | "code" | "imports"): void { const actual = this.languageService.getOutliningSpans(this.activeFile.fileName); const filterActual = ts.filter(actual, f => kind === undefined ? true : f.kind === kind); @@ -3310,7 +3310,7 @@ export class TestState { }); } - public verifyOutliningHintSpans(spans: Range[]) { + public verifyOutliningHintSpans(spans: Range[]): void { const actual = this.languageService.getOutliningSpans(this.activeFile.fileName); if (actual.length !== spans.length) { @@ -3324,7 +3324,7 @@ export class TestState { }); } - public verifyTodoComments(descriptors: string[], spans: Range[]) { + public verifyTodoComments(descriptors: string[], spans: Range[]): void { const actual = this.languageService.getTodoComments(this.activeFile.fileName, descriptors.map(d => ({ text: d, priority: 0 }))); if (actual.length !== spans.length) { @@ -3346,7 +3346,7 @@ export class TestState { * @param errorCode The error code that generated the code action. * @param index The nth (0-index-based) codeaction available generated by errorCode. */ - public getAndApplyCodeActions(errorCode?: number, index?: number) { + public getAndApplyCodeActions(errorCode?: number, index?: number): void { const fileName = this.activeFile.fileName; const fixes = this.getCodeFixes(fileName, errorCode); if (index === undefined) { @@ -3364,7 +3364,7 @@ export class TestState { this.applyChanges(fixes[index].changes); } - public applyCodeActionFromCompletion(markerName: string | undefined, options: FourSlashInterface.VerifyCompletionActionOptions) { + public applyCodeActionFromCompletion(markerName: string | undefined, options: FourSlashInterface.VerifyCompletionActionOptions): undefined { if (markerName !== undefined) { this.goToMarker(markerName); } @@ -3392,7 +3392,7 @@ export class TestState { this.verifyNewContentAfterChange(options, ts.flatMap(codeActions, a => a.changes.map(c => c.fileName))); } - public verifyRangeIs(expectedText: string, includeWhiteSpace?: boolean) { + public verifyRangeIs(expectedText: string, includeWhiteSpace?: boolean): void { this.verifyTextMatches(this.rangeText(this.getOnlyRange()), !!includeWhiteSpace, expectedText); } @@ -3416,7 +3416,7 @@ export class TestState { * (ie: [|...|]) in the file after applying the codefix sole codefix * in the source file. */ - public verifyRangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number) { + public verifyRangeAfterCodeFix(expectedText: string, includeWhiteSpace?: boolean, errorCode?: number, index?: number): void { this.getAndApplyCodeActions(errorCode, index); this.verifyRangeIs(expectedText, includeWhiteSpace); } @@ -3435,7 +3435,7 @@ export class TestState { this.verifyNewContent({ newFileContent }, changes); } - public verifyCodeFix(options: FourSlashInterface.VerifyCodeFixOptions) { + public verifyCodeFix(options: FourSlashInterface.VerifyCodeFixOptions): void { const fileName = this.activeFile.fileName; const actions = this.getCodeFixes(fileName, options.errorCode, options.preferences); let index = options.index; @@ -3562,7 +3562,7 @@ export class TestState { } } - public verifyImportFixAtPosition(expectedTextArray: string[], errorCode: number | undefined, preferences: ts.UserPreferences | undefined) { + public verifyImportFixAtPosition(expectedTextArray: string[], errorCode: number | undefined, preferences: ts.UserPreferences | undefined): void { const { fileName } = this.activeFile; const ranges = this.getRanges().filter(r => r.fileName === fileName); if (ranges.length > 1) { @@ -3612,7 +3612,7 @@ export class TestState { }); } - public verifyImportFixModuleSpecifiers(markerName: string, moduleSpecifiers: string[], preferences?: ts.UserPreferences) { + public verifyImportFixModuleSpecifiers(markerName: string, moduleSpecifiers: string[], preferences?: ts.UserPreferences): void { const marker = this.getMarkerByName(markerName); const codeFixes = this.getCodeFixes(marker.fileName, ts.Diagnostics.Cannot_find_name_0.code, { includeCompletionsForModuleExports: true, @@ -3635,7 +3635,7 @@ export class TestState { this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits); } - public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined, options?: ts.DocCommentTemplateOptions) { + public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined, options?: ts.DocCommentTemplateOptions): void { const name = "verifyDocCommentTemplate"; const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition, options || { generateReturnInDocTemplate: true }, this.formatCodeSettings)!; @@ -3661,7 +3661,7 @@ export class TestState { } } - public verifyBraceCompletionAtPosition(negative: boolean, openingBrace: string) { + public verifyBraceCompletionAtPosition(negative: boolean, openingBrace: string): void { const openBraceMap = new Map(Object.entries({ "(": ts.CharacterCodes.openParen, "{": ts.CharacterCodes.openBrace, @@ -3690,7 +3690,7 @@ export class TestState { } } - public baselineAutoImports(markerName: string, fullNamesForCodeFix?: string[], preferences?: ts.UserPreferences) { + public baselineAutoImports(markerName: string, fullNamesForCodeFix?: string[], preferences?: ts.UserPreferences): void { const marker = this.getMarkerByName(markerName); const completionPreferences = { includeCompletionsForModuleExports: true, @@ -3844,7 +3844,7 @@ export class TestState { } } - public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) { + public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number): void { const actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); if (actual.length !== 2) { @@ -3867,7 +3867,7 @@ export class TestState { } } - public verifyNoMatchingBracePosition(bracePosition: number) { + public verifyNoMatchingBracePosition(bracePosition: number): void { const actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); if (actual.length !== 0) { @@ -3875,7 +3875,7 @@ export class TestState { } } - public verifySpanOfEnclosingComment(negative: boolean, onlyMultiLineDiverges?: boolean) { + public verifySpanOfEnclosingComment(negative: boolean, onlyMultiLineDiverges?: boolean): void { const expected = !negative; const position = this.currentCaretPosition; const fileName = this.activeFile.fileName; @@ -3913,11 +3913,11 @@ export class TestState { } } - public verifyNavigationBar(json: any, options: { checkSpans?: boolean; } | undefined) { + public verifyNavigationBar(json: any, options: { checkSpans?: boolean; } | undefined): void { this.verifyNavigationTreeOrBar(json, this.languageService.getNavigationBarItems(this.activeFile.fileName), "Bar", options); } - public verifyNavigationTree(json: any, options: { checkSpans?: boolean; } | undefined) { + public verifyNavigationTree(json: any, options: { checkSpans?: boolean; } | undefined): void { this.verifyNavigationTreeOrBar(json, this.languageService.getNavigationTree(this.activeFile.fileName), "Tree", options); } @@ -3944,7 +3944,7 @@ export class TestState { } } - public printNavigationItems(searchValue: string) { + public printNavigationItems(searchValue: string): void { const items = this.languageService.getNavigateToItems(searchValue); Harness.IO.log(`NavigationItems list (${items.length} items)`); for (const item of items) { @@ -3952,7 +3952,7 @@ export class TestState { } } - public printNavigationBar() { + public printNavigationBar(): void { const items = this.languageService.getNavigationBarItems(this.activeFile.fileName); Harness.IO.log(`Navigation bar (${items.length} items)`); for (const item of items) { @@ -3969,7 +3969,7 @@ export class TestState { markerOrRange: ArrayOrSingle | undefined, rangeText: ArrayOrSingle | undefined, options: FourSlashInterface.VerifyDocumentHighlightsOptions | undefined, - ) { + ): void { this.baselineEachMarkerOrRangeArrayOrSingle( "documentHighlights", markerOrRange, @@ -4015,7 +4015,7 @@ export class TestState { } } - public verifyCodeFixAllAvailable(negative: boolean, fixName: string) { + public verifyCodeFixAllAvailable(negative: boolean, fixName: string): void { const availableFixes = this.getCodeFixes(this.activeFile.fileName); const hasFix = availableFixes.some(fix => fix.fixName === fixName && fix.fixId); if (negative && hasFix) { @@ -4035,7 +4035,7 @@ export class TestState { } } - public verifyApplicableRefactorAvailableAtMarker(negative: boolean, markerName: string) { + public verifyApplicableRefactorAvailableAtMarker(negative: boolean, markerName: string): void { const isAvailable = this.getApplicableRefactors(this.getMarkerByName(markerName)).length > 0; if (negative && isAvailable) { this.raiseError(`verifyApplicableRefactorAvailableAtMarker failed - expected no refactor at marker ${markerName} but found some.`); @@ -4052,7 +4052,7 @@ export class TestState { }; } - public verifyRefactorAvailable(negative: boolean, triggerReason: ts.RefactorTriggerReason, name: string, actionName?: string, actionDescription?: string, kind?: string, preferences = ts.emptyOptions, includeInteractiveActions?: boolean) { + public verifyRefactorAvailable(negative: boolean, triggerReason: ts.RefactorTriggerReason, name: string, actionName?: string, actionDescription?: string, kind?: string, preferences: {} = ts.emptyOptions, includeInteractiveActions?: boolean): void { let refactors = this.getApplicableRefactorsAtSelection(triggerReason, kind, preferences, includeInteractiveActions); refactors = refactors.filter(r => r.name === name); @@ -4083,7 +4083,7 @@ export class TestState { } } - public verifyRefactorKindsAvailable(kind: string, expected: string[], preferences = ts.emptyOptions) { + public verifyRefactorKindsAvailable(kind: string, expected: string[], preferences: {} = ts.emptyOptions): void { const refactors = this.getApplicableRefactorsAtSelection("invoked", kind, preferences); const availableKinds = ts.flatMap(refactors, refactor => refactor.actions).map(action => action.kind); assert.deepEqual(availableKinds.slice().sort(), expected.slice().sort(), `Expected kinds to be equal`); @@ -4093,7 +4093,7 @@ export class TestState { assert.deepEqual(unique(this.getApplicableRefactorsAtSelection(), r => r.name), names); } - public verifyApplicableRefactorAvailableForRange(negative: boolean) { + public verifyApplicableRefactorAvailableForRange(negative: boolean): void { const ranges = this.getRanges(); if (!(ranges && ranges.length === 1)) { throw new Error("Exactly one refactor range is allowed per test."); @@ -4108,7 +4108,7 @@ export class TestState { } } - public applyRefactor({ refactorName, actionName, actionDescription, newContent: newContentWithRenameMarker, triggerReason }: FourSlashInterface.ApplyRefactorOptions) { + public applyRefactor({ refactorName, actionName, actionDescription, newContent: newContentWithRenameMarker, triggerReason }: FourSlashInterface.ApplyRefactorOptions): void { const range = this.getSelection(); const refactors = this.getApplicableRefactorsAtSelection(triggerReason); const refactorsWithName = refactors.filter(r => r.name === refactorName); @@ -4169,7 +4169,7 @@ export class TestState { } } - public noMoveToNewFile() { + public noMoveToNewFile(): void { const ranges = this.getRanges(); assert(ranges.length); for (const range of ranges) { @@ -4239,7 +4239,7 @@ export class TestState { refactorNameToApply: string, actionName: string, formattingOptions?: ts.FormatCodeSettings, - ) { + ): void { formattingOptions = formattingOptions || this.formatCodeSettings; const marker = this.getMarkerByName(markerName); @@ -4262,7 +4262,7 @@ export class TestState { } } - public printAvailableCodeFixes() { + public printAvailableCodeFixes(): void { const codeFixes = this.getCodeFixes(this.activeFile.fileName); Harness.IO.log(stringify(codeFixes)); } @@ -4392,7 +4392,7 @@ export class TestState { return text; } - public baselineCallHierarchy() { + public baselineCallHierarchy(): void { const callHierarchyItem = this.languageService.prepareCallHierarchy(this.activeFile.fileName, this.currentCaretPosition); const text = callHierarchyItem ? ts.mapOneOrMany(callHierarchyItem, item => this.formatCallHierarchy(item), result => result.join("")) : "none"; this.baseline("Call Hierarchy", text, ".callHierarchy.txt"); @@ -4484,7 +4484,7 @@ export class TestState { return `line ${(pos.line + 1)}, col ${pos.character}`; } - public getMarkerByName(markerName: string) { + public getMarkerByName(markerName: string): Marker { const markerPos = this.testData.markerPositions.get(markerName); if (markerPos === undefined) { throw new Error(`Unknown marker "${markerName}" Available markers: ${this.getMarkerNames().map(m => '"' + m + '"').join(", ")}`); @@ -4532,7 +4532,7 @@ export class TestState { (this.languageService as ts.server.SessionClient).configurePlugin(pluginName, configuration); } - public setCompilerOptionsForInferredProjects(options: ts.server.protocol.CompilerOptions) { + public setCompilerOptionsForInferredProjects(options: ts.server.protocol.CompilerOptions): void { ts.Debug.assert(this.testType === FourSlashTestType.Server); (this.languageService as ts.server.SessionClient).setCompilerOptionsForInferredProjects(options); } @@ -4675,7 +4675,7 @@ export interface FourSlashServerLogBaseliner { baseline?: () => void; } -export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string, serverLogBaseliner?: FourSlashServerLogBaseliner) { +export function runFourSlashTest(basePath: string, testType: FourSlashTestType, fileName: string, serverLogBaseliner?: FourSlashServerLogBaseliner): void { const content = Harness.IO.readFile(fileName)!; runFourSlashTestContent(basePath, testType, content, fileName, serverLogBaseliner); } diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index eaa9699158914..8af5de8cdc5ba 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -17,7 +17,7 @@ export class Test { return this.state.getMarkerByName(name); } - public markerName(m: FourSlash.Marker) { + public markerName(m: FourSlash.Marker): string { return this.state.markerName(m); } @@ -83,7 +83,7 @@ export class GoTo { // Moves the caret to the specified marker, // or the anonymous marker ('/**/') if no name // is given - public marker(name?: string | FourSlash.Marker) { + public marker(name?: string | FourSlash.Marker): void { this.state.goToMarker(name); } @@ -94,19 +94,19 @@ export class GoTo { this.state.goToEachMarker(markers, typeof a === "function" ? a : b!); } - public rangeStart(range: FourSlash.Range) { + public rangeStart(range: FourSlash.Range): void { this.state.goToRangeStart(range); } - public eachRange(action: (range: FourSlash.Range) => void) { + public eachRange(action: (range: FourSlash.Range) => void): void { this.state.goToEachRange(action); } - public bof() { + public bof(): void { this.state.goToBOF(); } - public eof() { + public eof(): void { this.state.goToEOF(); } @@ -124,11 +124,11 @@ export class GoTo { this.state.openFile(indexOrName, content, scriptKindName); } - public select(startMarker: string, endMarker: string) { + public select(startMarker: string, endMarker: string): void { this.state.select(startMarker, endMarker); } - public selectAllInFile(fileName: string) { + public selectAllInFile(fileName: string): void { this.state.selectAllInFile(fileName); } @@ -146,7 +146,7 @@ export class VerifyNegatable { } } - public assertHasRanges(ranges: FourSlash.Range[]) { + public assertHasRanges(ranges: FourSlash.Range[]): void { assert(ranges.length !== 0, "Array of ranges is expected to be non-empty"); } @@ -166,23 +166,23 @@ export class VerifyNegatable { this.state.verifySignatureHelp(options); } - public errorExistsBetweenMarkers(startMarker: string, endMarker: string) { + public errorExistsBetweenMarkers(startMarker: string, endMarker: string): void { this.state.verifyErrorExistsBetweenMarkers(startMarker, endMarker, !this.negative); } - public errorExistsAfterMarker(markerName = "") { + public errorExistsAfterMarker(markerName = ""): void { this.state.verifyErrorExistsAfterMarker(markerName, !this.negative, /*after*/ true); } - public errorExistsBeforeMarker(markerName = "") { + public errorExistsBeforeMarker(markerName = ""): void { this.state.verifyErrorExistsAfterMarker(markerName, !this.negative, /*after*/ false); } - public quickInfoExists() { + public quickInfoExists(): void { this.state.verifyQuickInfoExists(this.negative); } - public isValidBraceCompletionAtPosition(openingBrace: string) { + public isValidBraceCompletionAtPosition(openingBrace: string): void { this.state.verifyBraceCompletionAtPosition(this.negative, openingBrace); } @@ -198,27 +198,27 @@ export class VerifyNegatable { this.state.baselineLinkedEditing(); } - public isInCommentAtPosition(onlyMultiLineDiverges?: boolean) { + public isInCommentAtPosition(onlyMultiLineDiverges?: boolean): void { this.state.verifySpanOfEnclosingComment(this.negative, onlyMultiLineDiverges); } - public codeFix(options: VerifyCodeFixOptions) { + public codeFix(options: VerifyCodeFixOptions): void { this.state.verifyCodeFix(options); } - public codeFixAvailable(options?: VerifyCodeFixAvailableOptions[]) { + public codeFixAvailable(options?: VerifyCodeFixAvailableOptions[]): void { this.state.verifyCodeFixAvailable(this.negative, options); } - public codeFixAllAvailable(fixName: string) { + public codeFixAllAvailable(fixName: string): void { this.state.verifyCodeFixAllAvailable(this.negative, fixName); } - public applicableRefactorAvailableAtMarker(markerName: string) { + public applicableRefactorAvailableAtMarker(markerName: string): void { this.state.verifyApplicableRefactorAvailableAtMarker(this.negative, markerName); } - public applicableRefactorAvailableForRange() { + public applicableRefactorAvailableForRange(): void { this.state.verifyApplicableRefactorAvailableForRange(this.negative); } @@ -226,31 +226,31 @@ export class VerifyNegatable { this.state.verifyRefactorsAvailable(names); } - public refactorAvailable(name: string, actionName?: string, actionDescription?: string, kind?: string, preferences = ts.emptyOptions, includeInteractiveActions?: boolean) { + public refactorAvailable(name: string, actionName?: string, actionDescription?: string, kind?: string, preferences: {} = ts.emptyOptions, includeInteractiveActions?: boolean): void { this.state.verifyRefactorAvailable(this.negative, "implicit", name, actionName, actionDescription, kind, preferences, includeInteractiveActions); } - public refactorAvailableForTriggerReason(triggerReason: ts.RefactorTriggerReason, name: string, actionName?: string, actionDescription?: string, kind?: string, preferences = ts.emptyOptions, includeInteractiveActions?: boolean) { + public refactorAvailableForTriggerReason(triggerReason: ts.RefactorTriggerReason, name: string, actionName?: string, actionDescription?: string, kind?: string, preferences: {} = ts.emptyOptions, includeInteractiveActions?: boolean): void { this.state.verifyRefactorAvailable(this.negative, triggerReason, name, actionName, actionDescription, kind, preferences, includeInteractiveActions); } - public refactorKindAvailable(kind: string, expected: string[], preferences = ts.emptyOptions) { + public refactorKindAvailable(kind: string, expected: string[], preferences: {} = ts.emptyOptions): void { this.state.verifyRefactorKindsAvailable(kind, expected, preferences); } - public toggleLineComment(newFileContent: string) { + public toggleLineComment(newFileContent: string): void { this.state.toggleLineComment(newFileContent); } - public toggleMultilineComment(newFileContent: string) { + public toggleMultilineComment(newFileContent: string): void { this.state.toggleMultilineComment(newFileContent); } - public commentSelection(newFileContent: string) { + public commentSelection(newFileContent: string): void { this.state.commentSelection(newFileContent); } - public uncommentSelection(newFileContent: string) { + public uncommentSelection(newFileContent: string): void { this.state.uncommentSelection(newFileContent); } @@ -259,12 +259,22 @@ export class VerifyNegatable { } } +export interface CompletionsResult { + andApplyCodeAction: (options: { + name: string; + source: string; + description: string; + newFileContent?: string; + newRangeContent?: string; + }) => void; +} + export class Verify extends VerifyNegatable { constructor(state: FourSlash.TestState) { super(state); } - public completions(...optionsArray: VerifyCompletionsOptions[]) { + public completions(...optionsArray: VerifyCompletionsOptions[]): CompletionsResult | undefined { if (optionsArray.length === 1) { return this.state.verifyCompletions(optionsArray[0]); } @@ -278,35 +288,35 @@ export class Verify extends VerifyNegatable { }; } - public baselineInlayHints(span: ts.TextSpan, preference?: ts.UserPreferences) { + public baselineInlayHints(span: ts.TextSpan, preference?: ts.UserPreferences): void { this.state.baselineInlayHints(span, preference); } - public quickInfoIs(expectedText: string, expectedDocumentation?: string, expectedTags?: { name: string; text: string; }[]) { + public quickInfoIs(expectedText: string, expectedDocumentation?: string, expectedTags?: { name: string; text: string; }[]): void { this.state.verifyQuickInfoString(expectedText, expectedDocumentation, expectedTags); } - public quickInfoAt(markerName: string | FourSlash.Range, expectedText: string, expectedDocumentation?: string, expectedTags?: { name: string; text: string; }[]) { + public quickInfoAt(markerName: string | FourSlash.Range, expectedText: string, expectedDocumentation?: string, expectedTags?: { name: string; text: string; }[]): void { this.state.verifyQuickInfoAt(markerName, expectedText, expectedDocumentation, expectedTags); } - public quickInfos(namesAndTexts: { [name: string]: string; }) { + public quickInfos(namesAndTexts: { [name: string]: string; }): void { this.state.verifyQuickInfos(namesAndTexts); } - public caretAtMarker(markerName?: string) { + public caretAtMarker(markerName?: string): void { this.state.verifyCaretAtMarker(markerName); } - public indentationIs(numberOfSpaces: number) { + public indentationIs(numberOfSpaces: number): void { this.state.verifyIndentationAtCurrentPosition(numberOfSpaces); } - public indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle = ts.IndentStyle.Smart, baseIndentSize = 0) { + public indentationAtPositionIs(fileName: string, position: number, numberOfSpaces: number, indentStyle: ts.IndentStyle = ts.IndentStyle.Smart, baseIndentSize = 0): void { this.state.verifyIndentationAtPosition(fileName, position, numberOfSpaces, indentStyle, baseIndentSize); } - public textAtCaretIs(text: string) { + public textAtCaretIs(text: string): void { this.state.verifyTextAtCaretIs(text); } @@ -315,15 +325,15 @@ export class Verify extends VerifyNegatable { * the emitted output, then compares (using ===) the result of that expression * to 'value'. Do not use this function with external modules as it is not supported. */ - public eval(expr: string, value: any) { + public eval(expr: string, value: any): void { this.state.verifyEval(expr, value); } - public currentLineContentIs(text: string) { + public currentLineContentIs(text: string): void { this.state.verifyCurrentLineContent(text); } - public currentFileContentIs(text: string) { + public currentFileContentIs(text: string): void { this.state.verifyCurrentFileContent(text); } @@ -339,95 +349,95 @@ export class Verify extends VerifyNegatable { this.state.verifyGetEmitOutputContentsForCurrentFile(expected); } - public symbolAtLocation(startRange: FourSlash.Range, ...declarationRanges: FourSlash.Range[]) { + public symbolAtLocation(startRange: FourSlash.Range, ...declarationRanges: FourSlash.Range[]): void { this.state.verifySymbolAtLocation(startRange, declarationRanges); } - public typeOfSymbolAtLocation(range: FourSlash.Range, symbol: ts.Symbol, expected: string) { + public typeOfSymbolAtLocation(range: FourSlash.Range, symbol: ts.Symbol, expected: string): void { this.state.verifyTypeOfSymbolAtLocation(range, symbol, expected); } - public typeAtLocation(range: FourSlash.Range, expected: string) { + public typeAtLocation(range: FourSlash.Range, expected: string): void { this.state.verifyTypeAtLocation(range, expected); } - public baselineFindAllReferences(...markerOrRange: FourSlash.MarkerOrNameOrRange[]) { + public baselineFindAllReferences(...markerOrRange: FourSlash.MarkerOrNameOrRange[]): void { this.state.baselineFindAllReferences(markerOrRange, /*rangeText*/ undefined); } - public baselineFindAllReferencesAtRangesWithText(...rangeText: string[]) { + public baselineFindAllReferencesAtRangesWithText(...rangeText: string[]): void { this.state.baselineFindAllReferences(/*markerOrRange*/ undefined, rangeText); } - public baselineGetFileReferences(...fileName: string[]) { + public baselineGetFileReferences(...fileName: string[]): void { this.state.baselineGetFileReferences(fileName); } - public baselineGoToDefinition(...markerOrRange: FourSlash.MarkerOrNameOrRange[]) { + public baselineGoToDefinition(...markerOrRange: FourSlash.MarkerOrNameOrRange[]): void { this.state.baselineGoToDefinition(markerOrRange, /*rangeText*/ undefined); } - public baselineGoToDefinitionAtRangesWithText(...rangeText: string[]) { + public baselineGoToDefinitionAtRangesWithText(...rangeText: string[]): void { this.state.baselineGoToDefinition(/*markerOrRange*/ undefined, rangeText); } - public baselineGetDefinitionAtPosition(...markerOrRange: FourSlash.MarkerOrNameOrRange[]) { + public baselineGetDefinitionAtPosition(...markerOrRange: FourSlash.MarkerOrNameOrRange[]): void { this.state.baselineGetDefinitionAtPosition(markerOrRange, /*rangeText*/ undefined); } - public baselineGetDefinitionAtRangesWithText(...rangeText: string[]) { + public baselineGetDefinitionAtRangesWithText(...rangeText: string[]): void { this.state.baselineGetDefinitionAtPosition(/*markerOrRange*/ undefined, rangeText); } - public baselineGoToSourceDefinition(...markerOrRange: FourSlash.MarkerOrNameOrRange[]) { + public baselineGoToSourceDefinition(...markerOrRange: FourSlash.MarkerOrNameOrRange[]): void { this.state.baselineGoToSourceDefinition(markerOrRange, /*rangeText*/ undefined); } - public baselineGoToSourceDefinitionAtRangesWithText(...rangeText: string[]) { + public baselineGoToSourceDefinitionAtRangesWithText(...rangeText: string[]): void { this.state.baselineGoToSourceDefinition(/*markerOrRange*/ undefined, rangeText); } - public baselineGoToType(...markerOrRange: FourSlash.MarkerOrNameOrRange[]) { + public baselineGoToType(...markerOrRange: FourSlash.MarkerOrNameOrRange[]): void { this.state.baselineGoToType(markerOrRange, /*rangeText*/ undefined); } - public baselineGoToTypeAtRangesWithText(...rangeText: string[]) { + public baselineGoToTypeAtRangesWithText(...rangeText: string[]): void { this.state.baselineGoToType(/*markerOrRange*/ undefined, rangeText); } - public baselineGoToImplementation(...markerOrRange: FourSlash.MarkerOrNameOrRange[]) { + public baselineGoToImplementation(...markerOrRange: FourSlash.MarkerOrNameOrRange[]): void { this.state.baselineGoToImplementation(markerOrRange, /*rangeText*/ undefined); } - public baselineGoToImplementationAtRangesWithText(...rangeText: string[]) { + public baselineGoToImplementationAtRangesWithText(...rangeText: string[]): void { this.state.baselineGoToImplementation(/*markerOrRange*/ undefined, rangeText); } - public baselineDocumentHighlights(markerOrRange?: ArrayOrSingle, options?: VerifyDocumentHighlightsOptions) { + public baselineDocumentHighlights(markerOrRange?: ArrayOrSingle, options?: VerifyDocumentHighlightsOptions): void { this.state.baselineDocumentHighlights(markerOrRange, /*rangeText*/ undefined, options); } - public baselineDocumentHighlightsAtRangesWithText(rangeText?: ArrayOrSingle, options?: VerifyDocumentHighlightsOptions) { + public baselineDocumentHighlightsAtRangesWithText(rangeText?: ArrayOrSingle, options?: VerifyDocumentHighlightsOptions): void { this.state.baselineDocumentHighlights(/*markerOrRange*/ undefined, rangeText, options); } - public noErrors() { + public noErrors(): void { this.state.verifyNoErrors(); } - public errorExistsAtRange(range: FourSlash.Range, code: number, message?: string) { + public errorExistsAtRange(range: FourSlash.Range, code: number, message?: string): void { this.state.verifyErrorExistsAtRange(range, code, message); } - public numberOfErrorsInCurrentFile(expected: number) { + public numberOfErrorsInCurrentFile(expected: number): void { this.state.verifyNumberOfErrorsInCurrentFile(expected); } - public baselineCurrentFileBreakpointLocations() { + public baselineCurrentFileBreakpointLocations(): void { this.state.baselineCurrentFileBreakpointLocations(); } - public baselineCurrentFileNameOrDottedNameSpans() { + public baselineCurrentFileNameOrDottedNameSpans(): void { this.state.baselineCurrentFileNameOrDottedNameSpans(); } @@ -435,64 +445,64 @@ export class Verify extends VerifyNegatable { this.state.verifyGetEmitOutput(expectedOutputFiles); } - public baselineGetEmitOutput() { + public baselineGetEmitOutput(): void { this.state.baselineGetEmitOutput(); } - public baselineQuickInfo() { + public baselineQuickInfo(): void { this.state.baselineQuickInfo(); } - public baselineSignatureHelp() { + public baselineSignatureHelp(): void { this.state.baselineSignatureHelp(); } - public baselineCompletions(preferences?: ts.UserPreferences) { + public baselineCompletions(preferences?: ts.UserPreferences): void { this.state.baselineCompletions(preferences); } - public baselineSmartSelection() { + public baselineSmartSelection(): void { this.state.baselineSmartSelection(); } - public baselineSyntacticDiagnostics() { + public baselineSyntacticDiagnostics(): void { this.state.baselineSyntacticDiagnostics(); } - public baselineSyntacticAndSemanticDiagnostics() { + public baselineSyntacticAndSemanticDiagnostics(): void { this.state.baselineSyntacticAndSemanticDiagnostics(); } - public nameOrDottedNameSpanTextIs(text: string) { + public nameOrDottedNameSpanTextIs(text: string): void { this.state.verifyCurrentNameOrDottedNameSpanText(text); } - public outliningSpansInCurrentFile(spans: FourSlash.Range[], kind?: "comment" | "region" | "code" | "imports") { + public outliningSpansInCurrentFile(spans: FourSlash.Range[], kind?: "comment" | "region" | "code" | "imports"): void { this.state.verifyOutliningSpans(spans, kind); } - public outliningHintSpansInCurrentFile(spans: FourSlash.Range[]) { + public outliningHintSpansInCurrentFile(spans: FourSlash.Range[]): void { this.state.verifyOutliningHintSpans(spans); } - public todoCommentsInCurrentFile(descriptors: string[]) { + public todoCommentsInCurrentFile(descriptors: string[]): void { this.state.verifyTodoComments(descriptors, this.state.getRanges()); } - public matchingBracePositionInCurrentFile(bracePosition: number, expectedMatchPosition: number) { + public matchingBracePositionInCurrentFile(bracePosition: number, expectedMatchPosition: number): void { this.state.verifyMatchingBracePosition(bracePosition, expectedMatchPosition); } - public noMatchingBracePositionInCurrentFile(bracePosition: number) { + public noMatchingBracePositionInCurrentFile(bracePosition: number): void { this.state.verifyNoMatchingBracePosition(bracePosition); } - public docCommentTemplateAt(marker: string | FourSlash.Marker, expectedOffset: number, expectedText: string, options?: ts.DocCommentTemplateOptions) { + public docCommentTemplateAt(marker: string | FourSlash.Marker, expectedOffset: number, expectedText: string, options?: ts.DocCommentTemplateOptions): void { this.state.goToMarker(marker); this.state.verifyDocCommentTemplate({ newText: expectedText.replace(/\r?\n/g, ts.testFormatSettings.newLineCharacter!), caretOffset: expectedOffset }, options); } - public noDocCommentTemplateAt(marker: string | FourSlash.Marker) { + public noDocCommentTemplateAt(marker: string | FourSlash.Marker): void { this.state.goToMarker(marker); this.state.verifyDocCommentTemplate(/*expected*/ undefined); } @@ -525,19 +535,19 @@ export class Verify extends VerifyNegatable { this.state.verifyImportFixAtPosition(expectedTextArray, errorCode, preferences); } - public importFixModuleSpecifiers(marker: string, moduleSpecifiers: string[], preferences?: ts.UserPreferences) { + public importFixModuleSpecifiers(marker: string, moduleSpecifiers: string[], preferences?: ts.UserPreferences): void { this.state.verifyImportFixModuleSpecifiers(marker, moduleSpecifiers, preferences); } - public baselineAutoImports(marker: string, fullNamesForCodeFix?: string[], options?: ts.UserPreferences) { + public baselineAutoImports(marker: string, fullNamesForCodeFix?: string[], options?: ts.UserPreferences): void { this.state.baselineAutoImports(marker, fullNamesForCodeFix, options); } - public navigationBar(json: any, options?: { checkSpans?: boolean; }) { + public navigationBar(json: any, options?: { checkSpans?: boolean; }): void { this.state.verifyNavigationBar(json, options); } - public navigationTree(json: any, options?: { checkSpans?: boolean; }) { + public navigationTree(json: any, options?: { checkSpans?: boolean; }): void { this.state.verifyNavigationTree(json, options); } @@ -548,26 +558,26 @@ export class Verify extends VerifyNegatable { /** * This method *requires* a contiguous, complete, and ordered stream of classifications for a file. */ - public syntacticClassificationsAre(...classifications: { classificationType: string; text: string; }[]) { + public syntacticClassificationsAre(...classifications: { classificationType: string; text: string; }[]): void { this.state.verifySyntacticClassifications(classifications); } - public encodedSyntacticClassificationsLength(length: number) { + public encodedSyntacticClassificationsLength(length: number): void { this.state.verifyEncodedSyntacticClassificationsLength(length); } - public encodedSemanticClassificationsLength(format: ts.SemanticClassificationFormat, length: number) { + public encodedSemanticClassificationsLength(format: ts.SemanticClassificationFormat, length: number): void { this.state.verifyEncodedSemanticClassificationsLength(format, length); } /** * This method *requires* an ordered stream of classifications for a file, and spans are highly recommended. */ - public semanticClassificationsAre(format: ts.SemanticClassificationFormat, ...classifications: Classification[]) { + public semanticClassificationsAre(format: ts.SemanticClassificationFormat, ...classifications: Classification[]): void { this.state.verifySemanticClassifications(format, classifications); } - public replaceWithSemanticClassifications(format: ts.SemanticClassificationFormat.TwentyTwenty) { + public replaceWithSemanticClassifications(format: ts.SemanticClassificationFormat.TwentyTwenty): void { this.state.replaceWithSemanticClassifications(format); } @@ -579,31 +589,31 @@ export class Verify extends VerifyNegatable { fileToRename?: string, expectedRange?: FourSlash.Range, preferences?: ts.UserPreferences, - ) { + ): void { this.state.verifyRenameInfoSucceeded(displayName, fullDisplayName, kind, kindModifiers, fileToRename, expectedRange, preferences); } - public renameInfoFailed(message?: string, preferences?: ts.UserPreferences) { + public renameInfoFailed(message?: string, preferences?: ts.UserPreferences): void { this.state.verifyRenameInfoFailed(message, preferences); } - public baselineRename(markerOrRange?: ArrayOrSingle, options?: RenameOptions) { + public baselineRename(markerOrRange?: ArrayOrSingle, options?: RenameOptions): void { this.state.baselineRename(markerOrRange, /*rangeText*/ undefined, options); } - public baselineRenameAtRangesWithText(rangeText?: ArrayOrSingle, options?: RenameOptions) { + public baselineRenameAtRangesWithText(rangeText?: ArrayOrSingle, options?: RenameOptions): void { this.state.baselineRename(/*markerOrRange*/ undefined, rangeText, options); } - public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: FourSlash.TextSpan, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: ts.JSDocTagInfo[]) { + public verifyQuickInfoDisplayParts(kind: string, kindModifiers: string, textSpan: FourSlash.TextSpan, displayParts: ts.SymbolDisplayPart[], documentation: ts.SymbolDisplayPart[], tags: ts.JSDocTagInfo[]): void { this.state.verifyQuickInfoDisplayParts(kind, kindModifiers, textSpan, displayParts, documentation, tags); } - public getSyntacticDiagnostics(expected: readonly Diagnostic[]) { + public getSyntacticDiagnostics(expected: readonly Diagnostic[]): void { this.state.getSyntacticDiagnostics(expected); } - public getSemanticDiagnostics(expected: readonly Diagnostic[]) { + public getSemanticDiagnostics(expected: readonly Diagnostic[]): void { this.state.verifySemanticDiagnostics(expected); } @@ -611,23 +621,23 @@ export class Verify extends VerifyNegatable { ranges: ts.TextRange[], expectedDiagnostics: readonly Diagnostic[], expectedRanges: ts.TextRange[] | undefined, - ) { + ): void { this.state.getRegionSemanticDiagnostics(ranges, expectedDiagnostics, expectedRanges); } - public getSuggestionDiagnostics(expected: readonly Diagnostic[]) { + public getSuggestionDiagnostics(expected: readonly Diagnostic[]): void { this.state.getSuggestionDiagnostics(expected); } - public ProjectInfo(expected: string[]) { + public ProjectInfo(expected: string[]): void { this.state.verifyProjectInfo(expected); } - public getEditsForFileRename(options: GetEditsForFileRenameOptions) { + public getEditsForFileRename(options: GetEditsForFileRenameOptions): void { this.state.getEditsForFileRename(options); } - public baselineCallHierarchy() { + public baselineCallHierarchy(): void { this.state.baselineCallHierarchy(); } @@ -655,70 +665,70 @@ export class Verify extends VerifyNegatable { export class Edit { constructor(private state: FourSlash.TestState) { } - public caretPosition() { + public caretPosition(): FourSlash.Marker { return this.state.caretPosition(); } - public backspace(count?: number) { + public backspace(count?: number): void { this.state.deleteCharBehindMarker(count); } - public deleteAtCaret(times?: number) { + public deleteAtCaret(times?: number): void { this.state.deleteChar(times); } - public replace(start: number, length: number, text: string) { + public replace(start: number, length: number, text: string): void { this.state.replace(start, length, text); } - public paste(text: string) { + public paste(text: string): void { this.state.paste(text); } - public insert(text: string) { + public insert(text: string): void { this.insertLines(text); } - public insertLine(text: string) { + public insertLine(text: string): void { this.insertLines(text + "\n"); } - public insertLines(...lines: string[]) { + public insertLines(...lines: string[]): void { this.state.type(lines.join("\n")); } - public deleteLine(index: number) { + public deleteLine(index: number): void { this.deleteLineRange(index, index); } - public deleteLineRange(startIndex: number, endIndexInclusive: number) { + public deleteLineRange(startIndex: number, endIndexInclusive: number): void { this.state.deleteLineRange(startIndex, endIndexInclusive); } - public replaceLine(index: number, text: string) { + public replaceLine(index: number, text: string): void { this.state.selectLine(index); this.state.type(text); } - public moveRight(count?: number) { + public moveRight(count?: number): void { this.state.moveCaretRight(count); } - public moveLeft(count?: number) { + public moveLeft(count?: number): void { if (typeof count === "undefined") { count = 1; } this.state.moveCaretRight(count * -1); } - public enableFormatting() { + public enableFormatting(): void { this.state.enableFormatting = true; } - public disableFormatting() { + public disableFormatting(): void { this.state.enableFormatting = false; } - public applyRefactor(options: ApplyRefactorOptions) { + public applyRefactor(options: ApplyRefactorOptions): void { this.state.applyRefactor(options); } } @@ -727,66 +737,66 @@ export class Debug { constructor(private state: FourSlash.TestState) { } - public printCurrentParameterHelp() { + public printCurrentParameterHelp(): void { this.state.printCurrentParameterHelp(); } - public printCurrentFileState() { + public printCurrentFileState(): void { this.state.printCurrentFileState(/*showWhitespace*/ false, /*makeCaretVisible*/ true); } - public printCurrentFileStateWithWhitespace() { + public printCurrentFileStateWithWhitespace(): void { this.state.printCurrentFileState(/*showWhitespace*/ true, /*makeCaretVisible*/ true); } - public printCurrentFileStateWithoutCaret() { + public printCurrentFileStateWithoutCaret(): void { this.state.printCurrentFileState(/*showWhitespace*/ false, /*makeCaretVisible*/ false); } - public printCurrentQuickInfo() { + public printCurrentQuickInfo(): void { this.state.printCurrentQuickInfo(); } - public printCurrentSignatureHelp() { + public printCurrentSignatureHelp(): void { this.state.printCurrentSignatureHelp(); } - public printCompletionListMembers(options: ts.UserPreferences | undefined) { + public printCompletionListMembers(options: ts.UserPreferences | undefined): void { this.state.printCompletionListMembers(options); } - public printAvailableCodeFixes() { + public printAvailableCodeFixes(): void { this.state.printAvailableCodeFixes(); } - public printBreakpointLocation(pos: number) { + public printBreakpointLocation(pos: number): void { this.state.printBreakpointLocation(pos); } - public printBreakpointAtCurrentLocation() { + public printBreakpointAtCurrentLocation(): void { this.state.printBreakpointAtCurrentLocation(); } - public printNameOrDottedNameSpans(pos: number) { + public printNameOrDottedNameSpans(pos: number): void { this.state.printNameOrDottedNameSpans(pos); } - public printErrorList() { + public printErrorList(): void { this.state.printErrorList(); } - public printNavigationItems(searchValue = ".*") { + public printNavigationItems(searchValue = ".*"): void { this.state.printNavigationItems(searchValue); } - public printNavigationBar() { + public printNavigationBar(): void { this.state.printNavigationBar(); } - public printContext() { + public printContext(): void { this.state.printContext(); } - public printOutliningSpans() { + public printOutliningSpans(): void { this.state.printOutliningSpans(); } } @@ -795,7 +805,7 @@ export class Format { constructor(private state: FourSlash.TestState) { } - public document() { + public document(): void { this.state.formatDocument(); } @@ -803,15 +813,15 @@ export class Format { return this.state.copyFormatOptions(); } - public setFormatOptions(options: ts.FormatCodeOptions) { + public setFormatOptions(options: ts.FormatCodeOptions): ts.FormatCodeSettings { return this.state.setFormatOptions(options); } - public selection(startMarker: string, endMarker: string) { + public selection(startMarker: string, endMarker: string): void { this.state.formatSelection(this.state.getMarkerByName(startMarker).position, this.state.getMarkerByName(endMarker).position); } - public onType(posMarker: string, key: string) { + public onType(posMarker: string, key: string): void { this.state.formatOnType(this.state.getMarkerByName(posMarker).position, key); } @@ -824,11 +834,11 @@ export class Cancellation { constructor(private state: FourSlash.TestState) { } - public resetCancelled() { + public resetCancelled(): void { this.state.resetCancelled(); } - public setCancelled(numberOfCalls = 0) { + public setCancelled(numberOfCalls = 0): void { this.state.setCancelled(numberOfCalls); } } @@ -848,7 +858,59 @@ interface ModernClassification { type Classification = OlderClassification | ModernClassification; -export function classification(format: ts.SemanticClassificationFormat) { +export function classification(format: ts.SemanticClassificationFormat): { + semanticToken: (identifier: string, text: string, _position: number) => Classification; + comment?: undefined; + identifier?: undefined; + keyword?: undefined; + numericLiteral?: undefined; + operator?: undefined; + stringLiteral?: undefined; + whiteSpace?: undefined; + text?: undefined; + punctuation?: undefined; + docCommentTagName?: undefined; + className?: undefined; + enumName?: undefined; + interfaceName?: undefined; + moduleName?: undefined; + typeParameterName?: undefined; + parameterName?: undefined; + typeAliasName?: undefined; + jsxOpenTagName?: undefined; + jsxCloseTagName?: undefined; + jsxSelfClosingTagName?: undefined; + jsxAttribute?: undefined; + jsxText?: undefined; + jsxAttributeStringLiteralValue?: undefined; + getClassification?: undefined; +} | { + comment: (text: string, position?: number) => Classification; + identifier: (text: string, position?: number) => Classification; + keyword: (text: string, position?: number) => Classification; + numericLiteral: (text: string, position?: number) => Classification; + operator: (text: string, position?: number) => Classification; + stringLiteral: (text: string, position?: number) => Classification; + whiteSpace: (text: string, position?: number) => Classification; + text: (text: string, position?: number) => Classification; + punctuation: (text: string, position?: number) => Classification; + docCommentTagName: (text: string, position?: number) => Classification; + className: (text: string, position?: number) => Classification; + enumName: (text: string, position?: number) => Classification; + interfaceName: (text: string, position?: number) => Classification; + moduleName: (text: string, position?: number) => Classification; + typeParameterName: (text: string, position?: number) => Classification; + parameterName: (text: string, position?: number) => Classification; + typeAliasName: (text: string, position?: number) => Classification; + jsxOpenTagName: (text: string, position?: number) => Classification; + jsxCloseTagName: (text: string, position?: number) => Classification; + jsxSelfClosingTagName: (text: string, position?: number) => Classification; + jsxAttribute: (text: string, position?: number) => Classification; + jsxText: (text: string, position?: number) => Classification; + jsxAttributeStringLiteralValue: (text: string, position?: number) => Classification; + getClassification: (classificationType: ts.ClassificationTypeNames, text: string, position?: number) => Classification; + semanticToken?: undefined; +} { function semanticToken(identifier: string, text: string, _position: number): Classification { return { classificationType: identifier, @@ -1137,7 +1199,7 @@ export namespace Completion { return Object.assign(sorted([...providedByHarness, ...providedByTest]), { plusFunctionName: functionName, plusArgument: providedByTest }); } - export function typeKeywordsPlus(plus: readonly ExpectedCompletionEntry[]) { + export function typeKeywordsPlus(plus: readonly ExpectedCompletionEntry[]): ExpectedExactCompletionsPlus { return combineExpectedCompletionEntries("typeKeywordsPlus", typeKeywords, plus); } @@ -1268,8 +1330,8 @@ export namespace Completion { kind: "module", sortText: SortText.GlobalsOrKeywords, }; - export const globalTypes = globalTypesPlus([]); - export function globalTypesPlus(plus: readonly ExpectedCompletionEntry[]) { + export const globalTypes: ExpectedExactCompletionsPlus = globalTypesPlus([]); + export function globalTypesPlus(plus: readonly ExpectedCompletionEntry[]): ExpectedExactCompletionsPlus { return combineExpectedCompletionEntries( "globalTypesPlus", [globalThisEntry, ...globalTypeDecls, ...typeKeywords], @@ -1332,7 +1394,7 @@ export namespace Completion { "static", ].map(keywordEntry); - export const classElementInJsKeywords = getInJsKeywords(classElementKeywords); + export const classElementInJsKeywords: readonly ExpectedCompletionEntryObject[] = getInJsKeywords(classElementKeywords); export const constructorParameterKeywords: readonly ExpectedCompletionEntryObject[] = ["override", "private", "protected", "public", "readonly"].map((name): ExpectedCompletionEntryObject => ({ name, @@ -1350,7 +1412,7 @@ export namespace Completion { propertyEntry("caller"), ].sort(compareExpectedCompletionEntries); - export function functionMembersPlus(plus: readonly ExpectedCompletionEntryObject[]) { + export function functionMembersPlus(plus: readonly ExpectedCompletionEntryObject[]): ExpectedExactCompletionsPlus { return combineExpectedCompletionEntries("functionMembersPlus", functionMembers, plus); } @@ -1383,7 +1445,7 @@ export namespace Completion { propertyEntry("prototype"), ].sort(compareExpectedCompletionEntries); - export function functionMembersWithPrototypePlus(plus: readonly ExpectedCompletionEntryObject[]) { + export function functionMembersWithPrototypePlus(plus: readonly ExpectedCompletionEntryObject[]): ExpectedCompletionEntryObject[] { return [...functionMembersWithPrototype, ...plus].sort(compareExpectedCompletionEntries); } @@ -1472,7 +1534,7 @@ export namespace Completion { } }); - export const statementInJsKeywords = getInJsKeywords(statementKeywords); + export const statementInJsKeywords: readonly ExpectedCompletionEntryObject[] = getInJsKeywords(statementKeywords); export const globalsVars: readonly ExpectedCompletionEntryObject[] = [ varEntry("Array"), @@ -1675,7 +1737,7 @@ export namespace Completion { "yield", ].map(keywordEntry); - export const globalInJsKeywords = getInJsKeywords(globalKeywords); + export const globalInJsKeywords: readonly ExpectedCompletionEntryObject[] = getInJsKeywords(globalKeywords); export const insideMethodKeywords: readonly ExpectedCompletionEntryObject[] = [ "as", @@ -1727,7 +1789,7 @@ export namespace Completion { "yield", ].map(keywordEntry); - export const insideMethodInJsKeywords = getInJsKeywords(insideMethodKeywords); + export const insideMethodInJsKeywords: readonly ExpectedCompletionEntryObject[] = getInJsKeywords(insideMethodKeywords); export const globals: readonly ExpectedCompletionEntryObject[] = [ globalThisEntry, @@ -1743,7 +1805,7 @@ export namespace Completion { ...globalInJsKeywords, ].sort(compareExpectedCompletionEntries); - export function globalsPlus(plus: readonly ExpectedCompletionEntry[], options?: { noLib?: boolean; }) { + export function globalsPlus(plus: readonly ExpectedCompletionEntry[], options?: { noLib?: boolean; }): ExpectedExactCompletionsPlus { return combineExpectedCompletionEntries("globalsPlus", [ globalThisEntry, ...options?.noLib ? [] : globalsVars, @@ -1752,7 +1814,7 @@ export namespace Completion { ], plus); } - export function globalsInJsPlus(plus: readonly ExpectedCompletionEntry[], options?: { noLib?: boolean; }) { + export function globalsInJsPlus(plus: readonly ExpectedCompletionEntry[], options?: { noLib?: boolean; }): ExpectedExactCompletionsPlus { return combineExpectedCompletionEntries("globalsInJsPlus", [ globalThisEntry, ...options?.noLib ? [] : globalsVars, diff --git a/src/harness/harnessIO.ts b/src/harness/harnessIO.ts index 32b5c1e42811f..dadf1477f743e 100644 --- a/src/harness/harnessIO.ts +++ b/src/harness/harnessIO.ts @@ -44,7 +44,7 @@ export interface IO { } export let IO: IO; -export function setHarnessIO(io: IO) { +export function setHarnessIO(io: IO): void { IO = io; } @@ -173,7 +173,7 @@ export type SourceMapEmitterCallback = ( export let userSpecifiedRoot = ""; export let lightMode = false; /* eslint-enable prefer-const */ -export function setLightMode(flag: boolean) { +export function setLightMode(flag: boolean): void { lightMode = flag; } @@ -186,23 +186,23 @@ export namespace Compiler { public lines: string[] = []; public currentLine: string = undefined!; - public Write(str: string) { + public Write(str: string): void { // out of memory usage concerns avoid using + or += if we're going to do any manipulation of this string later this.currentLine = [this.currentLine || "", str].join(""); } - public WriteLine(str: string) { + public WriteLine(str: string): void { // out of memory usage concerns avoid using + or += if we're going to do any manipulation of this string later this.lines.push([this.currentLine || "", str].join("")); this.currentLine = undefined!; } - public Close() { + public Close(): void { if (this.currentLine !== undefined) this.lines.push(this.currentLine); this.currentLine = undefined!; } - public reset() { + public reset(): void { this.lines = []; this.currentLine = undefined!; } @@ -212,7 +212,7 @@ export namespace Compiler { fileName: string, sourceText: string, languageVersionOrOptions: ts.ScriptTarget | ts.CreateSourceFileOptions, - ) { + ): ts.SourceFile { // We'll only assert invariants outside of light mode. const shouldAssertInvariants = !lightMode; @@ -235,7 +235,7 @@ export namespace Compiler { // Cache of lib files from "built/local" export let libFileNameSourceFileMap: Map | undefined; - export function getDefaultLibrarySourceFile(fileName = defaultLibFileName): ts.SourceFile | undefined { + export function getDefaultLibrarySourceFile(fileName: string = defaultLibFileName): ts.SourceFile | undefined { if (!isDefaultLibraryFile(fileName)) { return undefined; } @@ -519,7 +519,11 @@ export namespace Compiler { } } - export function compileDeclarationFiles(context: DeclarationCompilationContext | undefined, symlinks: vfs.FileSet | undefined) { + export function compileDeclarationFiles(context: DeclarationCompilationContext | undefined, symlinks: vfs.FileSet | undefined): { + declInputFiles: TestFile[]; + declOtherFiles: TestFile[]; + declResult: CompileFilesResult; + } | undefined { if (!context) { return; } @@ -528,12 +532,12 @@ export namespace Compiler { return { declInputFiles, declOtherFiles, declResult: output }; } - export function minimalDiagnosticsToString(diagnostics: readonly ts.Diagnostic[], pretty?: boolean) { + export function minimalDiagnosticsToString(diagnostics: readonly ts.Diagnostic[], pretty?: boolean): string { const host = { getCanonicalFileName, getCurrentDirectory: () => "", getNewLine: () => IO.newLine() }; return (pretty ? ts.formatDiagnosticsWithColorAndContext : ts.formatDiagnostics)(diagnostics, host); } - export function getErrorBaseline(inputFiles: readonly TestFile[], diagnostics: readonly ts.Diagnostic[], pretty?: boolean) { + export function getErrorBaseline(inputFiles: readonly TestFile[], diagnostics: readonly ts.Diagnostic[], pretty?: boolean): string { let outputLines = ""; const gen = iterateErrorBaseline(inputFiles, diagnostics, { pretty }); for (const value of gen) { @@ -708,11 +712,21 @@ export namespace Compiler { assert.equal(totalErrorsReportedInNonLibraryNonTsconfigFiles + numLibraryDiagnostics + numTsconfigDiagnostics, diagnostics.length, "total number of errors"); } - export function doErrorBaseline(baselinePath: string, inputFiles: readonly TestFile[], errors: readonly ts.Diagnostic[], pretty?: boolean) { + export function doErrorBaseline(baselinePath: string, inputFiles: readonly TestFile[], errors: readonly ts.Diagnostic[], pretty?: boolean): void { Baseline.runBaseline(baselinePath.replace(/\.tsx?$/, ".errors.txt"), !errors || (errors.length === 0) ? null : getErrorBaseline(inputFiles, errors, pretty)); // eslint-disable-line no-restricted-syntax } - export function doTypeAndSymbolBaseline(baselinePath: string, header: string, program: ts.Program, allFiles: { unitName: string; content: string; }[], opts?: Baseline.BaselineOptions, multifile?: boolean, skipTypeBaselines?: boolean, skipSymbolBaselines?: boolean, hasErrorBaseline?: boolean) { + export function doTypeAndSymbolBaseline( + baselinePath: string, + header: string, + program: ts.Program, + allFiles: { unitName: string; content: string; }[], + opts?: Baseline.BaselineOptions, + multifile?: boolean, + skipTypeBaselines?: boolean, + skipSymbolBaselines?: boolean, + hasErrorBaseline?: boolean, + ): void { // The full walker simulates the types that you would get from doing a full // compile. The pull walker simulates the types you get when you just do // a type query for a random node (like how the LS would do it). Most of the @@ -903,7 +917,7 @@ export namespace Compiler { } } - export function doSourcemapBaseline(baselinePath: string, options: ts.CompilerOptions, result: compiler.CompilationResult, harnessSettings: TestCaseParser.CompilerSettings) { + export function doSourcemapBaseline(baselinePath: string, options: ts.CompilerOptions, result: compiler.CompilationResult, harnessSettings: TestCaseParser.CompilerSettings): void { const declMaps = ts.getAreDeclarationMapsEnabled(options); if (options.inlineSourceMap) { if (result.maps.size > 0 && !declMaps) { @@ -949,7 +963,16 @@ export namespace Compiler { return "\n//// https://sokra.github.io/source-map-visualization" + hash + "\n"; } - export function doJsEmitBaseline(baselinePath: string, header: string, options: ts.CompilerOptions, result: CompileFilesResult, tsConfigFiles: readonly TestFile[], toBeCompiled: readonly TestFile[], otherFiles: readonly TestFile[], harnessSettings: TestCaseParser.CompilerSettings) { + export function doJsEmitBaseline( + baselinePath: string, + header: string, + options: ts.CompilerOptions, + result: CompileFilesResult, + tsConfigFiles: readonly TestFile[], + toBeCompiled: readonly TestFile[], + otherFiles: readonly TestFile[], + harnessSettings: TestCaseParser.CompilerSettings, + ): void { if (!options.noEmit && !options.emitDeclarationOnly && result.js.size === 0 && result.diagnostics.length === 0) { throw new Error("Expected at least one js file to be emitted or at least one error to be created."); } @@ -1081,7 +1104,7 @@ export namespace Compiler { return resultName; } - export function sanitizeTestFilePath(name: string) { + export function sanitizeTestFilePath(name: string): string { const path = ts.toPath(ts.normalizeSlashes(name.replace(/[\^<>:"|?*%]/g, "_")).replace(/\.\.\//g, "__dotdot/"), "", Utils.canonicalizeForHarness); if (ts.startsWith(path, "/")) { return path.substring(1); @@ -1221,7 +1244,7 @@ export function getFileBasedTestConfigurations(settings: TestCaseParser.Compiler /** * Compute a description for this configuration based on its entries */ -export function getFileBasedTestConfigurationDescription(configuration: FileBasedTestConfiguration) { +export function getFileBasedTestConfigurationDescription(configuration: FileBasedTestConfiguration): string { let name = ""; if (configuration) { const keys = Object.keys(configuration).sort(); @@ -1252,7 +1275,7 @@ export namespace TestCaseParser { const optionRegex = /^\/{2}\s*@(\w+)\s*:\s*([^\r\n]*)/gm; // multiple matches on multiple lines const linkRegex = /^\/{2}\s*@link\s*:\s*([^\r\n]*)\s*->\s*([^\r\n]*)/gm; // multiple matches on multiple lines - export function parseSymlinkFromTest(line: string, symlinks: vfs.FileSet | undefined, absoluteRootDir?: string) { + export function parseSymlinkFromTest(line: string, symlinks: vfs.FileSet | undefined, absoluteRootDir?: string): vfs.FileSet | undefined { const linkMetaData = linkRegex.exec(line); linkRegex.lastIndex = 0; if (!linkMetaData) return undefined; @@ -1282,7 +1305,7 @@ export namespace TestCaseParser { } /** Given a test file containing // @FileName directives, return an array of named units of code to be added to an existing compiler instance */ - export function makeUnitsFromTest(code: string, fileName: string, settings = extractCompilerSettings(code)): TestCaseContent { + export function makeUnitsFromTest(code: string, fileName: string, settings: CompilerSettings = extractCompilerSettings(code)): TestCaseContent { // List of all the subfiles we've parsed out const testUnitData: TestUnitData[] = []; @@ -1427,7 +1450,7 @@ export namespace Baseline { PrintDiff?: true; } - export function localPath(fileName: string, baselineFolder?: string, subfolder?: string) { + export function localPath(fileName: string, baselineFolder?: string, subfolder?: string): string { if (baselineFolder === undefined) { return baselinePath(fileName, "local", "tests/baselines", subfolder); } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index cc4a6aa89b308..7aff47310a4b6 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -113,7 +113,7 @@ class ScriptSnapshot implements ts.IScriptSnapshot { } class DefaultHostCancellationToken implements ts.HostCancellationToken { - public static readonly instance = new DefaultHostCancellationToken(); + public static readonly instance: DefaultHostCancellationToken = new DefaultHostCancellationToken(); public isCancellationRequested() { return false; @@ -129,16 +129,16 @@ export interface LanguageServiceAdapter { } export abstract class LanguageServiceAdapterHost { - public readonly sys = new fakes.System(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: virtualFileSystemRoot })); + public readonly sys: fakes.System = new fakes.System(new vfs.FileSystem(/*ignoreCase*/ true, { cwd: virtualFileSystemRoot })); public typesRegistry: Map | undefined; private scriptInfos: collections.SortedMap; public jsDocParsingMode: ts.JSDocParsingMode | undefined; - constructor(protected cancellationToken = DefaultHostCancellationToken.instance, protected settings = ts.getDefaultCompilerOptions()) { + constructor(protected cancellationToken: DefaultHostCancellationToken = DefaultHostCancellationToken.instance, protected settings: ts.CompilerOptions = ts.getDefaultCompilerOptions()) { this.scriptInfos = new collections.SortedMap({ comparer: this.vfs.stringComparer, sort: "insertion" }); } - public get vfs() { + public get vfs(): vfs.FileSystem { return this.sys.vfs; } @@ -185,7 +185,7 @@ export abstract class LanguageServiceAdapterHost { } } - public directoryExists(path: string) { + public directoryExists(path: string): boolean { return this.vfs.statSync(path).isDirectory(); } @@ -214,7 +214,7 @@ export abstract class LanguageServiceAdapterHost { }); } - public editScript(fileName: string, start: number, end: number, newText: string) { + public editScript(fileName: string, start: number, end: number, newText: string): void { const script = this.getScriptInfo(fileName); if (script) { script.editContent(start, end, newText); @@ -244,7 +244,7 @@ export abstract class LanguageServiceAdapterHost { return ts.computePositionOfLineAndCharacter(script.getLineMap(), lineAndCharacter.line, lineAndCharacter.character); } - useCaseSensitiveFileNames() { + useCaseSensitiveFileNames(): boolean { return !this.vfs.ignoreCase; } } @@ -257,17 +257,17 @@ class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts return !!this.typesRegistry && this.typesRegistry.has(name); } - getGlobalTypingsCacheLocation() { + getGlobalTypingsCacheLocation(): string { return harnessTypingInstallerCacheLocation; } - installPackage = ts.notImplemented; + installPackage: typeof ts.notImplemented = ts.notImplemented; - getCompilationSettings() { + getCompilationSettings(): ts.CompilerOptions { return this.settings; } - getCancellationToken() { + getCancellationToken(): DefaultHostCancellationToken { return this.cancellationToken; } @@ -325,14 +325,14 @@ class NativeLanguageServiceHost extends LanguageServiceAdapterHost implements ts return 0; } - log = ts.noop; - trace = ts.noop; - error = ts.noop; + log: typeof ts.noop = ts.noop; + trace: typeof ts.noop = ts.noop; + error: typeof ts.noop = ts.noop; } export class NativeLanguageServiceAdapter implements LanguageServiceAdapter { private host: NativeLanguageServiceHost; - getLogger = ts.returnUndefined; + getLogger: typeof ts.returnUndefined = ts.returnUndefined; constructor(cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) { this.host = new NativeLanguageServiceHost(cancellationToken, options); } @@ -367,10 +367,10 @@ class SessionClientHost extends NativeLanguageServiceHost implements ts.server.S return harnessSessionCurrentDirectory; } - onMessage = ts.noop; - writeMessage = ts.noop; + onMessage: typeof ts.noop = ts.noop; + writeMessage: typeof ts.noop = ts.noop; - setClient(client: ts.server.SessionClient) { + setClient(client: ts.server.SessionClient): void { this.client = client; } @@ -379,7 +379,7 @@ class SessionClientHost extends NativeLanguageServiceHost implements ts.server.S this.client.openFile(fileName, content, scriptKindName); } - override editScript(fileName: string, start: number, end: number, newText: string) { + override editScript(fileName: string, start: number, end: number, newText: string): void { const changeArgs = this.client.createChangeFileRequestArgs(fileName, start, end, newText); super.editScript(fileName, start, end, newText); this.client.changeFile(fileName, changeArgs); @@ -675,10 +675,10 @@ export class ServerLanguageServiceAdapter implements LanguageServiceAdapter { this.client = client; this.host = clientHost; } - getLogger() { + getLogger(): LoggerWithInMemoryLogs { return this.logger; } - getHost() { + getHost(): SessionClientHost { return this.host; } getLanguageService(): ts.LanguageService { @@ -690,7 +690,7 @@ export class ServerLanguageServiceAdapter implements LanguageServiceAdapter { getPreProcessedFileInfo(): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); } - assertTextConsistent(fileName: string) { + assertTextConsistent(fileName: string): void { const serverText = this.server.getText(fileName); const clientText = this.host.readFile(fileName); ts.Debug.assert( diff --git a/src/harness/harnessUtils.ts b/src/harness/harnessUtils.ts index 372202d08e443..b0b0edd8af868 100644 --- a/src/harness/harnessUtils.ts +++ b/src/harness/harnessUtils.ts @@ -6,7 +6,7 @@ export function encodeString(s: string): string { return Buffer.from(s).toString("utf8"); } -export function evalFile(fileContents: string, fileName: string, nodeContext?: any) { +export function evalFile(fileContents: string, fileName: string, nodeContext?: any): void { if (nodeContext) { vm.runInNewContext(fileContents, nodeContext, fileName); } @@ -16,7 +16,7 @@ export function evalFile(fileContents: string, fileName: string, nodeContext?: a } /** Splits the given string on \r\n, or on only \n if that fails, or on only \r if *that* fails. */ -export function splitContentByNewlines(content: string) { +export function splitContentByNewlines(content: string): string[] { // Split up the input file by line // Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so // we have to use string-based splitting instead and try to figure out the delimiting chars @@ -32,7 +32,7 @@ export function splitContentByNewlines(content: string) { } /** Reads a file under /tests */ -export function readTestFile(path: string) { +export function readTestFile(path: string): string | undefined { if (!path.includes("tests")) { path = "tests/" + path; } @@ -64,9 +64,9 @@ export function memoize(f: T, memoKey: (...anything: a } as any); } -export const canonicalizeForHarness = ts.createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ false); // This is done so tests work on windows _and_ linux +export const canonicalizeForHarness: ts.GetCanonicalFileName = ts.createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ false); // This is done so tests work on windows _and_ linux -export function assertInvariants(node: ts.Node | undefined, parent: ts.Node | undefined) { +export function assertInvariants(node: ts.Node | undefined, parent: ts.Node | undefined): void { const queue: [ts.Node | undefined, ts.Node | undefined][] = [[node, parent]]; for (const [node, parent] of queue) { assertInvariantsWorker(node, parent); @@ -149,7 +149,13 @@ function isNodeOrArray(a: any): boolean { return a !== undefined && typeof a.pos === "number"; } -export function convertDiagnostics(diagnostics: readonly ts.Diagnostic[]) { +export function convertDiagnostics(diagnostics: readonly ts.Diagnostic[]): { + start: number | undefined; + length: number | undefined; + messageText: string; + category: string; + code: number; +}[] { return diagnostics.map(convertDiagnostic); } @@ -247,7 +253,7 @@ export function sourceFileToJSON(file: ts.Node): string { } } -export function assertDiagnosticsEquals(array1: readonly ts.Diagnostic[], array2: readonly ts.Diagnostic[]) { +export function assertDiagnosticsEquals(array1: readonly ts.Diagnostic[], array2: readonly ts.Diagnostic[]): void { if (array1 === array2) { return; } @@ -273,7 +279,7 @@ export function assertDiagnosticsEquals(array1: readonly ts.Diagnostic[], array2 } } -export function assertStructuralEquals(node1: ts.Node, node2: ts.Node) { +export function assertStructuralEquals(node1: ts.Node, node2: ts.Node): void { if (node1 === node2) { return; } @@ -330,7 +336,7 @@ function findChildName(parent: any, child: any) { const maxHarnessFrames = 1; -export function filterStack(error: Error, stackTraceLimit = Infinity) { +export function filterStack(error: Error, stackTraceLimit: number = Infinity): Error { const stack = (error as any).stack as string; if (stack) { const lines = stack.split(/\r\n?|\n/); diff --git a/src/harness/incrementalUtils.ts b/src/harness/incrementalUtils.ts index ff4ad100373c8..47114c88d5151 100644 --- a/src/harness/incrementalUtils.ts +++ b/src/harness/incrementalUtils.ts @@ -1,6 +1,6 @@ import * as ts from "./_namespaces/ts.js"; -export function reportDocumentRegistryStats(documentRegistry: ts.DocumentRegistry) { +export function reportDocumentRegistryStats(documentRegistry: ts.DocumentRegistry): string[] { const str: string[] = []; documentRegistry.getBuckets().forEach((bucketEntries, key) => { str.push(` Key:: ${key}`); @@ -193,7 +193,7 @@ function getProgramStructure(program: ts.Program | undefined) { return baseline.join("\n"); } -export function verifyProgramStructure(expectedProgram: ts.Program, actualProgram: ts.Program, projectName: string) { +export function verifyProgramStructure(expectedProgram: ts.Program, actualProgram: ts.Program, projectName: string): void { const actual = getProgramStructure(actualProgram); const expected = getProgramStructure(expectedProgram); ts.Debug.assert(actual === expected, `Program verification:: ${projectName}`); @@ -204,7 +204,7 @@ export function verifyResolutionCache( actualProgram: ts.Program, resolutionHostCacheHost: ts.ResolutionCacheHost, projectName: string, -) { +): void { const currentDirectory = resolutionHostCacheHost.getCurrentDirectory!(); const expected = ts.createResolutionCache(resolutionHostCacheHost, actual.rootDirForResolution, /*logChangesWhenResolvingModule*/ false); expected.startCachingPerDirectoryResolution(); @@ -645,7 +645,7 @@ export interface IncrementalVerifierCallbacks { afterVerification?(dataFromBefore: any): void; } -export function incrementalVerifier(service: ts.server.ProjectService) { +export function incrementalVerifier(service: ts.server.ProjectService): void { service.verifyDocumentRegistry = withIncrementalVerifierCallbacks(service, verifyDocumentRegistry); service.verifyProgram = withIncrementalVerifierCallbacks(service, verifyProgram); service.onProjectCreation = onProjectCreation; diff --git a/src/harness/projectServiceStateLogger.ts b/src/harness/projectServiceStateLogger.ts index 42f64fde7f321..ea40e5a81d749 100644 --- a/src/harness/projectServiceStateLogger.ts +++ b/src/harness/projectServiceStateLogger.ts @@ -67,7 +67,7 @@ enum Diff { type StatePropertyLog = string | string[]; type StateItemLog = [string, StatePropertyLog[]]; -export function patchServiceForStateBaseline(service: ProjectService) { +export function patchServiceForStateBaseline(service: ProjectService): void { if (!service.logger.isTestLogger || !service.logger.hasLevel(LogLevel.verbose)) return; if (service.baseline !== noop) return; // Already patched diff --git a/src/harness/runnerbase.ts b/src/harness/runnerbase.ts index 7173eb3ab4fcd..90ef7834b5bc1 100644 --- a/src/harness/runnerbase.ts +++ b/src/harness/runnerbase.ts @@ -12,10 +12,10 @@ export let shards = 1; export let shardId = 1; // The following have setters as while they're read here in the harness, they're only set in the runner -export function setShards(count: number) { +export function setShards(count: number): void { shards = count; } -export function setShardId(id: number) { +export function setShardId(id: number): void { shardId = id; } @@ -24,7 +24,7 @@ export abstract class RunnerBase { public tests: string[] = []; /** Add a source file to the runner's list of tests that need to be initialized with initializeTests */ - public addTest(fileName: string) { + public addTest(fileName: string): void { this.tests.push(fileName); } @@ -53,7 +53,7 @@ export abstract class RunnerBase { public abstract initializeTests(): void; /** Replaces instances of full paths with fileNames only */ - static removeFullPaths(path: string) { + static removeFullPaths(path: string): string { // If its a full path (starts with "C:" or "/") replace with just the filename let fixedPath = /^(?:\w:|\/)/.test(path) ? ts.getBaseFileName(path) : path; diff --git a/src/harness/sourceMapRecorder.ts b/src/harness/sourceMapRecorder.ts index 44a6c12edf935..11366f98c5076 100644 --- a/src/harness/sourceMapRecorder.ts +++ b/src/harness/sourceMapRecorder.ts @@ -277,7 +277,7 @@ namespace SourceMapSpanWriter { } } -export function getSourceMapRecord(sourceMapDataList: readonly ts.SourceMapEmitResult[], program: ts.Program, jsFiles: readonly documents.TextDocument[], declarationFiles: readonly documents.TextDocument[]) { +export function getSourceMapRecord(sourceMapDataList: readonly ts.SourceMapEmitResult[], program: ts.Program, jsFiles: readonly documents.TextDocument[], declarationFiles: readonly documents.TextDocument[]): string { const sourceMapRecorder = new Compiler.WriterAggregator(); for (let i = 0; i < sourceMapDataList.length; i++) { @@ -324,7 +324,7 @@ export function getSourceMapRecord(sourceMapDataList: readonly ts.SourceMapEmitR return sourceMapRecorder.lines.join("\r\n"); } -export function getSourceMapRecordWithSystem(sys: ts.System, sourceMapFile: string) { +export function getSourceMapRecordWithSystem(sys: ts.System, sourceMapFile: string): string { const sourceMapRecorder = new Compiler.WriterAggregator(); let prevSourceFile: documents.TextDocument | undefined; const files = new Map(); diff --git a/src/harness/util.ts b/src/harness/util.ts index a31a60ada18e5..fc67ac36f069e 100644 --- a/src/harness/util.ts +++ b/src/harness/util.ts @@ -21,14 +21,14 @@ const replaceTypesVersionsMessage = createDiagnosticMessageReplacer( ([entry, , moduleName], compilerVersion) => [entry, compilerVersion, moduleName], ); -export function sanitizeTraceResolutionLogEntry(text: string) { +export function sanitizeTraceResolutionLogEntry(text: string): string { return text && replaceTypesVersionsMessage(text, "3.1.0-dev"); } /** * Removes leading indentation from a template literal string. */ -export function dedent(array: TemplateStringsArray, ...args: any[]) { +export function dedent(array: TemplateStringsArray, ...args: any[]): string { let text = array[0]; for (let i = 0; i < args.length; i++) { text += args[i]; @@ -97,11 +97,11 @@ export function removeByteOrderMark(text: string): string { return length ? text.slice(length) : text; } -export function addUTF8ByteOrderMark(text: string) { +export function addUTF8ByteOrderMark(text: string): string { return getByteOrderMarkLength(text) === 0 ? "\u00EF\u00BB\u00BF" + text : text; } -export function theory(name: string, cb: (...args: T) => void, data: T[]) { +export function theory(name: string, cb: (...args: T) => void, data: T[]): void { for (const entry of data) { it(`${name}(${entry.map(formatTheoryDatum).join(", ")})`, () => cb(...entry)); } diff --git a/src/harness/vfsUtil.ts b/src/harness/vfsUtil.ts index 7e6e76d545d19..1995d79ab6da0 100644 --- a/src/harness/vfsUtil.ts +++ b/src/harness/vfsUtil.ts @@ -111,14 +111,14 @@ export class FileSystem { /** * Gets a value indicating whether the file system is read-only. */ - public get isReadonly() { + public get isReadonly(): boolean { return Object.isFrozen(this); } /** * Makes the file system read-only. */ - public makeReadonly() { + public makeReadonly(): this { Object.freeze(this); return this; } @@ -126,7 +126,7 @@ export class FileSystem { /** * Gets the file system shadowed by this file system. */ - public get shadowRoot() { + public get shadowRoot(): FileSystem | undefined { return this._shadowRoot; } @@ -135,7 +135,7 @@ export class FileSystem { * generating file system patches using `.diff()` from one snapshot to the next. Performs * no action if this file system is read-only. */ - public snapshot() { + public snapshot(): void { if (this.isReadonly) return; const fs = new FileSystem(this.ignoreCase, { time: this._time }); fs._lazy = this._lazy; @@ -153,7 +153,7 @@ export class FileSystem { * original, allowing multiple copies of the same core file system without multiple copies * of the same data. */ - public shadow(ignoreCase = this.ignoreCase) { + public shadow(ignoreCase: boolean = this.ignoreCase): FileSystem { if (!this.isReadonly) throw new Error("Cannot shadow a mutable file system."); if (ignoreCase && !this.ignoreCase) throw new Error("Cannot create a case-insensitive file system from a case-sensitive one."); const fs = new FileSystem(ignoreCase, { time: this._time }); @@ -201,7 +201,7 @@ export class FileSystem { * * @link - http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html */ - public cwd() { + public cwd(): string { if (!this._cwd) throw new Error("The current working directory has not been set."); const { node } = this._walk(this._cwd); if (!node) throw createIOError("ENOENT"); @@ -214,7 +214,7 @@ export class FileSystem { * * @link http://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html */ - public chdir(path: string) { + public chdir(path: string): void { if (this.isReadonly) throw createIOError("EPERM"); path = this._resolve(path); const { node } = this._walk(path); @@ -226,7 +226,7 @@ export class FileSystem { /** * Pushes the current directory onto the directory stack and changes the current working directory to the supplied path. */ - public pushd(path?: string) { + public pushd(path?: string): void { if (this.isReadonly) throw createIOError("EPERM"); if (path) path = this._resolve(path); if (this._cwd) { @@ -241,7 +241,7 @@ export class FileSystem { /** * Pops the previous directory from the location stack and changes the current directory to that directory. */ - public popd() { + public popd(): void { if (this.isReadonly) throw createIOError("EPERM"); const path = this._dirStack && this._dirStack.pop(); if (path) { @@ -252,7 +252,7 @@ export class FileSystem { /** * Update the file system with a set of files. */ - public apply(files: FileSet) { + public apply(files: FileSet): void { this._applyFiles(files, this._cwd); } @@ -262,7 +262,7 @@ export class FileSystem { * @param axis The axis along which to traverse. * @param traversal The traversal scheme to use. */ - public scanSync(path: string, axis: Axis, traversal: Traversal) { + public scanSync(path: string, axis: Axis, traversal: Traversal): string[] { path = this._resolve(path); const results: string[] = []; this._scan(path, this._stat(this._walk(path)), axis, traversal, /*noFollow*/ false, results); @@ -275,7 +275,7 @@ export class FileSystem { * @param axis The axis along which to traverse. * @param traversal The traversal scheme to use. */ - public lscanSync(path: string, axis: Axis, traversal: Traversal) { + public lscanSync(path: string, axis: Axis, traversal: Traversal): string[] { path = this._resolve(path); const results: string[] = []; this._scan(path, this._stat(this._walk(path, /*noFollow*/ true)), axis, traversal, /*noFollow*/ true, results); @@ -321,7 +321,7 @@ export class FileSystem { * @param target The path in this virtual file system. * @param resolver An object used to resolve files in `source`. */ - public mountSync(source: string, target: string, resolver: FileSystemResolver) { + public mountSync(source: string, target: string, resolver: FileSystemResolver): void { if (this.isReadonly) throw createIOError("EROFS"); source = vpath.validate(source, vpath.ValidationFlags.Absolute); @@ -339,7 +339,7 @@ export class FileSystem { /** * Recursively remove all files and directories underneath the provided path. */ - public rimrafSync(path: string) { + public rimrafSync(path: string): void { try { const stats = this.lstatSync(path); if (stats.isFile() || stats.isSymbolicLink()) { @@ -361,7 +361,7 @@ export class FileSystem { /** * Make a directory and all of its parent paths (if they don't exist). */ - public mkdirpSync(path: string) { + public mkdirpSync(path: string): void { path = this._resolve(path); const result = this._walk(path, /*noFollow*/ true, (error, result) => { if (error.code === "ENOENT") { @@ -410,7 +410,7 @@ export class FileSystem { /** * Determines whether a path exists. */ - public existsSync(path: string) { + public existsSync(path: string): boolean { const result = this._walk(this._resolve(path), /*noFollow*/ true, () => "stop"); return result !== undefined && result.node !== undefined; } @@ -422,7 +422,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public statSync(path: string) { + public statSync(path: string): Stats { return this._stat(this._walk(this._resolve(path))); } @@ -431,7 +431,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public utimesSync(path: string, atime: Date, mtime: Date) { + public utimesSync(path: string, atime: Date, mtime: Date): void { if (this.isReadonly) throw createIOError("EROFS"); if (!isFinite(+atime) || !isFinite(+mtime)) throw createIOError("EINVAL"); @@ -451,7 +451,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public lstatSync(path: string) { + public lstatSync(path: string): Stats { return this._stat(this._walk(this._resolve(path), /*noFollow*/ true)); } @@ -481,7 +481,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public readdirSync(path: string) { + public readdirSync(path: string): string[] { const { node } = this._walk(this._resolve(path)); if (!node) throw createIOError("ENOENT"); if (!isDirectory(node)) throw createIOError("ENOTDIR"); @@ -495,7 +495,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public mkdirSync(path: string) { + public mkdirSync(path: string): void { if (this.isReadonly) throw createIOError("EROFS"); this._mkdir(this._walk(this._resolve(path), /*noFollow*/ true)); @@ -515,7 +515,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public rmdirSync(path: string) { + public rmdirSync(path: string): void { if (this.isReadonly) throw createIOError("EROFS"); path = this._resolve(path); @@ -534,7 +534,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public linkSync(oldpath: string, newpath: string) { + public linkSync(oldpath: string, newpath: string): void { if (this.isReadonly) throw createIOError("EROFS"); const { node } = this._walk(this._resolve(oldpath)); @@ -555,7 +555,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public unlinkSync(path: string) { + public unlinkSync(path: string): void { if (this.isReadonly) throw createIOError("EROFS"); const { parent, links, node, basename } = this._walk(this._resolve(path), /*noFollow*/ true); @@ -573,7 +573,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public renameSync(oldpath: string, newpath: string) { + public renameSync(oldpath: string, newpath: string): void { if (this.isReadonly) throw createIOError("EROFS"); const { parent: oldParent, links: oldParentLinks, node, basename: oldBasename } = this._walk(this._resolve(oldpath), /*noFollow*/ true); @@ -607,7 +607,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public symlinkSync(target: string, linkpath: string) { + public symlinkSync(target: string, linkpath: string): void { if (this.isReadonly) throw createIOError("EROFS"); const { parent, links, node: existingNode, basename } = this._walk(this._resolve(linkpath), /*noFollow*/ true); @@ -627,7 +627,7 @@ export class FileSystem { * * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ - public realpathSync(path: string) { + public realpathSync(path: string): string { const { realpath } = this._walk(this._resolve(path)); return realpath; } @@ -666,7 +666,7 @@ export class FileSystem { * NOTE: do not rename this method as it is intended to align with the same named export of the "fs" module. */ // eslint-disable-next-line no-restricted-syntax - public writeFileSync(path: string, data: string | Buffer, encoding: string | null = null) { + public writeFileSync(path: string, data: string | Buffer, encoding: string | null = null): void { if (this.isReadonly) throw createIOError("EROFS"); const { parent, links, node: existingNode, basename } = this._walk(this._resolve(path), /*noFollow*/ false); @@ -694,7 +694,7 @@ export class FileSystem { * Generates a `FileSet` patch containing all the entries in this `FileSystem` that are not in `base`. * @param base The base file system. If not provided, this file system's `shadowRoot` is used (if present). */ - public diff(base?: FileSystem | undefined, options: DiffOptions = {}) { + public diff(base?: FileSystem | undefined, options: DiffOptions = {}): FileSet | undefined { if (!base && !options.baseIsNotShadowRoot) base = this.shadowRoot; const differences: FileSet = {}; const hasDifferences = base ? @@ -707,7 +707,7 @@ export class FileSystem { /** * Generates a `FileSet` patch containing all the entries in `changed` that are not in `base`. */ - public static diff(changed: FileSystem, base: FileSystem, options: DiffOptions = {}) { + public static diff(changed: FileSystem, base: FileSystem, options: DiffOptions = {}): FileSet | undefined { const differences: FileSet = {}; return FileSystem.rootDiff(differences, changed, base, options) ? differences : @@ -1253,7 +1253,7 @@ export function createResolver(host: FileSystemResolverHost): FileSystemResolver * * Unless overridden, `/.src` will be the current working directory for the virtual file system. */ -export function createFromFileSystem(host: FileSystemResolverHost, ignoreCase: boolean, { documents, files, cwd, time, meta }: FileSystemCreateOptions = {}) { +export function createFromFileSystem(host: FileSystemResolverHost, ignoreCase: boolean, { documents, files, cwd, time, meta }: FileSystemCreateOptions = {}): FileSystem { const fs = getBuiltLocal(host, ignoreCase).shadow(); if (meta) { for (const key of Object.keys(meta)) { @@ -1331,30 +1331,31 @@ export class Stats { this.birthtime = new Date(this.birthtimeMs); } - public isFile() { + public isFile(): boolean { return (this.mode & S_IFMT) === S_IFREG; } - public isDirectory() { + public isDirectory(): boolean { return (this.mode & S_IFMT) === S_IFDIR; } - public isSymbolicLink() { + public isSymbolicLink(): boolean { return (this.mode & S_IFMT) === S_IFLNK; } - public isBlockDevice() { + public isBlockDevice(): boolean { return (this.mode & S_IFMT) === S_IFBLK; } - public isCharacterDevice() { + public isCharacterDevice(): boolean { return (this.mode & S_IFMT) === S_IFCHR; } - public isFIFO() { + public isFIFO(): boolean { return (this.mode & S_IFMT) === S_IFIFO; } - public isSocket() { + public isSocket(): boolean { return (this.mode & S_IFMT) === S_IFSOCK; } } -export const IOErrorMessages = Object.freeze({ +// IOErrorMessages is defined like this to reduce duplication for --isolatedDeclarations +const TemplateIOErrorMessages = { EACCES: "access denied", EIO: "an I/O error occurred", ENOENT: "no such file or directory", @@ -1367,9 +1368,10 @@ export const IOErrorMessages = Object.freeze({ ENOTEMPTY: "directory not empty", EPERM: "operation not permitted", EROFS: "file system is read-only", -}); +} as const; +export const IOErrorMessages: typeof TemplateIOErrorMessages = Object.freeze(TemplateIOErrorMessages); -export function createIOError(code: keyof typeof IOErrorMessages, details = "") { +export function createIOError(code: keyof typeof IOErrorMessages, details = ""): NodeJS.ErrnoException { const err: NodeJS.ErrnoException = new Error(`${code}: ${IOErrorMessages[code]} ${details}`); err.code = code; if (Error.captureStackTrace) Error.captureStackTrace(err, createIOError); diff --git a/src/harness/vpathUtil.ts b/src/harness/vpathUtil.ts index fa26c4a7fd1de..2dfa6b27be03d 100644 --- a/src/harness/vpathUtil.ts +++ b/src/harness/vpathUtil.ts @@ -102,32 +102,32 @@ function validateComponents(components: string[], flags: ValidationFlags, hasTra return true; } -export function validate(path: string, flags: ValidationFlags = ValidationFlags.RelativeOrAbsolute) { +export function validate(path: string, flags: ValidationFlags = ValidationFlags.RelativeOrAbsolute): string { const components = parse(path); const trailing = hasTrailingSeparator(path); if (!validateComponents(components, flags, trailing)) throw vfs.createIOError("ENOENT"); return components.length > 1 && trailing ? format(reduce(components)) + sep : format(reduce(components)); } -export function isDeclaration(path: string) { +export function isDeclaration(path: string): boolean { return ts.isDeclarationFileName(path); } -export function isSourceMap(path: string) { +export function isSourceMap(path: string): boolean { return extname(path, ".map", /*ignoreCase*/ false).length > 0; } const javaScriptSourceMapExtensions: readonly string[] = [".js.map", ".jsx.map"]; -export function isJavaScriptSourceMap(path: string) { +export function isJavaScriptSourceMap(path: string): boolean { return extname(path, javaScriptSourceMapExtensions, /*ignoreCase*/ false).length > 0; } -export function isJson(path: string) { +export function isJson(path: string): boolean { return extname(path, ".json", /*ignoreCase*/ false).length > 0; } -export function isDefaultLibrary(path: string) { +export function isDefaultLibrary(path: string): boolean { return isDeclaration(path) && basename(path).startsWith("lib."); } diff --git a/src/harness/watchUtils.ts b/src/harness/watchUtils.ts index 23a5e3d453014..5875264317424 100644 --- a/src/harness/watchUtils.ts +++ b/src/harness/watchUtils.ts @@ -14,7 +14,7 @@ import { System, } from "./_namespaces/ts.js"; -export function ensureWatchablePath(path: string, locationType: string) { +export function ensureWatchablePath(path: string, locationType: string): void { Debug.assert( canWatchDirectoryOrFilePath(path as Path), `Not a watchable location: ${locationType} like "/home/src/workspaces/project" or refer canWatchDirectoryOrFile for more allowed locations`, @@ -195,7 +195,7 @@ export function createWatchUtils( } } -export function serializeMultiMap(baseline: string[], caption: string, multiMap: MultiMap, serialized: Map | undefined) { +export function serializeMultiMap(baseline: string[], caption: string, multiMap: MultiMap, serialized: Map | undefined): Map | undefined { let hasChange = diffMap(baseline, caption, multiMap, serialized, /*deleted*/ false); hasChange = diffMap(baseline, caption, serialized, multiMap, /*deleted*/ true) || hasChange; if (hasChange) { diff --git a/src/jsTyping/jsTyping.ts b/src/jsTyping/jsTyping.ts index cb38ce1d1af0b..4554eb4c731eb 100644 --- a/src/jsTyping/jsTyping.ts +++ b/src/jsTyping/jsTyping.ts @@ -57,13 +57,13 @@ export interface CachedTyping { } /** @internal */ -export function isTypingUpToDate(cachedTyping: CachedTyping, availableTypingVersions: MapLike) { +export function isTypingUpToDate(cachedTyping: CachedTyping, availableTypingVersions: MapLike): boolean { const availableVersion = new Version(getProperty(availableTypingVersions, `ts${versionMajorMinor}`) || getProperty(availableTypingVersions, "latest")!); return availableVersion.compareTo(cachedTyping.version) <= 0; } /** @internal */ -export function nonRelativeModuleNameForTypingCache(moduleName: string) { +export function nonRelativeModuleNameForTypingCache(moduleName: string): string { return nodeCoreModules.has(moduleName) ? "node" : moduleName; } diff --git a/src/jsTyping/shared.ts b/src/jsTyping/shared.ts index ddf13a4c9f9d7..9689eebaeda66 100644 --- a/src/jsTyping/shared.ts +++ b/src/jsTyping/shared.ts @@ -45,7 +45,7 @@ export namespace Arguments { } /** @internal */ -export function hasArgument(argumentName: string) { +export function hasArgument(argumentName: string): boolean { return sys.args.includes(argumentName); } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 663eb94fcf3dd..1a9e6ed5b920f 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -188,9 +188,9 @@ import { } from "./_namespaces/ts.server.js"; import * as protocol from "./protocol.js"; -export const maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; +export const maxProgramSizeForNonTsFiles: number = 20 * 1024 * 1024; /** @internal */ -export const maxFileSize = 4 * 1024 * 1024; +export const maxFileSize: number = 4 * 1024 * 1024; export const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground"; export const ProjectLoadingStartEvent = "projectLoadingStart"; @@ -489,7 +489,7 @@ export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName return isString(scriptKindName) ? convertScriptKindName(scriptKindName) : scriptKindName; } -export function convertScriptKindName(scriptKindName: protocol.ScriptKindName) { +export function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind { switch (scriptKindName) { case "JS": return ScriptKind.JS; @@ -952,7 +952,7 @@ function isScriptInfoWatchedFromNodeModules(info: ScriptInfo) { * returns true if project updated with new program * @internal */ -export function updateProjectIfDirty(project: Project) { +export function updateProjectIfDirty(project: Project): boolean { project.invalidateResolutionsOfFailedLookupLocations(); return project.dirty && !project.updateGraph(); } @@ -1161,7 +1161,7 @@ export class ProjectService { * * @internal */ - readonly filenameToScriptInfo = new Map(); + readonly filenameToScriptInfo: Map = new Map(); private readonly nodeModulesWatchers = new Map(); /** * Contains all the deleted script info's version information so that @@ -1194,17 +1194,17 @@ export class ProjectService { /** * projects specified by a tsconfig.json file */ - readonly configuredProjects: Map = new Map(); + readonly configuredProjects: Map = new Map(); /** @internal */ - readonly newInferredProjectName = createProjectNameFactoryWithCounter(makeInferredProjectName); + readonly newInferredProjectName: () => string = createProjectNameFactoryWithCounter(makeInferredProjectName); /** @internal */ - readonly newAutoImportProviderProjectName = createProjectNameFactoryWithCounter(makeAutoImportProviderProjectName); + readonly newAutoImportProviderProjectName: () => string = createProjectNameFactoryWithCounter(makeAutoImportProviderProjectName); /** @internal */ - readonly newAuxiliaryProjectName = createProjectNameFactoryWithCounter(makeAuxiliaryProjectName); + readonly newAuxiliaryProjectName: () => string = createProjectNameFactoryWithCounter(makeAuxiliaryProjectName); /** * Open files: with value being project root path, and key being Path of the file that is open */ - readonly openFiles: Map = new Map(); + readonly openFiles: Map = new Map(); /** Config files looked up and cached config files for open script info */ private readonly configFileForOpenFiles = new Map(); /** Set of open script infos that are root of inferred project */ @@ -1233,7 +1233,7 @@ export class ProjectService { * * @internal */ - readonly configFileExistenceInfoCache = new Map(); + readonly configFileExistenceInfoCache: Map = new Map(); /** @internal */ readonly throttledOperations: ThrottledOperations; private readonly hostConfiguration: HostConfiguration; @@ -1295,7 +1295,7 @@ export class ProjectService { private currentPluginEnablementPromise?: Promise; /** @internal */ baseline: (title?: string) => void = noop; - /** @internal */ verifyDocumentRegistry = noop; + /** @internal */ verifyDocumentRegistry: typeof noop = noop; /** @internal */ verifyProgram: (project: Project) => void = noop; /** @internal */ onProjectCreation: (project: Project) => void = noop; /** @internal */ canUseWatchEvents: boolean; @@ -1381,22 +1381,22 @@ export class ProjectService { opts.incrementalVerifier?.(this); } - toPath(fileName: string) { + toPath(fileName: string): Path { return toPath(fileName, this.currentDirectory, this.toCanonicalFileName); } /** @internal */ - getExecutingFilePath() { + getExecutingFilePath(): string { return this.getNormalizedAbsolutePath(this.host.getExecutingFilePath()); } /** @internal */ - getNormalizedAbsolutePath(fileName: string) { + getNormalizedAbsolutePath(fileName: string): string { return getNormalizedAbsolutePath(fileName, this.host.getCurrentDirectory()); } /** @internal */ - setDocument(key: DocumentRegistryBucketKeyWithMode, path: Path, sourceFile: SourceFile) { + setDocument(key: DocumentRegistryBucketKeyWithMode, path: Path, sourceFile: SourceFile): void { const info = Debug.checkDefined(this.getScriptInfoForPath(path)); info.cacheSourceFile = { key, sourceFile }; } @@ -1408,17 +1408,17 @@ export class ProjectService { } /** @internal */ - ensureInferredProjectsUpToDate_TestOnly() { + ensureInferredProjectsUpToDate_TestOnly(): void { this.ensureProjectStructuresUptoDate(); } /** @internal */ - getCompilerOptionsForInferredProjects() { + getCompilerOptionsForInferredProjects(): CompilerOptions | undefined { return this.compilerOptionsForInferredProjects; } /** @internal */ - onUpdateLanguageServiceStateForProject(project: Project, languageServiceEnabled: boolean) { + onUpdateLanguageServiceStateForProject(project: Project, languageServiceEnabled: boolean): void { if (!this.eventHandler) { return; } @@ -1482,12 +1482,12 @@ export class ProjectService { } /** @internal */ - watchTypingLocations(response: WatchTypingLocations) { + watchTypingLocations(response: WatchTypingLocations): void { this.findProject(response.projectName)?.watchTypingLocations(response.files); } /** @internal */ - delayEnsureProjectForOpenFiles() { + delayEnsureProjectForOpenFiles(): void { if (!this.openFiles.size) return; this.pendingEnsureProjectForOpenFiles = true; this.throttledOperations.schedule(ensureProjectForOpenFileSchedule, /*delay*/ 2500, () => { @@ -1520,12 +1520,12 @@ export class ProjectService { } /** @internal */ - hasPendingProjectUpdate(project: Project) { + hasPendingProjectUpdate(project: Project): boolean { return this.pendingProjectUpdates.has(project.getProjectName()); } /** @internal */ - sendProjectsUpdatedInBackgroundEvent() { + sendProjectsUpdatedInBackgroundEvent(): void { if (!this.eventHandler) { return; } @@ -1540,7 +1540,7 @@ export class ProjectService { } /** @internal */ - sendLargeFileReferencedEvent(file: string, fileSize: number) { + sendLargeFileReferencedEvent(file: string, fileSize: number): void { if (!this.eventHandler) { return; } @@ -1553,7 +1553,7 @@ export class ProjectService { } /** @internal */ - sendProjectLoadingStartEvent(project: ConfiguredProject, reason: string) { + sendProjectLoadingStartEvent(project: ConfiguredProject, reason: string): void { if (!this.eventHandler) { return; } @@ -1566,7 +1566,7 @@ export class ProjectService { } /** @internal */ - sendProjectLoadingFinishEvent(project: ConfiguredProject) { + sendProjectLoadingFinishEvent(project: ConfiguredProject): void { if (!this.eventHandler || !project.sendLoadingProjectFinish) { return; } @@ -1580,14 +1580,14 @@ export class ProjectService { } /** @internal */ - sendPerformanceEvent(kind: PerformanceEvent["kind"], durationMs: number) { + sendPerformanceEvent(kind: PerformanceEvent["kind"], durationMs: number): void { if (this.performanceEventHandler) { this.performanceEventHandler({ kind, durationMs }); } } /** @internal */ - delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project: Project) { + delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(project: Project): void { this.delayUpdateProjectGraph(project); this.delayEnsureProjectForOpenFiles(); } @@ -1663,14 +1663,14 @@ export class ProjectService { } /** @internal */ - forEachProject(cb: (project: Project) => void) { + forEachProject(cb: (project: Project) => void): void { this.externalProjects.forEach(cb); this.configuredProjects.forEach(cb); this.inferredProjects.forEach(cb); } /** @internal */ - forEachEnabledProject(cb: (project: Project) => void) { + forEachEnabledProject(cb: (project: Project) => void): void { this.forEachProject(project => { if (!project.isOrphan() && project.languageServiceEnabled) { cb(project); @@ -1721,7 +1721,7 @@ export class ProjectService { (this.logErrorForScriptInfoNotFound(isString(fileNameOrScriptInfo) ? fileNameOrScriptInfo : fileNameOrScriptInfo.fileName), Errors.ThrowNoProject()); } - getScriptInfoEnsuringProjectsUptoDate(uncheckedFileName: string) { + getScriptInfoEnsuringProjectsUptoDate(uncheckedFileName: string): ScriptInfo | undefined { this.ensureProjectStructuresUptoDate(); return this.getScriptInfo(uncheckedFileName); } @@ -1748,7 +1748,7 @@ export class ProjectService { } } - getFormatCodeOptions(file: NormalizedPath) { + getFormatCodeOptions(file: NormalizedPath): FormatCodeSettings { const info = this.getScriptInfoForNormalizedPath(file); return info && info.getFormatCodeSettings() || this.hostConfiguration.formatCodeOptions; } @@ -2103,7 +2103,7 @@ export class ProjectService { } /** @internal */ - assignOrphanScriptInfoToInferredProject(info: ScriptInfo, projectRootPath: NormalizedPath | undefined) { + assignOrphanScriptInfoToInferredProject(info: ScriptInfo, projectRootPath: NormalizedPath | undefined): InferredProject { Debug.assert(info.isOrphan()); const project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) || this.getOrCreateSingleInferredProjectIfEnabled() || @@ -2307,7 +2307,7 @@ export class ProjectService { } /** @internal */ - releaseParsedConfig(canonicalConfigFilePath: NormalizedPath, forProject: ConfiguredProject) { + releaseParsedConfig(canonicalConfigFilePath: NormalizedPath, forProject: ConfiguredProject): void { const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath)!; if (!configFileExistenceInfo.config?.projects.delete(forProject.canonicalConfigFilePath)) return; // If there are still projects watching this config file existence and config, there is nothing to do @@ -2345,7 +2345,7 @@ export class ProjectService { * so that we handle the watches and inferred project root data * @internal */ - stopWatchingConfigFilesForScriptInfo(info: ScriptInfo) { + stopWatchingConfigFilesForScriptInfo(info: ScriptInfo): void { if (this.serverMode !== LanguageServiceMode.Semantic) return; const isRootOfInferredProject = this.rootOfInferredProjects.delete(info); const isOpen = info.isScriptOpen(); @@ -2401,7 +2401,7 @@ export class ProjectService { * * @internal */ - startWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo) { + startWatchingConfigFilesForInferredProjectRoot(info: ScriptInfo): void { if (this.serverMode !== LanguageServiceMode.Semantic) return; Debug.assert(info.isScriptOpen()); // Set this file as the root of inferred project @@ -2489,7 +2489,7 @@ export class ProjectService { } /** @internal */ - findDefaultConfiguredProject(info: ScriptInfo) { + findDefaultConfiguredProject(info: ScriptInfo): ConfiguredProject | undefined { return info.isScriptOpen() ? this.tryFindDefaultConfiguredProjectForOpenScriptInfo( info, @@ -2532,7 +2532,7 @@ export class ProjectService { * when findFromCacheOnly is true only looked up in cache instead of hitting disk to figure things out * @internal */ - getConfigFileNameForFile(info: OpenScriptInfoOrClosedOrConfigFileInfo, findFromCacheOnly: boolean) { + getConfigFileNameForFile(info: OpenScriptInfoOrClosedOrConfigFileInfo, findFromCacheOnly: boolean): NormalizedPath | undefined { // If we are using already cached values, look for values from pending update as well const fromCache = this.getConfigFileNameForFileFromCache(info, findFromCacheOnly); if (fromCache !== undefined) return fromCache || undefined; @@ -2690,7 +2690,7 @@ export class ProjectService { } /** @internal */ - createConfiguredProject(configFileName: NormalizedPath, reason: string) { + createConfiguredProject(configFileName: NormalizedPath, reason: string): ConfiguredProject { tracing?.instant(tracing.Phase.Session, "createConfiguredProject", { configFilePath: configFileName }); const canonicalConfigFilePath = asNormalizedPath(this.toCanonicalFileName(configFileName)); let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); @@ -2874,7 +2874,7 @@ export class ProjectService { } /** @internal */ - watchWildcards(configFileName: NormalizedPath, { exists, config }: ConfigFileExistenceInfo, forProject: ConfiguredProject) { + watchWildcards(configFileName: NormalizedPath, { exists, config }: ConfigFileExistenceInfo, forProject: ConfiguredProject): void { config!.projects.set(forProject.canonicalConfigFilePath, true); if (exists) { if (config!.watchedDirectories && !config!.watchedDirectoriesStale) return; @@ -2895,7 +2895,7 @@ export class ProjectService { } /** @internal */ - stopWatchingWildCards(canonicalConfigFilePath: NormalizedPath, forProject: ConfiguredProject) { + stopWatchingWildCards(canonicalConfigFilePath: NormalizedPath, forProject: ConfiguredProject): void { const configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath)!; if ( !configFileExistenceInfo.config || @@ -3001,7 +3001,7 @@ export class ProjectService { * * @internal */ - reloadFileNamesOfConfiguredProject(project: ConfiguredProject) { + reloadFileNamesOfConfiguredProject(project: ConfiguredProject): boolean { const fileNames = this.reloadFileNamesOfParsedConfig(project.getConfigFilePath(), this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath)!.config!); project.updateErrorOnNoInputFiles(fileNames); this.updateNonInferredProjectFiles(project, fileNames.concat(project.getExternalFiles(ProgramUpdateLevel.RootNamesAndUpdate)), fileNamePropertyReader); @@ -3028,7 +3028,7 @@ export class ProjectService { setFileNamesOfAutoImportProviderOrAuxillaryProject( project: AutoImportProviderProject | AuxiliaryProject, fileNames: readonly string[], - ) { + ): void { this.updateNonInferredProjectFiles(project, fileNames, fileNamePropertyReader); } @@ -3037,7 +3037,7 @@ export class ProjectService { project: ConfiguredProject, reason: string, reloadedProjects: Set, - ) { + ): boolean { if (!tryAddToSet(reloadedProjects, project)) return false; this.clearSemanticCache(project); this.reloadConfiguredProject(project, reloadReason(reason)); @@ -3049,7 +3049,7 @@ export class ProjectService { * * @internal */ - reloadConfiguredProject(project: ConfiguredProject, reason: string) { + reloadConfiguredProject(project: ConfiguredProject, reason: string): void { project.isInitialLoadPending = returnFalse; project.pendingUpdateReason = undefined; project.pendingUpdateLevel = ProgramUpdateLevel.Update; @@ -3074,7 +3074,7 @@ export class ProjectService { } /** @internal */ - sendConfigFileDiagEvent(project: ConfiguredProject, triggerFile: NormalizedPath | undefined, force: boolean) { + sendConfigFileDiagEvent(project: ConfiguredProject, triggerFile: NormalizedPath | undefined, force: boolean): boolean { if (!this.eventHandler || this.suppressDiagnosticEvents) return false; const diagnostics = project.getLanguageService().getCompilerOptionsDiagnostics(); diagnostics.push(...project.getAllProjectErrors()); @@ -3216,7 +3216,7 @@ export class ProjectService { currentDirectory: string, hostToQueryFileExistsOn: DirectoryStructureHost, deferredDeleteOk: boolean, - ) { + ): ScriptInfo | undefined { return this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath( toNormalizedPath(uncheckedFileName), currentDirectory, @@ -3227,7 +3227,7 @@ export class ProjectService { ); } - getScriptInfo(uncheckedFileName: string) { + getScriptInfo(uncheckedFileName: string): ScriptInfo | undefined { return this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName)); } @@ -3475,7 +3475,7 @@ export class ProjectService { scriptKind?: ScriptKind, hasMixedContent?: boolean, hostToQueryFileExistsOn?: { fileExists(path: string): boolean; }, - ) { + ): ScriptInfo | undefined { return this.getOrCreateScriptInfoWorker( fileName, this.currentDirectory, @@ -3544,12 +3544,12 @@ export class ProjectService { /** * This gets the script info for the normalized path. If the path is not rooted disk path then the open script info with project root context is preferred */ - getScriptInfoForNormalizedPath(fileName: NormalizedPath) { + getScriptInfoForNormalizedPath(fileName: NormalizedPath): ScriptInfo | undefined { return !isRootedDiskPath(fileName) && this.openFilesWithNonRootedDiskPath.get(this.toCanonicalFileName(fileName)) || this.getScriptInfoForPath(normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName)); } - getScriptInfoForPath(fileName: Path) { + getScriptInfoForPath(fileName: Path): ScriptInfo | undefined { const info = this.filenameToScriptInfo.get(fileName); return !info || !info.deferredDelete ? info : undefined; } @@ -3722,11 +3722,11 @@ export class ProjectService { } /** @internal */ - setPerformanceEventHandler(performanceEventHandler: PerformanceEventHandler) { + setPerformanceEventHandler(performanceEventHandler: PerformanceEventHandler): void { this.performanceEventHandler = performanceEventHandler; } - setHostConfiguration(args: protocol.ConfigureRequestArguments) { + setHostConfiguration(args: protocol.ConfigureRequestArguments): void { if (args.file) { const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file)); if (info) { @@ -3794,7 +3794,7 @@ export class ProjectService { } /** @internal */ - getWatchOptions(project: Project) { + getWatchOptions(project: Project): WatchOptions | undefined { return this.getWatchOptionsFromProjectWatchOptions(project.getWatchOptions(), project.getCurrentDirectory()); } @@ -3809,7 +3809,7 @@ export class ProjectService { projectOptions || hostWatchOptions; } - closeLog() { + closeLog(): void { this.logger.close(); } @@ -3845,7 +3845,7 @@ export class ProjectService { * This function rebuilds the project for every file opened by the client * This does not reload contents of open files from disk. But we could do that if needed */ - reloadProjects() { + reloadProjects(): void { this.logger.info("reload projects."); // If we want this to also reload open files from disk, we could do that, // but then we need to make sure we arent calling this function @@ -4343,7 +4343,7 @@ export class ProjectService { } /** @internal */ - loadAncestorProjectTree(forProjects?: ReadonlyCollection) { + loadAncestorProjectTree(forProjects?: ReadonlyCollection): void { forProjects ??= new Set( mapDefinedIterator(this.configuredProjects.entries(), ([key, project]) => !project.isInitialLoadPending() ? key : undefined), ); @@ -4750,7 +4750,7 @@ export class ProjectService { } /** @internal */ - applyChangesToFile(scriptInfo: ScriptInfo, changes: Iterable) { + applyChangesToFile(scriptInfo: ScriptInfo, changes: Iterable): void { for (const change of changes) { scriptInfo.editContent(change.span.start, change.span.start + change.span.length, change.newText); } @@ -5004,7 +5004,7 @@ export class ProjectService { } } - hasDeferredExtension() { + hasDeferredExtension(): boolean { for (const extension of this.hostConfiguration.extraFileExtensions!) { // TODO: GH#18217 if (extension.scriptKind === ScriptKind.Deferred) { return true; @@ -5018,7 +5018,7 @@ export class ProjectService { * Performs the initial steps of enabling a plugin by finding and instantiating the module for a plugin either asynchronously or synchronously * @internal */ - requestEnablePlugin(project: Project, pluginConfigEntry: PluginImport, searchPaths: string[]) { + requestEnablePlugin(project: Project, pluginConfigEntry: PluginImport, searchPaths: string[]): void { if (!this.host.importPlugin && !this.host.require) { this.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; @@ -5082,12 +5082,12 @@ export class ProjectService { } /** @internal */ - hasNewPluginEnablementRequests() { + hasNewPluginEnablementRequests(): boolean { return !!this.pendingPluginEnablements; } /** @internal */ - hasPendingPluginEnablements() { + hasPendingPluginEnablements(): boolean { return !!this.currentPluginEnablementPromise; } @@ -5096,7 +5096,7 @@ export class ProjectService { * * @internal */ - async waitForPendingPlugins() { + async waitForPendingPlugins(): Promise { while (this.currentPluginEnablementPromise) { await this.currentPluginEnablementPromise; } @@ -5107,7 +5107,7 @@ export class ProjectService { * * @internal */ - enableRequestedPlugins() { + enableRequestedPlugins(): void { if (this.pendingPluginEnablements) { void this.enableRequestedPluginsAsync(); } @@ -5164,7 +5164,7 @@ export class ProjectService { if (sendProjectsUpdatedInBackgroundEvent) this.sendProjectsUpdatedInBackgroundEvent(); } - configurePlugin(args: protocol.ConfigurePluginRequestArguments) { + configurePlugin(args: protocol.ConfigurePluginRequestArguments): void { // For any projects that already have the plugin loaded, configure the plugin this.forEachEnabledProject(project => project.onPluginConfigurationChanged(args.pluginName, args.configuration)); @@ -5283,7 +5283,7 @@ export class ProjectService { } /** @internal */ - getIncompleteCompletionsCache() { + getIncompleteCompletionsCache(): IncompleteCompletionsCache { return this.incompleteCompletionsCache ||= createIncompleteCompletionsCache(); } } diff --git a/src/server/project.ts b/src/server/project.ts index bbd97689b17d5..6df9e1aca3e4a 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -68,6 +68,7 @@ import { HasInvalidatedLibResolutions, HasInvalidatedResolutions, HostCancellationToken, + IncompleteCompletionsCache, inferredTypesContainingFile, InstallPackageOptions, IScriptSnapshot, @@ -85,6 +86,7 @@ import { memoize, ModuleResolutionCache, ModuleResolutionHost, + ModuleSpecifierCache, noop, noopFileWatcher, normalizePath, @@ -115,6 +117,7 @@ import { sortAndDeduplicate, SortedReadonlyArray, SourceFile, + SourceFileLike, SourceMapper, startsWith, StringLiteralLike, @@ -146,6 +149,7 @@ import { Msg, NormalizedPath, nullTypingsInstaller, + PackageJsonCache, PackageJsonWatcher, ProjectOptions, ProjectService, @@ -378,7 +382,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo * * @internal */ - cachedUnresolvedImportsPerFile = new Map(); + cachedUnresolvedImportsPerFile: Map = new Map(); /** @internal */ lastCachedUnresolvedImportsList: SortedReadonlyArray | undefined; @@ -466,12 +470,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo private readonly cancellationToken: ThrottledCancellationToken; - public isNonTsProject() { + public isNonTsProject(): boolean { updateProjectIfDirty(this); return allFilesAreJsOrDts(this); } - public isJsOnlyProject() { + public isJsOnlyProject(): boolean { updateProjectIfDirty(this); return hasOneOrMoreJsAndNoTsFiles(this); } @@ -555,7 +559,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo /** @internal */ protected typeAcquisition: TypeAcquisition | undefined; /** @internal */ - createHash = maybeBind(this.projectService.host, this.projectService.host.createHash); + createHash: ((data: string) => string) | undefined = maybeBind(this.projectService.host, this.projectService.host.createHash); /** @internal*/ preferNonRecursiveWatch: boolean | undefined; readonly jsDocParsingMode: JSDocParsingMode | undefined; @@ -648,7 +652,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - getGlobalTypingsCacheLocation() { + getGlobalTypingsCacheLocation(): string | undefined { return this.getTypeAcquisition().enable ? this.projectService.typingsInstaller.globalTypingsCacheLocation : undefined; } @@ -668,20 +672,20 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } // Method of LanguageServiceHost - getCompilationSettings() { + getCompilationSettings(): CompilerOptions { return this.compilerOptions; } // Method to support public API - getCompilerOptions() { + getCompilerOptions(): CompilerOptions { return this.getCompilationSettings(); } - getNewLine() { + getNewLine(): string { return this.projectService.host.newLine; } - getProjectVersion() { + getProjectVersion(): string { return this.projectStateVersion.toString(); } @@ -689,7 +693,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return undefined; } - getScriptFileNames() { + getScriptFileNames(): string[] { if (!this.rootFilesMap.size) { return ts.emptyArray; } @@ -723,12 +727,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return scriptInfo; } - getScriptKind(fileName: string) { + getScriptKind(fileName: string): ScriptKind { const info = this.projectService.getScriptInfoForPath(this.toPath(fileName)); return (info && info.scriptKind)!; // TODO: GH#18217 } - getScriptVersion(filename: string) { + getScriptVersion(filename: string): string { // Don't attach to the project if version is asked const info = this.projectService.getOrCreateScriptInfoNotOpenedByClient( @@ -755,12 +759,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return this.currentDirectory; } - getDefaultLibFileName() { + getDefaultLibFileName(): string { const nodeModuleBinDir = getDirectoryPath(normalizePath(this.projectService.getExecutingFilePath())); return combinePaths(nodeModuleBinDir, getDefaultLibFileName(this.compilerOptions)); } - useCaseSensitiveFileNames() { + useCaseSensitiveFileNames(): boolean { return this.projectService.host.useCaseSensitiveFileNames; } @@ -825,12 +829,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - toPath(fileName: string) { + toPath(fileName: string): Path { return toPath(fileName, this.currentDirectory, this.projectService.toCanonicalFileName); } /** @internal */ - watchDirectoryOfFailedLookupLocation(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags) { + watchDirectoryOfFailedLookupLocation(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher { return this.projectService.watchFactory.watchDirectory( directory, cb, @@ -842,7 +846,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - watchAffectingFileLocation(file: string, cb: FileWatcherCallback) { + watchAffectingFileLocation(file: string, cb: FileWatcherCallback): FileWatcher { return this.projectService.watchFactory.watchFile( file, cb, @@ -854,12 +858,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - clearInvalidateResolutionOfFailedLookupTimer() { + clearInvalidateResolutionOfFailedLookupTimer(): boolean { return this.projectService.throttledOperations.cancel(`${this.getProjectName()}FailedLookupInvalidation`); } /** @internal */ - scheduleInvalidateResolutionsOfFailedLookupLocations() { + scheduleInvalidateResolutionsOfFailedLookupLocations(): void { this.projectService.throttledOperations.schedule(`${this.getProjectName()}FailedLookupInvalidation`, /*delay*/ 1000, () => { if (this.resolutionCache.invalidateResolutionsOfFailedLookupLocations()) { this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this); @@ -868,7 +872,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - invalidateResolutionsOfFailedLookupLocations() { + invalidateResolutionsOfFailedLookupLocations(): void { if ( this.clearInvalidateResolutionOfFailedLookupTimer() && this.resolutionCache.invalidateResolutionsOfFailedLookupLocations() @@ -879,12 +883,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - onInvalidatedResolution() { + onInvalidatedResolution(): void { this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this); } /** @internal */ - watchTypeRootsDirectory(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags) { + watchTypeRootsDirectory(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher { return this.projectService.watchFactory.watchDirectory( directory, cb, @@ -896,33 +900,33 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - hasChangedAutomaticTypeDirectiveNames() { + hasChangedAutomaticTypeDirectiveNames(): boolean { return this.resolutionCache.hasChangedAutomaticTypeDirectiveNames(); } /** @internal */ - onChangedAutomaticTypeDirectiveNames() { + onChangedAutomaticTypeDirectiveNames(): void { this.projectService.delayUpdateProjectGraphAndEnsureProjectStructureForOpenFiles(this); } /** @internal */ - globalCacheResolutionModuleName = JsTyping.nonRelativeModuleNameForTypingCache; + globalCacheResolutionModuleName: typeof JsTyping.nonRelativeModuleNameForTypingCache = JsTyping.nonRelativeModuleNameForTypingCache; /** @internal */ - fileIsOpen(filePath: Path) { + fileIsOpen(filePath: Path): boolean { return this.projectService.openFiles.has(filePath); } /** @internal */ - writeLog(s: string) { + writeLog(s: string): void { this.projectService.logger.info(s); } - log(s: string) { + log(s: string): void { this.writeLog(s); } - error(s: string) { + error(s: string): void { this.projectService.logger.msg(s, Msg.Err); } @@ -946,7 +950,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return this.projectErrors || emptyArray; } - setProjectErrors(projectErrors: Diagnostic[] | undefined) { + setProjectErrors(projectErrors: Diagnostic[] | undefined): void { this.projectErrors = projectErrors; } @@ -963,7 +967,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - clearSourceMapperCache() { + clearSourceMapperCache(): void { this.languageService.clearSourceMapperCache(); } @@ -973,12 +977,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - getSourceFileLike(fileName: string) { + getSourceFileLike(fileName: string): SourceFileLike | undefined { return this.projectService.getSourceFileLike(fileName, this); } /** @internal */ - shouldEmitFile(scriptInfo: ScriptInfo | undefined) { + shouldEmitFile(scriptInfo: ScriptInfo | undefined): boolean | undefined { return scriptInfo && !scriptInfo.isDynamicOrHasMixedContent() && !this.program!.isSourceOfProjectReferenceRedirect(scriptInfo.path); @@ -1032,7 +1036,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return { emitSkipped, diagnostics }; } - enableLanguageService() { + enableLanguageService(): void { if (this.languageServiceEnabled || this.projectService.serverMode === LanguageServiceMode.Syntactic) { return; } @@ -1042,7 +1046,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - cleanupProgram() { + cleanupProgram(): void { if (this.program) { // Root files are always attached to the project irrespective of program for (const f of this.program.getSourceFiles()) { @@ -1053,7 +1057,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } } - disableLanguageService(lastFileExceededProgramSize?: string) { + disableLanguageService(lastFileExceededProgramSize?: string): void { if (!this.languageServiceEnabled) { return; } @@ -1073,7 +1077,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo this.projectService.onUpdateLanguageServiceStateForProject(this, /*languageServiceEnabled*/ false); } - getProjectName() { + getProjectName(): string { return this.projectName; } @@ -1100,7 +1104,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo })); } - getSourceFile(path: Path) { + getSourceFile(path: Path): SourceFile | undefined { if (!this.program) { return undefined; } @@ -1113,7 +1117,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return path === options.configFilePath ? options.configFile : this.getSourceFile(path); } - close() { + close(): void { if (this.typingsCache) this.projectService.typingsInstaller.onProjectClosed(this); this.typingsCache = undefined; this.closeWatchingTypingLocations(); @@ -1176,11 +1180,11 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } } - isClosed() { + isClosed(): boolean { return this.rootFilesMap === undefined; } - hasRoots() { + hasRoots(): boolean { return !!this.rootFilesMap?.size; } @@ -1194,11 +1198,11 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - getRootFilesMap() { + getRootFilesMap(): Map { return this.rootFilesMap; } - getRootScriptInfos() { + getRootScriptInfos(): ScriptInfo[] { return arrayFrom(ts.mapDefinedIterator(this.rootFilesMap.values(), value => value.info)); } @@ -1218,7 +1222,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return emptyArray; } - getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean) { + getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean): NormalizedPath[] { if (!this.program) { return []; } @@ -1256,14 +1260,14 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - getFileNamesWithRedirectInfo(includeProjectReferenceRedirectInfo: boolean) { + getFileNamesWithRedirectInfo(includeProjectReferenceRedirectInfo: boolean): protocol.FileWithProjectReferenceRedirectInfo[] { return this.getFileNames().map((fileName): protocol.FileWithProjectReferenceRedirectInfo => ({ fileName, isSourceOfProjectReferenceRedirect: includeProjectReferenceRedirectInfo && this.isSourceOfProjectReferenceRedirect(fileName), })); } - hasConfigFile(configFilePath: NormalizedPath) { + hasConfigFile(configFilePath: NormalizedPath): boolean { if (this.program && this.languageServiceEnabled) { const configFile = this.program.getCompilerOptions().configFile; if (configFile) { @@ -1297,12 +1301,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return false; } - isRoot(info: ScriptInfo) { + isRoot(info: ScriptInfo): boolean { return this.rootFilesMap?.get(info.path)?.info === info; } // add a root file to project - addRoot(info: ScriptInfo, fileName?: NormalizedPath) { + addRoot(info: ScriptInfo, fileName?: NormalizedPath): void { Debug.assert(!this.isRoot(info)); this.rootFilesMap.set(info.path, { fileName: fileName || info.fileName, info }); info.attachToProject(this); @@ -1311,13 +1315,13 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } // add a root file that doesnt exist on host - addMissingFileRoot(fileName: NormalizedPath) { + addMissingFileRoot(fileName: NormalizedPath): void { const path = this.projectService.toPath(fileName); this.rootFilesMap.set(path, { fileName }); this.markAsDirty(); } - removeFile(info: ScriptInfo, fileExists: boolean, detachFromProject: boolean) { + removeFile(info: ScriptInfo, fileExists: boolean, detachFromProject: boolean): void { if (this.isRoot(info)) { this.removeRoot(info); } @@ -1337,12 +1341,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo this.markAsDirty(); } - registerFileUpdate(fileName: string) { + registerFileUpdate(fileName: string): void { (this.updatedFileNames || (this.updatedFileNames = new Set())).add(fileName); } /** @internal */ - markFileAsDirty(changedFile: Path) { + markFileAsDirty(changedFile: Path): void { this.markAsDirty(); if (this.exportMapCache && !this.exportMapCache.isEmpty()) { (this.changedFilesForExportMapCache ||= new Set()).add(changedFile); @@ -1350,7 +1354,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - markAsDirty() { + markAsDirty(): void { if (!this.dirty) { this.projectStateVersion++; this.dirty = true; @@ -1358,24 +1362,24 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - markAutoImportProviderAsDirty() { + markAutoImportProviderAsDirty(): void { if (!this.autoImportProviderHost) this.autoImportProviderHost = undefined; this.autoImportProviderHost?.markAsDirty(); } /** @internal */ - onAutoImportProviderSettingsChanged() { + onAutoImportProviderSettingsChanged(): void { this.markAutoImportProviderAsDirty(); } /** @internal */ - onPackageJsonChange() { + onPackageJsonChange(): void { this.moduleSpecifierCache.clear(); this.markAutoImportProviderAsDirty(); } /** @internal */ - onFileAddedOrRemoved(isSymlink: boolean | undefined) { + onFileAddedOrRemoved(isSymlink: boolean | undefined): void { this.hasAddedorRemovedFiles = true; if (isSymlink) { this.hasAddedOrRemovedSymlinks = true; @@ -1383,7 +1387,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - onDiscoveredSymlink() { + onDiscoveredSymlink(): void { this.hasAddedOrRemovedSymlinks = true; } @@ -1393,7 +1397,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo _oldOptions: CompilerOptions, hasSourceFileByPath: boolean, newSourceFileByResolvedPath: SourceFile | undefined, - ) { + ): void { if ( !newSourceFileByResolvedPath || (oldSourceFile.resolvedPath === oldSourceFile.path && newSourceFileByResolvedPath.resolvedPath !== oldSourceFile.path) @@ -1409,7 +1413,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo updateFromProjectInProgress = false; /** @internal */ - updateFromProject() { + updateFromProject(): void { updateProjectIfDirty(this); } @@ -1468,7 +1472,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - enqueueInstallTypingsForProject(forceRefresh: boolean) { + enqueueInstallTypingsForProject(forceRefresh: boolean): void { const typeAcquisition = this.getTypeAcquisition(); if (!typeAcquisition || !typeAcquisition.enable || this.projectService.typingsInstaller === nullTypingsInstaller) { @@ -1496,7 +1500,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - updateTypingFiles(compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, newTypings: string[]) { + updateTypingFiles(compilerOptions: CompilerOptions, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray, newTypings: string[]): void { this.typingsCache = { compilerOptions, typeAcquisition, @@ -1523,7 +1527,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - watchTypingLocations(files: readonly string[] | undefined) { + watchTypingLocations(files: readonly string[] | undefined): void { if (!files) { this.typingWatchers!.isInvoked = false; return; @@ -1789,7 +1793,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - sendPerformanceEvent(kind: PerformanceEvent["kind"], durationMs: number) { + sendPerformanceEvent(kind: PerformanceEvent["kind"], durationMs: number): void { this.projectService.sendPerformanceEvent(kind, durationMs); } @@ -1837,7 +1841,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - addGeneratedFileWatch(generatedFile: string, sourceFile: string) { + addGeneratedFileWatch(generatedFile: string, sourceFile: string): void { if (this.compilerOptions.outFile) { // Single watcher if (!this.generatedFilesMap) { @@ -1902,11 +1906,11 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return scriptInfo; } - getScriptInfo(uncheckedFileName: string) { + getScriptInfo(uncheckedFileName: string): ScriptInfo | undefined { return this.projectService.getScriptInfo(uncheckedFileName); } - filesToString(writeProjectFileNames: boolean) { + filesToString(writeProjectFileNames: boolean): string { return this.filesToStringWorker(writeProjectFileNames, /*writeFileExplaination*/ true, /*writeFileVersionAndText*/ false); } @@ -1928,7 +1932,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - print(writeProjectFileNames: boolean, writeFileExplaination: boolean, writeFileVersionAndText: boolean) { + print(writeProjectFileNames: boolean, writeFileExplaination: boolean, writeFileVersionAndText: boolean): void { this.writeLog(`Project '${this.projectName}' (${ProjectKind[this.projectKind]})`); this.writeLog(this.filesToStringWorker( writeProjectFileNames && this.projectService.logger.hasLevel(LogLevel.verbose), @@ -1942,7 +1946,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo this.noDtsResolutionProject?.print(/*writeProjectFileNames*/ false, /*writeFileExplaination*/ false, /*writeFileVersionAndText*/ false); } - setCompilerOptions(compilerOptions: CompilerOptions) { + setCompilerOptions(compilerOptions: CompilerOptions): void { if (compilerOptions) { compilerOptions.allowNonTsExtensions = true; const oldOptions = this.compilerOptions; @@ -1961,7 +1965,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - setWatchOptions(watchOptions: WatchOptions | undefined) { + setWatchOptions(watchOptions: WatchOptions | undefined): void { this.watchOptions = watchOptions; } @@ -1976,7 +1980,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } } - getTypeAcquisition() { + getTypeAcquisition(): TypeAcquisition { return this.typeAcquisition || {}; } @@ -2023,8 +2027,8 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo info => info.isSourceOfProjectReferenceRedirect, ); - const added: Map = new Map(); - const removed: Map = new Map(); + const added: Map = new Map(); + const removed: Map = new Map(); const updated: string[] = updatedFileNames ? arrayFrom(updatedFileNames.keys()) : []; const updatedRedirects: protocol.FileWithProjectReferenceRedirectInfo[] = []; @@ -2091,12 +2095,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - isSourceOfProjectReferenceRedirect(fileName: string) { + isSourceOfProjectReferenceRedirect(fileName: string): boolean { return !!this.program && this.program.isSourceOfProjectReferenceRedirect(fileName); } /** @internal */ - protected getGlobalPluginSearchPaths() { + protected getGlobalPluginSearchPaths(): string[] { // Search any globally-specified probe paths, then our peer node_modules return [ ...this.projectService.pluginProbeLocations, @@ -2135,7 +2139,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport) { + enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport): void { try { if (typeof pluginModuleFactory !== "function") { this.projectService.logger.info(`Skipped loading plugin ${configEntry.name} because it did not expose a proper factory function`); @@ -2170,7 +2174,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - onPluginConfigurationChanged(pluginName: string, configuration: any) { + onPluginConfigurationChanged(pluginName: string, configuration: any): void { this.plugins.filter(plugin => plugin.name === pluginName).forEach(plugin => { if (plugin.module.onConfigurationChanged) { plugin.module.onConfigurationChanged(configuration); @@ -2179,7 +2183,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** Starts a new check for diagnostics. Call this if some file has updated that would cause diagnostics to be changed. */ - refreshDiagnostics() { + refreshDiagnostics(): void { this.projectService.sendProjectsUpdatedInBackgroundEvent(); } @@ -2200,22 +2204,22 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - getPackageJsonCache() { + getPackageJsonCache(): PackageJsonCache { return this.projectService.packageJsonCache; } /** @internal */ - getCachedExportInfoMap() { + getCachedExportInfoMap(): ExportInfoMap { return this.exportMapCache ||= createCacheableExportInfoMap(this); } /** @internal */ - clearCachedExportInfoMap() { + clearCachedExportInfoMap(): void { this.exportMapCache?.clear(); } /** @internal */ - getModuleSpecifierCache() { + getModuleSpecifierCache(): ModuleSpecifierCache { return this.moduleSpecifierCache; } @@ -2296,12 +2300,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - watchNodeModulesForPackageJsonChanges(directoryPath: string) { + watchNodeModulesForPackageJsonChanges(directoryPath: string): FileWatcher { return this.projectService.watchPackageJsonsInNodeModules(directoryPath, this); } /** @internal */ - getIncompleteCompletionsCache() { + getIncompleteCompletionsCache(): IncompleteCompletionsCache { return this.projectService.getIncompleteCompletionsCache(); } @@ -2320,7 +2324,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - runWithTemporaryFileUpdate(rootFile: string, updatedText: string, cb: (updatedProgram: Program, originalProgram: Program | undefined, updatedFile: SourceFile) => void) { + runWithTemporaryFileUpdate(rootFile: string, updatedText: string, cb: (updatedProgram: Program, originalProgram: Program | undefined, updatedFile: SourceFile) => void): void { const originalProgram = this.program; const rootSourceFile = Debug.checkDefined(this.program?.getSourceFile(rootFile), "Expected file to be part of program"); const originalText = Debug.checkDefined(rootSourceFile.getFullText()); @@ -2336,7 +2340,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - getCompilerOptionsForNoDtsResolutionProject() { + getCompilerOptionsForNoDtsResolutionProject(): CompilerOptions { return { ...this.getCompilerOptions(), noDtsResolution: true, @@ -2395,14 +2399,14 @@ function extractUnresolvedImportsFromSourceFile( export class InferredProject extends Project { private _isJsInferredProject = false; - toggleJsInferredProject(isJsInferredProject: boolean) { + toggleJsInferredProject(isJsInferredProject: boolean): void { if (isJsInferredProject !== this._isJsInferredProject) { this._isJsInferredProject = isJsInferredProject; this.setCompilerOptions(); } } - override setCompilerOptions(options?: CompilerOptions) { + override setCompilerOptions(options?: CompilerOptions): void { // Avoid manipulating the given options directly if (!options && !this.getCompilationSettings()) { return; @@ -2457,7 +2461,7 @@ export class InferredProject extends Project { this.enableGlobalPlugins(this.getCompilerOptions()); } - override addRoot(info: ScriptInfo) { + override addRoot(info: ScriptInfo): void { Debug.assert(info.isScriptOpen()); this.projectService.startWatchingConfigFilesForInferredProjectRoot(info); if (!this._isJsInferredProject && info.isJavaScript()) { @@ -2469,7 +2473,7 @@ export class InferredProject extends Project { super.addRoot(info); } - override removeRoot(info: ScriptInfo) { + override removeRoot(info: ScriptInfo): void { this.projectService.stopWatchingConfigFilesForScriptInfo(info); super.removeRoot(info); // Delay toggling to isJsInferredProject = false till we actually need it again @@ -2481,11 +2485,11 @@ export class InferredProject extends Project { } /** @internal */ - override isOrphan() { + override isOrphan(): boolean { return !this.hasRoots(); } - isProjectWithSingleRoot() { + isProjectWithSingleRoot(): boolean { // - when useSingleInferredProject is not set and projectRootPath is not set, // we can guarantee that this will be the only root // - other wise it has single root if it has single root script info @@ -2493,7 +2497,7 @@ export class InferredProject extends Project { this.getRootScriptInfos().length === 1; } - override close() { + override close(): void { forEach(this.getRootScriptInfos(), info => this.projectService.stopWatchingConfigFilesForScriptInfo(info)); super.close(); } @@ -2764,7 +2768,7 @@ export class AutoImportProviderProject extends Project { } /** @internal */ - isEmpty() { + isEmpty(): boolean { return !some(this.rootFileNames); } @@ -2773,7 +2777,7 @@ export class AutoImportProviderProject extends Project { return true; } - override updateGraph() { + override updateGraph(): boolean { let rootFileNames = this.rootFileNames; if (!rootFileNames) { rootFileNames = AutoImportProviderProject.getRootFileNames( @@ -2800,17 +2804,17 @@ export class AutoImportProviderProject extends Project { return; } - override hasRoots() { + override hasRoots(): boolean { return !!this.rootFileNames?.length; } /** @internal */ - override markAsDirty() { + override markAsDirty(): void { this.rootFileNames = undefined; super.markAsDirty(); } - override getScriptFileNames() { + override getScriptFileNames(): string[] { return this.rootFileNames || ts.emptyArray; } @@ -2832,22 +2836,22 @@ export class AutoImportProviderProject extends Project { throw new Error("AutoImportProviderProject cannot provide its own host; use `hostProject.getModuleResolutionHostForAutomImportProvider()` instead."); } - override getProjectReferences() { + override getProjectReferences(): readonly ProjectReference[] | undefined { return this.hostProject.getProjectReferences(); } /** @internal */ - override includePackageJsonAutoImports() { + override includePackageJsonAutoImports(): PackageJsonAutoImportPreference { return PackageJsonAutoImportPreference.Off; } /** @internal */ - override getSymlinkCache() { + override getSymlinkCache(): SymlinkCache { return this.hostProject.getSymlinkCache(); } /** @internal */ - override getModuleResolutionCache() { + override getModuleResolutionCache(): ModuleResolutionCache | undefined { return this.hostProject.getCurrentProgram()?.getModuleResolutionCache(); } } @@ -2864,7 +2868,7 @@ export class ConfiguredProject extends Project { pendingUpdateReason: string | undefined; /** @internal */ - openFileWatchTriggered = new Map(); + openFileWatchTriggered: Map = new Map(); /** @internal */ canConfigFileJsonReportNoInputFiles = false; @@ -2923,7 +2927,7 @@ export class ConfiguredProject extends Project { } /** @internal */ - setCompilerHost(host: CompilerHost) { + setCompilerHost(host: CompilerHost): void { this.compilerHost = host; } @@ -2933,12 +2937,12 @@ export class ConfiguredProject extends Project { } /** @internal */ - override useSourceOfProjectReferenceRedirect() { + override useSourceOfProjectReferenceRedirect(): boolean { return this.languageServiceEnabled; } /** @internal */ - override getParsedCommandLine(fileName: string) { + override getParsedCommandLine(fileName: string): ParsedCommandLine | undefined { const configFileName = asNormalizedPath(normalizePath(fileName)); const canonicalConfigFilePath = asNormalizedPath(this.projectService.toCanonicalFileName(configFileName)); // Ensure the config file existience info is cached @@ -2956,7 +2960,7 @@ export class ConfiguredProject extends Project { } /** @internal */ - onReleaseParsedCommandLine(fileName: string) { + onReleaseParsedCommandLine(fileName: string): void { this.releaseParsedConfig(asNormalizedPath(this.projectService.toCanonicalFileName(asNormalizedPath(normalizePath(fileName))))); } @@ -3017,7 +3021,7 @@ export class ConfiguredProject extends Project { return this.directoryStructureHost as CachedDirectoryStructureHost; } - getConfigFilePath() { + getConfigFilePath(): NormalizedPath { return asNormalizedPath(this.getProjectName()); } @@ -3025,13 +3029,13 @@ export class ConfiguredProject extends Project { return this.projectReferences; } - updateReferences(refs: readonly ProjectReference[] | undefined) { + updateReferences(refs: readonly ProjectReference[] | undefined): void { this.projectReferences = refs; this.potentialProjectReferences = undefined; } /** @internal */ - setPotentialProjectReference(canonicalConfigPath: NormalizedPath) { + setPotentialProjectReference(canonicalConfigPath: NormalizedPath): void { Debug.assert(this.isInitialLoadPending()); (this.potentialProjectReferences || (this.potentialProjectReferences = new Set())).add(canonicalConfigPath); } @@ -3090,11 +3094,11 @@ export class ConfiguredProject extends Project { return this.projectErrors || emptyArray; } - override setProjectErrors(projectErrors: Diagnostic[]) { + override setProjectErrors(projectErrors: Diagnostic[]): void { this.projectErrors = projectErrors; } - override close() { + override close(): void { this.projectService.configFileExistenceInfoCache.forEach((_configFileExistenceInfo, canonicalConfigFilePath) => this.releaseParsedConfig(canonicalConfigFilePath)); this.projectErrors = undefined; this.openFileWatchTriggered.clear(); @@ -3103,13 +3107,13 @@ export class ConfiguredProject extends Project { } /** @internal */ - override markAsDirty() { + override markAsDirty(): void { if (this.deferredClose) return; super.markAsDirty(); } /** @internal */ - isSolution() { + isSolution(): boolean { return this.getRootFilesMap().size === 0 && !this.canConfigFileJsonReportNoInputFiles; } @@ -3119,12 +3123,12 @@ export class ConfiguredProject extends Project { return !!this.deferredClose; } - getEffectiveTypeRoots() { + getEffectiveTypeRoots(): string[] { return getEffectiveTypeRoots(this.getCompilationSettings(), this) || []; } /** @internal */ - updateErrorOnNoInputFiles(fileNames: string[]) { + updateErrorOnNoInputFiles(fileNames: string[]): void { updateErrorForNoInputFiles(fileNames, this.getConfigFilePath(), this.getCompilerOptions().configFile!.configFileSpecs!, this.projectErrors!, this.canConfigFileJsonReportNoInputFiles); } } @@ -3160,13 +3164,13 @@ export class ExternalProject extends Project { this.enableGlobalPlugins(this.getCompilerOptions()); } - override updateGraph() { + override updateGraph(): boolean { const result = super.updateGraph(); this.projectService.sendProjectTelemetry(this); return result; } - override getExcludedFiles() { + override getExcludedFiles(): readonly NormalizedPath[] { return this.excludedFiles; } } diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index c974871f4d20c..afadbe12d50b7 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -100,13 +100,13 @@ export class TextStorage { this.version = initialVersion || 0; } - public getVersion() { + public getVersion(): string { return this.svc ? `SVC-${this.version}-${this.svc.getSnapshotVersion()}` : `Text-${this.version}`; } - public hasScriptVersionCache_TestOnly() { + public hasScriptVersionCache_TestOnly(): boolean { return this.svc !== undefined; } @@ -120,7 +120,7 @@ export class TextStorage { } /** Public for testing */ - public useText(newText: string) { + public useText(newText: string): void { this.svc = undefined; this.text = newText; this.textSnapshot = undefined; @@ -130,7 +130,7 @@ export class TextStorage { this.version++; } - public edit(start: number, end: number, newText: string) { + public edit(start: number, end: number, newText: string): void { this.switchToScriptVersionCache().edit(start, end - start, newText); this.ownFileText = false; this.text = undefined; @@ -174,7 +174,7 @@ export class TextStorage { * Reads the contents from tempFile(if supplied) or own file and sets it as contents * returns true if text changed */ - public reloadWithFileText(tempFileName?: string) { + public reloadWithFileText(tempFileName?: string): boolean { const { text: newText, fileSize } = tempFileName || !this.info.isDynamicOrHasMixedContent() ? this.getFileTextAndSize(tempFileName) : { text: "", fileSize: undefined }; @@ -196,13 +196,13 @@ export class TextStorage { * Schedule reload from the disk if its not already scheduled and its not own text * returns true when scheduling reload */ - public scheduleReloadIfNeeded() { + public scheduleReloadIfNeeded(): boolean { return !this.pendingReloadFromDisk && !this.ownFileText ? this.pendingReloadFromDisk = true : false; } - public delayReloadFromFileIntoText() { + public delayReloadFromFileIntoText(): void { this.pendingReloadFromDisk = true; } @@ -345,7 +345,7 @@ export class TextStorage { } } -export function isDynamicFileName(fileName: NormalizedPath) { +export function isDynamicFileName(fileName: NormalizedPath): boolean { return fileName[0] === "^" || ((fileName.includes("walkThroughSnippet:/") || fileName.includes("untitled:/")) && getBaseFileName(fileName)[0] === "^") || @@ -428,15 +428,15 @@ export class ScriptInfo { } /** @internal */ - public isDynamicOrHasMixedContent() { + public isDynamicOrHasMixedContent(): boolean { return this.hasMixedContent || this.isDynamic; } - public isScriptOpen() { + public isScriptOpen(): boolean { return this.textStorage.isOpen; } - public open(newText: string | undefined) { + public open(newText: string | undefined): void { this.textStorage.isOpen = true; if ( newText !== undefined && @@ -447,14 +447,14 @@ export class ScriptInfo { } } - public close(fileExists = true) { + public close(fileExists = true): void { this.textStorage.isOpen = false; if (fileExists && this.textStorage.scheduleReloadIfNeeded()) { this.markContainingProjectsAsDirty(); } } - public getSnapshot() { + public getSnapshot(): IScriptSnapshot { return this.textStorage.getSnapshot(); } @@ -510,7 +510,7 @@ export class ScriptInfo { return isNew; } - isAttached(project: Project) { + isAttached(project: Project): boolean { // unrolled for common cases switch (this.containingProjects.length) { case 0: @@ -524,7 +524,7 @@ export class ScriptInfo { } } - detachFromProject(project: Project) { + detachFromProject(project: Project): void { // unrolled for common cases switch (this.containingProjects.length) { case 0: @@ -554,7 +554,7 @@ export class ScriptInfo { } } - detachAllProjects() { + detachAllProjects(): void { for (const p of this.containingProjects) { if (isConfiguredProject(p)) { p.getCachedDirectoryStructureHost().addOrDeleteFile(this.fileName, this.path, FileWatcherEventKind.Deleted); @@ -572,7 +572,7 @@ export class ScriptInfo { clear(this.containingProjects); } - getDefaultProject() { + getDefaultProject(): Project { switch (this.containingProjects.length) { case 0: return Errors.ThrowNoProject(); @@ -654,18 +654,18 @@ export class ScriptInfo { return this.textStorage.getVersion(); } - saveTo(fileName: string) { + saveTo(fileName: string): void { this.host.writeFile(fileName, getSnapshotText(this.textStorage.getSnapshot())); } /** @internal */ - delayReloadNonMixedContentFile() { + delayReloadNonMixedContentFile(): void { Debug.assert(!this.isDynamicOrHasMixedContent()); this.textStorage.delayReloadFromFileIntoText(); this.markContainingProjectsAsDirty(); } - reloadFromFile(tempFileName?: NormalizedPath) { + reloadFromFile(tempFileName?: NormalizedPath): boolean { if (this.textStorage.reloadWithFileText(tempFileName)) { this.markContainingProjectsAsDirty(); return true; @@ -678,18 +678,18 @@ export class ScriptInfo { this.markContainingProjectsAsDirty(); } - markContainingProjectsAsDirty() { + markContainingProjectsAsDirty(): void { for (const p of this.containingProjects) { p.markFileAsDirty(this.path); } } - isOrphan() { + isOrphan(): boolean { return this.deferredDelete || !forEach(this.containingProjects, p => !p.isOrphan()); } /** @internal */ - isContainedByBackgroundProject() { + isContainedByBackgroundProject(): boolean { return some( this.containingProjects, isBackgroundProject, @@ -699,7 +699,7 @@ export class ScriptInfo { /** * @param line 1 based index */ - lineToTextSpan(line: number) { + lineToTextSpan(line: number): TextSpan { return this.textStorage.lineToTextSpan(line); } @@ -721,12 +721,12 @@ export class ScriptInfo { return location; } - public isJavaScript() { + public isJavaScript(): boolean { return this.scriptKind === ScriptKind.JS || this.scriptKind === ScriptKind.JSX; } /** @internal */ - closeSourceMapFileWatcher() { + closeSourceMapFileWatcher(): void { if (this.sourceMapFilePath && !isString(this.sourceMapFilePath)) { closeFileWatcherOf(this.sourceMapFilePath); this.sourceMapFilePath = undefined; diff --git a/src/server/scriptVersionCache.ts b/src/server/scriptVersionCache.ts index 306e310f23ee3..55a957928a1ae 100644 --- a/src/server/scriptVersionCache.ts +++ b/src/server/scriptVersionCache.ts @@ -287,7 +287,7 @@ export class ScriptVersionCache { } // REVIEW: can optimize by coalescing simple edits - edit(pos: number, deleteLen: number, insertedText?: string) { + edit(pos: number, deleteLen: number, insertedText?: string): void { this.changes.push(new TextChange(pos, deleteLen, insertedText)); if ( this.changes.length > ScriptVersionCache.changeNumberThreshold || @@ -345,7 +345,7 @@ export class ScriptVersionCache { return createTextSpan(absolutePosition, len); } - getTextChangesBetweenVersions(oldVersion: number, newVersion: number) { + getTextChangesBetweenVersions(oldVersion: number, newVersion: number): TextChangeRange | undefined { if (oldVersion < newVersion) { if (oldVersion >= this.minVersion) { const textChangeRanges: TextChangeRange[] = []; @@ -366,11 +366,11 @@ export class ScriptVersionCache { } } - getLineCount() { + getLineCount(): number { return this._getSnapshot().index.getLineCount(); } - static fromString(script: string) { + static fromString(script: string): ScriptVersionCache { const svc = new ScriptVersionCache(); const snap = new LineIndexSnapshot(0, svc, new LineIndex()); svc.versions[svc.currentVersion] = snap; @@ -423,7 +423,7 @@ export class LineIndex { return this.root.charOffsetToLineInfo(1, position); } - getLineCount() { + getLineCount(): number { return this.root.lineCount(); } @@ -438,7 +438,7 @@ export class LineIndex { } } - load(lines: string[]) { + load(lines: string[]): void { if (lines.length > 0) { const leaves: LineLeaf[] = []; for (let i = 0; i < lines.length; i++) { @@ -451,11 +451,11 @@ export class LineIndex { } } - walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) { + walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker): void { this.root.walk(rangeStart, rangeLength, walkFns); } - getText(rangeStart: number, rangeLength: number) { + getText(rangeStart: number, rangeLength: number): string { let accum = ""; if ((rangeLength > 0) && (rangeStart < this.root.charCount())) { this.walk(rangeStart, rangeLength, { @@ -473,7 +473,7 @@ export class LineIndex { return this.root.charCount(); } - every(f: (ll: LineLeaf, s: number, len: number) => boolean, rangeStart: number, rangeEnd?: number) { + every(f: (ll: LineLeaf, s: number, len: number) => boolean, rangeStart: number, rangeEnd?: number): boolean { if (!rangeEnd) { rangeEnd = this.root.charCount(); } @@ -559,7 +559,10 @@ export class LineIndex { return this.buildTreeFromBottom(interiorNodes); } - static linesFromText(text: string) { + static linesFromText(text: string): { + lines: string[]; + lineMap: number[]; + } { const lineMap = computeLineStarts(text); if (lineMap.length === 0) { @@ -595,7 +598,7 @@ export class LineNode implements LineCollection { return false; } - updateCounts() { + updateCounts(): void { this.totalChars = 0; this.totalLines = 0; for (const child of this.children) { @@ -627,7 +630,7 @@ export class LineNode implements LineCollection { } } - walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) { + walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker): void { // assume (rangeStart < this.totalChars) && (rangeLength <= this.totalChars) let childIndex = 0; let childCharCount = this.children[childIndex].charCount(); @@ -748,7 +751,7 @@ export class LineNode implements LineCollection { return splitNode; } - remove(child: LineCollection) { + remove(child: LineCollection): void { const childIndex = this.findChildIndex(child); const clen = this.children.length; if (childIndex < (clen - 1)) { @@ -765,7 +768,7 @@ export class LineNode implements LineCollection { return childIndex; } - insertAt(child: LineCollection, nodes: LineCollection[]) { + insertAt(child: LineCollection, nodes: LineCollection[]): LineNode[] { let childIndex = this.findChildIndex(child); const clen = this.children.length; const nodeCount = nodes.length; @@ -825,11 +828,11 @@ export class LineNode implements LineCollection { Debug.assert(this.children.length <= lineCollectionCapacity); } - charCount() { + charCount(): number { return this.totalChars; } - lineCount() { + lineCount(): number { return this.totalLines; } } @@ -843,11 +846,11 @@ export class LineLeaf implements LineCollection { return true; } - walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker) { + walk(rangeStart: number, rangeLength: number, walkFns: LineIndexWalker): void { walkFns.leaf(rangeStart, rangeLength, this); } - charCount() { + charCount(): number { return this.text.length; } diff --git a/src/server/session.ts b/src/server/session.ts index fd0ed26586dc7..c34a18a56011d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -316,7 +316,7 @@ function allEditsBeforePos(edits: readonly TextChange[], pos: number): boolean { /** @deprecated use ts.server.protocol.CommandTypes */ export type CommandNames = protocol.CommandTypes; /** @deprecated use ts.server.protocol.CommandTypes */ -export const CommandNames = (protocol as any).CommandTypes; +export const CommandNames: any = (protocol as any).CommandTypes; export function formatMessage(msg: T, logger: Logger, byteLength: (s: string, encoding: BufferEncoding) => number, newLine: string): string { const verboseLogging = logger.hasLevel(LogLevel.verbose); @@ -1227,7 +1227,7 @@ export class Session implements EventSender { this.logger.msg(msg, Msg.Err); } - public send(msg: protocol.Message) { + public send(msg: protocol.Message): void { if (msg.type === "event" && !this.canUseEvents) { if (this.logger.hasLevel(LogLevel.verbose)) { this.logger.info(`Session does not support events: ignored event: ${stringifyIndented(msg)}`); @@ -1237,7 +1237,7 @@ export class Session implements EventSender { this.writeMessage(msg); } - protected writeMessage(msg: protocol.Message) { + protected writeMessage(msg: protocol.Message): void { const msgText = formatMessage(msg, this.logger, this.byteLength, this.host.newLine); this.host.write(msgText); } @@ -3289,12 +3289,12 @@ export class Session implements EventSender { return outgoingCalls.map(call => this.toProtocolCallHierarchyOutgoingCall(call, scriptInfo)); } - getCanonicalFileName(fileName: string) { + getCanonicalFileName(fileName: string): string { const name = this.host.useCaseSensitiveFileNames ? fileName : toFileNameLowerCase(fileName); return normalizePath(name); } - exit() {/*overridden*/} + exit(): void {/*overridden*/} private notRequired(request: protocol.Request | undefined): HandlerResponse { if (request) this.doOutput(/*info*/ undefined, request.command, request.seq, /*success*/ true, this.performanceData); @@ -3710,7 +3710,7 @@ export class Session implements EventSender { }, })); - public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse) { + public addProtocolHandler(command: string, handler: (request: protocol.Request) => HandlerResponse): void { if (this.handlers.has(command)) { throw new Error(`Protocol handler already exists for command "${command}"`); } @@ -3759,7 +3759,7 @@ export class Session implements EventSender { } } - public onMessage(message: TMessage) { + public onMessage(message: TMessage): void { this.gcTimer.scheduleCollect(); let start: [number, number] | undefined; const currentPerformanceData = this.performanceData; diff --git a/src/server/typingInstallerAdapter.ts b/src/server/typingInstallerAdapter.ts index 5f8e90b7f837d..f92b6bf2a8405 100644 --- a/src/server/typingInstallerAdapter.ts +++ b/src/server/typingInstallerAdapter.ts @@ -104,7 +104,7 @@ export abstract class TypingsInstallerAdapter implements ITypingsInstaller { return promise; } - attach(projectService: ProjectService) { + attach(projectService: ProjectService): void { this.projectService = projectService; this.installer = this.createInstallerProcess(); } @@ -131,7 +131,7 @@ export abstract class TypingsInstallerAdapter implements ITypingsInstaller { } } - handleMessage(response: TypesRegistryResponse | PackageInstalledResponse | SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse | server.WatchTypingLocations) { + handleMessage(response: TypesRegistryResponse | PackageInstalledResponse | SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes | InitializationFailedResponse | server.WatchTypingLocations): void { if (this.logger.hasLevel(LogLevel.verbose)) { this.logger.info(`TIAdapter:: Received response:${stringifyIndented(response)}`); } @@ -234,7 +234,7 @@ export abstract class TypingsInstallerAdapter implements ITypingsInstaller { } } - scheduleRequest(request: DiscoverTypings) { + scheduleRequest(request: DiscoverTypings): void { if (this.logger.hasLevel(LogLevel.verbose)) { this.logger.info(`TIAdapter:: Scheduling request for: ${request.projectName}`); } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 5ea8cd876f3e7..5466d4c448d28 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -20,7 +20,7 @@ export class ThrottledOperations { * of the new one. (Note that the amount of time the canceled operation had been * waiting does not affect the amount of time that the new operation waits.) */ - public schedule(operationId: string, delay: number, cb: () => void) { + public schedule(operationId: string, delay: number, cb: () => void): void { const pendingTimeout = this.pendingTimeouts.get(operationId); if (pendingTimeout) { // another operation was already scheduled for this id - cancel it @@ -33,7 +33,7 @@ export class ThrottledOperations { } } - public cancel(operationId: string) { + public cancel(operationId: string): boolean { const pendingTimeout = this.pendingTimeouts.get(operationId); if (!pendingTimeout) return false; this.host.clearTimeout(pendingTimeout); @@ -55,7 +55,7 @@ export class GcTimer { constructor(private readonly host: ServerHost, private readonly delay: number, private readonly logger: Logger) { } - public scheduleCollect() { + public scheduleCollect(): void { if (!this.host.gc || this.timerId !== undefined) { // no global.gc or collection was already scheduled - skip this request return; diff --git a/src/server/utilitiesPublic.ts b/src/server/utilitiesPublic.ts index c0ce5dfea1295..2476292715de0 100644 --- a/src/server/utilitiesPublic.ts +++ b/src/server/utilitiesPublic.ts @@ -117,7 +117,7 @@ export interface ProjectOptions { configHasExcludeProperty: boolean; } -export function isInferredProjectName(name: string) { +export function isInferredProjectName(name: string): boolean { // POSIX defines /dev/null as a device - there should be no file with this prefix return /dev\/null\/inferredProject\d+\*/.test(name); } diff --git a/src/services/breakpoints.ts b/src/services/breakpoints.ts index 17d20da69ee92..b3e53fed929b5 100644 --- a/src/services/breakpoints.ts +++ b/src/services/breakpoints.ts @@ -77,7 +77,7 @@ import { * * @internal */ -export function spanInSourceFileAtLocation(sourceFile: SourceFile, position: number) { +export function spanInSourceFileAtLocation(sourceFile: SourceFile, position: number): TextSpan | undefined { // Cannot set breakpoint in dts file if (sourceFile.isDeclarationFile) { return undefined; diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts index 686a96dea6c8e..7dbf939b4da05 100644 --- a/src/services/codeFixProvider.ts +++ b/src/services/codeFixProvider.ts @@ -29,7 +29,7 @@ const errorCodeToFixes = createMultiMap(); const fixIdToRegistration = new Map(); /** @internal */ -export function createCodeFixActionWithoutFixAll(fixName: string, changes: FileTextChanges[], description: DiagnosticOrDiagnosticAndArguments) { +export function createCodeFixActionWithoutFixAll(fixName: string, changes: FileTextChanges[], description: DiagnosticOrDiagnosticAndArguments): CodeFixAction { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, /*fixId*/ undefined, /*fixAllDescription*/ undefined); } @@ -39,7 +39,7 @@ export function createCodeFixAction(fixName: string, changes: FileTextChanges[], } /** @internal */ -export function createCodeFixActionMaybeFixAll(fixName: string, changes: FileTextChanges[], description: DiagnosticOrDiagnosticAndArguments, fixId?: {}, fixAllDescription?: DiagnosticOrDiagnosticAndArguments, command?: CodeActionCommand) { +export function createCodeFixActionMaybeFixAll(fixName: string, changes: FileTextChanges[], description: DiagnosticOrDiagnosticAndArguments, fixId?: {}, fixAllDescription?: DiagnosticOrDiagnosticAndArguments, command?: CodeActionCommand): CodeFixAction { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, fixId, fixAllDescription && diagnosticToString(fixAllDescription), command); } @@ -48,7 +48,7 @@ function createCodeFixActionWorker(fixName: string, description: string, changes } /** @internal */ -export function registerCodeFix(reg: CodeFixRegistration) { +export function registerCodeFix(reg: CodeFixRegistration): void { for (const error of reg.errorCodes) { errorCodeToFixesArray = undefined; errorCodeToFixes.add(String(error), reg); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index c5fb66a99bd1d..3040e062dabaa 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -180,7 +180,7 @@ export function addNewNodeForMemberSymbol( importAdder: ImportAdder | undefined, addClassElement: (node: AddNode) => void, body: Block | undefined, - preserveOptional = PreserveOptionalFlags.All, + preserveOptional: PreserveOptionalFlags = PreserveOptionalFlags.All, isAmbient = false, ): void { const declarations = symbol.getDeclarations(); @@ -387,7 +387,7 @@ export function createSignatureDeclarationFromSignature( optional: boolean | undefined, enclosingDeclaration: Node | undefined, importAdder: ImportAdder | undefined, -) { +): FunctionDeclaration | MethodDeclaration | FunctionExpression | ArrowFunction | undefined { const program = context.program; const checker = program.getTypeChecker(); const scriptTarget = getEmitScriptTarget(program.getCompilerOptions()); @@ -850,7 +850,7 @@ export function setJsonCompilerOptionValues( changeTracker: textChanges.ChangeTracker, configFile: TsConfigSourceFile, options: [string, Expression][], -) { +): undefined { const tsconfigObjectLiteral = getTsConfigObjectLiteralExpression(configFile); if (!tsconfigObjectLiteral) return undefined; @@ -889,7 +889,7 @@ export function setJsonCompilerOptionValue( configFile: TsConfigSourceFile, optionName: string, optionValue: Expression, -) { +): void { setJsonCompilerOptionValues(changeTracker, configFile, [[optionName, optionValue]]); } @@ -908,7 +908,10 @@ function findJsonProperty(obj: ObjectLiteralExpression, name: string): PropertyA * * @internal */ -export function tryGetAutoImportableReferenceFromTypeNode(importTypeNode: TypeNode | undefined, scriptTarget: ScriptTarget) { +export function tryGetAutoImportableReferenceFromTypeNode(importTypeNode: TypeNode | undefined, scriptTarget: ScriptTarget): { + typeNode: TypeNode; + symbols: Symbol[]; +} | undefined { let symbols: Symbol[] | undefined; const typeNode = visitNode(importTypeNode, visit, isTypeNode); if (symbols && typeNode) { @@ -946,7 +949,7 @@ function replaceFirstIdentifierOfEntityName(name: EntityName, newIdentifier: Ide } /** @internal */ -export function importSymbols(importAdder: ImportAdder, symbols: readonly Symbol[]) { +export function importSymbols(importAdder: ImportAdder, symbols: readonly Symbol[]): void { symbols.forEach(s => importAdder.addImportFromExportedSymbol(s, /*isValidTypeOnlyUseSite*/ true)); } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index ad7f7c63022ff..d19746cba7826 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -857,7 +857,7 @@ export function getImportCompletionAction( } /** @internal */ -export function getPromoteTypeOnlyCompletionAction(sourceFile: SourceFile, symbolToken: Identifier, program: Program, host: LanguageServiceHost, formatContext: formatting.FormatContext, preferences: UserPreferences) { +export function getPromoteTypeOnlyCompletionAction(sourceFile: SourceFile, symbolToken: Identifier, program: Program, host: LanguageServiceHost, formatContext: formatting.FormatContext, preferences: UserPreferences): CodeAction | undefined { const compilerOptions = program.getCompilerOptions(); const symbolName = single(getSymbolNamesToImport(sourceFile, program.getTypeChecker(), symbolToken, compilerOptions)); const fix = getTypeOnlyPromotionFix(sourceFile, symbolToken, symbolName, program); diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index 62040ab30982b..1bfa8ab018580 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -458,7 +458,7 @@ export function forEachExternalModuleToImportFrom( preferences: UserPreferences, useAutoImportProvider: boolean, cb: (module: Symbol, moduleFile: SourceFile | undefined, program: Program, isFromPackageJson: boolean) => void, -) { +): void { const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host); const excludePatterns = preferences.autoImportFileExcludePatterns && getIsExcludedPatterns(preferences, useCaseSensitiveFileNames); @@ -527,7 +527,7 @@ function getIsExcluded(excludePatterns: readonly RegExp[], host: LanguageService } /** @internal */ -export function getIsFileExcluded(host: LanguageServiceHost, preferences: UserPreferences) { +export function getIsFileExcluded(host: LanguageServiceHost, preferences: UserPreferences): (sourceFile: SourceFile) => boolean { if (!preferences.autoImportFileExcludePatterns) return () => false; return getIsExcluded(getIsExcludedPatterns(preferences, hostUsesCaseSensitiveFileNames(host)), host); } @@ -599,7 +599,10 @@ export function getExportInfoMap(importingFile: SourceFile | FutureSourceFile, h } /** @internal */ -export function getDefaultLikeExportInfo(moduleSymbol: Symbol, checker: TypeChecker) { +export function getDefaultLikeExportInfo(moduleSymbol: Symbol, checker: TypeChecker): { + symbol: Symbol; + exportKind: ExportKind; +} | undefined { const exportEquals = checker.resolveExternalModuleSymbol(moduleSymbol); if (exportEquals !== moduleSymbol) return { symbol: exportEquals, exportKind: ExportKind.ExportEquals }; const defaultExport = checker.tryGetMemberInModuleExports(InternalSymbolName.Default, moduleSymbol); diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 6e11dac1419fd..74aeb9c5be05c 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -1051,7 +1051,7 @@ export namespace Core { return mergeReferences(program, moduleReferences, references, moduleReferencesOfExportTarget); } - export function getAdjustedNode(node: Node, options: Options) { + export function getAdjustedNode(node: Node, options: Options): Node { if (options.use === FindReferencesUse.References) { node = getAdjustedReferenceLocation(node); } diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 2dc19c021e302..e641b0f2b0434 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -1377,7 +1377,7 @@ export function getRangeOfEnclosingComment( sourceFile: SourceFile, position: number, precedingToken?: Node | null, // eslint-disable-line no-restricted-syntax - tokenAtPosition = getTokenAtPosition(sourceFile, position), + tokenAtPosition: Node = getTokenAtPosition(sourceFile, position), ): CommentRange | undefined { const jsdoc = findAncestor(tokenAtPosition, isJSDoc); if (jsdoc) tokenAtPosition = jsdoc.parent; diff --git a/src/services/formatting/formattingContext.ts b/src/services/formatting/formattingContext.ts index f41b7ee0ca283..ff73e9c578241 100644 --- a/src/services/formatting/formattingContext.ts +++ b/src/services/formatting/formattingContext.ts @@ -35,7 +35,7 @@ export class FormattingContext { constructor(public readonly sourceFile: SourceFileLike, public formattingRequestKind: FormattingRequestKind, public options: FormatCodeSettings) { } - public updateContext(currentRange: TextRangeWithKind, currentTokenParent: Node, nextRange: TextRangeWithKind, nextTokenParent: Node, commonParent: Node) { + public updateContext(currentRange: TextRangeWithKind, currentTokenParent: Node, nextRange: TextRangeWithKind, nextTokenParent: Node, commonParent: Node): void { this.currentTokenSpan = Debug.checkDefined(currentRange); this.currentTokenParent = Debug.checkDefined(currentTokenParent); this.nextTokenSpan = Debug.checkDefined(nextRange); @@ -76,7 +76,7 @@ export class FormattingContext { return this.tokensAreOnSameLine; } - public ContextNodeBlockIsOnOneLine() { + public ContextNodeBlockIsOnOneLine(): boolean { if (this.contextNodeBlockIsOnOneLine === undefined) { this.contextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.contextNode); } @@ -84,7 +84,7 @@ export class FormattingContext { return this.contextNodeBlockIsOnOneLine; } - public NextNodeBlockIsOnOneLine() { + public NextNodeBlockIsOnOneLine(): boolean { if (this.nextNodeBlockIsOnOneLine === undefined) { this.nextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.nextTokenParent); } diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index c2141602f1108..c6ed975a1a516 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -233,7 +233,7 @@ export namespace SmartIndenter { return getIndentationForNodeWorker(n, start, ignoreActualIndentationRange, /*indentationDelta*/ 0, sourceFile, /*isNextChild*/ false, options); } - export function getBaseIndentation(options: EditorSettings) { + export function getBaseIndentation(options: EditorSettings): number { return options.baseIndentSize || 0; } @@ -602,7 +602,10 @@ export namespace SmartIndenter { * value of 'character' for '$' is 3 * value of 'column' for '$' is 6 (assuming that tab size is 4) */ - export function findFirstNonWhitespaceCharacterAndColumn(startPos: number, endPos: number, sourceFile: SourceFileLike, options: EditorSettings) { + export function findFirstNonWhitespaceCharacterAndColumn(startPos: number, endPos: number, sourceFile: SourceFileLike, options: EditorSettings): { + column: number; + character: number; + } { let character = 0; let column = 0; for (let pos = startPos; pos < endPos; pos++) { diff --git a/src/services/jsDoc.ts b/src/services/jsDoc.ts index cbefd89bf8403..0f8cb859d6822 100644 --- a/src/services/jsDoc.ts +++ b/src/services/jsDoc.ts @@ -383,7 +383,7 @@ export function getJSDocTagNameCompletions(): CompletionEntry[] { } /** @internal */ -export const getJSDocTagNameCompletionDetails = getJSDocTagCompletionDetails; +export const getJSDocTagNameCompletionDetails: typeof getJSDocTagCompletionDetails = getJSDocTagCompletionDetails; /** @internal */ export function getJSDocTagCompletions(): CompletionEntry[] { diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index e7cc236947c84..1508ba7672d5e 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -914,19 +914,19 @@ export function getNamedImportSpecifierComparerWithDetection(importDecl: ImportD } /** @internal */ -export function getImportDeclarationInsertionIndex(sortedImports: readonly AnyImportOrRequireStatement[], newImport: AnyImportOrRequireStatement, comparer: Comparer) { +export function getImportDeclarationInsertionIndex(sortedImports: readonly AnyImportOrRequireStatement[], newImport: AnyImportOrRequireStatement, comparer: Comparer): number { const index = binarySearch(sortedImports, newImport, identity, (a, b) => compareImportsOrRequireStatements(a, b, comparer)); return index < 0 ? ~index : index; } /** @internal */ -export function getImportSpecifierInsertionIndex(sortedImports: readonly ImportSpecifier[], newImport: ImportSpecifier, comparer: Comparer) { +export function getImportSpecifierInsertionIndex(sortedImports: readonly ImportSpecifier[], newImport: ImportSpecifier, comparer: Comparer): number { const index = binarySearch(sortedImports, newImport, identity, comparer); return index < 0 ? ~index : index; } /** @internal */ -export function compareImportsOrRequireStatements(s1: AnyImportOrRequireStatement, s2: AnyImportOrRequireStatement, comparer: Comparer) { +export function compareImportsOrRequireStatements(s1: AnyImportOrRequireStatement, s2: AnyImportOrRequireStatement, comparer: Comparer): Comparison { return compareModuleSpecifiersWorker(getModuleSpecifierExpression(s1), getModuleSpecifierExpression(s2), comparer) || compareImportKind(s1, s2); } @@ -950,7 +950,7 @@ export function testCoalesceImports(importGroup: readonly ImportDeclaration[], i * @deprecated Only used for testing * @internal */ -export function testCoalesceExports(exportGroup: readonly ExportDeclaration[], ignoreCase: boolean, preferences?: UserPreferences) { +export function testCoalesceExports(exportGroup: readonly ExportDeclaration[], ignoreCase: boolean, preferences?: UserPreferences): readonly ExportDeclaration[] { const comparer = (s1: ExportSpecifier, s2: ExportSpecifier) => compareImportOrExportSpecifiers(s1, s2, getOrganizeImportsOrdinalStringComparer(ignoreCase), { organizeImportsTypeOrder: preferences?.organizeImportsTypeOrder ?? "last" }); return coalesceExportsWorker(exportGroup, comparer); } @@ -959,7 +959,7 @@ export function testCoalesceExports(exportGroup: readonly ExportDeclaration[], i * @deprecated Only used for testing * @internal */ -export function compareModuleSpecifiers(m1: Expression | undefined, m2: Expression | undefined, ignoreCase?: boolean) { +export function compareModuleSpecifiers(m1: Expression | undefined, m2: Expression | undefined, ignoreCase?: boolean): Comparison { const comparer = getOrganizeImportsOrdinalStringComparer(!!ignoreCase); return compareModuleSpecifiersWorker(m1, m2, comparer); } diff --git a/src/services/refactorProvider.ts b/src/services/refactorProvider.ts index 1b21149070931..b341d18124404 100644 --- a/src/services/refactorProvider.ts +++ b/src/services/refactorProvider.ts @@ -18,7 +18,7 @@ const refactors = new Map(); * * @internal */ -export function registerRefactor(name: string, refactor: Refactor) { +export function registerRefactor(name: string, refactor: Refactor): void { refactors.set(name, refactor); } diff --git a/src/services/refactors/convertImport.ts b/src/services/refactors/convertImport.ts index b0071598b3bb7..1b21d2d5beb02 100644 --- a/src/services/refactors/convertImport.ts +++ b/src/services/refactors/convertImport.ts @@ -210,7 +210,7 @@ function getLeftOfPropertyAccessOrQualifiedName(propertyAccessOrQualifiedName: P } /** @internal */ -export function doChangeNamedToNamespaceOrDefault(sourceFile: SourceFile, program: Program, changes: textChanges.ChangeTracker, toConvert: NamedImports, shouldUseDefault = getShouldUseDefault(program, toConvert.parent)): void { +export function doChangeNamedToNamespaceOrDefault(sourceFile: SourceFile, program: Program, changes: textChanges.ChangeTracker, toConvert: NamedImports, shouldUseDefault: boolean = getShouldUseDefault(program, toConvert.parent)): void { const checker = program.getTypeChecker(); const importDecl = toConvert.parent.parent; const { moduleSpecifier } = importDecl; diff --git a/src/services/refactors/extractSymbol.ts b/src/services/refactors/extractSymbol.ts index 423922f691323..2d59e42c433d6 100644 --- a/src/services/refactors/extractSymbol.ts +++ b/src/services/refactors/extractSymbol.ts @@ -387,17 +387,17 @@ export namespace Messages { export const cannotExtractRangeContainingConditionalReturnStatement: DiagnosticMessage = createMessage("Cannot extract range containing conditional return statement."); export const cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange: DiagnosticMessage = createMessage("Cannot extract range containing labeled break or continue with target outside of the range."); export const cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators: DiagnosticMessage = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); - export const typeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); - export const functionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); - export const cannotExtractIdentifier = createMessage("Select more than a single identifier."); - export const cannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); - export const cannotWriteInExpression = createMessage("Cannot write back side-effects when extracting an expression"); - export const cannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); - export const cannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts"); - export const cannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes"); - export const cannotExtractToJSClass = createMessage("Cannot extract constant to a class scope in JS"); - export const cannotExtractToExpressionArrowFunction = createMessage("Cannot extract constant to an arrow function without a block"); - export const cannotExtractFunctionsContainingThisToMethod = createMessage("Cannot extract functions containing this to method"); + export const typeWillNotBeVisibleInTheNewScope: DiagnosticMessage = createMessage("Type will not visible in the new scope."); + export const functionWillNotBeVisibleInTheNewScope: DiagnosticMessage = createMessage("Function will not visible in the new scope."); + export const cannotExtractIdentifier: DiagnosticMessage = createMessage("Select more than a single identifier."); + export const cannotExtractExportedEntity: DiagnosticMessage = createMessage("Cannot extract exported declaration"); + export const cannotWriteInExpression: DiagnosticMessage = createMessage("Cannot write back side-effects when extracting an expression"); + export const cannotExtractReadonlyPropertyInitializerOutsideConstructor: DiagnosticMessage = createMessage("Cannot move initialization of read-only class property outside of the constructor"); + export const cannotExtractAmbientBlock: DiagnosticMessage = createMessage("Cannot extract code from ambient contexts"); + export const cannotAccessVariablesFromNestedScopes: DiagnosticMessage = createMessage("Cannot access variables from nested scopes"); + export const cannotExtractToJSClass: DiagnosticMessage = createMessage("Cannot extract constant to a class scope in JS"); + export const cannotExtractToExpressionArrowFunction: DiagnosticMessage = createMessage("Cannot extract constant to an arrow function without a block"); + export const cannotExtractFunctionsContainingThisToMethod: DiagnosticMessage = createMessage("Cannot extract functions containing this to method"); } /** @internal */ diff --git a/src/services/refactors/helpers.ts b/src/services/refactors/helpers.ts index 459979c3ef0dc..38fc8b965f4b9 100644 --- a/src/services/refactors/helpers.ts +++ b/src/services/refactors/helpers.ts @@ -55,7 +55,7 @@ export function refactorKindBeginsWith(known: string, requested: string | undefi * * @internal */ -export function getIdentifierForNode(node: Node, scope: FunctionLikeDeclaration | SourceFile | ModuleBlock | ClassLikeDeclaration, checker: TypeChecker, file: SourceFile) { +export function getIdentifierForNode(node: Node, scope: FunctionLikeDeclaration | SourceFile | ModuleBlock | ClassLikeDeclaration, checker: TypeChecker, file: SourceFile): string { return isPropertyAccessExpression(node) && !isClassLike(scope) && !checker.resolveName(node.name.text, node, SymbolFlags.Value, /*excludeGlobals*/ false) && !isPrivateIdentifier(node.name) && !identifierToKeywordKind(node.name) ? node.name.text : getUniqueName(isClassLike(scope) ? "newProperty" : "newLocal", file); @@ -69,7 +69,7 @@ export function addTargetFileImports( checker: TypeChecker, program: Program, importAdder: codefix.ImportAdder, -) { +): void { /** * Recomputing the imports is preferred with importAdder because it manages multiple import additions for a file and writes then to a ChangeTracker, * but sometimes it fails because of unresolved imports from files, or when a source file is not available for the target file (in this case when creating a new file). diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 85c040013edcb..c1e102fc9c8bf 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -246,7 +246,7 @@ export function getNewStatementsAndRemoveFromOldFile( preferences: UserPreferences, importAdderForNewFile: codefix.ImportAdder, importAdderForOldFile: codefix.ImportAdder, -) { +): void { const checker = program.getTypeChecker(); const prologueDirectives = takeWhile(oldFile.statements, isPrologueDirective); @@ -311,7 +311,7 @@ function deleteUnusedOldImports(oldFile: SourceFile, toMove: readonly Statement[ } /** @internal */ -export function addExportsInOldFile(oldFile: SourceFile, targetFileImportsFromOldFile: Map, changes: textChanges.ChangeTracker, useEsModuleSyntax: boolean) { +export function addExportsInOldFile(oldFile: SourceFile, targetFileImportsFromOldFile: Map, changes: textChanges.ChangeTracker, useEsModuleSyntax: boolean): void { const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. targetFileImportsFromOldFile.forEach((_, symbol) => { if (!symbol.declarations) { @@ -512,7 +512,7 @@ export function addImportsForMovedSymbols( targetFileName: string, importAdder: codefix.ImportAdder, program: Program, -) { +): void { for (const [symbol, isValidTypeOnlyUseSite] of symbols) { const symbolName = getNameForExportedSymbol(symbol, getEmitScriptTarget(program.getCompilerOptions())); const exportKind = symbol.name === "default" && symbol.parent ? ExportKind.Default : ExportKind.Named; @@ -840,7 +840,7 @@ export function getStatementsToMove(context: RefactorContext): ToMove | undefine } /** @internal */ -export function containsJsx(statements: readonly Statement[] | undefined) { +export function containsJsx(statements: readonly Statement[] | undefined): Statement | undefined { return find(statements, statement => !!(statement.transformFlags & TransformFlags.ContainsJsx)); } @@ -1121,7 +1121,7 @@ function getOverloadRangeToMove(sourceFile: SourceFile, statement: Statement) { } /** @internal */ -export function getExistingLocals(sourceFile: SourceFile, statements: readonly Statement[], checker: TypeChecker) { +export function getExistingLocals(sourceFile: SourceFile, statements: readonly Statement[], checker: TypeChecker): Set { const existingLocals = new Set(); for (const moduleSpecifier of sourceFile.imports) { const declaration = importFromModuleSpecifier(moduleSpecifier); diff --git a/src/services/services.ts b/src/services/services.ts index 116bda8a27e75..c51089dfe25de 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1363,7 +1363,7 @@ function isCamelCase(s: string) { return !s.length || s.charAt(0) === s.charAt(0).toLowerCase(); } -export function displayPartsToString(displayParts: SymbolDisplayPart[] | undefined) { +export function displayPartsToString(displayParts: SymbolDisplayPart[] | undefined): string { if (displayParts) { return map(displayParts, displayPart => displayPart.text).join(""); } @@ -1379,7 +1379,7 @@ export function getDefaultCompilerOptions(): CompilerOptions { }; } -export function getSupportedCodeFixes() { +export function getSupportedCodeFixes(): readonly string[] { return codefix.getSupportedErrorCodes(); } diff --git a/src/services/sourcemaps.ts b/src/services/sourcemaps.ts index a8c168eb320aa..5613d2011102b 100644 --- a/src/services/sourcemaps.ts +++ b/src/services/sourcemaps.ts @@ -183,7 +183,7 @@ export function getDocumentPositionMapper( generatedFileName: string, generatedFileLineInfo: LineInfo, readMapFile: ReadMapFile, -) { +): DocumentPositionMapper | undefined { let mapFileName = tryGetSourceMappingURL(generatedFileLineInfo); if (mapFileName) { const match = base64UrlRegExp.exec(mapFileName); diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 8a0ef48935850..7c41dd5e103cf 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -298,7 +298,16 @@ function convertStringLiteralCompletions( } /** @internal */ -export function getStringLiteralCompletionDetails(name: string, sourceFile: SourceFile, position: number, contextToken: Node | undefined, program: Program, host: LanguageServiceHost, cancellationToken: CancellationToken, preferences: UserPreferences) { +export function getStringLiteralCompletionDetails( + name: string, + sourceFile: SourceFile, + position: number, + contextToken: Node | undefined, + program: Program, + host: LanguageServiceHost, + cancellationToken: CancellationToken, + preferences: UserPreferences, +): CompletionEntryDetails | undefined { if (!contextToken || !isStringLiteralLike(contextToken)) return undefined; const completions = getStringLiteralCompletionEntries(sourceFile, contextToken, position, program, host, preferences); return completions && stringLiteralCompletionDetails(name, contextToken, completions, sourceFile, program.getTypeChecker(), cancellationToken); diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 5ba8170b17b32..6c49848435e70 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -866,7 +866,15 @@ function getSymbolDisplayPartsDocumentationAndSymbolKindWorker(typeChecker: Type // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location /** @internal */ -export function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker: TypeChecker, symbol: Symbol, sourceFile: SourceFile, enclosingDeclaration: Node | undefined, location: Node, semanticMeaning = getMeaningFromLocation(location), alias?: Symbol): SymbolDisplayPartsDocumentationAndSymbolKind { +export function getSymbolDisplayPartsDocumentationAndSymbolKind( + typeChecker: TypeChecker, + symbol: Symbol, + sourceFile: SourceFile, + enclosingDeclaration: Node | undefined, + location: Node, + semanticMeaning: SemanticMeaning = getMeaningFromLocation(location), + alias?: Symbol, +): SymbolDisplayPartsDocumentationAndSymbolKind { return getSymbolDisplayPartsDocumentationAndSymbolKindWorker(typeChecker, symbol, sourceFile, enclosingDeclaration, location, /*type*/ undefined, semanticMeaning, alias); } diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index b02caba811bc0..e73da8490b683 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -509,7 +509,7 @@ export class ChangeTracker { /** Public for tests only. Other callers should use `ChangeTracker.with`. */ constructor(private readonly newLineCharacter: string, private readonly formatContext: formatting.FormatContext) {} - public pushRaw(sourceFile: SourceFile, change: FileTextChanges) { + public pushRaw(sourceFile: SourceFile, change: FileTextChanges): void { Debug.assertEqual(sourceFile.fileName, change.fileName); for (const c of change.textChanges) { this.changes.push({ @@ -534,7 +534,7 @@ export class ChangeTracker { this.deleteRange(sourceFile, getAdjustedRange(sourceFile, node, node, options)); } - public deleteNodes(sourceFile: SourceFile, nodes: readonly Node[], options: ConfigurableStartEnd = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }, hasTrailingComment: boolean): void { + public deleteNodes(sourceFile: SourceFile, nodes: readonly Node[], options: ConfigurableStartEnd | undefined = { leadingTriviaOption: LeadingTriviaOption.IncludeAll }, hasTrailingComment: boolean): void { // When deleting multiple nodes we need to track if the end position is including multiline trailing comments. for (const node of nodes) { const pos = getAdjustedStartPosition(sourceFile, node, options, hasTrailingComment); @@ -724,7 +724,7 @@ export class ChangeTracker { factory.createNodeArray(intersperse(comments, factory.createJSDocText("\n"))); } - public replaceJSDocComment(sourceFile: SourceFile, node: HasJSDoc, tags: readonly JSDocTag[]) { + public replaceJSDocComment(sourceFile: SourceFile, node: HasJSDoc, tags: readonly JSDocTag[]): void { this.insertJsdocCommentBefore(sourceFile, updateJSDocHost(node), factory.createJSDocComment(this.createJSDocText(sourceFile, node), factory.createNodeArray(tags))); } @@ -1011,7 +1011,7 @@ export class ChangeTracker { this.insertText(sourceFile, node.getStart(sourceFile), "export "); } - public insertImportSpecifierAtIndex(sourceFile: SourceFile, importSpecifier: ImportSpecifier, namedImports: NamedImports, index: number) { + public insertImportSpecifierAtIndex(sourceFile: SourceFile, importSpecifier: ImportSpecifier, namedImports: NamedImports, index: number): void { const prevSpecifier = namedImports.elements[index - 1]; if (prevSpecifier) { this.insertNodeInListAfter(sourceFile, prevSpecifier, importSpecifier); @@ -1031,7 +1031,7 @@ export class ChangeTracker { * i.e. arguments in arguments lists, parameters in parameter lists etc. * Note that separators are part of the node in statements and class elements. */ - public insertNodeInListAfter(sourceFile: SourceFile, after: Node, newNode: Node, containingList = formatting.SmartIndenter.getContainingList(after, sourceFile)): void { + public insertNodeInListAfter(sourceFile: SourceFile, after: Node, newNode: Node, containingList: NodeArray | undefined = formatting.SmartIndenter.getContainingList(after, sourceFile)): void { if (!containingList) { Debug.fail("node is not a list element"); return; @@ -1121,7 +1121,7 @@ export class ChangeTracker { } } - public parenthesizeExpression(sourceFile: SourceFile, expression: Expression) { + public parenthesizeExpression(sourceFile: SourceFile, expression: Expression): void { this.replaceRange(sourceFile, rangeOfNode(expression), factory.createParenthesizedExpression(expression)); } @@ -1659,7 +1659,7 @@ function getInsertionPositionAtSourceFileTop(sourceFile: SourceFile): number { } /** @internal */ -export function isValidLocationToAddComment(sourceFile: SourceFile, position: number) { +export function isValidLocationToAddComment(sourceFile: SourceFile, position: number): boolean { return !isInComment(sourceFile, position) && !isInString(sourceFile, position) && !isInTemplateString(sourceFile, position) && !isInJSXText(sourceFile, position); } diff --git a/src/services/types.ts b/src/services/types.ts index 10befea4c5386..30e4ee715d2af 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -1232,7 +1232,7 @@ export function getDefaultFormatCodeSettings(newLineCharacter?: string): FormatC } /** @internal */ -export const testFormatSettings = getDefaultFormatCodeSettings("\n"); +export const testFormatSettings: FormatCodeSettings = getDefaultFormatCodeSettings("\n"); export interface DefinitionInfo extends DocumentSpan { kind: ScriptElementKind; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 033486cbda9bd..fe06adeb8b217 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -525,7 +525,7 @@ function getMeaningFromRightHandSideOfImportEquals(node: Node): SemanticMeaning } /** @internal */ -export function isInRightSideOfInternalImportEqualsDeclaration(node: Node) { +export function isInRightSideOfInternalImportEqualsDeclaration(node: Node): boolean { while (node.parent.kind === SyntaxKind.QualifiedName) { node = node.parent; } @@ -645,7 +645,7 @@ function isCalleeWorker token.getStart(sourceFile); } /** @internal */ -export function isInJSXText(sourceFile: SourceFile, position: number) { +export function isInJSXText(sourceFile: SourceFile, position: number): boolean { const token = getTokenAtPosition(sourceFile, position); if (isJsxText(token)) { return true; @@ -1967,7 +1967,7 @@ export function isInsideJsxElement(sourceFile: SourceFile, position: number): bo } /** @internal */ -export function findPrecedingMatchingToken(token: Node, matchingTokenKind: SyntaxKind.OpenBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.OpenBracketToken, sourceFile: SourceFile) { +export function findPrecedingMatchingToken(token: Node, matchingTokenKind: SyntaxKind.OpenBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.OpenBracketToken, sourceFile: SourceFile): Node | undefined { const closeTokenText = tokenToString(token.kind)!; const matchingTokenText = tokenToString(matchingTokenKind); const tokenFullStart = token.getFullStart(); @@ -2171,7 +2171,7 @@ function nodeHasTokens(n: Node, sourceFile: SourceFileLike): boolean { } /** @internal */ -export function getNodeModifiers(node: Node, excludeFlags = ModifierFlags.None): string { +export function getNodeModifiers(node: Node, excludeFlags: ModifierFlags = ModifierFlags.None): string { const result: string[] = []; const flags = isDeclaration(node) ? getCombinedNodeFlagsAlwaysIncludeJSDoc(node) & ~excludeFlags @@ -2225,7 +2225,7 @@ function areIntersectedTypesAvoidingStringReduction(checker: TypeChecker, t1: Ty } /** @internal */ -export function isStringAndEmptyAnonymousObjectIntersection(type: Type) { +export function isStringAndEmptyAnonymousObjectIntersection(type: Type): boolean { if (!type.isIntersection()) { return false; } @@ -2242,7 +2242,7 @@ export function isInsideTemplateLiteral(node: TemplateLiteralToken, position: nu } /** @internal */ -export function isAccessibilityModifier(kind: SyntaxKind) { +export function isAccessibilityModifier(kind: SyntaxKind): boolean { switch (kind) { case SyntaxKind.PublicKeyword: case SyntaxKind.PrivateKeyword: @@ -2261,7 +2261,7 @@ export function cloneCompilerOptions(options: CompilerOptions): CompilerOptions } /** @internal */ -export function isArrayLiteralOrObjectLiteralDestructuringPattern(node: Node) { +export function isArrayLiteralOrObjectLiteralDestructuringPattern(node: Node): boolean { if ( node.kind === SyntaxKind.ArrayLiteralExpression || node.kind === SyntaxKind.ObjectLiteralExpression @@ -2313,7 +2313,7 @@ function isInReferenceCommentWorker(sourceFile: SourceFile, position: number, sh } /** @internal */ -export function getReplacementSpanForContextToken(contextToken: Node | undefined, position: number) { +export function getReplacementSpanForContextToken(contextToken: Node | undefined, position: number): TextSpan | undefined { if (!contextToken) return undefined; switch (contextToken.kind) { @@ -2331,7 +2331,7 @@ export function createTextSpanFromNode(node: Node, sourceFile?: SourceFile, endN } /** @internal */ -export function createTextSpanFromStringLiteralLikeContent(node: StringLiteralLike, position: number) { +export function createTextSpanFromStringLiteralLikeContent(node: StringLiteralLike, position: number): TextSpan | undefined { let replacementEnd = node.getEnd() - 1; if (node.isUnterminated) { // we return no replacement range only if unterminated string is empty @@ -2400,7 +2400,7 @@ function isTypeKeywordToken(node: Node): node is Token { } /** @internal */ -export function isTypeKeywordTokenOrIdentifier(node: Node) { +export function isTypeKeywordTokenOrIdentifier(node: Node): boolean { return isTypeKeywordToken(node) || isIdentifier(node) && node.text === "type"; } @@ -2772,7 +2772,7 @@ export function getMappedContextSpan(documentSpan: DocumentSpan, sourceMapper: S // Display-part writer helpers // #region /** @internal */ -export function isFirstDeclarationOfSymbolParameter(symbol: Symbol) { +export function isFirstDeclarationOfSymbolParameter(symbol: Symbol): boolean { const declaration = symbol.declarations ? firstOrUndefined(symbol.declarations) : undefined; return !!findAncestor(declaration, n => isParameter(n) ? true : isBindingElement(n) || isObjectBindingPattern(n) || isArrayBindingPattern(n) ? false : "quit"); } @@ -2903,37 +2903,37 @@ export function displayPart(text: string, kind: SymbolDisplayPartKind): SymbolDi } /** @internal */ -export function spacePart() { +export function spacePart(): SymbolDisplayPart { return displayPart(" ", SymbolDisplayPartKind.space); } /** @internal */ -export function keywordPart(kind: SyntaxKind) { +export function keywordPart(kind: SyntaxKind): SymbolDisplayPart { return displayPart(tokenToString(kind)!, SymbolDisplayPartKind.keyword); } /** @internal */ -export function punctuationPart(kind: SyntaxKind) { +export function punctuationPart(kind: SyntaxKind): SymbolDisplayPart { return displayPart(tokenToString(kind)!, SymbolDisplayPartKind.punctuation); } /** @internal */ -export function operatorPart(kind: SyntaxKind) { +export function operatorPart(kind: SyntaxKind): SymbolDisplayPart { return displayPart(tokenToString(kind)!, SymbolDisplayPartKind.operator); } /** @internal */ -export function parameterNamePart(text: string) { +export function parameterNamePart(text: string): SymbolDisplayPart { return displayPart(text, SymbolDisplayPartKind.parameterName); } /** @internal */ -export function propertyNamePart(text: string) { +export function propertyNamePart(text: string): SymbolDisplayPart { return displayPart(text, SymbolDisplayPartKind.propertyName); } /** @internal */ -export function textOrKeywordPart(text: string) { +export function textOrKeywordPart(text: string): SymbolDisplayPart { const kind = stringToToken(text); return kind === undefined ? textPart(text) @@ -2941,17 +2941,17 @@ export function textOrKeywordPart(text: string) { } /** @internal */ -export function textPart(text: string) { +export function textPart(text: string): SymbolDisplayPart { return displayPart(text, SymbolDisplayPartKind.text); } /** @internal */ -export function typeAliasNamePart(text: string) { +export function typeAliasNamePart(text: string): SymbolDisplayPart { return displayPart(text, SymbolDisplayPartKind.aliasName); } /** @internal */ -export function typeParameterNamePart(text: string) { +export function typeParameterNamePart(text: string): SymbolDisplayPart { return displayPart(text, SymbolDisplayPartKind.typeParameterName); } @@ -3040,14 +3040,14 @@ const lineFeed = "\n"; * * @internal */ -export function getNewLineOrDefaultFromHost(host: FormattingHost, formatSettings: FormatCodeSettings | undefined) { +export function getNewLineOrDefaultFromHost(host: FormattingHost, formatSettings: FormatCodeSettings | undefined): string { return formatSettings?.newLineCharacter || host.getNewLine?.() || lineFeed; } /** @internal */ -export function lineBreakPart() { +export function lineBreakPart(): SymbolDisplayPart { return displayPart("\n", SymbolDisplayPartKind.lineBreak); } @@ -3115,12 +3115,12 @@ function isAliasSymbol(symbol: Symbol): boolean { } /** @internal */ -export function getUniqueSymbolId(symbol: Symbol, checker: TypeChecker) { +export function getUniqueSymbolId(symbol: Symbol, checker: TypeChecker): number { return getSymbolId(skipAlias(symbol, checker)); } /** @internal */ -export function getFirstNonSpaceCharacterPosition(text: string, position: number) { +export function getFirstNonSpaceCharacterPosition(text: string, position: number): number { while (isWhiteSpaceLike(text.charCodeAt(position))) { position += 1; } @@ -3128,7 +3128,7 @@ export function getFirstNonSpaceCharacterPosition(text: string, position: number } /** @internal */ -export function getPrecedingNonSpaceCharacterPosition(text: string, position: number) { +export function getPrecedingNonSpaceCharacterPosition(text: string, position: number): number { while (position > -1 && isWhiteSpaceSingleLine(text.charCodeAt(position))) { position -= 1; } @@ -3219,7 +3219,7 @@ export function getSynthesizedDeepClonesWithReplacements( * * @internal */ -export function suppressLeadingAndTrailingTrivia(node: Node) { +export function suppressLeadingAndTrailingTrivia(node: Node): void { suppressLeadingTrivia(node); suppressTrailingTrivia(node); } @@ -3229,7 +3229,7 @@ export function suppressLeadingAndTrailingTrivia(node: Node) { * * @internal */ -export function suppressLeadingTrivia(node: Node) { +export function suppressLeadingTrivia(node: Node): void { addEmitFlagsRecursively(node, EmitFlags.NoLeadingComments, getFirstChild); } @@ -3238,12 +3238,12 @@ export function suppressLeadingTrivia(node: Node) { * * @internal @knipignore */ -export function suppressTrailingTrivia(node: Node) { +export function suppressTrailingTrivia(node: Node): void { addEmitFlagsRecursively(node, EmitFlags.NoTrailingComments, getLastChild); } /** @internal */ -export function copyComments(sourceNode: Node, targetNode: Node) { +export function copyComments(sourceNode: Node, targetNode: Node): void { const sourceFile = sourceNode.getSourceFile(); const text = sourceFile.text; if (hasLeadingLineBreak(sourceNode, text)) { @@ -3317,12 +3317,12 @@ export function getRenameLocation(edits: readonly FileTextChanges[], renameFilen } /** @internal */ -export function copyLeadingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean) { +export function copyLeadingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean): void { forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, addSyntheticLeadingComment)); } /** @internal */ -export function copyTrailingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean) { +export function copyTrailingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean): void { forEachTrailingCommentRange(sourceFile.text, sourceNode.end, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, addSyntheticTrailingComment)); } @@ -3335,7 +3335,7 @@ export function copyTrailingComments(sourceNode: Node, targetNode: Node, sourceF * * @internal */ -export function copyTrailingAsLeadingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean) { +export function copyTrailingAsLeadingComments(sourceNode: Node, targetNode: Node, sourceFile: SourceFile, commentKind?: CommentKind, hasTrailingNewLine?: boolean): void { forEachTrailingCommentRange(sourceFile.text, sourceNode.pos, getAddCommentsFunction(targetNode, sourceFile, commentKind, hasTrailingNewLine, addSyntheticLeadingComment)); } @@ -4008,7 +4008,7 @@ export function firstOrOnly(valueOrArray: T | readonly T[]): T { * instead, which searches for names of re-exported defaults/namespaces in target files. * @internal */ -export function getNameForExportedSymbol(symbol: Symbol, scriptTarget: ScriptTarget | undefined, preferCapitalized?: boolean) { +export function getNameForExportedSymbol(symbol: Symbol, scriptTarget: ScriptTarget | undefined, preferCapitalized?: boolean): string { if (symbol.escapedName === InternalSymbolName.ExportEquals || symbol.escapedName === InternalSymbolName.Default) { // Names for default exports: // - export default foo => foo @@ -4111,7 +4111,7 @@ export function moduleSpecifierToValidIdentifier(moduleSpecifier: string, target * * @internal */ -export function stringContainsAt(haystack: string, needle: string, startIndex: number) { +export function stringContainsAt(haystack: string, needle: string, startIndex: number): boolean { const needleLength = needle.length; if (needleLength + startIndex > haystack.length) { return false; @@ -4128,7 +4128,7 @@ export function startsWithUnderscore(name: string): boolean { } /** @internal */ -export function isDeprecatedDeclaration(decl: Declaration) { +export function isDeprecatedDeclaration(decl: Declaration): boolean { return !!(getCombinedNodeFlagsAlwaysIncludeJSDoc(decl) & ModifierFlags.Deprecated); } @@ -4177,12 +4177,12 @@ export function getFormatCodeSettingsForWriting({ options }: formatting.FormatCo } /** @internal */ -export function jsxModeNeedsExplicitImport(jsx: JsxEmit | undefined) { +export function jsxModeNeedsExplicitImport(jsx: JsxEmit | undefined): jsx is JsxEmit.React | JsxEmit.ReactNative { return jsx === JsxEmit.React || jsx === JsxEmit.ReactNative; } /** @internal */ -export function isSourceFileFromLibrary(program: Program, node: SourceFile) { +export function isSourceFileFromLibrary(program: Program, node: SourceFile): boolean { return program.isSourceFileFromExternalLibrary(node) || program.isSourceFileDefaultLibrary(node); } @@ -4258,7 +4258,7 @@ export function newCaseClauseTracker(checker: TypeChecker, clauses: readonly (Ca } /** @internal */ -export function fileShouldUseJavaScriptRequire(file: SourceFile | string, program: Program, host: LanguageServiceHost, preferRequire?: boolean) { +export function fileShouldUseJavaScriptRequire(file: SourceFile | string, program: Program, host: LanguageServiceHost, preferRequire?: boolean): boolean | undefined { const fileName = typeof file === "string" ? file : file.fileName; if (!hasJSFileExtension(fileName)) { return false; diff --git a/src/testRunner/compilerRunner.ts b/src/testRunner/compilerRunner.ts index 8ec63a8b7b921..aed00f47656b3 100644 --- a/src/testRunner/compilerRunner.ts +++ b/src/testRunner/compilerRunner.ts @@ -46,17 +46,17 @@ export class CompilerBaselineRunner extends RunnerBase { this.basePath += "/" + this.testSuiteName; } - public kind() { + public kind(): TestRunnerKind { return this.testSuiteName; } private testFiles: string[] | undefined; - public enumerateTestFiles() { + public enumerateTestFiles(): string[] { // see also: `enumerateTestFiles` in tests/webTestServer.ts return this.testFiles ??= this.enumerateFiles(this.basePath, /\.tsx?$/, { recursive: true }); } - public initializeTests() { + public initializeTests(): void { describe(this.testSuiteName + " tests", () => { describe("Setup compiler for compiler baselines", () => { this.parseOptions(); @@ -70,7 +70,7 @@ export class CompilerBaselineRunner extends RunnerBase { }); } - public checkTestCodeOutput(fileName: string, test?: CompilerFileBasedTest) { + public checkTestCodeOutput(fileName: string, test?: CompilerFileBasedTest): void { if (test && ts.some(test.configurations)) { test.configurations.forEach(configuration => { describe(`${this.testSuiteName} tests for ${fileName}${configuration ? ` (${getFileBasedTestConfigurationDescription(configuration)})` : ``}`, () => { diff --git a/src/testRunner/fourslashRunner.ts b/src/testRunner/fourslashRunner.ts index e1a0535963ca3..841cfd0b9b051 100644 --- a/src/testRunner/fourslashRunner.ts +++ b/src/testRunner/fourslashRunner.ts @@ -26,16 +26,16 @@ export class FourSlashRunner extends RunnerBase { } } - public enumerateTestFiles() { + public enumerateTestFiles(): string[] { // see also: `enumerateTestFiles` in tests/webTestServer.ts return this.enumerateFiles(this.basePath, /\.ts/i, { recursive: false }); } - public kind() { + public kind(): TestRunnerKind { return this.testSuiteName; } - public initializeTests() { + public initializeTests(): void { if (this.tests.length === 0) { this.tests = IO.enumerateTestFiles(this); } diff --git a/src/testRunner/parallel/host.ts b/src/testRunner/parallel/host.ts index 0df41fb73e2fd..400971655c6b4 100644 --- a/src/testRunner/parallel/host.ts +++ b/src/testRunner/parallel/host.ts @@ -33,7 +33,7 @@ import { import * as ts from "../_namespaces/ts.js"; import * as Utils from "../_namespaces/Utils.js"; -export function start(importTests: () => Promise) { +export function start(importTests: () => Promise): void { const Base = Mocha.reporters.Base; const color = Base.color; const cursor = Base.cursor; diff --git a/src/testRunner/parallel/shared.ts b/src/testRunner/parallel/shared.ts index 53d310eefcf15..e0adb6db04163 100644 --- a/src/testRunner/parallel/shared.ts +++ b/src/testRunner/parallel/shared.ts @@ -75,7 +75,7 @@ export interface ParallelTimeoutChangeMessage { export type ParallelClientMessage = ParallelErrorMessage | ParallelResultMessage | ParallelBatchProgressMessage | ParallelTimeoutChangeMessage; -export function shimNoopTestInterface(global: Mocha.MochaGlobals) { +export function shimNoopTestInterface(global: Mocha.MochaGlobals): void { global.before = ts.noop; global.after = ts.noop; global.beforeEach = ts.noop; diff --git a/src/testRunner/parallel/worker.ts b/src/testRunner/parallel/worker.ts index 23c089ef35411..0dde6ae90cab3 100644 --- a/src/testRunner/parallel/worker.ts +++ b/src/testRunner/parallel/worker.ts @@ -17,7 +17,7 @@ import { UnitTestTask, } from "../_namespaces/Harness.Parallel.js"; -export function start(importTests: () => Promise) { +export function start(importTests: () => Promise): void { // This brings in the tests after we finish setting things up and yield to the event loop. const importTestsPromise = importTests(); diff --git a/src/testRunner/projectsRunner.ts b/src/testRunner/projectsRunner.ts index fa5d15a11a13e..5befdf497dff2 100644 --- a/src/testRunner/projectsRunner.ts +++ b/src/testRunner/projectsRunner.ts @@ -38,7 +38,7 @@ interface BatchCompileProjectTestCaseResult extends CompileProjectFilesResult { } export class ProjectRunner extends Harness.RunnerBase { - public enumerateTestFiles() { + public enumerateTestFiles(): string[] { const all = this.enumerateFiles("tests/cases/project", /\.json$/, { recursive: true }); if (Harness.shards === 1) { return all; @@ -50,7 +50,7 @@ export class ProjectRunner extends Harness.RunnerBase { return "project"; } - public initializeTests() { + public initializeTests(): void { describe("projects tests", () => { const tests = this.tests.length === 0 ? this.enumerateTestFiles() : this.tests; for (const test of tests) { diff --git a/src/testRunner/transpileRunner.ts b/src/testRunner/transpileRunner.ts index 5ef62de5c806e..3926aa9b7d88e 100644 --- a/src/testRunner/transpileRunner.ts +++ b/src/testRunner/transpileRunner.ts @@ -14,16 +14,16 @@ export class TranspileRunner extends RunnerBase { protected basePath = "tests/cases/transpile"; protected testSuiteName: TestRunnerKind = "transpile"; - public enumerateTestFiles() { + public enumerateTestFiles(): string[] { // see also: `enumerateTestFiles` in tests/webTestServer.ts return this.enumerateFiles(this.basePath, /\.[cm]?[tj]sx?/i, { recursive: true }); } - public kind() { + public kind(): TestRunnerKind { return this.testSuiteName; } - public initializeTests() { + public initializeTests(): void { if (this.tests.length === 0) { this.tests = IO.enumerateTestFiles(this); } diff --git a/src/testRunner/unittests/config/helpers.ts b/src/testRunner/unittests/config/helpers.ts index 5a5aa78c24fed..084238fcd0499 100644 --- a/src/testRunner/unittests/config/helpers.ts +++ b/src/testRunner/unittests/config/helpers.ts @@ -65,12 +65,12 @@ export interface BaselineParseConfigInput { skipFs?: boolean; header?(baseline: string[]): void; } -export function baselineParseConfig(input: BaselineParseConfigInput) { +export function baselineParseConfig(input: BaselineParseConfigInput): void { if (!input.skipJson) baselineParseConfigWith("with json api", getParsedCommandJson, input); baselineParseConfigWith("with jsonSourceFile api", getParsedCommandJsonSourceFile, input); } -export function baselineParseConfigHost(baseline: string[], host: fakes.ParseConfigHost) { +export function baselineParseConfigHost(baseline: string[], host: fakes.ParseConfigHost): void { baseline.push("Fs::", vfs.formatPatch(host.sys.vfs.diff(/*base*/ undefined, { baseIsNotShadowRoot: true })!)); } diff --git a/src/testRunner/unittests/helpers.ts b/src/testRunner/unittests/helpers.ts index 026fdf7df5428..fc46832a59bb0 100644 --- a/src/testRunner/unittests/helpers.ts +++ b/src/testRunner/unittests/helpers.ts @@ -32,7 +32,7 @@ export interface TestCompilerHost extends ts.CompilerHost { export class SourceText implements ts.IScriptSnapshot { private fullText: string | undefined; - constructor(private references: string, private importsAndExports: string, private program: string, private changedPart = ChangedPart.none, private version = 0) { + constructor(private references: string, private importsAndExports: string, private program: string, private changedPart: ChangedPart = ChangedPart.none, private version = 0) { } static New(references: string, importsAndExports: string, program: string): SourceText { @@ -59,7 +59,7 @@ export class SourceText implements ts.IScriptSnapshot { return new SourceText(this.references, this.importsAndExports, newProgram, this.changedPart | ChangedPart.program, this.version + 1); } - public getFullText() { + public getFullText(): string { return this.fullText || (this.fullText = this.references + this.importsAndExports + this.program); } @@ -103,7 +103,7 @@ function createSourceFileWithText(fileName: string, sourceText: SourceText, targ return file; } -export function createTestCompilerHost(texts: readonly NamedSourceText[], target: ts.ScriptTarget, oldProgram?: ProgramWithSourceTexts, useGetSourceFileByPath?: boolean, useCaseSensitiveFileNames?: boolean) { +export function createTestCompilerHost(texts: readonly NamedSourceText[], target: ts.ScriptTarget, oldProgram?: ProgramWithSourceTexts, useGetSourceFileByPath?: boolean, useCaseSensitiveFileNames?: boolean): TestCompilerHost { const files = ts.arrayToMap(texts, t => t.name, t => { if (oldProgram) { let oldFile = oldProgram.getSourceFile(t.name) as SourceFileWithText; @@ -163,7 +163,7 @@ function programToProgramWithSourceTexts(program: ts.Program, texts: NamedSource return result; } -export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: readonly string[], options: ts.CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[], useGetSourceFileByPath?: boolean, useCaseSensitiveFileNames?: boolean) { +export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: readonly string[], options: ts.CompilerOptions, updater: (files: NamedSourceText[]) => void, newTexts?: NamedSourceText[], useGetSourceFileByPath?: boolean, useCaseSensitiveFileNames?: boolean): ProgramWithSourceTexts { if (!newTexts) { newTexts = oldProgram.sourceTexts!.slice(0); } @@ -177,11 +177,11 @@ export function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: rea ); } -export function updateProgramText(files: readonly NamedSourceText[], fileName: string, newProgramText: string) { +export function updateProgramText(files: readonly NamedSourceText[], fileName: string, newProgramText: string): void { const file = ts.find(files, f => f.name === fileName)!; file.text = file.text.updateProgram(newProgramText); } -export function jsonToReadableText(json: any) { +export function jsonToReadableText(json: any): string { return JSON.stringify(json, undefined, 2); } diff --git a/src/testRunner/unittests/helpers/alternateResult.ts b/src/testRunner/unittests/helpers/alternateResult.ts index 41aedb60b9871..65e334417f761 100644 --- a/src/testRunner/unittests/helpers/alternateResult.ts +++ b/src/testRunner/unittests/helpers/alternateResult.ts @@ -91,7 +91,7 @@ export function verifyAlternateResultScenario( sys: () => TestServerHost, edits: () => readonly TscWatchCompileChange[], ) => void, -) { +): void { action( "alternateResult", () => getSysForAlternateResult(forTsserver), diff --git a/src/testRunner/unittests/helpers/baseline.ts b/src/testRunner/unittests/helpers/baseline.ts index f6ea38100392e..97146d59b03cb 100644 --- a/src/testRunner/unittests/helpers/baseline.ts +++ b/src/testRunner/unittests/helpers/baseline.ts @@ -401,7 +401,7 @@ export function baselineBuildInfo( options: ts.CompilerOptions, sys: TestServerHost, originalReadCall?: ts.System["readFile"], -) { +): void { const buildInfoPath = ts.getTsBuildInfoEmitOutputFilePath(options); if (!buildInfoPath || !sys.writtenFiles!.has(toPathWithSystem(sys, buildInfoPath))) return; if (!sys.fileExists(buildInfoPath)) return; @@ -411,7 +411,7 @@ export function baselineBuildInfo( generateBuildInfoBaseline(sys, buildInfoPath, buildInfo); } -export function isWatch(commandLineArgs: readonly string[]) { +export function isWatch(commandLineArgs: readonly string[]): boolean | undefined { return ts.forEach(commandLineArgs, arg => { if (arg.charCodeAt(0) !== ts.CharacterCodes.minus) return false; const option = arg.slice(arg.charCodeAt(1) === ts.CharacterCodes.minus ? 2 : 1).toLowerCase(); @@ -440,7 +440,7 @@ export interface Baseline extends BaselineBase, CommandLineCallbacks { export const fakeTsVersion = "FakeTSVersion"; -export function patchHostForBuildInfoReadWrite(sys: T) { +export function patchHostForBuildInfoReadWrite(sys: T): T { const originalReadFile = sys.readFile; sys.readFile = (path, encoding) => { const value = originalReadFile.call(sys, path, encoding); @@ -454,7 +454,7 @@ export function patchHostForBuildInfoReadWrite(sys: T) { return patchHostForBuildInfoWrite(sys, fakeTsVersion); } -export function patchHostForBuildInfoWrite(sys: T, version: string) { +export function patchHostForBuildInfoWrite(sys: T, version: string): T { const originalWrite = sys.write; sys.write = msg => originalWrite.call(sys, msg.replace(ts.version, version)); const originalWriteFile = sys.writeFile; @@ -492,7 +492,7 @@ export function applyEdit( baseline: BaselineBase["baseline"], edit: (sys: TscWatchSystem) => void, caption?: string, -) { +): void { baseline.push(`Change::${caption ? " " + caption : ""}`, ""); edit(sys); baseline.push("Input::"); @@ -507,7 +507,7 @@ export function baselineAfterTscCompile( baselineSourceMap: boolean | undefined, shouldBaselinePrograms: boolean | undefined, baselineDependencies: boolean | undefined, -) { +): readonly CommandLineProgram[] { if (baselineSourceMap) generateSourceMapBaselineFiles(sys); const programs = getPrograms(); sys.writtenFiles.forEach((value, key) => { diff --git a/src/testRunner/unittests/helpers/contents.ts b/src/testRunner/unittests/helpers/contents.ts index 580ebe09786c0..780ca4b1d81ee 100644 --- a/src/testRunner/unittests/helpers/contents.ts +++ b/src/testRunner/unittests/helpers/contents.ts @@ -5,12 +5,12 @@ import { import * as ts from "../../_namespaces/ts.js"; /** Default typescript and lib installs location for tests */ -export const tscTypeScriptTestLocation = getPathForTypeScriptTestLocation("tsc.js"); -export function getPathForTypeScriptTestLocation(fileName: string) { +export const tscTypeScriptTestLocation: string = getPathForTypeScriptTestLocation("tsc.js"); +export function getPathForTypeScriptTestLocation(fileName: string): string { return ts.combinePaths(harnessSessionLibLocation, fileName); } -export function getTypeScriptLibTestLocation(libName: string) { +export function getTypeScriptLibTestLocation(libName: string): string { return getPathForTypeScriptTestLocation(ts.libMap.get(libName) ?? `lib.${libName}.d.ts`); } @@ -18,7 +18,7 @@ export function getPathForTypeScriptTypingInstallerCacheTest(fileName: string) { return `${harnessTypingInstallerCacheLocation}/${fileName}`; } -export function compilerOptionsToConfigJson(options: ts.CompilerOptions) { +export function compilerOptionsToConfigJson(options: ts.CompilerOptions): object { return ts.optionMapToObject(ts.serializeCompilerOptions(options)); } @@ -33,6 +33,6 @@ interface Symbol { } `; -export function getProjectConfigWithNodeNext(withNodeNext: boolean | undefined) { +export function getProjectConfigWithNodeNext(withNodeNext: boolean | undefined): object | undefined { return withNodeNext ? { module: "nodenext", target: "es5" } : undefined; } diff --git a/src/testRunner/unittests/helpers/declarationEmit.ts b/src/testRunner/unittests/helpers/declarationEmit.ts index 8116b9f935d27..512860a91e82e 100644 --- a/src/testRunner/unittests/helpers/declarationEmit.ts +++ b/src/testRunner/unittests/helpers/declarationEmit.ts @@ -70,7 +70,7 @@ export function forEachDeclarationEmitWithErrorsScenario( sys: () => TestServerHost, ) => void, withComposite: boolean, -) { +): void { for (const outFile of [false, true]) { for (const incremental of [undefined, true] as const) { action( diff --git a/src/testRunner/unittests/helpers/demoProjectReferences.ts b/src/testRunner/unittests/helpers/demoProjectReferences.ts index 90f09b8ab7760..38e7360f704c4 100644 --- a/src/testRunner/unittests/helpers/demoProjectReferences.ts +++ b/src/testRunner/unittests/helpers/demoProjectReferences.ts @@ -2,7 +2,7 @@ import { dedent } from "../../_namespaces/Utils.js"; import { jsonToReadableText } from "../helpers.js"; import { TestServerHost } from "./virtualFileSystemWithWatch.js"; -export function getFsContentsForDemoProjectReferencesCoreConfig(additional?: object) { +export function getFsContentsForDemoProjectReferencesCoreConfig(additional?: object): string { return jsonToReadableText({ extends: "../tsconfig-base.json", compilerOptions: { @@ -12,7 +12,7 @@ export function getFsContentsForDemoProjectReferencesCoreConfig(additional?: obj ...additional, }); } -export function getSysForDemoProjectReferences() { +export function getSysForDemoProjectReferences(): TestServerHost { return TestServerHost.createWatchedSystem({ "/user/username/projects/demo/animals/animal.ts": dedent` export type Size = "small" | "medium" | "large"; diff --git a/src/testRunner/unittests/helpers/extends.ts b/src/testRunner/unittests/helpers/extends.ts index 960ceaa198bc4..204825cf58ad0 100644 --- a/src/testRunner/unittests/helpers/extends.ts +++ b/src/testRunner/unittests/helpers/extends.ts @@ -100,7 +100,7 @@ export function forConfigDirExtendsSysScenario( sys: () => TestServerHost, edits: () => readonly TscWatchCompileChange[], ) => void, -) { +): void { action( "configDir template", () => getConfigDirExtendsSys(forTsserver), diff --git a/src/testRunner/unittests/helpers/forceConsistentCasingInFileNames.ts b/src/testRunner/unittests/helpers/forceConsistentCasingInFileNames.ts index 48cc0e08fc955..a8546156d1abb 100644 --- a/src/testRunner/unittests/helpers/forceConsistentCasingInFileNames.ts +++ b/src/testRunner/unittests/helpers/forceConsistentCasingInFileNames.ts @@ -2,7 +2,7 @@ import { dedent } from "../../_namespaces/Utils.js"; import { jsonToReadableText } from "../helpers.js"; import { TestServerHost } from "./virtualFileSystemWithWatch.js"; -export function getSysForMultipleErrorsForceConsistentCasingInFileNames(forTsserver?: boolean) { +export function getSysForMultipleErrorsForceConsistentCasingInFileNames(forTsserver?: boolean): TestServerHost { return TestServerHost.getCreateWatchedSystem(forTsserver)({ "/home/src/projects/project/src/struct.d.ts": dedent` import * as xs1 from "fp-ts/lib/Struct"; diff --git a/src/testRunner/unittests/helpers/libraryResolution.ts b/src/testRunner/unittests/helpers/libraryResolution.ts index e23d3882046db..aa113a86f8629 100644 --- a/src/testRunner/unittests/helpers/libraryResolution.ts +++ b/src/testRunner/unittests/helpers/libraryResolution.ts @@ -201,7 +201,7 @@ export function forEachLibResolutionScenario( forTsserver: boolean, withoutConfig: true | undefined, action: (scenario: string, sys: () => TestServerHost, edits: () => readonly TscWatchCompileChange[]) => void, -) { +): void { [undefined, true].forEach(libRedirection => { action( `${withoutConfig ? "without" : "with"} config${libRedirection ? " with redirection" : ""}`, @@ -214,13 +214,13 @@ export function forEachLibResolutionScenario( }); } -export function getCommandLineArgsForLibResolution(withoutConfig: true | undefined) { +export function getCommandLineArgsForLibResolution(withoutConfig: true | undefined): string[] { return withoutConfig ? ["project1/core.d.ts", "project1/utils.d.ts", "project1/file.ts", "project1/index.ts", "project1/file2.ts", "--lib", "es5,dom", "--traceResolution", "--explainFiles"] : ["-p", "project1", "--explainFiles"]; } -export function getSysForLibResolutionUnknown() { +export function getSysForLibResolutionUnknown(): TestServerHost { return TestServerHost.createWatchedSystem({ "/home/src/workspace/projects/project1/utils.d.ts": `export const y = 10;`, "/home/src/workspace/projects/project1/file.ts": `export const file = 10;`, diff --git a/src/testRunner/unittests/helpers/monorepoSymlinkedSiblingPackages.ts b/src/testRunner/unittests/helpers/monorepoSymlinkedSiblingPackages.ts index cd57e0a51ced7..2f0139f2595d3 100644 --- a/src/testRunner/unittests/helpers/monorepoSymlinkedSiblingPackages.ts +++ b/src/testRunner/unittests/helpers/monorepoSymlinkedSiblingPackages.ts @@ -276,7 +276,7 @@ export function forEachMonorepoSymlinkScenario( indexFile: string, currentDirectory: string, ) => void, -) { +): void { describe("monorepoSymlinkedSiblingPackages:: monorepo style sibling packages symlinked", () => { forEachMonorepoSymlinkedSiblingPackagesSys(forTsserver, action); }); diff --git a/src/testRunner/unittests/helpers/noCheck.ts b/src/testRunner/unittests/helpers/noCheck.ts index 28ce347bad5b5..94220091a09fc 100644 --- a/src/testRunner/unittests/helpers/noCheck.ts +++ b/src/testRunner/unittests/helpers/noCheck.ts @@ -7,7 +7,7 @@ import { } from "./tsc.js"; import { TestServerHost } from "./virtualFileSystemWithWatch.js"; -export function forEachTscScenarioWithNoCheck(buildType: "-b" | "-p") { +export function forEachTscScenarioWithNoCheck(buildType: "-b" | "-p"): void { const commandLineArgs = buildType === "-b" ? ["-b", "-v"] : emptyArray; diff --git a/src/testRunner/unittests/helpers/noEmit.ts b/src/testRunner/unittests/helpers/noEmit.ts index 2d2b4e3c7f44e..ccf3d04431e58 100644 --- a/src/testRunner/unittests/helpers/noEmit.ts +++ b/src/testRunner/unittests/helpers/noEmit.ts @@ -143,7 +143,7 @@ function forEachNoEmitChangesWorker(commandType: string[], compilerOptions: Comp } } -export function forEachNoEmitChanges(commandType: string[]) { +export function forEachNoEmitChanges(commandType: string[]): void { describe("when noEmit changes between compilation", () => { forEachNoEmitChangesWorker(commandType, { incremental: true }); forEachNoEmitChangesWorker(commandType, { incremental: true, declaration: true }); @@ -206,7 +206,7 @@ function editsForDtsChanges( ]; } -export function forEachNoEmitDtsChanges(commandType: string[]) { +export function forEachNoEmitDtsChanges(commandType: string[]): void { describe("dts errors with declaration enable changes", () => { if (commandType[0] !== "-b") return; // Only test non multiple file errors with -b [false, true].forEach(asModules => @@ -341,7 +341,7 @@ function forEachNoEmitAndErrors( }); } -export function forEachNoEmitTsc(commandType: string[]) { +export function forEachNoEmitTsc(commandType: string[]): void { forEachNoEmitAndErrors((subScenario, sys, aTsContent, fixedATsContent, compilerOptions) => verifyTsc({ scenario: "noEmit", @@ -385,7 +385,7 @@ export function forEachNoEmitTsc(commandType: string[]) { ); } -export function forEachNoEmitTscWatch(commandType: string[]) { +export function forEachNoEmitTscWatch(commandType: string[]): void { forEachNoEmitAndErrors((subScenario, sys, aTsContent, fixedATsContent, compilerOptions) => verifyTscWatch({ scenario: "noEmit", diff --git a/src/testRunner/unittests/helpers/noEmitOnError.ts b/src/testRunner/unittests/helpers/noEmitOnError.ts index 77474094504d2..92f347253a9d8 100644 --- a/src/testRunner/unittests/helpers/noEmitOnError.ts +++ b/src/testRunner/unittests/helpers/noEmitOnError.ts @@ -102,7 +102,7 @@ function getNoEmitOnErrorErrorsType(): [subScenario: string, mainErrorContent: s ]; } -export function forEachNoEmitOnErrorScenarioTsc(commandLineArgs: string[]) { +export function forEachNoEmitOnErrorScenarioTsc(commandLineArgs: string[]): void { getNoEmitOnErrorErrorsType().forEach(([subScenario, mainErrorContent, fixedErrorContent]) => forEachNoEmitOnErrorScenario( subScenario, @@ -129,7 +129,7 @@ export function forEachNoEmitOnErrorScenarioTsc(commandLineArgs: string[]) { ); } -export function forEachNoEmitOnErrorScenarioTscWatch(commandLineArgs: string[]) { +export function forEachNoEmitOnErrorScenarioTscWatch(commandLineArgs: string[]): void { const errorTypes = getNoEmitOnErrorErrorsType(); forEachNoEmitOnErrorScenario( "noEmitOnError", diff --git a/src/testRunner/unittests/helpers/projectRoots.ts b/src/testRunner/unittests/helpers/projectRoots.ts index 2792d8062b04e..111038f493c13 100644 --- a/src/testRunner/unittests/helpers/projectRoots.ts +++ b/src/testRunner/unittests/helpers/projectRoots.ts @@ -66,7 +66,7 @@ export function forEachScenarioForRootsFromReferencedProject( sys: () => TestServerHost, edits: () => readonly TscWatchCompileChange[], ) => void, -) { +): void { [true, false].forEach(serverFirst => action( `when root file is from referenced project${!serverFirst ? " and shared is first" : ""}`, diff --git a/src/testRunner/unittests/helpers/sampleProjectReferences.ts b/src/testRunner/unittests/helpers/sampleProjectReferences.ts index adc358e6c4c49..fbafb4d43d277 100644 --- a/src/testRunner/unittests/helpers/sampleProjectReferences.ts +++ b/src/testRunner/unittests/helpers/sampleProjectReferences.ts @@ -4,7 +4,7 @@ import { getProjectConfigWithNodeNext } from "./contents.js"; import { solutionBuildWithBaseline } from "./solutionBuilder.js"; import { TestServerHost } from "./virtualFileSystemWithWatch.js"; -export function getFsContentsForSampleProjectReferencesLogicConfig(withNodeNext?: boolean) { +export function getFsContentsForSampleProjectReferencesLogicConfig(withNodeNext?: boolean): string { return jsonToReadableText({ compilerOptions: { ...getProjectConfigWithNodeNext(withNodeNext), @@ -24,7 +24,7 @@ export function getSysForSampleProjectReferences( withNodeNext?: boolean, skipReferenceCoreFromTest?: boolean, forTsserver?: boolean, -) { +): TestServerHost { return TestServerHost.getCreateWatchedSystem(forTsserver)({ "/user/username/projects/sample1/core/tsconfig.json": jsonToReadableText({ compilerOptions: { @@ -82,7 +82,7 @@ export function getSysForSampleProjectReferences( }, { currentDirectory: "/user/username/projects/sample1" }); } -export function getSysForSampleProjectReferencesBuilt(withNodeNext?: boolean) { +export function getSysForSampleProjectReferencesBuilt(withNodeNext?: boolean): TestServerHost { return solutionBuildWithBaseline( getSysForSampleProjectReferences(withNodeNext), ["tests"], diff --git a/src/testRunner/unittests/helpers/solutionBuilder.ts b/src/testRunner/unittests/helpers/solutionBuilder.ts index 8f5278d400181..5e4d32a990514 100644 --- a/src/testRunner/unittests/helpers/solutionBuilder.ts +++ b/src/testRunner/unittests/helpers/solutionBuilder.ts @@ -40,12 +40,12 @@ export function createSolutionBuilder( rootNames: readonly string[], buildOptions?: ts.BuildOptions, originalRead?: TestServerHost["readFile"], -) { +): ts.SolutionBuilder { const host = createSolutionBuilderHostForBaseline(system, originalRead); return ts.createSolutionBuilder(host, rootNames, buildOptions ?? {}); } -export function ensureErrorFreeBuild(host: TestServerHost, rootNames: readonly string[]) { +export function ensureErrorFreeBuild(host: TestServerHost, rootNames: readonly string[]): void { // ts build should succeed solutionBuildWithBaseline(host, rootNames); assert.equal(host.getOutput().length, 0, jsonToReadableText(host.getOutput())); @@ -57,7 +57,7 @@ export function solutionBuildWithBaseline( buildOptions?: ts.BuildOptions, versionToWrite?: string, originalRead?: TestServerHost["readFile"], -) { +): TestServerHost { if (sys.writtenFiles === undefined) { const originalReadFile = sys.readFile; const originalWrite = sys.write; @@ -87,7 +87,7 @@ export function solutionBuildWithBaseline( } } -export function verifySolutionBuilderWithDifferentTsVersion(input: VerifyTscWithEditsInput, rootNames: readonly string[]) { +export function verifySolutionBuilderWithDifferentTsVersion(input: VerifyTscWithEditsInput, rootNames: readonly string[]): void { describe(input.subScenario, () => { let originalReadFile: TscWatchSystem["readFile"]; let originalWriteFile: TscWatchSystem["writeFile"]; diff --git a/src/testRunner/unittests/helpers/transitiveReferences.ts b/src/testRunner/unittests/helpers/transitiveReferences.ts index 787e860980e2d..8d7dd8b5cb673 100644 --- a/src/testRunner/unittests/helpers/transitiveReferences.ts +++ b/src/testRunner/unittests/helpers/transitiveReferences.ts @@ -3,14 +3,14 @@ import { jsonToReadableText } from "../helpers.js"; import { getProjectConfigWithNodeNext } from "./contents.js"; import { TestServerHost } from "./virtualFileSystemWithWatch.js"; -export function getFsContentsForTransitiveReferencesRefsAdts() { +export function getFsContentsForTransitiveReferencesRefsAdts(): string { return dedent` export class X {} export class A {} `; } -export function getFsContentsForTransitiveReferencesBConfig(withNodeNext: boolean) { +export function getFsContentsForTransitiveReferencesBConfig(withNodeNext: boolean): string { return jsonToReadableText({ compilerOptions: { ...getProjectConfigWithNodeNext(withNodeNext), @@ -25,7 +25,7 @@ export function getFsContentsForTransitiveReferencesBConfig(withNodeNext: boolea }); } -export function getFsContentsForTransitiveReferencesAConfig(withNodeNext: boolean) { +export function getFsContentsForTransitiveReferencesAConfig(withNodeNext: boolean): string { return jsonToReadableText({ compilerOptions: { ...getProjectConfigWithNodeNext(withNodeNext), @@ -35,7 +35,7 @@ export function getFsContentsForTransitiveReferencesAConfig(withNodeNext: boolea }); } -export function getSysForTransitiveReferences(withNodeNext?: boolean) { +export function getSysForTransitiveReferences(withNodeNext?: boolean): TestServerHost { return TestServerHost.createWatchedSystem({ "/user/username/projects/transitiveReferences/refs/a.d.ts": getFsContentsForTransitiveReferencesRefsAdts(), "/user/username/projects/transitiveReferences/a.ts": dedent` diff --git a/src/testRunner/unittests/helpers/tsc.ts b/src/testRunner/unittests/helpers/tsc.ts index 8bdd49cb1206f..85cc75125190c 100644 --- a/src/testRunner/unittests/helpers/tsc.ts +++ b/src/testRunner/unittests/helpers/tsc.ts @@ -32,7 +32,7 @@ export const noChangeRun: TestTscEdit = { caption: "no-change-run", edit: ts.noop, }; -export const noChangeOnlyRuns = [noChangeRun]; +export const noChangeOnlyRuns: TestTscEdit[] = [noChangeRun]; export interface TestTscCompile { commandLineArgs: readonly string[]; @@ -461,7 +461,7 @@ export interface VerifyTscWithEditsInput extends Omit { let snaps: TestServerHostSnapshot[] | undefined; after(() => { diff --git a/src/testRunner/unittests/helpers/tscWatch.ts b/src/testRunner/unittests/helpers/tscWatch.ts index e9c6d79e6bb07..2e6dbc2b8c970 100644 --- a/src/testRunner/unittests/helpers/tscWatch.ts +++ b/src/testRunner/unittests/helpers/tscWatch.ts @@ -80,7 +80,7 @@ function tscWatchCompile(input: TscWatchCompile) { }); } -export function createSolutionBuilderWithWatchHostForBaseline(sys: TestServerHost, cb: ts.ExecuteCommandLineCallbacks) { +export function createSolutionBuilderWithWatchHostForBaseline(sys: TestServerHost, cb: ts.ExecuteCommandLineCallbacks): ts.SolutionBuilderWithWatchHost { const host = ts.createSolutionBuilderWithWatchHost(sys, /*createProgram*/ undefined, ts.createDiagnosticReporter(sys, /*pretty*/ true), ts.createBuilderStatusReporter(sys, /*pretty*/ true), ts.createWatchStatusReporter(sys, /*pretty*/ true)); host.afterProgramEmitAndDiagnostics = cb; return host; @@ -93,7 +93,7 @@ interface CreateWatchCompilerHostOfConfigFileForBaseline( input: CreateWatchCompilerHostOfConfigFileForBaseline, -) { +): ts.WatchCompilerHostOfConfigFile { const host = ts.createWatchCompilerHostOfConfigFile({ ...input, reportDiagnostic: ts.createDiagnosticReporter(input.system, /*pretty*/ true), @@ -109,7 +109,7 @@ interface CreateWatchCompilerHostOfFilesAndCompilerOptionsForBaseline( input: CreateWatchCompilerHostOfFilesAndCompilerOptionsForBaseline, -) { +): ts.WatchCompilerHostOfFilesAndCompilerOptions { const host = ts.createWatchCompilerHostOfFilesAndCompilerOptions({ ...input, reportDiagnostic: ts.createDiagnosticReporter(input.system, /*pretty*/ true), @@ -146,7 +146,7 @@ export function runWatchBaseline) { +}: RunWatchBaseline): void { baseline.push(`${sys.getExecutingFilePath()} ${commandLineArgs.join(" ")}`); let programs = watchBaseline({ baseline, @@ -194,7 +194,7 @@ export function watchBaseline({ caption, resolutionCache, useSourceOfProjectReferenceRedirect, -}: WatchBaseline) { +}: WatchBaseline): readonly CommandLineProgram[] { const programs = baselineAfterTscCompile( sys, baseline, @@ -262,7 +262,7 @@ function verifyProgramStructureAndResolutionCache( export interface VerifyTscWatch extends TscWatchCompile { baselineIncremental?: boolean; } -export function verifyTscWatch(input: VerifyTscWatch) { +export function verifyTscWatch(input: VerifyTscWatch): void { describe(input.scenario, () => { describe(input.subScenario, () => { tscWatchCompile(input); diff --git a/src/testRunner/unittests/helpers/tsserver.ts b/src/testRunner/unittests/helpers/tsserver.ts index 5f17f30e83e1c..f8c5a4a81de7a 100644 --- a/src/testRunner/unittests/helpers/tsserver.ts +++ b/src/testRunner/unittests/helpers/tsserver.ts @@ -25,7 +25,7 @@ import { TestServerHostTrackingWrittenFiles, } from "./virtualFileSystemWithWatch.js"; -export function baselineTsserverLogs(scenario: string, subScenario: string, sessionOrService: { logger: LoggerWithInMemoryLogs; }) { +export function baselineTsserverLogs(scenario: string, subScenario: string, sessionOrService: { logger: LoggerWithInMemoryLogs; }): void { Baseline.runBaseline(`tsserver/${scenario}/${subScenario.split(" ").join("-")}.js`, sessionOrService.logger.logs.join("\r\n")); } @@ -33,7 +33,7 @@ export function toExternalFile(fileName: string): ts.server.protocol.ExternalFil return { fileName }; } -export function toExternalFiles(fileNames: string[]) { +export function toExternalFiles(fileNames: string[]): ts.server.protocol.ExternalFile[] { return ts.map(fileNames, toExternalFile); } @@ -45,7 +45,7 @@ export function patchHostTimeouts( inputHost: TestServerHostTrackingWrittenFiles, session: TestSession | undefined, logger: LoggerWithInMemoryLogs, -) { +): TestSessionAndServiceHost { const host = inputHost as TestSessionAndServiceHost; host.service = session?.getProjectService(); if (session) patchServiceForStateBaseline(session.getProjectService()); @@ -216,7 +216,7 @@ export class TestSession extends ts.server.Session { public override logger!: LoggerWithInMemoryLogs; public override readonly typingsInstaller!: TestTypingsInstallerAdapter; public serverCancellationToken: TestServerCancellationToken; - public watchChanges = new Map(); + public watchChanges: Map = new Map(); constructor(optsOrHost: TestSessionConstructorOptions) { const opts = getTestSessionPartialOptionsAndHost(optsOrHost); @@ -255,19 +255,19 @@ export class TestSession extends ts.server.Session { if (opts.canUseWatchEvents) patchSessionToHandleWatchEvents(this); } - getProjectService() { + getProjectService(): ts.server.ProjectService { return this.projectService; } - public getSeq() { + public getSeq(): number { return this.seq; } - public getNextSeq() { + public getNextSeq(): number { return this.seq + 1; } - public override executeCommand(request: ts.server.protocol.Request) { + public override executeCommand(request: ts.server.protocol.Request): ts.server.HandlerResponse { if (this.logger.hasLevel(ts.server.LogLevel.verbose)) { this.host.baselineHost("Before request"); this.logger.info(`request:${ts.server.stringifyIndented(request)}`); @@ -280,7 +280,7 @@ export class TestSession extends ts.server.Session { return response; } - public executeCommandSeq(inputRequest: TestSessionRequest) { + public executeCommandSeq(inputRequest: TestSessionRequest): ts.server.HandlerResponse { this.seq++; const request: T = inputRequest as T; request.seq = this.seq; @@ -288,7 +288,7 @@ export class TestSession extends ts.server.Session { return this.executeCommand(request); } - public invokeWatchChanges() { + public invokeWatchChanges(): void { const changes = ts.singleOrMany(ts.arrayFrom(this.watchChanges.values())); this.watchChanges.clear(); this.executeCommandSeq({ @@ -301,7 +301,7 @@ export class TestSession extends ts.server.Session { export function createSessionWithCustomEventHandler( optsOrHost: TestSessionConstructorOptions, customAction?: (event: ts.server.ProjectServiceEvent) => void, -) { +): TestSession { const opts = getTestSessionPartialOptionsAndHost(optsOrHost); opts.eventHandler = eventHandler; const session = new TestSession(opts); @@ -402,24 +402,24 @@ export class TestServerCancellationToken implements ts.server.ServerCancellation constructor(private logger: LoggerWithInMemoryLogs, private cancelAfterRequest = 0) { } - setRequest(requestId: number) { + setRequest(requestId: number): void { this.currentId = requestId; this.logger.log(`TestServerCancellationToken:: Cancellation Request id:: ${requestId}`); } - setRequestToCancel(requestId: number) { + setRequestToCancel(requestId: number): void { this.logger.log(`TestServerCancellationToken:: Setting request to cancel:: ${requestId}`); this.resetToken(); this.requestToCancel = requestId; } - resetRequest(requestId: number) { + resetRequest(requestId: number): void { this.logger.log(`TestServerCancellationToken:: resetRequest:: ${requestId} is ${requestId === this.currentId ? "as expected" : `expected to be ${this.currentId}`}`); assert.equal(requestId, this.currentId, "unexpected request id in cancellation"); this.currentId = undefined; } - isCancellationRequested() { + isCancellationRequested(): boolean { this.isCancellationRequestedCount++; // If the request id is the request to cancel and isCancellationRequestedCount // has been met then cancel the request. Ex: cancel the request if it is a @@ -429,7 +429,7 @@ export class TestServerCancellationToken implements ts.server.ServerCancellation return result; } - resetToken() { + resetToken(): void { this.currentId = -1; this.isCancellationRequestedCount = 0; this.requestToCancel = -1; @@ -471,14 +471,14 @@ export function closeFilesForSession(files: readonly (File | string)[], session: } } -export function openExternalProjectForSession(project: ts.server.protocol.ExternalProject, session: TestSession) { +export function openExternalProjectForSession(project: ts.server.protocol.ExternalProject, session: TestSession): void { session.executeCommandSeq({ command: ts.server.protocol.CommandTypes.OpenExternalProject, arguments: project, }); } -export function openExternalProjectsForSession(projects: ts.server.protocol.ExternalProject[], session: TestSession) { +export function openExternalProjectsForSession(projects: ts.server.protocol.ExternalProject[], session: TestSession): void { session.executeCommandSeq({ command: ts.server.protocol.CommandTypes.OpenExternalProjects, arguments: { projects }, @@ -488,7 +488,7 @@ export function openExternalProjectsForSession(projects: ts.server.protocol.Exte export function setCompilerOptionsForInferredProjectsRequestForSession( options: ts.server.protocol.InferredProjectCompilerOptions | ts.server.protocol.SetCompilerOptionsForInferredProjectsArgs, session: TestSession, -) { +): void { session.executeCommandSeq({ command: ts.server.protocol.CommandTypes.CompilerOptionsForInferredProjects, arguments: "options" in options ? // eslint-disable-line local/no-in-operator @@ -497,7 +497,7 @@ export function setCompilerOptionsForInferredProjectsRequestForSession( }); } -export function logDiagnostics(sessionOrService: TestSession, diagnosticsType: string, project: ts.server.Project, diagnostics: readonly ts.Diagnostic[]) { +export function logDiagnostics(sessionOrService: TestSession, diagnosticsType: string, project: ts.server.Project, diagnostics: readonly ts.Diagnostic[]): void { sessionOrService.logger.info(`${diagnosticsType}:: ${diagnostics.length}`); diagnostics.forEach(d => sessionOrService.logger.info(ts.formatDiagnostic(d, project))); } @@ -509,7 +509,7 @@ export interface VerifyGetErrRequest extends VerifyGetErrRequestBase { files: readonly (string | File | FileRangesRequestArgs)[]; skip?: CheckAllErrors["skip"]; } -export function verifyGetErrRequest(request: VerifyGetErrRequest) { +export function verifyGetErrRequest(request: VerifyGetErrRequest): void { const { session, files } = request; session.executeCommandSeq({ command: ts.server.protocol.CommandTypes.Geterr, @@ -619,13 +619,13 @@ export interface VerifyGetErrScenario { getErrForProjectRequest: () => readonly GetErrForProjectDiagnostics[]; syncDiagnostics: () => readonly SyncDiagnostics[]; } -export function verifyGetErrScenario(scenario: VerifyGetErrScenario) { +export function verifyGetErrScenario(scenario: VerifyGetErrScenario): void { verifyErrorsUsingGeterr(scenario); verifyErrorsUsingGeterrForProject(scenario); verifyErrorsUsingSyncMethods(scenario); } -export function createHostWithSolutionBuild(files: readonly FileOrFolderOrSymLink[], rootNames: readonly string[]) { +export function createHostWithSolutionBuild(files: readonly FileOrFolderOrSymLink[], rootNames: readonly string[]): TestServerHost { const host = TestServerHost.createServerHost(files); // ts build should succeed ensureErrorFreeBuild(host, rootNames); @@ -636,7 +636,7 @@ export function forEachTscWatchEdit( session: TestSession, edits: readonly TscWatchCompileChange[], action: () => void, -) { +): void { edits.forEach(edit => { session.logger.log(edit.caption); edit.edit(session.host); diff --git a/src/testRunner/unittests/helpers/typingsInstaller.ts b/src/testRunner/unittests/helpers/typingsInstaller.ts index 1c543c7b05f11..8f5b3a699e740 100644 --- a/src/testRunner/unittests/helpers/typingsInstaller.ts +++ b/src/testRunner/unittests/helpers/typingsInstaller.ts @@ -153,7 +153,7 @@ export class TestTypingsInstallerWorker extends ts.server.typingsInstaller.Typin ); } - sendResponse(response: ts.server.SetTypings | ts.server.InvalidateCachedTypings | ts.server.BeginInstallTypes | ts.server.EndInstallTypes | ts.server.WatchTypingLocations | ts.server.PackageInstalledResponse) { + sendResponse(response: ts.server.SetTypings | ts.server.InvalidateCachedTypings | ts.server.BeginInstallTypes | ts.server.EndInstallTypes | ts.server.WatchTypingLocations | ts.server.PackageInstalledResponse): void { this.log.writeLine(`Sending response:${stringifyIndented(response)}`); this.testTypingInstaller.handleMessage(response); } @@ -228,6 +228,6 @@ export function createTypesRegistryFileContent(list: readonly string[]): TypesRe return { entries }; } -export function createTypesRegistry(...list: string[]) { +export function createTypesRegistry(...list: string[]): Map> { return new Map(Object.entries(createTypesRegistryFileContent(list).entries)); } diff --git a/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts b/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts index d58f205339235..f4cd771c092d4 100644 --- a/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts +++ b/src/testRunner/unittests/helpers/virtualFileSystemWithWatch.ts @@ -210,7 +210,7 @@ interface CallbackData { time: number; } class Callbacks { - readonly map = new Map(); + readonly map: Map = new Map(); private nextId = 1; invoke: (invokeKey?: number) => void = invokeKey => this.invokeWorker(invokeKey); private hasChanges = false; @@ -219,11 +219,11 @@ class Callbacks { constructor(private host: TestServerHost, readonly callbackType: string, private readonly swallowExitException?: boolean) { } - getNextId() { + getNextId(): number { return this.nextId; } - register(cb: TimeOutCallback, args: any[], ms?: number) { + register(cb: TimeOutCallback, args: any[], ms?: number): number { const timeoutId = this.nextId; this.nextId++; this.map.set(timeoutId, { cb, args, ms, time: this.host.getTime() }); @@ -231,13 +231,13 @@ class Callbacks { return timeoutId; } - unregister(id: any) { + unregister(id: any): void { if (typeof id === "number") { this.hasChanges = this.map.delete(id) || this.hasChanges; } } - log(logChanges?: boolean) { + log(logChanges?: boolean): string { const details: string[] = []; this.map.forEach(({ args }, timeoutId) => { details.push(`${timeoutId}: ${args[0]}${!logChanges || this.serializedKeys.has(timeoutId) ? "" : " *new*"}`); @@ -271,7 +271,7 @@ class Callbacks { cb(...args); } - invokeWorker(invokeKey?: number) { + invokeWorker(invokeKey?: number): void { try { if (invokeKey) return this.invokeCallback(invokeKey); @@ -291,7 +291,7 @@ class Callbacks { } } - switchToBaseliningInvoke(logger: StateLogger, serializeOutputOrder: SerializeOutputOrder) { + switchToBaseliningInvoke(logger: StateLogger, serializeOutputOrder: SerializeOutputOrder): void { this.invoke = invokeKey => { logger.log(`Before running ${this.log()}`); this.host.serializeState(logger.logs, serializeOutputOrder); @@ -302,7 +302,7 @@ class Callbacks { }; } - serialize(baseline: string[]) { + serialize(baseline: string[]): void { if (this.hasChanges) { baseline.push(this.log(/*logChanges*/ true), ""); this.hasChanges = false; @@ -403,9 +403,9 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, private time = timeIncrements; getCanonicalFileName: (s: string) => string; toPath: (f: string) => Path; - readonly timeoutCallbacks = new Callbacks(this, "Timeout", /*swallowExitException*/ true); - readonly immediateCallbacks = new Callbacks(this, "Immedidate"); - readonly pendingInstalls = new Callbacks(this, "PendingInstalls"); + readonly timeoutCallbacks: Callbacks = new Callbacks(this, "Timeout", /*swallowExitException*/ true); + readonly immediateCallbacks: Callbacks = new Callbacks(this, "Immedidate"); + readonly pendingInstalls: Callbacks = new Callbacks(this, "PendingInstalls"); readonly screenClears: number[] = []; readonly watchUtils: WatchUtils; @@ -520,7 +520,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, }); } - ensureTypingRegistryFile() { + ensureTypingRegistryFile(): void { this.ensureFileOrFolder({ path: getTypesRegistryFileLocation(this.globalTypingsCacheLocation), content: jsonToReadableText(createTypesRegistryFileContent( @@ -563,7 +563,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, return host; } - static getCreateWatchedSystem(forTsserver: boolean | undefined) { + static getCreateWatchedSystem(forTsserver: boolean | undefined): typeof TestServerHost.createWatchedSystem | typeof TestServerHost.createServerHost { return (!forTsserver ? TestServerHost.createWatchedSystem : TestServerHost.createServerHost); } @@ -577,19 +577,19 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, return true; } - getNewLine() { + getNewLine(): string { return this.newLine; } - toNormalizedAbsolutePath(s: string) { + toNormalizedAbsolutePath(s: string): string { return getNormalizedAbsolutePath(s, this.currentDirectory); } - toFullPath(s: string) { + toFullPath(s: string): Path { return this.toPath(this.toNormalizedAbsolutePath(s)); } - getHostSpecificPath(s: string) { + getHostSpecificPath(s: string): string { if (this.windowsStyleRoot) { let result = s; if (s.startsWith(directorySeparator)) { @@ -601,20 +601,20 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, return s; } - now() { + now(): Date { this.time += timeIncrements; return new Date(this.time); } - getTime() { + getTime(): number { return this.time; } - setTime(time: number) { + setTime(time: number): void { this.time = time; } - switchToBaseliningInvoke(logger: StateLogger, serializeOutputOrder: SerializeOutputOrder) { + switchToBaseliningInvoke(logger: StateLogger, serializeOutputOrder: SerializeOutputOrder): void { const originalSetTime = this.setTime; this.setTime = time => { logger.log(`Host is moving to new time`); @@ -659,7 +659,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, this.ensureFileOrFolder({ path: !this.windowsStyleRoot ? "/" : this.getHostSpecificPath("/") }); } - modifyFile(filePath: string, content: string, options?: Partial) { + modifyFile(filePath: string, content: string, options?: Partial): void { const path = this.toFullPath(filePath); const currentEntry = this.fs.get(path); if (!currentEntry || !isFsFileOrFsLibFile(currentEntry)) { @@ -687,7 +687,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, } } - renameFile(fileName: string, newFileName: string) { + renameFile(fileName: string, newFileName: string): void { const fullPath = getNormalizedAbsolutePath(fileName, this.currentDirectory); const path = this.toPath(fullPath); const file = this.fs.get(path) as FsFile; @@ -707,7 +707,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, this.addFileOrFolderInFolder(baseFolder, newFile); } - renameFolder(folderName: string, newFolderName: string, skipFolderEntryWatches?: true) { + renameFolder(folderName: string, newFolderName: string, skipFolderEntryWatches?: true): void { const fullPath = getNormalizedAbsolutePath(folderName, this.currentDirectory); const path = this.toPath(fullPath); const folder = this.fs.get(path) as FsFolder; @@ -749,7 +749,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, } } - ensureFileOrFolder(fileOrDirectoryOrSymLink: FileOrFolderOrSymLinkOrLibFile, ignoreWatchInvokedWithTriggerAsFileCreate?: boolean, ignoreParentWatch?: boolean, options?: Partial) { + ensureFileOrFolder(fileOrDirectoryOrSymLink: FileOrFolderOrSymLinkOrLibFile, ignoreWatchInvokedWithTriggerAsFileCreate?: boolean, ignoreParentWatch?: boolean, options?: Partial): void { if (isFile(fileOrDirectoryOrSymLink)) { const file = this.toFsFileOrLibFile(fileOrDirectoryOrSymLink); // file may already exist when updating existing type declaration file @@ -834,19 +834,19 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, this.inodes?.delete(fileOrDirectory.path); } - rimrafSync(fileOrFolderPath: string) { + rimrafSync(fileOrFolderPath: string): void { const fileOrFolder = this.getRealFileOrFolder(fileOrFolderPath); if (isFsFileOrFsLibFile(fileOrFolder)) this.removeFileOrFolder(fileOrFolder); else if (isFsFolder(fileOrFolder)) this.deleteFolder(fileOrFolder.fullPath, /*recursive*/ true); } - deleteFile(filePath: string) { + deleteFile(filePath: string): void { const file = this.getRealFileOrFolder(filePath); Debug.assert(isFsFileOrFsLibFile(file)); this.removeFileOrFolder(file); } - deleteFolder(folderPath: string, recursive?: boolean) { + deleteFolder(folderPath: string, recursive?: boolean): void { const path = this.toFullPath(folderPath); const currentEntry = this.fs.get(path); Debug.assert(isFsFolder(currentEntry)); @@ -875,7 +875,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, fileOrDirectory: string, recursive: boolean, cb: FsWatchCallback, - ) { + ): FsWatchWorkerWatcher { if (this.runWithFallbackPolling) throw new Error("Need to use fallback polling instead of file system native watching"); let inode: number | undefined; if (this.inodeWatching) { @@ -897,7 +897,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, return result; } - invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind, modifiedTime: Date | undefined) { + invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind, modifiedTime: Date | undefined): void { this.watchUtils.pollingWatches.forEach(fileFullPath, ({ cb }, fullPath) => cb(fullPath, eventKind, modifiedTime)); } @@ -912,11 +912,11 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, }); } - invokeFsWatchesCallbacks(fullPath: string, eventName: "rename" | "change", eventFullPath: string | undefined, useTildeSuffix?: boolean) { + invokeFsWatchesCallbacks(fullPath: string, eventName: "rename" | "change", eventFullPath: string | undefined, useTildeSuffix?: boolean): void { this.fsWatchCallback(this.watchUtils.fsWatches, fullPath, eventName, eventFullPath, useTildeSuffix); } - invokeFsWatchesRecursiveCallbacks(fullPath: string, eventName: "rename" | "change", eventFullPath: string | undefined, useTildeSuffix?: boolean) { + invokeFsWatchesRecursiveCallbacks(fullPath: string, eventName: "rename" | "change", eventFullPath: string | undefined, useTildeSuffix?: boolean): void { this.fsWatchCallback(this.watchUtils.fsWatchesRecursive, fullPath, eventName, eventFullPath, useTildeSuffix); } @@ -932,7 +932,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, } } - invokeFsWatches(fullPath: string, eventName: "rename" | "change", eventFullPath: string | undefined, useTildeSuffix: boolean | undefined) { + invokeFsWatches(fullPath: string, eventName: "rename" | "change", eventFullPath: string | undefined, useTildeSuffix: boolean | undefined): void { this.invokeFsWatchesCallbacks(fullPath, eventName, eventFullPath, useTildeSuffix); this.invokeFsWatchesCallbacks(getDirectoryPath(fullPath), eventName, eventFullPath, useTildeSuffix); this.invokeRecursiveFsWatches(fullPath, eventName, eventFullPath, useTildeSuffix); @@ -1020,20 +1020,20 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, return this.getRealFsEntry((entry): entry is FsFile | FsFolder => !!entry && !isFsSymLink(entry), this.toFullPath(s)); } - fileSystemEntryExists(s: string, entryKind: FileSystemEntryKind) { + fileSystemEntryExists(s: string, entryKind: FileSystemEntryKind): boolean { return entryKind === FileSystemEntryKind.File ? this.fileExists(s) : this.directoryExists(s); } - fileExists(s: string) { + fileExists(s: string): boolean { const path = this.toFullPath(s); return !!this.getRealFile(path); } - getModifiedTime(s: string) { + getModifiedTime(s: string): Date | undefined { return this.getRealFileOrFolder(s)?.modifiedTime; } - setModifiedTime(s: string, date: Date) { + setModifiedTime(s: string, date: Date): void { const fsEntry = this.getRealFileOrFolder(s); if (fsEntry) { fsEntry.modifiedTime = date; @@ -1046,7 +1046,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, return fsEntry ? getFsFileOrLibFileContent(fsEntry) : undefined; } - getFileSize(s: string) { + getFileSize(s: string): number { const path = this.toFullPath(s); const entry = this.fs.get(path)!; if (isFsFileOrFsLibFile(entry)) { @@ -1055,7 +1055,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, return undefined!; // TODO: GH#18217 } - directoryExists(s: string) { + directoryExists(s: string): boolean { const path = this.toFullPath(s); return !!this.getRealFolder(path); } @@ -1101,11 +1101,11 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, } // TOOD: record and invoke callbacks to simulate timer events - setTimeout(callback: TimeOutCallback, ms: number, ...args: any[]) { + setTimeout(callback: TimeOutCallback, ms: number, ...args: any[]): number { return this.timeoutCallbacks.register(callback, args, ms); } - getNextTimeoutId() { + getNextTimeoutId(): number { return this.timeoutCallbacks.getNextId(); } @@ -1117,15 +1117,15 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, this.screenClears.push(this.output.length); } - runQueuedTimeoutCallbacks(timeoutId?: number) { + runQueuedTimeoutCallbacks(timeoutId?: number): void { this.timeoutCallbacks.invoke(timeoutId); } - runQueuedImmediateCallbacks() { + runQueuedImmediateCallbacks(): void { this.immediateCallbacks.invoke(); } - setImmediate(callback: TimeOutCallback, ...args: any[]) { + setImmediate(callback: TimeOutCallback, ...args: any[]): number { return this.immediateCallbacks.register(callback, args); } @@ -1133,11 +1133,11 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, this.immediateCallbacks.unregister(timeoutId); } - scheduleInstall(cb: TimeOutCallback, ...args: any[]) { + scheduleInstall(cb: TimeOutCallback, ...args: any[]): void { this.pendingInstalls.register(cb, args); } - runPendingInstalls() { + runPendingInstalls(): void { this.pendingInstalls.invoke(); } @@ -1181,12 +1181,12 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, this.modifyFile(path, this.readFile(path) + content, options); } - replaceFileText(file: string, searchValue: string | RegExp, replaceValue: string) { + replaceFileText(file: string, searchValue: string | RegExp, replaceValue: string): void { const content = Debug.checkDefined(this.readFile(file)); this.writeFile(file, content.replace(searchValue, replaceValue)); } - write(message: string) { + write(message: string): void { if (Debug.isDebugging) console.log(message); this.output.push(message); } @@ -1195,12 +1195,12 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, return this.output; } - clearOutput() { + clearOutput(): void { clear(this.output); this.screenClears.length = 0; } - serializeOutput(baseline: string[]) { + serializeOutput(baseline: string[]): void { const output = this.getOutput(); if (!this.output.length && !this.screenClears.length) return; let start = 0; @@ -1215,7 +1215,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, this.clearOutput(); } - getSnap() { + getSnap(): TestServerHostSnapshot { return cloneFsMap(this.fs); } @@ -1223,7 +1223,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, this.serializedDiff = cloneFsMap(this.fs); } - serializeState(baseline: string[], serializeOutput: SerializeOutputOrder) { + serializeState(baseline: string[], serializeOutput: SerializeOutputOrder): void { if (serializeOutput === SerializeOutputOrder.BeforeDiff) this.serializeOutput(baseline); this.diff(baseline); if (serializeOutput === SerializeOutputOrder.AfterDiff) this.serializeOutput(baseline); @@ -1236,7 +1236,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, writtenFiles?: Map; private serializedDiff: TestServerHostSnapshot = new Map(); - diff(baseline: string[]) { + diff(baseline: string[]): void { this.fs.forEach((newFsEntry, path) => { diffFsEntry(baseline, this.serializedDiff.get(path), newFsEntry, this.inodes?.get(path), this.writtenFiles); }); @@ -1251,7 +1251,7 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, this.writtenFiles?.clear(); } - serializeWatches(baseline?: string[]) { + serializeWatches(baseline?: string[]): string[] { return this.watchUtils.serializeWatches(baseline); } @@ -1274,14 +1274,14 @@ export class TestServerHost implements server.ServerHost, FormatDiagnosticsHost, } exitCode: number | undefined; - readonly resolvePath = (s: string) => s; - readonly getExecutingFilePath = () => this.executingFilePath; - readonly getCurrentDirectory = () => this.currentDirectory; - exit(exitCode?: number) { + readonly resolvePath = (s: string): string => s; + readonly getExecutingFilePath = (): string => this.executingFilePath; + readonly getCurrentDirectory = (): string => this.currentDirectory; + exit(exitCode?: number): void { this.exitCode = exitCode; throw new Error(exitMessage); } - getEnvironmentVariable(name: string) { + getEnvironmentVariable(name: string): string { return this.environmentVariables && this.environmentVariables.get(name) || ""; } } @@ -1374,7 +1374,7 @@ function sanitizeSysOutput(output: string) { export type TestServerHostTrackingWrittenFiles = TestServerHost & { writtenFiles: Map; }; -export function changeToHostTrackingWrittenFiles(inputHost: TestServerHost) { +export function changeToHostTrackingWrittenFiles(inputHost: TestServerHost): TestServerHostTrackingWrittenFiles { const host = inputHost as TestServerHostTrackingWrittenFiles; if (host.writtenFiles) return host; const originalWriteFile = host.writeFile; @@ -1387,7 +1387,7 @@ export function changeToHostTrackingWrittenFiles(inputHost: TestServerHost) { return host; } -export function osFlavorToString(osFlavor: TestServerHostOsFlavor) { +export function osFlavorToString(osFlavor: TestServerHostOsFlavor): "Windows" | "MacOs" | "Linux" { switch (osFlavor) { case TestServerHostOsFlavor.Windows: return "Windows"; diff --git a/src/testRunner/unittests/services/extract/helpers.ts b/src/testRunner/unittests/services/extract/helpers.ts index 9c022f03c807e..b733b89f50c9c 100644 --- a/src/testRunner/unittests/services/extract/helpers.ts +++ b/src/testRunner/unittests/services/extract/helpers.ts @@ -108,7 +108,7 @@ export const notImplementedHost: ts.LanguageServiceHost = { fileExists: ts.notImplemented, }; -export function testExtractSymbol(caption: string, text: string, baselineFolder: string, description: ts.DiagnosticMessage) { +export function testExtractSymbol(caption: string, text: string, baselineFolder: string, description: ts.DiagnosticMessage): void { const t = extractTest(text); const selectionRange = t.ranges.get("selection")!; if (!selectionRange) { @@ -175,7 +175,7 @@ export function testExtractSymbol(caption: string, text: string, baselineFolder: } } -export function testExtractSymbolFailed(caption: string, text: string, description: ts.DiagnosticMessage) { +export function testExtractSymbolFailed(caption: string, text: string, description: ts.DiagnosticMessage): void { it(caption, () => { const t = extractTest(text); const selectionRange = t.ranges.get("selection"); diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index e4615aa785424..d0727f454b7f6 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -14,6 +14,7 @@ "sourceMap": true, "composite": true, "emitDeclarationOnly": true, + "isolatedDeclarations": true, "strict": true, "strictBindCallApply": false, diff --git a/src/tsserver/common.ts b/src/tsserver/common.ts index 01fd6db7dcf7c..89647f6032c82 100644 --- a/src/tsserver/common.ts +++ b/src/tsserver/common.ts @@ -1,7 +1,7 @@ import * as ts from "../typescript/typescript.js"; /** @internal */ -export function getLogLevel(level: string | undefined) { +export function getLogLevel(level: string | undefined): ts.server.LogLevel | undefined { if (level) { const l = level.toLowerCase(); for (const name in ts.server.LogLevel) { diff --git a/src/typingsInstaller/nodeTypingsInstaller.ts b/src/typingsInstaller/nodeTypingsInstaller.ts index e9fcfdfb5333d..56d6c7ac9385e 100644 --- a/src/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/typingsInstaller/nodeTypingsInstaller.ts @@ -135,7 +135,7 @@ export class NodeTypingsInstaller extends ts.server.typingsInstaller.TypingsInst this.typesRegistry = loadTypesRegistryFile(getTypesRegistryFileLocation(globalTypingsCacheLocation), this.installTypingHost, this.log); } - override handleRequest(req: ts.server.TypingInstallerRequestUnion) { + override handleRequest(req: ts.server.TypingInstallerRequestUnion): void { if (this.delayedInitializationError) { // report initializationFailed error this.sendResponse(this.delayedInitializationError); @@ -144,7 +144,7 @@ export class NodeTypingsInstaller extends ts.server.typingsInstaller.TypingsInst super.handleRequest(req); } - protected sendResponse(response: ts.server.TypingInstallerResponseUnion) { + protected sendResponse(response: ts.server.TypingInstallerResponseUnion): void { if (this.log.isEnabled()) { this.log.writeLine(`Sending response:${ts.server.stringifyIndented(response)}`); } diff --git a/src/typingsInstallerCore/typingsInstaller.ts b/src/typingsInstallerCore/typingsInstaller.ts index fe42a37272cc1..ce9c607b83c02 100644 --- a/src/typingsInstallerCore/typingsInstaller.ts +++ b/src/typingsInstallerCore/typingsInstaller.ts @@ -73,7 +73,7 @@ function typingToFileName(cachePath: string, packageName: string, installTypingH } /** @internal */ -export function installNpmPackages(npmPath: string, tsVersion: string, packageNames: string[], install: (command: string) => boolean) { +export function installNpmPackages(npmPath: string, tsVersion: string, packageNames: string[], install: (command: string) => boolean): boolean { let hasError = false; for (let remaining = packageNames.length; remaining > 0;) { const result = getNpmCommandForInstallation(npmPath, tsVersion, packageNames, remaining); @@ -84,7 +84,10 @@ export function installNpmPackages(npmPath: string, tsVersion: string, packageNa } /** @internal */ -export function getNpmCommandForInstallation(npmPath: string, tsVersion: string, packageNames: string[], remaining: number) { +export function getNpmCommandForInstallation(npmPath: string, tsVersion: string, packageNames: string[], remaining: number): { + command: string; + remaining: number; +} { const sliceStart = packageNames.length - remaining; let command: string, toSlice = remaining; while (true) { @@ -126,7 +129,7 @@ export abstract class TypingsInstaller { private readonly safeListPath: Path, private readonly typesMapLocation: Path, private readonly throttleLimit: number, - protected readonly log = nullLog, + protected readonly log: Log = nullLog, ) { const isLoggingEnabled = this.log.isEnabled(); if (isLoggingEnabled) { @@ -136,7 +139,7 @@ export abstract class TypingsInstaller { } /** @internal */ - handleRequest(req: TypingInstallerRequestUnion) { + handleRequest(req: TypingInstallerRequestUnion): void { switch (req.kind) { case "discover": this.install(req); @@ -162,7 +165,7 @@ export abstract class TypingsInstaller { } } - closeProject(req: CloseProject) { + closeProject(req: CloseProject): void { this.closeWatchers(req.projectName); } @@ -186,7 +189,7 @@ export abstract class TypingsInstaller { } } - install(req: DiscoverTypings) { + install(req: DiscoverTypings): void { if (this.log.isEnabled()) { this.log.writeLine(`Got install request${stringifyIndented(req)}`); } @@ -231,7 +234,7 @@ export abstract class TypingsInstaller { } /** @internal */ - installPackage(req: InstallPackageRequest) { + installPackage(req: InstallPackageRequest): void { const { fileName, packageName, projectName, projectRootPath, id } = req; const cwd = forEachAncestorDirectory(getDirectoryPath(fileName), directory => { if (this.installTypingHost.fileExists(combinePaths(directory, "package.json"))) { @@ -373,7 +376,7 @@ export abstract class TypingsInstaller { }); } - protected ensurePackageDirectoryExists(directory: string) { + protected ensurePackageDirectoryExists(directory: string): void { const npmConfigPath = combinePaths(directory, "package.json"); if (this.log.isEnabled()) { this.log.writeLine(`Npm config file: ${npmConfigPath}`); diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c8589f0b8ae9f..304462086e8a8 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2841,14 +2841,14 @@ declare namespace ts { readonly jsDocParsingMode: JSDocParsingMode | undefined; isKnownTypesPackageName(name: string): boolean; installPackage(options: InstallPackageOptions): Promise; - getCompilationSettings(): ts.CompilerOptions; - getCompilerOptions(): ts.CompilerOptions; + getCompilationSettings(): CompilerOptions; + getCompilerOptions(): CompilerOptions; getNewLine(): string; getProjectVersion(): string; getProjectReferences(): readonly ProjectReference[] | undefined; getScriptFileNames(): string[]; private getOrCreateScriptInfoAndAttachToProject; - getScriptKind(fileName: string): ts.ScriptKind; + getScriptKind(fileName: string): ScriptKind; getScriptVersion(filename: string): string; getScriptSnapshot(filename: string): IScriptSnapshot | undefined; getCancellationToken(): HostCancellationToken; @@ -2884,16 +2884,16 @@ declare namespace ts { getProjectName(): string; protected removeLocalTypingsFromTypeAcquisition(newTypeAcquisition: TypeAcquisition): TypeAcquisition; getExternalFiles(updateLevel?: ProgramUpdateLevel): SortedReadonlyArray; - getSourceFile(path: Path): ts.SourceFile | undefined; + getSourceFile(path: Path): SourceFile | undefined; close(): void; private detachScriptInfoIfNotRoot; isClosed(): boolean; hasRoots(): boolean; getRootFiles(): NormalizedPath[]; - getRootScriptInfos(): ts.server.ScriptInfo[]; + getRootScriptInfos(): ScriptInfo[]; getScriptInfos(): ScriptInfo[]; getExcludedFiles(): readonly NormalizedPath[]; - getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean): ts.server.NormalizedPath[]; + getFileNames(excludeFilesFromExternalLibraries?: boolean, excludeConfigFiles?: boolean): NormalizedPath[]; hasConfigFile(configFilePath: NormalizedPath): boolean; containsScriptInfo(info: ScriptInfo): boolean; containsFile(filename: NormalizedPath, requireOpen?: boolean): boolean; @@ -2918,12 +2918,12 @@ declare namespace ts { private isValidGeneratedFileWatcher; private clearGeneratedFileWatch; getScriptInfoForNormalizedPath(fileName: NormalizedPath): ScriptInfo | undefined; - getScriptInfo(uncheckedFileName: string): ts.server.ScriptInfo | undefined; + getScriptInfo(uncheckedFileName: string): ScriptInfo | undefined; filesToString(writeProjectFileNames: boolean): string; private filesToStringWorker; setCompilerOptions(compilerOptions: CompilerOptions): void; setTypeAcquisition(newTypeAcquisition: TypeAcquisition | undefined): void; - getTypeAcquisition(): ts.TypeAcquisition; + getTypeAcquisition(): TypeAcquisition; protected removeRoot(info: ScriptInfo): void; protected enableGlobalPlugins(options: CompilerOptions): void; protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]): void; @@ -2956,7 +2956,7 @@ declare namespace ts { getScriptFileNames(): string[]; getLanguageService(): never; getHostForAutoImportProvider(): never; - getProjectReferences(): readonly ts.ProjectReference[] | undefined; + getProjectReferences(): readonly ProjectReference[] | undefined; } /** * If a file is opened, the server will look for a tsconfig (or jsconfig) @@ -2973,7 +2973,7 @@ declare namespace ts { * @returns: true if set of files in the project stays the same and false - otherwise. */ updateGraph(): boolean; - getConfigFilePath(): ts.server.NormalizedPath; + getConfigFilePath(): NormalizedPath; getProjectReferences(): readonly ProjectReference[] | undefined; updateReferences(refs: readonly ProjectReference[] | undefined): void; /** @@ -2997,14 +2997,14 @@ declare namespace ts { compileOnSaveEnabled: boolean; excludedFiles: readonly NormalizedPath[]; updateGraph(): boolean; - getExcludedFiles(): readonly ts.server.NormalizedPath[]; + getExcludedFiles(): readonly NormalizedPath[]; } function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings; function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin; function convertWatchOptions(protocolOptions: protocol.ExternalProjectCompilerOptions, currentDirectory?: string): WatchOptionsAndErrors | undefined; function convertTypeAcquisition(protocolOptions: protocol.InferredProjectCompilerOptions): TypeAcquisition | undefined; function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind; - function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX; + function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind; const maxProgramSizeForNonTsFiles: number; const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground"; interface ProjectsUpdatedInBackgroundEvent {