solargraph 0.49.0 → 0.51.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/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'
|