From fecc7c485ffa80d0e46fd806c3262e1124824e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Wed, 4 Jul 2018 14:39:19 +0800 Subject: [PATCH 1/2] add support of extension preference --- src/compiler/moduleSpecifiers.ts | 52 +++++--- src/server/protocol.ts | 1 + src/services/types.ts | 1 + .../reference/api/tsserverlibrary.d.ts | 99 +++++++++++++++ tests/baselines/reference/api/typescript.d.ts | 1 + .../importNameCodeFix_ExtensionPreference.ts | 114 ++++++++++++++++++ 6 files changed, 251 insertions(+), 17 deletions(-) create mode 100644 tests/cases/fourslash/importNameCodeFix_ExtensionPreference.ts diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index b243ff348146f..17a5851c97d3e 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -3,6 +3,7 @@ namespace ts.moduleSpecifiers { export interface ModuleSpecifierPreferences { readonly importModuleSpecifierPreference?: "relative" | "non-relative"; + readonly includeExtensionInImports?: boolean } // Note: importingSourceFile is just for usesJsExtensionOnImports @@ -17,7 +18,7 @@ namespace ts.moduleSpecifiers { ): string { const info = getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host); const modulePaths = getAllModulePaths(files, toFileName, info.getCanonicalFileName, host); - return firstDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions)) || + return firstDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions, preferences)) || first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); } @@ -39,46 +40,47 @@ namespace ts.moduleSpecifiers { } const modulePaths = getAllModulePaths(files, getSourceFileOfNode(moduleSymbol.valueDeclaration).fileName, info.getCanonicalFileName, host); - const global = mapDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions)); + const global = mapDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions, preferences)); return global.length ? global.map(g => [g]) : modulePaths.map(moduleFileName => getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences)); } interface Info { readonly moduleResolutionKind: ModuleResolutionKind; - readonly addJsExtension: boolean; + readonly addExtension: boolean; readonly getCanonicalFileName: GetCanonicalFileName; readonly sourceDirectory: Path; } // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path function getInfo(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Info { const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); - const addJsExtension = usesJsExtensionOnImports(importingSourceFile); + const addExtension = usesExtensionOnImports(importingSourceFile); const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true); const sourceDirectory = getDirectoryPath(importingSourceFileName); - return { moduleResolutionKind, addJsExtension, getCanonicalFileName, sourceDirectory }; + return { moduleResolutionKind, addExtension, getCanonicalFileName, sourceDirectory }; } function getGlobalModuleSpecifier( moduleFileName: string, - { addJsExtension, getCanonicalFileName, sourceDirectory }: Info, + { addExtension, getCanonicalFileName, sourceDirectory }: Info, host: ModuleSpecifierResolutionHost, compilerOptions: CompilerOptions, + preferences: ModuleSpecifierPreferences ) { - return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) + return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addExtension, preferences) || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory); } function getLocalModuleSpecifiers( moduleFileName: string, - { moduleResolutionKind, addJsExtension, getCanonicalFileName, sourceDirectory }: Info, + { moduleResolutionKind, addExtension, getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, preferences: ModuleSpecifierPreferences, ): ReadonlyArray { const { baseUrl, paths, rootDirs } = compilerOptions; const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) || - removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); + removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addExtension, compilerOptions, preferences); if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { return [relativePath]; } @@ -88,7 +90,7 @@ namespace ts.moduleSpecifiers { return [relativePath]; } - const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); + const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addExtension, compilerOptions, preferences); if (paths) { const fromPaths = tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); if (fromPaths) { @@ -138,8 +140,8 @@ namespace ts.moduleSpecifiers { return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; } - function usesJsExtensionOnImports({ imports }: SourceFile): boolean { - return firstDefined(imports, ({ text }) => pathIsRelative(text) ? fileExtensionIs(text, Extension.Js) : undefined) || false; + function usesExtensionOnImports({ imports }: SourceFile): boolean { + return firstDefined(imports, ({ text }) => pathIsRelative(text) ? fileExtensionIsOneOf(text, [Extension.Js, Extension.Jsx]) : undefined) || false; } function discoverProbableSymlinks(files: ReadonlyArray, getCanonicalFileName: (file: string) => string, host: ModuleSpecifierResolutionHost) { @@ -256,14 +258,15 @@ namespace ts.moduleSpecifiers { host: GetEffectiveTypeRootsHost, getCanonicalFileName: (file: string) => string, moduleFileName: string, - addJsExtension: boolean, + addExtension: boolean, + preferences: ModuleSpecifierPreferences ): string | undefined { const roots = getEffectiveTypeRoots(options, host); return firstDefined(roots, unNormalizedTypeRoot => { const typeRoot = toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName); if (startsWith(moduleFileName, typeRoot)) { // For a type definition, we can strip `/index` even with classic resolution. - return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ModuleResolutionKind.NodeJs, addJsExtension); + return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), ModuleResolutionKind.NodeJs, addExtension, options, preferences); } }); } @@ -408,10 +411,25 @@ namespace ts.moduleSpecifiers { }); } - function removeExtensionAndIndexPostFix(fileName: string, moduleResolutionKind: ModuleResolutionKind, addJsExtension: boolean): string { + function tryGetActualExtension(text: string, compilerOptions: CompilerOptions) { + const extension = pathIsRelative(text) && tryGetExtensionFromPath(text); + if (!extension) return undefined; + + switch (extension) { + case Extension.Ts: + return Extension.Js; + case Extension.Tsx: + return compilerOptions.jsx === JsxEmit.React || compilerOptions.jsx === JsxEmit.ReactNative ? Extension.Js : Extension.Jsx; + default: + return extension; + } + } + + function removeExtensionAndIndexPostFix(fileName: string, moduleResolutionKind: ModuleResolutionKind, addJsExtension: boolean, compilerOptions: CompilerOptions, preferences: ModuleSpecifierPreferences): string { const noExtension = removeFileExtension(fileName); - return addJsExtension - ? noExtension + ".js" + const actualExtension = tryGetActualExtension(fileName, compilerOptions); + return (actualExtension && (preferences.includeExtensionInImports !== undefined && preferences.includeExtensionInImports || addJsExtension)) + ? noExtension + actualExtension : moduleResolutionKind === ModuleResolutionKind.NodeJs ? removeSuffix(noExtension, "/index") : noExtension; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index a04b7fe5da8b8..f76a527f942d5 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2802,6 +2802,7 @@ namespace ts.server.protocol { readonly includeCompletionsWithInsertText?: boolean; readonly importModuleSpecifierPreference?: "relative" | "non-relative"; readonly allowTextChangesInNewFiles?: boolean; + readonly includeExtensionInImports?: boolean } export interface CompilerOptions { diff --git a/src/services/types.ts b/src/services/types.ts index 51c98724c0957..65d3036d63e0d 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -240,6 +240,7 @@ namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly importModuleSpecifierPreference?: "relative" | "non-relative"; readonly allowTextChangesInNewFiles?: boolean; + readonly includeExtensionInImports?: boolean } /* @internal */ export const emptyOptions = {}; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5118830e840ce..64e0b6efc6c4f 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4303,6 +4303,103 @@ declare namespace ts { function createAbstractBuilder(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; } declare namespace ts { +<<<<<<< HEAD +======= + /** This is the cache of module/typedirectives resolution that can be retained across program */ + interface ResolutionCache { + startRecordingFilesWithChangedResolutions(): void; + finishRecordingFilesWithChangedResolutions(): Path[] | undefined; + resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[]; + getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): CachedResolvedModuleWithFailedLookupLocations | undefined; + resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; + invalidateResolutionOfFile(filePath: Path): void; + removeResolutionsOfFile(filePath: Path): void; + setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map>): void; + createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution; + startCachingPerDirectoryResolution(): void; + finishCachingPerDirectoryResolution(): void; + updateTypeRootsWatch(): void; + closeTypeRootsWatch(): void; + clear(): void; + } + interface ResolutionWithFailedLookupLocations { + readonly failedLookupLocations: ReadonlyArray; + isInvalidated?: boolean; + refCount?: number; + } + interface CachedResolvedModuleWithFailedLookupLocations extends ResolvedModuleWithFailedLookupLocations, ResolutionWithFailedLookupLocations { + } + interface ResolutionCacheHost extends ModuleResolutionHost { + toPath(fileName: string): Path; + getCanonicalFileName: GetCanonicalFileName; + getCompilationSettings(): CompilerOptions; + watchDirectoryOfFailedLookupLocation(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher; + onInvalidatedResolution(): void; + watchTypeRootsDirectory(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher; + onChangedAutomaticTypeDirectiveNames(): void; + getCachedDirectoryStructureHost(): CachedDirectoryStructureHost | undefined; + projectName?: string; + getGlobalCache?(): string | undefined; + writeLog(s: string): void; + maxNumberOfFilesToIterateForInvalidation?: number; + getCurrentProgram(): Program; + } + const maxNumberOfFilesToIterateForInvalidation = 256; + function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string | undefined, logChangesWhenResolvingModule: boolean): ResolutionCache; +} +declare namespace ts.moduleSpecifiers { + interface ModuleSpecifierPreferences { + readonly importModuleSpecifierPreference?: "relative" | "non-relative"; + readonly includeExtensionInImports?: boolean; + } + function getModuleSpecifier(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: Path, toFileName: string, host: ModuleSpecifierResolutionHost, files: ReadonlyArray, preferences?: ModuleSpecifierPreferences): string; + function getModuleSpecifiers(moduleSymbol: Symbol, compilerOptions: CompilerOptions, importingSourceFile: SourceFile, host: ModuleSpecifierResolutionHost, files: ReadonlyArray, preferences: ModuleSpecifierPreferences): ReadonlyArray>; +} +declare namespace ts { + /** + * Create a function that reports error by writing to the system and handles the formating of the diagnostic + */ + function createDiagnosticReporter(system: System, pretty?: boolean): DiagnosticReporter; + /** @internal */ + const nonClearingMessageCodes: number[]; + /** @internal */ + const screenStartingMessageCodes: number[]; + /** + * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic + */ + function createWatchStatusReporter(system: System, pretty?: boolean): WatchStatusReporter; + /** Parses config file using System interface */ + function parseConfigFileWithSystem(configFileName: string, optionsToExtend: CompilerOptions, system: System, reportDiagnostic: DiagnosticReporter): ParsedCommandLine | undefined; + /** + * Program structure needed to emit the files and report diagnostics + */ + interface ProgramToEmitFilesAndReportErrors { + getCurrentDirectory(): string; + getCompilerOptions(): CompilerOptions; + getSourceFiles(): ReadonlyArray; + getSyntacticDiagnostics(): ReadonlyArray; + getOptionsDiagnostics(): ReadonlyArray; + getGlobalDiagnostics(): ReadonlyArray; + getSemanticDiagnostics(): ReadonlyArray; + getConfigFileParsingDiagnostics(): ReadonlyArray; + emit(): EmitResult; + } + type ReportEmitErrorSummary = (errorCount: number) => void; + /** + * Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options + */ + function emitFilesAndReportErrors(program: ProgramToEmitFilesAndReportErrors, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void, reportSummary?: ReportEmitErrorSummary): ExitStatus; + /** + * Creates the watch compiler host from system for config file in watch mode + */ + function createWatchCompilerHostOfConfigFile(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile; + /** + * Creates the watch compiler host from system for compiling root files and options in watch mode + */ + function createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions; +} +declare namespace ts { +>>>>>>> add support of extension preference type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void; /** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */ type CreateProgram = (rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray) => T; @@ -4811,6 +4908,7 @@ declare namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly importModuleSpecifierPreference?: "relative" | "non-relative"; readonly allowTextChangesInNewFiles?: boolean; + readonly includeExtensionInImports?: boolean; } interface LanguageService { cleanupSemanticCache(): void; @@ -7962,6 +8060,7 @@ declare namespace ts.server.protocol { readonly includeCompletionsWithInsertText?: boolean; readonly importModuleSpecifierPreference?: "relative" | "non-relative"; readonly allowTextChangesInNewFiles?: boolean; + readonly includeExtensionInImports?: boolean; } interface CompilerOptions { allowJs?: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 488f7c85a69d7..91c121a227d1b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4811,6 +4811,7 @@ declare namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly importModuleSpecifierPreference?: "relative" | "non-relative"; readonly allowTextChangesInNewFiles?: boolean; + readonly includeExtensionInImports?: boolean; } interface LanguageService { cleanupSemanticCache(): void; diff --git a/tests/cases/fourslash/importNameCodeFix_ExtensionPreference.ts b/tests/cases/fourslash/importNameCodeFix_ExtensionPreference.ts new file mode 100644 index 0000000000000..87ef25258f6ba --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_ExtensionPreference.ts @@ -0,0 +1,114 @@ +/// + +// @moduleResolution: node +// @noLib: true +// @allowJs: true +// @checkJs: true +// @jsx: preserve + +// @Filename: /a.js +////export function a() {} + +// @Filename: /b.ts +////export function b() {} + +// @Filename: /c.jsx +////export function c() {} + +// @Filename: /d.tsx +////export function d() {} + +// @Filename: /normalExt.ts +////a; +////b; +////c; +////d; + +// @Filename: /includeExt.ts +////a; +////b; +////c; +////d; + +// @Filename: /includeExt.js +////a; +////b; +////c; +////d; + + +goTo.file("/normalExt.ts"); +verify.importFixAtPosition([ + `import { a } from "./a"; + +a; +b; +c; +d;`, `import { b } from "./b"; + +a; +b; +c; +d;`, `import { c } from "./c"; + +a; +b; +c; +d;`, `import { d } from "./d"; + +a; +b; +c; +d;`]); + +goTo.file("/includeExt.ts"); +verify.importFixAtPosition([ + `import { a } from "./a.js"; + +a; +b; +c; +d;`, `import { b } from "./b.js"; + +a; +b; +c; +d;`, `import { c } from "./c.jsx"; + +a; +b; +c; +d;`, `import { d } from "./d.jsx"; + +a; +b; +c; +d;`], /* errorCode */ undefined, { + includeExtensionInImports: true + }); + +goTo.file("/includeExt.js"); +verify.importFixAtPosition([ + `import { a } from "./a.js"; + +a; +b; +c; +d;`, `import { b } from "./b.js"; + +a; +b; +c; +d;`, `import { c } from "./c.jsx"; + +a; +b; +c; +d;`, `import { d } from "./d.jsx"; + +a; +b; +c; +d;`], /* errorCode */ undefined, { + includeExtensionInImports: true + }); \ No newline at end of file From b24489f5b9de88dced7e8e9720dca89275dfe6a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E7=92=90?= Date: Wed, 4 Jul 2018 15:11:06 +0800 Subject: [PATCH 2/2] fix lint --- src/compiler/moduleSpecifiers.ts | 2 +- src/server/protocol.ts | 2 +- src/services/types.ts | 2 +- .../reference/api/tsserverlibrary.d.ts | 97 ------------------- 4 files changed, 3 insertions(+), 100 deletions(-) diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 17a5851c97d3e..625faf81b381d 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -3,7 +3,7 @@ namespace ts.moduleSpecifiers { export interface ModuleSpecifierPreferences { readonly importModuleSpecifierPreference?: "relative" | "non-relative"; - readonly includeExtensionInImports?: boolean + readonly includeExtensionInImports?: boolean; } // Note: importingSourceFile is just for usesJsExtensionOnImports diff --git a/src/server/protocol.ts b/src/server/protocol.ts index f76a527f942d5..e92cfc714dec7 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2802,7 +2802,7 @@ namespace ts.server.protocol { readonly includeCompletionsWithInsertText?: boolean; readonly importModuleSpecifierPreference?: "relative" | "non-relative"; readonly allowTextChangesInNewFiles?: boolean; - readonly includeExtensionInImports?: boolean + readonly includeExtensionInImports?: boolean; } export interface CompilerOptions { diff --git a/src/services/types.ts b/src/services/types.ts index 65d3036d63e0d..675802f7215e9 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -240,7 +240,7 @@ namespace ts { readonly includeCompletionsWithInsertText?: boolean; readonly importModuleSpecifierPreference?: "relative" | "non-relative"; readonly allowTextChangesInNewFiles?: boolean; - readonly includeExtensionInImports?: boolean + readonly includeExtensionInImports?: boolean; } /* @internal */ export const emptyOptions = {}; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 64e0b6efc6c4f..1332580c1c588 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4303,103 +4303,6 @@ declare namespace ts { function createAbstractBuilder(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; } declare namespace ts { -<<<<<<< HEAD -======= - /** This is the cache of module/typedirectives resolution that can be retained across program */ - interface ResolutionCache { - startRecordingFilesWithChangedResolutions(): void; - finishRecordingFilesWithChangedResolutions(): Path[] | undefined; - resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[]; - getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): CachedResolvedModuleWithFailedLookupLocations | undefined; - resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; - invalidateResolutionOfFile(filePath: Path): void; - removeResolutionsOfFile(filePath: Path): void; - setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map>): void; - createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution; - startCachingPerDirectoryResolution(): void; - finishCachingPerDirectoryResolution(): void; - updateTypeRootsWatch(): void; - closeTypeRootsWatch(): void; - clear(): void; - } - interface ResolutionWithFailedLookupLocations { - readonly failedLookupLocations: ReadonlyArray; - isInvalidated?: boolean; - refCount?: number; - } - interface CachedResolvedModuleWithFailedLookupLocations extends ResolvedModuleWithFailedLookupLocations, ResolutionWithFailedLookupLocations { - } - interface ResolutionCacheHost extends ModuleResolutionHost { - toPath(fileName: string): Path; - getCanonicalFileName: GetCanonicalFileName; - getCompilationSettings(): CompilerOptions; - watchDirectoryOfFailedLookupLocation(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher; - onInvalidatedResolution(): void; - watchTypeRootsDirectory(directory: string, cb: DirectoryWatcherCallback, flags: WatchDirectoryFlags): FileWatcher; - onChangedAutomaticTypeDirectiveNames(): void; - getCachedDirectoryStructureHost(): CachedDirectoryStructureHost | undefined; - projectName?: string; - getGlobalCache?(): string | undefined; - writeLog(s: string): void; - maxNumberOfFilesToIterateForInvalidation?: number; - getCurrentProgram(): Program; - } - const maxNumberOfFilesToIterateForInvalidation = 256; - function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string | undefined, logChangesWhenResolvingModule: boolean): ResolutionCache; -} -declare namespace ts.moduleSpecifiers { - interface ModuleSpecifierPreferences { - readonly importModuleSpecifierPreference?: "relative" | "non-relative"; - readonly includeExtensionInImports?: boolean; - } - function getModuleSpecifier(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: Path, toFileName: string, host: ModuleSpecifierResolutionHost, files: ReadonlyArray, preferences?: ModuleSpecifierPreferences): string; - function getModuleSpecifiers(moduleSymbol: Symbol, compilerOptions: CompilerOptions, importingSourceFile: SourceFile, host: ModuleSpecifierResolutionHost, files: ReadonlyArray, preferences: ModuleSpecifierPreferences): ReadonlyArray>; -} -declare namespace ts { - /** - * Create a function that reports error by writing to the system and handles the formating of the diagnostic - */ - function createDiagnosticReporter(system: System, pretty?: boolean): DiagnosticReporter; - /** @internal */ - const nonClearingMessageCodes: number[]; - /** @internal */ - const screenStartingMessageCodes: number[]; - /** - * Create a function that reports watch status by writing to the system and handles the formating of the diagnostic - */ - function createWatchStatusReporter(system: System, pretty?: boolean): WatchStatusReporter; - /** Parses config file using System interface */ - function parseConfigFileWithSystem(configFileName: string, optionsToExtend: CompilerOptions, system: System, reportDiagnostic: DiagnosticReporter): ParsedCommandLine | undefined; - /** - * Program structure needed to emit the files and report diagnostics - */ - interface ProgramToEmitFilesAndReportErrors { - getCurrentDirectory(): string; - getCompilerOptions(): CompilerOptions; - getSourceFiles(): ReadonlyArray; - getSyntacticDiagnostics(): ReadonlyArray; - getOptionsDiagnostics(): ReadonlyArray; - getGlobalDiagnostics(): ReadonlyArray; - getSemanticDiagnostics(): ReadonlyArray; - getConfigFileParsingDiagnostics(): ReadonlyArray; - emit(): EmitResult; - } - type ReportEmitErrorSummary = (errorCount: number) => void; - /** - * Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options - */ - function emitFilesAndReportErrors(program: ProgramToEmitFilesAndReportErrors, reportDiagnostic: DiagnosticReporter, writeFileName?: (s: string) => void, reportSummary?: ReportEmitErrorSummary): ExitStatus; - /** - * Creates the watch compiler host from system for config file in watch mode - */ - function createWatchCompilerHostOfConfigFile(configFileName: string, optionsToExtend: CompilerOptions | undefined, system: System, createProgram?: CreateProgram, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfConfigFile; - /** - * Creates the watch compiler host from system for compiling root files and options in watch mode - */ - function createWatchCompilerHostOfFilesAndCompilerOptions(rootFiles: string[], options: CompilerOptions, system: System, createProgram?: CreateProgram, reportDiagnostic?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter): WatchCompilerHostOfFilesAndCompilerOptions; -} -declare namespace ts { ->>>>>>> add support of extension preference type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void; /** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */ type CreateProgram = (rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray) => T;