From e125c672c63bccbb9fc76bade509a6583c7ec4af Mon Sep 17 00:00:00 2001 From: Herwin Date: Mon, 24 Jun 2024 11:34:58 +0200 Subject: [PATCH 1/5] Don't show "binding passed to eval will be ignored" for explicit nil argument Since this is done at compile time, we can only warn for an explicit nil statement, not for expressions. This argument can be explicit nil if the caller wants to add file/line arguments (arguments 2 and 3). --- lib/natalie/compiler/macro_expander.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/natalie/compiler/macro_expander.rb b/lib/natalie/compiler/macro_expander.rb index 70f7eac9a..c8766ecec 100644 --- a/lib/natalie/compiler/macro_expander.rb +++ b/lib/natalie/compiler/macro_expander.rb @@ -158,7 +158,7 @@ def macro_load(expr:, current_path:, **) def macro_eval(expr:, current_path:, locals:, **) args = expr.arguments&.arguments || [] node = args.first - $stderr.puts 'FIXME: binding passed to eval() will be ignored.' if args.size > 1 + $stderr.puts 'FIXME: binding passed to eval() will be ignored.' if args.size > 1 && args[1].type != :nil_node if node.type == :interpolated_string_node && node.parts.all? { |subnode| subnode.type == :string_node } node = Prism::StringNode.new( nil, From c086dd584bd0f18180178548cc133102fe20f980 Mon Sep 17 00:00:00 2001 From: Herwin Date: Mon, 24 Jun 2024 11:38:25 +0200 Subject: [PATCH 2/5] Update specs for binding We can run the specs, but they fail. Catch this in a NATFIXME block instead of removing the code. --- spec/core/proc/binding_spec.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spec/core/proc/binding_spec.rb b/spec/core/proc/binding_spec.rb index 0e550cda0..f5947e41a 100644 --- a/spec/core/proc/binding_spec.rb +++ b/spec/core/proc/binding_spec.rb @@ -15,8 +15,9 @@ def obj.test_binding(some, params) lambdas_binding = obj.test_binding(1, 2).binding - # NATFIXME: binding passed to eval() will be ignored. - # eval("some", lambdas_binding).should == 1 - # eval("params", lambdas_binding).should == 2 + NATFIXME 'binding passed to eval() will be ignored.', exception: NoMethodError, message: "undefined method `some' for main" do + eval("some", lambdas_binding).should == 1 + eval("params", lambdas_binding).should == 2 + end end end From 8db6b80dc2ab313227a3f435781e6c74eb1fe69c Mon Sep 17 00:00:00 2001 From: Herwin Date: Mon, 24 Jun 2024 12:26:51 +0200 Subject: [PATCH 3/5] Add specs for file and line arguments in eval calls --- test/natalie/eval_test.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/natalie/eval_test.rb b/test/natalie/eval_test.rb index 367eee7c5..d05312aaa 100644 --- a/test/natalie/eval_test.rb +++ b/test/natalie/eval_test.rb @@ -56,4 +56,9 @@ class C a RUBY end + + it 'can handle file and line argument' do + eval('"#{__FILE__}:#{__LINE__}"', nil, 'foo.rb').should == 'foo.rb:1' + eval('"#{__FILE__}:#{__LINE__}"', nil, 'foo.rb', 1234).should == 'foo.rb:1234' + end end From 20782e9b86b4079b263c5853f6b8ca1de90c1fd5 Mon Sep 17 00:00:00 2001 From: Herwin Date: Mon, 24 Jun 2024 11:42:16 +0200 Subject: [PATCH 4/5] Support file argument in eval --- lib/natalie/compiler/macro_expander.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/natalie/compiler/macro_expander.rb b/lib/natalie/compiler/macro_expander.rb index c8766ecec..70e369de0 100644 --- a/lib/natalie/compiler/macro_expander.rb +++ b/lib/natalie/compiler/macro_expander.rb @@ -171,6 +171,13 @@ def macro_eval(expr:, current_path:, locals:, **) ) end if node.type == :string_node + if args.size > 2 + if args[2].is_a?(Prism::StringNode) + current_path = args[2].unescaped + else + $stderr.puts 'FIXME: passed file to eval() will be ignored' + end + end begin Natalie::Parser.new(node.unescaped, current_path, locals: locals).ast rescue Parser::ParseError => e From 179f7f30e7aade3cb3ae73b0eb44ba306297ac11 Mon Sep 17 00:00:00 2001 From: Herwin Date: Mon, 24 Jun 2024 11:51:27 +0200 Subject: [PATCH 5/5] Support line argument in eval --- lib/natalie/compiler/macro_expander.rb | 10 +++++++++- lib/natalie/parser.rb | 5 +++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/natalie/compiler/macro_expander.rb b/lib/natalie/compiler/macro_expander.rb index 70e369de0..f7a879827 100644 --- a/lib/natalie/compiler/macro_expander.rb +++ b/lib/natalie/compiler/macro_expander.rb @@ -170,6 +170,7 @@ def macro_eval(expr:, current_path:, locals:, **) node.location, ) end + line = nil if node.type == :string_node if args.size > 2 if args[2].is_a?(Prism::StringNode) @@ -178,8 +179,15 @@ def macro_eval(expr:, current_path:, locals:, **) $stderr.puts 'FIXME: passed file to eval() will be ignored' end end + if args.size > 3 + if args[3].is_a?(Prism::IntegerNode) + line = args[3].value + else + $stderr.puts 'FIXME: passed line to eval() will be ignored' + end + end begin - Natalie::Parser.new(node.unescaped, current_path, locals: locals).ast + Natalie::Parser.new(node.unescaped, current_path, line: line, locals: locals).ast rescue Parser::ParseError => e drop_error(:SyntaxError, e.message, location: node.location) end diff --git a/lib/natalie/parser.rb b/lib/natalie/parser.rb index 04b8eeb4e..10bbf4b7f 100644 --- a/lib/natalie/parser.rb +++ b/lib/natalie/parser.rb @@ -63,9 +63,10 @@ class ParseError < StandardError class IncompleteExpression < ParseError end - def initialize(code_str, path, locals: []) + def initialize(code_str, path, line: nil, locals: []) @code_str = code_str @path = path + @line = line @locals = locals end @@ -74,7 +75,7 @@ def tokenize end def result - @result ||= Prism.parse(@code_str, filepath: @path, scopes: [@locals]) + @result ||= Prism.parse(@code_str, filepath: @path, line: @line, scopes: [@locals]) end def source = result.source