Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions lib/typeprof/core/ast/call.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def initialize(raw_node, recv, mid, mid_code_range, raw_args, last_arg, raw_bloc
@block_tbl = nil
@block_f_args = nil
@block_body = nil
@safe_navigation = raw_node.respond_to?(:safe_navigation?) && raw_node.safe_navigation?

if raw_args
args = []
Expand Down Expand Up @@ -71,13 +72,19 @@ def initialize(raw_node, recv, mid, mid_code_range, raw_args, last_arg, raw_bloc
attr_reader :recv, :mid, :mid_code_range, :yield
attr_reader :positional_args, :splat_flags, :keyword_args
attr_reader :block_tbl, :block_f_args, :block_body, :block_pass
attr_reader :safe_navigation

def subnodes = { recv:, positional_args:, keyword_args:, block_body:, block_pass: }
def attrs = { mid:, splat_flags:, block_tbl:, block_f_args:, yield: }
def attrs = { mid:, splat_flags:, block_tbl:, block_f_args:, yield:, safe_navigation: }

def install0(genv)
recv = @recv ? @recv.install(genv) : @yield ? @lenv.get_var(:"*given_block") : @lenv.get_var(:"*self")

if @safe_navigation
allow_nil = NilFilter.new(genv, self, recv, true).next_vtx
recv = NilFilter.new(genv, self, recv, false).next_vtx
end

positional_args = @positional_args.map do |arg|
arg.install(genv)
end
Expand Down Expand Up @@ -132,10 +139,15 @@ def install0(genv)
ret = Vertex.new(self)
@changes.add_edge(genv, box.ret, ret)
@changes.add_edge(genv, @block_body.lenv.break_vtx, ret)
ret
else
box.ret
ret = box.ret
end

if @safe_navigation
@changes.add_edge(genv, allow_nil, ret)
end

ret
end

def block_last_stmt_code_range
Expand Down
20 changes: 20 additions & 0 deletions scenario/method/safe-navigation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## update
def return_optional
if rand < 0.5
"str"
else
nil
end
end

def check
return_optional&.to_i
end

## diagnostics

## assert
class Object
def return_optional: -> String?
def check: -> Integer?
end