-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Initial implementation of nimsuggest v3 #19826
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
Conversation
d600c53
to
13e514d
Compare
nimsuggest/nimsuggest.nim
Outdated
suggestResult(graph.config, sug) | ||
of ideGlobalSymbols: | ||
var counter = 0 | ||
let reg = re(string(file)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a need for this to be a regex? Can't it be done with contains (in
) or something similar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code below seems to do find(cstring(sym.name.s), reg, 0, sym.name.s.len)
, you can instead just use https://nim-lang.org/docs/strutils.html#find%2Cstring%2Cstring%2CNatural%2Cint to get the position of the first match
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is my personal preference. It will be pretty much up to us to decide whether to run with regex
or with startsWith
or with in
. If we talk about other language servers some of them are using glob, and some of them use startsWith
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyoncho the problem is that it affects more than just personal preference - Nim's re
library depends on PCRE, so if you make nimsuggest depend on re, users will have to make sure they have pcre installed. In a simple case like this I really think you should just use strutils.find.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yyoncho the problem is that it affects more than just personal preference
Of course - I am just saying why I picked this implementation. Using find
should be good enough for the initial implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Yardanico changed to contains. I was wondering whether to downcase before matching but I guess it might lead to too many matches.
13e514d
to
b89a3eb
Compare
cfa4ede
to
25558fc
Compare
Friendly ping. |
nimsuggest/nimsuggest.nim
Outdated
import strformat | ||
import tables | ||
import std/sha1 | ||
import segfaults |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is import segfaults
required? Remove this, don't continue after segfaults, fix segfaults properly as they arise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea here is to catch segfaults as part of incremental recompilation and then do a clean compilation. In some of the future commits I will change to code to send the notification to the client about that failure to make sure that these crashes are not lost and after that properly fixed. Note that in any other case the uncaught exception will trigger that same behavior - the application will exit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To elaborate a bit more - I am trying to make nimsuggest more crash resilient to eliminate the need for having an external process wrapper(i. e. nimlangserver
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am also planning to replace quit
calls in the compiler with throw exception (in case nimsuggest
) to make crashes less likely. Please share your thoughts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The compiler keeps a tremendous amount of state around. This is pretty bad already and not easily fixed. If you continue after a bug the state becomes "corrupt", not necessarily in the sense that it causes a crash. A crash can easily be detected by nimlangserver or the like and the service can be restarted. If you instead make crashes disappear and at the same time nimsuggest produces wrong output, missing output etc then it becomes less trustworthy. It's not a good idea, Erlang's "let it crash" philosophy is the right idea and it relies on process isolation.
Process isolation is crucial for reliability. What we can do is to make nimsuggest a supervisor process like nimlangserver so that editor support does not have to reimplement the supervisor logic. Nimsuggest would then call something like a nimsuggest_worker process.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A crash can easily be detected by nimlangserver or the like and the service can be restarted.
I had that same conversation with @zah - the problem here is that there is no easy way to detect where the crash comes from - if the crash comes from something else and nimlangserver restarts nimsuggest then the result might be a loop.
The process isolation is crucial for reliability. What we can do is to make nimsuggest a supervisor process like nimlangserver so that editor support does not have to reimplement the supervisor logic. Nimsuggest would then call something like a nimsuggest_worker process.
Isn't throwing away ModuleGraph equivalent to starting a clean process? My understanding is that there is no state outside of ModuleGraph. Or you have other concerns? FWIW I have tried to emulate creating "fresh" module graph in initModuleGraphFields
which will be called after recompile crashes. If we remove segfaults
then we should remove the catch block here: https://github.com/yyoncho/Nim/blob/nimsuggest-version-3/nimsuggest/nimsuggest.nim#L707 because it no longer makes sense if the strategy is let it crash
. The java language server has a similar strategy in a slightly different context - it performs incremental builds as you type but in addition it has a command Clean build
which is for the cases when the server context breaks up.
If you don't buy these arguments what do you think about having this behavior behind a build flag?
PS: I see this code evolving and this "patch" is something that will go away once we address more and more recompilaton-related bugs. I have identified a few but I wanted to come up with something as usable as possible and then focus on fixing them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
throw exception
generally, in a compiler api built for tooling, exceptions are not the way to go in many / most cases - instead you want to collect errors along the way without aborting the process, meaning that you pass in some collector - if we're removing quit
and the like, this is likely a better way to go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arnetheduck afaics that is what is happening in practice, it is just that when the collected error kind is in fatalMsgs
it quits (https://github.com/yyoncho/Nim/blob/nimsuggest-version-3/compiler/lineinfos.nim#L214 ). So it is either throw an exception or let it continue. I guess for nimsuggest both should be good enough as long as it does not crash the process.
Apart from the |
So I removed the |
Rework `nimsuggest` to use caching to make usage of ide commands more efficient. Previously, all commands no matter what the state of the process is were causing clean build. In the context of Language Server Protocol(LSP) and lsp clients this was causing perf issues and overall instability. Overall, the goal of v3 is to fit to LSP Server needs - added two new commands: - `recompile` to do clean compilation - `changed` which can be used by the IDEs to notify that a particular file has been changed. The later can be utilized when using LSP file watches. - `globalSymbols` - searching global references - added `segfaults` dependency to allow fallback to clean build when incremental fails. I wish the error to be propagated to the client so we can work on fixing the incremental build failures (typically hitting pointer) - more efficient rebuild flow. ATM incremental rebuild is triggered when the command needs that(i. e. it is global) while the commands that work on the current source rebuild only it Things missing in this PR: - Documentation - Extensive unit testing. Although functional I still see this more as a POC that this approach can work. Next steps: - Implement `sug` request. - Rework/extend the protocol to allow better client/server communication. Ideally we will need push events, diagnostics should be restructored to allow per file notifications, etc. - implement v3 test suite. - better logging
fe3154c
to
97f22b9
Compare
* Initial implementation of nimsuggest v3 Rework `nimsuggest` to use caching to make usage of ide commands more efficient. Previously, all commands no matter what the state of the process is were causing clean build. In the context of Language Server Protocol(LSP) and lsp clients this was causing perf issues and overall instability. Overall, the goal of v3 is to fit to LSP Server needs - added two new commands: - `recompile` to do clean compilation - `changed` which can be used by the IDEs to notify that a particular file has been changed. The later can be utilized when using LSP file watches. - `globalSymbols` - searching global references - added `segfaults` dependency to allow fallback to clean build when incremental fails. I wish the error to be propagated to the client so we can work on fixing the incremental build failures (typically hitting pointer) - more efficient rebuild flow. ATM incremental rebuild is triggered when the command needs that(i. e. it is global) while the commands that work on the current source rebuild only it Things missing in this PR: - Documentation - Extensive unit testing. Although functional I still see this more as a POC that this approach can work. Next steps: - Implement `sug` request. - Rework/extend the protocol to allow better client/server communication. Ideally we will need push events, diagnostics should be restructored to allow per file notifications, etc. - implement v3 test suite. - better logging * Add tests for v3 and implement ideSug * Remove typeInstCache/procInstCache cleanup * Add ideChkFile command * Avoid contains call when adding symbol info * Remove log * Remove segfaults
* Initial implementation of nimsuggest v3 (#19826) * Initial implementation of nimsuggest v3 Rework `nimsuggest` to use caching to make usage of ide commands more efficient. Previously, all commands no matter what the state of the process is were causing clean build. In the context of Language Server Protocol(LSP) and lsp clients this was causing perf issues and overall instability. Overall, the goal of v3 is to fit to LSP Server needs - added two new commands: - `recompile` to do clean compilation - `changed` which can be used by the IDEs to notify that a particular file has been changed. The later can be utilized when using LSP file watches. - `globalSymbols` - searching global references - added `segfaults` dependency to allow fallback to clean build when incremental fails. I wish the error to be propagated to the client so we can work on fixing the incremental build failures (typically hitting pointer) - more efficient rebuild flow. ATM incremental rebuild is triggered when the command needs that(i. e. it is global) while the commands that work on the current source rebuild only it Things missing in this PR: - Documentation - Extensive unit testing. Although functional I still see this more as a POC that this approach can work. Next steps: - Implement `sug` request. - Rework/extend the protocol to allow better client/server communication. Ideally we will need push events, diagnostics should be restructored to allow per file notifications, etc. - implement v3 test suite. - better logging * Add tests for v3 and implement ideSug * Remove typeInstCache/procInstCache cleanup * Add ideChkFile command * Avoid contains call when adding symbol info * Remove log * Remove segfaults * Fixed bad cherry-pick resolve * modulegraphs.dependsOn does not work on transitive modules - make sure transitive deps are marked as dirty
…im-lang#19892) * Initial implementation of nimsuggest v3 (nim-lang#19826) * Initial implementation of nimsuggest v3 Rework `nimsuggest` to use caching to make usage of ide commands more efficient. Previously, all commands no matter what the state of the process is were causing clean build. In the context of Language Server Protocol(LSP) and lsp clients this was causing perf issues and overall instability. Overall, the goal of v3 is to fit to LSP Server needs - added two new commands: - `recompile` to do clean compilation - `changed` which can be used by the IDEs to notify that a particular file has been changed. The later can be utilized when using LSP file watches. - `globalSymbols` - searching global references - added `segfaults` dependency to allow fallback to clean build when incremental fails. I wish the error to be propagated to the client so we can work on fixing the incremental build failures (typically hitting pointer) - more efficient rebuild flow. ATM incremental rebuild is triggered when the command needs that(i. e. it is global) while the commands that work on the current source rebuild only it Things missing in this PR: - Documentation - Extensive unit testing. Although functional I still see this more as a POC that this approach can work. Next steps: - Implement `sug` request. - Rework/extend the protocol to allow better client/server communication. Ideally we will need push events, diagnostics should be restructored to allow per file notifications, etc. - implement v3 test suite. - better logging * Add tests for v3 and implement ideSug * Remove typeInstCache/procInstCache cleanup * Add ideChkFile command * Avoid contains call when adding symbol info * Remove log * Remove segfaults * Fixed bad cherry-pick resolve * modulegraphs.dependsOn does not work on transitive modules - make sure transitive deps are marked as dirty
* Initial implementation of nimsuggest v3 Rework `nimsuggest` to use caching to make usage of ide commands more efficient. Previously, all commands no matter what the state of the process is were causing clean build. In the context of Language Server Protocol(LSP) and lsp clients this was causing perf issues and overall instability. Overall, the goal of v3 is to fit to LSP Server needs - added two new commands: - `recompile` to do clean compilation - `changed` which can be used by the IDEs to notify that a particular file has been changed. The later can be utilized when using LSP file watches. - `globalSymbols` - searching global references - added `segfaults` dependency to allow fallback to clean build when incremental fails. I wish the error to be propagated to the client so we can work on fixing the incremental build failures (typically hitting pointer) - more efficient rebuild flow. ATM incremental rebuild is triggered when the command needs that(i. e. it is global) while the commands that work on the current source rebuild only it Things missing in this PR: - Documentation - Extensive unit testing. Although functional I still see this more as a POC that this approach can work. Next steps: - Implement `sug` request. - Rework/extend the protocol to allow better client/server communication. Ideally we will need push events, diagnostics should be restructored to allow per file notifications, etc. - implement v3 test suite. - better logging * Add tests for v3 and implement ideSug * Remove typeInstCache/procInstCache cleanup * Add ideChkFile command * Avoid contains call when adding symbol info * Remove log * Remove segfaults
Rework
nimsuggest
to use caching to make usage of ide commands more efficient.Previously, all commands no matter what the state of the process is were causing
clean build. In the context of Language Server Protocol(LSP) and lsp clients
this was causing perf issues and overall instability. Overall, the goal of v3 is
to fit to LSP Server needs
added two new commands:
recompile
to do clean compilationchanged
which can be used by the IDEs to notify that a particular file has been changed.The later can be utilized when using LSP file watches.
globalSymbols
- searching global referencesadded
segfaults
dependency to allow fallback to clean build when incrementalfails. I wish the error to be propagated to the client so we can work on fixing
the incremental build failures (typically hitting pointer)
more efficient rebuild flow. ATM incremental rebuild is triggered when the
command needs that(i. e. it is global) while the commands that work on the
current source rebuild only it
Things missing in this PR:
Although functional I still see this more as a POC that this approach can work.
Next steps:
sug
request.Ideally we will need push events, diagnostics should be restructured to allow
per file notifications, etc.