Class: MilkTea::LSP::Server
- Inherits:
-
Object
- Object
- MilkTea::LSP::Server
- Includes:
- ServerCallHierarchy, ServerCodeActions, ServerCodeLens, ServerCompletion, ServerConfiguration, ServerDebugInfo, ServerDefinition, ServerDiagnosticsScheduling, ServerExecuteCommand, ServerFoldingRange, ServerFormatting, ServerHover, ServerInlayHints, ServerLifecycle, ServerLinkedEditingRange, ServerOnTypeFormatting, ServerProgress, ServerReferences, ServerRename, ServerSelectionRange, ServerSemanticTokens, ServerSignatureHelp, ServerTextDocuments, ServerTypeHierarchy, ServerUtilities
- Defined in:
- lib/milk_tea/lsp/server.rb,
lib/milk_tea/lsp/server/hover.rb,
lib/milk_tea/lsp/server/rename.rb,
lib/milk_tea/lsp/server/progress.rb,
lib/milk_tea/lsp/server/code_lens.rb,
lib/milk_tea/lsp/server/lifecycle.rb,
lib/milk_tea/lsp/server/utilities.rb,
lib/milk_tea/lsp/server/completion.rb,
lib/milk_tea/lsp/server/debug_info.rb,
lib/milk_tea/lsp/server/definition.rb,
lib/milk_tea/lsp/server/formatting.rb,
lib/milk_tea/lsp/server/references.rb,
lib/milk_tea/lsp/server/inlay_hints.rb,
lib/milk_tea/lsp/server/code_actions.rb,
lib/milk_tea/lsp/server/configuration.rb,
lib/milk_tea/lsp/server/folding_range.rb,
lib/milk_tea/lsp/server/call_hierarchy.rb,
lib/milk_tea/lsp/server/signature_help.rb,
lib/milk_tea/lsp/server/text_documents.rb,
lib/milk_tea/lsp/server/type_hierarchy.rb,
lib/milk_tea/lsp/server/execute_command.rb,
lib/milk_tea/lsp/server/selection_range.rb,
lib/milk_tea/lsp/server/semantic_tokens.rb,
lib/milk_tea/lsp/server/on_type_formatting.rb,
lib/milk_tea/lsp/server/linked_editing_range.rb,
lib/milk_tea/lsp/server/diagnostics_scheduling.rb
Overview
Main LSP server — JSON-RPC 2.0 message loop with full MVP feature set.
Enhancements implemented:
1. Hover — real type signature from semantic facts
2. Goto Def — token-based definition site navigation
3. Incremental — textDocumentSync: 2 with range-based edits
4. Multi-file — workspace indexing via workspace/symbol
5. Completion — function/type/value completions from facts
Defined Under Namespace
Modules: ServerCallHierarchy, ServerCodeActions, ServerCodeLens, ServerCompletion, ServerConfiguration, ServerDebugInfo, ServerDefinition, ServerDiagnosticsScheduling, ServerExecuteCommand, ServerFoldingRange, ServerFormatting, ServerHover, ServerInlayHints, ServerLifecycle, ServerLinkedEditingRange, ServerOnTypeFormatting, ServerProgress, ServerReferences, ServerRename, ServerSelectionRange, ServerSemanticTokens, ServerSignatureHelp, ServerTextDocuments, ServerTypeHierarchy, ServerUtilities Classes: FakeWarning
Constant Summary collapse
- SEMANTIC_TOKEN_TYPES =
%w[ namespace type class enum interface struct typeParameter parameter variable property enumMember event function method macro keyword modifier comment string number regexp operator decorator ].freeze
- SEMANTIC_TOKEN_MODIFIERS =
%w[ declaration definition readonly static deprecated abstract async modification documentation defaultLibrary ].freeze
- KEYWORD_TOKEN_TYPES =
Token::KEYWORDS.values.to_set.freeze
- DEFAULT_LIBRARY_TYPE_NAMES =
Types::BUILTIN_TYPE_NAMES.to_set.freeze
- BUILTIN_FUNCTION_NAMES =
%w[ ref_of const_ptr_of ptr_of read fatal reinterpret array span zero default adapt get field_of callable_of has_attribute attribute_of attribute_arg fields_of members_of attributes_of ].to_set.freeze
- BUILTIN_ASSOCIATED_HOOK_NAMES =
%w[hash equal order].to_set.freeze
- BUILTIN_CALL_HOVER_INFO =
{ 'fatal' => { signature: 'builtin fatal(message) -> never', docs: '`fatal(message)` aborts execution with the provided message.' }, 'ref_of' => { signature: 'builtin ref_of(value) -> ref[T]', docs: '`ref_of(x)` borrows a safe lvalue as `ref[T]`.' }, 'const_ptr_of' => { signature: 'builtin const_ptr_of(value) -> const_ptr[T]', docs: '`const_ptr_of(x)` takes the address of a safe lvalue as `const_ptr[T]`.' }, 'ptr_of' => { signature: 'builtin ptr_of(value) -> ptr[T]', docs: '`ptr_of(x)` takes the address of a safe lvalue as `ptr[T]`.' }, 'read' => { signature: 'builtin read(value) -> T', docs: '`read(value)` projects a `ref[T]` or pointer-like value to its referent.' }, 'adapt' => { signature: 'builtin adapt[Interface](value) -> dyn[Interface]', docs: '`adapt[Interface](value)` constructs a `dyn[Interface]` runtime interface value. Compile-time verified: the value\'s type must implement the interface.' }, 'reinterpret' => { signature: 'builtin reinterpret[T](value) -> T', docs: '`reinterpret[T](value)` reinterprets the bits of `value` as type `T` without conversion. Requires `unsafe`.' }, 'array' => { signature: 'builtin array[T, N](elements...) -> array[T, N]', docs: '`array[T, N]` constructs a fixed-size array from elements. Omitted trailing elements default to zero.' }, 'span' => { signature: 'builtin span[T](data, len) -> span[T]', docs: '`span[T](data = ..., len = ...)` constructs a borrowed pointer-plus-length view over contiguous memory.' }, 'zero' => { signature: 'builtin zero[T] -> T', docs: '`zero[T]` returns a zero-initialized value of type `T`. All bits are set to zero.' }, 'default' => { signature: 'builtin default[T] -> T', docs: '`default[T]` calls `T.default()` to produce a semantic default value. Requires an accessible `default()` associated function on `T`.' }, 'get' => { signature: 'builtin get(collection, index) -> ptr[T]?', docs: '`get(collection, index)` performs recoverable bounds-checked indexing, returning `ptr[T]?` (null on out-of-bounds) instead of aborting.' }, 'attribute_arg' => { signature: 'builtin attribute_arg[T](handle) -> T', docs: '`attribute_arg[T](handle)` returns the `T`-typed argument of a resolved `attribute_handle`. The attribute must declare an argument of type `T`.' }, 'field_of' => { signature: 'builtin field_of(Type, field_name) -> field_handle', docs: '`field_of(Type, field_name)` returns a compile-time handle for the named field on a struct type.' }, 'callable_of' => { signature: 'builtin callable_of(name) -> callable_handle', docs: '`callable_of(name)` returns a compile-time handle for a callable declaration name.' }, 'has_attribute' => { signature: 'builtin has_attribute(target, attribute_name) -> bool', docs: '`has_attribute(target, attribute_name)` checks at compile time whether the resolved attribute is applied to the target.' }, 'attribute_of' => { signature: 'builtin attribute_of(target, attribute_name) -> attribute_handle', docs: '`attribute_of(target, attribute_name)` returns the applied attribute handle for the resolved target-and-attribute pair; use `has_attribute(...)` when absence is expected.' }, 'fields_of' => { signature: 'builtin fields_of(Type) -> array[field_handle, N]', docs: '`fields_of(Type)` returns all struct fields as a compile-time `array[field_handle, N]`, in declaration order. Use with `inline for` for reflective field iteration.' }, 'members_of' => { signature: 'builtin members_of(Type) -> array[member_handle, N]', docs: '`members_of(Type)` returns all members of an enum or flags type as a compile-time `array[member_handle, N]`. Each handle exposes `.name` and `.value`.' }, 'attributes_of' => { signature: 'builtin attributes_of(target [, name]) -> array[attribute_handle, N]', docs: '`attributes_of(target)` returns all attributes applied to a type, field, or callable as a compile-time array. `attributes_of(target, name)` filters by attribute kind.' }, }.freeze
- OPERATOR_TOKEN_TYPES =
%i[ amp colon comma caret dot lparen rparen pipe lbracket rbracket question equal plus minus star slash percent less greater tilde arrow shift_left shift_right plus_equal minus_equal star_equal slash_equal percent_equal amp_equal pipe_equal caret_equal shift_left_equal shift_right_equal equal_equal bang_equal less_equal greater_equal ellipsis at dot_dot ].to_set.freeze
- DIAGNOSTICS_WORKER_COUNT =
Integer(ENV.fetch('MILK_TEA_LSP_DIAGNOSTICS_WORKERS', '2')).clamp(1, 8)
Constants included from ServerUtilities
ServerUtilities::MESSAGE_TYPES
Constants included from ServerTypeHierarchy
ServerTypeHierarchy::TYPE_KIND_MAP
Constants included from ServerProgress
ServerProgress::PROGRESS_TOKEN_PREFIX
Constants included from ServerOnTypeFormatting
ServerOnTypeFormatting::BLOCK_INTRODUCING_KEYWORDS
Constants included from ServerLifecycle
ServerLifecycle::SEMANTIC_TOKENS_REFRESH_THROTTLE_MS
Constants included from ServerHover
ServerHover::BUILTIN_TYPE_DOCS, ServerHover::BUILTIN_TYPE_METHOD_SIGNATURES, ServerHover::KEYWORD_HOVER_INFO, ServerHover::LANGUAGE_KEYWORD_HOVER_INFO
Constants included from ServerFoldingRange
ServerFoldingRange::BLOCK_START_PATTERN, ServerFoldingRange::CONTINUATION_KEYWORDS
Constants included from ServerCompletion
ServerCompletion::COMPLETION_KEYWORDS, ServerCompletion::MAX_COMPLETION_ITEMS, ServerCompletion::TYPE_CONSTRUCTOR_KEYWORDS
Class Method Summary collapse
Instance Method Summary collapse
- #handle_notification(method_name, params) ⇒ Object
- #handle_request(method_name, params, id) ⇒ Object
-
#initialize(protocol: Protocol) ⇒ Server
constructor
A new instance of Server.
- #named_argument_definition_location(uri, name, tokens, token_index, stages: nil) ⇒ Object
- #named_argument_label_references(uri, name, tokens, token_index, include_declaration:, stages: nil) ⇒ Object
-
#process_message(message) ⇒ Object
── Message dispatch ─────────────────────────────────────────────────────.
-
#register_handlers ⇒ Object
── Handler registration ─────────────────────────────────────────────────.
- #run ⇒ Object
Methods included from ServerUtilities
#clear_cancelled_request, #collect_call_argument_starts, #current_word_prefix, #decode_client_char, #diagnostics_fingerprint, #elapsed_ms, #encode_char_for_client, #format_document_symbol, #format_symbol, #handle_did_change_watched_files, #hget, #invalidate_document_caches, #invalidate_document_caches_for, #library_uri?, #log_message, #log_perf_breakdown, #log_request_stage_breakdown, #measure_perf_stage, #monotonic_time, #new_perf_stages, #next_diagnostic_result_id, #next_non_trivia_token, #path_to_uri, #perf_breakdown_logging?, #perf_log_context, #perf_logging?, #perf_verbose?, #position_in_range?, #refresh_open_document_dependency_state, #request_cancelled?, #self_describing_argument_expression?, #shorten_uri, #show_message, #show_message_request, #simple_identifier_like_argument_expression?, #skip_expensive_source_fix_all?, #skip_expensive_work_reason, #summarize_lsp_params, #symbol_kind, #token_end_position, #token_to_range, #uri_to_path, #utf32_to_utf16_char, #utf8_to_utf16_char
Methods included from ServerTypeHierarchy
#handle_prepare_type_hierarchy, #handle_subtypes, #handle_supertypes
Methods included from ServerTextDocuments
#handle_did_change, #handle_did_close, #handle_did_open, #handle_did_save, #handle_document_context, #handle_will_save_wait_until
Methods included from ServerSignatureHelp
#build_signature_from_binding, #handle_signature_help, #resolve_this_receiver_type, #signature_help_bindings_for_name
Methods included from ServerSemanticTokens
#bare_builtin_specialization?, #bare_function_value_identifier_site?, #build_attribute_name_semantic_overrides, #build_semantic_token_entries, #callable_field_member_access?, #callable_parameter_declaration_token?, #callable_semantic_type?, #classify_name_semantic, #classify_semantic_token, #collect_generic_function_local_scopes, #compute_semantic_tokens_edits, #constructible_semantic_type?, #declaration_scope_end_line, #destructure_let_binding?, #dot_nested_type_member?, #dot_type_receiver_info, #embedded_heredoc_token?, #encode_semantic_tokens, #field_declaration_token?, #find_semantic_token_common_prefix, #find_semantic_token_common_suffix, #first_non_trivia_token_on_line?, #fstring_interpolation_entries, #generic_binding_scope, #generic_callable_lexical_scopes, #generic_function_binding_for_line, #generic_function_bindings, #generic_function_declaration?, #generic_function_lexical_binding_kind_at, #generic_function_lexical_binding_scopes, #generic_function_lexical_binding_semantic, #generic_function_lexical_scopes_for_declaration, #generic_method_lexical_scopes, #generic_statement_end_line, #generic_statement_list_end_line, #generic_type_parameter_header_token?, #generic_type_parameter_names_for_declaration, #generic_type_parameter_names_for_extending_block, #handle_semantic_tokens_delta, #handle_semantic_tokens_full, #handle_semantic_tokens_range, #identifier_in_type_argument_position?, #identifier_in_type_parameter_reference_position?, #identifier_in_type_reference_position?, #import_path_info_at, #imported_module_binding_for_member, #imported_module_function_value_member_access_site?, #inside_type_params?, #keyword_field_declaration_token?, #keyword_lifetime_or_type_param?, #keyword_member_access?, #keyword_named_argument_token?, #keyword_type_annotation?, #known_type_name?, #lexically_declared_free_function_name?, #lexically_declared_free_function_names, #local_semantic_value_binding, #mark_attribute_name_override, #mark_attribute_reflection_name_overrides, #match_arm_binding_token?, #matching_closer_index, #matching_opener_index, #module_declaration_info_at, #module_declaration_path_token?, #named_argument_label_in_type_constructor?, #named_argument_label_token?, #namespace_keyword_token?, #nested_declaration_scope_end_line, #next_non_trivia_token_index, #next_semantic_token_result_id, #non_trivia_tokens_on_line, #parameter_declaration_token?, #parameter_list_opener_index, #previous_non_trivia_token, #previous_non_trivia_token_index, #resolve_receiver_value_type, #resolve_struct_type_name, #resolved_call_callee_semantic, #semantic_modifiers_bitset, #semantic_token_entry_equal?, #semantic_value_binding_entry, #simple_type_parameter_name_from_type_argument, #specialized_call_with_type_args?, #static_type_member_access?, #struct_event_declaration_token?, #token_semantic_entries, #type_name_member_access?, #type_name_receiver_token?, #type_parameter_declaration_info_on_line, #type_parameter_declaration_token?, #type_parameter_names_in_scope, #type_parameter_reference_token?, #type_parameter_scopes_for_declaration, #variant_enum_member_declaration?, #variant_payload_field_declaration_token?, #walk_ast_nodes
Methods included from ServerSelectionRange
#build_selection_range, #find_enclosing_block_range, #find_statement_range, #handle_selection_range, #token_bounds_at
Methods included from ServerRename
#allow_hover_last_good_fallback?, #ast_name_range, #collect_struct_field_changes, #declaration_name_range, #definition_identity_key, #each_ast_node, #enum_member_rename_changes, #find_declaration_ast_node_at, #find_extending_type_for_method, #find_identifier_ast_node_at, #find_method_at_position, #find_struct_containing_field, #handle_prepare_rename, #handle_rename, #import_alias_rename_changes, #lexical_rename_changes_in_document, #local_binding_declaration_node?, #local_binding_id?, #method_rename_changes, #name_like_token?, #rename_target_binding_id, #scoped_binding_occurrence_ranges, #scoped_local_reference_locations, #scoped_rename_changes, #skip_trivia_forward, #struct_field_cursor_context?, #struct_field_edit_context?, #struct_field_rename_changes, #workspace_symbol_identity_rename_changes
Methods included from ServerLinkedEditingRange
Methods included from ServerExecuteCommand
Methods included from ServerReferences
#declaration_name_range_fallback, #find_member_column_in_line, #get_content_line, #handle_document_highlight, #handle_document_link, #handle_document_link_resolve, #handle_references, #handle_workspace_symbol, #module_level_ast_name?, #module_level_declaration_node?, #module_level_name?, #module_level_name_kind, #module_level_reference_locations, #path_like_string_literal?, #resolve_document_link_path, #resource_document_link
Methods included from ServerProgress
#create_progress, #create_progress_handle, #next_progress_token_id
Methods included from ServerOnTypeFormatting
Methods included from ServerLifecycle
#handle_cancel_request, #handle_did_change_configuration, #handle_did_change_workspace_folders, #handle_exit, #handle_initialize, #handle_initialized, #handle_shutdown, #handle_will_rename_files, #negotiate_position_encoding, #refresh_client_semantic_tokens
Methods included from ServerInlayHints
#collect_function_defs, #collect_inferred_return_hints, #collect_inferred_type_hints, #collect_local_decls, #collect_parameter_name_hints, #describe_type_for_hint, #handle_inlay_hint
Methods included from ServerHover
#append_structured_doc_comment_markdown, #attribute_target_token?, #builtin_call_hover_info, #builtin_hover_info, #builtin_in_member_access_context?, #builtin_keyword_hover_info, #builtin_specialized_call_hover_info, #builtin_type_constructor_hover_info, #builtin_value_specialization_info, #call_argument_token?, #completion_function_documentation, #declared_generic_local_hover_binding, #doc_tag_param_descriptions, #doc_tag_return_description, #embedded_heredoc_or_format_heredoc_token?, #enclosing_completion_frame, #field_declaration_receiver_info, #field_hover_signature, #find_member_in_types, #find_method_entry, #find_nested_type_by_short_name, #find_variant_arm_in_types, #for_binding_context_at, #format_params, #fstring_interpolation_token_context, #handle_hover, #hover_definition_entry_from_location, #hover_doc_comment_data_for_definition, #hover_doc_comment_for_definition, #hover_source_label, #hover_source_label_for_definition, #hover_source_label_from_location, #hover_source_line_for_definition, #hover_source_line_from_location, #hover_source_uri_for_definition, #hover_source_uri_from_location, #interface_method_signature, #interface_signature, #interpolation_expression_tokens, #keyword_member_access_token?, #latest_completion_snapshot, #member_access_chain_at, #member_access_token?, #member_method_info_for_receiver_type, #method_binding_at_token, #method_signature, #named_argument_callee_name, #named_argument_label_receiver_info, #named_argument_param_result, #named_argument_parameter_info, #param_doc_for_name, #parameter_declaration_token?, #render_builtin_specialization, #render_hover_markdown, #resolve_as_binding_declaration_hover_binding, #resolve_dot_receiver_value_type, #resolve_enum_member_access_info, #resolve_enum_member_definition_location, #resolve_enum_member_hover_info, #resolve_field_declaration_hover_info, #resolve_for_binding_hover_info, #resolve_hover_info, #resolve_lexical_local_hover_signature, #resolve_local_hover_binding, #resolve_local_hover_type, #resolve_member_access_hover_info, #resolve_named_argument_label_hover_info, #same_line_future_completion_snapshot, #shorten_qualified_types, #signature_help_doc_comment_for_call, #signature_help_markdown_for_doc_comment, #token_contains_position?, #token_context_at, #type_hover_signature, #value_hover_signature
Methods included from ServerFormatting
#child_event_symbol, #child_field_symbol, #child_member_symbol, #child_method_symbol, #child_nested_struct_symbol, #child_parent_name, #child_symbols_for, #child_variant_arm_symbol, #collect_local_decls, #collect_nested_type_names, #descendant_names, #enrich_with_children, #expand_generic_type_params, #handle_document_symbols, #handle_formatting, #handle_range_formatting, #local_decl_symbol, #proc_signature_detail, #resolve_outline_module_name, #symbol_line, #type_detail_string, #type_param_child_symbol, #wrap_in_module_hierarchy
Methods included from ServerFoldingRange
#block_start?, #compute_block_folds, #compute_comment_folds, #compute_import_folds, #continuation_start?, #folding_range, #handle_folding_range, #strip_comment, #trim_trailing_blank_lines
Methods included from ServerDiagnosticsScheduling
#cancel_diagnostics, #collect_diagnostics_for_content, #dependency_export_surface_fingerprint, #dependency_import_fingerprint, #dependency_refresh_required_for_edit?, #drain_diagnostics_queue, #lint_tier_rank, #more_strict_lint_tier, #notify_diagnostic_errors, #process_diagnostics_for_uri, #schedule_diagnostics, #semantic_tokens_allow_last_good_fallback?, #start_diagnostics_workers, #stop_diagnostics_workers
Methods included from ServerDefinition
#definition_file_ast, #definition_file_mtime_key, #definition_file_tokens, #definition_lookup_tokens, #enum_member_definition_location, #enum_member_value_text, #field_definition_location, #find_definition_token_in_file, #find_enum_member_token_in_body, #find_enum_member_token_in_file, #find_field_token_in_body, #find_field_token_in_type, #find_local_decl_node, #find_local_declaration_ast_node, #handle_declaration, #handle_definition, #handle_definition_request, #handle_implementation, #handle_type_definition, #imported_module_name_from_ast, #interface_implementation_locations, #interface_method_implementation_locations, #interface_receiver_definition_location, #is_builtin_name?, #local_type_definition_token, #module_definition_location, #module_member_binding_location, #module_member_definition_location, #module_path_for_name, #receiver_module_name, #resolve_definition_location, #resolve_field_member_definition_location, #resolve_implementation_locations, #resolve_interface_binding_at_position, #resolve_interface_method_target_at_token, #resolve_type_definition_location, #same_interface_binding?
Methods included from ServerConfiguration
#apply_configuration_settings, #apply_dependency_resolution_mode, #apply_platform_override, #apply_strict_current_root_diagnostics, #dependency_resolution_mode_from_settings, #formatter_mode_from_settings, #platform_override_from_settings, #pull_client_configuration, #strict_current_root_diagnostics_from_settings
Methods included from ServerCompletion
#attribute_completions, #completion_data, #completion_items_for_type_receiver, #completion_items_for_value_receiver, #field_owner_type, #field_type_from_struct_definition, #format_string_completions, #handle_completion, #handle_completion_resolve, #import_completions, #label_details_for_params, #location_matches_reference?, #method_dispatch_receiver_type_for_completion, #methods_for_receiver_type, #module_dir_contains_mt?, #module_member_access_info, #named_argument_completions, #pointer_type_name?, #project_field_receiver_type_for_completion, #project_method_receiver_type_for_completion, #project_receiver_type_for_completion, #ref_type_name?, #resolve_nested_type_binding, #resolve_static_type_receiver_method, #resolve_static_type_reference_target, #resolve_type_receiver_info, #same_location?, #snippet_for_callable, #specialization_completions, #static_method_binding_at_token, #static_method_binding_for_receiver, #static_type_method_reference?, #static_type_method_references, #value_chain_completions
Methods included from ServerDebugInfo
Methods included from ServerCodeLens
#handle_code_lens, #handle_code_lens_resolve, #static_method_code_lens_count
Methods included from ServerCodeActions
#find_match_end_line, #handle_code_action, #handle_document_diagnostic, #handle_workspace_diagnostic, #refresh_workspace_diagnostics
Methods included from ServerCallHierarchy
#handle_incoming_calls, #handle_outgoing_calls, #handle_prepare_call_hierarchy
Constructor Details
#initialize(protocol: Protocol) ⇒ Server
Returns a new instance of Server.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
# File 'lib/milk_tea/lsp/server.rb', line 197 def initialize(protocol: Protocol) @protocol = protocol @workspace = Workspace.new @format_mode = :tidy @dependency_resolution_mode = :auto @platform_override = nil @position_encoding = 'utf-16' @handlers = {} @diagnostic_report_cache = {} @workspace_diagnostic_cache = {} @semantic_tokens_cache = {} @semantic_tokens_delta_cache = {} @fixall_cache = {} @definition_file_token_cache = {} @definition_file_ast_cache = {} @diagnostics_perf = { scheduled: 0, skipped_unchanged: 0, cancelled: 0, dequeued: 0, collected_for_pull: 0, published: 0, dropped_stale: 0, requeued: 0, queue_peak: 0, } @diagnostics_mutex = Mutex.new @diagnostics_pending = {} @diagnostics_enqueued = Set.new @diagnostics_generation = Hash.new(0) @diagnostics_last_scheduled_hash = {} @diagnostics_queue = Queue.new @diagnostics_workers = [] @cancelled_requests_mutex = Mutex.new @cancelled_request_ids = Set.new @_initialize_called = false @_indexing_thread = nil Diagnostics.protocol = @protocol Diagnostics.position_encoding = @position_encoding register_handlers start_diagnostics_workers end |
Class Method Details
.semantic_tokens_for_path(path, module_roots: nil, package_graph: nil) ⇒ Object
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/milk_tea/lsp/server.rb', line 156 def self.semantic_tokens_for_path(path, module_roots: nil, package_graph: nil) = File.(path) roots = module_roots || MilkTea::ModuleRoots.roots_for_path() source = File.read() tokens = MilkTea::Lexer.lex(source, path: ) facts = MilkTea::ModuleLoader.new( module_roots: roots, package_graph: package_graph || load_package_graph(), ).check_file() helper = allocate entries = helper.send(:build_semantic_token_entries, tokens, facts) data = helper.send(:encode_semantic_tokens, entries) { path: , moduleName: facts.module_name, legend: { tokenTypes: SEMANTIC_TOKEN_TYPES, tokenModifiers: SEMANTIC_TOKEN_MODIFIERS, }, data: data, entries: entries.map do |entry| { line: entry[:line], startChar: entry[:start_char], length: entry[:length], tokenType: entry[:type].to_s, modifiers: entry[:modifiers].map(&:to_s), } end, } end |
Instance Method Details
#handle_notification(method_name, params) ⇒ Object
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 |
# File 'lib/milk_tea/lsp/server.rb', line 406 def handle_notification(method_name, params) handler = @handlers[method_name] return unless handler begin t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) handler.call(params) elapsed_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - t0) * 1000).round(1) if perf_logging? && (perf_verbose? || elapsed_ms > Workspace::PERF_LOG_THRESHOLD_MS) detail = perf_log_context(method_name, params, verbose: perf_verbose?) warn "[LSP perf] ntf #{method_name} #{elapsed_ms}ms#{detail}" end rescue StandardError => e (:warning, "Error in notification handler for #{method_name}: #{e.}") end end |
#handle_request(method_name, params, id) ⇒ Object
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 |
# File 'lib/milk_tea/lsp/server.rb', line 369 def handle_request(method_name, params, id) if request_cancelled?(id) clear_cancelled_request(id) @protocol.write_error(id, -32_800, 'Request cancelled') return end handler = @handlers[method_name] if handler.nil? @protocol.write_error(id, -32_601, 'Method not found') return end begin @current_request_id = id t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) result = handler.call(params) elapsed_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - t0) * 1000).round(1) if perf_logging? && (perf_verbose? || elapsed_ms > Workspace::PERF_LOG_THRESHOLD_MS) detail = perf_log_context(method_name, params, verbose: perf_verbose?) warn "[LSP perf] req #{method_name} #{elapsed_ms}ms id=#{id}#{detail}" end if request_cancelled?(id) clear_cancelled_request(id) @protocol.write_error(id, -32_800, 'Request cancelled') else @protocol.write_response(id, result) end rescue StandardError => e (:warning, "Error in handler for #{method_name}: #{e.}") @protocol.write_error(id, -32_603, "Internal error: #{e.}") ensure clear_cancelled_request(id) @current_request_id = nil end end |
#named_argument_definition_location(uri, name, tokens, token_index, stages: nil) ⇒ Object
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 |
# File 'lib/milk_tea/lsp/server/definition.rb', line 741 def named_argument_definition_location(uri, name, tokens, token_index, stages: nil) return nil unless named_argument_label_token?(tokens, token_index) callee_name = named_argument_callee_name(tokens, token_index) return nil unless callee_name facts = measure_perf_stage(stages, 'definition_facts') { @workspace.get_facts(uri) } return nil unless facts func = facts.functions[callee_name] unless func facts.methods.each_value do |methods| method = methods[callee_name] || methods["static:#{callee_name}"] if method func = method break end end end return nil unless func param = func.ast.params.find { |p| p.name == name } return nil unless param range = ast_name_range(name, param.line, param.column) return nil unless range { uri: uri, range: { start: { line: range[:line] - 1, character: range[:column] - 1 }, end: { line: range[:line] - 1, character: range[:column] - 1 + name.length }, }, } end |
#named_argument_label_references(uri, name, tokens, token_index, include_declaration:, stages: nil) ⇒ Object
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 |
# File 'lib/milk_tea/lsp/server/references.rb', line 401 def named_argument_label_references(uri, name, tokens, token_index, include_declaration:, stages: nil) return nil unless named_argument_label_token?(tokens, token_index) callee_name = named_argument_callee_name(tokens, token_index) return nil unless callee_name facts = measure_perf_stage(stages, 'nav_ref_facts') { @workspace.get_facts(uri) } return nil unless facts func = facts.functions[callee_name] unless func facts.methods.each_value do |methods| method = methods[callee_name] || methods["static:#{callee_name}"] if method func = method break end end end return nil unless func param = func.ast.params.find { |p| p.name == name } return nil unless param range = declaration_name_range(param) unless range range = ast_name_range(name, param.line, param.column) end return [] unless range declaration_location = { uri: uri, range: { start: { line: range[:line] - 1, character: range[:column] - 1 }, end: { line: range[:line] - 1, character: range[:column] - 1 + name.length }, }, } refs = if include_declaration [declaration_location] else [] end mock_token = Struct.new(:lexeme, :type, :line, :column).new(name, :identifier, param.line, param.column) scoped_refs = scoped_local_reference_locations(uri, mock_token, param.line - 1, param.column - 1, facts, include_declaration: false) if scoped_refs refs.concat(scoped_refs) else refs end end |
#process_message(message) ⇒ Object
── Message dispatch ─────────────────────────────────────────────────────
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
# File 'lib/milk_tea/lsp/server.rb', line 352 def () method_name = ['method'] params = ['params'] || {} id = ['id'] if .key?('id') && !.key?('method') Protocol.handle_response() elsif .key?('id') handle_request(method_name, params, id) else handle_notification(method_name, params) end rescue StandardError => e (:warning, "Error processing message: #{e.}") @protocol.write_error(id, -32_603, 'Internal server error') if id && .key?('method') end |
#register_handlers ⇒ Object
── Handler registration ─────────────────────────────────────────────────
286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 |
# File 'lib/milk_tea/lsp/server.rb', line 286 def register_handlers # Lifecycle @handlers['initialize'] = method(:handle_initialize) @handlers['initialized'] = method(:handle_initialized) @handlers['shutdown'] = method(:handle_shutdown) @handlers['exit'] = method(:handle_exit) @handlers['$/cancelRequest'] = method(:handle_cancel_request) # Text document sync @handlers['milkTea/documentContext'] = method(:handle_document_context) @handlers['textDocument/didOpen'] = method(:handle_did_open) @handlers['textDocument/didChange'] = method(:handle_did_change) @handlers['textDocument/didClose'] = method(:handle_did_close) @handlers['textDocument/didSave'] = method(:handle_did_save) @handlers['textDocument/willSaveWaitUntil'] = method(:handle_will_save_wait_until) # IDE features @handlers['textDocument/hover'] = method(:handle_hover) @handlers['textDocument/definition'] = method(:handle_definition) @handlers['textDocument/declaration'] = method(:handle_declaration) @handlers['textDocument/typeDefinition'] = method(:handle_type_definition) @handlers['textDocument/implementation'] = method(:handle_implementation) @handlers['textDocument/references'] = method(:handle_references) @handlers['milkTea/debugInfo'] = method(:handle_debug_info) @handlers['textDocument/documentLink'] = method(:handle_document_link) @handlers['documentLink/resolve'] = method(:handle_document_link_resolve) @handlers['textDocument/documentHighlight'] = method(:handle_document_highlight) @handlers['textDocument/documentSymbol'] = method(:handle_document_symbols) @handlers['textDocument/formatting'] = method(:handle_formatting) @handlers['textDocument/rangeFormatting'] = method(:handle_range_formatting) @handlers['textDocument/onTypeFormatting'] = method(:handle_on_type_formatting) @handlers['textDocument/foldingRange'] = method(:handle_folding_range) @handlers['textDocument/completion'] = method(:handle_completion) @handlers['completionItem/resolve'] = method(:handle_completion_resolve) @handlers['textDocument/codeAction'] = method(:handle_code_action) @handlers['textDocument/codeLens'] = method(:handle_code_lens) @handlers['codeLens/resolve'] = method(:handle_code_lens_resolve) @handlers['textDocument/prepareCallHierarchy'] = method(:handle_prepare_call_hierarchy) @handlers['callHierarchy/incomingCalls'] = method(:handle_incoming_calls) @handlers['callHierarchy/outgoingCalls'] = method(:handle_outgoing_calls) @handlers['textDocument/inlayHint'] = method(:handle_inlay_hint) @handlers['textDocument/semanticTokens/full'] = method(:handle_semantic_tokens_full) @handlers['textDocument/semanticTokens/full/delta'] = method(:handle_semantic_tokens_delta) @handlers['textDocument/semanticTokens/range'] = method(:handle_semantic_tokens_range) @handlers['textDocument/selectionRange'] = method(:handle_selection_range) @handlers['textDocument/diagnostic'] = method(:handle_document_diagnostic) @handlers['workspace/diagnostic'] = method(:handle_workspace_diagnostic) @handlers['textDocument/signatureHelp'] = method(:handle_signature_help) @handlers['textDocument/prepareTypeHierarchy'] = method(:handle_prepare_type_hierarchy) @handlers['typeHierarchy/supertypes'] = method(:handle_supertypes) @handlers['typeHierarchy/subtypes'] = method(:handle_subtypes) @handlers['textDocument/prepareRename'] = method(:handle_prepare_rename) @handlers['textDocument/rename'] = method(:handle_rename) @handlers['textDocument/linkedEditingRange'] = method(:handle_linked_editing_range) # Workspace @handlers['workspace/symbol'] = method(:handle_workspace_symbol) @handlers['workspace/executeCommand'] = method(:handle_execute_command) @handlers['workspace/didChangeWorkspaceFolders'] = method(:handle_did_change_workspace_folders) @handlers['workspace/didChangeConfiguration'] = method(:handle_did_change_configuration) @handlers['workspace/didChangeWatchedFiles'] = method(:handle_did_change_watched_files) @handlers['workspace/willRenameFiles'] = method(:handle_will_rename_files) end |
#run ⇒ Object
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/milk_tea/lsp/server.rb', line 240 def run if perf_logging? mode = perf_verbose? ? 'verbose' : 'threshold' warn "[LSP perf] enabled mode=#{mode} threshold_ms=#{Workspace::PERF_LOG_THRESHOLD_MS}" end loop do = @protocol. break if .nil? next if .equal?(Protocol::INVALID_MESSAGE) () end rescue StandardError => e warn "Server error: #{e.}" raise end |