solargraph 0.58.2 → 0.59.0.dev.1
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 +40 -36
- data/.github/workflows/rspec.yml +45 -13
- data/.github/workflows/typecheck.yml +2 -2
- data/.gitignore +0 -1
- data/.rubocop_todo.yml +27 -49
- data/CHANGELOG.md +1 -7
- data/README.md +3 -3
- data/Rakefile +1 -0
- 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 +22 -11
- data/lib/solargraph/api_map/source_to_yard.rb +13 -1
- data/lib/solargraph/api_map/store.rb +11 -8
- data/lib/solargraph/api_map.rb +105 -50
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +16 -2
- data/lib/solargraph/complex_type/unique_type.rb +170 -20
- data/lib/solargraph/complex_type.rb +119 -14
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +3 -1
- data/lib/solargraph/convention/data_definition.rb +4 -1
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -0
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +1 -0
- data/lib/solargraph/convention/struct_definition.rb +5 -1
- data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
- data/lib/solargraph/diagnostics/rubocop.rb +1 -0
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +2 -0
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/doc_map.rb +134 -373
- data/lib/solargraph/equality.rb +1 -1
- data/lib/solargraph/gem_pins.rb +14 -15
- data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
- data/lib/solargraph/language_server/host/dispatch.rb +1 -0
- data/lib/solargraph/language_server/host/message_worker.rb +2 -1
- data/lib/solargraph/language_server/host/sources.rb +1 -0
- data/lib/solargraph/language_server/host.rb +6 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -7
- data/lib/solargraph/language_server/message/extended/document.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/completion.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +2 -0
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -0
- data/lib/solargraph/library.rb +59 -13
- data/lib/solargraph/location.rb +9 -4
- data/lib/solargraph/logging.rb +21 -1
- data/lib/solargraph/parser/comment_ripper.rb +7 -0
- data/lib/solargraph/parser/flow_sensitive_typing.rb +330 -102
- data/lib/solargraph/parser/node_processor/base.rb +32 -2
- data/lib/solargraph/parser/node_processor.rb +7 -6
- data/lib/solargraph/parser/parser_gem/class_methods.rb +28 -10
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +31 -6
- data/lib/solargraph/parser/parser_gem/node_methods.rb +27 -7
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +2 -0
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -11
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +7 -0
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +3 -2
- 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 +2 -2
- 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 +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +12 -7
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +5 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
- data/lib/solargraph/parser/region.rb +9 -3
- data/lib/solargraph/parser/snippet.rb +1 -1
- data/lib/solargraph/pin/base.rb +53 -21
- data/lib/solargraph/pin/base_variable.rb +312 -20
- data/lib/solargraph/pin/block.rb +26 -4
- data/lib/solargraph/pin/breakable.rb +5 -1
- data/lib/solargraph/pin/callable.rb +50 -3
- data/lib/solargraph/pin/closure.rb +2 -6
- data/lib/solargraph/pin/common.rb +20 -5
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/conversions.rb +2 -1
- data/lib/solargraph/pin/delegated_method.rb +15 -4
- data/lib/solargraph/pin/documenting.rb +1 -0
- data/lib/solargraph/pin/instance_variable.rb +5 -1
- data/lib/solargraph/pin/keyword.rb +0 -4
- data/lib/solargraph/pin/local_variable.rb +13 -57
- data/lib/solargraph/pin/method.rb +90 -42
- data/lib/solargraph/pin/method_alias.rb +8 -0
- data/lib/solargraph/pin/namespace.rb +7 -1
- data/lib/solargraph/pin/parameter.rb +76 -13
- data/lib/solargraph/pin/proxy_type.rb +2 -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 +2 -0
- data/lib/solargraph/pin/search.rb +1 -0
- data/lib/solargraph/pin/signature.rb +8 -0
- data/lib/solargraph/pin/symbol.rb +1 -1
- data/lib/solargraph/pin/until.rb +1 -1
- data/lib/solargraph/pin/while.rb +1 -1
- data/lib/solargraph/pin.rb +2 -0
- data/lib/solargraph/pin_cache.rb +477 -57
- data/lib/solargraph/position.rb +12 -26
- data/lib/solargraph/range.rb +6 -6
- data/lib/solargraph/rbs_map/conversions.rb +33 -10
- data/lib/solargraph/rbs_map/core_map.rb +24 -17
- data/lib/solargraph/rbs_map/stdlib_map.rb +34 -5
- data/lib/solargraph/rbs_map.rb +74 -20
- data/lib/solargraph/shell.rb +73 -28
- data/lib/solargraph/source/chain/call.rb +52 -17
- data/lib/solargraph/source/chain/constant.rb +2 -0
- data/lib/solargraph/source/chain/hash.rb +1 -0
- data/lib/solargraph/source/chain/if.rb +1 -0
- data/lib/solargraph/source/chain/instance_variable.rb +22 -1
- data/lib/solargraph/source/chain/literal.rb +5 -0
- data/lib/solargraph/source/chain/or.rb +9 -1
- data/lib/solargraph/source/chain.rb +25 -22
- data/lib/solargraph/source/change.rb +9 -2
- data/lib/solargraph/source/cursor.rb +7 -1
- data/lib/solargraph/source/source_chainer.rb +13 -3
- data/lib/solargraph/source/updater.rb +4 -0
- data/lib/solargraph/source.rb +33 -7
- data/lib/solargraph/source_map/clip.rb +13 -2
- data/lib/solargraph/source_map/data.rb +4 -1
- data/lib/solargraph/source_map/mapper.rb +24 -1
- data/lib/solargraph/source_map.rb +14 -6
- data/lib/solargraph/type_checker/problem.rb +3 -1
- data/lib/solargraph/type_checker/rules.rb +75 -2
- data/lib/solargraph/type_checker.rb +111 -30
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +3 -1
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +1 -0
- data/lib/solargraph/workspace.rb +158 -16
- data/lib/solargraph/yard_map/helpers.rb +2 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +5 -1
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
- data/lib/solargraph/yard_map/mapper.rb +5 -0
- data/lib/solargraph/yardoc.rb +33 -23
- data/lib/solargraph.rb +24 -3
- 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 +2 -1
- metadata +12 -7
- 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
|
@@ -7,13 +7,13 @@ module Solargraph
|
|
|
7
7
|
class Change
|
|
8
8
|
include EncodingFixes
|
|
9
9
|
|
|
10
|
-
# @return [Range]
|
|
10
|
+
# @return [Range, nil]
|
|
11
11
|
attr_reader :range
|
|
12
12
|
|
|
13
13
|
# @return [String]
|
|
14
14
|
attr_reader :new_text
|
|
15
15
|
|
|
16
|
-
# @param range [Range] The starting and ending positions of the change.
|
|
16
|
+
# @param range [Range, nil] The starting and ending positions of the change.
|
|
17
17
|
# If nil, the original text will be overwritten.
|
|
18
18
|
# @param new_text [String] The text to be changed.
|
|
19
19
|
def initialize range, new_text
|
|
@@ -31,9 +31,11 @@ module Solargraph
|
|
|
31
31
|
if nullable and !range.nil? and new_text.match(/[.\[{(@$:]$/)
|
|
32
32
|
[':', '@'].each do |dupable|
|
|
33
33
|
next unless new_text == dupable
|
|
34
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
34
35
|
offset = Position.to_offset(text, range.start)
|
|
35
36
|
if text[offset - 1] == dupable
|
|
36
37
|
p = Position.from_offset(text, offset - 1)
|
|
38
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
37
39
|
r = Change.new(Range.new(p, range.start), ' ')
|
|
38
40
|
text = r.write(text)
|
|
39
41
|
end
|
|
@@ -58,9 +60,12 @@ module Solargraph
|
|
|
58
60
|
fixed
|
|
59
61
|
else
|
|
60
62
|
result = commit text, fixed
|
|
63
|
+
# @sg-ignore flow sensitive typing needs to handle attrs
|
|
61
64
|
off = Position.to_offset(text, range.start)
|
|
65
|
+
# @sg-ignore Need to add nil check here
|
|
62
66
|
match = result[0, off].match(/[.:]+\z/)
|
|
63
67
|
if match
|
|
68
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
64
69
|
result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..-1]
|
|
65
70
|
end
|
|
66
71
|
result
|
|
@@ -73,7 +78,9 @@ module Solargraph
|
|
|
73
78
|
# @param insert [String]
|
|
74
79
|
# @return [String]
|
|
75
80
|
def commit text, insert
|
|
81
|
+
# @sg-ignore Need to add nil check here
|
|
76
82
|
start_offset = Position.to_offset(text, range.start)
|
|
83
|
+
# @sg-ignore Need to add nil check here
|
|
77
84
|
end_offset = Position.to_offset(text, range.ending)
|
|
78
85
|
(start_offset == 0 ? '' : text[0..start_offset-1].to_s) + normalize(insert) + text[end_offset..-1].to_s
|
|
79
86
|
end
|
|
@@ -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,12 +35,14 @@ 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
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
|
|
45
|
+
# @sg-ignore Need to add nil check here
|
|
44
46
|
result = ":#{result}" if source.code[0..offset-result.length-1].end_with?(':') and !source.code[0..offset-result.length-1].end_with?('::')
|
|
45
47
|
result
|
|
46
48
|
end
|
|
@@ -50,6 +52,7 @@ module Solargraph
|
|
|
50
52
|
# `foo.bar`, the end_of_word at position (0,6) is `r`.
|
|
51
53
|
#
|
|
52
54
|
# @return [String]
|
|
55
|
+
# @sg-ignore Need to add nil check here
|
|
53
56
|
def end_of_word
|
|
54
57
|
@end_of_word ||= begin
|
|
55
58
|
match = source.code[offset..-1].to_s.match(end_word_pattern)
|
|
@@ -110,6 +113,7 @@ module Solargraph
|
|
|
110
113
|
def recipient
|
|
111
114
|
@recipient ||= begin
|
|
112
115
|
node = recipient_node
|
|
116
|
+
# @sg-ignore Need to add nil check here
|
|
113
117
|
node ? Cursor.new(source, Range.from_node(node).ending) : nil
|
|
114
118
|
end
|
|
115
119
|
end
|
|
@@ -124,8 +128,10 @@ module Solargraph
|
|
|
124
128
|
def node_position
|
|
125
129
|
@node_position ||= begin
|
|
126
130
|
if start_of_word.empty?
|
|
131
|
+
# @sg-ignore Need to add nil check here
|
|
127
132
|
match = source.code[0, offset].match(/\s*(\.|:+)\s*$/)
|
|
128
133
|
if match
|
|
134
|
+
# @sg-ignore Need to add nil check here
|
|
129
135
|
Position.from_offset(source.code, offset - match[0].length)
|
|
130
136
|
else
|
|
131
137
|
position
|
|
@@ -33,25 +33,29 @@ module Solargraph
|
|
|
33
33
|
def chain
|
|
34
34
|
# Special handling for files that end with an integer and a period
|
|
35
35
|
return Chain.new([Chain::Literal.new('Integer', Integer(phrase[0..-2])), Chain::UNDEFINED_CALL]) if phrase =~ /^[0-9]+\.$/
|
|
36
|
+
# @sg-ignore Need to add nil check here
|
|
36
37
|
return Chain.new([Chain::Literal.new('Symbol', phrase[1..].to_sym)]) if phrase.start_with?(':') && !phrase.start_with?('::')
|
|
37
38
|
return SourceChainer.chain(source, Position.new(position.line, position.character + 1)) if end_of_phrase.strip == '::' && source.code[Position.to_offset(source.code, position)].to_s.match?(/[a-z]/i)
|
|
38
39
|
begin
|
|
39
40
|
return Chain.new([]) if phrase.end_with?('..')
|
|
41
|
+
# @type [::Parser::AST::Node, nil]
|
|
40
42
|
node = nil
|
|
43
|
+
# @type [::Parser::AST::Node, nil]
|
|
41
44
|
parent = nil
|
|
42
45
|
if !source.repaired? && source.parsed? && source.synchronized?
|
|
43
46
|
tree = source.tree_at(position.line, position.column)
|
|
44
47
|
node, parent = tree[0..2]
|
|
45
48
|
elsif source.parsed? && source.repaired? && end_of_phrase == '.'
|
|
46
49
|
node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2]
|
|
47
|
-
|
|
50
|
+
# provide filename and line so that we can look up local variables there later
|
|
51
|
+
node = Parser.parse(fixed_phrase, source.filename, fixed_position.line) if node.nil?
|
|
48
52
|
elsif source.repaired?
|
|
49
|
-
node = Parser.parse(fixed_phrase)
|
|
53
|
+
node = Parser.parse(fixed_phrase, source.filename, fixed_position.line)
|
|
50
54
|
else
|
|
51
55
|
node, parent = source.tree_at(fixed_position.line, fixed_position.column)[0..2] unless source.error_ranges.any?{|r| r.nil? || r.include?(fixed_position)}
|
|
52
56
|
# Exception for positions that chain literal nodes in unsynchronized sources
|
|
53
57
|
node = nil unless source.synchronized? || !Parser.infer_literal_node_type(node).nil?
|
|
54
|
-
node = Parser.parse(fixed_phrase) if node.nil?
|
|
58
|
+
node = Parser.parse(fixed_phrase, source.filename, fixed_position.line) if node.nil?
|
|
55
59
|
end
|
|
56
60
|
rescue Parser::SyntaxError
|
|
57
61
|
return Chain.new([Chain::UNDEFINED_CALL])
|
|
@@ -79,11 +83,13 @@ module Solargraph
|
|
|
79
83
|
# @return [Solargraph::Source]
|
|
80
84
|
attr_reader :source
|
|
81
85
|
|
|
86
|
+
# @sg-ignore Need to add nil check here
|
|
82
87
|
# @return [String]
|
|
83
88
|
def phrase
|
|
84
89
|
@phrase ||= source.code[signature_data..offset-1]
|
|
85
90
|
end
|
|
86
91
|
|
|
92
|
+
# @sg-ignore Need to add nil check here
|
|
87
93
|
# @return [String]
|
|
88
94
|
def fixed_phrase
|
|
89
95
|
@fixed_phrase ||= phrase[0..-(end_of_phrase.length+1)]
|
|
@@ -95,6 +101,7 @@ module Solargraph
|
|
|
95
101
|
end
|
|
96
102
|
|
|
97
103
|
# @return [String]
|
|
104
|
+
# @sg-ignore Need to add nil check here
|
|
98
105
|
def end_of_phrase
|
|
99
106
|
@end_of_phrase ||= begin
|
|
100
107
|
match = phrase.match(/\s*(\.{1}|::)\s*$/)
|
|
@@ -149,9 +156,12 @@ module Solargraph
|
|
|
149
156
|
in_whitespace = true
|
|
150
157
|
else
|
|
151
158
|
if brackets.zero? and parens.zero? and squares.zero? and in_whitespace
|
|
159
|
+
# @sg-ignore Need to add nil check here
|
|
152
160
|
unless char == '.' or @source.code[index+1..-1].strip.start_with?('.')
|
|
153
161
|
old = @source.code[index+1..-1]
|
|
162
|
+
# @sg-ignore Need to add nil check here
|
|
154
163
|
nxt = @source.code[index+1..-1].lstrip
|
|
164
|
+
# @sg-ignore Need to add nil check here
|
|
155
165
|
index += (@source.code[index+1..-1].length - @source.code[index+1..-1].lstrip.length)
|
|
156
166
|
break
|
|
157
167
|
end
|
|
@@ -29,6 +29,7 @@ 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)
|
|
@@ -37,6 +38,9 @@ module Solargraph
|
|
|
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,6 +60,8 @@ 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)
|
|
@@ -81,7 +83,7 @@ module Solargraph
|
|
|
81
83
|
#
|
|
82
84
|
# @param line [Integer]
|
|
83
85
|
# @param column [Integer]
|
|
84
|
-
# @return [Array<AST::Node>]
|
|
86
|
+
# @return [Array<Parser::AST::Node>]
|
|
85
87
|
def tree_at(line, column)
|
|
86
88
|
position = Position.new(line, column)
|
|
87
89
|
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
|
|
142
|
+
# @sg-ignore Need to add nil check here
|
|
137
143
|
return true if [: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))
|
|
153
|
+
# @sg-ignore Need to add nil check here
|
|
145
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
|
|
@@ -181,17 +192,22 @@ module Solargraph
|
|
|
181
192
|
# @return [String]
|
|
182
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
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
|
|
@@ -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,23 @@ 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)
|
|
295
|
+
# @sg-ignore Need to add nil check here
|
|
276
296
|
if result.empty? || range.start.line > result.last.start.line
|
|
297
|
+
# @sg-ignore Need to add nil check here
|
|
277
298
|
result.push range unless range.ending.line - range.start.line < 2
|
|
278
299
|
end
|
|
279
300
|
end
|
|
301
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
280
302
|
top.children.each do |child|
|
|
281
303
|
inner_folding_ranges(child, result, top.type)
|
|
282
304
|
end
|
|
@@ -298,6 +320,7 @@ module Solargraph
|
|
|
298
320
|
ctxt.concat p
|
|
299
321
|
else
|
|
300
322
|
here = p.index(/[^ \t]/)
|
|
323
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
301
324
|
skip = here if skip.nil? || here < skip
|
|
302
325
|
ctxt.concat p[skip..-1]
|
|
303
326
|
end
|
|
@@ -308,7 +331,7 @@ module Solargraph
|
|
|
308
331
|
|
|
309
332
|
# A hash of line numbers and their associated comments.
|
|
310
333
|
#
|
|
311
|
-
# @return [Hash{Integer =>
|
|
334
|
+
# @return [Hash{Integer => String}]
|
|
312
335
|
def stringified_comments
|
|
313
336
|
@stringified_comments ||= {}
|
|
314
337
|
end
|
|
@@ -348,9 +371,11 @@ module Solargraph
|
|
|
348
371
|
def string_nodes_in n
|
|
349
372
|
result = []
|
|
350
373
|
if Parser.is_ast_node?(n)
|
|
374
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
351
375
|
if n.type == :str || n.type == :dstr || n.type == :STR || n.type == :DSTR
|
|
352
376
|
result.push n
|
|
353
377
|
else
|
|
378
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
354
379
|
n.children.each{ |c| result.concat string_nodes_in(c) }
|
|
355
380
|
end
|
|
356
381
|
end
|
|
@@ -364,6 +389,7 @@ module Solargraph
|
|
|
364
389
|
def inner_tree_at node, position, stack
|
|
365
390
|
return if node.nil?
|
|
366
391
|
here = Range.from_node(node)
|
|
392
|
+
# @sg-ignore Need to add nil check here
|
|
367
393
|
if here.contain?(position)
|
|
368
394
|
stack.unshift node
|
|
369
395
|
node.children.each do |c|
|
|
@@ -396,7 +422,7 @@ module Solargraph
|
|
|
396
422
|
end
|
|
397
423
|
@finalized = true
|
|
398
424
|
begin
|
|
399
|
-
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
|
|
425
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename, 0)
|
|
400
426
|
@parsed = true
|
|
401
427
|
@repaired = @code
|
|
402
428
|
rescue Parser::SyntaxError, EncodingError => e
|
|
@@ -412,7 +438,7 @@ module Solargraph
|
|
|
412
438
|
end
|
|
413
439
|
error_ranges.concat(changes.map(&:range))
|
|
414
440
|
begin
|
|
415
|
-
@node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename)
|
|
441
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename, 0)
|
|
416
442
|
@parsed = true
|
|
417
443
|
rescue Parser::SyntaxError, EncodingError => e
|
|
418
444
|
@node = nil
|
|
@@ -12,6 +12,7 @@ module Solargraph
|
|
|
12
12
|
@api_map = api_map
|
|
13
13
|
@cursor = cursor
|
|
14
14
|
closure_pin = closure
|
|
15
|
+
# @sg-ignore Need to add nil check here
|
|
15
16
|
closure_pin.rebind(api_map) if closure_pin.is_a?(Pin::Block) && !Solargraph::Range.from_node(closure_pin.receiver).contain?(cursor.range.start)
|
|
16
17
|
end
|
|
17
18
|
|
|
@@ -20,6 +21,7 @@ module Solargraph
|
|
|
20
21
|
return [] if cursor.comment? || cursor.chain.literal?
|
|
21
22
|
result = cursor.chain.define(api_map, closure, locals)
|
|
22
23
|
result.concat file_global_methods
|
|
24
|
+
# @sg-ignore Need to add nil check here
|
|
23
25
|
result.concat((source_map.pins + source_map.locals).select{ |p| p.name == cursor.word && p.location.range.contain?(cursor.position) }) if result.empty?
|
|
24
26
|
result
|
|
25
27
|
end
|
|
@@ -78,7 +80,7 @@ module Solargraph
|
|
|
78
80
|
# @param phrase [String]
|
|
79
81
|
# @return [Array<Solargraph::Pin::Base>]
|
|
80
82
|
def translate phrase
|
|
81
|
-
chain = Parser.chain(Parser.parse(phrase))
|
|
83
|
+
chain = Parser.chain(Parser.parse(phrase, cursor.filename, cursor.position.line))
|
|
82
84
|
chain.define(api_map, closure, locals)
|
|
83
85
|
end
|
|
84
86
|
|
|
@@ -92,6 +94,7 @@ module Solargraph
|
|
|
92
94
|
|
|
93
95
|
# @return [SourceMap]
|
|
94
96
|
def source_map
|
|
97
|
+
# @sg-ignore Need to add nil check here
|
|
95
98
|
@source_map ||= api_map.source_map(cursor.filename)
|
|
96
99
|
end
|
|
97
100
|
|
|
@@ -150,16 +153,23 @@ module Solargraph
|
|
|
150
153
|
# @return [Completion]
|
|
151
154
|
def tag_complete
|
|
152
155
|
result = []
|
|
156
|
+
# @sg-ignore Need to add nil check here
|
|
153
157
|
match = source_map.code[0..cursor.offset-1].match(/[\[<, ]([a-z0-9_:]*)\z/i)
|
|
154
158
|
if match
|
|
159
|
+
# @sg-ignore Need to add nil check here
|
|
155
160
|
full = match[1]
|
|
161
|
+
# @sg-ignore Need to add nil check here
|
|
156
162
|
if full.include?('::')
|
|
163
|
+
# @sg-ignore Need to add nil check here
|
|
157
164
|
if full.end_with?('::')
|
|
165
|
+
# @sg-ignore Need to add nil check here
|
|
158
166
|
result.concat api_map.get_constants(full[0..-3], *gates)
|
|
159
167
|
else
|
|
168
|
+
# @sg-ignore Need to add nil check here
|
|
160
169
|
result.concat api_map.get_constants(full.split('::')[0..-2].join('::'), *gates)
|
|
161
170
|
end
|
|
162
171
|
else
|
|
172
|
+
# @sg-ignore Need to add nil check here
|
|
163
173
|
result.concat api_map.get_constants('', full.end_with?('::') ? '' : context_pin.full_context.namespace, *gates) #.select { |pin| pin.name.start_with?(full) }
|
|
164
174
|
end
|
|
165
175
|
end
|
|
@@ -176,6 +186,7 @@ module Solargraph
|
|
|
176
186
|
cursor.chain.base.infer(api_map, context_pin, locals)
|
|
177
187
|
else
|
|
178
188
|
if full.include?('::') && cursor.chain.links.length == 1
|
|
189
|
+
# @sg-ignore Need to add nil check here
|
|
179
190
|
ComplexType.try_parse(full.split('::')[0..-2].join('::'))
|
|
180
191
|
elsif cursor.chain.links.length > 1
|
|
181
192
|
ComplexType.try_parse(full)
|
|
@@ -199,7 +210,7 @@ module Solargraph
|
|
|
199
210
|
if cursor.word.start_with?('@@')
|
|
200
211
|
return package_completions(api_map.get_class_variable_pins(context_pin.full_context.namespace))
|
|
201
212
|
elsif cursor.word.start_with?('@')
|
|
202
|
-
return package_completions(api_map.get_instance_variable_pins(closure.
|
|
213
|
+
return package_completions(api_map.get_instance_variable_pins(closure.full_context.namespace, closure.context.scope))
|
|
203
214
|
elsif cursor.word.start_with?('$')
|
|
204
215
|
return package_completions(api_map.get_global_variable_pins)
|
|
205
216
|
end
|
|
@@ -8,13 +8,16 @@ module Solargraph
|
|
|
8
8
|
@source = source
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
11
12
|
# @return [Array<Solargraph::Pin::Base>]
|
|
13
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1100
|
|
12
14
|
def pins
|
|
13
15
|
generate
|
|
14
16
|
@pins || []
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
# @
|
|
19
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
20
|
+
# @return [Array<Solargraph::Pin::LocalVariable>]
|
|
18
21
|
def locals
|
|
19
22
|
generate
|
|
20
23
|
@locals || []
|
|
@@ -24,6 +24,7 @@ module Solargraph
|
|
|
24
24
|
@code = source.code
|
|
25
25
|
@comments = source.comments
|
|
26
26
|
@pins, @locals = Parser.map(source)
|
|
27
|
+
# @param p [Solargraph::Pin::Base]
|
|
27
28
|
@pins.each { |p| p.source = :code }
|
|
28
29
|
@locals.each { |l| l.source = :code }
|
|
29
30
|
process_comment_directives
|
|
@@ -48,6 +49,7 @@ module Solargraph
|
|
|
48
49
|
# @param source [Source]
|
|
49
50
|
# @return [Array]
|
|
50
51
|
def map source
|
|
52
|
+
# @sg-ignore Need to add nil check here
|
|
51
53
|
return new.unmap(source.filename, source.code) unless source.parsed?
|
|
52
54
|
new.map source
|
|
53
55
|
end
|
|
@@ -62,6 +64,7 @@ module Solargraph
|
|
|
62
64
|
# @param position [Solargraph::Position]
|
|
63
65
|
# @return [Solargraph::Pin::Closure]
|
|
64
66
|
def closure_at(position)
|
|
67
|
+
# @sg-ignore Need to add nil check here
|
|
65
68
|
pins.select{|pin| pin.is_a?(Pin::Closure) and pin.location.range.contain?(position)}.last
|
|
66
69
|
end
|
|
67
70
|
|
|
@@ -90,11 +93,13 @@ module Solargraph
|
|
|
90
93
|
def find_directive_line_number comment, tag, start
|
|
91
94
|
# Avoid overruning the index
|
|
92
95
|
return start unless start < comment.lines.length
|
|
96
|
+
# @sg-ignore Need to add nil check here
|
|
93
97
|
num = comment.lines[start..-1].find_index do |line|
|
|
94
98
|
# Legacy method directives might be `@method` instead of `@!method`
|
|
95
99
|
# @todo Legacy syntax should probably emit a warning
|
|
96
100
|
line.include?("@!#{tag}") || (tag == 'method' && line.include?("@#{tag}"))
|
|
97
101
|
end
|
|
102
|
+
# @sg-ignore Need to add nil check here
|
|
98
103
|
num.to_i + start
|
|
99
104
|
end
|
|
100
105
|
|
|
@@ -103,17 +108,21 @@ module Solargraph
|
|
|
103
108
|
# @param directive [YARD::Tags::Directive]
|
|
104
109
|
# @return [void]
|
|
105
110
|
def process_directive source_position, comment_position, directive
|
|
111
|
+
# @sg-ignore Need to add nil check here
|
|
106
112
|
docstring = Solargraph::Source.parse_docstring(directive.tag.text).to_docstring
|
|
107
113
|
location = Location.new(@filename, Range.new(comment_position, comment_position))
|
|
108
114
|
case directive.tag.tag_name
|
|
109
115
|
when 'method'
|
|
110
116
|
namespace = closure_at(source_position) || @pins.first
|
|
117
|
+
# @todo Missed nil violation
|
|
118
|
+
# @todo Need to add nil check here
|
|
111
119
|
if namespace.location.range.start.line < comment_position.line
|
|
112
120
|
namespace = closure_at(comment_position)
|
|
113
121
|
end
|
|
114
122
|
begin
|
|
115
123
|
src = Solargraph::Source.load_string("def #{directive.tag.name};end", @source.filename)
|
|
116
124
|
region = Parser::Region.new(source: src, closure: namespace)
|
|
125
|
+
# @type [Array<Pin::Method>]
|
|
117
126
|
method_gen_pins = Parser.process_node(src.node, region).first.select { |pin| pin.is_a?(Pin::Method) }
|
|
118
127
|
gen_pin = method_gen_pins.last
|
|
119
128
|
return if gen_pin.nil?
|
|
@@ -165,10 +174,13 @@ module Solargraph
|
|
|
165
174
|
when 'visibility'
|
|
166
175
|
|
|
167
176
|
kind = directive.tag.text&.to_sym
|
|
177
|
+
# @sg-ignore Need to look at Tuple#include? handling
|
|
168
178
|
return unless [:private, :protected, :public].include?(kind)
|
|
169
179
|
|
|
170
180
|
name = directive.tag.name
|
|
171
181
|
closure = closure_at(source_position) || @pins.first
|
|
182
|
+
# @todo Missed nil violation
|
|
183
|
+
# @todo Need to add nil check here
|
|
172
184
|
if closure.location.range.start.line < comment_position.line
|
|
173
185
|
closure = closure_at(comment_position)
|
|
174
186
|
end
|
|
@@ -186,6 +198,7 @@ module Solargraph
|
|
|
186
198
|
when 'parse'
|
|
187
199
|
begin
|
|
188
200
|
ns = closure_at(source_position)
|
|
201
|
+
# @sg-ignore Need to add nil check here
|
|
189
202
|
src = Solargraph::Source.load_string(directive.tag.text, @source.filename)
|
|
190
203
|
region = Parser::Region.new(source: src, closure: ns)
|
|
191
204
|
# @todo These pins may need to be marked not explicit
|
|
@@ -195,7 +208,11 @@ module Solargraph
|
|
|
195
208
|
else
|
|
196
209
|
comment_position.line
|
|
197
210
|
end
|
|
198
|
-
|
|
211
|
+
locals = []
|
|
212
|
+
ivars = []
|
|
213
|
+
Parser.process_node(src.node, region, @pins, locals, ivars)
|
|
214
|
+
@pins.concat ivars
|
|
215
|
+
# @sg-ignore Need to add nil check here
|
|
199
216
|
@pins[index..-1].each do |p|
|
|
200
217
|
# @todo Smelly instance variable access
|
|
201
218
|
p.location.range.start.instance_variable_set(:@line, p.location.range.start.line + loff)
|
|
@@ -206,8 +223,10 @@ module Solargraph
|
|
|
206
223
|
end
|
|
207
224
|
when 'domain'
|
|
208
225
|
namespace = closure_at(source_position) || Pin::ROOT_PIN
|
|
226
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
209
227
|
namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
|
|
210
228
|
when 'override'
|
|
229
|
+
# @sg-ignore Need to add nil check here
|
|
211
230
|
pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags,
|
|
212
231
|
source: :source_map)
|
|
213
232
|
when 'macro'
|
|
@@ -217,7 +236,9 @@ module Solargraph
|
|
|
217
236
|
|
|
218
237
|
# @param line1 [Integer]
|
|
219
238
|
# @param line2 [Integer]
|
|
239
|
+
# @sg-ignore Need to add nil check here
|
|
220
240
|
def no_empty_lines?(line1, line2)
|
|
241
|
+
# @sg-ignore Need to add nil check here
|
|
221
242
|
@code.lines[line1..line2].none? { |line| line.strip.empty? }
|
|
222
243
|
end
|
|
223
244
|
|
|
@@ -235,6 +256,7 @@ module Solargraph
|
|
|
235
256
|
started = true
|
|
236
257
|
elsif started && !p.strip.empty?
|
|
237
258
|
cur = p.index(/[^ ]/)
|
|
259
|
+
# @sg-ignore Need to add nil check here
|
|
238
260
|
num = cur if cur < num
|
|
239
261
|
end
|
|
240
262
|
ctxt += "#{p[num..-1]}" if started
|
|
@@ -248,6 +270,7 @@ module Solargraph
|
|
|
248
270
|
code_lines = @code.lines
|
|
249
271
|
@source.associated_comments.each do |line, comments|
|
|
250
272
|
src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
|
|
273
|
+
# @sg-ignore Need to add nil check here
|
|
251
274
|
com_pos = Position.new(line + 1 - comments.lines.length, 0)
|
|
252
275
|
process_comment(src_pos, com_pos, comments)
|
|
253
276
|
end
|
|
@@ -34,6 +34,8 @@ module Solargraph
|
|
|
34
34
|
# @param source [Source]
|
|
35
35
|
def initialize source
|
|
36
36
|
@source = source
|
|
37
|
+
# @type [Array<Pin::Base>, nil]
|
|
38
|
+
@convention_pins = nil
|
|
37
39
|
|
|
38
40
|
conventions_environ.merge Convention.for_local(self) unless filename.nil?
|
|
39
41
|
# FIXME: unmemoizing the document_symbols in case it was called and memoized from any of conventions above
|
|
@@ -63,7 +65,7 @@ module Solargraph
|
|
|
63
65
|
@api_hash ||= (pins_by_class(Pin::Constant) + pins_by_class(Pin::Namespace).select { |pin| pin.namespace.to_s > '' } + pins_by_class(Pin::Reference) + pins_by_class(Pin::Method).map(&:node) + locals).hash
|
|
64
66
|
end
|
|
65
67
|
|
|
66
|
-
# @return [String]
|
|
68
|
+
# @return [String, nil]
|
|
67
69
|
def filename
|
|
68
70
|
source.filename
|
|
69
71
|
end
|
|
@@ -84,6 +86,7 @@ module Solargraph
|
|
|
84
86
|
end
|
|
85
87
|
|
|
86
88
|
# all pins except Solargraph::Pin::Reference::Reference
|
|
89
|
+
#
|
|
87
90
|
# @return [Array<Pin::Base>]
|
|
88
91
|
def document_symbols
|
|
89
92
|
@document_symbols ||= (pins + convention_pins).select do |pin|
|
|
@@ -97,7 +100,7 @@ module Solargraph
|
|
|
97
100
|
Pin::Search.new(document_symbols, query).results
|
|
98
101
|
end
|
|
99
102
|
|
|
100
|
-
# @param position [Position]
|
|
103
|
+
# @param position [Position, Array(Integer, Integer)]
|
|
101
104
|
# @return [Source::Cursor]
|
|
102
105
|
def cursor_at position
|
|
103
106
|
Source::Cursor.new(source, position)
|
|
@@ -125,7 +128,7 @@ module Solargraph
|
|
|
125
128
|
|
|
126
129
|
# @param line [Integer]
|
|
127
130
|
# @param character [Integer]
|
|
128
|
-
# @return [Pin::
|
|
131
|
+
# @return [Pin::Closure]
|
|
129
132
|
def locate_closure_pin line, character
|
|
130
133
|
_locate_pin line, character, Pin::Closure
|
|
131
134
|
end
|
|
@@ -143,7 +146,7 @@ module Solargraph
|
|
|
143
146
|
# @return [Array<Pin::LocalVariable>]
|
|
144
147
|
def locals_at(location)
|
|
145
148
|
return [] if location.filename != filename
|
|
146
|
-
closure =
|
|
149
|
+
closure = locate_closure_pin(location.range.start.line, location.range.start.character)
|
|
147
150
|
locals.select { |pin| pin.visible_at?(closure, location) }
|
|
148
151
|
end
|
|
149
152
|
|
|
@@ -178,6 +181,7 @@ module Solargraph
|
|
|
178
181
|
|
|
179
182
|
# @return [Hash{Class<Pin::Base> => Array<Pin::Base>}]
|
|
180
183
|
def pin_class_hash
|
|
184
|
+
# @todo Need to support generic resolution in classify and transform_values
|
|
181
185
|
@pin_class_hash ||= pins.to_set.classify(&:class).transform_values(&:to_a)
|
|
182
186
|
end
|
|
183
187
|
|
|
@@ -191,10 +195,12 @@ module Solargraph
|
|
|
191
195
|
@convention_pins || []
|
|
192
196
|
end
|
|
193
197
|
|
|
198
|
+
# @generic T
|
|
194
199
|
# @param line [Integer]
|
|
195
200
|
# @param character [Integer]
|
|
196
|
-
# @param klasses [Array<Class
|
|
197
|
-
# @return [
|
|
201
|
+
# @param klasses [Array<Class<generic<T>>>]
|
|
202
|
+
# @return [generic<T>, nil]
|
|
203
|
+
# @sg-ignore Need better generic inference here
|
|
198
204
|
def _locate_pin line, character, *klasses
|
|
199
205
|
position = Position.new(line, character)
|
|
200
206
|
found = nil
|
|
@@ -202,7 +208,9 @@ module Solargraph
|
|
|
202
208
|
# @todo Attribute pins should not be treated like closures, but
|
|
203
209
|
# there's probably a better way to handle it
|
|
204
210
|
next if pin.is_a?(Pin::Method) && pin.attribute?
|
|
211
|
+
# @sg-ignore Need to add nil check here
|
|
205
212
|
found = pin if (klasses.empty? || klasses.any? { |kls| pin.is_a?(kls) } ) && pin.location.range.contain?(position)
|
|
213
|
+
# @sg-ignore Need to add nil check here
|
|
206
214
|
break if pin.location.range.start.line > line
|
|
207
215
|
end
|
|
208
216
|
# Assuming the root pin is always valid
|
|
@@ -5,19 +5,21 @@ module Solargraph
|
|
|
5
5
|
# A problem reported by TypeChecker.
|
|
6
6
|
#
|
|
7
7
|
class Problem
|
|
8
|
+
# @todo Missed nil violation
|
|
8
9
|
# @return [Solargraph::Location]
|
|
9
10
|
attr_reader :location
|
|
10
11
|
|
|
11
12
|
# @return [String]
|
|
12
13
|
attr_reader :message
|
|
13
14
|
|
|
15
|
+
# @todo Missed nil violation
|
|
14
16
|
# @return [Pin::Base]
|
|
15
17
|
attr_reader :pin
|
|
16
18
|
|
|
17
19
|
# @return [String, nil]
|
|
18
20
|
attr_reader :suggestion
|
|
19
21
|
|
|
20
|
-
# @param location [Solargraph::Location]
|
|
22
|
+
# @param location [Solargraph::Location, nil]
|
|
21
23
|
# @param message [String]
|
|
22
24
|
# @param pin [Solargraph::Pin::Base, nil]
|
|
23
25
|
# @param suggestion [String, nil]
|