-
Notifications
You must be signed in to change notification settings - Fork 128
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
[Tapioca Add-on] Generate DSL RBIs in add-on mode #2093
Conversation
Co-authored-by: Alex Rocha <[email protected]> Co-authored-by: Andy Waite <[email protected]>
By leveraging file checksums using `Zlib.crc32`, we can avoid triggering the DSL generation process for files that have not changed.
@@ -13,13 +13,17 @@ def name | |||
def execute(request, params) | |||
case request | |||
when "dsl" | |||
dsl(params) | |||
fork do |
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.
We run the DSL generation in a short living process because it uses a lot of memory.
lib/ruby_lsp/tapioca/addon.rb
Outdated
@@ -41,6 +46,7 @@ def activate(global_state, outgoing_queue) | |||
rescue IncompatibleApiError | |||
# The requested version for the Rails add-on no longer matches. We need to upgrade and fix the breaking | |||
# changes | |||
puts "IncompatibleApiError: Cannot activate Tapioca LSP add-on" |
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 assume if we get this error @rails_runner_client
will never be set and we'll return early in workspace_did_change_watched_files
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.
We shouldn't puts
in LSP related code. Although the Ruby LSP will override the default output device to prevent this from breaking communication, we should always standardize on window log messages.
puts "IncompatibleApiError: Cannot activate Tapioca LSP add-on" | |
outgoing_queue << Notification.window_log_message("IncompatibleApiError: Cannot activate Tapioca LSP add-on", type: Constant::MessageType::WARNING) |
@processable_constants = nil | ||
@all_classes = nil | ||
@all_modules = nil | ||
end |
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.
These are memoized but in LSP mode we want them to be calculated every time.
@@ -63,7 +69,41 @@ def workspace_did_change_watched_files(changes) | |||
return unless T.must(@global_state).enabled_feature?(:tapiocaAddon) | |||
return unless @rails_runner_client # Client is not ready | |||
|
|||
nil | |||
constants = changes.flat_map do |change| | |||
path = URI(change[:uri]).to_standardized_path |
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.
(nit) Perhaps extract the body of this to its own method for readability?
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 refactored the checksum logic into its own method. It's a bit longer and I don't love the boolean returns but I think main loop reads much better now. Lmk what you think.
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'm a little uncomfortable that file_updated?
has side-effects. I'll take a look to see if there is another way we could structure it.
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.
Just two minor things
lib/ruby_lsp/tapioca/addon.rb
Outdated
@@ -41,6 +46,7 @@ def activate(global_state, outgoing_queue) | |||
rescue IncompatibleApiError | |||
# The requested version for the Rails add-on no longer matches. We need to upgrade and fix the breaking | |||
# changes | |||
puts "IncompatibleApiError: Cannot activate Tapioca LSP add-on" |
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.
We shouldn't puts
in LSP related code. Although the Ruby LSP will override the default output device to prevent this from breaking communication, we should always standardize on window log messages.
puts "IncompatibleApiError: Cannot activate Tapioca LSP add-on" | |
outgoing_queue << Notification.window_log_message("IncompatibleApiError: Cannot activate Tapioca LSP add-on", type: Constant::MessageType::WARNING) |
a4293e1
to
8610d6f
Compare
when Constant::FileChangeType::DELETED | ||
@file_checksums.delete(path) | ||
else | ||
T.must(@outgoing_queue) << Notification.window_log_message( |
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.
Are we anticipating other change types?
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.
No, Sorbet was complaining and I thought it'd be nice to have an else
here for the future.
lib/ruby_lsp/tapioca/addon.rb
Outdated
@rails_runner_client.register_server_addon(File.expand_path("server_addon.rb", __dir__)) | ||
rescue IncompatibleApiError | ||
# The requested version for the Rails add-on no longer matches. We need to upgrade and fix the breaking | ||
# changes | ||
outgoing_queue << Notification.window_log_message( |
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.
Should this also be an instance variable?
outgoing_queue << Notification.window_log_message( | |
@outgoing_queue << Notification.window_log_message( |
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.
Maybe for consistency, but both are pointing to the same object.
@@ -77,6 +77,10 @@ def initialize( | |||
|
|||
sig { params(outpath: Pathname, quiet: T::Boolean).returns(T::Set[Pathname]) } | |||
def generate_dsl_rbi_files(outpath, quiet:) | |||
if @lsp_addon | |||
pipeline.active_compilers.each(&:reset_state) |
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.
maybe extract this to pipeline#reset
?
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 think main issue is another method checking for lsp_addon
. I don't want this code to be reusable for other clients. It's a unique thing (kind of hacky and not ideal 😬 ) for addon support.
8610d6f
to
c630b69
Compare
Motivation
Extracting from main...tapioca-addon-feature-branch.
Implementation
Tests
Will be added later.