diff options
Diffstat (limited to 'lib/irb')
-rw-r--r-- | lib/irb/context.rb | 2 | ||||
-rw-r--r-- | lib/irb/type_completion/type_analyzer.rb | 48 |
2 files changed, 31 insertions, 19 deletions
diff --git a/lib/irb/context.rb b/lib/irb/context.rb index 5dfe9d0d71..a7b8ca2c26 100644 --- a/lib/irb/context.rb +++ b/lib/irb/context.rb @@ -164,7 +164,7 @@ module IRB RegexpCompletor.new end - TYPE_COMPLETION_REQUIRED_PRISM_VERSION = '0.17.1' + TYPE_COMPLETION_REQUIRED_PRISM_VERSION = '0.18.0' private def build_type_completor unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('3.0.0') && RUBY_ENGINE != 'truffleruby' diff --git a/lib/irb/type_completion/type_analyzer.rb b/lib/irb/type_completion/type_analyzer.rb index c4a41e4999..344924c9fc 100644 --- a/lib/irb/type_completion/type_analyzer.rb +++ b/lib/irb/type_completion/type_analyzer.rb @@ -703,19 +703,31 @@ module IRB end def evaluate_case_node(node, scope) - target = evaluate(node.predicate, scope) if node.predicate + evaluate(node.predicate, scope) if node.predicate # TODO branches = node.conditions.map do |condition| - ->(s) { evaluate_case_match target, condition, s } + ->(s) { evaluate_case_when_condition condition, s } end if node.consequent branches << ->(s) { evaluate node.consequent, s } - elsif node.conditions.any? { _1.is_a? Prism::WhenNode } + else branches << ->(_s) { Types::NIL } end Types::UnionType[*scope.run_branches(*branches)] end + def evaluate_case_match_node(node, scope) + target = evaluate(node.predicate, scope) + # TODO + branches = node.conditions.map do |condition| + ->(s) { evaluate_case_in_condition target, condition, s } + end + if node.consequent + branches << ->(s) { evaluate node.consequent, s } + end + Types::UnionType[*scope.run_branches(*branches)] + end + def evaluate_match_required_node(node, scope) value_type = evaluate node.value, scope evaluate_match_pattern value_type, node.pattern, scope @@ -765,7 +777,8 @@ module IRB def evaluate_match_write_node(node, scope) # /(?<a>)(?<b>)/ =~ string evaluate node.call, scope - node.locals.each { scope[_1.to_s] = Types::UnionType[Types::STRING, Types::NIL] } + locals = node.targets.map(&:name) + locals.each { scope[_1.to_s] = Types::UnionType[Types::STRING, Types::NIL] } Types::BOOLEAN end @@ -948,21 +961,20 @@ module IRB end end - def evaluate_case_match(target, node, scope) - case node - when Prism::WhenNode - node.conditions.each { evaluate _1, scope } - node.statements ? evaluate(node.statements, scope) : Types::NIL - when Prism::InNode - pattern = node.pattern - if pattern.is_a?(Prism::IfNode) || pattern.is_a?(Prism::UnlessNode) - cond_node = pattern.predicate - pattern = pattern.statements.body.first - end - evaluate_match_pattern(target, pattern, scope) - evaluate cond_node, scope if cond_node # TODO: conditional branch - node.statements ? evaluate(node.statements, scope) : Types::NIL + def evaluate_case_when_condition(node, scope) + node.conditions.each { evaluate _1, scope } + node.statements ? evaluate(node.statements, scope) : Types::NIL + end + + def evaluate_case_in_condition(target, node, scope) + pattern = node.pattern + if pattern.is_a?(Prism::IfNode) || pattern.is_a?(Prism::UnlessNode) + cond_node = pattern.predicate + pattern = pattern.statements.body.first end + evaluate_match_pattern(target, pattern, scope) + evaluate cond_node, scope if cond_node # TODO: conditional branch + node.statements ? evaluate(node.statements, scope) : Types::NIL end def evaluate_match_pattern(value, pattern, scope) |