solargraph 0.49.0 → 0.51.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rspec.yml +4 -6
- data/CHANGELOG.md +38 -0
- data/README.md +2 -4
- data/SPONSORS.md +2 -1
- data/lib/solargraph/cache.rb +3 -1
- data/lib/solargraph/complex_type.rb +9 -2
- data/lib/solargraph/convention.rb +0 -2
- data/lib/solargraph/language_server/host/cataloger.rb +1 -1
- data/lib/solargraph/language_server/host.rb +11 -1
- data/lib/solargraph/language_server/message/initialize.rb +8 -0
- data/lib/solargraph/language_server/message/initialized.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +4 -1
- data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -4
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +24 -0
- data/lib/solargraph/language_server/message/text_document.rb +1 -0
- data/lib/solargraph/language_server/message.rb +1 -0
- data/lib/solargraph/library.rb +22 -2
- data/lib/solargraph/parser/rubyvm/class_methods.rb +4 -0
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +1 -1
- data/lib/solargraph/parser/rubyvm/node_methods.rb +3 -1
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +10 -4
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +2 -2
- data/lib/solargraph/parser/rubyvm/node_processors.rb +1 -0
- data/lib/solargraph/parser.rb +2 -2
- data/lib/solargraph/pin/base_variable.rb +1 -1
- data/lib/solargraph/pin/block.rb +1 -1
- data/lib/solargraph/pin/delegated_method.rb +97 -0
- data/lib/solargraph/pin/method.rb +5 -0
- data/lib/solargraph/pin/search.rb +1 -1
- data/lib/solargraph/pin.rb +1 -0
- data/lib/solargraph/range.rb +2 -4
- data/lib/solargraph/rbs_map/conversions.rb +8 -6
- data/lib/solargraph/rbs_map/core_fills.rb +7 -1
- data/lib/solargraph/rbs_map/core_map.rb +1 -1
- data/lib/solargraph/rbs_map/stdlib_map.rb +3 -0
- data/lib/solargraph/shell.rb +16 -6
- data/lib/solargraph/source/chain/call.rb +1 -1
- data/lib/solargraph/source/chain.rb +1 -1
- data/lib/solargraph/source_map/clip.rb +14 -0
- data/lib/solargraph/source_map/mapper.rb +6 -4
- data/lib/solargraph/source_map.rb +15 -2
- data/lib/solargraph/type_checker.rb +33 -21
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +6 -5
- data/lib/solargraph/yard_map.rb +15 -7
- data/solargraph.gemspec +11 -5
- metadata +73 -22
- data/.travis.yml +0 -19
- data/lib/solargraph/convention/rspec.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 925e6692e134d83820ade3224a10e1e25ba8b7f65c5a8399b185574f225ad8e7
|
4
|
+
data.tar.gz: 319f943451956ac714e110f48db851391cfb5c4b2ceb1e3e8d2eb2d22dc56c05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df03f1f0ed8e51f8c286395c4b87b1c254c78a897761ec71a9af896ef86c01e6d4285530ddf2e40c72f17afb6b5d87be11e219cc46859d7d7b7c2e05e24687bf
|
7
|
+
data.tar.gz: dd6b4f96bc8e6361bcfd313129a4ba9d680c8db45484deea040ec5fa6ba5a8873dcefa2980af4824d26f2ecc16d68bd5b5554e4978ae71853e22df49ed427894
|
data/.github/workflows/rspec.yml
CHANGED
@@ -22,19 +22,17 @@ jobs:
|
|
22
22
|
runs-on: ubuntu-latest
|
23
23
|
strategy:
|
24
24
|
matrix:
|
25
|
-
ruby-version: ['2.6', '2.7', '3.0', '3.1']
|
25
|
+
ruby-version: ['2.6', '2.7', '3.0', '3.1', '3.2', '3.3', '3.4', 'head']
|
26
26
|
|
27
27
|
steps:
|
28
28
|
- uses: actions/checkout@v3
|
29
29
|
- name: Set up Ruby
|
30
|
-
|
31
|
-
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
32
|
-
# uses: ruby/setup-ruby@v1
|
33
|
-
uses: ruby/setup-ruby@2b019609e2b0f1ea1a2bc8ca11cb82ab46ada124
|
30
|
+
uses: ruby/setup-ruby@v1
|
34
31
|
with:
|
35
32
|
ruby-version: ${{ matrix.ruby-version }}
|
36
33
|
bundler-cache: false
|
37
|
-
-
|
34
|
+
- name: Install gems
|
35
|
+
run: bundle install
|
38
36
|
- name: Set up yardocs
|
39
37
|
run: bundle exec yard gems
|
40
38
|
- name: Run tests
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,41 @@
|
|
1
|
+
## 0.51.0 - January 19, 2025
|
2
|
+
- Resolve self in yieldself tags
|
3
|
+
- Include absolute paths in config (#674)
|
4
|
+
- Enable diagnostics by default
|
5
|
+
- Fix cache resolution (#704)
|
6
|
+
- Modify rubocop option for rubocop < 1.30 (#665)
|
7
|
+
- Include absolute paths in config (#674)
|
8
|
+
- Enable diagnostics by default
|
9
|
+
- Remove RSpec convention (#716)
|
10
|
+
- Include convention pins in document_symbols (#724)
|
11
|
+
- Remove e2mmap dependency (#699)
|
12
|
+
- Update rbs to 3.0
|
13
|
+
- Relax reverse_markdown dependency (#729)
|
14
|
+
- Fix Ruby 3.4 and move all parsing to whitequark (#739)
|
15
|
+
- Add Pin::DelegatedMethod (#602)
|
16
|
+
- Complete global methods from a file inside namespaces (#714)
|
17
|
+
- gemspec dashes and required path slashes (#697)
|
18
|
+
|
19
|
+
## 0.50.0 - December 5, 2023
|
20
|
+
- Remove .travis.yml as its not longer used (#627)
|
21
|
+
- Fix empty string case when processing requires (#644)
|
22
|
+
- Fix scope() method call on wrong object (#670)
|
23
|
+
- Parse comments that start with multiple hashes (#667)
|
24
|
+
- Use XDG_CACHE_HOME if it exists (#664)
|
25
|
+
- Add rbs mention to readme (#693)
|
26
|
+
- Remove Atom from the readme (#692)
|
27
|
+
- Add more metadata to the gemspec (#691)
|
28
|
+
- Do not deprecate clear command
|
29
|
+
- Library#locate_ref returns nil for unresolved requires (#675)
|
30
|
+
- Hide deprecated commands
|
31
|
+
- List command
|
32
|
+
- Fixes (or ignores) ffi crash (#676)
|
33
|
+
- increase sleep time on cataloger (#677)
|
34
|
+
- YardMap ignores absolute paths (#678)
|
35
|
+
- Clarify macros vs. directives
|
36
|
+
- Infer complex types from method calls
|
37
|
+
- Default cache uses XDG_CACHE_HOME default (#664)
|
38
|
+
|
1
39
|
## 0.49.0 - April 9, 2023
|
2
40
|
- Better union type handling
|
3
41
|
- First version of RBS support
|
data/README.md
CHANGED
@@ -28,10 +28,6 @@ Plug-ins and extensions are available for the following editors:
|
|
28
28
|
* Extension: https://marketplace.visualstudio.com/items?itemName=castwide.solargraph
|
29
29
|
* GitHub: https://github.com/castwide/vscode-solargraph
|
30
30
|
|
31
|
-
* **Atom**
|
32
|
-
* Package: https://atom.io/packages/ruby-solargraph
|
33
|
-
* GitHub: https://github.com/castwide/atom-solargraph
|
34
|
-
|
35
31
|
* **Sublime Text**
|
36
32
|
* Extension: https://packagecontrol.io/packages/LSP
|
37
33
|
* GitHub: https://github.com/sublimelsp/LSP
|
@@ -71,6 +67,8 @@ As of version 0.33.0, Solargraph includes a [type checker](https://github.com/ca
|
|
71
67
|
|
72
68
|
### Updating Core Documentation
|
73
69
|
|
70
|
+
As of version 0.49.0, Solargraph uses [rbs](https://github.com/ruby/rbs) for core and stdlib documentation. The following only applies to prior versions.
|
71
|
+
|
74
72
|
The Solargraph gem ships with documentation for Ruby 2.2.2. You can download documentation for other Ruby versions from the command line.
|
75
73
|
|
76
74
|
$ solargraph list-cores # List the installed documentation versions
|
data/SPONSORS.md
CHANGED
data/lib/solargraph/cache.rb
CHANGED
@@ -9,7 +9,9 @@ module Solargraph
|
|
9
9
|
def base_dir
|
10
10
|
# The directory is not stored in a variable so it can be overridden
|
11
11
|
# in specs.
|
12
|
-
ENV['SOLARGRAPH_CACHE'] ||
|
12
|
+
ENV['SOLARGRAPH_CACHE'] ||
|
13
|
+
(ENV['XDG_CACHE_HOME'] ? File.join(ENV['XDG_CACHE_HOME'], 'solargraph') : nil) ||
|
14
|
+
File.join(Dir.home, '.cache', 'solargraph')
|
13
15
|
end
|
14
16
|
|
15
17
|
# The working directory for the current Ruby and Solargraph versions.
|
@@ -67,11 +67,18 @@ module Solargraph
|
|
67
67
|
def select &block
|
68
68
|
@items.select &block
|
69
69
|
end
|
70
|
+
|
71
|
+
# @return [String]
|
70
72
|
def namespace
|
71
73
|
# cache this attr for high frequency call
|
72
74
|
@namespace ||= method_missing(:namespace).to_s
|
73
75
|
end
|
74
76
|
|
77
|
+
# @return [Array<String>]
|
78
|
+
def namespaces
|
79
|
+
@items.map(&:namespace)
|
80
|
+
end
|
81
|
+
|
75
82
|
def method_missing name, *args, &block
|
76
83
|
return if @items.first.nil?
|
77
84
|
return @items.first.send(name, *args, &block) if respond_to_missing?(name)
|
@@ -113,7 +120,7 @@ module Solargraph
|
|
113
120
|
return self unless selfy?
|
114
121
|
red = reduce_class(dst)
|
115
122
|
result = @items.map { |i| i.self_to red }
|
116
|
-
ComplexType.parse(*result.map(&:
|
123
|
+
ComplexType.parse(*result.map(&:to_s))
|
117
124
|
end
|
118
125
|
|
119
126
|
def nullable?
|
@@ -169,7 +176,7 @@ module Solargraph
|
|
169
176
|
paren_stack = 0
|
170
177
|
base = String.new
|
171
178
|
subtype_string = String.new
|
172
|
-
type_string
|
179
|
+
type_string&.each_char do |char|
|
173
180
|
if char == '='
|
174
181
|
#raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
|
175
182
|
elsif char == '<'
|
@@ -9,7 +9,6 @@ module Solargraph
|
|
9
9
|
module Convention
|
10
10
|
autoload :Base, 'solargraph/convention/base'
|
11
11
|
autoload :Gemfile, 'solargraph/convention/gemfile'
|
12
|
-
autoload :Rspec, 'solargraph/convention/rspec'
|
13
12
|
autoload :Gemspec, 'solargraph/convention/gemspec'
|
14
13
|
autoload :Rakefile, 'solargraph/convention/rakefile'
|
15
14
|
|
@@ -43,7 +42,6 @@ module Solargraph
|
|
43
42
|
|
44
43
|
register Gemfile
|
45
44
|
register Gemspec
|
46
|
-
register Rspec
|
47
45
|
register Rakefile
|
48
46
|
end
|
49
47
|
end
|
@@ -533,6 +533,15 @@ module Solargraph
|
|
533
533
|
library.definitions_at(uri_to_file(uri), line, column)
|
534
534
|
end
|
535
535
|
|
536
|
+
# @param uri [String]
|
537
|
+
# @param line [Integer]
|
538
|
+
# @param column [Integer]
|
539
|
+
# @return [Array<Solargraph::Pin::Base>]
|
540
|
+
def type_definitions_at uri, line, column
|
541
|
+
library = library_for(uri)
|
542
|
+
library.type_definitions_at(uri_to_file(uri), line, column)
|
543
|
+
end
|
544
|
+
|
536
545
|
# @param uri [String]
|
537
546
|
# @param line [Integer]
|
538
547
|
# @param column [Integer]
|
@@ -630,10 +639,11 @@ module Solargraph
|
|
630
639
|
'hover' => true,
|
631
640
|
'symbols' => true,
|
632
641
|
'definitions' => true,
|
642
|
+
'typeDefinitions' => true,
|
633
643
|
'rename' => true,
|
634
644
|
'references' => true,
|
635
645
|
'autoformat' => false,
|
636
|
-
'diagnostics' =>
|
646
|
+
'diagnostics' => true,
|
637
647
|
'formatting' => false,
|
638
648
|
'folding' => true,
|
639
649
|
'highlights' => true,
|
@@ -34,6 +34,7 @@ module Solargraph
|
|
34
34
|
result[:capabilities].merge! static_document_formatting unless dynamic_registration_for?('textDocument', 'formatting')
|
35
35
|
result[:capabilities].merge! static_document_symbols unless dynamic_registration_for?('textDocument', 'documentSymbol')
|
36
36
|
result[:capabilities].merge! static_definitions unless dynamic_registration_for?('textDocument', 'definition')
|
37
|
+
result[:capabilities].merge! static_type_definitions unless dynamic_registration_for?('textDocument', 'typeDefinition')
|
37
38
|
result[:capabilities].merge! static_rename unless dynamic_registration_for?('textDocument', 'rename')
|
38
39
|
result[:capabilities].merge! static_references unless dynamic_registration_for?('textDocument', 'references')
|
39
40
|
result[:capabilities].merge! static_workspace_symbols unless dynamic_registration_for?('workspace', 'symbol')
|
@@ -121,6 +122,13 @@ module Solargraph
|
|
121
122
|
}
|
122
123
|
end
|
123
124
|
|
125
|
+
def static_type_definitions
|
126
|
+
return {} unless host.options['type_definitions']
|
127
|
+
{
|
128
|
+
definitionProvider: true
|
129
|
+
}
|
130
|
+
end
|
131
|
+
|
124
132
|
def static_rename
|
125
133
|
{
|
126
134
|
renameProvider: {prepareProvider: true}
|
@@ -6,6 +6,8 @@ class Solargraph::LanguageServer::Message::TextDocument::DocumentSymbol < Solarg
|
|
6
6
|
def process
|
7
7
|
pins = host.document_symbols params['textDocument']['uri']
|
8
8
|
info = pins.map do |pin|
|
9
|
+
next nil unless pin.location&.filename
|
10
|
+
|
9
11
|
result = {
|
10
12
|
name: pin.name,
|
11
13
|
containerName: pin.namespace,
|
@@ -17,7 +19,8 @@ class Solargraph::LanguageServer::Message::TextDocument::DocumentSymbol < Solarg
|
|
17
19
|
deprecated: pin.deprecated?
|
18
20
|
}
|
19
21
|
result
|
20
|
-
end
|
22
|
+
end.compact
|
23
|
+
|
21
24
|
set_result info
|
22
25
|
end
|
23
26
|
end
|
@@ -17,17 +17,17 @@ module Solargraph
|
|
17
17
|
args = cli_args(file_uri, config)
|
18
18
|
|
19
19
|
require_rubocop(config['version'])
|
20
|
-
options, paths = RuboCop::Options.new.parse(args)
|
20
|
+
options, paths = ::RuboCop::Options.new.parse(args)
|
21
21
|
options[:stdin] = original
|
22
22
|
corrections = redirect_stdout do
|
23
|
-
RuboCop::Runner.new(options, RuboCop::ConfigStore.new).run(paths)
|
23
|
+
::RuboCop::Runner.new(options, ::RuboCop::ConfigStore.new).run(paths)
|
24
24
|
end
|
25
25
|
result = options[:stdin]
|
26
26
|
|
27
27
|
log_corrections(corrections)
|
28
28
|
|
29
29
|
format original, result
|
30
|
-
rescue RuboCop::ValidationError, RuboCop::ConfigNotFoundError => e
|
30
|
+
rescue ::RuboCop::ValidationError, ::RuboCop::ConfigNotFoundError => e
|
31
31
|
set_error(Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}")
|
32
32
|
end
|
33
33
|
|
@@ -54,7 +54,7 @@ module Solargraph
|
|
54
54
|
def cli_args file_uri, config
|
55
55
|
file = UriHelpers.uri_to_file(file_uri)
|
56
56
|
args = [
|
57
|
-
config['cops'] == 'all' ? '
|
57
|
+
config['cops'] == 'all' ? '-A' : '-a',
|
58
58
|
'--cache', 'false',
|
59
59
|
'--format', formatter_class(config).name,
|
60
60
|
]
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph::LanguageServer::Message::TextDocument
|
4
|
+
class TypeDefinition < Base
|
5
|
+
def process
|
6
|
+
@line = params['position']['line']
|
7
|
+
@column = params['position']['character']
|
8
|
+
set_result(code_location || [])
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def code_location
|
14
|
+
suggestions = host.type_definitions_at(params['textDocument']['uri'], @line, @column)
|
15
|
+
return nil if suggestions.empty?
|
16
|
+
suggestions.reject { |pin| pin.location.nil? || pin.location.filename.nil? }.map do |pin|
|
17
|
+
{
|
18
|
+
uri: file_to_uri(pin.location.filename),
|
19
|
+
range: pin.location.range.to_hash
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -15,6 +15,7 @@ module Solargraph
|
|
15
15
|
autoload :DiagnosticsQueue, 'solargraph/language_server/message/text_document/diagnostics_queue'
|
16
16
|
autoload :OnTypeFormatting, 'solargraph/language_server/message/text_document/on_type_formatting'
|
17
17
|
autoload :Definition, 'solargraph/language_server/message/text_document/definition'
|
18
|
+
autoload :TypeDefinition, 'solargraph/language_server/message/text_document/type_definition'
|
18
19
|
autoload :DocumentSymbol, 'solargraph/language_server/message/text_document/document_symbol'
|
19
20
|
autoload :Formatting, 'solargraph/language_server/message/text_document/formatting'
|
20
21
|
autoload :References, 'solargraph/language_server/message/text_document/references'
|
@@ -66,6 +66,7 @@ module Solargraph
|
|
66
66
|
register 'textDocument/didClose', TextDocument::DidClose
|
67
67
|
register 'textDocument/hover', TextDocument::Hover
|
68
68
|
register 'textDocument/definition', TextDocument::Definition
|
69
|
+
register 'textDocument/typeDefinition', TextDocument::TypeDefinition
|
69
70
|
register 'textDocument/formatting', TextDocument::Formatting
|
70
71
|
register 'textDocument/onTypeFormatting', TextDocument::OnTypeFormatting
|
71
72
|
register 'textDocument/documentSymbol', TextDocument::DocumentSymbol
|
data/lib/solargraph/library.rb
CHANGED
@@ -97,7 +97,7 @@ module Solargraph
|
|
97
97
|
def create filename, text
|
98
98
|
result = false
|
99
99
|
mutex.synchronize do
|
100
|
-
next unless contain?(filename) || open?(filename)
|
100
|
+
next unless contain?(filename) || open?(filename)
|
101
101
|
@synchronized = false
|
102
102
|
source = Solargraph::Source.load_string(text, filename)
|
103
103
|
workspace.merge(source)
|
@@ -199,6 +199,22 @@ module Solargraph
|
|
199
199
|
handle_file_not_found(filename, e)
|
200
200
|
end
|
201
201
|
|
202
|
+
# Get type definition suggestions for the expression at the specified file and
|
203
|
+
# location.
|
204
|
+
#
|
205
|
+
# @param filename [String] The file to analyze
|
206
|
+
# @param line [Integer] The zero-based line number
|
207
|
+
# @param column [Integer] The zero-based column number
|
208
|
+
# @return [Array<Solargraph::Pin::Base>]
|
209
|
+
# @todo Take filename/position instead of filename/line/column
|
210
|
+
def type_definitions_at filename, line, column
|
211
|
+
position = Position.new(line, column)
|
212
|
+
cursor = Source::Cursor.new(read(filename), position)
|
213
|
+
api_map.clip(cursor).types
|
214
|
+
rescue FileNotFoundError => e
|
215
|
+
handle_file_not_found filename, e
|
216
|
+
end
|
217
|
+
|
202
218
|
# Get signature suggestions for the method at the specified file and
|
203
219
|
# location.
|
204
220
|
#
|
@@ -258,6 +274,10 @@ module Solargraph
|
|
258
274
|
api_map.locate_pins(location).map { |pin| pin.realize(api_map) }
|
259
275
|
end
|
260
276
|
|
277
|
+
# Match a require reference to a file.
|
278
|
+
#
|
279
|
+
# @param location [Location]
|
280
|
+
# @return [Location, nil]
|
261
281
|
def locate_ref location
|
262
282
|
map = source_map_hash[location.filename]
|
263
283
|
return if map.nil?
|
@@ -268,7 +288,7 @@ module Solargraph
|
|
268
288
|
next unless source_map_hash.key?(full)
|
269
289
|
return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0))
|
270
290
|
end
|
271
|
-
|
291
|
+
nil
|
272
292
|
rescue FileNotFoundError
|
273
293
|
nil
|
274
294
|
end
|
@@ -108,9 +108,13 @@ module Solargraph
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def node_range node
|
111
|
+
if node.nil?
|
112
|
+
nil
|
113
|
+
else
|
111
114
|
st = Position.new(node.first_lineno - 1, node.first_column)
|
112
115
|
en = Position.new(node.last_lineno - 1, node.last_column)
|
113
116
|
Range.new(st, en)
|
117
|
+
end
|
114
118
|
end
|
115
119
|
|
116
120
|
def recipient_node tree
|
@@ -98,7 +98,7 @@ module Solargraph
|
|
98
98
|
result.concat generate_links(n.children.last)
|
99
99
|
elsif n.type == :OR
|
100
100
|
result.push Chain::Or.new([NodeChainer.chain(n.children[0], @filename), NodeChainer.chain(n.children[1], @filename)])
|
101
|
-
elsif n.type == :
|
101
|
+
elsif n.type == :BEGIN
|
102
102
|
result.concat generate_links(n.children[0])
|
103
103
|
elsif n.type == :BLOCK_PASS
|
104
104
|
result.push Chain::BlockVariable.new("&#{n.children[1].children[0].to_s}")
|
@@ -32,10 +32,12 @@ module Solargraph
|
|
32
32
|
def infer_literal_node_type node
|
33
33
|
return nil unless Parser.is_ast_node?(node)
|
34
34
|
case node.type
|
35
|
-
when :LIT, :STR
|
35
|
+
when :LIT, :STR, :SYM
|
36
36
|
"::#{node.children.first.class.to_s}"
|
37
37
|
when :DSTR
|
38
38
|
"::String"
|
39
|
+
when :INTEGER
|
40
|
+
'::Integer'
|
39
41
|
when :ARRAY, :ZARRAY, :LIST, :ZLIST
|
40
42
|
'::Array'
|
41
43
|
when :HASH
|
@@ -22,7 +22,7 @@ module Solargraph
|
|
22
22
|
locals.push Solargraph::Pin::LocalVariable.new(
|
23
23
|
location: loc,
|
24
24
|
closure: region.closure,
|
25
|
-
name: node.children[1].children.first.
|
25
|
+
name: node.children[1].children.first.to_s,
|
26
26
|
comments: "@type [#{types.join(',')}]",
|
27
27
|
presence: presence
|
28
28
|
)
|
@@ -34,9 +34,15 @@ module Solargraph
|
|
34
34
|
private
|
35
35
|
|
36
36
|
def exception_variable?
|
37
|
-
|
38
|
-
Parser.is_ast_node?(node.children[1]
|
39
|
-
|
37
|
+
if RUBY_VERSION =~ /^3\.4\./
|
38
|
+
Parser.is_ast_node?(node.children[1]) &&
|
39
|
+
# Parser.is_ast_node?(node.children[1].children.first) &&
|
40
|
+
node.children[1].type == :LASGN
|
41
|
+
else
|
42
|
+
Parser.is_ast_node?(node.children[1]) &&
|
43
|
+
Parser.is_ast_node?(node.children[1].children.first) &&
|
44
|
+
node.children[1].children.first.type == :LASGN
|
45
|
+
end
|
40
46
|
end
|
41
47
|
end
|
42
48
|
end
|
@@ -43,7 +43,7 @@ module Solargraph
|
|
43
43
|
if node.type == :FCALL && Parser.is_ast_node?(node.children.last)
|
44
44
|
node.children.last.children[0..-2].each do |child|
|
45
45
|
# next unless child.is_a?(AST::Node) && (child.type == :sym || child.type == :str)
|
46
|
-
if child.type == :LIT || child.type == :STR
|
46
|
+
if child.type == :LIT || child.type == :STR || child.type == :SYM
|
47
47
|
name = child.children[0].to_s
|
48
48
|
matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)}
|
49
49
|
matches.each do |pin|
|
@@ -175,7 +175,7 @@ module Solargraph
|
|
175
175
|
NodeProcessor.process node.children.last.children[0], region.update(visibility: :module_function), pins, locals
|
176
176
|
else
|
177
177
|
node.children.last.children[0..-2].each do |x|
|
178
|
-
next unless [:LIT, :STR].include?(x.type)
|
178
|
+
next unless [:LIT, :STR, :SYM].include?(x.type)
|
179
179
|
cn = x.children[0].to_s
|
180
180
|
ref = pins.select { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == cn }.first
|
181
181
|
unless ref.nil?
|
data/lib/solargraph/parser.rb
CHANGED
data/lib/solargraph/pin/block.rb
CHANGED
@@ -63,7 +63,7 @@ module Solargraph
|
|
63
63
|
if receiver_pin && receiver_pin.docstring
|
64
64
|
ys = receiver_pin.docstring.tag(:yieldself)
|
65
65
|
if ys && ys.types && !ys.types.empty?
|
66
|
-
return ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
|
66
|
+
return ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace).self_to(receiver_pin.full_context.namespace)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
nil
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
module Pin
|
5
|
+
# A DelegatedMethod is a more complicated version of a MethodAlias that
|
6
|
+
# allows aliasing a method from a different closure (class/module etc).
|
7
|
+
class DelegatedMethod < Pin::Method
|
8
|
+
# A DelegatedMethod can be constructed with either a :resolved_method
|
9
|
+
# pin, or a :receiver_chain. When a :receiver_chain is supplied, it
|
10
|
+
# will be used to *dynamically* resolve a receiver type within the
|
11
|
+
# given closure/scope, and the delegated method will then be resolved
|
12
|
+
# to a method pin on that type.
|
13
|
+
#
|
14
|
+
# @param resolved_method [Method] an already resolved method pin.
|
15
|
+
# @param receiver [Source::Chain] the source code used to resolve the receiver for this delegated method.
|
16
|
+
# @param receiver_method_name [String] the method name that will be called on the receiver (defaults to :name).
|
17
|
+
def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat)
|
18
|
+
raise ArgumentError, 'either :method or :receiver is required' if (method && receiver) || (!method && !receiver)
|
19
|
+
super(name: name, **splat)
|
20
|
+
|
21
|
+
@receiver_chain = receiver
|
22
|
+
@resolved_method = method
|
23
|
+
@receiver_method_name = receiver_method_name
|
24
|
+
end
|
25
|
+
|
26
|
+
%i[comments parameters return_type location].each do |method|
|
27
|
+
define_method(method) do
|
28
|
+
@resolved_method ? @resolved_method.send(method) : super()
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
%i[typify realize infer probe].each do |method|
|
33
|
+
# @param api_map [ApiMap]
|
34
|
+
define_method(method) do |api_map|
|
35
|
+
resolve_method(api_map)
|
36
|
+
@resolved_method ? @resolved_method.send(method, api_map) : super(api_map)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def resolvable?(api_map)
|
41
|
+
resolve_method(api_map)
|
42
|
+
!!@resolved_method
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
# Resolves the receiver chain and method name to a method pin, resetting any previously resolution.
|
48
|
+
#
|
49
|
+
# @param api_map [ApiMap]
|
50
|
+
# @return [Pin::Method, nil]
|
51
|
+
def resolve_method api_map
|
52
|
+
return if @resolved_method
|
53
|
+
|
54
|
+
resolver = @receiver_chain.define(api_map, self, []).first
|
55
|
+
|
56
|
+
unless resolver
|
57
|
+
Solargraph.logger.warn \
|
58
|
+
"Delegated receiver for #{path} was resolved to nil from `#{print_chain(@receiver_chain)}'"
|
59
|
+
return
|
60
|
+
end
|
61
|
+
|
62
|
+
receiver_type = resolver.return_type
|
63
|
+
|
64
|
+
return if receiver_type.undefined?
|
65
|
+
|
66
|
+
receiver_path, method_scope =
|
67
|
+
if @receiver_chain.constant?
|
68
|
+
# HACK: the `return_type` of a constant is Class<Whatever>, but looking up a method expects
|
69
|
+
# the arguments `"Whatever"` and `scope: :class`.
|
70
|
+
[receiver_type.to_s.sub(/^Class<(.+)>$/, '\1'), :class]
|
71
|
+
else
|
72
|
+
[receiver_type.to_s, :instance]
|
73
|
+
end
|
74
|
+
|
75
|
+
method_stack = api_map.get_method_stack(receiver_path, @receiver_method_name, scope: method_scope)
|
76
|
+
@resolved_method = method_stack.first
|
77
|
+
end
|
78
|
+
|
79
|
+
# helper to print a source chain as code, probably not 100% correct.
|
80
|
+
#
|
81
|
+
# @param chain [Source::Chain]
|
82
|
+
def print_chain(chain)
|
83
|
+
out = +''
|
84
|
+
chain.links.each_with_index do |link, index|
|
85
|
+
if index > 0
|
86
|
+
if Source::Chain::Constant
|
87
|
+
out << '::' unless link.word.start_with?('::')
|
88
|
+
else
|
89
|
+
out << '.'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
out << link.word
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -130,6 +130,11 @@ module Solargraph
|
|
130
130
|
end
|
131
131
|
@documentation += "\n\n" unless @documentation.empty?
|
132
132
|
@documentation += "Visibility: #{visibility}"
|
133
|
+
example_tags = docstring.tags(:example)
|
134
|
+
unless example_tags.empty?
|
135
|
+
@documentation += "\n\nExamples:\n\n"
|
136
|
+
@documentation += example_tags.map(&:text).join("\n")
|
137
|
+
end
|
133
138
|
end
|
134
139
|
@documentation.to_s
|
135
140
|
end
|
@@ -49,7 +49,7 @@ module Solargraph
|
|
49
49
|
# @return [Float]
|
50
50
|
def fuzzy_string_match str1, str2
|
51
51
|
return (1.0 + (str2.length.to_f / str1.length.to_f)) if str1.downcase.include?(str2.downcase)
|
52
|
-
JaroWinkler.
|
52
|
+
JaroWinkler.similarity(str1, str2, ignore_case: true)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
data/lib/solargraph/pin.rb
CHANGED
@@ -12,6 +12,7 @@ module Solargraph
|
|
12
12
|
autoload :Method, 'solargraph/pin/method'
|
13
13
|
autoload :Signature, 'solargraph/pin/signature'
|
14
14
|
autoload :MethodAlias, 'solargraph/pin/method_alias'
|
15
|
+
autoload :DelegatedMethod, 'solargraph/pin/delegated_method'
|
15
16
|
autoload :BaseVariable, 'solargraph/pin/base_variable'
|
16
17
|
autoload :InstanceVariable, 'solargraph/pin/instance_variable'
|
17
18
|
autoload :ClassVariable, 'solargraph/pin/class_variable'
|