solargraph 0.59.0 → 0.59.2
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/linting.yml +6 -0
- data/.github/workflows/plugins.yml +9 -1
- data/.github/workflows/typecheck.yml +3 -1
- data/CHANGELOG.md +12 -0
- data/lib/solargraph/api_map/store.rb +1 -2
- data/lib/solargraph/api_map.rb +4 -6
- data/lib/solargraph/complex_type/type_methods.rb +1 -0
- data/lib/solargraph/complex_type/unique_type.rb +14 -15
- data/lib/solargraph/complex_type.rb +2 -1
- data/lib/solargraph/convention/active_support_concern.rb +111 -111
- data/lib/solargraph/convention/base.rb +50 -50
- data/lib/solargraph/diagnostics.rb +55 -55
- data/lib/solargraph/environ.rb +52 -52
- data/lib/solargraph/gem_pins.rb +0 -11
- data/lib/solargraph/language_server/host.rb +6 -7
- data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
- data/lib/solargraph/language_server/message/initialized.rb +28 -28
- data/lib/solargraph/language_server/message/text_document.rb +28 -28
- data/lib/solargraph/language_server/progress.rb +143 -143
- data/lib/solargraph/language_server/transport/adapter.rb +68 -68
- data/lib/solargraph/language_server.rb +20 -20
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -4
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +40 -40
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
- data/lib/solargraph/pin/base.rb +3 -3
- data/lib/solargraph/pin/method.rb +2 -0
- data/lib/solargraph/pin/parameter.rb +3 -1
- data/lib/solargraph/pin/reference/require.rb +14 -14
- data/lib/solargraph/pin/search.rb +5 -5
- data/lib/solargraph/pin/singleton.rb +11 -11
- data/lib/solargraph/rbs_map/conversions.rb +15 -8
- data/lib/solargraph/shell.rb +1 -1
- data/lib/solargraph/source/chain/array.rb +1 -12
- data/lib/solargraph/source/chain/block_symbol.rb +13 -13
- data/lib/solargraph/source/chain/block_variable.rb +13 -13
- data/lib/solargraph/source/chain/head.rb +19 -19
- data/lib/solargraph/source/chain/literal.rb +18 -14
- data/lib/solargraph/source/cursor.rb +11 -2
- data/lib/solargraph/source/source_chainer.rb +4 -4
- data/lib/solargraph/source_map/clip.rb +6 -1
- data/lib/solargraph/type_checker.rb +4 -4
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map/cache.rb +25 -25
- data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
- data/lib/solargraph/yard_map/mapper/to_method.rb +1 -1
- data/lib/solargraph.rb +2 -2
- metadata +1 -2
- data/rbs/fills/tuple/tuple.rbs +0 -177
|
@@ -1,143 +1,143 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'securerandom'
|
|
4
|
-
|
|
5
|
-
module Solargraph
|
|
6
|
-
module LanguageServer
|
|
7
|
-
# Progress notification handling for language server hosts.
|
|
8
|
-
#
|
|
9
|
-
class Progress
|
|
10
|
-
WAITING = :waiting
|
|
11
|
-
CREATED = :created
|
|
12
|
-
FINISHED = :finished
|
|
13
|
-
|
|
14
|
-
# @return [String]
|
|
15
|
-
attr_reader :uuid
|
|
16
|
-
|
|
17
|
-
# @return [String]
|
|
18
|
-
attr_reader :title
|
|
19
|
-
|
|
20
|
-
# @return [String, nil]
|
|
21
|
-
attr_reader :kind
|
|
22
|
-
|
|
23
|
-
# @return [String, nil]
|
|
24
|
-
attr_reader :message
|
|
25
|
-
|
|
26
|
-
# @return [Integer]
|
|
27
|
-
attr_reader :percentage
|
|
28
|
-
|
|
29
|
-
# @return [Symbol]
|
|
30
|
-
attr_reader :status
|
|
31
|
-
|
|
32
|
-
# @param title [String]
|
|
33
|
-
def initialize title
|
|
34
|
-
@title = title
|
|
35
|
-
@uuid = SecureRandom.uuid
|
|
36
|
-
@percentage = 0
|
|
37
|
-
@status = WAITING
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# @param message [String]
|
|
41
|
-
# @param percentage [Integer]
|
|
42
|
-
# @return [void]
|
|
43
|
-
def begin message, percentage
|
|
44
|
-
@kind = 'begin'
|
|
45
|
-
@message = message
|
|
46
|
-
@percentage = percentage
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# @param message [String]
|
|
50
|
-
# @param percentage [Integer]
|
|
51
|
-
# @return [void]
|
|
52
|
-
def report message, percentage
|
|
53
|
-
@kind = 'report'
|
|
54
|
-
@message = message
|
|
55
|
-
@percentage = percentage
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# @param message [String]
|
|
59
|
-
# @return [void]
|
|
60
|
-
def finish message
|
|
61
|
-
@kind = 'end'
|
|
62
|
-
@message = message
|
|
63
|
-
@percentage = 100
|
|
64
|
-
true
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# @param host [Solargraph::LanguageServer::Host]
|
|
68
|
-
# @return [void]
|
|
69
|
-
def send host
|
|
70
|
-
return unless host.client_supports_progress? && !finished?
|
|
71
|
-
|
|
72
|
-
message = build
|
|
73
|
-
create(host)
|
|
74
|
-
host.send_notification '$/progress', message
|
|
75
|
-
@status = FINISHED if kind == 'end'
|
|
76
|
-
keep_alive host
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def created?
|
|
80
|
-
[CREATED, FINISHED].include?(status)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def finished?
|
|
84
|
-
status == FINISHED
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
private
|
|
88
|
-
|
|
89
|
-
# @param host [Solargraph::LanguageServer::Host]
|
|
90
|
-
# @return [void]
|
|
91
|
-
def create host
|
|
92
|
-
return if created?
|
|
93
|
-
|
|
94
|
-
host.send_request 'window/workDoneProgress/create', { token: uuid }
|
|
95
|
-
@status = CREATED
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# @return [Hash]
|
|
99
|
-
def build
|
|
100
|
-
{
|
|
101
|
-
token: uuid,
|
|
102
|
-
value: {
|
|
103
|
-
kind: kind,
|
|
104
|
-
cancellable: false
|
|
105
|
-
}.merge(build_value)
|
|
106
|
-
}
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# @return [Hash]
|
|
110
|
-
def build_value
|
|
111
|
-
case kind
|
|
112
|
-
when 'begin'
|
|
113
|
-
{ title: title, message: message, percentage: percentage }
|
|
114
|
-
when 'report'
|
|
115
|
-
{ message: message, percentage: percentage }
|
|
116
|
-
when 'end'
|
|
117
|
-
{ message: message }
|
|
118
|
-
else
|
|
119
|
-
raise "Invalid progress kind #{kind}"
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# @param host [Host]
|
|
124
|
-
# @return [void]
|
|
125
|
-
def keep_alive host
|
|
126
|
-
mutex.synchronize { @last = Time.now }
|
|
127
|
-
@keep_alive ||= Thread.new do
|
|
128
|
-
until finished?
|
|
129
|
-
sleep 10
|
|
130
|
-
break if finished?
|
|
131
|
-
next if mutex.synchronize { Time.now - @last < 10 }
|
|
132
|
-
send host
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
# @return [Thread::Mutex]
|
|
138
|
-
def mutex
|
|
139
|
-
@mutex ||= Mutex.new
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'securerandom'
|
|
4
|
+
|
|
5
|
+
module Solargraph
|
|
6
|
+
module LanguageServer
|
|
7
|
+
# Progress notification handling for language server hosts.
|
|
8
|
+
#
|
|
9
|
+
class Progress
|
|
10
|
+
WAITING = :waiting
|
|
11
|
+
CREATED = :created
|
|
12
|
+
FINISHED = :finished
|
|
13
|
+
|
|
14
|
+
# @return [String]
|
|
15
|
+
attr_reader :uuid
|
|
16
|
+
|
|
17
|
+
# @return [String]
|
|
18
|
+
attr_reader :title
|
|
19
|
+
|
|
20
|
+
# @return [String, nil]
|
|
21
|
+
attr_reader :kind
|
|
22
|
+
|
|
23
|
+
# @return [String, nil]
|
|
24
|
+
attr_reader :message
|
|
25
|
+
|
|
26
|
+
# @return [Integer]
|
|
27
|
+
attr_reader :percentage
|
|
28
|
+
|
|
29
|
+
# @return [Symbol]
|
|
30
|
+
attr_reader :status
|
|
31
|
+
|
|
32
|
+
# @param title [String]
|
|
33
|
+
def initialize title
|
|
34
|
+
@title = title
|
|
35
|
+
@uuid = SecureRandom.uuid
|
|
36
|
+
@percentage = 0
|
|
37
|
+
@status = WAITING
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @param message [String]
|
|
41
|
+
# @param percentage [Integer]
|
|
42
|
+
# @return [void]
|
|
43
|
+
def begin message, percentage
|
|
44
|
+
@kind = 'begin'
|
|
45
|
+
@message = message
|
|
46
|
+
@percentage = percentage
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @param message [String]
|
|
50
|
+
# @param percentage [Integer]
|
|
51
|
+
# @return [void]
|
|
52
|
+
def report message, percentage
|
|
53
|
+
@kind = 'report'
|
|
54
|
+
@message = message
|
|
55
|
+
@percentage = percentage
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @param message [String]
|
|
59
|
+
# @return [void]
|
|
60
|
+
def finish message
|
|
61
|
+
@kind = 'end'
|
|
62
|
+
@message = message
|
|
63
|
+
@percentage = 100
|
|
64
|
+
true
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @param host [Solargraph::LanguageServer::Host]
|
|
68
|
+
# @return [void]
|
|
69
|
+
def send host
|
|
70
|
+
return unless host.client_supports_progress? && !finished?
|
|
71
|
+
|
|
72
|
+
message = build
|
|
73
|
+
create(host)
|
|
74
|
+
host.send_notification '$/progress', message
|
|
75
|
+
@status = FINISHED if kind == 'end'
|
|
76
|
+
keep_alive host
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def created?
|
|
80
|
+
[CREATED, FINISHED].include?(status)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def finished?
|
|
84
|
+
status == FINISHED
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
# @param host [Solargraph::LanguageServer::Host]
|
|
90
|
+
# @return [void]
|
|
91
|
+
def create host
|
|
92
|
+
return if created?
|
|
93
|
+
|
|
94
|
+
host.send_request 'window/workDoneProgress/create', { token: uuid }
|
|
95
|
+
@status = CREATED
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# @return [Hash]
|
|
99
|
+
def build
|
|
100
|
+
{
|
|
101
|
+
token: uuid,
|
|
102
|
+
value: {
|
|
103
|
+
kind: kind,
|
|
104
|
+
cancellable: false
|
|
105
|
+
}.merge(build_value)
|
|
106
|
+
}
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @return [Hash]
|
|
110
|
+
def build_value
|
|
111
|
+
case kind
|
|
112
|
+
when 'begin'
|
|
113
|
+
{ title: title, message: message, percentage: percentage }
|
|
114
|
+
when 'report'
|
|
115
|
+
{ message: message, percentage: percentage }
|
|
116
|
+
when 'end'
|
|
117
|
+
{ message: message }
|
|
118
|
+
else
|
|
119
|
+
raise "Invalid progress kind #{kind}"
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# @param host [Host]
|
|
124
|
+
# @return [void]
|
|
125
|
+
def keep_alive host
|
|
126
|
+
mutex.synchronize { @last = Time.now }
|
|
127
|
+
@keep_alive ||= Thread.new do
|
|
128
|
+
until finished?
|
|
129
|
+
sleep 10
|
|
130
|
+
break if finished?
|
|
131
|
+
next if mutex.synchronize { Time.now - @last < 10 }
|
|
132
|
+
send host
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# @return [Thread::Mutex]
|
|
138
|
+
def mutex
|
|
139
|
+
@mutex ||= Mutex.new
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'backport'
|
|
4
|
-
|
|
5
|
-
module Solargraph
|
|
6
|
-
module LanguageServer
|
|
7
|
-
module Transport
|
|
8
|
-
# A common module for running language servers in Backport.
|
|
9
|
-
#
|
|
10
|
-
module Adapter
|
|
11
|
-
# This runs in the context of Backport::Adapter, which
|
|
12
|
-
# provides write() - but if we didn't hide this behind a parse
|
|
13
|
-
# tag, it would override the one in the class.
|
|
14
|
-
#
|
|
15
|
-
# @!method write(text)
|
|
16
|
-
# @abstract
|
|
17
|
-
# Write the change to the specified text.
|
|
18
|
-
# @param text [String] The text to be changed.
|
|
19
|
-
# @return [String] The updated text.
|
|
20
|
-
|
|
21
|
-
# @return [void]
|
|
22
|
-
def opening
|
|
23
|
-
@host = Solargraph::LanguageServer::Host.new
|
|
24
|
-
@host.add_observer self
|
|
25
|
-
@host.start
|
|
26
|
-
@data_reader = Solargraph::LanguageServer::Transport::DataReader.new
|
|
27
|
-
@data_reader.set_message_handler do |message|
|
|
28
|
-
process message
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# @return [void]
|
|
33
|
-
def closing
|
|
34
|
-
@host.stop
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# @param data [String]
|
|
38
|
-
# @return [void]
|
|
39
|
-
def receiving data
|
|
40
|
-
@data_reader.receive data
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# @return [void]
|
|
44
|
-
def update
|
|
45
|
-
if @host.stopped?
|
|
46
|
-
shutdown
|
|
47
|
-
else
|
|
48
|
-
tmp = @host.flush
|
|
49
|
-
write tmp unless tmp.empty?
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
private
|
|
54
|
-
|
|
55
|
-
# @param request [Hash]
|
|
56
|
-
# @return [void]
|
|
57
|
-
def process request
|
|
58
|
-
@host.process(request)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# @return [void]
|
|
62
|
-
def shutdown
|
|
63
|
-
Backport.stop unless @host.options['transport'] == 'external'
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'backport'
|
|
4
|
+
|
|
5
|
+
module Solargraph
|
|
6
|
+
module LanguageServer
|
|
7
|
+
module Transport
|
|
8
|
+
# A common module for running language servers in Backport.
|
|
9
|
+
#
|
|
10
|
+
module Adapter
|
|
11
|
+
# This runs in the context of Backport::Adapter, which
|
|
12
|
+
# provides write() - but if we didn't hide this behind a parse
|
|
13
|
+
# tag, it would override the one in the class.
|
|
14
|
+
#
|
|
15
|
+
# @!method write(text)
|
|
16
|
+
# @abstract
|
|
17
|
+
# Write the change to the specified text.
|
|
18
|
+
# @param text [String] The text to be changed.
|
|
19
|
+
# @return [String] The updated text.
|
|
20
|
+
|
|
21
|
+
# @return [void]
|
|
22
|
+
def opening
|
|
23
|
+
@host = Solargraph::LanguageServer::Host.new
|
|
24
|
+
@host.add_observer self
|
|
25
|
+
@host.start
|
|
26
|
+
@data_reader = Solargraph::LanguageServer::Transport::DataReader.new
|
|
27
|
+
@data_reader.set_message_handler do |message|
|
|
28
|
+
process message
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @return [void]
|
|
33
|
+
def closing
|
|
34
|
+
@host.stop
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @param data [String]
|
|
38
|
+
# @return [void]
|
|
39
|
+
def receiving data
|
|
40
|
+
@data_reader.receive data
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @return [void]
|
|
44
|
+
def update
|
|
45
|
+
if @host.stopped?
|
|
46
|
+
shutdown
|
|
47
|
+
else
|
|
48
|
+
tmp = @host.flush
|
|
49
|
+
write tmp unless tmp.empty?
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
# @param request [Hash]
|
|
56
|
+
# @return [void]
|
|
57
|
+
def process request
|
|
58
|
+
@host.process(request)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @return [void]
|
|
62
|
+
def shutdown
|
|
63
|
+
Backport.stop unless @host.options['transport'] == 'external'
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'solargraph/language_server/error_codes'
|
|
4
|
-
require 'solargraph/language_server/completion_item_kinds'
|
|
5
|
-
require 'solargraph/language_server/symbol_kinds'
|
|
6
|
-
|
|
7
|
-
module Solargraph
|
|
8
|
-
# The LanguageServer namespace contains the classes and modules that compose
|
|
9
|
-
# concrete implementations of language servers.
|
|
10
|
-
#
|
|
11
|
-
module LanguageServer
|
|
12
|
-
autoload :Host, 'solargraph/language_server/host'
|
|
13
|
-
autoload :Message, 'solargraph/language_server/message'
|
|
14
|
-
autoload :UriHelpers, 'solargraph/language_server/uri_helpers'
|
|
15
|
-
autoload :MessageTypes, 'solargraph/language_server/message_types'
|
|
16
|
-
autoload :Request, 'solargraph/language_server/request'
|
|
17
|
-
autoload :Transport, 'solargraph/language_server/transport'
|
|
18
|
-
autoload :Progress, 'solargraph/language_server/progress'
|
|
19
|
-
end
|
|
20
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'solargraph/language_server/error_codes'
|
|
4
|
+
require 'solargraph/language_server/completion_item_kinds'
|
|
5
|
+
require 'solargraph/language_server/symbol_kinds'
|
|
6
|
+
|
|
7
|
+
module Solargraph
|
|
8
|
+
# The LanguageServer namespace contains the classes and modules that compose
|
|
9
|
+
# concrete implementations of language servers.
|
|
10
|
+
#
|
|
11
|
+
module LanguageServer
|
|
12
|
+
autoload :Host, 'solargraph/language_server/host'
|
|
13
|
+
autoload :Message, 'solargraph/language_server/message'
|
|
14
|
+
autoload :UriHelpers, 'solargraph/language_server/uri_helpers'
|
|
15
|
+
autoload :MessageTypes, 'solargraph/language_server/message_types'
|
|
16
|
+
autoload :Request, 'solargraph/language_server/request'
|
|
17
|
+
autoload :Transport, 'solargraph/language_server/transport'
|
|
18
|
+
autoload :Progress, 'solargraph/language_server/progress'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -4,6 +4,7 @@ require 'parser'
|
|
|
4
4
|
require 'ast'
|
|
5
5
|
|
|
6
6
|
# https://github.com/whitequark/parser
|
|
7
|
+
# rubocop:disable Metrics/ModuleLength
|
|
7
8
|
module Solargraph
|
|
8
9
|
module Parser
|
|
9
10
|
module ParserGem
|
|
@@ -246,15 +247,100 @@ module Solargraph
|
|
|
246
247
|
end
|
|
247
248
|
prev = node
|
|
248
249
|
end
|
|
249
|
-
|
|
250
|
+
find_recipient_node_by_text(source, offset)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
# Text-based fallback for finding a method call recipient when the AST
|
|
254
|
+
# is unavailable (e.g., unparseable source with syntax errors).
|
|
255
|
+
#
|
|
256
|
+
# Scans backward from cursor offset to find '(' and the method name
|
|
257
|
+
# before it, then creates a minimal :send node.
|
|
258
|
+
#
|
|
259
|
+
# @param source [Solargraph::Source]
|
|
260
|
+
# @param offset [Integer]
|
|
261
|
+
# @return [Parser::AST::Node, nil]
|
|
262
|
+
def find_recipient_node_by_text source, offset
|
|
263
|
+
code = source.code
|
|
264
|
+
return nil if offset.nil? || offset <= 0 || offset > code.length
|
|
265
|
+
|
|
266
|
+
# The '(' could be at offset-1 (cursor after '(') or at offset (cursor on '(')
|
|
267
|
+
start_pos = offset - 1
|
|
268
|
+
if start_pos.positive? && code[start_pos] != '(' && code[offset] == '('
|
|
269
|
+
start_pos = offset
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# Scan backward to find the matching '(' (handle nested parens)
|
|
273
|
+
depth = 0
|
|
274
|
+
paren_pos = nil
|
|
275
|
+
pos = start_pos
|
|
276
|
+
while pos >= 0
|
|
277
|
+
case code[pos]
|
|
278
|
+
when ')'
|
|
279
|
+
depth += 1
|
|
280
|
+
when '('
|
|
281
|
+
if depth.zero?
|
|
282
|
+
paren_pos = pos
|
|
283
|
+
break
|
|
284
|
+
end
|
|
285
|
+
depth -= 1
|
|
286
|
+
end
|
|
287
|
+
pos -= 1
|
|
288
|
+
end
|
|
289
|
+
return nil if paren_pos.nil?
|
|
290
|
+
|
|
291
|
+
# Skip whitespace before '(' to find method name
|
|
292
|
+
idx = paren_pos - 1
|
|
293
|
+
idx -= 1 while idx >= 0 && code[idx] =~ /\s/
|
|
294
|
+
return nil if idx.negative?
|
|
295
|
+
|
|
296
|
+
# Read method name (including ? and !)
|
|
297
|
+
name_end = idx + 1
|
|
298
|
+
idx -= 1 while idx >= 0 && code[idx] =~ /[a-zA-Z0-9_?!]/
|
|
299
|
+
name_start = idx + 1
|
|
300
|
+
return nil if name_start >= name_end
|
|
301
|
+
method_name = code[name_start...name_end]
|
|
302
|
+
return nil if method_name.empty?
|
|
303
|
+
|
|
304
|
+
# Check for receiver pattern: receiver.method( or receiver::method(
|
|
305
|
+
idx = name_start - 1
|
|
306
|
+
idx -= 1 while idx >= 0 && code[idx] =~ /\s/
|
|
307
|
+
if idx >= 0 && code[idx] == '.'
|
|
308
|
+
idx -= 1
|
|
309
|
+
idx -= 1 while idx >= 0 && code[idx] =~ /\s/
|
|
310
|
+
recv_end = idx + 1
|
|
311
|
+
idx -= 1 while idx >= 0 && code[idx] =~ /[a-zA-Z0-9_@$]/
|
|
312
|
+
recv_start = idx + 1
|
|
313
|
+
if recv_start < recv_end
|
|
314
|
+
recv_name = code[recv_start...recv_end]
|
|
315
|
+
unless recv_name.empty?
|
|
316
|
+
receiver_node = ::Parser::AST::Node.new(:send, [nil, recv_name.to_sym])
|
|
317
|
+
return ::Parser::AST::Node.new(:send, [receiver_node, method_name.to_sym])
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
elsif idx >= 0 && idx.positive? && code[idx - 1] == ':' && code[idx] == ':'
|
|
321
|
+
const_end = idx - 1
|
|
322
|
+
const_start = const_end
|
|
323
|
+
const_start -= 1 while const_start.positive? && code[const_start - 1] =~ /[a-zA-Z0-9_]/
|
|
324
|
+
const_name = code[const_start...const_end]
|
|
325
|
+
unless const_name.empty? || method_name.empty?
|
|
326
|
+
const_node = ::Parser::AST::Node.new(:const, [nil, const_name.to_sym])
|
|
327
|
+
return ::Parser::AST::Node.new(:send, [const_node, method_name.to_sym])
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# Simple method call without receiver
|
|
332
|
+
::Parser::AST::Node.new(:send, [nil, method_name.to_sym])
|
|
250
333
|
end
|
|
251
334
|
|
|
252
335
|
# @param cursor [Solargraph::Source::Cursor]
|
|
253
336
|
# @return [Parser::AST::Node, nil]
|
|
254
337
|
def repaired_find_recipient_node cursor
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
338
|
+
c = cursor.source.cursor_at([cursor.position.line, cursor.position.column - 1])
|
|
339
|
+
tree = c.source.tree_at(c.position.line, c.position.column)
|
|
340
|
+
tree.each do |node|
|
|
341
|
+
return node if node.type == :send
|
|
342
|
+
end
|
|
343
|
+
find_recipient_node_by_text(cursor.source, cursor.offset)
|
|
258
344
|
end
|
|
259
345
|
|
|
260
346
|
#
|
|
@@ -505,3 +591,4 @@ module Solargraph
|
|
|
505
591
|
end
|
|
506
592
|
end
|
|
507
593
|
end
|
|
594
|
+
# rubocop:enable Metrics/ModuleLength
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
module Parser
|
|
5
|
-
module ParserGem
|
|
6
|
-
module NodeProcessors
|
|
7
|
-
class AliasNode < Parser::NodeProcessor::Base
|
|
8
|
-
def process
|
|
9
|
-
loc = get_node_location(node)
|
|
10
|
-
pins.push Solargraph::Pin::MethodAlias.new(
|
|
11
|
-
location: loc,
|
|
12
|
-
closure: region.closure,
|
|
13
|
-
name: node.children[0].children[0].to_s,
|
|
14
|
-
original: node.children[1].children[0].to_s,
|
|
15
|
-
scope: region.scope || :instance,
|
|
16
|
-
source: :parser
|
|
17
|
-
)
|
|
18
|
-
process_children
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Parser
|
|
5
|
+
module ParserGem
|
|
6
|
+
module NodeProcessors
|
|
7
|
+
class AliasNode < Parser::NodeProcessor::Base
|
|
8
|
+
def process
|
|
9
|
+
loc = get_node_location(node)
|
|
10
|
+
pins.push Solargraph::Pin::MethodAlias.new(
|
|
11
|
+
location: loc,
|
|
12
|
+
closure: region.closure,
|
|
13
|
+
name: node.children[0].children[0].to_s,
|
|
14
|
+
original: node.children[1].children[0].to_s,
|
|
15
|
+
scope: region.scope || :instance,
|
|
16
|
+
source: :parser
|
|
17
|
+
)
|
|
18
|
+
process_children
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|