aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authortomoya ishida <tomoyapenguin@gmail.com>2023-11-23 05:29:47 +0900
committergit <svn-admin@ruby-lang.org>2023-11-22 20:29:51 +0000
commit8d6175bf64748eb646a83c74ff7bd541fdec166d (patch)
tree7d3bce00d59a199dcb766c742662f6ff8862603d /lib
parent7a93bee4f845f496742b03a0e575ed13631971b7 (diff)
downloadruby-8d6175bf64748eb646a83c74ff7bd541fdec166d.tar.gz
[ruby/irb] Require prism >= 0.18.0 (MatchWriteNode#targets and
CaseMatchNode) (https://github.com/ruby/irb/pull/778) https://github.com/ruby/irb/commit/943c14b12e
Diffstat (limited to 'lib')
-rw-r--r--lib/irb/context.rb2
-rw-r--r--lib/irb/type_completion/type_analyzer.rb48
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)