Skip to content

TSServer import path autocomplete reads incorrect directories when a file is not a direct child of a root directory #55232

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

Closed
PhoebeSzmucer opened this issue Aug 1, 2023 · 0 comments · Fixed by #55233
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@PhoebeSzmucer
Copy link
Contributor

Bug Report

My project has the following (simplified) structure:

app/
  build/
    dts/
      a.d.ts
      a.graphql.d.ts # Codegened from a.graphql
      tmp/
        b.d.ts
        b.graphql.d.ts # Codegened from b.graphql
  src/
    a.ts
    a.graphql
    tmp/
      b.ts
      b.graphql

where rootDirs is configured to read from both src/ and build/dts. In other words, I'm codegening some extra .d.ts files during build time which I can then import in my typescript code.

When tsserver computes autocomplete for an import path in the a.ts file, it correctly returns the relevant files:

Screenshot 2023-08-01 at 21 41 06

However, when this is done inside of a directory (in this example one called tmp/, but this works in general), tsserver reads the /tmp system directory instead of the src/tmp folder:

Screenshot 2023-08-01 at 21 44 57

TSServer is still searching the current script directory (in this case src/tmp), but instead of searching build/dts/tmp it then also searches /tmp. This is probably why this bug went unnoticed for such a long time - it mostly affects imports of "extra files" that are not in source already.

I traced this behaviour to the following code:

containsPath(rootDirectory, scriptDirectory, basePath, ignoreCase) ? scriptDirectory.substr(rootDirectory.length) : undefined)!; // TODO: GH#18217

If scriptDirectory is the same as rootDirectory, relativeDirectory is computed to "", and relativeDirectory is correctly appended to the root directories. This results in TSServer correctly searching both src/ and build/dst.

However, if scriptDirectory (in our example /Volumes/git/app/src/tmp) is a child of rootDirectory (/Volumes/git/app/src), this line will result in relativeDirectory being /tmp instead of /tmp, causing combinePaths a few lines down to output /tmp. This results in TSServer incorrectly searching src/tmp and /tmp (instead of build/dts/tmp). This is effectively an off-by-one error because we're accidentally grabbing a leading slash.

🔎 Search Terms

tsserver, getPathCompletionsAtPosition, import path, rootDirs

🕗 Version & Regression Information

As far as I can tell from the code this bug has always existed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants