solargraph 0.45.0 → 0.49.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.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/rspec.yml +1 -1
- data/CHANGELOG.md +41 -0
- data/LICENSE +1 -1
- data/README.md +8 -0
- data/SPONSORS.md +2 -4
- data/lib/solargraph/api_map/store.rb +13 -1
- data/lib/solargraph/api_map.rb +55 -32
- data/lib/solargraph/cache.rb +51 -0
- data/lib/solargraph/complex_type/type_methods.rb +10 -6
- data/lib/solargraph/complex_type/unique_type.rb +57 -0
- data/lib/solargraph/complex_type.rb +35 -2
- data/lib/solargraph/convention/rakefile.rb +17 -0
- data/lib/solargraph/convention.rb +2 -0
- data/lib/solargraph/diagnostics/require_not_found.rb +16 -0
- data/lib/solargraph/diagnostics/rubocop.rb +17 -3
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -1
- data/lib/solargraph/language_server/host.rb +22 -18
- data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
- data/lib/solargraph/language_server/message/initialize.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/hover.rb +16 -4
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +1 -1
- data/lib/solargraph/library.rb +21 -20
- data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +12 -2
- data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +24 -3
- data/lib/solargraph/parser/rubyvm/class_methods.rb +7 -2
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +13 -2
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +20 -9
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +14 -3
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +2 -2
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +14 -3
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +4 -2
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
- data/lib/solargraph/pin/base.rb +5 -2
- data/lib/solargraph/pin/block.rb +2 -1
- data/lib/solargraph/pin/conversions.rb +2 -6
- data/lib/solargraph/pin/method.rb +100 -10
- data/lib/solargraph/pin/namespace.rb +4 -1
- data/lib/solargraph/pin/parameter.rb +10 -7
- data/lib/solargraph/pin/search.rb +56 -0
- data/lib/solargraph/pin/signature.rb +23 -0
- data/lib/solargraph/pin.rb +2 -0
- data/lib/solargraph/rbs_map/conversions.rb +394 -0
- data/lib/solargraph/rbs_map/core_fills.rb +61 -0
- data/lib/solargraph/rbs_map/core_map.rb +38 -0
- data/lib/solargraph/rbs_map/core_signs.rb +33 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
- data/lib/solargraph/rbs_map.rb +73 -0
- data/lib/solargraph/shell.rb +38 -30
- data/lib/solargraph/source/chain/call.rb +34 -23
- data/lib/solargraph/source/chain.rb +21 -6
- data/lib/solargraph/source.rb +1 -1
- data/lib/solargraph/source_map/clip.rb +5 -0
- data/lib/solargraph/source_map/mapper.rb +31 -2
- data/lib/solargraph/source_map.rb +1 -10
- data/lib/solargraph/type_checker/checks.rb +13 -0
- data/lib/solargraph/type_checker.rb +88 -68
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +2 -2
- data/lib/solargraph/workspace.rb +12 -14
- data/lib/solargraph/yard_map/mapper/to_method.rb +7 -4
- data/lib/solargraph/yard_map.rb +51 -195
- data/lib/solargraph.rb +2 -2
- data/solargraph.gemspec +8 -6
- metadata +44 -36
- data/lib/solargraph/compat.rb +0 -37
- data/lib/solargraph/yard_map/core_docs.rb +0 -170
- data/lib/solargraph/yard_map/core_fills.rb +0 -208
- data/lib/solargraph/yard_map/core_gen.rb +0 -76
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
- data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
- data/yardoc/2.2.2.tar.gz +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0b66abd5cf5a0376d5521532dda16db328592eb38bac6acd84f997b19cb328c
|
4
|
+
data.tar.gz: 51e038df27bae1457393c7ff023c9951b0f8919267678e29aab2e21efeb2b1a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b8310748d4754c27fd62763ce1bd8759fc43fc825b1b40353d4537130f2b6143cdb59101da679a8b4a7fb0778430eeac2eccbb845f7a9a5ac11f402b3a71461
|
7
|
+
data.tar.gz: 1b2f79f5396a3c056d0b2acbcb49d6c1385b02a49b33edbe1a3e452a7b451b9b87547b8b8d5974a17e25ea2f5c21db8dd315d2b3d856fb3c7ce2d300a4595c70
|
data/.github/FUNDING.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
patreon: castwide
|
data/.github/workflows/rspec.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,44 @@
|
|
1
|
+
## 0.49.0 - April 9, 2023
|
2
|
+
- Better union type handling
|
3
|
+
- First version of RBS support
|
4
|
+
- Dependency updates
|
5
|
+
- Update RuboCop config options
|
6
|
+
- RBS core and stdlib mapping
|
7
|
+
- Anonymous splats and multisig arity
|
8
|
+
- Infinite loop when checking if a class is a superclass (#641)
|
9
|
+
|
10
|
+
## 0.48.0 - December 19, 2022
|
11
|
+
- Add Sublime Text to README (#604)
|
12
|
+
- Map nested constant assignments
|
13
|
+
- Handle rest/kwrest modifiers on overload arguments (#601)
|
14
|
+
- Make rubocop info severity Severity::HINT (#576)
|
15
|
+
- Process non-self singleton classes (#581)
|
16
|
+
- Fix nest gemspec dependency (#599)
|
17
|
+
- Strip 'file ' prefix from all filenames in RdocToYard (#585)
|
18
|
+
- Show why rubocop fails (#605)
|
19
|
+
- Link solargraph-rails (#611)
|
20
|
+
|
21
|
+
## 0.47.2 - September 30, 2022
|
22
|
+
- Fix complex type inference (#578)
|
23
|
+
- Off-by-one diagnostic (#595)
|
24
|
+
|
25
|
+
## 0.47.1 - September 27, 2022
|
26
|
+
- Remove debug code from release (#600)
|
27
|
+
|
28
|
+
## 0.47.0 - September 25, 2022
|
29
|
+
- Completion candidates for union types (#507)
|
30
|
+
- Nullify Hover object instead of contents value (#583)
|
31
|
+
- Mapping workspace stuck in 0 (#587)
|
32
|
+
- Fix parsing of nested subtypes (#589)
|
33
|
+
- Update YARD tags on Pin::Block methods (#588)
|
34
|
+
- @!visibility directive support (#566)
|
35
|
+
|
36
|
+
## 0.46.0 - August 22, 2022
|
37
|
+
- Ignore typecheck errors with @sg-ignore tag (#419)
|
38
|
+
- Strict checks report undefined method calls on variables (#553)
|
39
|
+
- Infer type from method arguments (#554)
|
40
|
+
- Return nil value for empty hover contents (#543)
|
41
|
+
|
1
42
|
## 0.45.0 - May 23, 2022
|
2
43
|
- Basic support for RSpec #describe and #it
|
3
44
|
- fix: domain can complete private method (#490)
|
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2017-
|
3
|
+
Copyright (c) 2017-2023 by Fred Snyder for Castwide Technologies
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -32,6 +32,11 @@ Plug-ins and extensions are available for the following editors:
|
|
32
32
|
* Package: https://atom.io/packages/ruby-solargraph
|
33
33
|
* GitHub: https://github.com/castwide/atom-solargraph
|
34
34
|
|
35
|
+
* **Sublime Text**
|
36
|
+
* Extension: https://packagecontrol.io/packages/LSP
|
37
|
+
* GitHub: https://github.com/sublimelsp/LSP
|
38
|
+
* Instructions: https://lsp.sublimetext.io/language_servers/#solargraph
|
39
|
+
|
35
40
|
* **Vim**
|
36
41
|
* GitHub: `LanguageClient-neovim`, https://github.com/autozimu/LanguageClient-neovim
|
37
42
|
* GitHub: `coc`, https://github.com/neoclide/coc-solargraph
|
@@ -49,6 +54,9 @@ Plug-ins and extensions are available for the following editors:
|
|
49
54
|
|
50
55
|
Solargraph's behavior can be controlled via optional [configuration](https://solargraph.org/guides/configuration) files. The highest priority file is a `.solargraph.yml` file at the root of the project. If not present, any global configuration at `~/.config/solargraph/config.yml` will apply. The path to the global configuration can be overridden with the `SOLARGRAPH_GLOBAL_CONFIG` environment variable.
|
51
56
|
|
57
|
+
### Rails Support
|
58
|
+
For better Rails support, please consider using [solargraph-rails](https://github.com/iftheshoefritz/solargraph-rails/)
|
59
|
+
|
52
60
|
### Gem Support
|
53
61
|
|
54
62
|
Solargraph is capable of providing code completion and documentation for gems that have YARD documentation. You can make sure your gems are documented by running `yard gems` from the command line. (YARD is included as one of Solargraph's gem dependencies. The first time you run it might take a while if you have a lot of gems installed).
|
data/SPONSORS.md
CHANGED
@@ -247,10 +247,22 @@ module Solargraph
|
|
247
247
|
end
|
248
248
|
ovr.tags.each do |tag|
|
249
249
|
pin.docstring.add_tag(tag)
|
250
|
-
|
250
|
+
redefine_return_type pin, tag
|
251
|
+
if new_pin
|
252
|
+
new_pin.docstring.add_tag(tag)
|
253
|
+
redefine_return_type new_pin, tag
|
254
|
+
end
|
251
255
|
end
|
252
256
|
end
|
253
257
|
end
|
258
|
+
|
259
|
+
def redefine_return_type pin, tag
|
260
|
+
return unless pin && tag.tag_name == 'return'
|
261
|
+
pin.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
|
262
|
+
pin.signatures.each do |sig|
|
263
|
+
sig.instance_variable_set(:@return_type, ComplexType.try_parse(tag.type))
|
264
|
+
end
|
265
|
+
end
|
254
266
|
end
|
255
267
|
end
|
256
268
|
end
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -21,6 +21,11 @@ module Solargraph
|
|
21
21
|
# @return [Array<String>]
|
22
22
|
attr_reader :unresolved_requires
|
23
23
|
|
24
|
+
@@core_map = RbsMap::CoreMap.new
|
25
|
+
|
26
|
+
# @return [Array<String>]
|
27
|
+
attr_reader :missing_docs
|
28
|
+
|
24
29
|
# @param pins [Array<Solargraph::Pin::Base>]
|
25
30
|
def initialize pins: []
|
26
31
|
@source_map_hash = {}
|
@@ -37,7 +42,7 @@ module Solargraph
|
|
37
42
|
@source_map_hash = {}
|
38
43
|
implicit.clear
|
39
44
|
cache.clear
|
40
|
-
@store = Store.new(
|
45
|
+
@store = Store.new(@@core_map.pins + pins)
|
41
46
|
self
|
42
47
|
end
|
43
48
|
|
@@ -65,14 +70,25 @@ module Solargraph
|
|
65
70
|
end
|
66
71
|
external_requires.merge implicit.requires
|
67
72
|
external_requires.merge bench.workspace.config.required
|
68
|
-
|
69
|
-
|
73
|
+
@rbs_maps = external_requires.map { |r| load_rbs_map(r) }
|
74
|
+
unresolved_requires = @rbs_maps.reject(&:resolved?).map(&:library)
|
75
|
+
yard_map.change(unresolved_requires, bench.workspace.directory, bench.workspace.source_gems)
|
76
|
+
@store = Store.new(@@core_map.pins + @rbs_maps.flat_map(&:pins) + yard_map.pins + implicit.pins + pins)
|
70
77
|
@unresolved_requires = yard_map.unresolved_requires
|
78
|
+
@missing_docs = yard_map.missing_docs
|
71
79
|
@rebindable_method_names = nil
|
72
80
|
store.block_pins.each { |blk| blk.rebind(self) }
|
73
81
|
self
|
74
82
|
end
|
75
83
|
|
84
|
+
def core_pins
|
85
|
+
@@core_map.pins
|
86
|
+
end
|
87
|
+
|
88
|
+
def yard_map
|
89
|
+
@yard_map ||= YardMap.new
|
90
|
+
end
|
91
|
+
|
76
92
|
# @param name [String]
|
77
93
|
# @return [YARD::Tags::MacroDirective, nil]
|
78
94
|
def named_macro name
|
@@ -128,7 +144,8 @@ module Solargraph
|
|
128
144
|
|
129
145
|
def rebindable_method_names
|
130
146
|
@rebindable_method_names ||= begin
|
131
|
-
result = yard_map.rebindable_method_names
|
147
|
+
# result = yard_map.rebindable_method_names
|
148
|
+
result = ['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec', 'define_method'].to_set
|
132
149
|
source_maps.each do |map|
|
133
150
|
result.merge map.rebindable_method_names
|
134
151
|
end
|
@@ -187,7 +204,7 @@ module Solargraph
|
|
187
204
|
#
|
188
205
|
# @param namespace [String, nil] The namespace to match
|
189
206
|
# @param context [String] The context to search
|
190
|
-
# @return [String]
|
207
|
+
# @return [String, nil]
|
191
208
|
def qualify namespace, context = ''
|
192
209
|
return namespace if ['self', nil].include?(namespace)
|
193
210
|
cached = cache.get_qualified_namespace(namespace, context)
|
@@ -281,33 +298,33 @@ module Solargraph
|
|
281
298
|
# type = Solargraph::ComplexType.parse('String')
|
282
299
|
# api_map.get_complex_type_methods(type)
|
283
300
|
#
|
284
|
-
# @param
|
301
|
+
# @param complex_type [Solargraph::ComplexType] The complex type of the namespace
|
285
302
|
# @param context [String] The context from which the type is referenced
|
286
303
|
# @param internal [Boolean] True to include private methods
|
287
304
|
# @return [Array<Solargraph::Pin::Base>]
|
288
|
-
def get_complex_type_methods
|
305
|
+
def get_complex_type_methods complex_type, context = '', internal = false
|
289
306
|
# This method does not qualify the complex type's namespace because
|
290
307
|
# it can cause conflicts between similar names, e.g., `Foo` vs.
|
291
308
|
# `Other::Foo`. It still takes a context argument to determine whether
|
292
309
|
# protected and private methods are visible.
|
293
|
-
return [] if
|
294
|
-
result =
|
295
|
-
|
296
|
-
type.
|
297
|
-
result.
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
310
|
+
return [] if complex_type.undefined? || complex_type.void?
|
311
|
+
result = Set.new
|
312
|
+
complex_type.each do |type|
|
313
|
+
if type.duck_type?
|
314
|
+
result.add Pin::DuckMethod.new(name: type.to_s[1..-1])
|
315
|
+
result.merge get_methods('Object')
|
316
|
+
else
|
317
|
+
unless type.nil? || type.name == 'void'
|
318
|
+
visibility = [:public]
|
319
|
+
if type.namespace == context || super_and_sub?(type.namespace, context)
|
320
|
+
visibility.push :protected
|
321
|
+
visibility.push :private if internal
|
322
|
+
end
|
323
|
+
result.merge get_methods(type.namespace, scope: type.scope, visibility: visibility)
|
306
324
|
end
|
307
|
-
result.concat get_methods(type.namespace, scope: type.scope, visibility: visibility)
|
308
325
|
end
|
309
326
|
end
|
310
|
-
result
|
327
|
+
result.to_a
|
311
328
|
end
|
312
329
|
|
313
330
|
# Get a stack of method pins for a method name in a namespace. The order
|
@@ -383,9 +400,10 @@ module Solargraph
|
|
383
400
|
# @param query [String]
|
384
401
|
# @return [Array<Pin::Base>]
|
385
402
|
def query_symbols query
|
386
|
-
|
387
|
-
|
388
|
-
|
403
|
+
Pin::Search.new(
|
404
|
+
source_map_hash.values.flat_map(&:document_symbols),
|
405
|
+
query
|
406
|
+
).results
|
389
407
|
end
|
390
408
|
|
391
409
|
# @param location [Solargraph::Location]
|
@@ -442,18 +460,15 @@ module Solargraph
|
|
442
460
|
def super_and_sub?(sup, sub)
|
443
461
|
fqsup = qualify(sup)
|
444
462
|
cls = qualify(sub)
|
445
|
-
|
463
|
+
tested = []
|
464
|
+
until fqsup.nil? || cls.nil? || tested.include?(cls)
|
446
465
|
return true if cls == fqsup
|
466
|
+
tested.push cls
|
447
467
|
cls = qualify_superclass(cls)
|
448
468
|
end
|
449
469
|
false
|
450
470
|
end
|
451
471
|
|
452
|
-
# @return [YardMap]
|
453
|
-
def yard_map
|
454
|
-
@yard_map ||= YardMap.new
|
455
|
-
end
|
456
|
-
|
457
472
|
# Check if the host class includes the specified module.
|
458
473
|
#
|
459
474
|
# @param host [String] The class
|
@@ -470,6 +485,14 @@ module Solargraph
|
|
470
485
|
# @return [Hash{String => SourceMap}]
|
471
486
|
attr_reader :source_map_hash
|
472
487
|
|
488
|
+
# @param library [String]
|
489
|
+
# @return [RbsMap]
|
490
|
+
def load_rbs_map library
|
491
|
+
# map = RbsMap.load(library)
|
492
|
+
# return map if map.resolved?
|
493
|
+
RbsMap::StdlibMap.load(library)
|
494
|
+
end
|
495
|
+
|
473
496
|
# @return [ApiMap::Store]
|
474
497
|
def store
|
475
498
|
@store ||= Store.new
|
@@ -672,7 +695,7 @@ module Solargraph
|
|
672
695
|
comments: origin.comments,
|
673
696
|
scope: origin.scope,
|
674
697
|
visibility: origin.visibility,
|
675
|
-
|
698
|
+
signatures: origin.signatures,
|
676
699
|
attribute: origin.attribute?
|
677
700
|
}
|
678
701
|
Pin::Method.new **args
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
module Cache
|
5
|
+
class << self
|
6
|
+
# The base directory where cached documentation is installed.
|
7
|
+
#
|
8
|
+
# @return [String]
|
9
|
+
def base_dir
|
10
|
+
# The directory is not stored in a variable so it can be overridden
|
11
|
+
# in specs.
|
12
|
+
ENV['SOLARGRAPH_CACHE'] || File.join(Dir.home, '.solargraph', 'cache')
|
13
|
+
end
|
14
|
+
|
15
|
+
# The working directory for the current Ruby and Solargraph versions.
|
16
|
+
#
|
17
|
+
# @return [String]
|
18
|
+
def work_dir
|
19
|
+
# The directory is not stored in a variable so it can be overridden
|
20
|
+
# in specs.
|
21
|
+
File.join(base_dir, "ruby-#{RUBY_VERSION}", "rbs-#{RBS::VERSION}", "solargraph-#{Solargraph::VERSION}")
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [Array<Solargraph::Pin::Base>, nil]
|
25
|
+
def load *path
|
26
|
+
file = File.join(work_dir, *path)
|
27
|
+
return nil unless File.file?(file)
|
28
|
+
Marshal.load(File.read(file, mode: 'rb'))
|
29
|
+
rescue StandardError => e
|
30
|
+
Solargraph.logger.warn "Failed to load cached file #{file}: [#{e.class}] #{e.message}"
|
31
|
+
FileUtils.rm_f file
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Boolean]
|
36
|
+
def save *path, pins
|
37
|
+
return false if pins.empty?
|
38
|
+
file = File.join(work_dir, *path)
|
39
|
+
base = File.dirname(file)
|
40
|
+
FileUtils.mkdir_p base unless File.directory?(base)
|
41
|
+
ser = Marshal.dump(pins)
|
42
|
+
File.write file, ser, mode: 'wb'
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
def clear
|
47
|
+
FileUtils.rm_rf base_dir, secure: true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -101,6 +101,7 @@ module Solargraph
|
|
101
101
|
# @param context [String] The namespace from which to resolve names
|
102
102
|
# @return [ComplexType] The generated ComplexType
|
103
103
|
def qualify api_map, context = ''
|
104
|
+
return self if name == 'param'
|
104
105
|
return ComplexType.new([self]) if duck_type? || void? || undefined?
|
105
106
|
recon = (rooted? ? '' : context)
|
106
107
|
fqns = api_map.qualify(name, recon)
|
@@ -109,12 +110,8 @@ module Solargraph
|
|
109
110
|
return UniqueType::UNDEFINED
|
110
111
|
end
|
111
112
|
fqns = "::#{fqns}" # Ensure the resulting complex type is rooted
|
112
|
-
ltypes = key_types.map
|
113
|
-
|
114
|
-
end
|
115
|
-
rtypes = value_types.map do |t|
|
116
|
-
t.qualify api_map, context
|
117
|
-
end
|
113
|
+
ltypes = key_types.map { |t| t.qualify api_map, context }.uniq
|
114
|
+
rtypes = value_types.map { |t| t.qualify api_map, context }.uniq
|
118
115
|
if list_parameters?
|
119
116
|
Solargraph::ComplexType.parse("#{fqns}<#{rtypes.map(&:tag).join(', ')}>")
|
120
117
|
elsif fixed_parameters?
|
@@ -125,6 +122,13 @@ module Solargraph
|
|
125
122
|
Solargraph::ComplexType.parse(fqns)
|
126
123
|
end
|
127
124
|
end
|
125
|
+
|
126
|
+
# @yieldparam [UniqueType]
|
127
|
+
# @return [Enumerator<UniqueType>]
|
128
|
+
def each_unique_type &block
|
129
|
+
return enum_for(__method__) unless block_given?
|
130
|
+
yield self
|
131
|
+
end
|
128
132
|
end
|
129
133
|
end
|
130
134
|
end
|
@@ -8,6 +8,8 @@ module Solargraph
|
|
8
8
|
class UniqueType
|
9
9
|
include TypeMethods
|
10
10
|
|
11
|
+
attr_reader :all_params
|
12
|
+
|
11
13
|
# Create a UniqueType with the specified name and an optional substring.
|
12
14
|
# The substring is the parameter section of a parametrized type, e.g.,
|
13
15
|
# for the type `Array<String>`, the name is `Array` and the substring is
|
@@ -27,6 +29,7 @@ module Solargraph
|
|
27
29
|
@tag = @name + substring
|
28
30
|
@key_types = []
|
29
31
|
@subtypes = []
|
32
|
+
@all_params = []
|
30
33
|
return unless parameters?
|
31
34
|
if @substring.start_with?('<(') && @substring.end_with?(')>')
|
32
35
|
subs = ComplexType.parse(substring[2..-3], partial: true)
|
@@ -40,12 +43,66 @@ module Solargraph
|
|
40
43
|
else
|
41
44
|
@subtypes.concat subs
|
42
45
|
end
|
46
|
+
@all_params.concat @key_types
|
47
|
+
@all_params.concat @subtypes
|
43
48
|
end
|
44
49
|
|
45
50
|
def to_s
|
46
51
|
tag
|
47
52
|
end
|
48
53
|
|
54
|
+
def to_rbs
|
55
|
+
"#{namespace}#{parameters? ? "[#{subtypes.map { |s| s.to_rbs }.join(', ')}]" : ''}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def parameterized?
|
59
|
+
name == 'param' || all_params.any?(&:parameterized?)
|
60
|
+
end
|
61
|
+
|
62
|
+
def resolve_parameters definitions, context
|
63
|
+
new_name = if name == 'param'
|
64
|
+
idx = definitions.parameters.index(subtypes.first.name)
|
65
|
+
return ComplexType::UNDEFINED if idx.nil?
|
66
|
+
param_type = context.return_type.all_params[idx]
|
67
|
+
return ComplexType::UNDEFINED unless param_type
|
68
|
+
param_type.to_s
|
69
|
+
else
|
70
|
+
name
|
71
|
+
end
|
72
|
+
new_key_types = if name != 'param'
|
73
|
+
@key_types.map { |t| t.resolve_parameters(definitions, context) }.select(&:defined?)
|
74
|
+
else
|
75
|
+
[]
|
76
|
+
end
|
77
|
+
new_subtypes = if name != 'param'
|
78
|
+
@subtypes.map { |t| t.resolve_parameters(definitions, context) }.select(&:defined?)
|
79
|
+
else
|
80
|
+
[]
|
81
|
+
end
|
82
|
+
if name != 'param' && !(new_key_types.empty? && new_subtypes.empty?)
|
83
|
+
if hash_parameters?
|
84
|
+
UniqueType.new(new_name, "{#{new_key_types.join(', ')} => #{new_subtypes.join(', ')}}")
|
85
|
+
elsif parameters?
|
86
|
+
if @substring.start_with?'<('
|
87
|
+
UniqueType.new(new_name, "<(#{new_subtypes.join(', ')})>")
|
88
|
+
else
|
89
|
+
UniqueType.new(new_name, "<#{new_subtypes.join(', ')}>")
|
90
|
+
end
|
91
|
+
else
|
92
|
+
UniqueType.new(new_name)
|
93
|
+
end
|
94
|
+
else
|
95
|
+
UniqueType.new(new_name)
|
96
|
+
end
|
97
|
+
|
98
|
+
# idx = definitions.parameters.index(subtypes.first.name)
|
99
|
+
# STDERR.puts "Index: #{idx}"
|
100
|
+
# return ComplexType::UNDEFINED if idx.nil?
|
101
|
+
# param_type = context.return_type.all_params[idx]
|
102
|
+
# return ComplexType::UNDEFINED unless param_type
|
103
|
+
# ComplexType.try_parse(param_type.to_s)
|
104
|
+
end
|
105
|
+
|
49
106
|
def self_to dst
|
50
107
|
return self unless selfy?
|
51
108
|
new_name = (@name == 'self' ? dst : @name)
|
@@ -30,6 +30,12 @@ module Solargraph
|
|
30
30
|
@items.first
|
31
31
|
end
|
32
32
|
|
33
|
+
def to_rbs
|
34
|
+
((@items.length > 1 ? '(' : '') + @items.map do |item|
|
35
|
+
"#{item.namespace}#{item.parameters? ? "[#{item.subtypes.map { |s| s.to_rbs }.join(', ')}]" : ''}"
|
36
|
+
end.join(' | ') + (@items.length > 1 ? ')' : '')).gsub(/undefined/, 'untyped')
|
37
|
+
end
|
38
|
+
|
33
39
|
def map &block
|
34
40
|
@items.map &block
|
35
41
|
end
|
@@ -40,6 +46,16 @@ module Solargraph
|
|
40
46
|
@items.each &block
|
41
47
|
end
|
42
48
|
|
49
|
+
# @yieldparam [UniqueType]
|
50
|
+
# @return [Enumerator<UniqueType>]
|
51
|
+
def each_unique_type &block
|
52
|
+
return enum_for(__method__) unless block_given?
|
53
|
+
|
54
|
+
@items.each do |item|
|
55
|
+
item.each_unique_type &block
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
43
59
|
def length
|
44
60
|
@items.length
|
45
61
|
end
|
@@ -74,10 +90,23 @@ module Solargraph
|
|
74
90
|
@items.all? &block
|
75
91
|
end
|
76
92
|
|
93
|
+
def any? &block
|
94
|
+
@items.compact.any? &block
|
95
|
+
end
|
96
|
+
|
77
97
|
def selfy?
|
78
98
|
@items.any?(&:selfy?)
|
79
99
|
end
|
80
100
|
|
101
|
+
def parameterized?
|
102
|
+
any?(&:parameterized?)
|
103
|
+
end
|
104
|
+
|
105
|
+
def resolve_parameters definitions, context
|
106
|
+
result = @items.map { |i| i.resolve_parameters(definitions, context) }
|
107
|
+
ComplexType.parse(*result.map(&:tag))
|
108
|
+
end
|
109
|
+
|
81
110
|
# @param dst [String]
|
82
111
|
# @return [ComplexType]
|
83
112
|
def self_to dst
|
@@ -91,6 +120,10 @@ module Solargraph
|
|
91
120
|
@items.any?(&:nil_type?)
|
92
121
|
end
|
93
122
|
|
123
|
+
def all_params
|
124
|
+
@items.first.all_params || []
|
125
|
+
end
|
126
|
+
|
94
127
|
private
|
95
128
|
|
96
129
|
# @todo This is a quick and dirty hack that forces `self` keywords
|
@@ -154,9 +187,9 @@ module Solargraph
|
|
154
187
|
subtype_string.clear
|
155
188
|
next
|
156
189
|
else
|
190
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack == 0
|
157
191
|
point_stack -= 1
|
158
|
-
subtype_string += char
|
159
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack < 0
|
192
|
+
subtype_string += char
|
160
193
|
end
|
161
194
|
next
|
162
195
|
elsif char == '{'
|
@@ -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
|
@@ -11,6 +11,7 @@ module Solargraph
|
|
11
11
|
autoload :Gemfile, 'solargraph/convention/gemfile'
|
12
12
|
autoload :Rspec, 'solargraph/convention/rspec'
|
13
13
|
autoload :Gemspec, 'solargraph/convention/gemspec'
|
14
|
+
autoload :Rakefile, 'solargraph/convention/rakefile'
|
14
15
|
|
15
16
|
@@conventions = Set.new
|
16
17
|
|
@@ -43,5 +44,6 @@ module Solargraph
|
|
43
44
|
register Gemfile
|
44
45
|
register Gemspec
|
45
46
|
register Rspec
|
47
|
+
register Rakefile
|
46
48
|
end
|
47
49
|
end
|
@@ -12,6 +12,10 @@ module Solargraph
|
|
12
12
|
refs = {}
|
13
13
|
map = api_map.source_map(source.filename)
|
14
14
|
map.requires.each { |ref| refs[ref.name] = ref }
|
15
|
+
api_map.missing_docs.each do |r|
|
16
|
+
next unless refs.key?(r)
|
17
|
+
result.push docs_error(r, refs[r].location)
|
18
|
+
end
|
15
19
|
api_map.unresolved_requires.each do |r|
|
16
20
|
next unless refs.key?(r)
|
17
21
|
result.push require_error(r, refs[r].location)
|
@@ -21,6 +25,18 @@ module Solargraph
|
|
21
25
|
|
22
26
|
private
|
23
27
|
|
28
|
+
# @param path [String]
|
29
|
+
# @param location [Location]
|
30
|
+
# @return [Hash]
|
31
|
+
def docs_error path, location
|
32
|
+
{
|
33
|
+
range: location.range.to_hash,
|
34
|
+
severity: Diagnostics::Severities::WARNING,
|
35
|
+
source: 'RequireNotFound',
|
36
|
+
message: "YARD docs not found for #{path}"
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
24
40
|
# @param path [String]
|
25
41
|
# @param location [Location]
|
26
42
|
# @return [Hash]
|
@@ -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,
|
38
|
+
rescue JSON::ParserError => e
|
39
|
+
raise DiagnosticsError, "RuboCop returned invalid data: #{e.message}"
|
35
40
|
end
|
36
41
|
|
37
42
|
private
|
@@ -88,8 +93,17 @@ module Solargraph
|
|
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
|
+
last_column = off['location']['last_column']
|
98
|
+
line = @source.code.lines[start_line]
|
99
|
+
col_off = if line.nil? || line.empty?
|
100
|
+
1
|
101
|
+
else
|
102
|
+
0
|
103
|
+
end
|
104
|
+
|
91
105
|
Position.new(
|
92
|
-
|
106
|
+
start_line, last_column - col_off
|
93
107
|
)
|
94
108
|
end
|
95
109
|
end
|