solargraph 0.59.0.dev.1 → 0.59.0.dev.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 +4 -1
- data/.github/workflows/rspec.yml +3 -14
- data/.gitignore +1 -0
- data/.rubocop.yml +32 -5
- data/.rubocop_todo.yml +37 -931
- data/CHANGELOG.md +7 -1
- data/Gemfile +3 -1
- data/Rakefile +25 -23
- data/bin/solargraph +2 -1
- data/lib/solargraph/api_map/index.rb +5 -11
- data/lib/solargraph/api_map/source_to_yard.rb +9 -8
- data/lib/solargraph/api_map/store.rb +22 -20
- data/lib/solargraph/api_map.rb +50 -37
- data/lib/solargraph/bench.rb +44 -45
- data/lib/solargraph/complex_type/type_methods.rb +12 -15
- data/lib/solargraph/complex_type/unique_type.rb +54 -43
- data/lib/solargraph/complex_type.rb +69 -61
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +4 -4
- data/lib/solargraph/convention/data_definition.rb +1 -1
- data/lib/solargraph/convention/gemfile.rb +15 -15
- data/lib/solargraph/convention/gemspec.rb +23 -23
- data/lib/solargraph/convention/rakefile.rb +17 -17
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -1
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +3 -3
- data/lib/solargraph/convention/struct_definition.rb +3 -3
- data/lib/solargraph/convention.rb +78 -78
- data/lib/solargraph/converters/dd.rb +19 -17
- data/lib/solargraph/converters/dl.rb +17 -15
- data/lib/solargraph/converters/dt.rb +17 -15
- data/lib/solargraph/converters/misc.rb +3 -1
- data/lib/solargraph/diagnostics/rubocop.rb +10 -10
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -3
- data/lib/solargraph/diagnostics/type_check.rb +10 -10
- data/lib/solargraph/diagnostics/update_errors.rb +37 -41
- data/lib/solargraph/doc_map.rb +9 -10
- data/lib/solargraph/equality.rb +3 -3
- data/lib/solargraph/gem_pins.rb +7 -5
- data/lib/solargraph/language_server/error_codes.rb +20 -20
- data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
- data/lib/solargraph/language_server/host/dispatch.rb +2 -3
- data/lib/solargraph/language_server/host/message_worker.rb +2 -2
- data/lib/solargraph/language_server/host/sources.rb +1 -1
- data/lib/solargraph/language_server/host.rb +24 -21
- data/lib/solargraph/language_server/message/base.rb +97 -97
- data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +10 -11
- data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
- data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
- data/lib/solargraph/language_server/message/extended/search.rb +20 -20
- data/lib/solargraph/language_server/message/initialize.rb +197 -191
- data/lib/solargraph/language_server/message/text_document/completion.rb +8 -8
- data/lib/solargraph/language_server/message/text_document/definition.rb +41 -34
- data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -21
- data/lib/solargraph/language_server/message/text_document/formatting.rb +6 -6
- data/lib/solargraph/language_server/message/text_document/hover.rb +3 -5
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
- data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
- data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +2 -2
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -19
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -19
- data/lib/solargraph/language_server/message.rb +94 -94
- data/lib/solargraph/language_server/request.rb +29 -27
- data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
- data/lib/solargraph/language_server/uri_helpers.rb +49 -49
- data/lib/solargraph/library.rb +28 -33
- data/lib/solargraph/location.rb +10 -12
- data/lib/solargraph/logging.rb +4 -4
- data/lib/solargraph/page.rb +92 -92
- data/lib/solargraph/parser/comment_ripper.rb +12 -4
- data/lib/solargraph/parser/flow_sensitive_typing.rb +32 -42
- data/lib/solargraph/parser/node_processor/base.rb +4 -4
- data/lib/solargraph/parser/node_processor.rb +1 -1
- data/lib/solargraph/parser/parser_gem/class_methods.rb +4 -4
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +20 -20
- data/lib/solargraph/parser/parser_gem/node_methods.rb +66 -65
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +12 -12
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +3 -5
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +118 -112
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem.rb +14 -12
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +25 -23
- data/lib/solargraph/pin/base.rb +78 -64
- data/lib/solargraph/pin/base_variable.rb +28 -71
- data/lib/solargraph/pin/block.rb +3 -2
- data/lib/solargraph/pin/breakable.rb +2 -0
- data/lib/solargraph/pin/callable.rb +23 -26
- data/lib/solargraph/pin/closure.rb +5 -4
- data/lib/solargraph/pin/common.rb +5 -2
- data/lib/solargraph/pin/compound_statement.rb +3 -3
- data/lib/solargraph/pin/constant.rb +43 -45
- data/lib/solargraph/pin/conversions.rb +9 -4
- data/lib/solargraph/pin/delegated_method.rb +4 -4
- data/lib/solargraph/pin/documenting.rb +3 -2
- data/lib/solargraph/pin/local_variable.rb +4 -4
- data/lib/solargraph/pin/method.rb +71 -70
- data/lib/solargraph/pin/namespace.rb +13 -12
- data/lib/solargraph/pin/parameter.rb +28 -27
- data/lib/solargraph/pin/proxy_type.rb +2 -0
- data/lib/solargraph/pin/reference.rb +17 -0
- data/lib/solargraph/pin/search.rb +2 -2
- data/lib/solargraph/pin/signature.rb +9 -14
- data/lib/solargraph/pin/symbol.rb +1 -0
- data/lib/solargraph/pin/until.rb +1 -3
- data/lib/solargraph/pin/while.rb +1 -3
- data/lib/solargraph/pin_cache.rb +16 -19
- data/lib/solargraph/position.rb +35 -17
- data/lib/solargraph/range.rb +10 -9
- data/lib/solargraph/rbs_map/conversions.rb +312 -206
- data/lib/solargraph/rbs_map/core_fills.rb +91 -84
- data/lib/solargraph/rbs_map/stdlib_map.rb +0 -1
- data/lib/solargraph/rbs_map.rb +3 -12
- data/lib/solargraph/server_methods.rb +16 -16
- data/lib/solargraph/shell.rb +63 -53
- data/lib/solargraph/source/chain/array.rb +39 -37
- data/lib/solargraph/source/chain/call.rb +49 -44
- data/lib/solargraph/source/chain/class_variable.rb +13 -13
- data/lib/solargraph/source/chain/constant.rb +3 -1
- data/lib/solargraph/source/chain/global_variable.rb +13 -13
- data/lib/solargraph/source/chain/hash.rb +8 -6
- data/lib/solargraph/source/chain/if.rb +11 -10
- data/lib/solargraph/source/chain/instance_variable.rb +3 -1
- data/lib/solargraph/source/chain/link.rb +99 -109
- data/lib/solargraph/source/chain/literal.rb +4 -6
- data/lib/solargraph/source/chain/or.rb +2 -4
- data/lib/solargraph/source/chain/q_call.rb +13 -11
- data/lib/solargraph/source/chain/variable.rb +15 -13
- data/lib/solargraph/source/chain/z_super.rb +28 -30
- data/lib/solargraph/source/chain.rb +24 -16
- data/lib/solargraph/source/change.rb +3 -3
- data/lib/solargraph/source/cursor.rb +18 -18
- data/lib/solargraph/source/encoding_fixes.rb +6 -7
- data/lib/solargraph/source/source_chainer.rb +46 -32
- data/lib/solargraph/source/updater.rb +1 -1
- data/lib/solargraph/source.rb +27 -29
- data/lib/solargraph/source_map/clip.rb +38 -30
- data/lib/solargraph/source_map/mapper.rb +52 -46
- data/lib/solargraph/source_map.rb +8 -4
- data/lib/solargraph/type_checker/rules.rb +8 -8
- data/lib/solargraph/type_checker.rb +95 -101
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +10 -9
- data/lib/solargraph/workspace/gemspecs.rb +1 -1
- data/lib/solargraph/workspace.rb +21 -44
- data/lib/solargraph/yard_map/helpers.rb +6 -2
- data/lib/solargraph/yard_map/mapper/to_method.rb +8 -6
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -1
- data/lib/solargraph/yard_map/mapper.rb +12 -12
- data/lib/solargraph/yard_tags.rb +20 -20
- data/lib/solargraph.rb +5 -5
- data/solargraph.gemspec +35 -34
- metadata +28 -28
|
@@ -1,30 +1,28 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class Source
|
|
5
|
-
class Chain
|
|
6
|
-
class ZSuper < Call
|
|
7
|
-
# @return [String]
|
|
8
|
-
attr_reader :word
|
|
9
|
-
|
|
10
|
-
# @return [::Array<Chain>]
|
|
11
|
-
attr_reader :arguments
|
|
12
|
-
|
|
13
|
-
# @param word [String]
|
|
14
|
-
# @param
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
# @param
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
end
|
|
30
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class Source
|
|
5
|
+
class Chain
|
|
6
|
+
class ZSuper < Call
|
|
7
|
+
# @return [String]
|
|
8
|
+
attr_reader :word
|
|
9
|
+
|
|
10
|
+
# @return [::Array<Chain>]
|
|
11
|
+
attr_reader :arguments
|
|
12
|
+
|
|
13
|
+
# @param word [String]
|
|
14
|
+
# @param with_block [Boolean] True if the chain is inside a block
|
|
15
|
+
def initialize word, with_block = false
|
|
16
|
+
super(word, nil, [], with_block)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @param api_map [ApiMap]
|
|
20
|
+
# @param name_pin [Pin::Base]
|
|
21
|
+
# @param locals [::Array<Pin::Base>]
|
|
22
|
+
def resolve api_map, name_pin, locals
|
|
23
|
+
super_pins(api_map, name_pin)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -48,11 +48,6 @@ module Solargraph
|
|
|
48
48
|
|
|
49
49
|
attr_reader :node
|
|
50
50
|
|
|
51
|
-
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
52
|
-
protected def equality_fields
|
|
53
|
-
[links, node]
|
|
54
|
-
end
|
|
55
|
-
|
|
56
51
|
# @param node [Parser::AST::Node, nil]
|
|
57
52
|
# @param links [::Array<Chain::Link>]
|
|
58
53
|
# @param splat [Boolean]
|
|
@@ -119,7 +114,9 @@ module Solargraph
|
|
|
119
114
|
pins = link.resolve(api_map, working_pin, locals)
|
|
120
115
|
type = infer_from_definitions(pins, working_pin, api_map, locals)
|
|
121
116
|
if type.undefined?
|
|
122
|
-
logger.debug
|
|
117
|
+
logger.debug do
|
|
118
|
+
"Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) => [] - undefined type from #{link.desc}"
|
|
119
|
+
end
|
|
123
120
|
return []
|
|
124
121
|
end
|
|
125
122
|
# We continue to use the context from the head pin, in case
|
|
@@ -128,7 +125,9 @@ module Solargraph
|
|
|
128
125
|
# for the binder, as this is chaining off of it, and the
|
|
129
126
|
# binder is now the lhs of the rhs we are evaluating.
|
|
130
127
|
working_pin = Pin::ProxyType.anonymous(name_pin.context, binder: type, closure: name_pin, source: :chain)
|
|
131
|
-
logger.debug
|
|
128
|
+
logger.debug do
|
|
129
|
+
"Chain#define(links=#{links.map(&:desc)}, name_pin=#{name_pin.inspect}, locals=#{locals}) - after processing #{link.desc}, new working_pin=#{working_pin} with binder #{working_pin.binder}"
|
|
130
|
+
end
|
|
132
131
|
end
|
|
133
132
|
links.last.last_context = working_pin
|
|
134
133
|
links.last.resolve(api_map, working_pin, locals)
|
|
@@ -150,7 +149,9 @@ module Solargraph
|
|
|
150
149
|
@@inference_cache = {}
|
|
151
150
|
end
|
|
152
151
|
out = infer_uncached(api_map, name_pin, locals).downcast_to_literal_if_possible
|
|
153
|
-
logger.debug
|
|
152
|
+
logger.debug do
|
|
153
|
+
"Chain#infer() - caching result - cache_key_hash=#{cache_key.hash}, links.map(&:hash)=#{links.map(&:hash)}, links=#{links}, cache_key.map(&:hash) = #{cache_key.map(&:hash)}, cache_key=#{cache_key}"
|
|
154
|
+
end
|
|
154
155
|
@@inference_cache[cache_key] = out
|
|
155
156
|
end
|
|
156
157
|
|
|
@@ -161,12 +162,16 @@ module Solargraph
|
|
|
161
162
|
def infer_uncached api_map, name_pin, locals
|
|
162
163
|
pins = define(api_map, name_pin, locals)
|
|
163
164
|
if pins.empty?
|
|
164
|
-
logger.debug
|
|
165
|
+
logger.debug do
|
|
166
|
+
"Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}) => undefined - no pins"
|
|
167
|
+
end
|
|
165
168
|
return ComplexType::UNDEFINED
|
|
166
169
|
end
|
|
167
170
|
type = infer_from_definitions(pins, links.last.last_context, api_map, locals)
|
|
168
171
|
out = maybe_nil(type)
|
|
169
|
-
logger.debug
|
|
172
|
+
logger.debug do
|
|
173
|
+
"Chain#infer_uncached(links=#{links.map(&:desc)}, locals=#{locals.map(&:desc)}, name_pin=#{name_pin}, name_pin.closure=#{name_pin.closure.inspect}, name_pin.binder=#{name_pin.binder}) => #{out.rooted_tags.inspect}"
|
|
174
|
+
end
|
|
170
175
|
out
|
|
171
176
|
end
|
|
172
177
|
|
|
@@ -245,17 +250,13 @@ module Solargraph
|
|
|
245
250
|
end
|
|
246
251
|
|
|
247
252
|
# Limit method inference recursion
|
|
248
|
-
if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
|
|
249
|
-
return ComplexType::UNDEFINED
|
|
250
|
-
end
|
|
253
|
+
return ComplexType::UNDEFINED if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
|
|
251
254
|
|
|
252
255
|
@@inference_depth += 1
|
|
253
256
|
# @param pin [Pin::Base]
|
|
254
257
|
unresolved_pins.each do |pin|
|
|
255
258
|
# Avoid infinite recursion
|
|
256
|
-
if @@inference_stack.include?(pin.identity)
|
|
257
|
-
next
|
|
258
|
-
end
|
|
259
|
+
next if @@inference_stack.include?(pin.identity)
|
|
259
260
|
|
|
260
261
|
@@inference_stack.push(pin.identity)
|
|
261
262
|
type = pin.probe(api_map)
|
|
@@ -289,6 +290,13 @@ module Solargraph
|
|
|
289
290
|
return type unless nullable?
|
|
290
291
|
ComplexType.new(type.items + [ComplexType::NIL])
|
|
291
292
|
end
|
|
293
|
+
|
|
294
|
+
protected
|
|
295
|
+
|
|
296
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
297
|
+
def equality_fields
|
|
298
|
+
[links, node]
|
|
299
|
+
end
|
|
292
300
|
end
|
|
293
301
|
end
|
|
294
302
|
end
|
|
@@ -28,7 +28,7 @@ module Solargraph
|
|
|
28
28
|
# syntax errors will be repaired.
|
|
29
29
|
# @return [String] The updated text.
|
|
30
30
|
def write text, nullable = false
|
|
31
|
-
if nullable
|
|
31
|
+
if nullable && !range.nil? && new_text.match(/[.\[{(@$:]$/)
|
|
32
32
|
[':', '@'].each do |dupable|
|
|
33
33
|
next unless new_text == dupable
|
|
34
34
|
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
@@ -66,7 +66,7 @@ module Solargraph
|
|
|
66
66
|
match = result[0, off].match(/[.:]+\z/)
|
|
67
67
|
if match
|
|
68
68
|
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
69
|
-
result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off
|
|
69
|
+
result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..]
|
|
70
70
|
end
|
|
71
71
|
result
|
|
72
72
|
end
|
|
@@ -82,7 +82,7 @@ module Solargraph
|
|
|
82
82
|
start_offset = Position.to_offset(text, range.start)
|
|
83
83
|
# @sg-ignore Need to add nil check here
|
|
84
84
|
end_offset = Position.to_offset(text, range.ending)
|
|
85
|
-
(start_offset
|
|
85
|
+
(start_offset.zero? ? '' : text[0..(start_offset - 1)].to_s) + normalize(insert) + text[end_offset..].to_s
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
88
|
end
|
|
@@ -39,11 +39,13 @@ module Solargraph
|
|
|
39
39
|
# @return [String]
|
|
40
40
|
def start_of_word
|
|
41
41
|
@start_of_word ||= begin
|
|
42
|
-
match = source.code[0..offset-1].to_s.match(start_word_pattern)
|
|
42
|
+
match = source.code[0..(offset - 1)].to_s.match(start_word_pattern)
|
|
43
43
|
result = (match ? match[0] : '')
|
|
44
44
|
# Including the preceding colon if the word appears to be a symbol
|
|
45
45
|
# @sg-ignore Need to add nil check here
|
|
46
|
-
|
|
46
|
+
if source.code[0..(offset - result.length - 1)].end_with?(':') && !source.code[0..(offset - result.length - 1)].end_with?('::')
|
|
47
|
+
result = ":#{result}"
|
|
48
|
+
end
|
|
47
49
|
result
|
|
48
50
|
end
|
|
49
51
|
end
|
|
@@ -55,14 +57,14 @@ module Solargraph
|
|
|
55
57
|
# @sg-ignore Need to add nil check here
|
|
56
58
|
def end_of_word
|
|
57
59
|
@end_of_word ||= begin
|
|
58
|
-
match = source.code[offset
|
|
60
|
+
match = source.code[offset..].to_s.match(end_word_pattern)
|
|
59
61
|
match ? match[0] : ''
|
|
60
62
|
end
|
|
61
63
|
end
|
|
62
64
|
|
|
63
65
|
# @return [Boolean]
|
|
64
66
|
def start_of_constant?
|
|
65
|
-
source.code[offset-2, 2] == '::'
|
|
67
|
+
source.code[offset - 2, 2] == '::'
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
# The range of the word at the current position.
|
|
@@ -126,20 +128,18 @@ module Solargraph
|
|
|
126
128
|
|
|
127
129
|
# @return [Position]
|
|
128
130
|
def node_position
|
|
129
|
-
@node_position ||=
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
end
|
|
142
|
-
end
|
|
131
|
+
@node_position ||= if start_of_word.empty?
|
|
132
|
+
# @sg-ignore Need to add nil check here
|
|
133
|
+
match = source.code[0, offset].match(/\s*(\.|:+)\s*$/)
|
|
134
|
+
if match
|
|
135
|
+
# @sg-ignore Need to add nil check here
|
|
136
|
+
Position.from_offset(source.code, offset - match[0].length)
|
|
137
|
+
else
|
|
138
|
+
position
|
|
139
|
+
end
|
|
140
|
+
else
|
|
141
|
+
position
|
|
142
|
+
end
|
|
143
143
|
end
|
|
144
144
|
|
|
145
145
|
# @return [Parser::AST::Node, nil]
|
|
@@ -10,13 +10,12 @@ module Solargraph
|
|
|
10
10
|
# @param string [String]
|
|
11
11
|
# @return [String]
|
|
12
12
|
def normalize string
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
end
|
|
13
|
+
string.dup.force_encoding('UTF-8')
|
|
14
|
+
rescue ::Encoding::CompatibilityError, ::Encoding::UndefinedConversionError,
|
|
15
|
+
::Encoding::InvalidByteSequenceError => e
|
|
16
|
+
# @todo Improve error handling
|
|
17
|
+
Solargraph::Logging.logger.warn "Normalize error: #{e.message}"
|
|
18
|
+
string
|
|
20
19
|
end
|
|
21
20
|
end
|
|
22
21
|
end
|
|
@@ -32,10 +32,22 @@ module Solargraph
|
|
|
32
32
|
# @return [Source::Chain]
|
|
33
33
|
def chain
|
|
34
34
|
# Special handling for files that end with an integer and a period
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
if phrase =~ /^[0-9]+\.$/
|
|
36
|
+
return Chain.new([Chain::Literal.new('Integer', Integer(phrase[0..-2])),
|
|
37
|
+
Chain::UNDEFINED_CALL])
|
|
38
|
+
end
|
|
39
|
+
if phrase.start_with?(':') && !phrase.start_with?('::')
|
|
40
|
+
return Chain.new([Chain::Literal.new('Symbol',
|
|
41
|
+
# @sg-ignore Need to add nil check here
|
|
42
|
+
phrase[1..].to_sym)])
|
|
43
|
+
end
|
|
44
|
+
if end_of_phrase.strip == '::' && source.code[Position.to_offset(
|
|
45
|
+
source.code, position
|
|
46
|
+
)].to_s.match?(/[a-z]/i)
|
|
47
|
+
return SourceChainer.chain(source,
|
|
48
|
+
Position.new(position.line,
|
|
49
|
+
position.character + 1))
|
|
50
|
+
end
|
|
39
51
|
begin
|
|
40
52
|
return Chain.new([]) if phrase.end_with?('..')
|
|
41
53
|
# @type [::Parser::AST::Node, nil]
|
|
@@ -52,7 +64,12 @@ module Solargraph
|
|
|
52
64
|
elsif source.repaired?
|
|
53
65
|
node = Parser.parse(fixed_phrase, source.filename, fixed_position.line)
|
|
54
66
|
else
|
|
55
|
-
|
|
67
|
+
unless source.error_ranges.any? do |r|
|
|
68
|
+
r.nil? || r.include?(fixed_position)
|
|
69
|
+
end
|
|
70
|
+
node, parent = source.tree_at(fixed_position.line,
|
|
71
|
+
fixed_position.column)[0..2]
|
|
72
|
+
end
|
|
56
73
|
# Exception for positions that chain literal nodes in unsynchronized sources
|
|
57
74
|
node = nil unless source.synchronized? || !Parser.infer_literal_node_type(node).nil?
|
|
58
75
|
node = Parser.parse(fixed_phrase, source.filename, fixed_position.line) if node.nil?
|
|
@@ -86,13 +103,13 @@ module Solargraph
|
|
|
86
103
|
# @sg-ignore Need to add nil check here
|
|
87
104
|
# @return [String]
|
|
88
105
|
def phrase
|
|
89
|
-
@phrase ||= source.code[signature_data..offset-1]
|
|
106
|
+
@phrase ||= source.code[signature_data..(offset - 1)]
|
|
90
107
|
end
|
|
91
108
|
|
|
92
109
|
# @sg-ignore Need to add nil check here
|
|
93
110
|
# @return [String]
|
|
94
111
|
def fixed_phrase
|
|
95
|
-
@fixed_phrase ||= phrase[0..-(end_of_phrase.length+1)]
|
|
112
|
+
@fixed_phrase ||= phrase[0..-(end_of_phrase.length + 1)]
|
|
96
113
|
end
|
|
97
114
|
|
|
98
115
|
# @return [Position]
|
|
@@ -144,50 +161,47 @@ module Solargraph
|
|
|
144
161
|
brackets = 0
|
|
145
162
|
squares = 0
|
|
146
163
|
parens = 0
|
|
147
|
-
index -=1
|
|
164
|
+
index -= 1
|
|
148
165
|
in_whitespace = false
|
|
149
166
|
while index >= 0
|
|
150
167
|
pos = Position.from_offset(@source.code, index)
|
|
151
|
-
break if index
|
|
152
|
-
break if brackets
|
|
168
|
+
break if index.positive? && @source.comment_at?(pos)
|
|
169
|
+
break if brackets.positive? || parens.positive? || squares.positive?
|
|
153
170
|
char = @source.code[index, 1]
|
|
154
171
|
break if char.nil? # @todo Is this the right way to handle this?
|
|
155
|
-
if brackets.zero?
|
|
172
|
+
if brackets.zero? && parens.zero? && squares.zero? && [' ', "\r", "\n", "\t"].include?(char)
|
|
156
173
|
in_whitespace = true
|
|
157
174
|
else
|
|
158
|
-
|
|
175
|
+
# @sg-ignore Need to add nil check here
|
|
176
|
+
if brackets.zero? && parens.zero? && squares.zero? && in_whitespace && !((char == '.') || @source.code[(index + 1)..].strip.start_with?('.'))
|
|
177
|
+
@source.code[(index + 1)..]
|
|
159
178
|
# @sg-ignore Need to add nil check here
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
# @sg-ignore Need to add nil check here
|
|
165
|
-
index += (@source.code[index+1..-1].length - @source.code[index+1..-1].lstrip.length)
|
|
166
|
-
break
|
|
167
|
-
end
|
|
179
|
+
@source.code[(index + 1)..].lstrip
|
|
180
|
+
# @sg-ignore Need to add nil check here
|
|
181
|
+
index += (@source.code[(index + 1)..].length - @source.code[(index + 1)..].lstrip.length)
|
|
182
|
+
break
|
|
168
183
|
end
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
184
|
+
case char
|
|
185
|
+
when ')'
|
|
186
|
+
parens -= 1
|
|
187
|
+
when ']'
|
|
188
|
+
squares -= 1
|
|
189
|
+
when '}'
|
|
174
190
|
brackets -= 1
|
|
175
|
-
|
|
191
|
+
when '('
|
|
176
192
|
parens += 1
|
|
177
|
-
|
|
193
|
+
when '{'
|
|
178
194
|
brackets += 1
|
|
179
|
-
|
|
195
|
+
when '['
|
|
180
196
|
squares += 1
|
|
181
197
|
end
|
|
182
|
-
if brackets.zero?
|
|
198
|
+
if brackets.zero? && parens.zero? && squares.zero?
|
|
183
199
|
break if ['"', "'", ',', ';', '%'].include?(char)
|
|
184
200
|
break if ['!', '?'].include?(char) && index < offset - 1
|
|
185
201
|
break if char == '$'
|
|
186
202
|
if char == '@'
|
|
187
203
|
index -= 1
|
|
188
|
-
if @source.code[index, 1] == '@'
|
|
189
|
-
index -= 1
|
|
190
|
-
end
|
|
204
|
+
index -= 1 if @source.code[index, 1] == '@'
|
|
191
205
|
break
|
|
192
206
|
end
|
|
193
207
|
elsif parens == 1 || brackets == 1 || squares == 1
|
|
@@ -33,7 +33,7 @@ module Solargraph
|
|
|
33
33
|
# @return [String]
|
|
34
34
|
def write text, nullable = false
|
|
35
35
|
can_nullify = (nullable and changes.length == 1)
|
|
36
|
-
return @output if @input == text
|
|
36
|
+
return @output if (@input == text) && (can_nullify == @did_nullify)
|
|
37
37
|
@input = text
|
|
38
38
|
@output = text
|
|
39
39
|
@did_nullify = can_nullify
|
data/lib/solargraph/source.rb
CHANGED
|
@@ -66,7 +66,7 @@ module Solargraph
|
|
|
66
66
|
def from_to l1, c1, l2, c2
|
|
67
67
|
b = Solargraph::Position.line_char_to_offset(code, l1, c1)
|
|
68
68
|
e = Solargraph::Position.line_char_to_offset(code, l2, c2)
|
|
69
|
-
code[b..e-1]
|
|
69
|
+
code[b..(e - 1)]
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
# Get the nearest node that contains the specified index.
|
|
@@ -74,7 +74,7 @@ module Solargraph
|
|
|
74
74
|
# @param line [Integer]
|
|
75
75
|
# @param column [Integer]
|
|
76
76
|
# @return [AST::Node]
|
|
77
|
-
def node_at
|
|
77
|
+
def node_at line, column
|
|
78
78
|
tree_at(line, column).first
|
|
79
79
|
end
|
|
80
80
|
|
|
@@ -84,7 +84,7 @@ module Solargraph
|
|
|
84
84
|
# @param line [Integer]
|
|
85
85
|
# @param column [Integer]
|
|
86
86
|
# @return [Array<Parser::AST::Node>]
|
|
87
|
-
def tree_at
|
|
87
|
+
def tree_at line, column
|
|
88
88
|
position = Position.new(line, column)
|
|
89
89
|
stack = []
|
|
90
90
|
inner_tree_at node, position, stack
|
|
@@ -140,7 +140,7 @@ module Solargraph
|
|
|
140
140
|
# @sg-ignore Need to add nil check here
|
|
141
141
|
return true if node.type == :str && range.include?(position) && range.start != position
|
|
142
142
|
# @sg-ignore Need to add nil check here
|
|
143
|
-
return true if [
|
|
143
|
+
return true if %i[STR str].include?(node.type) && range.include?(position) && range.start != position
|
|
144
144
|
if node.type == :dstr
|
|
145
145
|
inner = node_at(position.line, position.column)
|
|
146
146
|
next if inner.nil?
|
|
@@ -151,7 +151,7 @@ module Solargraph
|
|
|
151
151
|
# @sg-ignore Need to add nil check here
|
|
152
152
|
inner_code = at(Solargraph::Range.new(inner_range.start, position))
|
|
153
153
|
# @sg-ignore Need to add nil check here
|
|
154
|
-
return true if (inner.type == :dstr && inner_range.ending.character <= position.character
|
|
154
|
+
return true if (inner.type == :dstr && inner_range.ending.character <= position.character && !inner_code.end_with?('}')) ||
|
|
155
155
|
# @sg-ignore Need to add nil check here
|
|
156
156
|
(inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
|
|
157
157
|
end
|
|
@@ -171,7 +171,7 @@ module Solargraph
|
|
|
171
171
|
def comment_at? position
|
|
172
172
|
comment_ranges.each do |range|
|
|
173
173
|
return true if range.include?(position) ||
|
|
174
|
-
|
|
174
|
+
(range.ending.line == position.line && range.ending.column < position.column)
|
|
175
175
|
break if range.ending.line > position.line
|
|
176
176
|
end
|
|
177
177
|
false
|
|
@@ -190,13 +190,13 @@ module Solargraph
|
|
|
190
190
|
|
|
191
191
|
# @param node [Parser::AST::Node]
|
|
192
192
|
# @return [String]
|
|
193
|
-
def code_for
|
|
193
|
+
def code_for node
|
|
194
194
|
rng = Range.from_node(node)
|
|
195
195
|
# @sg-ignore Need to add nil check here
|
|
196
196
|
b = Position.line_char_to_offset(code, rng.start.line, rng.start.column)
|
|
197
197
|
# @sg-ignore Need to add nil check here
|
|
198
198
|
e = Position.line_char_to_offset(code, rng.ending.line, rng.ending.column)
|
|
199
|
-
frag = code[b..e-1].to_s
|
|
199
|
+
frag = code[b..(e - 1)].to_s
|
|
200
200
|
frag.strip.gsub(/,$/, '')
|
|
201
201
|
end
|
|
202
202
|
|
|
@@ -224,8 +224,8 @@ module Solargraph
|
|
|
224
224
|
end
|
|
225
225
|
|
|
226
226
|
FOLDING_NODE_TYPES = %i[
|
|
227
|
-
|
|
228
|
-
|
|
227
|
+
class sclass module def defs if str dstr array while unless kwbegin hash block
|
|
228
|
+
].freeze
|
|
229
229
|
|
|
230
230
|
# Get an array of ranges that can be folded, e.g., the range of a class
|
|
231
231
|
# definition or an if condition.
|
|
@@ -293,9 +293,8 @@ module Solargraph
|
|
|
293
293
|
# @sg-ignore Translate to something flow sensitive typing understands
|
|
294
294
|
range = Range.from_node(top)
|
|
295
295
|
# @sg-ignore Need to add nil check here
|
|
296
|
-
if result.empty? || range.start.line > result.last.start.line
|
|
297
|
-
|
|
298
|
-
result.push range unless range.ending.line - range.start.line < 2
|
|
296
|
+
if (result.empty? || range.start.line > result.last.start.line) && range.ending.line - range.start.line >= 2
|
|
297
|
+
result.push range
|
|
299
298
|
end
|
|
300
299
|
end
|
|
301
300
|
# @sg-ignore Translate to something flow sensitive typing understands
|
|
@@ -312,7 +311,7 @@ module Solargraph
|
|
|
312
311
|
ctxt = String.new('')
|
|
313
312
|
started = false
|
|
314
313
|
skip = nil
|
|
315
|
-
comments.lines.each
|
|
314
|
+
comments.lines.each do |l|
|
|
316
315
|
# Trim the comment and minimum leading whitespace
|
|
317
316
|
p = l.force_encoding('UTF-8').encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#+/, '')
|
|
318
317
|
if p.strip.empty?
|
|
@@ -322,10 +321,10 @@ module Solargraph
|
|
|
322
321
|
here = p.index(/[^ \t]/)
|
|
323
322
|
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
324
323
|
skip = here if skip.nil? || here < skip
|
|
325
|
-
ctxt.concat p[skip
|
|
324
|
+
ctxt.concat p[skip..]
|
|
326
325
|
end
|
|
327
326
|
started = true
|
|
328
|
-
|
|
327
|
+
end
|
|
329
328
|
ctxt
|
|
330
329
|
end
|
|
331
330
|
|
|
@@ -354,7 +353,7 @@ module Solargraph
|
|
|
354
353
|
return [] unless synchronized?
|
|
355
354
|
result = []
|
|
356
355
|
grouped = []
|
|
357
|
-
comments.
|
|
356
|
+
comments.each_key do |l|
|
|
358
357
|
if grouped.empty? || l == grouped.last + 1
|
|
359
358
|
grouped.push l
|
|
360
359
|
else
|
|
@@ -372,11 +371,11 @@ module Solargraph
|
|
|
372
371
|
result = []
|
|
373
372
|
if Parser.is_ast_node?(n)
|
|
374
373
|
# @sg-ignore Translate to something flow sensitive typing understands
|
|
375
|
-
if
|
|
374
|
+
if %i[str dstr STR DSTR].include?(n.type)
|
|
376
375
|
result.push n
|
|
377
376
|
else
|
|
378
377
|
# @sg-ignore Translate to something flow sensitive typing understands
|
|
379
|
-
n.children.each{ |c| result.concat string_nodes_in(c) }
|
|
378
|
+
n.children.each { |c| result.concat string_nodes_in(c) }
|
|
380
379
|
end
|
|
381
380
|
end
|
|
382
381
|
result
|
|
@@ -390,13 +389,12 @@ module Solargraph
|
|
|
390
389
|
return if node.nil?
|
|
391
390
|
here = Range.from_node(node)
|
|
392
391
|
# @sg-ignore Need to add nil check here
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
end
|
|
392
|
+
return unless here.contain?(position)
|
|
393
|
+
stack.unshift node
|
|
394
|
+
node.children.each do |c|
|
|
395
|
+
next unless Parser.is_ast_node?(c)
|
|
396
|
+
next if c.loc.expression.nil?
|
|
397
|
+
inner_tree_at(c, position, stack)
|
|
400
398
|
end
|
|
401
399
|
end
|
|
402
400
|
|
|
@@ -425,7 +423,7 @@ module Solargraph
|
|
|
425
423
|
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename, 0)
|
|
426
424
|
@parsed = true
|
|
427
425
|
@repaired = @code
|
|
428
|
-
rescue Parser::SyntaxError, EncodingError
|
|
426
|
+
rescue Parser::SyntaxError, EncodingError
|
|
429
427
|
@node = nil
|
|
430
428
|
@comments = {}
|
|
431
429
|
@parsed = false
|
|
@@ -440,7 +438,7 @@ module Solargraph
|
|
|
440
438
|
begin
|
|
441
439
|
@node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename, 0)
|
|
442
440
|
@parsed = true
|
|
443
|
-
rescue Parser::SyntaxError, EncodingError
|
|
441
|
+
rescue Parser::SyntaxError, EncodingError
|
|
444
442
|
@node = nil
|
|
445
443
|
@comments = {}
|
|
446
444
|
@parsed = false
|
|
@@ -453,7 +451,7 @@ module Solargraph
|
|
|
453
451
|
|
|
454
452
|
# @param val [String]
|
|
455
453
|
# @return [String]
|
|
456
|
-
def code=
|
|
454
|
+
def code= val
|
|
457
455
|
@code_lines = nil
|
|
458
456
|
@finalized = false
|
|
459
457
|
@code = val
|