The Wayback Machine - https://web.archive.org/web/20210525151804/https://github.com/microsoft/TypeScript/pull/42539
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

Support go-to-definition for imports of arbitrary files #42539

Merged
merged 10 commits into from Mar 1, 2021

Conversation

@andrewbranch
Copy link
Member

@andrewbranch andrewbranch commented Jan 28, 2021

Fixes #41861

The first commit adds support for jumping to arbitrary files from import/require module specifiers, whether those are scripts or non-source files like CSS (thanks @DanielRosenwasser for the idea that this should work).

The second commit goes further by allowing us to return a successful response for files that don’t exist. I was curious what would happen, so I removed the host.fileExists check and made sure we don’t try to read a file’s text to convert { position: 0 } to { line: 0, column: 0 }. The result in VS Code was this:

File does not exist, do you want to create it?

Having the quick option to create the file seemed like a win to me; better than doing nothing. But I’m open to debate on whether we want that.

Also, if anyone knows how this will work in Visual Studio or has a quick way to test it, that would be appreciated!

@DanielRosenwasser
Copy link
Member

@DanielRosenwasser DanielRosenwasser commented Jan 28, 2021

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

@typescript-bot typescript-bot commented Jan 28, 2021

Heya @DanielRosenwasser, I've started to run the tarball bundle task on this PR at 5f256f1. You can monitor the build here.

@DanielRosenwasser
Copy link
Member

@DanielRosenwasser DanielRosenwasser commented Jan 28, 2021

Heads up @mjbvz and @minestarks.

@DanielRosenwasser
Copy link
Member

@DanielRosenwasser DanielRosenwasser commented Jan 28, 2021

How does this work with partial semantic mode (including in the browser)?

What will happen if we try go-to-definition on thing or the module specifier in this example?

import { thing } from "./vandelay.js"/*1*/;

thing/*2*/();
@typescript-bot
Copy link
Collaborator

@typescript-bot typescript-bot commented Jan 28, 2021

Hey @DanielRosenwasser, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/94419/artifacts?artifactName=tgz&fileId=5DF50A9CF42BC37629C1481AFE23876083889D0471511DD2357A7CB0CDC5F1A602&fileName=/typescript-4.2.0-insiders.20210128.tgz"
    }
}

and then running npm install.


There is also a playground for this build and an npm module you can use via "typescript": "npm:@typescript-deploys/[email protected]".;

@andrewbranch
Copy link
Member Author

@andrewbranch andrewbranch commented Jan 28, 2021

What will happen if we try go-to-definition on thing

Whatever the current behavior for go-to-definition on the identifier reference, that will be unchanged.

or the module specifier

Don’t we already resolve one level of direct imports from your current source file? That should be unchanged as well. If we don’t, we would return a response saying the definition is at position 0 of ./thing.js, resolved relative to whatever we said the path of the current source file is. If we were to re-add the host.fileExists check and we haven’t already successfully resolved and loaded ./thing.js for normal module resolution reasons, we would not offer a definition there.

@DanielRosenwasser
Copy link
Member

@DanielRosenwasser DanielRosenwasser commented Jan 28, 2021

I mostly ask because #39037 is a related issue I've been interested in unlocking as well, but I get why this doesn't automatically unlock that.

@sandersn
Copy link
Member

@sandersn sandersn commented Jan 28, 2021

Answering a question that nobody has asked, I tested this with emacs. This gives a picture of how a simply written language plugin will behave and is usually similar to how VS works too.

Everything works fine. For the non-existent file, the editor raises an error inside tide-get-file-buffer and since the error's not handled, it's displayed to the user. That's a fine user experience, and I would be surprised if it's worse in other editors.

@andrewbranch
Copy link
Member Author

@andrewbranch andrewbranch commented Feb 1, 2021

we dont resolve imports currently in partial semantic mode, so adding a test that it works for that would be good too

@sheetalkamat I’m looking at adding a case in partialSemanticServer.ts now (just pushed a new commit), and it seems imports are resolved... the source file’s resolvedModules contains correct resolutions.

If we hadn’t resolved them, this case would be a problem, because the module specifier is extensionless. Without doing at least some basic module resolution, we wouldn’t know that the target file has a .ts extension. I guess in that situation, we would either want to turn this feature off or potentially do real module resolution on-demand. But at the moment it seems that module resolution did already happen so it’s not a problem.

@sheetalkamat
Copy link
Member

@sheetalkamat sheetalkamat commented Feb 1, 2021

@andrewbranch interesting.. till you pointed out, I didn't realize we were doing module resolution as part of noResolve. PR #4368 added this. Not sure if this additional cost is really what we want with partial semantic server or not but that can be handled separately.

@andrewbranch
Copy link
Member Author

@andrewbranch andrewbranch commented Feb 1, 2021

In that case, this feature currently works exactly the same for partial semantic mode as full semantic mode, and the new test will ensure that we don’t break it if we change partial semantic mode later.

@andrewbranch andrewbranch force-pushed the andrewbranch:bug/41861 branch from 2c49160 to f6d3b18 Feb 1, 2021
@andrewbranch andrewbranch requested a review from sheetalkamat Feb 2, 2021
@sandersn sandersn added this to Not started in PR Backlog Feb 8, 2021
@andrewbranch
Copy link
Member Author

@andrewbranch andrewbranch commented Feb 16, 2021

New changes:

  1. Whenever the file reference lookup does not yield an actual source file (this could be because the file doesn’t exist, or because it’s a file type like CSS that the compiler doesn’t care about), a new unverified: true property is added to the definition in the response. VS Code could use this to show a less-error-y prompt to create a new file if it finds that the file doesn’t exist.

  2. Whenever (1) happens, instead of immediately returning that speculative file result, we continue other methods of definition lookup and combine the results. This specifically allows us to return two definitions for pattern ambient module matches: one for the actual file referenced, and one for the ambient module declaration. Screen cap:

    Go to definition on index.css returns a result for the CSS file and for a "*.css" pattern ambient module declaration

    Notes: I’m not sure why the second definition is expanded by default instead of the first. Possibly because the first has a zero-length definition span? Also, the underlining on only part of the path seems to be unrelated to TypeScript’s response (the span we send there is the whole module specifier, quotes included).

@andrewbranch andrewbranch requested a review from sheetalkamat Feb 16, 2021
PR Backlog automation moved this from Not started to Needs merge Feb 25, 2021
PR Backlog automation moved this from Needs merge to Waiting on author Feb 25, 2021
src/services/goToDefinition.ts Outdated Show resolved Hide resolved
…urce file has that path
@andrewbranch andrewbranch requested a review from sheetalkamat Feb 26, 2021
PR Backlog automation moved this from Waiting on author to Needs merge Mar 1, 2021
@andrewbranch andrewbranch merged commit 4b67b4a into microsoft:master Mar 1, 2021
9 checks passed
9 checks passed
@github-actions
build (10.x)
Details
@github-actions
CodeQL-Build CodeQL-Build
Details
@github-actions
build (12.x)
Details
@github-actions
build (14.x)
Details
@github-code-scanning
CodeQL No new or fixed alerts
Details
@microsoft-cla
license/cla All CLA requirements met.
Details
@azure-pipelines
node10 Build #97285 succeeded
Details
@azure-pipelines
node12 Build #97283 succeeded
Details
@azure-pipelines
node14 Build #97284 succeeded
Details
PR Backlog automation moved this from Needs merge to Done Mar 1, 2021
end: node.getEnd(),
fileName: node.text
},
unverified: !!verifiedFileName,

This comment has been minimized.

@sheetalkamat

sheetalkamat Apr 1, 2021
Member

@andrewbranch just realised that we are not passing this on in the through server even though we added this property to protocol.
tsserver37220.log

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
PR Backlog
  
Done
Linked issues

Successfully merging this pull request may close these issues.

6 participants