# typed: strict# frozen_string_literal: trueRubyLsp::Addon.depend_on_ruby_lsp!(">= 0.23.10","< 0.26")begin# The Tapioca add-on depends on the Rails add-on to add a runtime component to the runtime server. We can allow the# add-on to work outside of a Rails context in the future, but that may require Tapioca spawning its own runtime# serverrequire"ruby_lsp/ruby_lsp_rails/runner_client"rescueLoadErrorreturnendrequire"zlib"require"ruby_lsp/tapioca/run_gem_rbi_check"moduleRubyLspmoduleTapiocaclassAddon<::RubyLsp::Addon#: -> voiddefinitializesuper@global_state=nil#: RubyLsp::GlobalState?@rails_runner_client=Rails::NullClient.new#: RubyLsp::Rails::RunnerClient@index=nil#: RubyIndexer::Index?@file_checksums={}#: Hash[String, String]@lockfile_diff=nil#: String?@outgoing_queue=nil#: Thread::Queue?end# @override#: (RubyLsp::GlobalState global_state, Thread::Queue outgoing_queue) -> voiddefactivate(global_state,outgoing_queue)@global_state=global_statereturnunless@global_state.enabled_feature?(:tapiocaAddon)@index=@global_state.index@outgoing_queue=outgoing_queueThread.newdo# Get a handle to the Rails add-on's runtime client. The call to `rails_runner_client` will block this thread# until the server has finished booting, but it will not block the main LSP. This has to happen inside of a# threadaddon=::RubyLsp::Addon.get("Ruby LSP Rails",">= 0.4.0","< 0.5")#: as ::RubyLsp::Rails::Addon@rails_runner_client=addon.rails_runner_client@outgoing_queue<<Notification.window_log_message("Activating Tapioca add-on v#{version}")@rails_runner_client.register_server_addon(File.expand_path("server_addon.rb",__dir__))@rails_runner_client.delegate_notification(server_addon_name: "Tapioca",request_name: "load_compilers_and_extensions",workspace_path: @global_state.workspace_path,)send_usage_telemetry("activated")run_gem_rbi_checkrescueIncompatibleApiErrorsend_usage_telemetry("incompatible_api_error")# 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("IncompatibleApiError: Cannot activate Tapioca LSP add-on",type: Constant::MessageType::WARNING,)endend# @override#: -> voiddefdeactivateend# @override#: -> Stringdefname"Tapioca"end# @override#: -> Stringdefversion"0.1.3"end#: (Array[{uri: String, type: Integer}] changes) -> voiddefworkspace_did_change_watched_files(changes)returnunless@global_state&.enabled_feature?(:tapiocaAddon)returnunless@rails_runner_client.connected?has_route_change=false#: boolhas_fixtures_change=false#: boolneeds_compiler_reload=false#: boolindex=@index#: as !nilconstants=changes.flat_mapdo|change|path=URI(change[:uri]).to_standardized_path#: String?nextunlesspath&&file_updated?(change,path)ifFile.fnmatch("**/fixtures/**/*.yml{,.erb}",path,File::FNM_PATHNAME|File::FNM_EXTGLOB)has_fixtures_change=truenextendifFile.basename(path)=="routes.rb"||File.fnmatch?("**/routes/**/*.rb",path,File::FNM_PATHNAME)has_route_change=truenextendnextifFile.fnmatch?("**/{test,spec,features}/**/*",path,File::FNM_PATHNAME|File::FNM_EXTGLOB)ifFile.fnmatch?("**/tapioca/**/compilers/**/*.rb",path,File::FNM_PATHNAME)needs_compiler_reload=truenextendentries=index.entries_for(change[:uri])nextunlessentriesentries.filter_mapdo|entry|entry.nameifentry.class==RubyIndexer::Entry::Class||entry.class==RubyIndexer::Entry::Moduleendend.compactreturnifconstants.empty?&&!has_route_change&&!has_fixtures_change&&!needs_compiler_reload@rails_runner_client.trigger_reloadifneeds_compiler_reload@rails_runner_client.delegate_notification(server_addon_name: "Tapioca",request_name: "reload_workspace_compilers",workspace_path: @global_state.workspace_path,)endifhas_route_changesend_usage_telemetry("route_dsl")@rails_runner_client.delegate_notification(server_addon_name: "Tapioca",request_name: "route_dsl")endifhas_fixtures_changesend_usage_telemetry("fixtures_dsl")@rails_runner_client.delegate_notification(server_addon_name: "Tapioca",request_name: "fixtures_dsl")endifconstants.any?send_usage_telemetry("dsl")@rails_runner_client.delegate_notification(server_addon_name: "Tapioca",request_name: "dsl",constants: constants,)endendprivate#: (String feature_name) -> voiddefsend_usage_telemetry(feature_name)returnunless@outgoing_queue&&@global_state# Telemetry is not captured by default even if events are produced by the server# See https://github.com/Shopify/ruby-lsp/tree/main/vscode#telemetry@outgoing_queue<<Notification.telemetry({eventName: "tapioca_addon.feature_usage",type: "data",data: {type: "counter",attributes: {label: feature_name,machineId: @global_state.telemetry_machine_id,},},})end#: (Hash[Symbol, untyped] change, String path) -> booldeffile_updated?(change,path)queue=@outgoing_queue#: as !nilcasechange[:type]whenConstant::FileChangeType::CREATED@file_checksums[path]=Zlib.crc32(File.read(path)).to_sreturntruewhenConstant::FileChangeType::CHANGEDcurrent_checksum=Zlib.crc32(File.read(path)).to_sif@file_checksums[path]==current_checksumqueue<<Notification.window_log_message("File has not changed. Skipping #{path}",type: Constant::MessageType::INFO,)else@file_checksums[path]=current_checksumreturntrueendwhenConstant::FileChangeType::DELETED@file_checksums.delete(path)elsequeue<<Notification.window_log_message("Unexpected file change type: #{change[:type]}",type: Constant::MessageType::WARNING,)endfalseend#: -> voiddefrun_gem_rbi_checkstate=@global_state#: as !nilgem_rbi_check=RunGemRbiCheck.new(state.workspace_path)gem_rbi_check.runqueue=@outgoing_queue#: as !nilqueue<<Notification.window_log_message(gem_rbi_check.stdout)unlessgem_rbi_check.stdout.empty?unlessgem_rbi_check.stderr.empty?queue<<Notification.window_log_message(gem_rbi_check.stderr,type: Constant::MessageType::WARNING)endendendendend