solargraph 0.23.6 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,6 +22,7 @@ module Solargraph
22
22
  autoload :Block, 'solargraph/pin/block'
23
23
  autoload :Localized, 'solargraph/pin/localized'
24
24
  autoload :ProxyMethod, 'solargraph/pin/proxy_method'
25
+ autoload :DuckMethod, 'solargraph/pin/duck_method'
25
26
 
26
27
  ATTRIBUTE = 1
27
28
  CLASS_VARIABLE = 2
@@ -30,12 +30,15 @@ module Solargraph
30
30
  @path ||= namespace + (scope == :instance ? '#' : '.') + name
31
31
  end
32
32
 
33
- def return_type
34
- if @return_type.nil? and !docstring.nil?
35
- tag = docstring.tag(:return)
36
- @return_type = tag.types[0] unless tag.nil?
33
+ def return_complex_types
34
+ if @return_complex_types.nil?
35
+ @return_complex_types = []
36
+ unless docstring.nil?
37
+ tag = docstring.tag(:return)
38
+ @return_complex_types.concat ComplexType.parse(*tag.types) unless tag.nil?
39
+ end
37
40
  end
38
- @return_type
41
+ @return_complex_types
39
42
  end
40
43
 
41
44
  def visibility
@@ -48,6 +51,10 @@ module Solargraph
48
51
  # them as methods without parameters
49
52
  []
50
53
  end
54
+
55
+ def parameter_names
56
+ []
57
+ end
51
58
  end
52
59
  end
53
60
  end
@@ -18,15 +18,16 @@ module Solargraph
18
18
  # @return [YARD::Docstring]
19
19
  attr_reader :docstring
20
20
 
21
- # @return [String]
22
- attr_reader :return_type
23
-
24
21
  # @return [Integer]
25
22
  attr_reader :kind
26
23
 
27
24
  # @return [String]
28
25
  attr_reader :path
29
26
 
27
+ # @param location [Solargraph::Source::Location]
28
+ # @param namespace [String]
29
+ # @param name [String]
30
+ # @param docstring [YARD::Docstring]
30
31
  def initialize location, namespace, name, docstring
31
32
  @location = location
32
33
  @namespace = namespace
@@ -58,6 +59,7 @@ module Solargraph
58
59
  @identifier ||= "#{path}|#{name}"
59
60
  end
60
61
 
62
+ # @return [Boolean]
61
63
  def variable?
62
64
  false
63
65
  end
@@ -66,6 +68,48 @@ module Solargraph
66
68
  def named_context
67
69
  namespace
68
70
  end
71
+
72
+ def == other
73
+ return false unless self.class == other.class
74
+ location == other.location and
75
+ namespace == other.namespace and
76
+ name == other.name and
77
+ ( (docstring.nil? and other.docstring.nil?) or (docstring == other.docstring and docstring.all == other.docstring.all) )
78
+ end
79
+
80
+ # The first return type associated with the pin.
81
+ # Use return_complex_types for an array of all return types.
82
+ #
83
+ # @return [String]
84
+ def return_type
85
+ return nil if return_complex_types.empty?
86
+ return_complex_types.first.tag
87
+ end
88
+
89
+ # The namespace of the first return type.
90
+ # Use return_complex_types for an array of all return types.
91
+ #
92
+ # @return [String]
93
+ def return_namespace
94
+ return nil if return_complex_types.empty?
95
+ @return_namespace ||= return_complex_types.first.namespace
96
+ end
97
+
98
+ # The scope of the first return type.
99
+ # Use return_complex_types for an array of all return types.
100
+ #
101
+ # @return [String]
102
+ def return_scope
103
+ return nil if complex_types.empty?
104
+ @return_scope ||= return_complex_types.first.scope
105
+ end
106
+
107
+ # All of the pin's return types as an array of ComplexTypes.
108
+ #
109
+ # @return [Array<ComplexType>]
110
+ def return_complex_types
111
+ @return_complex_types ||= []
112
+ end
69
113
  end
70
114
  end
71
115
  end
@@ -26,17 +26,29 @@ module Solargraph
26
26
  end
27
27
 
28
28
  def return_type
29
+ # if @return_type.nil?
30
+ # if !docstring.nil?
31
+ # tag = docstring.tag(:type)
32
+ # @return_type = tag.types[0] unless tag.nil?
33
+ # else
34
+ # @return_type = @literal
35
+ # end
36
+ # end
37
+ # @return_type
29
38
  if @return_type.nil?
30
- if !docstring.nil?
31
- tag = docstring.tag(:type)
32
- @return_type = tag.types[0] unless tag.nil?
33
- else
39
+ if return_complex_types.empty?
34
40
  @return_type = @literal
41
+ else
42
+ @return_type = return_complex_types.first.tag
35
43
  end
36
44
  end
37
45
  @return_type
38
46
  end
39
47
 
48
+ def return_complex_types
49
+ @return_complex_types ||= generate_complex_types
50
+ end
51
+
40
52
  def nil_assignment?
41
53
  return_type == 'NilClass'
42
54
  end
@@ -44,6 +56,15 @@ module Solargraph
44
56
  def variable?
45
57
  true
46
58
  end
59
+
60
+ private
61
+
62
+ def generate_complex_types
63
+ return [] if docstring.nil?
64
+ tag = docstring.tag(:type)
65
+ return [] if tag.nil?
66
+ ComplexType.parse *tag.types
67
+ end
47
68
  end
48
69
  end
49
70
  end
@@ -3,8 +3,7 @@ module Solargraph
3
3
  class BlockParameter < Base
4
4
  include Localized
5
5
 
6
- attr_reader :index
7
-
6
+ # @return [Pin::Block]
8
7
  attr_reader :block
9
8
 
10
9
  def initialize location, namespace, name, docstring, block
@@ -13,33 +12,43 @@ module Solargraph
13
12
  @presence = block.location.range
14
13
  end
15
14
 
15
+ # @return [Integer]
16
16
  def kind
17
17
  Pin::BLOCK_PARAMETER
18
18
  end
19
19
 
20
+ # @return [Integer]
20
21
  def completion_item_kind
21
22
  Solargraph::LanguageServer::CompletionItemKinds::VARIABLE
22
23
  end
23
24
 
25
+ # @return [Integer]
24
26
  def symbol_kind
25
27
  Solargraph::LanguageServer::SymbolKinds::VARIABLE
26
28
  end
27
29
 
30
+ # The parameter's zero-based location in the block's signature.
31
+ #
32
+ # @return [Integer]
28
33
  def index
29
34
  block.parameters.index(self)
30
35
  end
31
36
 
32
- def return_type
33
- if @return_type.nil? and !block.docstring.nil?
34
- found = nil
35
- params = block.docstring.tags(:param)
36
- params.each do |p|
37
- next unless p.name == name
38
- found = p
37
+ # @return [Array<Solargraph::ComplexType>]
38
+ def return_complex_types
39
+ if @return_complex_types.nil?
40
+ @return_complex_types = []
41
+ unless block.docstring.nil?
42
+ found = nil
43
+ params = block.docstring.tags(:param)
44
+ params.each do |p|
45
+ next unless p.name == name
46
+ found = p
47
+ end
48
+ @return_complex_types.concat ComplexType.parse(*found.types) unless found.nil? or found.types.nil?
39
49
  end
40
- @return_type = found.types[0] unless found.nil? or found.types.nil?
41
50
  end
42
- @return_type
51
+ @return_complex_types
43
52
  end
44
53
  end
45
54
  end
@@ -0,0 +1,15 @@
1
+ module Solargraph
2
+ module Pin
3
+ # DuckMethod pins are used to add completion items for type tags that
4
+ # use duck typing, e.g., `@param file [#read]`.
5
+ #
6
+ class DuckMethod < Pin::Method
7
+ # @param location [Solargraph::Source::Location]
8
+ # @param name [String]
9
+ #
10
+ def initialize location, name
11
+ super(location, 'Object', name, nil, :instance, :public, [])
12
+ end
13
+ end
14
+ end
15
+ end
@@ -12,6 +12,10 @@ module Solargraph
12
12
  @parameters = args
13
13
  end
14
14
 
15
+ def parameter_names
16
+ @parameter_names ||= parameters.map{|p| p.split(/[ =:]/).first}
17
+ end
18
+
15
19
  def kind
16
20
  Solargraph::Pin::METHOD
17
21
  end
@@ -29,16 +33,8 @@ module Solargraph
29
33
  LanguageServer::SymbolKinds::METHOD
30
34
  end
31
35
 
32
- def return_type
33
- if @return_type.nil? and !docstring.nil?
34
- tag = docstring.tag(:return)
35
- if tag.nil?
36
- ol = docstring.tag(:overload)
37
- tag = ol.tag(:return) unless ol.nil?
38
- end
39
- @return_type = tag.types[0] unless tag.nil? or tag.types.nil?
40
- end
41
- @return_type
36
+ def return_complex_types
37
+ @return_complex_types ||= generate_complex_types
42
38
  end
43
39
 
44
40
  def documentation
@@ -63,23 +59,17 @@ module Solargraph
63
59
  @documentation
64
60
  end
65
61
 
66
- # @todo This method was temporarily migrated directly from Suggestion
67
- # @return [Array<String>]
68
- def params
69
- if @params.nil?
70
- @params = []
71
- return @params if docstring.nil?
72
- param_tags = docstring.tags(:param)
73
- unless param_tags.empty?
74
- param_tags.each do |t|
75
- txt = t.name.to_s
76
- txt += " [#{t.types.join(',')}]" unless t.types.nil? or t.types.empty?
77
- txt += " #{t.text}" unless t.text.nil? or t.text.empty?
78
- @params.push txt
79
- end
80
- end
62
+ private
63
+
64
+ def generate_complex_types
65
+ return [] if docstring.nil?
66
+ tag = docstring.tag(:return)
67
+ if tag.nil?
68
+ ol = docstring.tag(:overload)
69
+ tag = ol.tag(:return) unless ol.nil?
81
70
  end
82
- @params
71
+ return [] if tag.nil?
72
+ ComplexType.parse *tag.types
83
73
  end
84
74
  end
85
75
  end
@@ -1,18 +1,21 @@
1
1
  module Solargraph
2
2
  module Pin
3
3
  class MethodParameter < LocalVariable
4
- def return_type
5
- if @return_type.nil? and !block.docstring.nil?
6
- found = nil
7
- params = block.docstring.tags(:param)
8
- params.each do |p|
9
- next unless p.name == name
10
- found = p
4
+ def return_complex_types
5
+ if @return_complex_types.nil?
6
+ @return_complex_types = []
7
+ unless block.docstring.nil?
8
+ found = nil
9
+ params = block.docstring.tags(:param)
10
+ params.each do |p|
11
+ next unless p.name == name
12
+ found = p
13
+ end
14
+ @return_complex_types.concat ComplexType.parse(*found.types) unless found.nil? or found.types.nil?
11
15
  end
12
- @return_type = found.types[0] unless found.nil? or found.types.nil?
13
16
  end
14
17
  super
15
- @return_type
18
+ @return_complex_types
16
19
  end
17
20
  end
18
21
  end
@@ -51,8 +51,8 @@ module Solargraph
51
51
  @path ||= (namespace.empty? ? '' : "#{namespace}::") + name
52
52
  end
53
53
 
54
- def return_type
55
- @return_type ||= (type == :class ? 'Class' : 'Module') + "<#{path}>"
54
+ def return_complex_types
55
+ @return_complex_types ||= ComplexType.parse( (type == :class ? 'Class' : 'Module') + "<#{path}>" )
56
56
  end
57
57
  end
58
58
  end
@@ -5,16 +5,15 @@ module Solargraph
5
5
  # method while analyzing signatures.
6
6
  #
7
7
  class ProxyMethod < Base
8
- # @return [String]
9
- attr_reader :return_type
10
-
11
- def initialize return_type
12
- @return_type = return_type
8
+ def initialize *return_types
9
+ @return_complex_types = ComplexType.parse(*return_types.reject(&:nil?))
13
10
  end
14
11
 
15
12
  # @return [String]
16
13
  def namespace
17
- @namespace ||= ApiMap::TypeMethods.extract_namespace(@return_type)
14
+ # @namespace ||= ApiMap::TypeMethods.extract_namespace(return_type)
15
+ return nil if @return_complex_types.empty?
16
+ @namespace ||= @return_complex_types.first.namespace
18
17
  end
19
18
 
20
19
  # @return [Integer]
@@ -86,6 +86,10 @@ module Solargraph
86
86
  @parameters ||= get_method_args
87
87
  end
88
88
 
89
+ def parameter_names
90
+ @parameter_names ||= parameters.map{|p| p.split(/[ =:]/).first}
91
+ end
92
+
89
93
  def visibility
90
94
  @visibility ||= (code_object.respond_to?(:visibility) ? code_object.visibility : :public)
91
95
  end
@@ -100,14 +104,14 @@ module Solargraph
100
104
  def get_method_args
101
105
  return [] unless code_object.kind_of?(YARD::CodeObjects::MethodObject)
102
106
  args = []
103
- code_object.parameters.each { |a|
107
+ code_object.parameters.each do |a|
104
108
  p = a[0]
105
109
  unless a[1].nil?
106
110
  p += ' =' unless p.end_with?(':')
107
111
  p += " #{a[1]}"
108
112
  end
109
113
  args.push p
110
- }
114
+ end
111
115
  args
112
116
  end
113
117
  end
@@ -207,7 +207,7 @@ module Solargraph
207
207
  end
208
208
 
209
209
  # @param updater [Source::Updater]
210
- def synchronize updater
210
+ def synchronize updater, reparse = true
211
211
  raise 'Invalid synchronization' unless updater.filename == filename
212
212
  original_code = @code
213
213
  original_fixed = @fixed
@@ -215,6 +215,7 @@ module Solargraph
215
215
  @fixed = updater.write(original_code, true)
216
216
  @version = updater.version
217
217
  return if @code == original_code
218
+ return unless reparse
218
219
  begin
219
220
  parse
220
221
  @fixed = @code
@@ -248,6 +249,8 @@ module Solargraph
248
249
  @all_pins.select{|pin| pin.location == location}.first
249
250
  end
250
251
 
252
+ # @param line [Integer] A zero-based line number
253
+ # @param column [Integer] A zero-based column number
251
254
  # @return [Solargraph::Source::Fragment]
252
255
  def fragment_at line, column
253
256
  Fragment.new(self, line, column)
@@ -321,8 +324,28 @@ module Solargraph
321
324
  end
322
325
 
323
326
  def process_parsed node, comments
324
- @pins, @locals, @requires, @symbols, @path_macros, @domains = Mapper.map filename, code, node, comments
325
- @stime = Time.now
327
+ new_map_data = Mapper.map(filename, code, node, comments)
328
+ synchronize_mapped *new_map_data
329
+ end
330
+
331
+ def synchronize_mapped new_pins, new_locals, new_requires, new_symbols, new_path_macros, new_domains
332
+ resync = (
333
+ @pins.nil? or
334
+ @locals.nil? or
335
+ @pins[1..-1] != new_pins[1..-1] or
336
+ @locals != new_locals
337
+ # @requires != new_requires or
338
+ # @path_macros != new_path_macros or
339
+ # @new_domains != new_domains
340
+ )
341
+ @pins = new_pins
342
+ @locals = new_locals
343
+ @requires = new_requires
344
+ @symbols = new_symbols
345
+ @path_macros = new_path_macros
346
+ @domains = new_domains
347
+ # Check for bare minimum change required to synchronize workspaces, etc.
348
+ @stime = Time.now if resync
326
349
  end
327
350
 
328
351
  class << self