solargraph 0.51.2 → 0.54.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/plugins.yml +40 -0
- data/.github/workflows/rspec.yml +1 -3
- data/.github/workflows/typecheck.yml +34 -0
- data/.yardopts +2 -2
- data/CHANGELOG.md +127 -5
- data/README.md +13 -16
- data/SPONSORS.md +1 -7
- data/lib/solargraph/api_map/cache.rb +50 -20
- data/lib/solargraph/api_map/source_to_yard.rb +17 -10
- data/lib/solargraph/api_map/store.rb +60 -15
- data/lib/solargraph/api_map.rb +282 -123
- data/lib/solargraph/bench.rb +3 -2
- data/lib/solargraph/cache.rb +29 -5
- data/lib/solargraph/complex_type/type_methods.rb +122 -39
- data/lib/solargraph/complex_type/unique_type.rb +310 -76
- data/lib/solargraph/complex_type.rb +166 -44
- data/lib/solargraph/convention.rb +0 -1
- data/lib/solargraph/converters/dd.rb +5 -0
- data/lib/solargraph/converters/dl.rb +3 -0
- data/lib/solargraph/converters/dt.rb +3 -0
- data/lib/solargraph/diagnostics/rubocop.rb +8 -7
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/diagnostics.rb +2 -2
- data/lib/solargraph/doc_map.rb +187 -0
- data/lib/solargraph/gem_pins.rb +72 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
- data/lib/solargraph/language_server/host/dispatch.rb +22 -5
- data/lib/solargraph/language_server/host/message_worker.rb +49 -5
- data/lib/solargraph/language_server/host/sources.rb +8 -65
- data/lib/solargraph/language_server/host.rb +65 -84
- data/lib/solargraph/language_server/message/base.rb +19 -12
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
- data/lib/solargraph/language_server/message/initialize.rb +19 -2
- data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
- data/lib/solargraph/language_server/message/text_document/definition.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
- data/lib/solargraph/language_server/message/text_document.rb +0 -1
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
- data/lib/solargraph/language_server/progress.rb +135 -0
- data/lib/solargraph/language_server/transport/adapter.rb +16 -1
- data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
- data/lib/solargraph/language_server.rb +1 -0
- data/lib/solargraph/library.rb +207 -111
- data/lib/solargraph/location.rb +15 -1
- data/lib/solargraph/page.rb +6 -0
- data/lib/solargraph/parser/comment_ripper.rb +4 -0
- data/lib/solargraph/parser/node_methods.rb +47 -7
- data/lib/solargraph/parser/node_processor/base.rb +11 -1
- data/lib/solargraph/parser/node_processor.rb +1 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -9
- data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +62 -43
- data/lib/solargraph/parser/parser_gem/node_methods.rb +495 -0
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +57 -0
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +7 -20
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +4 -4
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +53 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +8 -6
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +56 -0
- data/lib/solargraph/parser/parser_gem.rb +12 -0
- data/lib/solargraph/parser/region.rb +1 -1
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +8 -12
- data/lib/solargraph/pin/base.rb +78 -10
- data/lib/solargraph/pin/base_variable.rb +40 -7
- data/lib/solargraph/pin/block.rb +69 -46
- data/lib/solargraph/pin/callable.rb +147 -0
- data/lib/solargraph/pin/closure.rb +23 -3
- data/lib/solargraph/pin/common.rb +6 -6
- data/lib/solargraph/pin/conversions.rb +36 -5
- data/lib/solargraph/pin/delegated_method.rb +6 -2
- data/lib/solargraph/pin/documenting.rb +25 -32
- data/lib/solargraph/pin/instance_variable.rb +6 -2
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +205 -32
- data/lib/solargraph/pin/namespace.rb +20 -7
- data/lib/solargraph/pin/parameter.rb +41 -36
- data/lib/solargraph/pin/proxy_type.rb +1 -1
- data/lib/solargraph/pin/reference/override.rb +2 -2
- data/lib/solargraph/pin/reference.rb +8 -0
- data/lib/solargraph/pin/search.rb +3 -3
- data/lib/solargraph/pin/signature.rb +8 -14
- data/lib/solargraph/pin.rb +4 -2
- data/lib/solargraph/range.rb +4 -6
- data/lib/solargraph/rbs_map/conversions.rb +326 -76
- data/lib/solargraph/rbs_map/core_fills.rb +16 -33
- data/lib/solargraph/rbs_map/core_map.rb +3 -13
- data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
- data/lib/solargraph/rbs_map.rb +32 -13
- data/lib/solargraph/shell.rb +95 -72
- data/lib/solargraph/source/chain/array.rb +33 -0
- data/lib/solargraph/source/chain/block_symbol.rb +13 -0
- data/lib/solargraph/source/chain/block_variable.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +152 -69
- data/lib/solargraph/source/chain/constant.rb +15 -1
- data/lib/solargraph/source/chain/if.rb +23 -0
- data/lib/solargraph/source/chain/link.rb +17 -2
- data/lib/solargraph/source/chain/or.rb +2 -2
- data/lib/solargraph/source/chain/z_super.rb +3 -3
- data/lib/solargraph/source/chain.rb +85 -26
- data/lib/solargraph/source/change.rb +3 -0
- data/lib/solargraph/source/cursor.rb +16 -2
- data/lib/solargraph/source/source_chainer.rb +8 -5
- data/lib/solargraph/source/updater.rb +1 -0
- data/lib/solargraph/source.rb +120 -148
- data/lib/solargraph/source_map/clip.rb +16 -27
- data/lib/solargraph/source_map/data.rb +30 -0
- data/lib/solargraph/source_map/mapper.rb +15 -3
- data/lib/solargraph/source_map.rb +48 -24
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker/rules.rb +6 -1
- data/lib/solargraph/type_checker.rb +150 -39
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +9 -6
- data/lib/solargraph/workspace.rb +30 -3
- data/lib/solargraph/yard_map/cache.rb +6 -0
- data/lib/solargraph/yard_map/helpers.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +16 -3
- data/lib/solargraph/yard_map/mapper.rb +1 -1
- data/lib/solargraph/yard_map/to_method.rb +11 -4
- data/lib/solargraph/yard_map.rb +1 -292
- data/lib/solargraph/yard_tags.rb +20 -0
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +6 -4
- data/solargraph.gemspec +7 -6
- metadata +71 -82
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/documentor.rb +0 -76
- data/lib/solargraph/language_server/host/cataloger.rb +0 -56
- data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -50
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
- data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
- data/lib/solargraph/parser/legacy.rb +0 -12
- data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -153
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
- data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
- data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
- data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
- data/lib/solargraph/parser/rubyvm.rb +0 -40
- data/lib/solargraph/rbs_map/core_signs.rb +0 -33
- data/lib/yard-solargraph.rb +0 -33
data/lib/solargraph/source.rb
CHANGED
@@ -8,7 +8,6 @@ module Solargraph
|
|
8
8
|
class Source
|
9
9
|
autoload :Updater, 'solargraph/source/updater'
|
10
10
|
autoload :Change, 'solargraph/source/change'
|
11
|
-
autoload :Mapper, 'solargraph/source/mapper'
|
12
11
|
autoload :EncodingFixes, 'solargraph/source/encoding_fixes'
|
13
12
|
autoload :Cursor, 'solargraph/source/cursor'
|
14
13
|
autoload :Chain, 'solargraph/source/chain'
|
@@ -20,37 +19,35 @@ module Solargraph
|
|
20
19
|
attr_reader :filename
|
21
20
|
|
22
21
|
# @return [String]
|
23
|
-
|
22
|
+
def code
|
23
|
+
finalize
|
24
|
+
@code
|
25
|
+
end
|
24
26
|
|
25
|
-
# @return [Parser::AST::Node]
|
26
|
-
|
27
|
+
# @return [Parser::AST::Node, nil]
|
28
|
+
def node
|
29
|
+
finalize
|
30
|
+
@node
|
31
|
+
end
|
27
32
|
|
28
33
|
# @return [Hash{Integer => Array<String>}]
|
29
|
-
|
34
|
+
def comments
|
35
|
+
finalize
|
36
|
+
@comments
|
37
|
+
end
|
30
38
|
|
31
39
|
# @todo Deprecate?
|
32
40
|
# @return [Integer]
|
33
41
|
attr_reader :version
|
34
42
|
|
35
43
|
# @param code [String]
|
36
|
-
# @param filename [String]
|
44
|
+
# @param filename [String, nil]
|
37
45
|
# @param version [Integer]
|
38
46
|
def initialize code, filename = nil, version = 0
|
39
47
|
@code = normalize(code)
|
40
48
|
@repaired = code
|
41
49
|
@filename = filename
|
42
50
|
@version = version
|
43
|
-
@domains = []
|
44
|
-
begin
|
45
|
-
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
|
46
|
-
@parsed = true
|
47
|
-
rescue Parser::SyntaxError, EncodingError => e
|
48
|
-
@node = nil
|
49
|
-
@comments = {}
|
50
|
-
@parsed = false
|
51
|
-
ensure
|
52
|
-
@code.freeze
|
53
|
-
end
|
54
51
|
end
|
55
52
|
|
56
53
|
# @param range [Solargraph::Range]
|
@@ -65,9 +62,9 @@ module Solargraph
|
|
65
62
|
# @param c2 [Integer]
|
66
63
|
# @return [String]
|
67
64
|
def from_to l1, c1, l2, c2
|
68
|
-
b = Solargraph::Position.line_char_to_offset(
|
69
|
-
e = Solargraph::Position.line_char_to_offset(
|
70
|
-
|
65
|
+
b = Solargraph::Position.line_char_to_offset(code, l1, c1)
|
66
|
+
e = Solargraph::Position.line_char_to_offset(code, l2, c2)
|
67
|
+
code[b..e-1]
|
71
68
|
end
|
72
69
|
|
73
70
|
# Get the nearest node that contains the specified index.
|
@@ -86,57 +83,12 @@ module Solargraph
|
|
86
83
|
# @param column [Integer]
|
87
84
|
# @return [Array<AST::Node>]
|
88
85
|
def tree_at(line, column)
|
89
|
-
# offset = Position.line_char_to_offset(@code, line, column)
|
90
86
|
position = Position.new(line, column)
|
91
87
|
stack = []
|
92
|
-
inner_tree_at
|
88
|
+
inner_tree_at node, position, stack
|
93
89
|
stack
|
94
90
|
end
|
95
91
|
|
96
|
-
# Start synchronizing the source. This method updates the code without
|
97
|
-
# parsing a new AST. The resulting Source object will be marked not
|
98
|
-
# synchronized (#synchronized? == false).
|
99
|
-
#
|
100
|
-
# @param updater [Source::Updater]
|
101
|
-
# @return [Source]
|
102
|
-
def start_synchronize updater
|
103
|
-
raise 'Invalid synchronization' unless updater.filename == filename
|
104
|
-
real_code = updater.write(@code)
|
105
|
-
src = Source.allocate
|
106
|
-
src.filename = filename
|
107
|
-
src.code = real_code
|
108
|
-
src.version = updater.version
|
109
|
-
src.parsed = parsed?
|
110
|
-
src.repaired = updater.repair(@repaired)
|
111
|
-
src.synchronized = false
|
112
|
-
src.node = @node
|
113
|
-
src.comments = @comments
|
114
|
-
src.error_ranges = error_ranges
|
115
|
-
src.last_updater = updater
|
116
|
-
return src.finish_synchronize unless real_code.lines.length == @code.lines.length
|
117
|
-
src
|
118
|
-
end
|
119
|
-
|
120
|
-
# Finish synchronizing a source that was updated via #start_synchronize.
|
121
|
-
# This method returns self if the source is already synchronized. Otherwise
|
122
|
-
# it parses the AST and returns a new synchronized Source.
|
123
|
-
#
|
124
|
-
# @return [Source]
|
125
|
-
def finish_synchronize
|
126
|
-
return self if synchronized?
|
127
|
-
synced = Source.new(@code, filename)
|
128
|
-
if synced.parsed?
|
129
|
-
synced.version = version
|
130
|
-
return synced
|
131
|
-
end
|
132
|
-
synced = Source.new(@repaired, filename)
|
133
|
-
synced.error_ranges.concat (error_ranges + last_updater.changes.map(&:range))
|
134
|
-
synced.code = @code
|
135
|
-
synced.synchronized = true
|
136
|
-
synced.version = version
|
137
|
-
synced
|
138
|
-
end
|
139
|
-
|
140
92
|
# Synchronize the Source with an update. This method applies changes to the
|
141
93
|
# code, parses the new code's AST, and returns the resulting Source object.
|
142
94
|
#
|
@@ -149,70 +101,56 @@ module Solargraph
|
|
149
101
|
@version = updater.version
|
150
102
|
return self
|
151
103
|
end
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
104
|
+
Source.new(@code, filename, updater.version).tap do |src|
|
105
|
+
src.repaired = @repaired
|
106
|
+
src.error_ranges.concat error_ranges
|
107
|
+
src.changes.concat(changes + updater.changes)
|
156
108
|
end
|
157
|
-
incr_code = updater.repair(@repaired)
|
158
|
-
synced = Source.new(incr_code, filename)
|
159
|
-
synced.error_ranges.concat (error_ranges + updater.changes.map(&:range))
|
160
|
-
synced.code = real_code
|
161
|
-
synced.version = updater.version
|
162
|
-
synced
|
163
109
|
end
|
164
110
|
|
165
111
|
# @param position [Position, Array(Integer, Integer)]
|
166
112
|
# @return [Source::Cursor]
|
167
113
|
def cursor_at position
|
114
|
+
finalize
|
168
115
|
Cursor.new(self, position)
|
169
116
|
end
|
170
117
|
|
171
118
|
# @return [Boolean]
|
172
119
|
def parsed?
|
120
|
+
finalize
|
173
121
|
@parsed
|
174
122
|
end
|
175
123
|
|
176
124
|
def repaired?
|
177
|
-
|
125
|
+
code != @repaired
|
178
126
|
end
|
179
127
|
|
180
128
|
# @param position [Position]
|
181
129
|
# @return [Boolean]
|
182
130
|
def string_at? position
|
183
|
-
if
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
return true if [:STR, :str].include?(node.type) && range.include?(position) && range.start != position
|
200
|
-
if node.type == :dstr
|
201
|
-
inner = node_at(position.line, position.column)
|
202
|
-
next if inner.nil?
|
203
|
-
inner_range = Range.from_node(inner)
|
204
|
-
next unless range.include?(inner_range.ending)
|
205
|
-
return true if inner.type == :str
|
206
|
-
inner_code = at(Solargraph::Range.new(inner_range.start, position))
|
207
|
-
return true if (inner.type == :dstr && inner_range.ending.character <= position.character) && !inner_code.end_with?('}') ||
|
208
|
-
(inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
|
209
|
-
end
|
210
|
-
break if range.ending.line > position.line
|
131
|
+
return false if Position.to_offset(code, position) >= code.length
|
132
|
+
string_nodes.each do |node|
|
133
|
+
range = Range.from_node(node)
|
134
|
+
next if range.ending.line < position.line
|
135
|
+
break if range.ending.line > position.line
|
136
|
+
return true if node.type == :str && range.include?(position) && range.start != position
|
137
|
+
return true if [:STR, :str].include?(node.type) && range.include?(position) && range.start != position
|
138
|
+
if node.type == :dstr
|
139
|
+
inner = node_at(position.line, position.column)
|
140
|
+
next if inner.nil?
|
141
|
+
inner_range = Range.from_node(inner)
|
142
|
+
next unless range.include?(inner_range.ending)
|
143
|
+
return true if inner.type == :str
|
144
|
+
inner_code = at(Solargraph::Range.new(inner_range.start, position))
|
145
|
+
return true if (inner.type == :dstr && inner_range.ending.character <= position.character) && !inner_code.end_with?('}') ||
|
146
|
+
(inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
|
211
147
|
end
|
212
|
-
|
148
|
+
break if range.ending.line > position.line
|
213
149
|
end
|
150
|
+
false
|
214
151
|
end
|
215
152
|
|
153
|
+
# @return [::Array<Range>]
|
216
154
|
def string_ranges
|
217
155
|
@string_ranges ||= Parser.string_ranges(node)
|
218
156
|
end
|
@@ -243,14 +181,14 @@ module Solargraph
|
|
243
181
|
# @return [String]
|
244
182
|
def code_for(node)
|
245
183
|
rng = Range.from_node(node)
|
246
|
-
b = Position.line_char_to_offset(
|
247
|
-
e = Position.line_char_to_offset(
|
184
|
+
b = Position.line_char_to_offset(code, rng.start.line, rng.start.column)
|
185
|
+
e = Position.line_char_to_offset(code, rng.ending.line, rng.ending.column)
|
248
186
|
frag = code[b..e-1].to_s
|
249
187
|
frag.strip.gsub(/,$/, '')
|
250
188
|
end
|
251
189
|
|
252
190
|
# @param node [Parser::AST::Node]
|
253
|
-
# @return [String]
|
191
|
+
# @return [String, nil]
|
254
192
|
def comments_for node
|
255
193
|
rng = Range.from_node(node)
|
256
194
|
stringified_comments[rng.start.line] ||= begin
|
@@ -269,15 +207,9 @@ module Solargraph
|
|
269
207
|
Location.new(filename, range)
|
270
208
|
end
|
271
209
|
|
272
|
-
FOLDING_NODE_TYPES =
|
273
|
-
%i[
|
274
|
-
CLASS SCLASS MODULE DEFN DEFS IF WHILE UNLESS ITER STR HASH ARRAY LIST
|
275
|
-
].freeze
|
276
|
-
else
|
277
|
-
%i[
|
210
|
+
FOLDING_NODE_TYPES = %i[
|
278
211
|
class sclass module def defs if str dstr array while unless kwbegin hash block
|
279
212
|
].freeze
|
280
|
-
end
|
281
213
|
|
282
214
|
# Get an array of ranges that can be folded, e.g., the range of a class
|
283
215
|
# definition or an if condition.
|
@@ -295,19 +227,19 @@ module Solargraph
|
|
295
227
|
end
|
296
228
|
|
297
229
|
def synchronized?
|
298
|
-
|
299
|
-
@synchronized
|
230
|
+
true
|
300
231
|
end
|
301
232
|
|
302
233
|
# Get a hash of comments grouped by the line numbers of the associated code.
|
303
234
|
#
|
304
|
-
# @return [Hash{Integer =>
|
235
|
+
# @return [Hash{Integer => String}]
|
305
236
|
def associated_comments
|
306
237
|
@associated_comments ||= begin
|
307
238
|
result = {}
|
308
239
|
buffer = String.new('')
|
240
|
+
# @type [Integer, nil]
|
309
241
|
last = nil
|
310
|
-
|
242
|
+
comments.each_pair do |num, snip|
|
311
243
|
if !last || num == last + 1
|
312
244
|
buffer.concat "#{snip.text}\n"
|
313
245
|
else
|
@@ -323,6 +255,8 @@ module Solargraph
|
|
323
255
|
|
324
256
|
private
|
325
257
|
|
258
|
+
# @param line [Integer]
|
259
|
+
# @return [Integer]
|
326
260
|
def first_not_empty_from line
|
327
261
|
cursor = line
|
328
262
|
cursor += 1 while cursor < code_lines.length && code_lines[cursor].strip.empty?
|
@@ -332,17 +266,14 @@ module Solargraph
|
|
332
266
|
|
333
267
|
# @param top [Parser::AST::Node]
|
334
268
|
# @param result [Array<Range>]
|
335
|
-
# @param parent [Symbol]
|
269
|
+
# @param parent [Symbol, nil]
|
336
270
|
# @return [void]
|
337
271
|
def inner_folding_ranges top, result = [], parent = nil
|
338
272
|
return unless Parser.is_ast_node?(top)
|
339
273
|
if FOLDING_NODE_TYPES.include?(top.type)
|
340
|
-
|
341
|
-
|
342
|
-
range
|
343
|
-
if result.empty? || range.start.line > result.last.start.line
|
344
|
-
result.push range unless range.ending.line - range.start.line < 2
|
345
|
-
end
|
274
|
+
range = Range.from_node(top)
|
275
|
+
if result.empty? || range.start.line > result.last.start.line
|
276
|
+
result.push range unless range.ending.line - range.start.line < 2
|
346
277
|
end
|
347
278
|
end
|
348
279
|
top.children.each do |child|
|
@@ -383,12 +314,12 @@ module Solargraph
|
|
383
314
|
|
384
315
|
# @return [Array<Parser::AST::Node>]
|
385
316
|
def string_nodes
|
386
|
-
@string_nodes ||= string_nodes_in(
|
317
|
+
@string_nodes ||= string_nodes_in(node)
|
387
318
|
end
|
388
319
|
|
389
320
|
# @return [Array<Range>]
|
390
321
|
def comment_ranges
|
391
|
-
@comment_ranges ||=
|
322
|
+
@comment_ranges ||= comments.values.map(&:range)
|
392
323
|
end
|
393
324
|
|
394
325
|
# Get an array of foldable comment block ranges. Blocks are excluded if
|
@@ -411,7 +342,7 @@ module Solargraph
|
|
411
342
|
result
|
412
343
|
end
|
413
344
|
|
414
|
-
# @param n [Parser::AST::Node]
|
345
|
+
# @param n [Parser::AST::Node, nil]
|
415
346
|
# @return [Array<Parser::AST::Node>]
|
416
347
|
def string_nodes_in n
|
417
348
|
result = []
|
@@ -425,66 +356,103 @@ module Solargraph
|
|
425
356
|
result
|
426
357
|
end
|
427
358
|
|
428
|
-
# @param node [Parser::AST::Node]
|
359
|
+
# @param node [Parser::AST::Node, nil]
|
429
360
|
# @param position [Position]
|
430
361
|
# @param stack [Array<Parser::AST::Node>]
|
431
362
|
# @return [void]
|
432
363
|
def inner_tree_at node, position, stack
|
433
364
|
return if node.nil?
|
434
365
|
here = Range.from_node(node)
|
435
|
-
if here.contain?(position)
|
366
|
+
if here.contain?(position)
|
436
367
|
stack.unshift node
|
437
368
|
node.children.each do |c|
|
438
369
|
next unless Parser.is_ast_node?(c)
|
439
|
-
next if
|
370
|
+
next if c.loc.expression.nil?
|
440
371
|
inner_tree_at(c, position, stack)
|
441
372
|
end
|
442
373
|
end
|
443
374
|
end
|
444
375
|
|
445
|
-
def colonized range, position, node
|
446
|
-
node.type == :COLON2 &&
|
447
|
-
range.ending.line == position.line &&
|
448
|
-
range.ending.character == position.character - 2 &&
|
449
|
-
code[Position.to_offset(code, Position.new(position.line, position.character - 2)), 2] == '::'
|
450
|
-
end
|
451
|
-
|
452
376
|
protected
|
453
377
|
|
378
|
+
def changes
|
379
|
+
@changes ||= []
|
380
|
+
end
|
381
|
+
|
454
382
|
# @return [String]
|
455
383
|
attr_writer :filename
|
456
384
|
|
457
385
|
# @return [Integer]
|
458
386
|
attr_writer :version
|
459
387
|
|
388
|
+
def finalize
|
389
|
+
return if @finalized && changes.empty?
|
390
|
+
|
391
|
+
changes.each do |change|
|
392
|
+
@code = change.write(@code)
|
393
|
+
end
|
394
|
+
@finalized = true
|
395
|
+
begin
|
396
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
|
397
|
+
@parsed = true
|
398
|
+
@repaired = @code
|
399
|
+
rescue Parser::SyntaxError, EncodingError => e
|
400
|
+
@node = nil
|
401
|
+
@comments = {}
|
402
|
+
@parsed = false
|
403
|
+
ensure
|
404
|
+
@code.freeze
|
405
|
+
end
|
406
|
+
if !@parsed && !changes.empty?
|
407
|
+
changes.each do |change|
|
408
|
+
@repaired = change.repair(@repaired)
|
409
|
+
end
|
410
|
+
error_ranges.concat(changes.map(&:range))
|
411
|
+
begin
|
412
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename)
|
413
|
+
@parsed = true
|
414
|
+
rescue Parser::SyntaxError, EncodingError => e
|
415
|
+
@node = nil
|
416
|
+
@comments = {}
|
417
|
+
@parsed = false
|
418
|
+
end
|
419
|
+
elsif @parsed
|
420
|
+
error_ranges.clear
|
421
|
+
end
|
422
|
+
changes.clear
|
423
|
+
end
|
424
|
+
|
460
425
|
# @param val [String]
|
461
426
|
# @return [String]
|
462
427
|
def code=(val)
|
463
|
-
@code_lines= nil
|
428
|
+
@code_lines = nil
|
429
|
+
@finalized = false
|
464
430
|
@code = val
|
465
431
|
end
|
466
432
|
|
467
|
-
# @return [Parser::AST::Node]
|
433
|
+
# @return [Parser::AST::Node, nil]
|
468
434
|
attr_writer :node
|
469
435
|
|
470
436
|
# @return [Array<Range>]
|
471
437
|
attr_writer :error_ranges
|
472
438
|
|
473
439
|
# @return [String]
|
474
|
-
|
440
|
+
attr_writer :repaired
|
441
|
+
|
442
|
+
def repaired
|
443
|
+
finalize
|
444
|
+
@repaired
|
445
|
+
end
|
475
446
|
|
476
447
|
# @return [Boolean]
|
477
448
|
attr_writer :parsed
|
478
449
|
|
479
|
-
# @return [
|
450
|
+
# @return [Hash{Integer => String}
|
480
451
|
attr_writer :comments
|
481
452
|
|
482
453
|
# @return [Boolean]
|
483
454
|
attr_writer :synchronized
|
484
455
|
|
485
|
-
# @return [Source::Updater]
|
486
|
-
attr_accessor :last_updater
|
487
|
-
|
488
456
|
private
|
489
457
|
|
490
458
|
# @return [Array<String>]
|
@@ -503,7 +471,7 @@ module Solargraph
|
|
503
471
|
end
|
504
472
|
|
505
473
|
# @param code [String]
|
506
|
-
# @param filename [String]
|
474
|
+
# @param filename [String, nil]
|
507
475
|
# @param version [Integer]
|
508
476
|
# @return [Solargraph::Source]
|
509
477
|
def load_string code, filename = nil, version = 0
|
@@ -516,6 +484,10 @@ module Solargraph
|
|
516
484
|
# HACK: Pass a dummy code object to the parser for plugins that
|
517
485
|
# expect it not to be nil
|
518
486
|
YARD::Docstring.parser.parse(comments, YARD::CodeObjects::Base.new(:root, 'stub'))
|
487
|
+
rescue StandardError => e
|
488
|
+
Solargraph.logger.info "YARD failed to parse docstring: [#{e.class}] #{e.message}"
|
489
|
+
Solargraph.logger.debug "Unparsed comment: #{comments}"
|
490
|
+
YARD::Docstring.parser
|
519
491
|
end
|
520
492
|
end
|
521
493
|
end
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Solargraph
|
4
4
|
class SourceMap
|
5
|
-
# A static analysis tool for obtaining definitions,
|
6
|
-
# signatures, and type inferences from a
|
5
|
+
# A static analysis tool for obtaining definitions, Completions,
|
6
|
+
# signatures, and type inferences from a Cursor.
|
7
7
|
#
|
8
8
|
class Clip
|
9
9
|
# @param api_map [ApiMap]
|
@@ -11,9 +11,10 @@ module Solargraph
|
|
11
11
|
def initialize api_map, cursor
|
12
12
|
@api_map = api_map
|
13
13
|
@cursor = cursor
|
14
|
+
block.rebind(api_map) if block.is_a?(Pin::Block)
|
14
15
|
end
|
15
16
|
|
16
|
-
# @return [Array<Pin::Base>]
|
17
|
+
# @return [Array<Pin::Base>] Relevant pins for infering the type of the Cursor's position
|
17
18
|
def define
|
18
19
|
return [] if cursor.comment? || cursor.chain.literal?
|
19
20
|
result = cursor.chain.define(api_map, block, locals)
|
@@ -50,23 +51,24 @@ module Solargraph
|
|
50
51
|
def infer
|
51
52
|
result = cursor.chain.infer(api_map, block, locals)
|
52
53
|
if result.tag == 'Class'
|
53
|
-
# HACK: Exception to return
|
54
|
+
# HACK: Exception to return BasicObject from Class#new
|
54
55
|
dfn = cursor.chain.define(api_map, block, locals).first
|
55
|
-
return ComplexType.try_parse('
|
56
|
+
return ComplexType.try_parse('::BasicObject') if dfn && dfn.path == 'Class#new'
|
56
57
|
end
|
57
58
|
return result unless result.tag == 'self'
|
58
|
-
|
59
|
+
cursor.chain.base.infer(api_map, block, locals)
|
59
60
|
end
|
60
61
|
|
61
62
|
# Get an array of all the locals that are visible from the cursors's
|
62
63
|
# position. Locals can be local variables, method parameters, or block
|
63
64
|
# parameters. The array starts with the nearest local pin.
|
64
65
|
#
|
65
|
-
# @return [Array<Solargraph::Pin::Base>]
|
66
|
+
# @return [::Array<Solargraph::Pin::Base>]
|
66
67
|
def locals
|
67
68
|
@locals ||= source_map.locals_at(location)
|
68
69
|
end
|
69
70
|
|
71
|
+
# @return [::Array<String>]
|
70
72
|
def gates
|
71
73
|
block.gates
|
72
74
|
end
|
@@ -99,11 +101,12 @@ module Solargraph
|
|
99
101
|
@source_map ||= api_map.source_map(cursor.filename)
|
100
102
|
end
|
101
103
|
|
104
|
+
# @return [Location]
|
102
105
|
def location
|
103
106
|
Location.new(source_map.filename, Solargraph::Range.new(cursor.position, cursor.position))
|
104
107
|
end
|
105
108
|
|
106
|
-
# @return [Solargraph::Pin::
|
109
|
+
# @return [Solargraph::Pin::Closure]
|
107
110
|
def block
|
108
111
|
@block ||= source_map.locate_block_pin(cursor.node_position.line, cursor.node_position.character)
|
109
112
|
end
|
@@ -115,22 +118,7 @@ module Solargraph
|
|
115
118
|
@context_pin ||= source_map.locate_named_path_pin(cursor.node_position.line, cursor.node_position.character)
|
116
119
|
end
|
117
120
|
|
118
|
-
# @return [Array<Pin::
|
119
|
-
def yielded_self_pins
|
120
|
-
return [] unless block.is_a?(Pin::Block) && block.receiver
|
121
|
-
chain = Parser.chain(block.receiver, source_map.source.filename)
|
122
|
-
receiver_pin = chain.define(api_map, context_pin, locals).first
|
123
|
-
return [] if receiver_pin.nil?
|
124
|
-
result = []
|
125
|
-
ys = receiver_pin.docstring.tag(:yieldpublic)
|
126
|
-
unless ys.nil? || ys.types.empty?
|
127
|
-
ysct = ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
|
128
|
-
result.concat api_map.get_complex_type_methods(ysct, '', false)
|
129
|
-
end
|
130
|
-
result
|
131
|
-
end
|
132
|
-
|
133
|
-
# @return [Array<Pin::KeywordParam]
|
121
|
+
# @return [Array<Pin::KeywordParam>]
|
134
122
|
def complete_keyword_parameters
|
135
123
|
return [] unless cursor.argument? && cursor.chain.links.one? && cursor.word =~ /^[a-z0-9_]*:?$/
|
136
124
|
pins = signify
|
@@ -154,7 +142,7 @@ module Solargraph
|
|
154
142
|
result
|
155
143
|
end
|
156
144
|
|
157
|
-
# @param result [
|
145
|
+
# @param result [Enumerable<Pin::Base>]
|
158
146
|
# @return [Completion]
|
159
147
|
def package_completions result
|
160
148
|
frag_start = cursor.start_of_word.to_s.downcase
|
@@ -165,6 +153,7 @@ module Solargraph
|
|
165
153
|
Completion.new(filtered, cursor.range)
|
166
154
|
end
|
167
155
|
|
156
|
+
# @return [Completion]
|
168
157
|
def tag_complete
|
169
158
|
result = []
|
170
159
|
match = source_map.code[0..cursor.offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
|
@@ -183,6 +172,7 @@ module Solargraph
|
|
183
172
|
package_completions(result)
|
184
173
|
end
|
185
174
|
|
175
|
+
# @return [Completion]
|
186
176
|
def code_complete
|
187
177
|
result = []
|
188
178
|
result.concat complete_keyword_parameters
|
@@ -224,14 +214,13 @@ module Solargraph
|
|
224
214
|
result.concat api_map.get_constants(context_pin.context.namespace, *gates)
|
225
215
|
result.concat api_map.get_methods(block.binder.namespace, scope: block.binder.scope, visibility: [:public, :private, :protected])
|
226
216
|
result.concat api_map.get_methods('Kernel')
|
227
|
-
# result.concat ApiMap.keywords
|
228
217
|
result.concat api_map.keyword_pins.to_a
|
229
|
-
result.concat yielded_self_pins
|
230
218
|
end
|
231
219
|
end
|
232
220
|
package_completions(result)
|
233
221
|
end
|
234
222
|
|
223
|
+
# @return [Array<Pin::Base>]
|
235
224
|
def file_global_methods
|
236
225
|
return [] if cursor.word.empty?
|
237
226
|
source_map.pins.select do |pin|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class SourceMap
|
5
|
+
class Data
|
6
|
+
def initialize source
|
7
|
+
@source = source
|
8
|
+
end
|
9
|
+
|
10
|
+
def pins
|
11
|
+
generate
|
12
|
+
@pins || []
|
13
|
+
end
|
14
|
+
|
15
|
+
def locals
|
16
|
+
generate
|
17
|
+
@locals || []
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def generate
|
23
|
+
return if @generated
|
24
|
+
|
25
|
+
@generated = true
|
26
|
+
@pins, @locals = Mapper.map(@source)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|