solargraph 0.47.2 → 0.54.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.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/plugins.yml +40 -0
  4. data/.github/workflows/rspec.yml +4 -8
  5. data/.github/workflows/typecheck.yml +34 -0
  6. data/.yardopts +2 -2
  7. data/CHANGELOG.md +166 -3
  8. data/LICENSE +1 -1
  9. data/README.md +19 -16
  10. data/SPONSORS.md +2 -9
  11. data/lib/solargraph/api_map/cache.rb +50 -20
  12. data/lib/solargraph/api_map/source_to_yard.rb +17 -10
  13. data/lib/solargraph/api_map/store.rb +68 -15
  14. data/lib/solargraph/api_map.rb +238 -112
  15. data/lib/solargraph/bench.rb +3 -2
  16. data/lib/solargraph/cache.rb +77 -0
  17. data/lib/solargraph/complex_type/type_methods.rb +116 -35
  18. data/lib/solargraph/complex_type/unique_type.rb +261 -33
  19. data/lib/solargraph/complex_type.rb +149 -30
  20. data/lib/solargraph/convention/rakefile.rb +17 -0
  21. data/lib/solargraph/convention.rb +2 -3
  22. data/lib/solargraph/converters/dd.rb +5 -0
  23. data/lib/solargraph/converters/dl.rb +3 -0
  24. data/lib/solargraph/converters/dt.rb +3 -0
  25. data/lib/solargraph/diagnostics/rubocop.rb +23 -8
  26. data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -1
  27. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  28. data/lib/solargraph/diagnostics.rb +2 -2
  29. data/lib/solargraph/doc_map.rb +187 -0
  30. data/lib/solargraph/gem_pins.rb +72 -0
  31. data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
  32. data/lib/solargraph/language_server/host/dispatch.rb +22 -5
  33. data/lib/solargraph/language_server/host/message_worker.rb +4 -0
  34. data/lib/solargraph/language_server/host/sources.rb +8 -65
  35. data/lib/solargraph/language_server/host.rb +88 -93
  36. data/lib/solargraph/language_server/message/base.rb +1 -1
  37. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  38. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
  39. data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
  40. data/lib/solargraph/language_server/message/initialize.rb +27 -0
  41. data/lib/solargraph/language_server/message/initialized.rb +1 -0
  42. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +4 -1
  43. data/lib/solargraph/language_server/message/text_document/formatting.rb +5 -4
  44. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  45. data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
  46. data/lib/solargraph/language_server/message/text_document/type_definition.rb +24 -0
  47. data/lib/solargraph/language_server/message/text_document.rb +1 -1
  48. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  49. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
  50. data/lib/solargraph/language_server/message.rb +1 -0
  51. data/lib/solargraph/language_server/progress.rb +118 -0
  52. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  53. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  54. data/lib/solargraph/language_server.rb +1 -0
  55. data/lib/solargraph/library.rb +231 -104
  56. data/lib/solargraph/location.rb +1 -0
  57. data/lib/solargraph/page.rb +6 -0
  58. data/lib/solargraph/parser/comment_ripper.rb +4 -0
  59. data/lib/solargraph/parser/node_methods.rb +47 -7
  60. data/lib/solargraph/parser/node_processor/base.rb +11 -1
  61. data/lib/solargraph/parser/node_processor.rb +1 -0
  62. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -9
  63. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
  64. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +57 -41
  65. data/lib/solargraph/parser/parser_gem/node_methods.rb +495 -0
  66. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
  67. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +53 -0
  68. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
  69. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
  70. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +14 -4
  71. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/cvasgn_node.rb +1 -1
  72. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/def_node.rb +7 -20
  73. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
  74. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
  75. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
  76. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
  77. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +47 -0
  78. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
  79. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
  80. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
  81. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +42 -0
  82. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +7 -5
  83. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sym_node.rb +1 -1
  84. data/lib/solargraph/parser/parser_gem/node_processors.rb +56 -0
  85. data/lib/solargraph/parser/parser_gem.rb +12 -0
  86. data/lib/solargraph/parser/region.rb +1 -1
  87. data/lib/solargraph/parser/snippet.rb +2 -0
  88. data/lib/solargraph/parser.rb +9 -10
  89. data/lib/solargraph/pin/base.rb +69 -11
  90. data/lib/solargraph/pin/base_variable.rb +40 -7
  91. data/lib/solargraph/pin/block.rb +81 -33
  92. data/lib/solargraph/pin/closure.rb +17 -2
  93. data/lib/solargraph/pin/common.rb +7 -3
  94. data/lib/solargraph/pin/conversions.rb +34 -8
  95. data/lib/solargraph/pin/delegated_method.rb +101 -0
  96. data/lib/solargraph/pin/documenting.rb +25 -32
  97. data/lib/solargraph/pin/instance_variable.rb +4 -0
  98. data/lib/solargraph/pin/local_variable.rb +13 -1
  99. data/lib/solargraph/pin/method.rb +273 -17
  100. data/lib/solargraph/pin/namespace.rb +17 -1
  101. data/lib/solargraph/pin/parameter.rb +40 -28
  102. data/lib/solargraph/pin/reference/override.rb +2 -2
  103. data/lib/solargraph/pin/reference.rb +8 -0
  104. data/lib/solargraph/pin/search.rb +4 -4
  105. data/lib/solargraph/pin/signature.rb +143 -0
  106. data/lib/solargraph/pin.rb +2 -1
  107. data/lib/solargraph/range.rb +4 -6
  108. data/lib/solargraph/rbs_map/conversions.rb +607 -0
  109. data/lib/solargraph/rbs_map/core_fills.rb +50 -0
  110. data/lib/solargraph/rbs_map/core_map.rb +28 -0
  111. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -0
  112. data/lib/solargraph/rbs_map.rb +92 -0
  113. data/lib/solargraph/shell.rb +85 -59
  114. data/lib/solargraph/source/chain/array.rb +32 -0
  115. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  116. data/lib/solargraph/source/chain/call.rb +125 -61
  117. data/lib/solargraph/source/chain/constant.rb +15 -1
  118. data/lib/solargraph/source/chain/if.rb +23 -0
  119. data/lib/solargraph/source/chain/link.rb +8 -2
  120. data/lib/solargraph/source/chain/or.rb +1 -1
  121. data/lib/solargraph/source/chain/z_super.rb +3 -3
  122. data/lib/solargraph/source/chain.rb +64 -14
  123. data/lib/solargraph/source/change.rb +3 -0
  124. data/lib/solargraph/source/cursor.rb +2 -0
  125. data/lib/solargraph/source/source_chainer.rb +8 -5
  126. data/lib/solargraph/source/updater.rb +1 -0
  127. data/lib/solargraph/source.rb +18 -63
  128. data/lib/solargraph/source_map/clip.rb +31 -23
  129. data/lib/solargraph/source_map/mapper.rb +23 -7
  130. data/lib/solargraph/source_map.rb +36 -11
  131. data/lib/solargraph/type_checker/checks.rb +10 -2
  132. data/lib/solargraph/type_checker.rb +229 -100
  133. data/lib/solargraph/version.rb +1 -1
  134. data/lib/solargraph/views/environment.erb +2 -2
  135. data/lib/solargraph/workspace/config.rb +15 -11
  136. data/lib/solargraph/workspace.rb +41 -17
  137. data/lib/solargraph/yard_map/cache.rb +6 -0
  138. data/lib/solargraph/yard_map/helpers.rb +1 -1
  139. data/lib/solargraph/yard_map/mapper/to_method.rb +23 -7
  140. data/lib/solargraph/yard_map/mapper.rb +1 -1
  141. data/lib/solargraph/yard_map/to_method.rb +11 -4
  142. data/lib/solargraph/yard_map.rb +1 -443
  143. data/lib/solargraph/yard_tags.rb +20 -0
  144. data/lib/solargraph/yardoc.rb +52 -0
  145. data/lib/solargraph.rb +8 -6
  146. data/solargraph.gemspec +19 -8
  147. metadata +164 -99
  148. data/.travis.yml +0 -19
  149. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  150. data/lib/solargraph/compat.rb +0 -37
  151. data/lib/solargraph/convention/rspec.rb +0 -30
  152. data/lib/solargraph/documentor.rb +0 -76
  153. data/lib/solargraph/language_server/host/cataloger.rb +0 -56
  154. data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
  155. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  156. data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -35
  157. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  158. data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +0 -23
  159. data/lib/solargraph/parser/legacy/node_processors/def_node.rb +0 -63
  160. data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +0 -21
  161. data/lib/solargraph/parser/legacy/node_processors.rb +0 -54
  162. data/lib/solargraph/parser/legacy.rb +0 -12
  163. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -144
  164. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
  165. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -315
  166. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  167. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  168. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -22
  169. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -57
  170. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  171. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  172. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  173. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  174. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  175. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  176. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  177. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  178. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -45
  179. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -21
  180. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  181. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -277
  182. data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +0 -18
  183. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -63
  184. data/lib/solargraph/parser/rubyvm.rb +0 -40
  185. data/lib/solargraph/yard_map/core_docs.rb +0 -170
  186. data/lib/solargraph/yard_map/core_fills.rb +0 -208
  187. data/lib/solargraph/yard_map/core_gen.rb +0 -76
  188. data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
  189. data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
  190. data/lib/yard-solargraph.rb +0 -33
  191. data/yardoc/2.2.2.tar.gz +0 -0
@@ -4,64 +4,124 @@ module Solargraph
4
4
  # A container for type data based on YARD type tags.
5
5
  #
6
6
  class ComplexType
7
+ GENERIC_TAG_NAME = 'generic'.freeze
7
8
  # @!parse
8
9
  # include TypeMethods
9
10
 
10
11
  autoload :TypeMethods, 'solargraph/complex_type/type_methods'
11
12
  autoload :UniqueType, 'solargraph/complex_type/unique_type'
12
13
 
13
- # @param types [Array<UniqueType>]
14
+ # @param types [Array<UniqueType, ComplexType>]
14
15
  def initialize types = [UniqueType::UNDEFINED]
15
- @items = types.uniq(&:to_s)
16
+ # @todo @items here should not need an annotation
17
+ # @type [Array<UniqueType>]
18
+ @items = types.flat_map(&:items).uniq(&:to_s)
16
19
  end
17
20
 
18
21
  # @param api_map [ApiMap]
19
22
  # @param context [String]
20
23
  # @return [ComplexType]
21
24
  def qualify api_map, context = ''
22
- types = @items.map do |t|
25
+ red = reduce_object
26
+ types = red.items.map do |t|
23
27
  next t if ['Boolean', 'nil', 'void', 'undefined'].include?(t.name)
24
28
  t.qualify api_map, context
25
29
  end
26
- ComplexType.new(types)
30
+ ComplexType.new(types).reduce_object
27
31
  end
28
32
 
33
+ # @param generics_to_resolve [Enumerable<String>]]
34
+ # @param context_type [UniqueType, nil]
35
+ # @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
36
+ # @return [self]
37
+ def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
38
+ return self unless generic?
39
+
40
+ ComplexType.new(@items.map { |i| i.resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: resolved_generic_values) })
41
+ end
42
+
43
+ # @return [UniqueType]
29
44
  def first
30
45
  @items.first
31
46
  end
32
47
 
48
+ # @return [String]
49
+ def to_rbs
50
+ ((@items.length > 1 ? '(' : '') +
51
+ @items.map(&:to_rbs).join(' | ') +
52
+ (@items.length > 1 ? ')' : ''))
53
+ end
54
+
55
+ # @yieldparam [UniqueType]
56
+ # @return [Array]
33
57
  def map &block
34
58
  @items.map &block
35
59
  end
36
60
 
37
61
  # @yieldparam [UniqueType]
38
- # @return [Array]
62
+ # @return [Enumerable<UniqueType>]
39
63
  def each &block
40
64
  @items.each &block
41
65
  end
42
66
 
67
+ # @yieldparam [UniqueType]
68
+ # @return [void]
69
+ # @overload each_unique_type()
70
+ # @return [Enumerator<UniqueType>]
71
+ def each_unique_type &block
72
+ return enum_for(__method__) unless block_given?
73
+
74
+ @items.each do |item|
75
+ item.each_unique_type &block
76
+ end
77
+ end
78
+
79
+ # @return [Integer]
43
80
  def length
44
81
  @items.length
45
82
  end
46
83
 
84
+ # @return [Array<UniqueType>]
85
+ def to_a
86
+ @items
87
+ end
88
+
89
+ def tags
90
+ @items.map(&:tag).join(', ')
91
+ end
92
+
93
+ # @param index [Integer]
94
+ # @return [UniqueType]
47
95
  def [](index)
48
96
  @items[index]
49
97
  end
50
98
 
99
+ # @return [Array<UniqueType>]
51
100
  def select &block
52
101
  @items.select &block
53
102
  end
103
+
104
+ # @return [String]
54
105
  def namespace
55
106
  # cache this attr for high frequency call
56
107
  @namespace ||= method_missing(:namespace).to_s
57
108
  end
58
109
 
110
+ # @return [Array<String>]
111
+ def namespaces
112
+ @items.map(&:namespace)
113
+ end
114
+
115
+ # @param name [Symbol]
116
+ # @return [Object, nil]
59
117
  def method_missing name, *args, &block
60
118
  return if @items.first.nil?
61
119
  return @items.first.send(name, *args, &block) if respond_to_missing?(name)
62
120
  super
63
121
  end
64
122
 
123
+ # @param name [Symbol]
124
+ # @param include_private [Boolean]
65
125
  def respond_to_missing?(name, include_private = false)
66
126
  TypeMethods.public_instance_methods.include?(name) || super
67
127
  end
@@ -70,44 +130,80 @@ module Solargraph
70
130
  map(&:tag).join(', ')
71
131
  end
72
132
 
133
+ def rooted_tags
134
+ map(&:rooted_tag).join(', ')
135
+ end
136
+
73
137
  def all? &block
74
138
  @items.all? &block
75
139
  end
76
140
 
77
141
  def any? &block
78
- @items.any? &block
142
+ @items.compact.any? &block
79
143
  end
80
144
 
81
145
  def selfy?
82
146
  @items.any?(&:selfy?)
83
147
  end
84
148
 
149
+ def generic?
150
+ any?(&:generic?)
151
+ end
152
+
153
+ # @param new_name [String, nil]
154
+ # @yieldparam t [UniqueType]
155
+ # @yieldreturn [UniqueType]
156
+ # @return [ComplexType]
157
+ def transform(new_name = nil, &transform_type)
158
+ raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}" if new_name&.start_with?('::')
159
+ ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
160
+ end
161
+
162
+ # @return [self]
163
+ def force_rooted
164
+ transform do |t|
165
+ t.recreate(make_rooted: true)
166
+ end
167
+ end
168
+
169
+ # @param definitions [Pin::Namespace, Pin::Method]
170
+ # @param context_type [ComplexType]
171
+ # @return [ComplexType]
172
+ def resolve_generics definitions, context_type
173
+ result = @items.map { |i| i.resolve_generics(definitions, context_type) }
174
+ ComplexType.try_parse(*result.map(&:tag))
175
+ end
176
+
85
177
  # @param dst [String]
86
178
  # @return [ComplexType]
87
179
  def self_to dst
88
180
  return self unless selfy?
89
181
  red = reduce_class(dst)
90
182
  result = @items.map { |i| i.self_to red }
91
- ComplexType.parse(*result.map(&:tag))
183
+ ComplexType.try_parse(*result.map(&:tag))
92
184
  end
93
185
 
94
186
  def nullable?
95
187
  @items.any?(&:nil_type?)
96
188
  end
97
189
 
98
- private
190
+ # @return [Array<ComplexType>]
191
+ def all_params
192
+ @items.first.all_params || []
193
+ end
99
194
 
100
- # @todo This is a quick and dirty hack that forces `self` keywords
101
- # to reference an instance of their class and never the class itself.
102
- # This behavior may change depending on which result is expected
103
- # from YARD conventions. See https://github.com/lsegal/yard/issues/1257
104
- # @param dst [String]
105
- # @return [String]
106
- def reduce_class dst
107
- while dst =~ /^(Class|Module)\<(.*?)\>$/
108
- dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '')
109
- end
110
- dst
195
+ attr_reader :items
196
+
197
+ protected
198
+
199
+ # @return [ComplexType]
200
+ def reduce_object
201
+ return self if name != 'Object' || subtypes.empty?
202
+ ComplexType.try_parse(reduce_class(subtypes.join(', ')))
203
+ end
204
+
205
+ def bottom?
206
+ @items.all?(&:bot?)
111
207
  end
112
208
 
113
209
  class << self
@@ -124,9 +220,13 @@ module Solargraph
124
220
  # used internally.
125
221
  #
126
222
  # @param *strings [Array<String>] The type definitions to parse
127
- # @param partial [Boolean] True if the string is part of a another type
128
- # @return [ComplexType, Array, nil]
223
+ # @return [ComplexType]
224
+ # @overload parse(*strings, partial: false)
225
+ # @todo Need ability to use a literal true as a type below
226
+ # @param partial [Boolean] True if the string is part of a another type
227
+ # @return [Array<UniqueType>]
129
228
  def parse *strings, partial: false
229
+ # @type [Hash{Array<String> => ComplexType}]
130
230
  @cache ||= {}
131
231
  unless partial
132
232
  cached = @cache[strings]
@@ -140,7 +240,7 @@ module Solargraph
140
240
  paren_stack = 0
141
241
  base = String.new
142
242
  subtype_string = String.new
143
- type_string.each_char do |char|
243
+ type_string&.each_char do |char|
144
244
  if char == '='
145
245
  #raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
146
246
  elsif char == '<'
@@ -151,7 +251,10 @@ module Solargraph
151
251
  elsif base.end_with?('=')
152
252
  raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
153
253
  # types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
154
- types.push UniqueType.new(base[0..-2].strip)
254
+ types.push UniqueType.parse(base[0..-2].strip, subtype_string)
255
+ # @todo this should either expand key_type's type
256
+ # automatically or complain about not being
257
+ # compatible with key_type's type in type checking
155
258
  key_types = types
156
259
  types = []
157
260
  base.clear
@@ -174,12 +277,12 @@ module Solargraph
174
277
  paren_stack += 1
175
278
  elsif char == ')'
176
279
  paren_stack -= 1
177
- subtype_string += char if paren_stack == 0
280
+ subtype_string += char
178
281
  raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
179
282
  next
180
283
  elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
181
284
  # types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
182
- types.push UniqueType.new(base.strip, subtype_string.strip)
285
+ types.push UniqueType.parse(base.strip, subtype_string.strip)
183
286
  base.clear
184
287
  subtype_string.clear
185
288
  next
@@ -192,7 +295,7 @@ module Solargraph
192
295
  end
193
296
  raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 || curly_stack != 0 || paren_stack != 0
194
297
  # types.push ComplexType.new([UniqueType.new(base, subtype_string)])
195
- types.push UniqueType.new(base.strip, subtype_string.strip)
298
+ types.push UniqueType.parse(base.strip, subtype_string.strip)
196
299
  end
197
300
  unless key_types.nil?
198
301
  raise ComplexTypeError, "Invalid use of key/value parameters" unless partial
@@ -209,17 +312,33 @@ module Solargraph
209
312
  def try_parse *strings
210
313
  parse *strings
211
314
  rescue ComplexTypeError => e
212
- Solargraph.logger.info "Error parsing complex type: #{e.message}"
315
+ Solargraph.logger.info "Error parsing complex type `#{strings.join(', ')}`: #{e.message}"
213
316
  ComplexType::UNDEFINED
214
317
  end
215
318
  end
216
319
 
217
320
  VOID = ComplexType.parse('void')
218
321
  UNDEFINED = ComplexType.parse('undefined')
219
- SYMBOL = ComplexType.parse('Symbol')
220
- ROOT = ComplexType.parse('Class<>')
322
+ SYMBOL = ComplexType.parse('::Symbol')
323
+ ROOT = ComplexType.parse('::Class<>')
221
324
  NIL = ComplexType.parse('nil')
222
325
  SELF = ComplexType.parse('self')
223
- BOOLEAN = ComplexType.parse('Boolean')
326
+ BOOLEAN = ComplexType.parse('::Boolean')
327
+ BOT = ComplexType.parse('bot')
328
+
329
+ private
330
+
331
+ # @todo This is a quick and dirty hack that forces `self` keywords
332
+ # to reference an instance of their class and never the class itself.
333
+ # This behavior may change depending on which result is expected
334
+ # from YARD conventions. See https://github.com/lsegal/yard/issues/1257
335
+ # @param dst [String]
336
+ # @return [String]
337
+ def reduce_class dst
338
+ while dst =~ /^(Class|Module)\<(.*?)\>$/
339
+ dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '')
340
+ end
341
+ dst
342
+ end
224
343
  end
225
344
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ class Rakefile < Base
6
+ def local source_map
7
+ basename = File.basename(source_map.filename)
8
+ return EMPTY_ENVIRON unless basename.end_with?('.rake') || basename == 'Rakefile'
9
+
10
+ @environ ||= Environ.new(
11
+ requires: ['rake'],
12
+ domains: ['Rake::DSL']
13
+ )
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
3
 
5
4
  module Solargraph
6
5
  # Conventions provide a way to modify an ApiMap based on expectations about
@@ -9,8 +8,8 @@ module Solargraph
9
8
  module Convention
10
9
  autoload :Base, 'solargraph/convention/base'
11
10
  autoload :Gemfile, 'solargraph/convention/gemfile'
12
- autoload :Rspec, 'solargraph/convention/rspec'
13
11
  autoload :Gemspec, 'solargraph/convention/gemspec'
12
+ autoload :Rakefile, 'solargraph/convention/rakefile'
14
13
 
15
14
  @@conventions = Set.new
16
15
 
@@ -42,6 +41,6 @@ module Solargraph
42
41
 
43
42
  register Gemfile
44
43
  register Gemspec
45
- register Rspec
44
+ register Rakefile
46
45
  end
47
46
  end
@@ -1,6 +1,11 @@
1
+ require 'nokogiri'
2
+
1
3
  module ReverseMarkdown
2
4
  module Converters
3
5
  class Dd < Base
6
+ # @return [String]
7
+ # @param node [Nokogiri::XML::Element]
8
+ # @param state [Hash]
4
9
  def convert node, state = {}
5
10
  content = treat_children(node, state)
6
11
  ": #{content.strip}\n"
@@ -1,6 +1,9 @@
1
1
  module ReverseMarkdown
2
2
  module Converters
3
3
  class Dl < Base
4
+ # @return [String]
5
+ # @param node [Nokogiri::XML::Element]
6
+ # @param state [Hash]
4
7
  def convert node, state = {}
5
8
  content = treat_children(node, state).strip
6
9
  "\n\n#{content}\n"
@@ -1,6 +1,9 @@
1
1
  module ReverseMarkdown
2
2
  module Converters
3
3
  class Dt < Base
4
+ # @return [String]
5
+ # @param node [Nokogiri::XML::Element]
6
+ # @param state [Hash]
4
7
  def convert node, state = {}
5
8
  content = treat_children(node, state)
6
9
  "\n#{content.strip}\n"
@@ -11,6 +11,7 @@ module Solargraph
11
11
 
12
12
  # Conversion of RuboCop severity names to LSP constants
13
13
  SEVERITIES = {
14
+ 'info' => Severities::HINT,
14
15
  'refactor' => Severities::HINT,
15
16
  'convention' => Severities::INFORMATION,
16
17
  'warning' => Severities::WARNING,
@@ -22,16 +23,20 @@ module Solargraph
22
23
  # @param _api_map [Solargraph::ApiMap]
23
24
  # @return [Array<Hash>]
24
25
  def diagnose source, _api_map
26
+ @source = source
25
27
  require_rubocop(rubocop_version)
26
28
  options, paths = generate_options(source.filename, source.code)
27
29
  store = RuboCop::ConfigStore.new
28
30
  runner = RuboCop::Runner.new(options, store)
29
31
  result = redirect_stdout{ runner.run(paths) }
32
+
33
+ return [] if result.empty?
34
+
30
35
  make_array JSON.parse(result)
31
36
  rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
32
37
  raise DiagnosticsError, "Error in RuboCop configuration: #{e.message}"
33
- rescue JSON::ParserError
34
- raise DiagnosticsError, 'RuboCop returned invalid data'
38
+ rescue JSON::ParserError => e
39
+ raise DiagnosticsError, "RuboCop returned invalid data: #{e.message}"
35
40
  end
36
41
 
37
42
  private
@@ -43,7 +48,7 @@ module Solargraph
43
48
  args.find { |a| a =~ /version=/ }.to_s.split('=').last
44
49
  end
45
50
 
46
- # @param resp [Hash]
51
+ # @param resp [Hash{String => Array<Hash{String => Array<Hash{String => undefined}>}>}]
47
52
  # @return [Array<Hash>]
48
53
  def make_array resp
49
54
  diagnostics = []
@@ -57,8 +62,8 @@ module Solargraph
57
62
 
58
63
  # Convert a RuboCop offense to an LSP diagnostic
59
64
  #
60
- # @param off [Hash] Offense received from Rubocop
61
- # @return [Hash] LSP diagnostic
65
+ # @param off [Hash{String => unknown}] Offense received from Rubocop
66
+ # @return [Hash{Symbol => Hash, String, Integer}] LSP diagnostic
62
67
  def offense_to_diagnostic off
63
68
  {
64
69
  range: offense_range(off).to_hash,
@@ -76,20 +81,30 @@ module Solargraph
76
81
  Range.new(offense_start_position(off), offense_ending_position(off))
77
82
  end
78
83
 
79
- # @param off [Hash]
84
+ # @param off [Hash{String => Hash{String => Integer}}]
80
85
  # @return [Position]
81
86
  def offense_start_position off
82
87
  Position.new(off['location']['start_line'] - 1, off['location']['start_column'] - 1)
83
88
  end
84
89
 
85
- # @param off [Hash]
90
+ # @param off [Hash{String => Hash{String => Integer}}]
86
91
  # @return [Position]
87
92
  def offense_ending_position off
88
93
  if off['location']['start_line'] != off['location']['last_line']
89
94
  Position.new(off['location']['start_line'], 0)
90
95
  else
96
+ start_line = off['location']['start_line'] - 1
97
+ # @type [Integer]
98
+ last_column = off['location']['last_column']
99
+ line = @source.code.lines[start_line]
100
+ col_off = if line.nil? || line.empty?
101
+ 1
102
+ else
103
+ 0
104
+ end
105
+
91
106
  Position.new(
92
- off['location']['start_line'] - 1, off['location']['last_column'] - 1
107
+ start_line, last_column - col_off
93
108
  )
94
109
  end
95
110
  end
@@ -10,13 +10,16 @@ module Solargraph
10
10
  # Requires a specific version of rubocop, or the latest installed version
11
11
  # if _version_ is `nil`.
12
12
  #
13
- # @param version [String]
13
+ # @param version [String, nil]
14
14
  # @raise [InvalidRubocopVersionError] if _version_ is not installed
15
+ # @return [void]
15
16
  def require_rubocop(version = nil)
16
17
  begin
17
18
  gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
18
19
  gem_lib_path = File.join(gem_path, 'lib')
19
20
  $LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path)
21
+ # @todo Gem::MissingSpecVersionError is undocumented for some reason
22
+ # @sg-ignore
20
23
  rescue Gem::MissingSpecVersionError => e
21
24
  raise InvalidRubocopVersionError,
22
25
  "could not find '#{e.name}' (#{e.requirement}) - "\
@@ -6,6 +6,7 @@ module Solargraph
6
6
  # parameters, and invalid param tags.
7
7
  #
8
8
  class TypeCheck < Base
9
+ # @return [Array<Hash>]
9
10
  def diagnose source, api_map
10
11
  # return [] unless args.include?('always') || api_map.workspaced?(source.filename)
11
12
  severity = Diagnostics::Severities::ERROR
@@ -33,14 +33,14 @@ module Solargraph
33
33
  # Find a reporter by name.
34
34
  #
35
35
  # @param name [String] The name with which the reporter was registered
36
- # @return [Class<Solargraph::Diagnostics::Base>]
36
+ # @return [Class<Solargraph::Diagnostics::Base>, nil]
37
37
  def reporter name
38
38
  reporter_hash[name]
39
39
  end
40
40
 
41
41
  private
42
42
 
43
- # @return [Hash]
43
+ # @return [Hash{String => Class<Solargraph::Diagnostics::Base>}]
44
44
  def reporter_hash
45
45
  @reporter_hash ||= {}
46
46
  end