Class: Kapusta::LSP::WorkspaceIndex
- Inherits:
-
Object
- Object
- Kapusta::LSP::WorkspaceIndex
- Defined in:
- lib/kapusta/lsp/workspace_index.rb
Defined Under Namespace
Classes: Entry
Constant Summary collapse
- MACRO_MODULE_EXTENSIONS =
%w[kapm kap].freeze
- SCAN_EXTENSIONS =
%w[kap kapm].freeze
Instance Method Summary collapse
- #constant_definition_with_prefix?(prefix, except_prefix: nil) ⇒ Boolean
- #constant_definitions_with_prefix(prefix) ⇒ Object
- #constant_occurrences(prefix) ⇒ Object
- #each_entry ⇒ Object
- #entry(uri) ⇒ Object
- #entry_count ⇒ Object
- #find_macro_definition(importing_uri, module_label, import_key) ⇒ Object
- #import_resolves_to?(importing_uri, module_label, target_uri) ⇒ Boolean
-
#initialize(roots: []) ⇒ WorkspaceIndex
constructor
A new instance of WorkspaceIndex.
- #macro_definition_anywhere?(name, except_uri: nil) ⇒ Boolean
- #refresh(uri, text) ⇒ Object
- #remove(uri) ⇒ Object
- #scan! ⇒ Object
- #toplevel_definition?(name, except_name: nil) ⇒ Boolean
- #toplevel_fn_definitions(name) ⇒ Object
- #toplevel_fn_occurrences(name) ⇒ Object
Constructor Details
#initialize(roots: []) ⇒ WorkspaceIndex
Returns a new instance of WorkspaceIndex.
15 16 17 18 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 15 def initialize(roots: []) @roots = Array(roots) @entries = {} end |
Instance Method Details
#constant_definition_with_prefix?(prefix, except_prefix: nil) ⇒ Boolean
104 105 106 107 108 109 110 111 112 113 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 104 def constant_definition_with_prefix?(prefix, except_prefix: nil) @entries.any? do |_uri, entry| entry.walker.bindings.any? do |b| next false unless %i[module class].include?(b.kind) next false if except_prefix && matches_prefix?(b.sym, except_prefix) matches_prefix?(b.sym, prefix) end end end |
#constant_definitions_with_prefix(prefix) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 64 def constant_definitions_with_prefix(prefix) result = [] @entries.each do |uri, entry| entry.walker.bindings.each do |b| next unless %i[module class].include?(b.kind) segs = b.sym.dotted? ? b.sym.segments : [b.sym.name] result << [uri, b] if segs == prefix end end result end |
#constant_occurrences(prefix) ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 145 def constant_occurrences(prefix) result = {} @entries.each do |uri, entry| occs = [] entry.walker.bindings.each do |b| next unless %i[module class].include?(b.kind) occs << b if matches_prefix?(b.sym, prefix) end entry.walker.references.each do |r| sym = r.sym next unless sym.is_a?(Sym) next unless r.target.nil? next unless first_segment_capitalized?(sym) occs << r if matches_prefix?(sym, prefix) end result[uri] = occs unless occs.empty? end result end |
#each_entry ⇒ Object
115 116 117 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 115 def each_entry(&) @entries.each(&) end |
#entry(uri) ⇒ Object
46 47 48 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 46 def entry(uri) @entries[uri] end |
#entry_count ⇒ Object
50 51 52 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 50 def entry_count @entries.length end |
#find_macro_definition(importing_uri, module_label, import_key) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 119 def find_macro_definition(importing_uri, module_label, import_key) target_name = import_key.to_s.tr('_', '-') resolve_module_uris(importing_uri, module_label).each do |uri| entry = @entries[uri] next unless entry binding = entry.walker.bindings.find do |b| %i[macro toplevel_fn].include?(b.kind) && b.name == target_name end return [uri, binding] if binding end nil end |
#import_resolves_to?(importing_uri, module_label, target_uri) ⇒ Boolean
133 134 135 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 133 def import_resolves_to?(importing_uri, module_label, target_uri) resolve_module_uris(importing_uri, module_label).include?(target_uri) end |
#macro_definition_anywhere?(name, except_uri: nil) ⇒ Boolean
137 138 139 140 141 142 143 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 137 def macro_definition_anywhere?(name, except_uri: nil) @entries.any? do |uri, entry| next false if except_uri && uri == except_uri entry.walker.bindings.any? { |b| b.kind == :macro && b.name == name } end end |
#refresh(uri, text) ⇒ Object
33 34 35 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 33 def refresh(uri, text) store(uri, text) end |
#remove(uri) ⇒ Object
37 38 39 40 41 42 43 44 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 37 def remove(uri) path = uri_to_path(uri) if path && File.file?(path) store(uri, File.read(path)) else @entries.delete(uri) end end |
#scan! ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 20 def scan! @roots.each do |root| SCAN_EXTENSIONS.each do |ext| Dir.glob(File.join(root, '**', "*.#{ext}")).each do |path| uri = path_to_uri(path) text = File.read(path) store(uri, text) end end end self end |
#toplevel_definition?(name, except_name: nil) ⇒ Boolean
93 94 95 96 97 98 99 100 101 102 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 93 def toplevel_definition?(name, except_name: nil) @entries.any? do |_uri, entry| entry.walker.bindings.any? do |b| next false unless file_toplevel_binding?(b) next false if except_name && b.name == except_name b.name == name end end end |
#toplevel_fn_definitions(name) ⇒ Object
54 55 56 57 58 59 60 61 62 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 54 def toplevel_fn_definitions(name) result = [] @entries.each do |uri, entry| entry.walker.bindings.each do |b| result << [uri, b] if b.kind == :toplevel_fn && b.name == name end end result end |
#toplevel_fn_occurrences(name) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/kapusta/lsp/workspace_index.rb', line 77 def toplevel_fn_occurrences(name) result = {} @entries.each do |uri, entry| occs = entry.walker.bindings.select do |b| b.kind == :toplevel_fn && b.name == name end occs += entry.walker.references.select do |r| next false unless r.sym.is_a?(Sym) && !r.sym.dotted? && r.name == name r.target.nil? || (r.target.kind == :toplevel_fn && r.target.name == name) end result[uri] = occs unless occs.empty? end result end |