solargraph 0.58.3 → 0.60.0
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 +12 -5
- data/.github/workflows/plugins.yml +54 -34
- data/.github/workflows/rspec.yml +18 -28
- data/.github/workflows/typecheck.yml +6 -3
- data/.rubocop.yml +39 -6
- data/.rubocop_todo.yml +53 -966
- data/CHANGELOG.md +35 -0
- data/Gemfile +6 -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 +12 -3
- data/lib/solargraph/api_map/index.rb +42 -20
- data/lib/solargraph/api_map/source_to_yard.rb +22 -9
- data/lib/solargraph/api_map/store.rb +61 -36
- data/lib/solargraph/api_map.rb +192 -78
- data/lib/solargraph/bench.rb +2 -3
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +31 -18
- data/lib/solargraph/complex_type/unique_type.rb +225 -63
- data/lib/solargraph/complex_type.rb +177 -59
- data/lib/solargraph/convention/active_support_concern.rb +111 -111
- data/lib/solargraph/convention/base.rb +50 -50
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
- 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 +1 -1
- data/lib/solargraph/convention/gemspec.rb +1 -1
- data/lib/solargraph/convention/rakefile.rb +1 -1
- 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 +2 -2
- data/lib/solargraph/converters/dd.rb +2 -0
- data/lib/solargraph/converters/dl.rb +2 -0
- data/lib/solargraph/converters/dt.rb +2 -0
- data/lib/solargraph/converters/misc.rb +2 -0
- 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 +4 -8
- data/lib/solargraph/diagnostics.rb +55 -55
- data/lib/solargraph/doc_map.rb +39 -39
- data/lib/solargraph/environ.rb +52 -52
- data/lib/solargraph/equality.rb +4 -4
- data/lib/solargraph/gem_pins.rb +4 -15
- data/lib/solargraph/language_server/error_codes.rb +10 -10
- 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 +35 -28
- data/lib/solargraph/language_server/message/base.rb +1 -1
- data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
- 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 +7 -7
- data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
- data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
- data/lib/solargraph/language_server/message/extended/search.rb +1 -1
- data/lib/solargraph/language_server/message/initialize.rb +20 -14
- data/lib/solargraph/language_server/message/initialized.rb +28 -28
- 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 +17 -10
- 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 +13 -6
- data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
- data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
- 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/text_document.rb +28 -28
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
- data/lib/solargraph/language_server/message.rb +1 -1
- data/lib/solargraph/language_server/progress.rb +143 -143
- data/lib/solargraph/language_server/request.rb +4 -2
- data/lib/solargraph/language_server/transport/adapter.rb +68 -68
- data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
- data/lib/solargraph/language_server/uri_helpers.rb +2 -2
- data/lib/solargraph/language_server.rb +20 -20
- data/lib/solargraph/library.rb +57 -38
- data/lib/solargraph/location.rb +17 -14
- data/lib/solargraph/logging.rb +22 -4
- data/lib/solargraph/page.rb +1 -1
- data/lib/solargraph/parser/comment_ripper.rb +19 -4
- data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -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 +30 -14
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +51 -25
- data/lib/solargraph/parser/parser_gem/node_methods.rb +222 -72
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
- 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 +11 -12
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
- 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/namespace_node.rb +64 -40
- 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/sym_node.rb +20 -20
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
- 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 +2 -0
- data/lib/solargraph/parser/region.rb +9 -3
- data/lib/solargraph/parser/snippet.rb +3 -1
- data/lib/solargraph/parser.rb +2 -0
- data/lib/solargraph/pin/base.rb +156 -84
- 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 +67 -23
- data/lib/solargraph/pin/closure.rb +7 -10
- data/lib/solargraph/pin/common.rb +36 -6
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/constant.rb +3 -5
- 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 +205 -111
- data/lib/solargraph/pin/method_alias.rb +8 -0
- data/lib/solargraph/pin/namespace.rb +19 -12
- data/lib/solargraph/pin/parameter.rb +102 -36
- data/lib/solargraph/pin/proxy_type.rb +4 -1
- data/lib/solargraph/pin/reference/override.rb +1 -1
- data/lib/solargraph/pin/reference/require.rb +14 -14
- data/lib/solargraph/pin/reference/superclass.rb +2 -0
- data/lib/solargraph/pin/reference/type_alias.rb +16 -0
- data/lib/solargraph/pin/reference.rb +20 -0
- data/lib/solargraph/pin/search.rb +8 -7
- data/lib/solargraph/pin/signature.rb +15 -12
- data/lib/solargraph/pin/singleton.rb +11 -11
- 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 +22 -19
- data/lib/solargraph/position.rb +17 -10
- data/lib/solargraph/range.rb +16 -15
- data/lib/solargraph/rbs_map/conversions.rb +278 -191
- data/lib/solargraph/rbs_map/core_fills.rb +18 -11
- 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 +76 -32
- data/lib/solargraph/rbs_translator.rb +206 -0
- data/lib/solargraph/server_methods.rb +1 -1
- data/lib/solargraph/shell.rb +330 -71
- data/lib/solargraph/source/chain/array.rb +3 -12
- data/lib/solargraph/source/chain/block_symbol.rb +13 -13
- data/lib/solargraph/source/chain/block_variable.rb +13 -13
- data/lib/solargraph/source/chain/call.rb +91 -119
- data/lib/solargraph/source/chain/class_variable.rb +1 -1
- data/lib/solargraph/source/chain/constant.rb +5 -1
- data/lib/solargraph/source/chain/global_variable.rb +1 -1
- data/lib/solargraph/source/chain/hash.rb +8 -5
- data/lib/solargraph/source/chain/head.rb +19 -19
- 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 +12 -22
- data/lib/solargraph/source/chain/literal.rb +22 -15
- data/lib/solargraph/source/chain/or.rb +10 -4
- data/lib/solargraph/source/chain/q_call.rb +2 -0
- data/lib/solargraph/source/chain/variable.rb +3 -1
- data/lib/solargraph/source/chain/z_super.rb +1 -3
- data/lib/solargraph/source/chain.rb +51 -38
- data/lib/solargraph/source/change.rb +12 -5
- data/lib/solargraph/source/cursor.rb +33 -18
- 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 +54 -30
- data/lib/solargraph/source_map/data.rb +4 -1
- data/lib/solargraph/source_map/mapper.rb +28 -131
- data/lib/solargraph/source_map.rb +35 -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 +196 -122
- data/lib/solargraph/version.rb +19 -1
- data/lib/solargraph/workspace/config.rb +14 -11
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +1 -0
- data/lib/solargraph/workspace.rb +50 -28
- data/lib/solargraph/yard_map/cache.rb +25 -25
- data/lib/solargraph/yard_map/directives/attribute_directive.rb +65 -0
- data/lib/solargraph/yard_map/directives/domain_directive.rb +30 -0
- data/lib/solargraph/yard_map/directives/method_directive.rb +51 -0
- data/lib/solargraph/yard_map/directives/override_directive.rb +30 -0
- data/lib/solargraph/yard_map/directives/parse_directive.rb +53 -0
- data/lib/solargraph/yard_map/directives/visibility_directive.rb +70 -0
- data/lib/solargraph/yard_map/directives.rb +35 -0
- data/lib/solargraph/yard_map/helpers.rb +8 -3
- data/lib/solargraph/yard_map/macro.rb +113 -0
- data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
- 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 +31 -8
- data/lib/solargraph/yard_map.rb +19 -18
- data/lib/solargraph/yard_tags.rb +2 -2
- data/lib/solargraph/yardoc.rb +7 -4
- data/lib/solargraph.rb +34 -10
- data/rbs/fills/rubygems/0/dependency.rbs +193 -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 +38 -35
- metadata +64 -42
- 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
- data/rbs/fills/tuple/tuple.rbs +0 -149
|
@@ -4,6 +4,7 @@ require 'parser'
|
|
|
4
4
|
require 'ast'
|
|
5
5
|
|
|
6
6
|
# https://github.com/whitequark/parser
|
|
7
|
+
# rubocop:disable Metrics/ModuleLength
|
|
7
8
|
module Solargraph
|
|
8
9
|
module Parser
|
|
9
10
|
module ParserGem
|
|
@@ -12,17 +13,17 @@ module Solargraph
|
|
|
12
13
|
|
|
13
14
|
# @param node [Parser::AST::Node]
|
|
14
15
|
# @return [String]
|
|
15
|
-
def unpack_name
|
|
16
|
-
pack_name(node).join(
|
|
16
|
+
def unpack_name node
|
|
17
|
+
pack_name(node).join('::')
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
# @param node [Parser::AST::Node]
|
|
20
21
|
# @return [Array<String>]
|
|
21
|
-
def pack_name
|
|
22
|
+
def pack_name node
|
|
22
23
|
# @type [Array<String>]
|
|
23
24
|
parts = []
|
|
24
25
|
if node.is_a?(AST::Node)
|
|
25
|
-
node.children.each
|
|
26
|
+
node.children.each do |n|
|
|
26
27
|
if n.is_a?(AST::Node)
|
|
27
28
|
if n.type == :cbase
|
|
28
29
|
parts = [''] + pack_name(n)
|
|
@@ -32,16 +33,16 @@ module Solargraph
|
|
|
32
33
|
else
|
|
33
34
|
parts.push n unless n.nil?
|
|
34
35
|
end
|
|
35
|
-
|
|
36
|
+
end
|
|
36
37
|
end
|
|
37
38
|
parts
|
|
38
39
|
end
|
|
39
40
|
|
|
40
|
-
# @param node [Parser::AST::Node]
|
|
41
|
+
# @param node [Parser::AST::Node, nil]
|
|
41
42
|
# @return [String, nil]
|
|
42
43
|
def infer_literal_node_type node
|
|
43
44
|
return nil unless node.is_a?(AST::Node)
|
|
44
|
-
if
|
|
45
|
+
if %i[str dstr].include?(node.type)
|
|
45
46
|
return '::String'
|
|
46
47
|
elsif node.type == :array
|
|
47
48
|
return '::Array'
|
|
@@ -53,30 +54,30 @@ module Solargraph
|
|
|
53
54
|
return '::Integer'
|
|
54
55
|
elsif node.type == :float
|
|
55
56
|
return '::Float'
|
|
56
|
-
elsif
|
|
57
|
+
elsif %i[sym dsym].include?(node.type)
|
|
57
58
|
return '::Symbol'
|
|
58
59
|
elsif node.type == :regexp
|
|
59
60
|
return '::Regexp'
|
|
60
61
|
elsif node.type == :irange
|
|
61
62
|
return '::Range'
|
|
62
|
-
elsif
|
|
63
|
+
elsif %i[true false].include?(node.type)
|
|
63
64
|
return '::Boolean'
|
|
64
65
|
# @todo Support `nil` keyword in types
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
# elsif node.type == :nil
|
|
67
|
+
# return 'NilClass'
|
|
67
68
|
end
|
|
68
69
|
nil
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
# @param node [Parser::AST::Node]
|
|
72
73
|
# @return [Position]
|
|
73
|
-
def get_node_start_position
|
|
74
|
+
def get_node_start_position node
|
|
74
75
|
Position.new(node.loc.line, node.loc.column)
|
|
75
76
|
end
|
|
76
77
|
|
|
77
78
|
# @param node [Parser::AST::Node]
|
|
78
79
|
# @return [Position]
|
|
79
|
-
def get_node_end_position
|
|
80
|
+
def get_node_end_position node
|
|
80
81
|
Position.new(node.loc.last_line, node.loc.last_column)
|
|
81
82
|
end
|
|
82
83
|
|
|
@@ -86,40 +87,84 @@ module Solargraph
|
|
|
86
87
|
# @return [String]
|
|
87
88
|
def drill_signature node, signature
|
|
88
89
|
return signature unless node.is_a?(AST::Node)
|
|
89
|
-
if
|
|
90
|
-
unless node.children[0].nil?
|
|
91
|
-
signature += drill_signature(node.children[0], signature)
|
|
92
|
-
end
|
|
90
|
+
if %i[const cbase].include?(node.type)
|
|
91
|
+
signature += drill_signature(node.children[0], signature) unless node.children[0].nil?
|
|
93
92
|
signature += '::' unless signature.empty?
|
|
94
93
|
signature += node.children[1].to_s
|
|
95
|
-
elsif
|
|
94
|
+
elsif %i[lvar ivar cvar].include?(node.type)
|
|
96
95
|
signature += '.' unless signature.empty?
|
|
97
96
|
signature += node.children[0].to_s
|
|
98
97
|
elsif node.type == :send
|
|
99
|
-
unless node.children[0].nil?
|
|
100
|
-
signature += drill_signature(node.children[0], signature)
|
|
101
|
-
end
|
|
98
|
+
signature += drill_signature(node.children[0], signature) unless node.children[0].nil?
|
|
102
99
|
signature += '.' unless signature.empty?
|
|
103
100
|
signature += node.children[1].to_s
|
|
104
101
|
end
|
|
105
102
|
signature
|
|
106
103
|
end
|
|
107
104
|
|
|
105
|
+
# Convert a DSL method call argument with directly inferrable simple params.
|
|
106
|
+
# @param node [Parser::AST::Node]
|
|
107
|
+
# @return [String, Integer, Float, Symbol, Array, Hash, Source::Chain, nil]
|
|
108
|
+
# @sg-ignore "does not match inferred type ::String, ::Parser::AST::Node" - this probably comes from the
|
|
109
|
+
# `.children[0]` call, which is not recognized as returning a literal value.
|
|
110
|
+
def simple_convert node
|
|
111
|
+
return nil unless Parser.is_ast_node?(node)
|
|
112
|
+
|
|
113
|
+
case node.type
|
|
114
|
+
when :const
|
|
115
|
+
unpack_name(node)
|
|
116
|
+
when :str, :dstr, :int, :float, :sym, true, false
|
|
117
|
+
node.children[0]
|
|
118
|
+
when :array
|
|
119
|
+
simple_convert_array(node)
|
|
120
|
+
when :hash
|
|
121
|
+
simple_convert_hash(node)
|
|
122
|
+
else
|
|
123
|
+
Solargraph::Parser.chain(node)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
108
127
|
# @param node [Parser::AST::Node]
|
|
128
|
+
# @return [Array]
|
|
129
|
+
def simple_convert_array node
|
|
130
|
+
return [] unless Parser.is_ast_node?(node) && node.type == :array
|
|
131
|
+
node.children.compact.map { |c| simple_convert(c) }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @param node [Parser::AST::Node]
|
|
135
|
+
# @return [Hash]
|
|
136
|
+
def simple_convert_hash node
|
|
137
|
+
return {} unless Parser.is_ast_node?(node) && node.type == :hash
|
|
138
|
+
result = {}
|
|
139
|
+
# @param pair [Parser::AST::Node]
|
|
140
|
+
node.children.each do |pair|
|
|
141
|
+
next unless Parser.is_ast_node?(pair) && pair.children[0]
|
|
142
|
+
result[pair.children[0].children[0]] = simple_convert(pair.children[1])
|
|
143
|
+
end
|
|
144
|
+
result
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# @param node [Parser::AST::Node, nil]
|
|
109
148
|
# @return [Hash{Symbol => Chain}]
|
|
110
149
|
def convert_hash node
|
|
111
150
|
return {} unless Parser.is_ast_node?(node)
|
|
151
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
112
152
|
return convert_hash(node.children[0]) if node.type == :kwsplat
|
|
113
|
-
|
|
153
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
154
|
+
if Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat
|
|
155
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
156
|
+
return convert_hash(node.children[0])
|
|
157
|
+
end
|
|
158
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
114
159
|
return {} unless node.type == :hash
|
|
115
160
|
result = {}
|
|
161
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
116
162
|
node.children.each do |pair|
|
|
117
163
|
result[pair.children[0].children[0]] = Solargraph::Parser.chain(pair.children[1])
|
|
118
164
|
end
|
|
119
165
|
result
|
|
120
166
|
end
|
|
121
167
|
|
|
122
|
-
# @sg-ignore Wrong argument type for AST::Node.new: type expected AST::_ToSym, received :nil
|
|
123
168
|
NIL_NODE = ::Parser::AST::Node.new(:nil)
|
|
124
169
|
|
|
125
170
|
# @param node [Parser::AST::Node]
|
|
@@ -148,7 +193,7 @@ module Solargraph
|
|
|
148
193
|
end
|
|
149
194
|
|
|
150
195
|
# @param nodes [Enumerable<Parser::AST::Node>]
|
|
151
|
-
def any_splatted_call?
|
|
196
|
+
def any_splatted_call? nodes
|
|
152
197
|
nodes.any? { |n| splatted_call?(n) }
|
|
153
198
|
end
|
|
154
199
|
|
|
@@ -161,14 +206,17 @@ module Solargraph
|
|
|
161
206
|
if node.type == :block
|
|
162
207
|
result.push node
|
|
163
208
|
if Parser.is_ast_node?(node.children[0]) && node.children[0].children.length > 2
|
|
164
|
-
|
|
209
|
+
# @sg-ignore Need to add nil check here
|
|
210
|
+
node.children[0].children[2..].each { |child| result.concat call_nodes_from(child) }
|
|
165
211
|
end
|
|
166
|
-
|
|
212
|
+
# @sg-ignore Need to add nil check here
|
|
213
|
+
node.children[1..].each { |child| result.concat call_nodes_from(child) }
|
|
167
214
|
elsif node.type == :send
|
|
168
215
|
result.push node
|
|
169
216
|
result.concat call_nodes_from(node.children.first)
|
|
170
|
-
|
|
171
|
-
|
|
217
|
+
# @sg-ignore Need to add nil check here
|
|
218
|
+
node.children[2..].each { |child| result.concat call_nodes_from(child) }
|
|
219
|
+
elsif %i[super zsuper].include?(node.type)
|
|
172
220
|
result.push node
|
|
173
221
|
node.children.each { |child| result.concat call_nodes_from(child) }
|
|
174
222
|
else
|
|
@@ -199,53 +247,142 @@ module Solargraph
|
|
|
199
247
|
# @return [Array<AST::Node>] low-level value nodes in
|
|
200
248
|
# value position. Does not include explicit return
|
|
201
249
|
# statements
|
|
202
|
-
def value_position_nodes_only
|
|
250
|
+
def value_position_nodes_only node
|
|
203
251
|
DeepInference.value_position_nodes_only(node).map { |n| n || NIL_NODE }
|
|
204
252
|
end
|
|
205
253
|
|
|
206
254
|
# @param cursor [Solargraph::Source::Cursor]
|
|
207
255
|
# @return [Parser::AST::Node, nil]
|
|
208
256
|
def find_recipient_node cursor
|
|
209
|
-
|
|
257
|
+
if cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '('
|
|
258
|
+
return repaired_find_recipient_node(cursor)
|
|
259
|
+
end
|
|
210
260
|
source = cursor.source
|
|
211
261
|
position = cursor.position
|
|
212
262
|
offset = cursor.offset
|
|
213
263
|
tree = if source.synchronized?
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
264
|
+
# @sg-ignore Need to add nil check here
|
|
265
|
+
match = source.code[0..(offset - 1)].match(/,\s*\z/)
|
|
266
|
+
if match
|
|
267
|
+
# @sg-ignore Need to add nil check here
|
|
268
|
+
source.tree_at(position.line, position.column - match[0].length)
|
|
269
|
+
else
|
|
270
|
+
source.tree_at(position.line, position.column)
|
|
271
|
+
end
|
|
272
|
+
else
|
|
273
|
+
source.tree_at(position.line, position.column - 1)
|
|
274
|
+
end
|
|
223
275
|
# @type [AST::Node, nil]
|
|
224
276
|
prev = nil
|
|
225
277
|
tree.each do |node|
|
|
226
278
|
if node.type == :send
|
|
227
|
-
args = node.children[2
|
|
279
|
+
args = node.children[2..]
|
|
280
|
+
# @sg-ignore Need to add nil check here
|
|
228
281
|
if !args.empty?
|
|
282
|
+
# @sg-ignore Need to add nil check here
|
|
229
283
|
return node if prev && args.include?(prev)
|
|
230
|
-
|
|
231
|
-
if source.
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
return node if source.code[0..offset-1] =~ /\([^(]*\z/
|
|
235
|
-
end
|
|
284
|
+
elsif source.synchronized?
|
|
285
|
+
return node if source.code[0..(offset - 1)] =~ /\(\s*\z/ && source.code[offset..] =~ /^\s*\)/
|
|
286
|
+
elsif source.code[0..(offset - 1)] =~ /\([^(]*\z/
|
|
287
|
+
return node
|
|
236
288
|
end
|
|
237
289
|
end
|
|
238
290
|
prev = node
|
|
239
291
|
end
|
|
240
|
-
|
|
292
|
+
find_recipient_node_by_text(source, offset)
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Text-based fallback for finding a method call recipient when the AST
|
|
296
|
+
# is unavailable (e.g., unparseable source with syntax errors).
|
|
297
|
+
#
|
|
298
|
+
# Scans backward from cursor offset to find '(' and the method name
|
|
299
|
+
# before it, then creates a minimal :send node.
|
|
300
|
+
#
|
|
301
|
+
# @param source [Solargraph::Source]
|
|
302
|
+
# @param offset [Integer]
|
|
303
|
+
# @return [Parser::AST::Node, nil]
|
|
304
|
+
def find_recipient_node_by_text source, offset
|
|
305
|
+
code = source.code
|
|
306
|
+
return nil if offset.nil? || offset <= 0 || offset > code.length
|
|
307
|
+
|
|
308
|
+
# The '(' could be at offset-1 (cursor after '(') or at offset (cursor on '(')
|
|
309
|
+
start_pos = offset - 1
|
|
310
|
+
if start_pos.positive? && code[start_pos] != '(' && code[offset] == '('
|
|
311
|
+
start_pos = offset
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# Scan backward to find the matching '(' (handle nested parens)
|
|
315
|
+
depth = 0
|
|
316
|
+
paren_pos = nil
|
|
317
|
+
pos = start_pos
|
|
318
|
+
while pos >= 0
|
|
319
|
+
case code[pos]
|
|
320
|
+
when ')'
|
|
321
|
+
depth += 1
|
|
322
|
+
when '('
|
|
323
|
+
if depth.zero?
|
|
324
|
+
paren_pos = pos
|
|
325
|
+
break
|
|
326
|
+
end
|
|
327
|
+
depth -= 1
|
|
328
|
+
end
|
|
329
|
+
pos -= 1
|
|
330
|
+
end
|
|
331
|
+
return nil if paren_pos.nil?
|
|
332
|
+
|
|
333
|
+
# Skip whitespace before '(' to find method name
|
|
334
|
+
idx = paren_pos - 1
|
|
335
|
+
idx -= 1 while idx >= 0 && code[idx] =~ /\s/
|
|
336
|
+
return nil if idx.negative?
|
|
337
|
+
|
|
338
|
+
# Read method name (including ? and !)
|
|
339
|
+
name_end = idx + 1
|
|
340
|
+
idx -= 1 while idx >= 0 && code[idx] =~ /[a-zA-Z0-9_?!]/
|
|
341
|
+
name_start = idx + 1
|
|
342
|
+
return nil if name_start >= name_end
|
|
343
|
+
method_name = code[name_start...name_end]
|
|
344
|
+
return nil if method_name.empty?
|
|
345
|
+
|
|
346
|
+
# Check for receiver pattern: receiver.method( or receiver::method(
|
|
347
|
+
idx = name_start - 1
|
|
348
|
+
idx -= 1 while idx >= 0 && code[idx] =~ /\s/
|
|
349
|
+
if idx >= 0 && code[idx] == '.'
|
|
350
|
+
idx -= 1
|
|
351
|
+
idx -= 1 while idx >= 0 && code[idx] =~ /\s/
|
|
352
|
+
recv_end = idx + 1
|
|
353
|
+
idx -= 1 while idx >= 0 && code[idx] =~ /[a-zA-Z0-9_@$]/
|
|
354
|
+
recv_start = idx + 1
|
|
355
|
+
if recv_start < recv_end
|
|
356
|
+
recv_name = code[recv_start...recv_end]
|
|
357
|
+
unless recv_name.empty?
|
|
358
|
+
receiver_node = ::Parser::AST::Node.new(:send, [nil, recv_name.to_sym])
|
|
359
|
+
return ::Parser::AST::Node.new(:send, [receiver_node, method_name.to_sym])
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
elsif idx >= 0 && idx.positive? && code[idx - 1] == ':' && code[idx] == ':'
|
|
363
|
+
const_end = idx - 1
|
|
364
|
+
const_start = const_end
|
|
365
|
+
const_start -= 1 while const_start.positive? && code[const_start - 1] =~ /[a-zA-Z0-9_]/
|
|
366
|
+
const_name = code[const_start...const_end]
|
|
367
|
+
unless const_name.empty? || method_name.empty?
|
|
368
|
+
const_node = ::Parser::AST::Node.new(:const, [nil, const_name.to_sym])
|
|
369
|
+
return ::Parser::AST::Node.new(:send, [const_node, method_name.to_sym])
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
# Simple method call without receiver
|
|
374
|
+
::Parser::AST::Node.new(:send, [nil, method_name.to_sym])
|
|
241
375
|
end
|
|
242
376
|
|
|
243
377
|
# @param cursor [Solargraph::Source::Cursor]
|
|
244
378
|
# @return [Parser::AST::Node, nil]
|
|
245
379
|
def repaired_find_recipient_node cursor
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
380
|
+
c = cursor.source.cursor_at([cursor.position.line, cursor.position.column - 1])
|
|
381
|
+
tree = c.source.tree_at(c.position.line, c.position.column)
|
|
382
|
+
tree.each do |node|
|
|
383
|
+
return node if node.type == :send
|
|
384
|
+
end
|
|
385
|
+
find_recipient_node_by_text(cursor.source, cursor.offset)
|
|
249
386
|
end
|
|
250
387
|
|
|
251
388
|
#
|
|
@@ -302,19 +439,15 @@ module Solargraph
|
|
|
302
439
|
# statements in value positions.
|
|
303
440
|
module DeepInference
|
|
304
441
|
class << self
|
|
305
|
-
CONDITIONAL_ALL_BUT_FIRST = [
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
CASE_STATEMENT = [:case]
|
|
442
|
+
CONDITIONAL_ALL_BUT_FIRST = %i[if unless].freeze
|
|
443
|
+
ONLY_ONE_CHILD = [:return].freeze
|
|
444
|
+
FIRST_TWO_CHILDREN = [:rescue].freeze
|
|
445
|
+
COMPOUND_STATEMENTS = %i[begin kwbegin].freeze
|
|
446
|
+
SKIPPABLE = %i[def defs class sclass module].freeze
|
|
447
|
+
FUNCTION_VALUE = [:block].freeze
|
|
448
|
+
CASE_STATEMENT = [:case].freeze
|
|
313
449
|
|
|
314
450
|
# @param node [AST::Node] a method body compound statement
|
|
315
|
-
# @param include_explicit_returns [Boolean] If true,
|
|
316
|
-
# include the value nodes of the parameter of the
|
|
317
|
-
# 'return' statements in the type returned.
|
|
318
451
|
# @return [Array<AST::Node>] low-level value nodes from
|
|
319
452
|
# both nodes in value position as well as explicit
|
|
320
453
|
# return statements in the method's closure.
|
|
@@ -327,14 +460,14 @@ module Solargraph
|
|
|
327
460
|
# @return [Array<AST::Node>] low-level value nodes in
|
|
328
461
|
# value position. Does not include explicit return
|
|
329
462
|
# statements
|
|
330
|
-
def value_position_nodes_only
|
|
463
|
+
def value_position_nodes_only node
|
|
331
464
|
from_value_position_statement(node, include_explicit_returns: false)
|
|
332
465
|
end
|
|
333
466
|
|
|
334
467
|
# Look at known control statements and use them to find
|
|
335
468
|
# more specific return nodes.
|
|
336
469
|
#
|
|
337
|
-
# @param node [
|
|
470
|
+
# @param node [AST::Node] Statement which is in
|
|
338
471
|
# value position for a method body
|
|
339
472
|
# @param include_explicit_returns [Boolean] If true,
|
|
340
473
|
# include the value nodes of the parameter of the
|
|
@@ -348,10 +481,9 @@ module Solargraph
|
|
|
348
481
|
if COMPOUND_STATEMENTS.include?(node.type)
|
|
349
482
|
result.concat from_value_position_compound_statement node
|
|
350
483
|
elsif CONDITIONAL_ALL_BUT_FIRST.include?(node.type)
|
|
351
|
-
|
|
484
|
+
# @sg-ignore Need to add nil check here
|
|
485
|
+
result.concat reduce_to_value_nodes(node.children[1..])
|
|
352
486
|
# 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
487
|
elsif ONLY_ONE_CHILD.include?(node.type)
|
|
356
488
|
result.concat reduce_to_value_nodes([node.children[0]])
|
|
357
489
|
elsif FIRST_TWO_CHILDREN.include?(node.type)
|
|
@@ -362,9 +494,12 @@ module Solargraph
|
|
|
362
494
|
# @todo any explicit returns actually return from
|
|
363
495
|
# scope in which the proc is run. This asssumes
|
|
364
496
|
# that the function is executed here.
|
|
365
|
-
|
|
497
|
+
if include_explicit_returns
|
|
498
|
+
result.concat explicit_return_values_from_compound_statement(node.children[2])
|
|
499
|
+
end
|
|
366
500
|
elsif CASE_STATEMENT.include?(node.type)
|
|
367
|
-
|
|
501
|
+
# @sg-ignore Need to add nil check here
|
|
502
|
+
node.children[1..].each do |cc|
|
|
368
503
|
if cc.nil?
|
|
369
504
|
result.push NIL_NODE
|
|
370
505
|
elsif cc.type == :when
|
|
@@ -397,7 +532,7 @@ module Solargraph
|
|
|
397
532
|
# @return [Array<Parser::AST::Node>]
|
|
398
533
|
def from_value_position_compound_statement parent
|
|
399
534
|
result = []
|
|
400
|
-
nodes = parent.children.select{|n| n.is_a?(AST::Node)}
|
|
535
|
+
nodes = parent.children.select { |n| n.is_a?(AST::Node) }
|
|
401
536
|
nodes.each_with_index do |node, idx|
|
|
402
537
|
if node.type == :block
|
|
403
538
|
result.concat explicit_return_values_from_compound_statement(node.children[2])
|
|
@@ -422,7 +557,10 @@ module Solargraph
|
|
|
422
557
|
# value position. we already have the explicit values
|
|
423
558
|
# from above; now we need to also gather the value
|
|
424
559
|
# position nodes
|
|
425
|
-
|
|
560
|
+
if idx == nodes.length - 1
|
|
561
|
+
result.concat from_value_position_statement(nodes.last,
|
|
562
|
+
include_explicit_returns: false)
|
|
563
|
+
end
|
|
426
564
|
end
|
|
427
565
|
result
|
|
428
566
|
end
|
|
@@ -438,7 +576,7 @@ module Solargraph
|
|
|
438
576
|
def explicit_return_values_from_compound_statement parent
|
|
439
577
|
return [] unless parent.is_a?(::Parser::AST::Node)
|
|
440
578
|
result = []
|
|
441
|
-
nodes = parent.children.select{|n| n.is_a?(::Parser::AST::Node)}
|
|
579
|
+
nodes = parent.children.select { |n| n.is_a?(::Parser::AST::Node) }
|
|
442
580
|
nodes.each do |node|
|
|
443
581
|
next if SKIPPABLE.include?(node.type)
|
|
444
582
|
if node.type == :return
|
|
@@ -460,17 +598,28 @@ module Solargraph
|
|
|
460
598
|
nodes.each do |node|
|
|
461
599
|
if !node.is_a?(::Parser::AST::Node)
|
|
462
600
|
result.push nil
|
|
601
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
463
602
|
elsif COMPOUND_STATEMENTS.include?(node.type)
|
|
464
603
|
result.concat from_value_position_compound_statement(node)
|
|
604
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
465
605
|
elsif CONDITIONAL_ALL_BUT_FIRST.include?(node.type)
|
|
466
|
-
|
|
606
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
607
|
+
result.concat reduce_to_value_nodes(node.children[1..])
|
|
608
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
467
609
|
elsif node.type == :return
|
|
610
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
468
611
|
result.concat reduce_to_value_nodes([node.children[0]])
|
|
612
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
469
613
|
elsif node.type == :or
|
|
614
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
470
615
|
result.concat reduce_to_value_nodes(node.children)
|
|
616
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
471
617
|
elsif node.type == :block
|
|
618
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
472
619
|
result.concat explicit_return_values_from_compound_statement(node.children[2])
|
|
620
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
473
621
|
elsif node.type == :resbody
|
|
622
|
+
# @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
|
|
474
623
|
result.concat reduce_to_value_nodes([node.children[2]])
|
|
475
624
|
else
|
|
476
625
|
result.push node
|
|
@@ -484,3 +633,4 @@ module Solargraph
|
|
|
484
633
|
end
|
|
485
634
|
end
|
|
486
635
|
end
|
|
636
|
+
# rubocop:enable Metrics/ModuleLength
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
module Parser
|
|
5
|
-
module ParserGem
|
|
6
|
-
module NodeProcessors
|
|
7
|
-
class AliasNode < Parser::NodeProcessor::Base
|
|
8
|
-
def process
|
|
9
|
-
loc = get_node_location(node)
|
|
10
|
-
pins.push Solargraph::Pin::MethodAlias.new(
|
|
11
|
-
location: loc,
|
|
12
|
-
closure: region.closure,
|
|
13
|
-
name: node.children[0].children[0].to_s,
|
|
14
|
-
original: node.children[1].children[0].to_s,
|
|
15
|
-
scope: region.scope || :instance,
|
|
16
|
-
source: :parser
|
|
17
|
-
)
|
|
18
|
-
process_children
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Parser
|
|
5
|
+
module ParserGem
|
|
6
|
+
module NodeProcessors
|
|
7
|
+
class AliasNode < Parser::NodeProcessor::Base
|
|
8
|
+
def process
|
|
9
|
+
loc = get_node_location(node)
|
|
10
|
+
pins.push Solargraph::Pin::MethodAlias.new(
|
|
11
|
+
location: loc,
|
|
12
|
+
closure: region.closure,
|
|
13
|
+
name: node.children[0].children[0].to_s,
|
|
14
|
+
original: node.children[1].children[0].to_s,
|
|
15
|
+
scope: region.scope || :instance,
|
|
16
|
+
source: :parser
|
|
17
|
+
)
|
|
18
|
+
process_children
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -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
|
|
@@ -14,16 +14,17 @@ module Solargraph
|
|
|
14
14
|
node.children.each do |u|
|
|
15
15
|
loc = get_node_location(u)
|
|
16
16
|
locals.push Solargraph::Pin::Parameter.new(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
location: loc,
|
|
18
|
+
closure: callable,
|
|
19
|
+
comments: comments_for(node),
|
|
20
|
+
name: u.children[0].to_s,
|
|
21
|
+
assignment: u.children[1],
|
|
22
|
+
asgn_code: u.children[1] ? region.code_for(u.children[1]) : nil,
|
|
23
|
+
# @sg-ignore Need to add nil check here
|
|
24
|
+
presence: callable.location.range,
|
|
25
|
+
decl: get_decl(u),
|
|
26
|
+
source: :parser
|
|
27
|
+
)
|
|
27
28
|
callable.parameters.push locals.last
|
|
28
29
|
end
|
|
29
30
|
end
|
|
@@ -35,11 +36,12 @@ module Solargraph
|
|
|
35
36
|
|
|
36
37
|
# @param callable [Pin::Callable]
|
|
37
38
|
# @return [void]
|
|
38
|
-
def forward
|
|
39
|
+
def forward callable
|
|
39
40
|
loc = get_node_location(node)
|
|
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
|