solargraph 0.27.1 → 0.28.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/solargraph.rb +8 -17
  3. data/lib/solargraph/api_map.rb +4 -3
  4. data/lib/solargraph/api_map/cache.rb +5 -5
  5. data/lib/solargraph/api_map/source_to_yard.rb +3 -2
  6. data/lib/solargraph/api_map/store.rb +25 -13
  7. data/lib/solargraph/complex_type.rb +3 -0
  8. data/lib/solargraph/diagnostics/update_errors.rb +21 -1
  9. data/lib/solargraph/language_server/host.rb +4 -3
  10. data/lib/solargraph/language_server/message/text_document/rename.rb +1 -1
  11. data/lib/solargraph/library.rb +12 -4
  12. data/lib/solargraph/pin.rb +5 -1
  13. data/lib/solargraph/pin/base.rb +0 -10
  14. data/lib/solargraph/pin/conversions.rb +1 -1
  15. data/lib/solargraph/pin/documenting.rb +0 -9
  16. data/lib/solargraph/pin/duck_method.rb +1 -1
  17. data/lib/solargraph/pin/keyword.rb +0 -5
  18. data/lib/solargraph/pin/namespace.rb +3 -16
  19. data/lib/solargraph/pin/reference.rb +13 -26
  20. data/lib/solargraph/pin/reference/extend.rb +11 -0
  21. data/lib/solargraph/pin/reference/include.rb +11 -0
  22. data/lib/solargraph/pin/reference/require.rb +15 -0
  23. data/lib/solargraph/pin/reference/superclass.rb +11 -0
  24. data/lib/solargraph/pin/symbol.rb +0 -4
  25. data/lib/solargraph/pin/yard_pin/namespace.rb +14 -14
  26. data/lib/solargraph/pin/yard_pin/yard_mixin.rb +0 -4
  27. data/lib/solargraph/position.rb +7 -0
  28. data/lib/solargraph/source.rb +7 -28
  29. data/lib/solargraph/source/chain.rb +0 -1
  30. data/lib/solargraph/source/chain/call.rb +1 -1
  31. data/lib/solargraph/source/chain/constant.rb +13 -4
  32. data/lib/solargraph/source/change.rb +7 -1
  33. data/lib/solargraph/source/cursor.rb +1 -5
  34. data/lib/solargraph/source/node_chainer.rb +5 -6
  35. data/lib/solargraph/source/source_chainer.rb +14 -12
  36. data/lib/solargraph/source_map.rb +5 -6
  37. data/lib/solargraph/source_map/clip.rb +16 -29
  38. data/lib/solargraph/source_map/mapper.rb +26 -21
  39. data/lib/solargraph/version.rb +1 -1
  40. data/lib/solargraph/workspace.rb +1 -2
  41. data/lib/solargraph/workspace/config.rb +10 -5
  42. data/lib/solargraph/yard_map.rb +3 -1
  43. metadata +6 -3
  44. data/lib/solargraph/source/chain/definition.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d239e2f354c236745db64f55ecd2f4c31de560aa8502a61713c185f455eca5a1
4
- data.tar.gz: 468155f7ea49d42a1998bee42b0645af7ba3bbf533b14b20f42ada78ab5161a0
3
+ metadata.gz: 68af7d3f5b6fca0126629ca8ed363004b4c12d2d8ef50a0fc01a571c6459d4cc
4
+ data.tar.gz: 366bbc31b39be7794af1de27a6d63ee88771b22134622dbc6c4ffb146a227712
5
5
  SHA512:
6
- metadata.gz: 56975c593fac1fb79cfdf9461c144e905858e7984aefa16996cba78afff282676f2102bf76ddf3909d89b37fbdf69605eac8d5a27305c0a519678e2000a52589
7
- data.tar.gz: ed3d2636a8e52bfdc61ac804eedc8252a382f674b5cfd43c5da934e1d7e4a7ff268a5291af511309d4c35581458530ff6d26560ad8ab7f8ba81395d9274d77a8
6
+ metadata.gz: 6ffc365f1e42f0a9d17aa40f4721d5f753e94e6b24c0b8c72f43abfc583e740b6e289d7d1ec88b7388c837406e60d2cd1f0376c8c12f477eb3a7ea4de28d579d
7
+ data.tar.gz: d999e3ef14ca1ee00beec4c5eac3906f4c86faccfa9742e1451e85aada0a969d818393b22dbe2be887a9d0346f0ca26810243a49cb6b3b694cead4e81b91cc5c
@@ -3,26 +3,16 @@ require 'solargraph/version'
3
3
  require 'rubygems/package'
4
4
  require 'yard-solargraph'
5
5
 
6
+ # The top-level namespace for the Solargraph code mapping, documentation,
7
+ # static analysis, and language server libraries.
8
+ #
6
9
  module Solargraph
7
10
  class InvalidOffsetError < RangeError; end
8
11
  class DiagnosticsError < RuntimeError; end
9
12
  class FileNotFoundError < RuntimeError; end
10
13
  class SourceNotAvailableError < StandardError; end
11
14
  class ComplexTypeError < StandardError; end
12
- class WorkspaceTooLargeError < RuntimeError
13
- # @return [Integer]
14
- attr_reader :size
15
-
16
- # @return [Integer]
17
- attr_reader :max
18
-
19
- # @param size [Integer] The number of files included in the workspace
20
- # @param max [Integer] The maximum number of files allowed
21
- def initialize size, max
22
- @size = size
23
- @max = max
24
- end
25
- end
15
+ class WorkspaceTooLargeError < RuntimeError; end
26
16
 
27
17
  autoload :Position, 'solargraph/position'
28
18
  autoload :Range, 'solargraph/range'
@@ -45,9 +35,10 @@ module Solargraph
45
35
  autoload :ComplexType, 'solargraph/complex_type'
46
36
  autoload :Bundle, 'solargraph/bundle'
47
37
 
48
- YARDOC_PATH = File.join(File.realpath(File.dirname(__FILE__)), '..', 'yardoc')
49
- YARD_EXTENSION_FILE = File.join(File.realpath(File.dirname(__FILE__)), 'yard-solargraph.rb')
50
- VIEWS_PATH = File.join(File.realpath(File.dirname(__FILE__)), 'solargraph', 'views')
38
+ dir = File.dirname(__FILE__)
39
+ YARDOC_PATH = File.realpath(File.join(dir, '..', 'yardoc'))
40
+ YARD_EXTENSION_FILE = File.join(dir, 'yard-solargraph.rb')
41
+ VIEWS_PATH = File.join(dir, 'solargraph', 'views')
51
42
  end
52
43
 
53
44
  Solargraph::YardMap::CoreDocs.require_minimum
@@ -21,7 +21,6 @@ module Solargraph
21
21
  attr_reader :unresolved_requires
22
22
 
23
23
  # @param pins [Array<Solargraph::Pin::Base>]
24
- # @param yard_map [YardMap]
25
24
  # def initialize workspace = Solargraph::Workspace.new(nil)
26
25
  def initialize pins: []
27
26
  # @todo Extensions don't work yet
@@ -297,6 +296,7 @@ module Solargraph
297
296
  #
298
297
  # @param type [Solargraph::ComplexType]
299
298
  # @param context [String]
299
+ # @param internal [Boolean] True to include private methods
300
300
  # @return [Array<Solargraph::Pin::Base>]
301
301
  def get_complex_type_methods type, context = '', internal = false
302
302
  return [] if type.undefined? || type.void?
@@ -305,6 +305,7 @@ module Solargraph
305
305
  type.select(&:duck_type?).each do |t|
306
306
  result.push Pin::DuckMethod.new(nil, t.tag[1..-1])
307
307
  end
308
+ result.concat get_methods('Object')
308
309
  else
309
310
  unless type.nil? || type.name == 'void'
310
311
  namespace = qualify(type.namespace, context)
@@ -480,7 +481,7 @@ module Solargraph
480
481
  return [] if skip.include?(reqstr)
481
482
  skip.push reqstr
482
483
  result = []
483
- result.concat store.get_methods(fqns, scope: scope, visibility: visibility)
484
+ result.concat store.get_methods(fqns, scope: scope, visibility: visibility).sort{ |a, b| a.name <=> b.name }
484
485
  if deep
485
486
  sc = store.get_superclass(fqns)
486
487
  unless sc.nil?
@@ -520,7 +521,7 @@ module Solargraph
520
521
  return [] if skip.include?(fqns)
521
522
  skip.push fqns
522
523
  result = []
523
- result.concat store.get_constants(fqns, visibility)
524
+ result.concat store.get_constants(fqns, visibility).sort{ |a, b| a.name <=> b.name }
524
525
  store.get_includes(fqns).each do |is|
525
526
  fqis = qualify(is, fqns)
526
527
  result.concat inner_get_constants(fqis, [:public], skip) unless fqis.nil?
@@ -74,11 +74,11 @@ module Solargraph
74
74
 
75
75
  # @return [Boolean]
76
76
  def empty?
77
- @signature_types.empty? and
78
- @assignment_node_types.empty? and
79
- @methods.empty? and
80
- @method_stacks.empty? and
81
- @constants.empty? amd
77
+ @signature_types.empty? &&
78
+ @assignment_node_types.empty? &&
79
+ @methods.empty? &&
80
+ @method_stacks.empty? &&
81
+ @constants.empty? &&
82
82
  @qualified_namespaces.empty?
83
83
  end
84
84
  end
@@ -28,8 +28,9 @@ module Solargraph
28
28
  code_object_map[pin.path].files.push pin.location.filename unless pin.location.nil?
29
29
  end
30
30
  store.namespace_pins.each do |pin|
31
- pin.include_references.each do |ref|
32
- code_object_map[pin.path].instance_mixins.push code_object_map[ref.name] unless code_object_map[ref.name].nil? or code_object_map[pin.path].nil?
31
+ # pin.include_references.each do |ref|
32
+ store.get_includes(pin.path).each do |ref|
33
+ code_object_map[pin.path].instance_mixins.push code_object_map[ref] unless code_object_map[ref].nil? or code_object_map[pin.path].nil?
33
34
  end
34
35
  end
35
36
  store.method_pins.each do |pin|
@@ -34,30 +34,20 @@ module Solargraph
34
34
  # @param fqns [String]
35
35
  # @return [String]
36
36
  def get_superclass fqns
37
- fqns_pins(fqns).each do |pin|
38
- return pin.superclass_reference.name unless pin.superclass_reference.nil?
39
- end
37
+ return superclass_references[fqns].first if superclass_references.has_key?(fqns)
40
38
  nil
41
39
  end
42
40
 
43
41
  # @param fqns [String]
44
42
  # @return [Array<String>]
45
43
  def get_includes fqns
46
- result = []
47
- fqns_pins(fqns).each do |pin|
48
- result.concat pin.include_references.map(&:name)
49
- end
50
- result
44
+ include_references[fqns] || []
51
45
  end
52
46
 
53
47
  # @param fqns [String]
54
48
  # @return [Array<String>]
55
49
  def get_extends fqns
56
- result = []
57
- fqns_pins(fqns).each do |pin|
58
- result.concat pin.extend_references.map(&:name)
59
- end
60
- result
50
+ extend_references[fqns] || []
61
51
  end
62
52
 
63
53
  # @param path [String]
@@ -141,6 +131,18 @@ module Solargraph
141
131
  @symbols ||= []
142
132
  end
143
133
 
134
+ def superclass_references
135
+ @superclass_references ||= {}
136
+ end
137
+
138
+ def include_references
139
+ @include_references ||= {}
140
+ end
141
+
142
+ def extend_references
143
+ @extend_references ||= {}
144
+ end
145
+
144
146
  # @param name [String]
145
147
  # @return [Array<Solargraph::Pin::Namespace>]
146
148
  def namespace_children name
@@ -163,6 +165,16 @@ module Solargraph
163
165
  namespace_map[pin.namespace].push pin
164
166
  namespaces.add pin.path if pin.kind == Pin::NAMESPACE and !pin.path.empty?
165
167
  symbols.push pin if pin.kind == Pin::SYMBOL
168
+ if pin.kind == Pin::INCLUDE_REFERENCE
169
+ include_references[pin.namespace] ||= []
170
+ include_references[pin.namespace].push pin.name
171
+ elsif pin.kind == Pin::EXTEND_REFERENCE
172
+ extend_references[pin.namespace] ||= []
173
+ extend_references[pin.namespace].push pin.name
174
+ elsif pin.kind == Pin::SUPERCLASS_REFERENCE
175
+ superclass_references[pin.namespace] ||= []
176
+ superclass_references[pin.namespace].push pin.name
177
+ end
166
178
  end
167
179
  @namespace_pins = nil
168
180
  @method_pins = nil
@@ -9,11 +9,14 @@ module Solargraph
9
9
  autoload :TypeMethods, 'solargraph/complex_type/type_methods'
10
10
  autoload :UniqueType, 'solargraph/complex_type/unique_type'
11
11
 
12
+ # @param types [Array<ComplexType>]
12
13
  def initialize types = [ComplexType::UNDEFINED]
13
14
  super()
14
15
  concat types
15
16
  end
16
17
 
18
+ # @param api_map [ApiMap]
19
+ # @param context [String]
17
20
  def qualify api_map, context = ''
18
21
  types = map do |t|
19
22
  t.qualify api_map, context
@@ -3,7 +3,7 @@ module Solargraph
3
3
  class UpdateErrors < Base
4
4
  def diagnose source, api_map
5
5
  result = []
6
- source.error_ranges.each do |range|
6
+ combine_ranges(source.code, source.error_ranges).each do |range|
7
7
  result.push(
8
8
  range: range.to_hash,
9
9
  severity: Diagnostics::Severities::ERROR,
@@ -13,6 +13,26 @@ module Solargraph
13
13
  end
14
14
  result
15
15
  end
16
+
17
+ private
18
+
19
+ # Combine an array of ranges by their starting lines.
20
+ #
21
+ # @param ranges [Array<Range>]
22
+ # @return [Array<Range>]
23
+ def combine_ranges code, ranges
24
+ result = []
25
+ lines = []
26
+ ranges.sort{|a, b| a.start.line <=> b.start.line}.each do |rng|
27
+ next if rng.nil? || lines.include?(rng.start.line)
28
+ lines.push rng.start.line
29
+ next if rng.start.line >= code.lines.length
30
+ scol = code.lines[rng.start.line].index(/[^\s]/) || 0
31
+ ecol = code.lines[rng.start.line].length
32
+ result.push Range.from_to(rng.start.line, scol, rng.start.line, ecol)
33
+ end
34
+ result
35
+ end
16
36
  end
17
37
  end
18
38
  end
@@ -186,7 +186,7 @@ module Solargraph
186
186
  rescue WorkspaceTooLargeError => e
187
187
  send_notification 'window/showMessage', {
188
188
  'type' => Solargraph::LanguageServer::MessageTypes::WARNING,
189
- 'message' => "The workspace is too large to index (#{e.size} files, max #{e.max})"
189
+ 'message' => e.message
190
190
  }
191
191
  @library = Solargraph::Library.load(nil)
192
192
  end
@@ -372,9 +372,10 @@ module Solargraph
372
372
  # @param filename [String]
373
373
  # @param line [Integer]
374
374
  # @param column [Integer]
375
+ # @param strip [Boolean] Strip special characters from variable names
375
376
  # @return [Array<Solargraph::Range>]
376
- def references_from filename, line, column
377
- result = library.references_from(filename, line, column)
377
+ def references_from filename, line, column, strip: true
378
+ result = library.references_from(filename, line, column, strip: strip)
378
379
  end
379
380
 
380
381
  # @param query [String]
@@ -1,7 +1,7 @@
1
1
  module Solargraph::LanguageServer::Message::TextDocument
2
2
  class Rename < Base
3
3
  def process
4
- locs = host.references_from(uri_to_file(params['textDocument']['uri']), params['position']['line'], params['position']['character'])
4
+ locs = host.references_from(uri_to_file(params['textDocument']['uri']), params['position']['line'], params['position']['character'], strip: true)
5
5
  changes = {}
6
6
  locs.each do |loc|
7
7
  uri = file_to_uri(loc.filename)
@@ -175,19 +175,27 @@ module Solargraph
175
175
  # @param filename [String]
176
176
  # @param line [Integer]
177
177
  # @param column [Integer]
178
+ # @param strip [Boolean] Strip special characters from variable names
178
179
  # @return [Array<Solargraph::Range>]
179
180
  # @todo Take a Location instead of filename/line/column
180
- def references_from filename, line, column
181
- clip = api_map.clip_at(filename, Position.new(line, column))
181
+ def references_from filename, line, column, strip: false
182
+ cursor = api_map.cursor_at(filename, Position.new(line, column))
183
+ clip = api_map.clip(cursor)
182
184
  pins = clip.define
183
185
  return [] if pins.empty?
184
186
  result = []
185
187
  pins.uniq.each do |pin|
186
188
  (workspace.sources + open_file_hash.values).uniq.each do |source|
187
189
  found = source.references(pin.name)
188
- found.select do |loc|
190
+ found.select! do |loc|
189
191
  referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character)
190
- referenced.any?{|r| r.path == pin.path}
192
+ referenced.any?{|r| r == pin}
193
+ end
194
+ # HACK for language clients that exclude special characters from the start of variable names
195
+ if strip && match = cursor.word.match(/^[^a-z0-9_]+/)
196
+ found.map! do |loc|
197
+ Solargraph::Location.new(loc.filename, Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line, loc.range.ending.column))
198
+ end
191
199
  end
192
200
  result.concat(found.sort{ |a, b|
193
201
  a.range.start.line <=> b.range.start.line
@@ -36,7 +36,11 @@ module Solargraph
36
36
  SYMBOL = 10
37
37
  BLOCK = 11
38
38
  BLOCK_PARAMETER = 12
39
+ REQUIRE_REFERENCE = 13
40
+ SUPERCLASS_REFERENCE = 14
41
+ INCLUDE_REFERENCE = 15
42
+ EXTEND_REFERENCE = 16
39
43
 
40
- ROOT_PIN = Pin::Namespace.new(nil, '', '', '', :class, :public, nil)
44
+ ROOT_PIN = Pin::Namespace.new(nil, '', '', '', :class, :public)
41
45
  end
42
46
  end
@@ -60,21 +60,11 @@ module Solargraph
60
60
  name.to_s
61
61
  end
62
62
 
63
- # @return [String]
64
- def identifier
65
- @identifier ||= "#{path}|#{name}"
66
- end
67
-
68
63
  # @return [Boolean]
69
64
  def variable?
70
65
  false
71
66
  end
72
67
 
73
- # @return [Boolean]
74
- def yard_pin?
75
- false
76
- end
77
-
78
68
  # @return [ComplexType]
79
69
  def context
80
70
  @context ||= ComplexType.parse(namespace || '')
@@ -44,7 +44,7 @@ module Solargraph
44
44
  if @detail.nil?
45
45
  @detail = ''
46
46
  @detail += "(#{parameters.join(', ')}) " unless kind != Pin::METHOD or parameters.empty?
47
- @detail += "=> #{return_complex_type.tag}" unless return_complex_type.undefined?
47
+ @detail += "=> #{return_complex_type}" unless return_complex_type.undefined?
48
48
  @detail.strip!
49
49
  end
50
50
  return nil if @detail.empty?
@@ -10,15 +10,6 @@ module Solargraph
10
10
  @documentation
11
11
  end
12
12
 
13
- # True if the suggestion has documentation.
14
- # Useful for determining whether a client should resolve a suggestion's
15
- # path to retrieve more information about it.
16
- #
17
- # @return [Boolean]
18
- def has_doc?
19
- !docstring.all.empty?
20
- end
21
-
22
13
  def helper
23
14
  @helper ||= Solargraph::Pin::Helper.new
24
15
  end
@@ -7,7 +7,7 @@ module Solargraph
7
7
  # @param location [Solargraph::Location]
8
8
  # @param name [String]
9
9
  def initialize location, name
10
- super(location, 'Object', name, nil, :instance, :public, [])
10
+ super(location, '', name, nil, :instance, :public, [])
11
11
  end
12
12
  end
13
13
  end
@@ -16,11 +16,6 @@ module Solargraph
16
16
  def completion_item_kind
17
17
  Solargraph::LanguageServer::CompletionItemKinds::KEYWORD
18
18
  end
19
-
20
- def identifier
21
- # HACK: A cheap way to make keyword identifiers unique
22
- object_id
23
- end
24
19
  end
25
20
  end
26
21
  end
@@ -1,29 +1,16 @@
1
1
  module Solargraph
2
2
  module Pin
3
3
  class Namespace < Pin::Base
4
+ # @return [Symbol] :public or :private
4
5
  attr_reader :visibility
5
6
 
7
+ # @return [Symbol] :class or :module
6
8
  attr_reader :type
7
9
 
8
- # @return [Pin::Reference]
9
- attr_reader :superclass_reference
10
-
11
- def initialize location, namespace, name, comments, type, visibility, superclass
10
+ def initialize location, namespace, name, comments, type, visibility
12
11
  super(location, namespace, name, comments)
13
12
  @type = type
14
13
  @visibility = visibility
15
- # @superclass_reference = Reference.new(self, superclass) unless superclass.nil?
16
- @superclass_reference = Pin::Reference.new(location, namespace, superclass) unless superclass.nil?
17
- end
18
-
19
- # @return [Array<Pin::Reference>]
20
- def include_references
21
- @include_references ||= []
22
- end
23
-
24
- # @return [Array<String>]
25
- def extend_references
26
- @extend_references ||= []
27
14
  end
28
15
 
29
16
  def kind
@@ -1,35 +1,22 @@
1
1
  module Solargraph
2
2
  module Pin
3
- class Reference
4
- # @return [Location]
5
- attr_reader :location
3
+ class Reference < Base
4
+ autoload :Require, 'solargraph/pin/reference/require'
5
+ autoload :Superclass, 'solargraph/pin/reference/superclass'
6
+ autoload :Include, 'solargraph/pin/reference/include'
7
+ autoload :Extend, 'solargraph/pin/reference/extend'
6
8
 
7
- # @return [String]
8
- attr_reader :namespace
9
-
10
- # @return [String]
11
- attr_reader :name
12
-
13
- # @param location [Location]
14
- # @param namespace [String]
15
- # @param name [String]
16
9
  def initialize location, namespace, name
17
- @location = location
18
- @namespace = namespace
19
- @name = name
10
+ super(location, namespace, name, '')
20
11
  end
21
12
 
22
- # @return [String]
23
- def filename
24
- location.filename
25
- end
26
-
27
- def == other
28
- return false unless self.class == other.class
29
- location == other.location and
30
- namespace = other.namespace and
31
- name == other.name
32
- end
13
+ # @todo Should Reference.new be protected?
14
+ # class << self
15
+ # protected
16
+ # def new *args
17
+ # super
18
+ # end
19
+ # end
33
20
  end
34
21
  end
35
22
  end