Class: Ibex::LSP::SymbolIndex
- Inherits:
-
Object
- Object
- Ibex::LSP::SymbolIndex
- Defined in:
- lib/ibex/lsp/symbol_index.rb
Overview
Answers source navigation and guarded workspace rename operations.
Constant Summary collapse
- IDENTIFIER =
: Regexp
/\A[A-Za-z_][A-Za-z0-9_]*\z/- RESERVED =
%w[ class fragment include token prechigh preclow left right nonassoc options expect start recover sync on_error_reduce convert display type pragma extended rule end separated_list separated_nonempty_list ].freeze
Instance Method Summary collapse
- #definition(path, position) ⇒ Object
- #hover(path, position) ⇒ Object
-
#initialize(store, path) ⇒ SymbolIndex
constructor
A new instance of SymbolIndex.
- #prepare_rename(path, position) ⇒ Object
- #references(path, position, include_declaration: false) ⇒ Object
- #rename(path, position, new_name) ⇒ Object
Constructor Details
#initialize(store, path) ⇒ SymbolIndex
Returns a new instance of SymbolIndex.
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/ibex/lsp/symbol_index.rb', line 15 def initialize(store, path) @store = store @path = path files = store.files_for(path) @occurrences, @documents = SymbolIndexBuilder.new(store, files).build @snapshot_state = files.to_h do |file| snapshot = store.snapshot_for(file) [file, snapshot && [snapshot.fetch(:version), snapshot.fetch(:source)]] end #: Hash[String, Array[untyped]?] end |
Instance Method Details
#definition(path, position) ⇒ Object
27 28 29 30 31 32 33 |
# File 'lib/ibex/lsp/symbol_index.rb', line 27 def definition(path, position) occurrence = occurrence_at(path, position) return [] unless occurrence return [include_target_location(occurrence)] if occurrence.kind == :include matching(occurrence.key, role: :definition).map { |entry| location(entry) } end |
#hover(path, position) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/ibex/lsp/symbol_index.rb', line 82 def hover(path, position) occurrence = occurrence_at(path, position) return unless occurrence value = hover_value(occurrence) return unless value { "contents" => { "kind" => "markdown", "value" => value }, "range" => range(occurrence) } end |
#prepare_rename(path, position) ⇒ Object
47 48 49 50 |
# File 'lib/ibex/lsp/symbol_index.rb', line 47 def prepare_rename(path, position) occurrence = renameable_occurrence(path, position) { "range" => range(occurrence), "placeholder" => occurrence.name } end |
#references(path, position, include_declaration: false) ⇒ Object
37 38 39 40 41 42 43 44 |
# File 'lib/ibex/lsp/symbol_index.rb', line 37 def references(path, position, include_declaration: false) occurrence = occurrence_at(path, position) return [] unless occurrence entries = matching(occurrence.key) entries = entries.reject { |entry| entry.role == :definition } unless include_declaration entries.map { |entry| location(entry) } end |
#rename(path, position, new_name) ⇒ Object
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/ibex/lsp/symbol_index.rb', line 53 def rename(path, position, new_name) ensure_fresh! occurrence = renameable_occurrence(path, position) validate_new_name(occurrence, new_name) entries = matching(occurrence.key) validate_unshared(entries) validate_nonoverlapping(entries) changes = entries.group_by(&:path).transform_values do |path_entries| path_entries.sort_by { |entry| entry.span.start_byte }.map do |entry| { "range" => range(entry), "newText" => new_name } end end replacements = changed_sources(entries, new_name) unless @store.valid_replacements?(replacements) raise ProtocolError.new("rename would make the affected grammar closure invalid", code: -32_602) end document_changes = changes.sort.map do |changed_path, edits| snapshot = @store.snapshot_for(changed_path) version = snapshot&.fetch(:open) ? snapshot.fetch(:version) : nil { "textDocument" => { "uri" => @store.uri_for(changed_path), "version" => version }, "edits" => edits } end { "documentChanges" => document_changes } end |