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

Link detection for the exception widget and debug console #24451

Merged
merged 13 commits into from
May 8, 2017
Merged

Link detection for the exception widget and debug console #24451

merged 13 commits into from
May 8, 2017

Conversation

michelkaporin
Copy link
Contributor

  1. Extracted link detection to a separate common class, shared and reused between REPL viewer and exception widget.
  2. Updated link detection to handle multiple links in a provided string.
  3. Added link validation to resolve only files which are part of file system.

Partially reused regex of the reverted PR by @felixfbecker, credits to you!

image
image

Fixes #15760, #17085 (and all its ancestors).
Partially implements #21349.

@mention-bot
Copy link

@michelkaporin, thanks for your PR! By analyzing the history of the files in this pull request, we identified @egamma and @bpasero to be potential reviewers.

@felixfbecker
Copy link
Contributor

felixfbecker commented Apr 10, 2017

Awesome! Did you test this with stack traces printed by mocha (relative paths)?

@michelkaporin
Copy link
Contributor Author

michelkaporin commented Apr 10, 2017

@felixfbecker Thank you :) I did not explicitly test mocha but those mocha stack traces described in #15760 should be picked up now (see the the sample image above which is a super set of what was outputted there).

The things that won't work currently:

  1. If file is coming from e.g. <node internals> or does not exist on file system, it won't be anchored.
  2. http:// links still not supported.
  3. If the path to the file defined without the column, it won't be recognised.

I plan to tackle those things in a separate issues.

@felixfbecker
Copy link
Contributor

I don't see this explicitely in the image above, will it work for relative paths that do not take up a whole line? Eg

  at myfunc (src/myfunc.ts:1:0)

right now that only highlights /myfunc.ts:1:0 like it was an absolute path

@michelkaporin
Copy link
Contributor Author

@felixfbecker yes, it will work for relative paths that do not take up a whole line. src/myfunc.ts:1:0 would be highlighted in your example.

image

@isidorn
Copy link
Contributor

isidorn commented Apr 13, 2017

@michelkaporin I appologize for the slow response was busy around the release.

Just checked the PR, looks great!
I really like that you are reusing the logic between the repl and the exceptionWidget.

After discussing with @bpasero we agreed that doing a FS stat to figure out if something is a relative link is too heavy for a simple operation like this.

How precise would the relative path mathching be if you can not verify it against the real file system? If not very precise then we should not support relative file matching.
But all in all we need to drop the dependency to 'fs' in the linkDetector

@felixfbecker
Copy link
Contributor

I think it should be doable to detect relative links without a stat. If spaces in paths are not to be supported, it's trivial. Otherwise you would need to have to look at common seperators like parenthesis. But please please keep relative link detection, I need to click on these >100 times a day in stack traces.

@michelkaporin
Copy link
Contributor Author

@isidorn Ok, I can drop link validation and try to match it with regex then.
However, current terminal implementation is also doing fs.stat to validate the links in the terminal. If we plan to reuse link detection code between terminal, debug console and exception widget, then we will have to drop fs.stat for terminal as well.

@isidorn
Copy link
Contributor

isidorn commented Apr 13, 2017

Thanks for letting me know, we should also not use fs.stat for link detection in the terminal.
fyi @Tyriar

@Tyriar
Copy link
Member

Tyriar commented Apr 17, 2017

@michelkaporin @isidorn @bpasero I disagree that we shouldn't stat the files. Without fs.stat there are a heap of false positives. A lot of stuff in the terminal is formed like a path, especially if we want to linkify files in the output of ls. Note that the terminal does not linkify all output, it happens 200ms after the viewport has not changed, so it will stat as many links that are matched in the viewport (typically 10-20 lines) at most every 200ms.

Related:

@bpasero
Copy link
Member

bpasero commented Apr 18, 2017

Stating things we "think" are links is crazy to put it in simple words (keep in mind that people work in environments with network drives where a stat might not be as fast as on your SSD disk). Since output is unbounded this could easily cause tons of disk access for no helpful reason. A link should be detected without going to disk and it is totally fine to have false positives (e.g. it is OK to not be 100% correct). Once the user clicks on a link, it is fine to show an error if the file does not exist.

@Tyriar
Copy link
Member

Tyriar commented Apr 18, 2017

@bpasero to be more specific the terminal stuff is using pfs so it's not a blocking call or anything. Also for the terminal it is bounded as only the current viewport is checked for links.

Is it so bad to check the existence of a handful of paths after a terminal command is run (or when the user scrolls the terminal)?

@bpasero
Copy link
Member

bpasero commented Apr 19, 2017

I would not do it, the output panel has never done it. There are tons of regexes that try to detect links and render them optimistically. What is wrong with that approach?

@Tyriar
Copy link
Member

Tyriar commented Apr 19, 2017

Tracking stat in terminal links in #25024

@michelkaporin michelkaporin modified the milestones: May 2017, April 2017 Apr 25, 2017
@michelkaporin
Copy link
Contributor Author

@isidorn I have updated regex to be more precise without fs.stat validation. We get higher false positive rate now without it, although it is more efficient.

Exception widget is an example of high false positive rate with file names coming from debug adapter, that are detected by regex as workspace' relative links, whereas they are not, in reality. On the good side the user will get an 'Unable to open' message, when clicking on such links.

// group 3: line number
// group 4: column number
// eg: at Context.<anonymous> (c:\Users\someone\Desktop\mocha-runner\test\test.js:26:11)
/(?![\(])(?:file:\/\/)?((?:([a-zA-Z]+:)|[^\(\)<>\'\"\[\]:\s]+)(?:[\\/][^\(\)<>\'\"\[\]:]*)?\.[a-zA-Z]+[0-9]*):(\d+)(?::(\d+))?/g
Copy link
Contributor

Choose a reason for hiding this comment

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

I notice that the comments are the same but the regex is now more complicated.
Could you please add some comments in code to clarify this regex beast

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@isidorn I've added more comments, hope it makes things more clear. It is quite big just because it tries not to match lots of special characters. In the end we still plan to move away from it to the common regex between terminal, debug console and exception widget.

// noop
}

public handleLinks(text: string): HTMLElement | string {
Copy link
Contributor

Choose a reason for hiding this comment

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

As far as I understand there have been no changes till the end of this file, it has just been moved over.
If that is the case it looks good to me

Copy link
Contributor Author

@michelkaporin michelkaporin May 5, 2017

Choose a reason for hiding this comment

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

@isidorn It was changed to handle multiple links in the provided string. Previously it used to detect only first link match and then stopped.

) {
// noop
}

Copy link
Contributor

@isidorn isidorn May 5, 2017

Choose a reason for hiding this comment

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

Since this handleLinks is now a public method we could try to make the API a bit nicer, a personally find it ugly that it returns an HTMLElement or a string. It is hard to figure out what to expect as a return result for someobdy who just wants to use the link detector.
At least provide some comments to clarify each case, or try to always return an object with the corresponding fields.

For ideas you can also check what does the terminal / editor link detector do and how does their API look like

Copy link
Contributor Author

@michelkaporin michelkaporin May 5, 2017

Choose a reason for hiding this comment

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

@isidorn I've added the comment to it. I hope this explains it well.

If you have any suggestions on what should be a return result instead, I am happy to hear. Currently it perfectly suits exception widget and debug console needs.

@@ -27,6 +27,11 @@
margin-top: 0.5em;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense

@@ -7,13 +7,10 @@ import * as nls from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks good overall and I like we removed code from this class.

I only have the issue that you are creating a linkDetector at every iteration in a loop. Would it not make sense just to create one global one for the replViewer and always to reuse it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@isidorn You're right, did not see that for-loop when refactored. I've moved LinkDetector instantiation to the constructor.

@@ -11,9 +11,11 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
Copy link
Contributor

Choose a reason for hiding this comment

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

looks good

@isidorn
Copy link
Contributor

isidorn commented May 5, 2017

@michelkaporin great work. I have added some comments directly in the code. Once you adrress them we can merge it in.
I see that the builds are failing, is everything ok when you build it localy?

@michelkaporin
Copy link
Contributor Author

@isidorn thank you! I've addressed all your comments, please see my replies. The build is passing locally, AppVeyour succeeds also on the latest codebase. Cannot find any build issues in the Travis log that are to do with my changes.

@isidorn
Copy link
Contributor

isidorn commented May 8, 2017

@michelkaporin looks good, let's merge it in to see how it behaves :)
@michelkaporin make sure all the issues that are fixed by this are closed and have a bug label - so we verify them in the endgame

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.

DEbug console link detection
7 participants