Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exposing canonical filename logic #37772

Open
5 tasks done
HoldYourWaffle opened this issue Apr 3, 2020 · 3 comments
Open
5 tasks done

Exposing canonical filename logic #37772

HoldYourWaffle opened this issue Apr 3, 2020 · 3 comments
Labels
API Relates to the public API for TypeScript

Comments

@HoldYourWaffle
Copy link
Contributor

Search Terms

canonical filename

Suggestion

I'd like to re-use the get-canonical-filename logic:

export type GetCanonicalFileName = (fileName: string) => string;
export function createGetCanonicalFileName(useCaseSensitiveFileNames: boolean): GetCanonicalFileName {
return useCaseSensitiveFileNames ? identity : toFileNameLowerCase;
}

Use Cases

I want to use ts.resolveModuleName and the accompanying ts.createModuleResolutionCache to resolve ImportDeclarations (as per this comment's suggestion).
createModuleResolutionCache requires a parameter getCanonicalFileName. I think it makes the most sense to use the same logic as the compiler itself here, which is the function I linked above.

I could just copy-and-paste this function, but that feels wrong and might lead to discrepancies in the future if toFileNameLowerCase (which is not exposed either) is ever updated.

Examples

const cache = ts.createModuleResolutionCache(currentDirectory, ts.createGetCanonicalFileName(true/false));
const resolved = ts.resolveModuleName(name, file, compilerOptions, host, cache);

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@sheetalkamat
Copy link
Member

Instead of exposing createGetCanonicalFileName we need to make createModuleResolutionCache accept caseSensitive as well.

@sheetalkamat sheetalkamat added the API Relates to the public API for TypeScript label Apr 3, 2020
@HoldYourWaffle
Copy link
Contributor Author

Yeah, that probably makes more sense. I assume I'd be able to use compilerHost.useCaseSensitiveFileNames to get the appropriate value?

@HoldYourWaffle
Copy link
Contributor Author

I just noticed that CompilerHost provides access to a getCanonicalFileName method:

TypeScript/lib/typescript.d.ts

Lines 2926 to 2934 in f31b5a2

export interface CompilerHost extends ModuleResolutionHost {
getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined;
getSourceFileByPath?(fileName: string, path: Path, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined;
getCancellationToken?(): CancellationToken;
getDefaultLibFileName(options: CompilerOptions): string;
getDefaultLibLocation?(): string;
writeFile: WriteFileCallback;
getCurrentDirectory(): string;
getCanonicalFileName(fileName: string): string;

A workaround for my specific usecase could thus be:

const host = ts.createCompilerHost(compilerOptions); //ugly, but necessary when using the transformer API (#37754)
const cache = ts.createModuleResolutionCache(currentDirectory, host.getCanonicalFileName, compilerOptions);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API Relates to the public API for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants