solargraph 0.59.1 → 0.60.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/linting.yml +6 -0
- data/.github/workflows/plugins.yml +8 -0
- data/.github/workflows/rspec.yml +4 -1
- data/.github/workflows/typecheck.yml +2 -0
- data/.rubocop.yml +1 -0
- data/.rubocop_todo.yml +1 -1
- data/CHANGELOG.md +18 -0
- data/Gemfile +3 -0
- data/lib/solargraph/api_map/index.rb +13 -2
- data/lib/solargraph/api_map/store.rb +22 -8
- data/lib/solargraph/api_map.rb +38 -8
- data/lib/solargraph/complex_type/type_methods.rb +1 -0
- data/lib/solargraph/complex_type/unique_type.rb +16 -13
- data/lib/solargraph/complex_type.rb +5 -0
- 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/doc_map.rb +1 -0
- data/lib/solargraph/environ.rb +52 -52
- data/lib/solargraph/gem_pins.rb +0 -11
- 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 +42 -0
- 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 +29 -5
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
- data/lib/solargraph/pin/base.rb +31 -3
- data/lib/solargraph/pin/callable.rb +2 -2
- data/lib/solargraph/pin/common.rb +12 -0
- data/lib/solargraph/pin/method.rb +56 -16
- data/lib/solargraph/pin/reference/require.rb +14 -14
- data/lib/solargraph/pin/singleton.rb +11 -11
- data/lib/solargraph/rbs_map/conversions.rb +103 -145
- data/lib/solargraph/rbs_translator.rb +206 -0
- data/lib/solargraph/shell.rb +131 -64
- 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/call.rb +8 -76
- data/lib/solargraph/source/chain/head.rb +19 -19
- data/lib/solargraph/source/chain/literal.rb +18 -14
- data/lib/solargraph/source/source_chainer.rb +4 -4
- data/lib/solargraph/source_map/mapper.rb +5 -135
- data/lib/solargraph/source_map.rb +14 -0
- data/lib/solargraph/version.rb +19 -1
- data/lib/solargraph/yard_map/cache.rb +25 -25
- data/lib/solargraph/yard_map/directives/attribute_directive.rb +65 -0
- data/lib/solargraph/yard_map/directives/domain_directive.rb +30 -0
- data/lib/solargraph/yard_map/directives/method_directive.rb +51 -0
- data/lib/solargraph/yard_map/directives/override_directive.rb +30 -0
- data/lib/solargraph/yard_map/directives/parse_directive.rb +53 -0
- data/lib/solargraph/yard_map/directives/visibility_directive.rb +70 -0
- data/lib/solargraph/yard_map/directives.rb +35 -0
- data/lib/solargraph/yard_map/macro.rb +113 -0
- data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
- data/lib/solargraph/yard_map/mapper.rb +19 -1
- data/lib/solargraph/yard_map.rb +2 -0
- data/lib/solargraph.rb +1 -0
- data/solargraph.gemspec +1 -0
- metadata +24 -2
- data/rbs/fills/tuple/tuple.rbs +0 -177
|
@@ -61,13 +61,6 @@ module Solargraph
|
|
|
61
61
|
@pins ||= []
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
# @param position [Solargraph::Position]
|
|
65
|
-
# @return [Solargraph::Pin::Closure]
|
|
66
|
-
def closure_at position
|
|
67
|
-
# @sg-ignore Need to add nil check here
|
|
68
|
-
pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location.range.contain?(position) }.last
|
|
69
|
-
end
|
|
70
|
-
|
|
71
64
|
# @param source_position [Position]
|
|
72
65
|
# @param comment_position [Position]
|
|
73
66
|
# @param comment [String]
|
|
@@ -108,135 +101,12 @@ module Solargraph
|
|
|
108
101
|
# @param directive [YARD::Tags::Directive]
|
|
109
102
|
# @return [void]
|
|
110
103
|
def process_directive source_position, comment_position, directive
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
location = Location.new(@filename, Range.new(comment_position, comment_position))
|
|
114
|
-
case directive.tag.tag_name
|
|
115
|
-
when 'method'
|
|
116
|
-
namespace = closure_at(source_position) || @pins.first
|
|
117
|
-
# @sg-ignore Need to add nil check here
|
|
118
|
-
namespace = closure_at(comment_position) if namespace.location.range.start.line < comment_position.line
|
|
119
|
-
begin
|
|
120
|
-
src = Solargraph::Source.load_string("def #{directive.tag.name};end", @source.filename)
|
|
121
|
-
region = Parser::Region.new(source: src, closure: namespace)
|
|
122
|
-
# @type [Array<Pin::Method>]
|
|
123
|
-
method_gen_pins = Parser.process_node(src.node, region).first.select { |pin| pin.is_a?(Pin::Method) }
|
|
124
|
-
gen_pin = method_gen_pins.last
|
|
125
|
-
return if gen_pin.nil?
|
|
126
|
-
# Move the location to the end of the line so it gets recognized
|
|
127
|
-
# as originating from a comment
|
|
128
|
-
shifted = Solargraph::Position.new(comment_position.line,
|
|
129
|
-
@code.lines[comment_position.line].to_s.chomp.length)
|
|
130
|
-
# @todo: Smelly instance variable access
|
|
131
|
-
gen_pin.instance_variable_set(:@comments, docstring.all.to_s)
|
|
132
|
-
gen_pin.instance_variable_set(:@location, Solargraph::Location.new(@filename, Range.new(shifted, shifted)))
|
|
133
|
-
gen_pin.instance_variable_set(:@explicit, false)
|
|
134
|
-
@pins.push gen_pin
|
|
135
|
-
rescue Parser::SyntaxError
|
|
136
|
-
# @todo Handle error in directive
|
|
137
|
-
end
|
|
138
|
-
when 'attribute'
|
|
139
|
-
return if directive.tag.name.nil?
|
|
140
|
-
namespace = closure_at(source_position)
|
|
141
|
-
t = directive.tag.types.nil? || directive.tag.types.empty? ? nil : directive.tag.types.join
|
|
142
|
-
if t.nil? || t.include?('r')
|
|
143
|
-
pins.push Solargraph::Pin::Method.new(
|
|
144
|
-
location: location,
|
|
145
|
-
closure: namespace,
|
|
146
|
-
name: directive.tag.name,
|
|
147
|
-
comments: docstring.all.to_s,
|
|
148
|
-
scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
|
|
149
|
-
visibility: :public,
|
|
150
|
-
explicit: false,
|
|
151
|
-
attribute: true,
|
|
152
|
-
source: :source_map
|
|
153
|
-
)
|
|
154
|
-
end
|
|
155
|
-
if t.nil? || t.include?('w')
|
|
156
|
-
method_pin = Solargraph::Pin::Method.new(
|
|
157
|
-
location: location,
|
|
158
|
-
closure: namespace,
|
|
159
|
-
name: "#{directive.tag.name}=",
|
|
160
|
-
comments: docstring.all.to_s,
|
|
161
|
-
scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
|
|
162
|
-
visibility: :public,
|
|
163
|
-
attribute: true,
|
|
164
|
-
source: :source_map
|
|
165
|
-
)
|
|
166
|
-
pins.push method_pin
|
|
167
|
-
method_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: pins.last,
|
|
168
|
-
source: :source_map)
|
|
169
|
-
if pins.last.return_type.defined?
|
|
170
|
-
pins.last.docstring.add_tag YARD::Tags::Tag.new(:param, '', pins.last.return_type.to_s.split(', '),
|
|
171
|
-
'value')
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
when 'visibility'
|
|
104
|
+
directive_processor = YardMap::Directives.for(directive)
|
|
105
|
+
return unless directive_processor
|
|
175
106
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
name = directive.tag.name
|
|
180
|
-
closure = closure_at(source_position) || @pins.first
|
|
181
|
-
# @sg-ignore Need to add nil check here
|
|
182
|
-
closure = closure_at(comment_position) if closure.location.range.start.line < comment_position.line
|
|
183
|
-
if closure.is_a?(Pin::Method) && no_empty_lines?(comment_position.line, source_position.line)
|
|
184
|
-
# @todo Smelly instance variable access
|
|
185
|
-
closure.instance_variable_set(:@visibility, kind)
|
|
186
|
-
else
|
|
187
|
-
matches = pins.select do |pin|
|
|
188
|
-
pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == namespace && pin.context.scope == namespace.is_a?(Pin::Singleton) ? :class : :instance
|
|
189
|
-
end
|
|
190
|
-
matches.each do |pin|
|
|
191
|
-
# @todo Smelly instance variable access
|
|
192
|
-
pin.instance_variable_set(:@visibility, kind)
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
when 'parse'
|
|
197
|
-
begin
|
|
198
|
-
ns = closure_at(source_position)
|
|
199
|
-
# @sg-ignore Need to add nil check here
|
|
200
|
-
src = Solargraph::Source.load_string(directive.tag.text, @source.filename)
|
|
201
|
-
region = Parser::Region.new(source: src, closure: ns)
|
|
202
|
-
# @todo These pins may need to be marked not explicit
|
|
203
|
-
index = @pins.length
|
|
204
|
-
loff = if @code.lines[comment_position.line].strip.end_with?('@!parse')
|
|
205
|
-
comment_position.line + 1
|
|
206
|
-
else
|
|
207
|
-
comment_position.line
|
|
208
|
-
end
|
|
209
|
-
locals = []
|
|
210
|
-
ivars = []
|
|
211
|
-
Parser.process_node(src.node, region, @pins, locals, ivars)
|
|
212
|
-
@pins.concat ivars
|
|
213
|
-
# @sg-ignore Need to add nil check here
|
|
214
|
-
@pins[index..].each do |p|
|
|
215
|
-
# @todo Smelly instance variable access
|
|
216
|
-
p.location.range.start.instance_variable_set(:@line, p.location.range.start.line + loff)
|
|
217
|
-
p.location.range.ending.instance_variable_set(:@line, p.location.range.ending.line + loff)
|
|
218
|
-
end
|
|
219
|
-
rescue Parser::SyntaxError
|
|
220
|
-
# @todo Handle parser errors in !parse directives
|
|
221
|
-
end
|
|
222
|
-
when 'domain'
|
|
223
|
-
namespace = closure_at(source_position) || Pin::ROOT_PIN
|
|
224
|
-
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
225
|
-
namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
|
|
226
|
-
when 'override'
|
|
227
|
-
pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags,
|
|
228
|
-
source: :source_map)
|
|
229
|
-
when 'macro'
|
|
230
|
-
# @todo Handle macros
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
# @param line1 [Integer]
|
|
235
|
-
# @param line2 [Integer]
|
|
236
|
-
# @sg-ignore Need to add nil check here
|
|
237
|
-
def no_empty_lines? line1, line2
|
|
238
|
-
# @sg-ignore Need to add nil check here
|
|
239
|
-
@code.lines[line1..line2].none? { |line| line.strip.empty? }
|
|
107
|
+
@pins += directive_processor.process_directive(
|
|
108
|
+
@source, @pins, source_position, comment_position, directive
|
|
109
|
+
)
|
|
240
110
|
end
|
|
241
111
|
|
|
242
112
|
# @param comment [String]
|
|
@@ -152,6 +152,20 @@ module Solargraph
|
|
|
152
152
|
locals.select { |pin| pin.visible_at?(closure, location) }
|
|
153
153
|
end
|
|
154
154
|
|
|
155
|
+
# @return [Array<Parser::AST::Node>]
|
|
156
|
+
def method_call_nodes
|
|
157
|
+
# @sg-ignore node expected Parser::AST::Node, received Parser::AST::Node, nil
|
|
158
|
+
@method_call_nodes ||= Solargraph::Parser::ParserGem::NodeMethods.call_nodes_from(source.node)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# @param macro_method_names [Array<String>]
|
|
162
|
+
# @return [Array<Parser::AST::Node>]
|
|
163
|
+
def macro_method_candidates macro_method_names
|
|
164
|
+
return @macro_method_candidates if @macro_method_names == macro_method_names
|
|
165
|
+
@macro_method_names = macro_method_names
|
|
166
|
+
@macro_method_candidates = method_call_nodes.select { |node| macro_method_names.include?(node.children[1].to_s) }
|
|
167
|
+
end
|
|
168
|
+
|
|
155
169
|
class << self
|
|
156
170
|
# @param filename [String]
|
|
157
171
|
# @return [SourceMap]
|
data/lib/solargraph/version.rb
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Solargraph
|
|
4
|
-
VERSION = ENV.fetch('SOLARGRAPH_FORCE_VERSION', '0.
|
|
4
|
+
VERSION = ENV.fetch('SOLARGRAPH_FORCE_VERSION', '0.60.0')
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# @generic T
|
|
8
|
+
class A
|
|
9
|
+
# @yieldparam param0 [generic<T>]
|
|
10
|
+
def foo
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class B < A # [Integer]
|
|
15
|
+
def bar
|
|
16
|
+
foo { |param0| }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
b = B.new
|
|
21
|
+
b.foo do |arg|
|
|
22
|
+
arg #=> Integer
|
|
5
23
|
end
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class YardMap
|
|
5
|
-
class Cache
|
|
6
|
-
def initialize
|
|
7
|
-
# @type [Hash{String => Array<Solargraph::Pin::Base>}]
|
|
8
|
-
@path_pins = {}
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
# @param path [String]
|
|
12
|
-
# @param pins [Array<Solargraph::Pin::Base>]
|
|
13
|
-
# @return [Array<Solargraph::Pin::Base>]
|
|
14
|
-
def set_path_pins path, pins
|
|
15
|
-
@path_pins[path] = pins
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# @param path [String]
|
|
19
|
-
# @return [Array<Solargraph::Pin::Base>]
|
|
20
|
-
def get_path_pins path
|
|
21
|
-
@path_pins[path]
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class YardMap
|
|
5
|
+
class Cache
|
|
6
|
+
def initialize
|
|
7
|
+
# @type [Hash{String => Array<Solargraph::Pin::Base>}]
|
|
8
|
+
@path_pins = {}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @param path [String]
|
|
12
|
+
# @param pins [Array<Solargraph::Pin::Base>]
|
|
13
|
+
# @return [Array<Solargraph::Pin::Base>]
|
|
14
|
+
def set_path_pins path, pins
|
|
15
|
+
@path_pins[path] = pins
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @param path [String]
|
|
19
|
+
# @return [Array<Solargraph::Pin::Base>]
|
|
20
|
+
def get_path_pins path
|
|
21
|
+
@path_pins[path]
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class YardMap
|
|
5
|
+
module Directives
|
|
6
|
+
module AttributeDirective
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
# @param source [Solargraph::Source]
|
|
10
|
+
# @param pins [Array<Solargraph::Pin::Base>]
|
|
11
|
+
# @param source_position [Position]
|
|
12
|
+
# @param comment_position [Position]
|
|
13
|
+
# @param directive [YARD::Tags::Directive]
|
|
14
|
+
# @return [Array<Solargraph::Pin::Method>]
|
|
15
|
+
def process_directive source, pins, source_position, comment_position, directive
|
|
16
|
+
new_pins = []
|
|
17
|
+
location = Location.new(source.filename, Range.new(comment_position, comment_position))
|
|
18
|
+
docstring = Solargraph::Source.parse_docstring(directive.tag.text.to_s).to_docstring
|
|
19
|
+
return [] if directive.tag.name.nil?
|
|
20
|
+
namespace = closure_at(pins, source_position)
|
|
21
|
+
t = directive.tag.types.nil? || directive.tag.types.empty? ? nil : directive.tag.types.join
|
|
22
|
+
if t.nil? || t.include?('r')
|
|
23
|
+
new_pins.push Solargraph::Pin::Method.new(
|
|
24
|
+
location: location,
|
|
25
|
+
closure: namespace,
|
|
26
|
+
name: directive.tag.name,
|
|
27
|
+
comments: docstring.all.to_s,
|
|
28
|
+
scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
|
|
29
|
+
visibility: :public,
|
|
30
|
+
explicit: false,
|
|
31
|
+
attribute: true,
|
|
32
|
+
source: :yard_map
|
|
33
|
+
)
|
|
34
|
+
end
|
|
35
|
+
if t.nil? || t.include?('w')
|
|
36
|
+
write_pin = Solargraph::Pin::Method.new(
|
|
37
|
+
location: location,
|
|
38
|
+
closure: namespace,
|
|
39
|
+
name: "#{directive.tag.name}=",
|
|
40
|
+
comments: docstring.all.to_s,
|
|
41
|
+
scope: namespace.is_a?(Pin::Singleton) ? :class : :instance,
|
|
42
|
+
visibility: :public,
|
|
43
|
+
attribute: true,
|
|
44
|
+
source: :yard_map
|
|
45
|
+
)
|
|
46
|
+
new_pins.push(write_pin)
|
|
47
|
+
write_pin.parameters.push Pin::Parameter.new(name: 'value', decl: :arg, closure: write_pin, source: :yard_map)
|
|
48
|
+
if write_pin.return_type&.defined?
|
|
49
|
+
write_pin.docstring.add_tag YARD::Tags::Tag.new(:param, '', write_pin.return_type.to_s.split(', '), 'value')
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
new_pins.compact
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @param [Array<Pin::Base>] pins
|
|
57
|
+
# @param [Position] position
|
|
58
|
+
# @return [Pin::Closure]
|
|
59
|
+
def closure_at pins, position
|
|
60
|
+
pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class YardMap
|
|
5
|
+
module Directives
|
|
6
|
+
module DomainDirective
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
# @param source [Solargraph::Source]
|
|
10
|
+
# @param pins [Array<Solargraph::Pin::Base>]
|
|
11
|
+
# @param source_position [Position]
|
|
12
|
+
# @param _comment_position [Position]
|
|
13
|
+
# @param directive [YARD::Tags::Directive]
|
|
14
|
+
# @return [Array<Solargraph::Pin::Method>]
|
|
15
|
+
def process_directive source, pins, source_position, _comment_position, directive
|
|
16
|
+
namespace = closure_at(pins, source_position) || Pin::ROOT_PIN
|
|
17
|
+
namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
|
|
18
|
+
[]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @param [Array<Pin::Base>] pins
|
|
22
|
+
# @param [Position] position
|
|
23
|
+
# @return [Pin::Namespace]
|
|
24
|
+
def closure_at pins, position
|
|
25
|
+
pins.select { |pin| pin.is_a?(Pin::Namespace) and pin.location&.range&.contain?(position) }.last
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class YardMap
|
|
5
|
+
module Directives
|
|
6
|
+
module MethodDirective
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
# @param source [Solargraph::Source]
|
|
10
|
+
# @param pins [Array<Solargraph::Pin::Base>]
|
|
11
|
+
# @param source_position [Position]
|
|
12
|
+
# @param comment_position [Position]
|
|
13
|
+
# @param directive [YARD::Tags::Directive]
|
|
14
|
+
# @return [Array<Solargraph::Pin::Method>]
|
|
15
|
+
def process_directive source, pins, source_position, comment_position, directive
|
|
16
|
+
namespace = closure_at(pins, source_position) || pins.first
|
|
17
|
+
|
|
18
|
+
namespace = closure_at(pins, comment_position) if namespace.location&.range&.start&.line&.< comment_position.line # rubocop:disable Style/SafeNavigationChainLength
|
|
19
|
+
begin
|
|
20
|
+
src = Solargraph::Source.load_string("def #{directive.tag.name};end", source.filename)
|
|
21
|
+
region = Parser::Region.new(source: src, closure: namespace)
|
|
22
|
+
method_gen_pins = Parser.process_node(src.node, region).first.select { |pin| pin.is_a?(Pin::Method) }
|
|
23
|
+
gen_pin = method_gen_pins.last
|
|
24
|
+
return [] if gen_pin.nil?
|
|
25
|
+
# Move the location to the end of the line so it gets recognized
|
|
26
|
+
# as originating from a comment
|
|
27
|
+
shifted = Solargraph::Position.new(comment_position.line,
|
|
28
|
+
source.code.lines[comment_position.line].to_s.chomp.length)
|
|
29
|
+
comments = Solargraph::Source.parse_docstring(directive.tag.text.to_s).to_docstring.all.to_s
|
|
30
|
+
# @todo: Smelly instance variable access
|
|
31
|
+
gen_pin.instance_variable_set(:@comments, comments)
|
|
32
|
+
gen_pin.instance_variable_set(:@location,
|
|
33
|
+
Solargraph::Location.new(source.filename, Range.new(shifted, shifted)))
|
|
34
|
+
gen_pin.instance_variable_set(:@explicit, false)
|
|
35
|
+
[gen_pin]
|
|
36
|
+
rescue Parser::SyntaxError
|
|
37
|
+
# @todo Handle error in directive
|
|
38
|
+
[]
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @param [Array<Pin::Base>] pins
|
|
43
|
+
# @param [Position] position
|
|
44
|
+
# @return [Pin::Closure]
|
|
45
|
+
def closure_at pins, position
|
|
46
|
+
pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class YardMap
|
|
5
|
+
module Directives
|
|
6
|
+
module OverrideDirective
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
# @param source [Solargraph::Source]
|
|
10
|
+
# @param _pins [Array<Solargraph::Pin::Base>]
|
|
11
|
+
# @param _source_position [Position]
|
|
12
|
+
# @param comment_position [Position]
|
|
13
|
+
# @param directive [YARD::Tags::Directive]
|
|
14
|
+
# @return [Array<Pin::Base>]
|
|
15
|
+
def process_directive source, _pins, _source_position, comment_position, directive
|
|
16
|
+
docstring = Solargraph::Source.parse_docstring(directive.tag.text.to_s).to_docstring
|
|
17
|
+
location = Location.new(source.filename, Range.new(comment_position, comment_position))
|
|
18
|
+
[Pin::Reference::Override.new(location, directive.tag.name.to_s, docstring.tags, source: :yard_map)]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @param [Array<Pin::Base>] pins
|
|
22
|
+
# @param [Position] position
|
|
23
|
+
# @return [Pin::Closure]
|
|
24
|
+
def closure_at pins, position
|
|
25
|
+
pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class YardMap
|
|
5
|
+
module Directives
|
|
6
|
+
module ParseDirective
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
# @param source [Solargraph::Source]
|
|
10
|
+
# @param pins [Array<Solargraph::Pin::Base>]
|
|
11
|
+
# @param source_position [Position]
|
|
12
|
+
# @param comment_position [Position]
|
|
13
|
+
# @param directive [YARD::Tags::Directive]
|
|
14
|
+
# @return [Array<Solargraph::Pin::Base>]
|
|
15
|
+
def process_directive source, pins, source_position, comment_position, directive
|
|
16
|
+
ns = closure_at(pins, source_position)
|
|
17
|
+
pins_copy = pins.dup
|
|
18
|
+
src = Solargraph::Source.load_string(directive.tag.text.to_s, source.filename)
|
|
19
|
+
region = Parser::Region.new(source: src, closure: ns)
|
|
20
|
+
# @todo These pins may need to be marked not explicit
|
|
21
|
+
old_pins_index = pins.length
|
|
22
|
+
loff = if source.code.lines[comment_position.line].strip.end_with?('@!parse')
|
|
23
|
+
comment_position.line + 1
|
|
24
|
+
else
|
|
25
|
+
comment_position.line
|
|
26
|
+
end
|
|
27
|
+
Parser.process_node(src.node, region, pins_copy)
|
|
28
|
+
new_pins = pins_copy[old_pins_index..] || []
|
|
29
|
+
new_pins.each do |p|
|
|
30
|
+
# @todo Smelly instance variable access
|
|
31
|
+
next if p.location.nil?
|
|
32
|
+
# @sg-ignore Unresolved call to range on Solargraph::Location, nil - does not account for next clause above.
|
|
33
|
+
p.location.range.start.instance_variable_set(:@line, p.location.range.start.line + loff)
|
|
34
|
+
# @sg-ignore Unresolved call to range on Solargraph::Location, nil
|
|
35
|
+
p.location.range.ending.instance_variable_set(:@line, p.location.range.ending.line + loff)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
new_pins
|
|
39
|
+
rescue Parser::SyntaxError
|
|
40
|
+
# @todo Handle parser errors in !parse directives
|
|
41
|
+
[]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @param [Array<Pin::Base>] pins
|
|
45
|
+
# @param [Position] position
|
|
46
|
+
# @return [Pin::Closure]
|
|
47
|
+
def closure_at pins, position
|
|
48
|
+
pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class YardMap
|
|
5
|
+
module Directives
|
|
6
|
+
module VisibilityDirective
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
VALID_VISIBILITIES = %i[public protected private].freeze
|
|
10
|
+
|
|
11
|
+
# @param source [Solargraph::Source]
|
|
12
|
+
# @param pins [Array<Solargraph::Pin::Base>]
|
|
13
|
+
# @param source_position [Position]
|
|
14
|
+
# @param comment_position [Position]
|
|
15
|
+
# @param directive [YARD::Tags::Directive]
|
|
16
|
+
# @return [Array<Solargraph::Pin::Base>]
|
|
17
|
+
def process_directive source, pins, source_position, comment_position, directive
|
|
18
|
+
kind = directive.tag.text&.to_sym
|
|
19
|
+
|
|
20
|
+
# @sg-ignore include? only expects Symbol, but receives Symbol or nil
|
|
21
|
+
return [] unless VALID_VISIBILITIES.include?(kind.to_sym)
|
|
22
|
+
|
|
23
|
+
name = directive.tag.name
|
|
24
|
+
closure = closure_at(pins, source_position) || pins.first
|
|
25
|
+
closure = closure_at(pins, comment_position) if closure.location&.range&.start&.line&.< comment_position.line # rubocop:disable Style/SafeNavigationChainLength
|
|
26
|
+
if closure.is_a?(Pin::Method) && no_empty_lines?(source.code, comment_position.line, source_position.line)
|
|
27
|
+
# @todo Smelly instance variable access
|
|
28
|
+
closure.instance_variable_set(:@visibility, kind)
|
|
29
|
+
else
|
|
30
|
+
namespace = closure_at(pins, source_position)
|
|
31
|
+
matches = pins.select do |pin|
|
|
32
|
+
if pin.is_a?(Pin::Method) &&
|
|
33
|
+
pin.name == name &&
|
|
34
|
+
pin.namespace == namespace &&
|
|
35
|
+
pin.context.scope == namespace.is_a?(Pin::Singleton)
|
|
36
|
+
:class
|
|
37
|
+
else
|
|
38
|
+
:instance
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
matches.each do |pin|
|
|
43
|
+
# @todo Smelly instance variable access
|
|
44
|
+
pin.instance_variable_set(:@visibility, kind)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
[]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @param [String] code
|
|
52
|
+
# @param [Integer] line1
|
|
53
|
+
# @param [Integer] line2
|
|
54
|
+
# @return [Boolean]
|
|
55
|
+
# @sg-ignore return type could not be inferred
|
|
56
|
+
def no_empty_lines? code, line1, line2
|
|
57
|
+
# @sg-ignore unresolved call none? on the array.
|
|
58
|
+
code.lines[line1..line2].none? { |line| line.strip.empty? }
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @param [Array<Pin::Base>] pins
|
|
62
|
+
# @param [Position] position
|
|
63
|
+
# @return [Pin::Closure]
|
|
64
|
+
def closure_at pins, position
|
|
65
|
+
pins.select { |pin| pin.is_a?(Pin::Closure) and pin.location&.range&.contain?(position) }.last
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class YardMap
|
|
5
|
+
module Directives
|
|
6
|
+
autoload :AttributeDirective, 'solargraph/yard_map/directives/attribute_directive'
|
|
7
|
+
autoload :MethodDirective, 'solargraph/yard_map/directives/method_directive'
|
|
8
|
+
autoload :DomainDirective, 'solargraph/yard_map/directives/domain_directive'
|
|
9
|
+
autoload :OverrideDirective, 'solargraph/yard_map/directives/override_directive'
|
|
10
|
+
autoload :ParseDirective, 'solargraph/yard_map/directives/parse_directive'
|
|
11
|
+
autoload :VisibilityDirective, 'solargraph/yard_map/directives/visibility_directive'
|
|
12
|
+
|
|
13
|
+
# @param directive [YARD::Tags::Directive]
|
|
14
|
+
# @return [Class<AttributeDirective>, Class<MethodDirective>, Class<DomainDirective>, Class<OverrideDirective>, Class<ParseDirective>, Class<VisibilityDirective>, nil]
|
|
15
|
+
def self.for directive
|
|
16
|
+
case directive.tag.tag_name
|
|
17
|
+
when 'attribute'
|
|
18
|
+
AttributeDirective
|
|
19
|
+
when 'method'
|
|
20
|
+
MethodDirective
|
|
21
|
+
when 'domain'
|
|
22
|
+
DomainDirective
|
|
23
|
+
when 'override'
|
|
24
|
+
OverrideDirective
|
|
25
|
+
when 'parse'
|
|
26
|
+
ParseDirective
|
|
27
|
+
when 'visibility'
|
|
28
|
+
VisibilityDirective
|
|
29
|
+
else # rubocop:disable Style/EmptyElse
|
|
30
|
+
nil
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|