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

Have module resolution be independend of --allowJs and --jsx flags #11704

Merged
8 commits merged into from
Oct 27, 2016

Conversation

ghost
Copy link

@ghost ghost commented Oct 18, 2016

…and don't have moduleNameResolver responsible for omitting files based on compiler options.

This PR has relatively little observable effect, but gives some better error messages if a module would have been resolved to a tsx file but you forgot the "--jsx" flag.

The API should be backwards compatible as the new ResolvedModule data structure still contains the resolvedFileName field, and we have a method convertResolvedModuleFromHost which adds the new resolvedTsFileName and resolvedJsFileName properties if necessary.

This also technically causes breaking change in the module resolution. Previously we would ignore ".tsx" files without "--jsx", but now we will resolve to that module and report an error in the checker.

Also, the secondary lookup in resolvedTypeReferenceDirective now only looks for .d.ts files, as the documentation on ResolvedTypeReferenceDirective seems to indicate that that's all we should be returning. I'm also wondering if loadModuleFromNodeModulesWorker should do the same when searching through @types, and same for loadModuleFromNodeModulesAtTypes.

I will redo #11446 after this is in.

@vladima brought up the point that we might want to consider getting rid of shims. That won't be necessary for this PR, as I haven't changed the resolvedModuleName method of CoreServicesShimObject. This method is public on the class, but the class isn't exported and is only used as an implementation of the CoreServicesShim interface, which doesn't define that method. Pinging @mhegazy too.

…moduleNameResolver responsible for omitting files based on compiler options
@ghost ghost assigned vladima Oct 18, 2016
@ghost ghost assigned mhegazy Oct 18, 2016
* - be a .d.ts file
* - use top level imports\exports
* - don't use tripleslash references
*/
isExternalLibraryImport?: boolean;
isExternalLibraryImport: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should stay optional. otherwise we break other API

* in which case they will be inferred from the file extension.
* Prefer to return a full ResolvedModule.
*/
export type ResolvedModuleFromHost = { resolvedFileName: string; isExternalLibraryImport: boolean } | ResolvedModule;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i do not understand why we need this. the two new properties are optional, and we have logic to handle them being missing. so do not see the value here.

return undefined;
}
// `resolvedTsFileName` and `resolvedJsFileName` should be present as properties even if undefined.
else if ("resolvedTsFileName" in resolved) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mm. do you really need that check? can we check when we create them instead?

* Extracts the file name from a ResolvedModule, or returns a DiagnosticMessage if we are not set up to use that kind of file.
* The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to.
*/
export function getResolutionOrDiagnostic(options: CompilerOptions, { resolvedTsFileName: ts, resolvedJsFileName: js }: ResolvedModule): string | { file: string, diag: DiagnosticMessage } {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit. i would rather we just use module.resolvedTsFileName || module.resolvedJsFileName for the module, and have this function just to report errors. this avoids the complexity of checking if the return type is string or not.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 18, 2016

@vladima can you take a look.

Andy Hanson added 3 commits October 18, 2016 14:22
… avoid using resolution.resolvedFileName if the diagnostic is defined.
…e` and `resolvedJsFileName` optional properties

(but still automatically infer one of them to supply if the host supplied neither)
/* @internal */
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage): void {
function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why removing @internal?


/** LsHost uses a global cache of automatically-installed typings to help it resolve modules. */
/* @internal */
export function resolveModuleNameForLsHost(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, globalCache: string | undefined, projectName: string): ResolvedModuleWithFailedLookupLocations {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don' think this function should be here given that this file is part of core compiler bits and LSHost is specific to server

resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile);
resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile).map(resolved => {
// An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
if (!resolved || resolved.extension) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extenstion.TS is Zero so this will fail. probably want to check for undefined here.

/*
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be proper external module:
/** Extension of resolvedFileName. This must match what's at the end of resolvedFileName. */
extension: Extension;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is optional we will need fallback logic on every access. I thought it was easier to just perform the conversion when getting it from an external source. This would mean that older clients won't compile against the new compiler, but will still run.
We might choose to not have this property as it is techincally redundant, but it's neater to have this property and use switch statements than to use if (fileExtensionIs(resolved.resolvedFileName, ".ts")) { ... } else if (fileExtensionIs(resolved.resolvedFileName, ".tsx")) { ... } all over.

Copy link
Contributor

@mhegazy mhegazy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a couple of API comments

@ghost ghost merged commit b5ba315 into master Oct 27, 2016
@ghost ghost deleted the refactor_module_resolution branch October 27, 2016 13:03
@ghost ghost changed the title Return both ts and js results from module resolution Have module resolution be independend of --allowJs and --jsx flags Oct 27, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
This pull request was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants