Class: Solargraph::ApiMap::Store

Inherits:
Object
  • Object
show all
Defined in:
lib/solargraph/api_map/store.rb

Overview

Queryable collection of Pins representing a Workspace, gems and the Ruby core.

Constant Summary collapse

BOOLEAN_SUPERCLASS_PIN =
Pin::Reference::Superclass.new(name: 'Boolean', closure: Pin::ROOT_PIN, source: :solargraph)
OBJECT_SUPERCLASS_PIN =
Pin::Reference::Superclass.new(name: 'Object', closure: Pin::ROOT_PIN, source: :solargraph)

Instance Method Summary collapse

Constructor Details

#initialize(*pinsets) ⇒ Store



10
11
12
13
# File 'lib/solargraph/api_map/store.rb', line 10

def initialize *pinsets
  @pinsets = pinsets
  catalog pinsets
end

Instance Method Details

#block_pinsEnumerable<Pin::Block>



193
194
195
# File 'lib/solargraph/api_map/store.rb', line 193

def block_pins
  pins_by_class(Pin::Block)
end

#constantsConstants



259
260
261
# File 'lib/solargraph/api_map/store.rb', line 259

def constants
  @constants ||= Constants.new(self)
end

#domains(fqns) ⇒ Array<String>



170
171
172
173
174
175
176
# File 'lib/solargraph/api_map/store.rb', line 170

def domains(fqns)
  result = []
  fqns_pins(fqns).each do |nspin|
    result.concat nspin.domains
  end
  result
end

#fqns_pins(fqns) ⇒ Array<Solargraph::Pin::Namespace>



206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/solargraph/api_map/store.rb', line 206

def fqns_pins fqns
  return [] if fqns.nil?
  if fqns.include?('::')
    parts = fqns.split('::')
    name = parts.pop
    base = parts.join('::')
  else
    base = ''
    name = fqns
  end
  fqns_pins_map[[base, name]]
end

#get_ancestors(fqns) ⇒ Array<String>

Get all ancestors (superclasses, includes, prepends, extends) for a namespace



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/solargraph/api_map/store.rb', line 222

def get_ancestors(fqns)
  return [] if fqns.nil? || fqns.empty?

  ancestors = [fqns]
  visited = Set.new
  queue = [fqns]

  until queue.empty?
    current = queue.shift
    next if current.nil? || current.empty? || visited.include?(current)
    visited.add(current)

    current = current.gsub(/^::/, '')

    # Add superclass

    ref = get_superclass(current)
    superclass = ref && constants.dereference(ref)
    if superclass && !superclass.empty? && !visited.include?(superclass)
      ancestors << superclass
      queue << superclass
    end

    # Add includes, prepends, and extends

    [get_includes(current), get_prepends(current), get_extends(current)].each do |refs|
      next if refs.nil?
      refs.map(&:parametrized_tag).map(&:to_s).each do |ref|
        next if ref.nil? || ref.empty? || visited.include?(ref)
        ancestors << ref
        queue << ref
      end
    end
  end

  ancestors.compact.uniq
end

#get_class_variables(fqns) ⇒ Enumerable<Solargraph::Pin::Base>



138
139
140
# File 'lib/solargraph/api_map/store.rb', line 138

def get_class_variables(fqns)
  namespace_children(fqns).select { |pin| pin.is_a?(Pin::ClassVariable)}
end

#get_constants(fqns, visibility = [:public]) ⇒ Enumerable<Solargraph::Pin::Base>



61
62
63
64
65
# File 'lib/solargraph/api_map/store.rb', line 61

def get_constants fqns, visibility = [:public]
  namespace_children(fqns).select { |pin|
    !pin.name.empty? && (pin.is_a?(Pin::Namespace) || pin.is_a?(Pin::Constant)) && visibility.include?(pin.visibility)
  }
end

#get_extends(fqns) ⇒ Array<Pin::Reference::Extend>



117
118
119
# File 'lib/solargraph/api_map/store.rb', line 117

def get_extends fqns
  extend_references[fqns] || []
end

#get_includes(fqns) ⇒ Array<Pin::Reference::Include>



105
106
107
# File 'lib/solargraph/api_map/store.rb', line 105

def get_includes fqns
  include_references[fqns] || []
end

#get_instance_variables(fqns, scope = :instance) ⇒ Enumerable<Solargraph::Pin::Base>



130
131
132
133
134
# File 'lib/solargraph/api_map/store.rb', line 130

def get_instance_variables(fqns, scope = :instance)
  all_instance_variables.select { |pin|
    pin.binder.namespace == fqns && pin.binder.scope == scope
  }
end

#get_methods(fqns, scope: :instance, visibility: [:public]) ⇒ Enumerable<Solargraph::Pin::Method>



71
72
73
74
75
76
# File 'lib/solargraph/api_map/store.rb', line 71

def get_methods fqns, scope: :instance, visibility: [:public]
  all_pins = namespace_children(fqns).select do |pin|
    pin.is_a?(Pin::Method) && pin.scope == scope && visibility.include?(pin.visibility)
  end
  GemPins.combine_method_pins_by_path(all_pins)
end

#get_path_pins(path) ⇒ Array<Solargraph::Pin::Base>



123
124
125
# File 'lib/solargraph/api_map/store.rb', line 123

def get_path_pins path
  index.path_pin_hash[path]
end

#get_prepends(fqns) ⇒ Array<Pin::Reference::Prepend>



111
112
113
# File 'lib/solargraph/api_map/store.rb', line 111

def get_prepends fqns
  prepend_references[fqns] || []
end

#get_superclass(fqns) ⇒ Pin::Reference::Superclass



83
84
85
86
87
88
# File 'lib/solargraph/api_map/store.rb', line 83

def get_superclass fqns
  return nil if fqns.nil? || fqns.empty?
  return BOOLEAN_SUPERCLASS_PIN if %w[TrueClass FalseClass].include?(fqns)

  superclass_references[fqns].first || try_special_superclasses(fqns)
end

#get_symbolsEnumerable<Solargraph::Pin::Base>



143
144
145
# File 'lib/solargraph/api_map/store.rb', line 143

def get_symbols
  symbols.uniq(&:name)
end

#inspectObject



54
55
56
# File 'lib/solargraph/api_map/store.rb', line 54

def inspect
  to_s
end

#method_pinsEnumerable<Solargraph::Pin::Method>



164
165
166
# File 'lib/solargraph/api_map/store.rb', line 164

def method_pins
  pins_by_class(Solargraph::Pin::Method)
end

#named_macrosHash{String => YARD::Tags::MacroDirective}



179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/solargraph/api_map/store.rb', line 179

def named_macros
  @named_macros ||= begin
    result = {}
    pins.each do |pin|
      pin.macros.select{|m| m.tag.tag_name == 'macro' && !m.tag.text.empty? }.each do |macro|
        next if macro.tag.name.nil? || macro.tag.name.empty?
        result[macro.tag.name] = macro
      end
    end
    result
  end
end

#namespace_exists?(fqns) ⇒ Boolean



149
150
151
# File 'lib/solargraph/api_map/store.rb', line 149

def namespace_exists?(fqns)
  fqns_pins(fqns).any?
end

#namespace_pinsEnumerable<Solargraph::Pin::Namespace>



159
160
161
# File 'lib/solargraph/api_map/store.rb', line 159

def namespace_pins
  pins_by_class(Solargraph::Pin::Namespace)
end

#namespacesSet<String>



154
155
156
# File 'lib/solargraph/api_map/store.rb', line 154

def namespaces
  index.namespaces
end

#pinsArray<Solargraph::Pin::Base>



16
17
18
# File 'lib/solargraph/api_map/store.rb', line 16

def pins
  index.pins
end

#pins_by_class(klass) ⇒ Set<generic<T>>



200
201
202
# File 'lib/solargraph/api_map/store.rb', line 200

def pins_by_class klass
  index.pins_by_class klass
end

#qualify_superclass(fq_sub_tag) ⇒ String?



92
93
94
95
96
97
98
99
100
101
# File 'lib/solargraph/api_map/store.rb', line 92

def qualify_superclass fq_sub_tag
  cached_qualify_superclass[fq_sub_tag] || qualify_and_cache_superclass(fq_sub_tag)
  type = ComplexType.try_parse(fq_sub_tag)
  return type.simplify_literals.to_s if type.literal?
  ref = get_superclass(fq_sub_tag)
  return unless ref
  res = constants.dereference(ref)
  return unless res
  res + type.substring
end

#to_sObject



50
51
52
# File 'lib/solargraph/api_map/store.rb', line 50

def to_s
  self.class.to_s
end

#update(*pinsets) ⇒ Boolean



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/solargraph/api_map/store.rb', line 27

def update *pinsets
  return catalog(pinsets) if pinsets.length != @pinsets.length

  changed = pinsets.find_index.with_index { |pinset, idx| @pinsets[idx] != pinset }
  return false unless changed

  # @todo Fix this map

  @fqns_pins_map = nil
  return catalog(pinsets) if changed == 0

  pinsets[changed..].each_with_index do |pins, idx|
    @pinsets[changed + idx] = pins
    @indexes[changed + idx] = if pins.empty?
      @indexes[changed + idx - 1]
    else
      @indexes[changed + idx - 1].merge(pins)
    end
  end
  constants.clear
  cached_qualify_superclass.clear
  true
end