diff options
author | Kevin Newton <[email protected]> | 2024-01-11 13:51:32 -0500 |
---|---|---|
committer | Kevin Newton <[email protected]> | 2024-01-11 14:59:37 -0500 |
commit | 44d0c5ae3f1e1586f9dac07dd19f65b80fb8e2b4 (patch) | |
tree | a2a1d2211d159388dfe4da42e72f6b76f7fddfdc | |
parent | 45dd8edf82d2648fed51b0e65f6fc1cf4473038d (diff) |
[PRISM] Raise syntax errors when found
-rw-r--r-- | common.mk | 2 | ||||
-rw-r--r-- | iseq.c | 38 | ||||
-rw-r--r-- | test/ruby/test_iseq.rb | 11 |
3 files changed, 37 insertions, 14 deletions
@@ -8495,6 +8495,7 @@ iseq.$(OBJEXT): $(top_srcdir)/internal/fixnum.h iseq.$(OBJEXT): $(top_srcdir)/internal/gc.h iseq.$(OBJEXT): $(top_srcdir)/internal/hash.h iseq.$(OBJEXT): $(top_srcdir)/internal/imemo.h +iseq.$(OBJEXT): $(top_srcdir)/internal/io.h iseq.$(OBJEXT): $(top_srcdir)/internal/numeric.h iseq.$(OBJEXT): $(top_srcdir)/internal/parse.h iseq.$(OBJEXT): $(top_srcdir)/internal/rational.h @@ -8702,6 +8703,7 @@ iseq.$(OBJEXT): {$(VPATH)}internal/value_type.h iseq.$(OBJEXT): {$(VPATH)}internal/variable.h iseq.$(OBJEXT): {$(VPATH)}internal/warning_push.h iseq.$(OBJEXT): {$(VPATH)}internal/xmalloc.h +iseq.$(OBJEXT): {$(VPATH)}io.h iseq.$(OBJEXT): {$(VPATH)}iseq.c iseq.$(OBJEXT): {$(VPATH)}iseq.h iseq.$(OBJEXT): {$(VPATH)}method.h @@ -28,6 +28,7 @@ #include "internal/file.h" #include "internal/gc.h" #include "internal/hash.h" +#include "internal/io.h" #include "internal/ruby_parser.h" #include "internal/sanitizers.h" #include "internal/symbol.h" @@ -1404,19 +1405,36 @@ static void iseqw_s_compile_prism_compile(pm_parser_t *parser, VALUE opt, rb_iseq_t *iseq, VALUE file, VALUE path, int first_lineno) { pm_node_t *node = pm_parse(parser); - rb_code_location_t code_location; - pm_code_location(&code_location, &parser->newline_list, &node->location); - rb_compile_option_t option; - make_compile_option(&option, opt); - prepare_iseq_build(iseq, rb_fstring_lit("<compiled>"), file, path, first_lineno, &code_location, -1, NULL, 0, ISEQ_TYPE_TOP, Qnil, &option); + if (parser->error_list.size > 0) { + pm_buffer_t buffer = { 0 }; + pm_parser_errors_format(parser, &buffer, rb_stderr_tty_p()); - pm_scope_node_t scope_node; - pm_scope_node_init(node, &scope_node, NULL, parser); - rb_iseq_compile_prism_node(iseq, &scope_node, parser); + pm_buffer_prepend_string(&buffer, "syntax errors found\n", 20); + VALUE error = rb_exc_new(rb_eSyntaxError, pm_buffer_value(&buffer), pm_buffer_length(&buffer)); - finish_iseq_build(iseq); - pm_node_destroy(parser, node); + pm_buffer_free(&buffer); + pm_node_destroy(parser, node); + + // TODO: We need to set the backtrace based on the ISEQ. + // VALUE path = pathobj_path(ISEQ_BODY(iseq)->location.pathobj); + // rb_funcallv(error, rb_intern("set_backtrace"), 1, &path); + rb_exc_raise(error); + } else { + rb_code_location_t code_location; + pm_code_location(&code_location, &parser->newline_list, &node->location); + + rb_compile_option_t option; + make_compile_option(&option, opt); + prepare_iseq_build(iseq, rb_fstring_lit("<compiled>"), file, path, first_lineno, &code_location, -1, NULL, 0, ISEQ_TYPE_TOP, Qnil, &option); + + pm_scope_node_t scope_node; + pm_scope_node_init(node, &scope_node, NULL, parser); + rb_iseq_compile_prism_node(iseq, &scope_node, parser); + + finish_iseq_build(iseq); + pm_node_destroy(parser, node); + } } static VALUE diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb index b0896511d8..f5c0b82057 100644 --- a/test/ruby/test_iseq.rb +++ b/test/ruby/test_iseq.rb @@ -801,12 +801,15 @@ class TestISeq < Test::Unit::TestCase def test_compile_prism_with_file Tempfile.create(%w"test_iseq .rb") do |f| - f.puts "name = 'Prism'; puts 'hello" + f.puts "name = 'Prism'; puts 'hello'" f.close - assert_nothing_raised(SyntaxError) { - RubyVM::InstructionSequence.compile_prism(f.path) - } + assert_nothing_raised(TypeError) do + begin + RubyVM::InstructionSequence.compile_prism(f.path) + rescue SyntaxError + end + end end end end |