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
|
@@ -35,9 +35,10 @@ module Solargraph
|
|
|
35
35
|
# @param node [Parser::AST::Node]
|
|
36
36
|
# @param region [Region]
|
|
37
37
|
# @param pins [Array<Pin::Base>]
|
|
38
|
-
# @param locals [Array<Pin::
|
|
39
|
-
# @
|
|
40
|
-
|
|
38
|
+
# @param locals [Array<Pin::LocalVariable>]
|
|
39
|
+
# @param ivars [Array<Pin::InstanceVariable>]
|
|
40
|
+
# @return [Array(Array<Pin::Base>, Array<Pin::LocalVariable>, Array<Pin::InstanceVariable>)]
|
|
41
|
+
def self.process node, region = Region.new, pins = [], locals = [], ivars = []
|
|
41
42
|
if pins.empty?
|
|
42
43
|
pins.push Pin::Namespace.new(
|
|
43
44
|
location: region.source.location,
|
|
@@ -45,17 +46,17 @@ module Solargraph
|
|
|
45
46
|
source: :parser,
|
|
46
47
|
)
|
|
47
48
|
end
|
|
48
|
-
return [pins, locals] unless Parser.is_ast_node?(node)
|
|
49
|
+
return [pins, locals, ivars] unless Parser.is_ast_node?(node)
|
|
49
50
|
node_processor_classes = @@processors[node.type] || [NodeProcessor::Base]
|
|
50
51
|
|
|
51
52
|
node_processor_classes.each do |klass|
|
|
52
|
-
processor = klass.new(node, region, pins, locals)
|
|
53
|
+
processor = klass.new(node, region, pins, locals, ivars)
|
|
53
54
|
process_next = processor.process
|
|
54
55
|
|
|
55
56
|
break unless process_next
|
|
56
57
|
end
|
|
57
58
|
|
|
58
|
-
[pins, locals]
|
|
59
|
+
[pins, locals, ivars]
|
|
59
60
|
end
|
|
60
61
|
end
|
|
61
62
|
end
|
|
@@ -8,19 +8,23 @@ module Solargraph
|
|
|
8
8
|
module ClassMethods
|
|
9
9
|
# @param code [String]
|
|
10
10
|
# @param filename [String, nil]
|
|
11
|
+
# @param starting_line [Integer] must be provided so that we
|
|
12
|
+
# can find relevant local variables later even if this is just
|
|
13
|
+
# a subset of the file in question
|
|
11
14
|
# @return [Array(Parser::AST::Node, Hash{Integer => Solargraph::Parser::Snippet})]
|
|
12
|
-
def parse_with_comments code, filename = nil
|
|
13
|
-
node = parse(code, filename)
|
|
15
|
+
def parse_with_comments code, filename = nil, starting_line = 0
|
|
16
|
+
node = parse(code, filename, starting_line)
|
|
14
17
|
comments = CommentRipper.new(code, filename, 0).parse
|
|
15
18
|
[node, comments]
|
|
16
19
|
end
|
|
17
20
|
|
|
18
21
|
# @param code [String]
|
|
19
22
|
# @param filename [String, nil]
|
|
20
|
-
# @param
|
|
23
|
+
# @param starting_line [Integer]
|
|
24
|
+
# @sg-ignore need to understand that raise does not return
|
|
21
25
|
# @return [Parser::AST::Node]
|
|
22
|
-
def parse code, filename = nil,
|
|
23
|
-
buffer = ::Parser::Source::Buffer.new(filename,
|
|
26
|
+
def parse code, filename = nil, starting_line = 0
|
|
27
|
+
buffer = ::Parser::Source::Buffer.new(filename, starting_line)
|
|
24
28
|
buffer.source = code
|
|
25
29
|
parser.parse(buffer)
|
|
26
30
|
rescue ::Parser::SyntaxError, ::Parser::UnknownEncodingInMagicComment => e
|
|
@@ -30,15 +34,20 @@ module Solargraph
|
|
|
30
34
|
# @return [::Parser::Base]
|
|
31
35
|
def parser
|
|
32
36
|
@parser ||= Prism::Translation::Parser.new(FlawedBuilder.new).tap do |parser|
|
|
37
|
+
# @sg-ignore Unresolved call to diagnostics on Prism::Translation::Parser
|
|
33
38
|
parser.diagnostics.all_errors_are_fatal = true
|
|
39
|
+
# @sg-ignore Unresolved call to diagnostics on Prism::Translation::Parser
|
|
34
40
|
parser.diagnostics.ignore_warnings = true
|
|
35
41
|
end
|
|
36
42
|
end
|
|
37
43
|
|
|
38
44
|
# @param source [Source]
|
|
39
|
-
# @return [Array(Array<Pin::Base>, Array<Pin::
|
|
45
|
+
# @return [Array(Array<Pin::Base>, Array<Pin::LocalVariable>)]
|
|
40
46
|
def map source
|
|
41
|
-
|
|
47
|
+
# @sg-ignore Need to add nil check here
|
|
48
|
+
pins, locals, ivars = NodeProcessor.process(source.node, Region.new(source: source))
|
|
49
|
+
pins.concat(ivars)
|
|
50
|
+
[pins, locals]
|
|
42
51
|
end
|
|
43
52
|
|
|
44
53
|
# @param source [Source]
|
|
@@ -50,15 +59,18 @@ module Solargraph
|
|
|
50
59
|
# @param code [String]
|
|
51
60
|
# @param offset [Integer]
|
|
52
61
|
# @return [Array(Integer, Integer), Array(nil, nil)]
|
|
62
|
+
# @sg-ignore Need to add nil check here
|
|
53
63
|
extract_offset = ->(code, offset) { reg.match(code, offset).offset(0) }
|
|
54
64
|
else
|
|
55
65
|
# @param code [String]
|
|
56
66
|
# @param offset [Integer]
|
|
57
67
|
# @return [Array(Integer, Integer), Array(nil, nil)]
|
|
68
|
+
# @sg-ignore Need to add nil check here
|
|
58
69
|
extract_offset = ->(code, offset) { [soff = code.index(name, offset), soff + name.length] }
|
|
59
70
|
end
|
|
60
71
|
inner_node_references(name, source.node).map do |n|
|
|
61
72
|
rng = Range.from_node(n)
|
|
73
|
+
# @sg-ignore Need to add nil check here
|
|
62
74
|
offset = Position.to_offset(source.code, rng.start)
|
|
63
75
|
soff, eoff = extract_offset[source.code, offset]
|
|
64
76
|
Location.new(
|
|
@@ -99,7 +111,7 @@ module Solargraph
|
|
|
99
111
|
Solargraph::Parser::NodeProcessor.process *args
|
|
100
112
|
end
|
|
101
113
|
|
|
102
|
-
# @param node [Parser::AST::Node]
|
|
114
|
+
# @param node [Parser::AST::Node, nil]
|
|
103
115
|
# @return [String, nil]
|
|
104
116
|
def infer_literal_node_type node
|
|
105
117
|
NodeMethods.infer_literal_node_type node
|
|
@@ -110,7 +122,7 @@ module Solargraph
|
|
|
110
122
|
parser.version
|
|
111
123
|
end
|
|
112
124
|
|
|
113
|
-
# @param node [BasicObject]
|
|
125
|
+
# @param node [BasicObject, nil]
|
|
114
126
|
# @return [Boolean]
|
|
115
127
|
def is_ast_node? node
|
|
116
128
|
node.is_a?(::Parser::AST::Node)
|
|
@@ -124,19 +136,25 @@ module Solargraph
|
|
|
124
136
|
Range.new(st, en)
|
|
125
137
|
end
|
|
126
138
|
|
|
127
|
-
# @param node [Parser::AST::Node]
|
|
139
|
+
# @param node [Parser::AST::Node, nil]
|
|
128
140
|
# @return [Array<Range>]
|
|
129
141
|
def string_ranges node
|
|
130
142
|
return [] unless is_ast_node?(node)
|
|
131
143
|
result = []
|
|
144
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
132
145
|
result.push Range.from_node(node) if node.type == :str
|
|
146
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
133
147
|
node.children.each do |child|
|
|
134
148
|
result.concat string_ranges(child)
|
|
135
149
|
end
|
|
150
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
136
151
|
if node.type == :dstr && node.children.last.nil?
|
|
152
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
137
153
|
last = node.children[-2]
|
|
154
|
+
# @sg-ignore Need to add nil check here
|
|
138
155
|
unless last.nil?
|
|
139
156
|
rng = Range.from_node(last)
|
|
157
|
+
# @sg-ignore Need to add nil check here
|
|
140
158
|
pos = Position.new(rng.ending.line, rng.ending.column - 1)
|
|
141
159
|
result.push Range.new(pos, pos)
|
|
142
160
|
end
|
|
@@ -35,9 +35,12 @@ module Solargraph
|
|
|
35
35
|
end
|
|
36
36
|
|
|
37
37
|
# @param code [String]
|
|
38
|
+
# @param filename [String]
|
|
39
|
+
# @param starting_line [Integer]
|
|
40
|
+
#
|
|
38
41
|
# @return [Source::Chain]
|
|
39
|
-
def load_string(code)
|
|
40
|
-
node = Parser.parse(code.sub(/\.$/, ''))
|
|
42
|
+
def load_string(code, filename, starting_line)
|
|
43
|
+
node = Parser.parse(code.sub(/\.$/, ''), filename, starting_line)
|
|
41
44
|
chain = NodeChainer.new(node).chain
|
|
42
45
|
chain.links.push(Chain::Link.new) if code.end_with?('.')
|
|
43
46
|
chain
|
|
@@ -61,6 +64,7 @@ module Solargraph
|
|
|
61
64
|
result.push Chain::Call.new(n.children[1].to_s, Location.from_node(n), node_args(n), passed_block(n))
|
|
62
65
|
elsif n.children[0].nil?
|
|
63
66
|
args = []
|
|
67
|
+
# @sg-ignore Need to add nil check here
|
|
64
68
|
n.children[2..-1].each do |c|
|
|
65
69
|
args.push NodeChainer.chain(c, @filename, n)
|
|
66
70
|
end
|
|
@@ -93,14 +97,22 @@ module Solargraph
|
|
|
93
97
|
elsif [:lvar, :lvasgn].include?(n.type)
|
|
94
98
|
result.push Chain::Call.new(n.children[0].to_s, Location.from_node(n))
|
|
95
99
|
elsif [:ivar, :ivasgn].include?(n.type)
|
|
96
|
-
result.push Chain::InstanceVariable.new(n.children[0].to_s)
|
|
100
|
+
result.push Chain::InstanceVariable.new(n.children[0].to_s, n, Location.from_node(n))
|
|
97
101
|
elsif [:cvar, :cvasgn].include?(n.type)
|
|
98
102
|
result.push Chain::ClassVariable.new(n.children[0].to_s)
|
|
99
103
|
elsif [:gvar, :gvasgn].include?(n.type)
|
|
100
104
|
result.push Chain::GlobalVariable.new(n.children[0].to_s)
|
|
101
105
|
elsif n.type == :or_asgn
|
|
102
|
-
|
|
103
|
-
|
|
106
|
+
# @bar ||= 123 translates to:
|
|
107
|
+
#
|
|
108
|
+
# s(:or_asgn,
|
|
109
|
+
# s(:ivasgn, :@bar),
|
|
110
|
+
# s(:int, 123))
|
|
111
|
+
lhs_chain = NodeChainer.chain n.children[0] # s(:ivasgn, :@bar)
|
|
112
|
+
rhs_chain = NodeChainer.chain n.children[1] # s(:int, 123)
|
|
113
|
+
or_link = Chain::Or.new([lhs_chain, rhs_chain])
|
|
114
|
+
# this is just for a call chain, so we don't need to record the assignment
|
|
115
|
+
result.push(or_link)
|
|
104
116
|
elsif [:class, :module, :def, :defs].include?(n.type)
|
|
105
117
|
# @todo Undefined or what?
|
|
106
118
|
result.push Chain::UNDEFINED_CALL
|
|
@@ -109,7 +121,17 @@ module Solargraph
|
|
|
109
121
|
elsif n.type == :or
|
|
110
122
|
result.push Chain::Or.new([NodeChainer.chain(n.children[0], @filename), NodeChainer.chain(n.children[1], @filename, n)])
|
|
111
123
|
elsif n.type == :if
|
|
112
|
-
|
|
124
|
+
then_clause = if n.children[1]
|
|
125
|
+
NodeChainer.chain(n.children[1], @filename, n)
|
|
126
|
+
else
|
|
127
|
+
Source::Chain.new([Source::Chain::Literal.new('nil', nil)], n)
|
|
128
|
+
end
|
|
129
|
+
else_clause = if n.children[2]
|
|
130
|
+
NodeChainer.chain(n.children[2], @filename, n)
|
|
131
|
+
else
|
|
132
|
+
Source::Chain.new([Source::Chain::Literal.new('nil', nil)], n)
|
|
133
|
+
end
|
|
134
|
+
result.push Chain::If.new([then_clause, else_clause])
|
|
113
135
|
elsif [:begin, :kwbegin].include?(n.type)
|
|
114
136
|
result.concat generate_links(n.children.last)
|
|
115
137
|
elsif n.type == :block_pass
|
|
@@ -150,12 +172,15 @@ module Solargraph
|
|
|
150
172
|
def passed_block node
|
|
151
173
|
return unless node == @node && @parent&.type == :block
|
|
152
174
|
|
|
175
|
+
# @sg-ignore Need to add nil check here
|
|
153
176
|
NodeChainer.chain(@parent.children[2], @filename)
|
|
154
177
|
end
|
|
155
178
|
|
|
156
179
|
# @param node [Parser::AST::Node]
|
|
180
|
+
# @sg-ignore Need to add nil check here
|
|
157
181
|
# @return [Array<Source::Chain>]
|
|
158
182
|
def node_args node
|
|
183
|
+
# @sg-ignore Need to add nil check here
|
|
159
184
|
node.children[2..-1].map do |child|
|
|
160
185
|
NodeChainer.chain(child, @filename, node)
|
|
161
186
|
end
|
|
@@ -37,7 +37,7 @@ module Solargraph
|
|
|
37
37
|
parts
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
# @param node [Parser::AST::Node]
|
|
40
|
+
# @param node [Parser::AST::Node, nil]
|
|
41
41
|
# @return [String, nil]
|
|
42
42
|
def infer_literal_node_type node
|
|
43
43
|
return nil unless node.is_a?(AST::Node)
|
|
@@ -105,21 +105,24 @@ module Solargraph
|
|
|
105
105
|
signature
|
|
106
106
|
end
|
|
107
107
|
|
|
108
|
-
# @param node [Parser::AST::Node]
|
|
108
|
+
# @param node [Parser::AST::Node, nil]
|
|
109
109
|
# @return [Hash{Symbol => Chain}]
|
|
110
110
|
def convert_hash node
|
|
111
111
|
return {} unless Parser.is_ast_node?(node)
|
|
112
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
112
113
|
return convert_hash(node.children[0]) if node.type == :kwsplat
|
|
114
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
113
115
|
return convert_hash(node.children[0]) if Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat
|
|
116
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
114
117
|
return {} unless node.type == :hash
|
|
115
118
|
result = {}
|
|
119
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
116
120
|
node.children.each do |pair|
|
|
117
121
|
result[pair.children[0].children[0]] = Solargraph::Parser.chain(pair.children[1])
|
|
118
122
|
end
|
|
119
123
|
result
|
|
120
124
|
end
|
|
121
125
|
|
|
122
|
-
# @sg-ignore Wrong argument type for AST::Node.new: type expected AST::_ToSym, received :nil
|
|
123
126
|
NIL_NODE = ::Parser::AST::Node.new(:nil)
|
|
124
127
|
|
|
125
128
|
# @param node [Parser::AST::Node]
|
|
@@ -161,12 +164,15 @@ module Solargraph
|
|
|
161
164
|
if node.type == :block
|
|
162
165
|
result.push node
|
|
163
166
|
if Parser.is_ast_node?(node.children[0]) && node.children[0].children.length > 2
|
|
167
|
+
# @sg-ignore Need to add nil check here
|
|
164
168
|
node.children[0].children[2..-1].each { |child| result.concat call_nodes_from(child) }
|
|
165
169
|
end
|
|
170
|
+
# @sg-ignore Need to add nil check here
|
|
166
171
|
node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
|
|
167
172
|
elsif node.type == :send
|
|
168
173
|
result.push node
|
|
169
174
|
result.concat call_nodes_from(node.children.first)
|
|
175
|
+
# @sg-ignore Need to add nil check here
|
|
170
176
|
node.children[2..-1].each { |child| result.concat call_nodes_from(child) }
|
|
171
177
|
elsif [:super, :zsuper].include?(node.type)
|
|
172
178
|
result.push node
|
|
@@ -211,8 +217,10 @@ module Solargraph
|
|
|
211
217
|
position = cursor.position
|
|
212
218
|
offset = cursor.offset
|
|
213
219
|
tree = if source.synchronized?
|
|
220
|
+
# @sg-ignore Need to add nil check here
|
|
214
221
|
match = source.code[0..offset-1].match(/,\s*\z/)
|
|
215
222
|
if match
|
|
223
|
+
# @sg-ignore Need to add nil check here
|
|
216
224
|
source.tree_at(position.line, position.column - match[0].length)
|
|
217
225
|
else
|
|
218
226
|
source.tree_at(position.line, position.column)
|
|
@@ -225,7 +233,9 @@ module Solargraph
|
|
|
225
233
|
tree.each do |node|
|
|
226
234
|
if node.type == :send
|
|
227
235
|
args = node.children[2..-1]
|
|
236
|
+
# @sg-ignore Need to add nil check here
|
|
228
237
|
if !args.empty?
|
|
238
|
+
# @sg-ignore Need to add nil check here
|
|
229
239
|
return node if prev && args.include?(prev)
|
|
230
240
|
else
|
|
231
241
|
if source.synchronized?
|
|
@@ -303,7 +313,6 @@ module Solargraph
|
|
|
303
313
|
module DeepInference
|
|
304
314
|
class << self
|
|
305
315
|
CONDITIONAL_ALL_BUT_FIRST = [:if, :unless]
|
|
306
|
-
CONDITIONAL_ALL = [:or]
|
|
307
316
|
ONLY_ONE_CHILD = [:return]
|
|
308
317
|
FIRST_TWO_CHILDREN = [:rescue]
|
|
309
318
|
COMPOUND_STATEMENTS = [:begin, :kwbegin]
|
|
@@ -334,7 +343,7 @@ module Solargraph
|
|
|
334
343
|
# Look at known control statements and use them to find
|
|
335
344
|
# more specific return nodes.
|
|
336
345
|
#
|
|
337
|
-
# @param node [
|
|
346
|
+
# @param node [AST::Node] Statement which is in
|
|
338
347
|
# value position for a method body
|
|
339
348
|
# @param include_explicit_returns [Boolean] If true,
|
|
340
349
|
# include the value nodes of the parameter of the
|
|
@@ -348,10 +357,9 @@ module Solargraph
|
|
|
348
357
|
if COMPOUND_STATEMENTS.include?(node.type)
|
|
349
358
|
result.concat from_value_position_compound_statement node
|
|
350
359
|
elsif CONDITIONAL_ALL_BUT_FIRST.include?(node.type)
|
|
360
|
+
# @sg-ignore Need to add nil check here
|
|
351
361
|
result.concat reduce_to_value_nodes(node.children[1..-1])
|
|
352
362
|
# result.push NIL_NODE unless node.children[2]
|
|
353
|
-
elsif CONDITIONAL_ALL.include?(node.type)
|
|
354
|
-
result.concat reduce_to_value_nodes(node.children)
|
|
355
363
|
elsif ONLY_ONE_CHILD.include?(node.type)
|
|
356
364
|
result.concat reduce_to_value_nodes([node.children[0]])
|
|
357
365
|
elsif FIRST_TWO_CHILDREN.include?(node.type)
|
|
@@ -364,6 +372,7 @@ module Solargraph
|
|
|
364
372
|
# that the function is executed here.
|
|
365
373
|
result.concat explicit_return_values_from_compound_statement(node.children[2]) if include_explicit_returns
|
|
366
374
|
elsif CASE_STATEMENT.include?(node.type)
|
|
375
|
+
# @sg-ignore Need to add nil check here
|
|
367
376
|
node.children[1..-1].each do |cc|
|
|
368
377
|
if cc.nil?
|
|
369
378
|
result.push NIL_NODE
|
|
@@ -460,17 +469,28 @@ module Solargraph
|
|
|
460
469
|
nodes.each do |node|
|
|
461
470
|
if !node.is_a?(::Parser::AST::Node)
|
|
462
471
|
result.push nil
|
|
472
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
463
473
|
elsif COMPOUND_STATEMENTS.include?(node.type)
|
|
464
474
|
result.concat from_value_position_compound_statement(node)
|
|
475
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
465
476
|
elsif CONDITIONAL_ALL_BUT_FIRST.include?(node.type)
|
|
477
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
466
478
|
result.concat reduce_to_value_nodes(node.children[1..-1])
|
|
479
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
467
480
|
elsif node.type == :return
|
|
481
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
468
482
|
result.concat reduce_to_value_nodes([node.children[0]])
|
|
483
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
469
484
|
elsif node.type == :or
|
|
485
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
470
486
|
result.concat reduce_to_value_nodes(node.children)
|
|
487
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
471
488
|
elsif node.type == :block
|
|
489
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
472
490
|
result.concat explicit_return_values_from_compound_statement(node.children[2])
|
|
491
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
473
492
|
elsif node.type == :resbody
|
|
493
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
474
494
|
result.concat reduce_to_value_nodes([node.children[2]])
|
|
475
495
|
else
|
|
476
496
|
result.push node
|
|
@@ -10,10 +10,10 @@ module Solargraph
|
|
|
10
10
|
def process
|
|
11
11
|
process_children
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
FlowSensitiveTyping.new(locals,
|
|
14
|
+
ivars,
|
|
15
|
+
enclosing_breakable_pin,
|
|
16
|
+
enclosing_compound_statement_pin).process_and(node)
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
end
|
|
@@ -20,6 +20,7 @@ module Solargraph
|
|
|
20
20
|
name: u.children[0].to_s,
|
|
21
21
|
assignment: u.children[1],
|
|
22
22
|
asgn_code: u.children[1] ? region.code_for(u.children[1]) : nil,
|
|
23
|
+
# @sg-ignore Need to add nil check here
|
|
23
24
|
presence: callable.location.range,
|
|
24
25
|
decl: get_decl(u),
|
|
25
26
|
source: :parser
|
|
@@ -40,6 +41,7 @@ module Solargraph
|
|
|
40
41
|
locals.push Solargraph::Pin::Parameter.new(
|
|
41
42
|
location: loc,
|
|
42
43
|
closure: callable,
|
|
44
|
+
# @sg-ignore Need to add nil check here
|
|
43
45
|
presence: region.closure.location.range,
|
|
44
46
|
decl: get_decl(node),
|
|
45
47
|
source: :parser
|
|
@@ -6,6 +6,15 @@ module Solargraph
|
|
|
6
6
|
module NodeProcessors
|
|
7
7
|
class BeginNode < Parser::NodeProcessor::Base
|
|
8
8
|
def process
|
|
9
|
+
# We intentionally don't create a CompoundStatement pin
|
|
10
|
+
# here, as this is not necessarily a control flow block -
|
|
11
|
+
# e.g., a begin...end without rescue or ensure should be
|
|
12
|
+
# treated by flow sensitive typing as if the begin and end
|
|
13
|
+
# didn't exist at all. As such, we create the
|
|
14
|
+
# CompoundStatement pins around the things which actually
|
|
15
|
+
# result in control flow changes - like
|
|
16
|
+
# if/while/rescue/etc
|
|
17
|
+
|
|
9
18
|
process_children
|
|
10
19
|
end
|
|
11
20
|
end
|
|
@@ -9,23 +9,22 @@ module Solargraph
|
|
|
9
9
|
|
|
10
10
|
def process
|
|
11
11
|
location = get_node_location(node)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
else
|
|
20
|
-
region.closure
|
|
12
|
+
scope = region.scope || region.closure.context.scope
|
|
13
|
+
if other_class_eval?
|
|
14
|
+
clazz_name = unpack_name(node.children[0].children[0])
|
|
15
|
+
# instance variables should come from the Class<T> type
|
|
16
|
+
# - i.e., treated as class instance variables
|
|
17
|
+
context = ComplexType.try_parse("Class<#{clazz_name}>")
|
|
18
|
+
scope = :class
|
|
21
19
|
end
|
|
22
20
|
block_pin = Solargraph::Pin::Block.new(
|
|
23
21
|
location: location,
|
|
24
|
-
closure:
|
|
22
|
+
closure: region.closure,
|
|
25
23
|
node: node,
|
|
24
|
+
context: context,
|
|
26
25
|
receiver: node.children[0],
|
|
27
26
|
comments: comments_for(node),
|
|
28
|
-
scope:
|
|
27
|
+
scope: scope,
|
|
29
28
|
source: :parser
|
|
30
29
|
)
|
|
31
30
|
pins.push block_pin
|
|
@@ -37,6 +36,7 @@ module Solargraph
|
|
|
37
36
|
def other_class_eval?
|
|
38
37
|
node.children[0].type == :send &&
|
|
39
38
|
node.children[0].children[1] == :class_eval &&
|
|
39
|
+
# @sg-ignore Need to add nil check here
|
|
40
40
|
[:cbase, :const].include?(node.children[0].children[0]&.type)
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -8,10 +8,15 @@ module Solargraph
|
|
|
8
8
|
def process
|
|
9
9
|
name = node.children[0].to_s
|
|
10
10
|
scope = region.scope || (region.closure.is_a?(Pin::Singleton) ? :class : :instance)
|
|
11
|
+
# specify context explicitly instead of relying on
|
|
12
|
+
# closure, as they may differ (e.g., defs inside
|
|
13
|
+
# class_eval)
|
|
14
|
+
method_context = scope == :instance ? region.closure.binder.namespace_type : region.closure.binder
|
|
11
15
|
methpin = Solargraph::Pin::Method.new(
|
|
12
16
|
location: get_node_location(node),
|
|
13
17
|
closure: region.closure,
|
|
14
18
|
name: name,
|
|
19
|
+
context: method_context,
|
|
15
20
|
comments: comments_for(node),
|
|
16
21
|
scope: scope,
|
|
17
22
|
visibility: scope == :instance && name == 'initialize' ? :private : region.visibility,
|
|
@@ -23,6 +28,7 @@ module Solargraph
|
|
|
23
28
|
location: methpin.location,
|
|
24
29
|
closure: methpin.closure,
|
|
25
30
|
name: methpin.name,
|
|
31
|
+
context: method_context,
|
|
26
32
|
comments: methpin.comments,
|
|
27
33
|
scope: :class,
|
|
28
34
|
visibility: :public,
|
|
@@ -34,6 +40,7 @@ module Solargraph
|
|
|
34
40
|
location: methpin.location,
|
|
35
41
|
closure: methpin.closure,
|
|
36
42
|
name: methpin.name,
|
|
43
|
+
context: method_context,
|
|
37
44
|
comments: methpin.comments,
|
|
38
45
|
scope: :instance,
|
|
39
46
|
visibility: :private,
|
|
@@ -8,13 +8,43 @@ module Solargraph
|
|
|
8
8
|
include ParserGem::NodeMethods
|
|
9
9
|
|
|
10
10
|
def process
|
|
11
|
-
|
|
11
|
+
FlowSensitiveTyping.new(locals,
|
|
12
|
+
ivars,
|
|
13
|
+
enclosing_breakable_pin,
|
|
14
|
+
enclosing_compound_statement_pin).process_if(node)
|
|
15
|
+
condition_node = node.children[0]
|
|
16
|
+
if condition_node
|
|
17
|
+
pins.push Solargraph::Pin::CompoundStatement.new(
|
|
18
|
+
location: get_node_location(condition_node),
|
|
19
|
+
closure: region.closure,
|
|
20
|
+
node: condition_node,
|
|
21
|
+
source: :parser,
|
|
22
|
+
)
|
|
23
|
+
NodeProcessor.process(condition_node, region, pins, locals, ivars)
|
|
24
|
+
end
|
|
25
|
+
then_node = node.children[1]
|
|
26
|
+
if then_node
|
|
27
|
+
pins.push Solargraph::Pin::CompoundStatement.new(
|
|
28
|
+
location: get_node_location(then_node),
|
|
29
|
+
closure: region.closure,
|
|
30
|
+
node: then_node,
|
|
31
|
+
source: :parser,
|
|
32
|
+
)
|
|
33
|
+
NodeProcessor.process(then_node, region, pins, locals, ivars)
|
|
34
|
+
end
|
|
12
35
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
36
|
+
else_node = node.children[2]
|
|
37
|
+
if else_node
|
|
38
|
+
pins.push Solargraph::Pin::CompoundStatement.new(
|
|
39
|
+
location: get_node_location(else_node),
|
|
40
|
+
closure: region.closure,
|
|
41
|
+
node: else_node,
|
|
42
|
+
source: :parser,
|
|
43
|
+
)
|
|
44
|
+
NodeProcessor.process(else_node, region, pins, locals, ivars)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
true
|
|
18
48
|
end
|
|
19
49
|
end
|
|
20
50
|
end
|
|
@@ -9,7 +9,7 @@ module Solargraph
|
|
|
9
9
|
|
|
10
10
|
def process
|
|
11
11
|
loc = get_node_location(node)
|
|
12
|
-
|
|
12
|
+
ivars.push Solargraph::Pin::InstanceVariable.new(
|
|
13
13
|
location: loc,
|
|
14
14
|
closure: region.closure,
|
|
15
15
|
name: node.children[0].to_s,
|
|
@@ -19,9 +19,10 @@ module Solargraph
|
|
|
19
19
|
)
|
|
20
20
|
if region.visibility == :module_function
|
|
21
21
|
here = get_node_start_position(node)
|
|
22
|
+
# @type [Pin::Closure, nil]
|
|
22
23
|
named_path = named_path_pin(here)
|
|
23
24
|
if named_path.is_a?(Pin::Method)
|
|
24
|
-
|
|
25
|
+
ivars.push Solargraph::Pin::InstanceVariable.new(
|
|
25
26
|
location: loc,
|
|
26
27
|
closure: Pin::Namespace.new(type: :module, closure: region.closure.closure, name: region.closure.name),
|
|
27
28
|
name: node.children[0].to_s,
|
|
@@ -9,6 +9,7 @@ module Solargraph
|
|
|
9
9
|
|
|
10
10
|
def process
|
|
11
11
|
here = get_node_start_position(node)
|
|
12
|
+
# @sg-ignore Need to add nil check here
|
|
12
13
|
presence = Range.new(here, region.closure.location.range.ending)
|
|
13
14
|
loc = get_node_location(node)
|
|
14
15
|
locals.push Solargraph::Pin::LocalVariable.new(
|
|
@@ -37,8 +37,10 @@ module Solargraph
|
|
|
37
37
|
pin = if lhs.type == :lvasgn
|
|
38
38
|
# lvasgn is a local variable
|
|
39
39
|
locals.find { |l| l.location == location }
|
|
40
|
+
elsif lhs.type == :ivasgn
|
|
41
|
+
# ivasgn is an instance variable assignment
|
|
42
|
+
ivars.find { |iv| iv.location == location }
|
|
40
43
|
else
|
|
41
|
-
# e.g., ivasgn is an instance variable, etc
|
|
42
44
|
pins.find { |iv| iv.location == location && iv.is_a?(Pin::BaseVariable) }
|
|
43
45
|
end
|
|
44
46
|
# @todo in line below, nothing in typechecking alerts
|
|
@@ -57,7 +57,7 @@ module Solargraph
|
|
|
57
57
|
[callee,
|
|
58
58
|
asgn_method,
|
|
59
59
|
node.updated(:send, [call, operator, argument])])
|
|
60
|
-
NodeProcessor.process(new_send, region, pins, locals)
|
|
60
|
+
NodeProcessor.process(new_send, region, pins, locals, ivars)
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
# @param asgn [Parser::AST::Node] the target of the assignment
|
|
@@ -89,7 +89,7 @@ module Solargraph
|
|
|
89
89
|
]
|
|
90
90
|
send_node = node.updated(:send, send_children)
|
|
91
91
|
new_asgn = node.updated(asgn.type, [variable_name, send_node])
|
|
92
|
-
NodeProcessor.process(new_asgn, region, pins, locals)
|
|
92
|
+
NodeProcessor.process(new_asgn, region, pins, locals, ivars)
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
95
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Parser
|
|
5
|
+
module ParserGem
|
|
6
|
+
module NodeProcessors
|
|
7
|
+
class OrNode < Parser::NodeProcessor::Base
|
|
8
|
+
include ParserGem::NodeMethods
|
|
9
|
+
|
|
10
|
+
def process
|
|
11
|
+
process_children
|
|
12
|
+
|
|
13
|
+
FlowSensitiveTyping.new(locals,
|
|
14
|
+
ivars,
|
|
15
|
+
enclosing_breakable_pin,
|
|
16
|
+
enclosing_compound_statement_pin).process_or(node)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -8,7 +8,7 @@ module Solargraph
|
|
|
8
8
|
# @return [void]
|
|
9
9
|
def process
|
|
10
10
|
new_node = node.updated(node.children[0].type, node.children[0].children + [node.children[1]])
|
|
11
|
-
NodeProcessor.process(new_node, region, pins, locals)
|
|
11
|
+
NodeProcessor.process(new_node, region, pins, locals, ivars)
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -11,6 +11,7 @@ module Solargraph
|
|
|
11
11
|
def process
|
|
12
12
|
if node.children[1] # Exception local variable name
|
|
13
13
|
here = get_node_start_position(node.children[1])
|
|
14
|
+
# @sg-ignore Need to add nil check here
|
|
14
15
|
presence = Range.new(here, region.closure.location.range.ending)
|
|
15
16
|
loc = get_node_location(node.children[1])
|
|
16
17
|
types = if node.children[0].nil?
|
|
@@ -29,7 +30,7 @@ module Solargraph
|
|
|
29
30
|
source: :parser
|
|
30
31
|
)
|
|
31
32
|
end
|
|
32
|
-
NodeProcessor.process(node.children[2], region, pins, locals)
|
|
33
|
+
NodeProcessor.process(node.children[2], region, pins, locals, ivars)
|
|
33
34
|
end
|
|
34
35
|
end
|
|
35
36
|
end
|