solargraph 0.58.2 → 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/.envrc +3 -0
- data/.github/workflows/linting.yml +4 -5
- data/.github/workflows/plugins.yml +41 -34
- data/.github/workflows/rspec.yml +44 -23
- data/.github/workflows/typecheck.yml +2 -2
- data/.rubocop.yml +32 -5
- data/.rubocop_todo.yml +50 -966
- data/Gemfile +3 -1
- data/README.md +3 -3
- data/Rakefile +26 -23
- data/bin/solargraph +2 -1
- data/lib/solargraph/api_map/cache.rb +3 -3
- data/lib/solargraph/api_map/constants.rb +13 -3
- data/lib/solargraph/api_map/index.rb +23 -18
- data/lib/solargraph/api_map/source_to_yard.rb +22 -9
- data/lib/solargraph/api_map/store.rb +33 -28
- data/lib/solargraph/api_map.rb +150 -82
- data/lib/solargraph/bench.rb +44 -45
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +28 -17
- data/lib/solargraph/complex_type/unique_type.rb +218 -57
- data/lib/solargraph/complex_type.rb +170 -57
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
- data/lib/solargraph/convention/data_definition.rb +5 -2
- 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 +2 -1
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
- data/lib/solargraph/convention/struct_definition.rb +8 -4
- 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/require_not_found.rb +1 -0
- data/lib/solargraph/diagnostics/rubocop.rb +11 -10
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
- data/lib/solargraph/diagnostics/type_check.rb +11 -10
- data/lib/solargraph/diagnostics/update_errors.rb +37 -41
- data/lib/solargraph/doc_map.rb +133 -373
- data/lib/solargraph/equality.rb +4 -4
- data/lib/solargraph/gem_pins.rb +21 -20
- data/lib/solargraph/language_server/error_codes.rb +20 -20
- data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
- data/lib/solargraph/language_server/host/dispatch.rb +3 -3
- data/lib/solargraph/language_server/host/message_worker.rb +4 -3
- data/lib/solargraph/language_server/host/sources.rb +2 -1
- data/lib/solargraph/language_server/host.rb +30 -22
- 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 +12 -18
- data/lib/solargraph/language_server/message/extended/document.rb +1 -0
- 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 +10 -8
- data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
- 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 -19
- data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
- data/lib/solargraph/language_server/message/text_document/hover.rb +5 -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 +3 -2
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
- 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 -17
- 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 +85 -44
- data/lib/solargraph/location.rb +17 -14
- data/lib/solargraph/logging.rb +24 -4
- data/lib/solargraph/page.rb +92 -92
- data/lib/solargraph/parser/comment_ripper.rb +19 -4
- data/lib/solargraph/parser/flow_sensitive_typing.rb +326 -108
- data/lib/solargraph/parser/node_processor/base.rb +34 -4
- data/lib/solargraph/parser/node_processor.rb +8 -7
- data/lib/solargraph/parser/parser_gem/class_methods.rb +32 -14
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
- data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +12 -12
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -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 +36 -6
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
- data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
- data/lib/solargraph/parser/parser_gem.rb +14 -12
- data/lib/solargraph/parser/region.rb +9 -3
- data/lib/solargraph/parser/snippet.rb +3 -1
- data/lib/solargraph/parser.rb +25 -23
- data/lib/solargraph/pin/base.rb +126 -80
- data/lib/solargraph/pin/base_variable.rb +273 -24
- data/lib/solargraph/pin/block.rb +29 -6
- data/lib/solargraph/pin/breakable.rb +7 -1
- data/lib/solargraph/pin/callable.rb +65 -21
- data/lib/solargraph/pin/closure.rb +7 -10
- data/lib/solargraph/pin/common.rb +24 -6
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/constant.rb +43 -45
- data/lib/solargraph/pin/conversions.rb +10 -4
- data/lib/solargraph/pin/delegated_method.rb +19 -8
- data/lib/solargraph/pin/documenting.rb +4 -2
- data/lib/solargraph/pin/instance_variable.rb +5 -1
- data/lib/solargraph/pin/keyword.rb +0 -4
- data/lib/solargraph/pin/local_variable.rb +15 -59
- data/lib/solargraph/pin/method.rb +153 -104
- data/lib/solargraph/pin/method_alias.rb +8 -0
- data/lib/solargraph/pin/namespace.rb +19 -12
- data/lib/solargraph/pin/parameter.rb +100 -36
- data/lib/solargraph/pin/proxy_type.rb +4 -1
- data/lib/solargraph/pin/reference/override.rb +1 -1
- data/lib/solargraph/pin/reference/superclass.rb +2 -0
- data/lib/solargraph/pin/reference.rb +19 -0
- data/lib/solargraph/pin/search.rb +3 -2
- data/lib/solargraph/pin/signature.rb +15 -12
- data/lib/solargraph/pin/symbol.rb +2 -1
- data/lib/solargraph/pin/until.rb +2 -4
- data/lib/solargraph/pin/while.rb +2 -4
- data/lib/solargraph/pin.rb +2 -0
- data/lib/solargraph/pin_cache.rb +490 -73
- data/lib/solargraph/position.rb +14 -10
- data/lib/solargraph/range.rb +16 -15
- data/lib/solargraph/rbs_map/conversions.rb +343 -214
- data/lib/solargraph/rbs_map/core_fills.rb +91 -84
- data/lib/solargraph/rbs_map/core_map.rb +24 -17
- data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
- data/lib/solargraph/rbs_map.rb +77 -32
- data/lib/solargraph/server_methods.rb +16 -16
- data/lib/solargraph/shell.rb +128 -73
- data/lib/solargraph/source/chain/array.rb +39 -37
- data/lib/solargraph/source/chain/call.rb +96 -56
- data/lib/solargraph/source/chain/class_variable.rb +13 -13
- data/lib/solargraph/source/chain/constant.rb +5 -1
- data/lib/solargraph/source/chain/global_variable.rb +13 -13
- data/lib/solargraph/source/chain/hash.rb +8 -5
- data/lib/solargraph/source/chain/if.rb +12 -10
- data/lib/solargraph/source/chain/instance_variable.rb +24 -1
- data/lib/solargraph/source/chain/link.rb +99 -109
- data/lib/solargraph/source/chain/literal.rb +9 -6
- data/lib/solargraph/source/chain/or.rb +10 -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 +49 -38
- data/lib/solargraph/source/change.rb +12 -5
- data/lib/solargraph/source/cursor.rb +23 -17
- data/lib/solargraph/source/encoding_fixes.rb +6 -7
- data/lib/solargraph/source/source_chainer.rb +56 -32
- data/lib/solargraph/source/updater.rb +5 -1
- data/lib/solargraph/source.rb +59 -35
- data/lib/solargraph/source_map/clip.rb +48 -29
- data/lib/solargraph/source_map/data.rb +4 -1
- data/lib/solargraph/source_map/mapper.rb +71 -42
- data/lib/solargraph/source_map.rb +21 -9
- data/lib/solargraph/type_checker/problem.rb +3 -1
- data/lib/solargraph/type_checker/rules.rb +81 -8
- data/lib/solargraph/type_checker.rb +195 -120
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +13 -10
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +1 -0
- data/lib/solargraph/workspace.rb +149 -30
- data/lib/solargraph/yard_map/helpers.rb +8 -3
- data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
- data/lib/solargraph/yard_map/mapper.rb +13 -8
- data/lib/solargraph/yard_tags.rb +20 -20
- data/lib/solargraph/yardoc.rb +33 -23
- data/lib/solargraph.rb +29 -8
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/fills/tuple/tuple.rbs +28 -0
- data/rbs/shims/ast/0/node.rbs +1 -1
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/solargraph.gemspec +36 -34
- metadata +38 -33
- data/lib/solargraph/type_checker/checks.rb +0 -124
- data/lib/solargraph/type_checker/param_def.rb +0 -37
- data/lib/solargraph/yard_map/to_method.rb +0 -89
|
@@ -19,7 +19,7 @@ module Solargraph
|
|
|
19
19
|
@position = Position.normalize(position)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
# @return [String]
|
|
22
|
+
# @return [String, nil]
|
|
23
23
|
def filename
|
|
24
24
|
source.filename
|
|
25
25
|
end
|
|
@@ -35,13 +35,17 @@ module Solargraph
|
|
|
35
35
|
# The part of the word before the current position. Given the text
|
|
36
36
|
# `foo.bar`, the start_of_word at position(0, 6) is `ba`.
|
|
37
37
|
#
|
|
38
|
+
# @sg-ignore Need to add nil check here
|
|
38
39
|
# @return [String]
|
|
39
40
|
def start_of_word
|
|
40
41
|
@start_of_word ||= begin
|
|
41
|
-
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)
|
|
42
43
|
result = (match ? match[0] : '')
|
|
43
44
|
# Including the preceding colon if the word appears to be a symbol
|
|
44
|
-
|
|
45
|
+
# @sg-ignore Need to add nil check here
|
|
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
|
|
45
49
|
result
|
|
46
50
|
end
|
|
47
51
|
end
|
|
@@ -50,16 +54,17 @@ module Solargraph
|
|
|
50
54
|
# `foo.bar`, the end_of_word at position (0,6) is `r`.
|
|
51
55
|
#
|
|
52
56
|
# @return [String]
|
|
57
|
+
# @sg-ignore Need to add nil check here
|
|
53
58
|
def end_of_word
|
|
54
59
|
@end_of_word ||= begin
|
|
55
|
-
match = source.code[offset
|
|
60
|
+
match = source.code[offset..].to_s.match(end_word_pattern)
|
|
56
61
|
match ? match[0] : ''
|
|
57
62
|
end
|
|
58
63
|
end
|
|
59
64
|
|
|
60
65
|
# @return [Boolean]
|
|
61
66
|
def start_of_constant?
|
|
62
|
-
source.code[offset-2, 2] == '::'
|
|
67
|
+
source.code[offset - 2, 2] == '::'
|
|
63
68
|
end
|
|
64
69
|
|
|
65
70
|
# The range of the word at the current position.
|
|
@@ -110,6 +115,7 @@ module Solargraph
|
|
|
110
115
|
def recipient
|
|
111
116
|
@recipient ||= begin
|
|
112
117
|
node = recipient_node
|
|
118
|
+
# @sg-ignore Need to add nil check here
|
|
113
119
|
node ? Cursor.new(source, Range.from_node(node).ending) : nil
|
|
114
120
|
end
|
|
115
121
|
end
|
|
@@ -122,18 +128,18 @@ module Solargraph
|
|
|
122
128
|
|
|
123
129
|
# @return [Position]
|
|
124
130
|
def node_position
|
|
125
|
-
@node_position ||=
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
|
137
143
|
end
|
|
138
144
|
|
|
139
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,26 +32,47 @@ 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
|
-
|
|
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
|
|
38
51
|
begin
|
|
39
52
|
return Chain.new([]) if phrase.end_with?('..')
|
|
53
|
+
# @type [::Parser::AST::Node, nil]
|
|
40
54
|
node = nil
|
|
55
|
+
# @type [::Parser::AST::Node, nil]
|
|
41
56
|
parent = nil
|
|
42
57
|
if !source.repaired? && source.parsed? && source.synchronized?
|
|
43
58
|
tree = source.tree_at(position.line, position.column)
|
|
44
59
|
node, parent = tree[0..2]
|
|
45
60
|
elsif source.parsed? && source.repaired? && end_of_phrase == '.'
|
|
46
61
|
node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2]
|
|
47
|
-
|
|
62
|
+
# provide filename and line so that we can look up local variables there later
|
|
63
|
+
node = Parser.parse(fixed_phrase, source.filename, fixed_position.line) if node.nil?
|
|
48
64
|
elsif source.repaired?
|
|
49
|
-
node = Parser.parse(fixed_phrase)
|
|
65
|
+
node = Parser.parse(fixed_phrase, source.filename, fixed_position.line)
|
|
50
66
|
else
|
|
51
|
-
|
|
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
|
|
52
73
|
# Exception for positions that chain literal nodes in unsynchronized sources
|
|
53
74
|
node = nil unless source.synchronized? || !Parser.infer_literal_node_type(node).nil?
|
|
54
|
-
node = Parser.parse(fixed_phrase) if node.nil?
|
|
75
|
+
node = Parser.parse(fixed_phrase, source.filename, fixed_position.line) if node.nil?
|
|
55
76
|
end
|
|
56
77
|
rescue Parser::SyntaxError
|
|
57
78
|
return Chain.new([Chain::UNDEFINED_CALL])
|
|
@@ -79,14 +100,16 @@ module Solargraph
|
|
|
79
100
|
# @return [Solargraph::Source]
|
|
80
101
|
attr_reader :source
|
|
81
102
|
|
|
103
|
+
# @sg-ignore Need to add nil check here
|
|
82
104
|
# @return [String]
|
|
83
105
|
def phrase
|
|
84
|
-
@phrase ||= source.code[signature_data..offset-1]
|
|
106
|
+
@phrase ||= source.code[signature_data..(offset - 1)]
|
|
85
107
|
end
|
|
86
108
|
|
|
109
|
+
# @sg-ignore Need to add nil check here
|
|
87
110
|
# @return [String]
|
|
88
111
|
def fixed_phrase
|
|
89
|
-
@fixed_phrase ||= phrase[0..-(end_of_phrase.length+1)]
|
|
112
|
+
@fixed_phrase ||= phrase[0..-(end_of_phrase.length + 1)]
|
|
90
113
|
end
|
|
91
114
|
|
|
92
115
|
# @return [Position]
|
|
@@ -95,6 +118,7 @@ module Solargraph
|
|
|
95
118
|
end
|
|
96
119
|
|
|
97
120
|
# @return [String]
|
|
121
|
+
# @sg-ignore Need to add nil check here
|
|
98
122
|
def end_of_phrase
|
|
99
123
|
@end_of_phrase ||= begin
|
|
100
124
|
match = phrase.match(/\s*(\.{1}|::)\s*$/)
|
|
@@ -137,47 +161,47 @@ module Solargraph
|
|
|
137
161
|
brackets = 0
|
|
138
162
|
squares = 0
|
|
139
163
|
parens = 0
|
|
140
|
-
index -=1
|
|
164
|
+
index -= 1
|
|
141
165
|
in_whitespace = false
|
|
142
166
|
while index >= 0
|
|
143
167
|
pos = Position.from_offset(@source.code, index)
|
|
144
|
-
break if index
|
|
145
|
-
break if brackets
|
|
168
|
+
break if index.positive? && @source.comment_at?(pos)
|
|
169
|
+
break if brackets.positive? || parens.positive? || squares.positive?
|
|
146
170
|
char = @source.code[index, 1]
|
|
147
171
|
break if char.nil? # @todo Is this the right way to handle this?
|
|
148
|
-
if brackets.zero?
|
|
172
|
+
if brackets.zero? && parens.zero? && squares.zero? && [' ', "\r", "\n", "\t"].include?(char)
|
|
149
173
|
in_whitespace = true
|
|
150
174
|
else
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
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)..]
|
|
178
|
+
# @sg-ignore Need to add nil check here
|
|
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
|
|
158
183
|
end
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
184
|
+
case char
|
|
185
|
+
when ')'
|
|
186
|
+
parens -= 1
|
|
187
|
+
when ']'
|
|
188
|
+
squares -= 1
|
|
189
|
+
when '}'
|
|
164
190
|
brackets -= 1
|
|
165
|
-
|
|
191
|
+
when '('
|
|
166
192
|
parens += 1
|
|
167
|
-
|
|
193
|
+
when '{'
|
|
168
194
|
brackets += 1
|
|
169
|
-
|
|
195
|
+
when '['
|
|
170
196
|
squares += 1
|
|
171
197
|
end
|
|
172
|
-
if brackets.zero?
|
|
198
|
+
if brackets.zero? && parens.zero? && squares.zero?
|
|
173
199
|
break if ['"', "'", ',', ';', '%'].include?(char)
|
|
174
200
|
break if ['!', '?'].include?(char) && index < offset - 1
|
|
175
201
|
break if char == '$'
|
|
176
202
|
if char == '@'
|
|
177
203
|
index -= 1
|
|
178
|
-
if @source.code[index, 1] == '@'
|
|
179
|
-
index -= 1
|
|
180
|
-
end
|
|
204
|
+
index -= 1 if @source.code[index, 1] == '@'
|
|
181
205
|
break
|
|
182
206
|
end
|
|
183
207
|
elsif parens == 1 || brackets == 1 || squares == 1
|
|
@@ -29,14 +29,18 @@ module Solargraph
|
|
|
29
29
|
|
|
30
30
|
# @param text [String]
|
|
31
31
|
# @param nullable [Boolean]
|
|
32
|
+
# @sg-ignore changes doesn't mutate @output, so this can never be nil
|
|
32
33
|
# @return [String]
|
|
33
34
|
def write text, nullable = false
|
|
34
35
|
can_nullify = (nullable and changes.length == 1)
|
|
35
|
-
return @output if @input == text
|
|
36
|
+
return @output if (@input == text) && (can_nullify == @did_nullify)
|
|
36
37
|
@input = text
|
|
37
38
|
@output = text
|
|
38
39
|
@did_nullify = can_nullify
|
|
39
40
|
changes.each do |ch|
|
|
41
|
+
# @sg-ignore Wrong argument type for
|
|
42
|
+
# Solargraph::Source::Change#write: text expected String,
|
|
43
|
+
# received String, nil
|
|
40
44
|
@output = ch.write(@output, can_nullify)
|
|
41
45
|
end
|
|
42
46
|
@output
|
data/lib/solargraph/source.rb
CHANGED
|
@@ -60,11 +60,13 @@ module Solargraph
|
|
|
60
60
|
# @param c1 [Integer]
|
|
61
61
|
# @param l2 [Integer]
|
|
62
62
|
# @param c2 [Integer]
|
|
63
|
+
#
|
|
64
|
+
# @sg-ignore Need to add nil check here
|
|
63
65
|
# @return [String]
|
|
64
66
|
def from_to l1, c1, l2, c2
|
|
65
67
|
b = Solargraph::Position.line_char_to_offset(code, l1, c1)
|
|
66
68
|
e = Solargraph::Position.line_char_to_offset(code, l2, c2)
|
|
67
|
-
code[b..e-1]
|
|
69
|
+
code[b..(e - 1)]
|
|
68
70
|
end
|
|
69
71
|
|
|
70
72
|
# Get the nearest node that contains the specified index.
|
|
@@ -72,7 +74,7 @@ module Solargraph
|
|
|
72
74
|
# @param line [Integer]
|
|
73
75
|
# @param column [Integer]
|
|
74
76
|
# @return [AST::Node]
|
|
75
|
-
def node_at
|
|
77
|
+
def node_at line, column
|
|
76
78
|
tree_at(line, column).first
|
|
77
79
|
end
|
|
78
80
|
|
|
@@ -81,8 +83,8 @@ module Solargraph
|
|
|
81
83
|
#
|
|
82
84
|
# @param line [Integer]
|
|
83
85
|
# @param column [Integer]
|
|
84
|
-
# @return [Array<AST::Node>]
|
|
85
|
-
def tree_at
|
|
86
|
+
# @return [Array<Parser::AST::Node>]
|
|
87
|
+
def tree_at line, column
|
|
86
88
|
position = Position.new(line, column)
|
|
87
89
|
stack = []
|
|
88
90
|
inner_tree_at node, position, stack
|
|
@@ -131,20 +133,29 @@ module Solargraph
|
|
|
131
133
|
return false if Position.to_offset(code, position) >= code.length
|
|
132
134
|
string_nodes.each do |node|
|
|
133
135
|
range = Range.from_node(node)
|
|
136
|
+
# @sg-ignore Need to add nil check here
|
|
134
137
|
next if range.ending.line < position.line
|
|
138
|
+
# @sg-ignore Need to add nil check here
|
|
135
139
|
break if range.ending.line > position.line
|
|
140
|
+
# @sg-ignore Need to add nil check here
|
|
136
141
|
return true if node.type == :str && range.include?(position) && range.start != position
|
|
137
|
-
|
|
142
|
+
# @sg-ignore Need to add nil check here
|
|
143
|
+
return true if %i[STR str].include?(node.type) && range.include?(position) && range.start != position
|
|
138
144
|
if node.type == :dstr
|
|
139
145
|
inner = node_at(position.line, position.column)
|
|
140
146
|
next if inner.nil?
|
|
141
147
|
inner_range = Range.from_node(inner)
|
|
148
|
+
# @sg-ignore Need to add nil check here
|
|
142
149
|
next unless range.include?(inner_range.ending)
|
|
143
150
|
return true if inner.type == :str
|
|
151
|
+
# @sg-ignore Need to add nil check here
|
|
144
152
|
inner_code = at(Solargraph::Range.new(inner_range.start, position))
|
|
145
|
-
|
|
153
|
+
# @sg-ignore Need to add nil check here
|
|
154
|
+
return true if (inner.type == :dstr && inner_range.ending.character <= position.character && !inner_code.end_with?('}')) ||
|
|
155
|
+
# @sg-ignore Need to add nil check here
|
|
146
156
|
(inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
|
|
147
157
|
end
|
|
158
|
+
# @sg-ignore Need to add nil check here
|
|
148
159
|
break if range.ending.line > position.line
|
|
149
160
|
end
|
|
150
161
|
false
|
|
@@ -160,7 +171,7 @@ module Solargraph
|
|
|
160
171
|
def comment_at? position
|
|
161
172
|
comment_ranges.each do |range|
|
|
162
173
|
return true if range.include?(position) ||
|
|
163
|
-
|
|
174
|
+
(range.ending.line == position.line && range.ending.column < position.column)
|
|
164
175
|
break if range.ending.line > position.line
|
|
165
176
|
end
|
|
166
177
|
false
|
|
@@ -179,19 +190,24 @@ module Solargraph
|
|
|
179
190
|
|
|
180
191
|
# @param node [Parser::AST::Node]
|
|
181
192
|
# @return [String]
|
|
182
|
-
def code_for
|
|
193
|
+
def code_for node
|
|
183
194
|
rng = Range.from_node(node)
|
|
195
|
+
# @sg-ignore Need to add nil check here
|
|
184
196
|
b = Position.line_char_to_offset(code, rng.start.line, rng.start.column)
|
|
197
|
+
# @sg-ignore Need to add nil check here
|
|
185
198
|
e = Position.line_char_to_offset(code, rng.ending.line, rng.ending.column)
|
|
186
|
-
frag = code[b..e-1].to_s
|
|
199
|
+
frag = code[b..(e - 1)].to_s
|
|
187
200
|
frag.strip.gsub(/,$/, '')
|
|
188
201
|
end
|
|
189
202
|
|
|
190
|
-
# @param node [
|
|
203
|
+
# @param node [AST::Node]
|
|
204
|
+
#
|
|
191
205
|
# @return [String, nil]
|
|
192
206
|
def comments_for node
|
|
193
207
|
rng = Range.from_node(node)
|
|
208
|
+
# @sg-ignore Need to add nil check here
|
|
194
209
|
stringified_comments[rng.start.line] ||= begin
|
|
210
|
+
# @sg-ignore Need to add nil check here
|
|
195
211
|
buff = associated_comments[rng.start.line]
|
|
196
212
|
buff ? stringify_comment_array(buff) : nil
|
|
197
213
|
end
|
|
@@ -208,8 +224,8 @@ module Solargraph
|
|
|
208
224
|
end
|
|
209
225
|
|
|
210
226
|
FOLDING_NODE_TYPES = %i[
|
|
211
|
-
|
|
212
|
-
|
|
227
|
+
class sclass module def defs if str dstr array while unless kwbegin hash block
|
|
228
|
+
].freeze
|
|
213
229
|
|
|
214
230
|
# Get an array of ranges that can be folded, e.g., the range of a class
|
|
215
231
|
# definition or an if condition.
|
|
@@ -219,6 +235,7 @@ module Solargraph
|
|
|
219
235
|
# @return [Array<Range>]
|
|
220
236
|
def folding_ranges
|
|
221
237
|
@folding_ranges ||= begin
|
|
238
|
+
# @type [Array<Range>]
|
|
222
239
|
result = []
|
|
223
240
|
inner_folding_ranges node, result
|
|
224
241
|
result.concat foldable_comment_block_ranges
|
|
@@ -232,7 +249,7 @@ module Solargraph
|
|
|
232
249
|
|
|
233
250
|
# Get a hash of comments grouped by the line numbers of the associated code.
|
|
234
251
|
#
|
|
235
|
-
# @return [Hash{Integer => String}]
|
|
252
|
+
# @return [Hash{Integer => String, nil}]
|
|
236
253
|
def associated_comments
|
|
237
254
|
@associated_comments ||= begin
|
|
238
255
|
# @type [Hash{Integer => String}]
|
|
@@ -265,18 +282,22 @@ module Solargraph
|
|
|
265
282
|
cursor
|
|
266
283
|
end
|
|
267
284
|
|
|
268
|
-
# @param top [Parser::AST::Node]
|
|
285
|
+
# @param top [Parser::AST::Node, nil]
|
|
269
286
|
# @param result [Array<Range>]
|
|
270
287
|
# @param parent [Symbol, nil]
|
|
271
288
|
# @return [void]
|
|
272
289
|
def inner_folding_ranges top, result = [], parent = nil
|
|
273
290
|
return unless Parser.is_ast_node?(top)
|
|
291
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
274
292
|
if FOLDING_NODE_TYPES.include?(top.type)
|
|
293
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
275
294
|
range = Range.from_node(top)
|
|
276
|
-
|
|
277
|
-
|
|
295
|
+
# @sg-ignore Need to add nil check here
|
|
296
|
+
if (result.empty? || range.start.line > result.last.start.line) && range.ending.line - range.start.line >= 2
|
|
297
|
+
result.push range
|
|
278
298
|
end
|
|
279
299
|
end
|
|
300
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
280
301
|
top.children.each do |child|
|
|
281
302
|
inner_folding_ranges(child, result, top.type)
|
|
282
303
|
end
|
|
@@ -290,7 +311,7 @@ module Solargraph
|
|
|
290
311
|
ctxt = String.new('')
|
|
291
312
|
started = false
|
|
292
313
|
skip = nil
|
|
293
|
-
comments.lines.each
|
|
314
|
+
comments.lines.each do |l|
|
|
294
315
|
# Trim the comment and minimum leading whitespace
|
|
295
316
|
p = l.force_encoding('UTF-8').encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#+/, '')
|
|
296
317
|
if p.strip.empty?
|
|
@@ -298,17 +319,18 @@ module Solargraph
|
|
|
298
319
|
ctxt.concat p
|
|
299
320
|
else
|
|
300
321
|
here = p.index(/[^ \t]/)
|
|
322
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
301
323
|
skip = here if skip.nil? || here < skip
|
|
302
|
-
ctxt.concat p[skip
|
|
324
|
+
ctxt.concat p[skip..]
|
|
303
325
|
end
|
|
304
326
|
started = true
|
|
305
|
-
|
|
327
|
+
end
|
|
306
328
|
ctxt
|
|
307
329
|
end
|
|
308
330
|
|
|
309
331
|
# A hash of line numbers and their associated comments.
|
|
310
332
|
#
|
|
311
|
-
# @return [Hash{Integer =>
|
|
333
|
+
# @return [Hash{Integer => String}]
|
|
312
334
|
def stringified_comments
|
|
313
335
|
@stringified_comments ||= {}
|
|
314
336
|
end
|
|
@@ -331,7 +353,7 @@ module Solargraph
|
|
|
331
353
|
return [] unless synchronized?
|
|
332
354
|
result = []
|
|
333
355
|
grouped = []
|
|
334
|
-
comments.
|
|
356
|
+
comments.each_key do |l|
|
|
335
357
|
if grouped.empty? || l == grouped.last + 1
|
|
336
358
|
grouped.push l
|
|
337
359
|
else
|
|
@@ -348,10 +370,12 @@ module Solargraph
|
|
|
348
370
|
def string_nodes_in n
|
|
349
371
|
result = []
|
|
350
372
|
if Parser.is_ast_node?(n)
|
|
351
|
-
|
|
373
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
374
|
+
if %i[str dstr STR DSTR].include?(n.type)
|
|
352
375
|
result.push n
|
|
353
376
|
else
|
|
354
|
-
|
|
377
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
378
|
+
n.children.each { |c| result.concat string_nodes_in(c) }
|
|
355
379
|
end
|
|
356
380
|
end
|
|
357
381
|
result
|
|
@@ -364,13 +388,13 @@ module Solargraph
|
|
|
364
388
|
def inner_tree_at node, position, stack
|
|
365
389
|
return if node.nil?
|
|
366
390
|
here = Range.from_node(node)
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
391
|
+
# @sg-ignore Need to add nil check here
|
|
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)
|
|
374
398
|
end
|
|
375
399
|
end
|
|
376
400
|
|
|
@@ -396,10 +420,10 @@ module Solargraph
|
|
|
396
420
|
end
|
|
397
421
|
@finalized = true
|
|
398
422
|
begin
|
|
399
|
-
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
|
|
423
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename, 0)
|
|
400
424
|
@parsed = true
|
|
401
425
|
@repaired = @code
|
|
402
|
-
rescue Parser::SyntaxError, EncodingError
|
|
426
|
+
rescue Parser::SyntaxError, EncodingError
|
|
403
427
|
@node = nil
|
|
404
428
|
@comments = {}
|
|
405
429
|
@parsed = false
|
|
@@ -412,9 +436,9 @@ module Solargraph
|
|
|
412
436
|
end
|
|
413
437
|
error_ranges.concat(changes.map(&:range))
|
|
414
438
|
begin
|
|
415
|
-
@node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename)
|
|
439
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename, 0)
|
|
416
440
|
@parsed = true
|
|
417
|
-
rescue Parser::SyntaxError, EncodingError
|
|
441
|
+
rescue Parser::SyntaxError, EncodingError
|
|
418
442
|
@node = nil
|
|
419
443
|
@comments = {}
|
|
420
444
|
@parsed = false
|
|
@@ -427,7 +451,7 @@ module Solargraph
|
|
|
427
451
|
|
|
428
452
|
# @param val [String]
|
|
429
453
|
# @return [String]
|
|
430
|
-
def code=
|
|
454
|
+
def code= val
|
|
431
455
|
@code_lines = nil
|
|
432
456
|
@finalized = false
|
|
433
457
|
@code = val
|