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

Returns a new instance of Store.

Parameters:



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>

Returns:



195
196
197
# File 'lib/solargraph/api_map/store.rb', line 195

def block_pins
  pins_by_class(Pin::Block)
end

#constantsConstants

Returns:



272
273
274
# File 'lib/solargraph/api_map/store.rb', line 272

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

#domains(fqns) ⇒ Array<String>

Parameters:

  • fqns (String)

Returns:

  • (Array<String>)


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

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

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

Parameters:

  • fqns (String, nil)

Returns:



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

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_ancestor_references(fqns) ⇒ Array<Solargraph::Pin::Reference>

Parameters:

  • fqns (String)

Returns:



267
268
269
# File 'lib/solargraph/api_map/store.rb', line 267

def get_ancestor_references fqns
  (get_prepends(fqns) + get_includes(fqns) + [get_superclass(fqns)]).compact
end

#get_ancestors(fqns) ⇒ Array<String>

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

Parameters:

  • fqns (String)

    The fully qualified namespace

Returns:

  • (Array<String>)

    Array of ancestor namespaces including the original



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
257
258
259
260
261
262
# File 'lib/solargraph/api_map/store.rb', line 224

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?
      # @param ref [String]
      refs.map(&:type).map(&:to_s).each do |ref|
        # @sg-ignore flow sensitive typing should be able to handle redefinition
        next if ref.nil? || ref.empty? || visited.include?(ref)
        # @sg-ignore flow sensitive typing should be able to handle redefinition
        ancestors << ref
        # @sg-ignore flow sensitive typing should be able to handle redefinition
        queue << ref
      end
    end
  end

  ancestors.compact.uniq
end

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

Parameters:

  • fqns (String)

Returns:



145
146
147
# File 'lib/solargraph/api_map/store.rb', line 145

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

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

Parameters:

  • fqns (String)
  • visibility (Array<Symbol>) (defaults to: [:public])

Returns:



65
66
67
68
69
70
# File 'lib/solargraph/api_map/store.rb', line 65

def get_constants fqns, visibility = [:public]
  namespace_children(fqns).select do |pin|
    # @sg-ignore flow sensitive typing not smart enough to handle this case
    !pin.name.empty? && (pin.is_a?(Pin::Namespace) || pin.is_a?(Pin::Constant)) && visibility.include?(pin.visibility)
  end
end

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

Parameters:

  • fqns (String)

Returns:



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

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

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

Parameters:

  • fqns (String)

Returns:



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

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

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

Parameters:

  • fqns (String, nil)
  • scope (Symbol) (defaults to: :instance)

    :class or :instance

Returns:



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

def get_instance_variables fqns, scope = :instance
  all_instance_variables.select do |pin|
    pin.binder.namespace == fqns && pin.binder.scope == scope
  end
end

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

Parameters:

  • fqns (String)
  • scope (Symbol) (defaults to: :instance)
  • visibility (Array<Symbol>) (defaults to: [:public])

Returns:



76
77
78
79
80
# File 'lib/solargraph/api_map/store.rb', line 76

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

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

Parameters:

  • path (String)

Returns:



129
130
131
# File 'lib/solargraph/api_map/store.rb', line 129

def get_path_pins path
  index.path_pin_hash[path]
end

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

Parameters:

  • fqns (String)

Returns:



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

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

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

Parameters:

  • fqns (String, nil)

Returns:



89
90
91
92
93
94
# File 'lib/solargraph/api_map/store.rb', line 89

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>

Returns:



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

def get_symbols
  symbols.uniq(&:name)
end

#inspectObject



58
59
60
# File 'lib/solargraph/api_map/store.rb', line 58

def inspect
  to_s
end

#macro_method_name_pinsHash{String => Array<Pin::Method>}

Returns:



288
289
290
# File 'lib/solargraph/api_map/store.rb', line 288

def macro_method_name_pins
  index.macro_method_name_pins
end

#macro_method_namesArray<String>

Returns:

  • (Array<String>)


283
284
285
# File 'lib/solargraph/api_map/store.rb', line 283

def macro_method_names
  index.macro_method_names
end

#method_pinsEnumerable<Solargraph::Pin::Method>

Returns:



166
167
168
# File 'lib/solargraph/api_map/store.rb', line 166

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

#named_macrosHash{String => YardMap::Macro}

Returns:



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

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

Parameters:

  • fqns (String)

Returns:

  • (Boolean)


156
157
158
# File 'lib/solargraph/api_map/store.rb', line 156

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

#namespace_pinsEnumerable<Solargraph::Pin::Namespace>

Returns:



161
162
163
# File 'lib/solargraph/api_map/store.rb', line 161

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

#pinsArray<Solargraph::Pin::Base>

Returns:



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

def pins
  index.pins
end

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

Parameters:

  • klass (Class<generic<T>>)

Returns:

  • (Set<generic<T>>)


202
203
204
# File 'lib/solargraph/api_map/store.rb', line 202

def pins_by_class klass
  index.pins_by_class klass
end

#qualify_superclass(fq_sub_tag) ⇒ String?

Parameters:

  • fq_sub_tag (String)

Returns:

  • (String, nil)


98
99
100
101
102
103
104
105
106
107
# File 'lib/solargraph/api_map/store.rb', line 98

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
end

#to_sObject



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

def to_s
  self.class.to_s
end

#unalias(name) ⇒ ComplexType?

Parameters:

  • name (String)

Returns:



278
279
280
# File 'lib/solargraph/api_map/store.rb', line 278

def unalias name
  index.alias_hash[name]
end

#update(*pinsets, &block) ⇒ Boolean

Returns True if the index was updated.

Parameters:

Returns:

  • (Boolean)

    True if the index was updated



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

def update *pinsets, &block
  return catalog(pinsets, &block) 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.zero?

  # @sg-ignore Need to add nil check here
  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
  # @type [Index]
  @index = @indexes.last.clone
  @index = @index.merge(block.call) if block
  constants.clear
  cached_qualify_superclass.clear
  true
end