Class: Solargraph::SourceMap

Inherits:
Object
  • Object
show all
Defined in:
lib/solargraph/source_map.rb,
lib/solargraph/source_map/clip.rb,
lib/solargraph/source_map/mapper.rb,
lib/solargraph/source_map/completion.rb

Overview

An index of pins and other ApiMap-related data for a Source.

Defined Under Namespace

Classes: Clip, Completion, Mapper

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, pins, locals) ⇒ SourceMap

Returns a new instance of SourceMap.

Parameters:



26
27
28
29
30
31
32
33
34
35
# File 'lib/solargraph/source_map.rb', line 26

def initialize source, pins, locals
  # HACK: Keep the library from changing this
  @source = source.dup
  @pins = pins
  @locals = locals
  environ.merge Convention.for_local(self) unless filename.nil?
  self.convention_pins = environ.pins
  @pin_class_hash = pins.to_set.classify(&:class).transform_values(&:to_a)
  @pin_select_cache = {}
end

Instance Attribute Details

#localsArray<Pin::LocalVariable> (readonly)

Returns:



21
22
23
# File 'lib/solargraph/source_map.rb', line 21

def locals
  @locals
end

#pinsArray<Pin::Base> (readonly)

Returns:



18
19
20
# File 'lib/solargraph/source_map.rb', line 18

def pins
  @pins
end

#sourceSource (readonly)

Returns:



15
16
17
# File 'lib/solargraph/source_map.rb', line 15

def source
  @source
end

Class Method Details

.load(filename) ⇒ SourceMap

Parameters:

  • filename (String)

Returns:



149
150
151
152
# File 'lib/solargraph/source_map.rb', line 149

def load filename
  source = Solargraph::Source.load(filename)
  SourceMap.map(source)
end

.load_string(code, filename = nil) ⇒ SourceMap

Parameters:

  • code (String)
  • filename (String, nil) (defaults to: nil)

Returns:



157
158
159
160
# File 'lib/solargraph/source_map.rb', line 157

def load_string code, filename = nil
  source = Solargraph::Source.load_string(code, filename)
  SourceMap.map(source)
end

.map(source) ⇒ SourceMap

Parameters:

Returns:



164
165
166
167
# File 'lib/solargraph/source_map.rb', line 164

def map source
  result = SourceMap::Mapper.map(source)
  new(source, *result)
end

Instance Method Details

#codeString

Returns:

  • (String)


57
58
59
# File 'lib/solargraph/source_map.rb', line 57

def code
  source.code
end

#cursor_at(position) ⇒ Source::Cursor

Parameters:

Returns:



87
88
89
# File 'lib/solargraph/source_map.rb', line 87

def cursor_at position
  Source::Cursor.new(source, position)
end

#document_symbolsArray<Pin::Base>

all pins except Solargraph::Pin::Reference::Reference

Returns:



73
74
75
76
77
# File 'lib/solargraph/source_map.rb', line 73

def document_symbols
  @document_symbols ||= (pins + convention_pins).select do |pin|
    pin.path && !pin.path.empty?
  end
end

#environEnviron

Returns:



67
68
69
# File 'lib/solargraph/source_map.rb', line 67

def environ
  @environ ||= Environ.new
end

#filenameString

Returns:

  • (String)


52
53
54
# File 'lib/solargraph/source_map.rb', line 52

def filename
  source.filename
end

#first_pin(path) ⇒ Pin::Base

Parameters:

  • path (String)

Returns:



93
94
95
# File 'lib/solargraph/source_map.rb', line 93

def first_pin path
  pins.select { |p| p.path == path }.first
end

#locals_at(location) ⇒ Array<Pin::LocalVariable>

Parameters:

Returns:



140
141
142
143
144
# File 'lib/solargraph/source_map.rb', line 140

def locals_at(location)
  return [] if location.filename != filename
  closure = locate_named_path_pin(location.range.start.line, location.range.start.character)
  locals.select { |pin| pin.visible_at?(closure, location) }
end

#locate_block_pin(line, character) ⇒ Pin::Namespace, ...

Parameters:

  • line (Integer)
  • character (Integer)

Returns:



114
115
116
# File 'lib/solargraph/source_map.rb', line 114

def locate_block_pin line, character
  _locate_pin line, character, Pin::Namespace, Pin::Method, Pin::Block
end

#locate_named_path_pin(line, character) ⇒ Pin::Method, Pin::Namespace

Parameters:

  • line (Integer)
  • character (Integer)

Returns:



107
108
109
# File 'lib/solargraph/source_map.rb', line 107

def locate_named_path_pin line, character
  _locate_pin line, character, Pin::Namespace, Pin::Method
end

#locate_pins(location) ⇒ Array<Solargraph::Pin::Base>

Parameters:

Returns:



99
100
101
102
# File 'lib/solargraph/source_map.rb', line 99

def locate_pins location
  # return nil unless location.start_with?("#{filename}:")
  (pins + locals).select { |pin| pin.location == location }
end

#pins_by_class(klass) ⇒ Array<Pin::Base>

Parameters:

  • klass (Class)

Returns:



39
40
41
# File 'lib/solargraph/source_map.rb', line 39

def pins_by_class klass
  @pin_select_cache[klass] ||= @pin_class_hash.select { |key, _| key <= klass }.values.flatten
end

#query_symbols(query) ⇒ Array<Pin::Base>

Parameters:

  • query (String)

Returns:



81
82
83
# File 'lib/solargraph/source_map.rb', line 81

def query_symbols query
  Pin::Search.new(document_symbols, query).results
end

#rebindable_method_namesSet<String>

Returns:

  • (Set<String>)


44
45
46
47
48
49
# File 'lib/solargraph/source_map.rb', line 44

def rebindable_method_names
  @rebindable_method_names ||= pins_by_class(Pin::Method)
    .select { |pin| pin.comments && pin.comments.include?('@yieldreceiver') }
    .map(&:name)
    .to_set
end

#references(name) ⇒ Array<Location>

Parameters:

  • name (String)

Returns:



134
135
136
# File 'lib/solargraph/source_map.rb', line 134

def references name
  source.references name
end

#requiresArray<Pin::Reference::Require>

Returns:



62
63
64
# File 'lib/solargraph/source_map.rb', line 62

def requires
  pins_by_class(Pin::Reference::Require)
end

#try_merge!(other_map) ⇒ Boolean

Parameters:

Returns:

  • (Boolean)


120
121
122
123
124
125
126
127
128
129
130
# File 'lib/solargraph/source_map.rb', line 120

def try_merge! other_map
  return false if pins.length != other_map.pins.length || locals.length != other_map.locals.length || requires.map(&:name).uniq.sort != other_map.requires.map(&:name).uniq.sort
  pins.each_index do |i|
    return false unless pins[i].try_merge!(other_map.pins[i])
  end
  locals.each_index do |i|
    return false unless locals[i].try_merge!(other_map.locals[i])
  end
  @source = other_map.source
  true
end