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

fix(lsp): move sloppy import resolution from loader to resolver #23751

Merged
merged 8 commits into from
May 9, 2024

Conversation

nathanwhit
Copy link
Member

@nathanwhit nathanwhit commented May 8, 2024

Fixes #23745
Fixes #23197

Moves sloppy import resolution from the loader to the resolver.

Also adds some test helper functions to make the lsp tests less verbose

@nathanwhit nathanwhit requested a review from dsherret May 8, 2024 23:29
Copy link
Member

@dsherret dsherret May 8, 2024

Choose a reason for hiding this comment

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

Before this PR -> ./foo.js resolves to ./foo.d.ts
After this PR ->./foo.js resolves to ./foo.js

This will cause typescript to resolve the incorrect file I think? Sloppy imports is informed by the provided ResolutionMode that will resolve .d.ts for ResolutionMode::Types and .js for ResolutionMode::Execution. Probably we need to surface that up to a higher level instead of only always doing ResolutionMode::Types (see in resolve_unstable_sloppy_import).

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm my thinking was that this matches the behavior without sloppy imports enabled. Without sloppy imports we don't resolve foo.js to foo.d.ts, since we don't actually do any special resolution for file specifiers. So it seems inconsistent to change that behavior for an import that isn't actually sloppy

Copy link
Member

Choose a reason for hiding this comment

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

Yeah it's different than Deno's default resolution. For sloppy imports it does TypeScript's Node resolution behaviour where it prefers .d.ts files when resolving the types, but .js files when executing the code.

Copy link
Member

@dsherret dsherret May 9, 2024

Choose a reason for hiding this comment

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

This actually might be a bug/design issue elsewhere as well. This is a fully resolved specifier so it's strange sloppy import resolution is happening here (in resolve_specifier). Probably it should only happen when resolving import specifiers (ex. code with (specifier: &str, base: &Url) params)

Copy link
Member

Choose a reason for hiding this comment

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

I did a commit that moves the sloppy import resolution from the loader to the resolver. This should fix the issue if you try it out now (and resolve to the .d.ts file).

This also seems to fix #23197 for me.

@dsherret dsherret changed the title fix(lsp): Prefer the original specifier when using sloppy imports fix(lsp): move sloppy import resolution from loader to resolver May 9, 2024
&self,
// this really only needs a HashSet<ModuleSpecifier>, but it's provided
// the entire HashMap to avoid cloning all the time
open_docs: &'a HashMap<ModuleSpecifier, Arc<Document>>,
Copy link
Member

Choose a reason for hiding this comment

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

This is only necessary for sloppy import resolution. It's slightly unfortunate to have to have to pass it around, but I'm not sure a better way because we're mutating the Documents while calling this sometimes and sloppy import resolution needs to know about files that may only exist in memory.

@@ -12106,7 +12049,7 @@ fn lsp_deno_future_env_byonm() {
}

#[test]
fn lsp_sloppy_imports_warn() {
Copy link
Member

Choose a reason for hiding this comment

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

I removed the warning. It's not worth maintaining because it's a lot of work to add when this is done from the resolver. We can add this back as a lint rule later (see #22844 (comment))

@dsherret dsherret requested a review from nayeemrmn May 9, 2024 02:42
Ok(
SloppyImportsResolver::resolve_with_stat_sync(
&specifier,
mode,
Copy link
Member

Choose a reason for hiding this comment

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

See here how this now properly handles the mode for resolution.

cli/lsp/resolver.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@nayeemrmn nayeemrmn left a comment

Choose a reason for hiding this comment

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

LGTM

&'a self,
// this really only needs a HashSet<ModuleSpecifier>, but it's provided
// the entire HashMap to avoid cloning all the time
open_docs: &'b HashMap<ModuleSpecifier, Arc<Document>>,
Copy link
Member

Choose a reason for hiding this comment

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

Was thinking about this more this morning and realized that we should just not bother passing the open documents here. In places like vscode, the file will always exist on the file system if it's open (unlike our test server), so we can just consult that for simplicity.

@dsherret dsherret enabled auto-merge (squash) May 9, 2024 13:47
} else {
None
}
})
Copy link
Member

Choose a reason for hiding this comment

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

One thing we're going to have to do (and this is an existing bug) is recreate the resolved resolutions when a file is deleted or created, but that's a problem for a different day.

@dsherret dsherret merged commit dc29986 into denoland:main May 9, 2024
17 checks passed
dsherret added a commit that referenced this pull request May 10, 2024
Moves sloppy import resolution from the loader to the resolver.

Also adds some test helper functions to make the lsp tests less verbose

---------

Co-authored-by: David Sherret <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants