diff options
author | Nobuyoshi Nakada <[email protected]> | 2022-11-20 22:59:52 +0900 |
---|---|---|
committer | Nobuyoshi Nakada <[email protected]> | 2022-12-01 17:05:41 +0900 |
commit | 4e68b594314760611d0926c3de70a4cad26802cd (patch) | |
tree | 58254a7288d2402fbe5baa41426a8e8c4d027470 | |
parent | 5752d11f1f33d277356373da749db111e03c96b5 (diff) |
[Feature #19138] Add `SyntaxError#path`
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/6779
-rw-r--r-- | NEWS.md | 4 | ||||
-rw-r--r-- | error.c | 38 | ||||
-rw-r--r-- | test/ruby/test_exception.rb | 23 |
3 files changed, 55 insertions, 10 deletions
@@ -300,6 +300,9 @@ Note: We're only listing outstanding class updates. * Time#deconstruct_keys is added, allowing to use Time instances in pattern-matching expressions [[Feature #19071]] +* SyntaxError + * SyntaxError#path has been added. [[Bug #19138]] + * TracePoint * TracePoint#binding now returns `nil` for `c_call`/`c_return` TracePoints. @@ -551,3 +554,4 @@ The following deprecated APIs are removed. [Feature #19071]: https://bugs.ruby-lang.org/issues/19071 [Bug #19100]: https://bugs.ruby-lang.org/issues/19100 [Feature #19135]: https://bugs.ruby-lang.org/issues/19135 +[Feature #19138]: https://bugs.ruby-lang.org/issues/19138 @@ -125,6 +125,8 @@ err_vcatf(VALUE str, const char *pre, const char *file, int line, return str; } +static VALUE syntax_error_with_path(VALUE, VALUE, VALUE*, rb_encoding*); + VALUE rb_syntax_error_append(VALUE exc, VALUE file, int line, int column, rb_encoding *enc, const char *fmt, va_list args) @@ -138,15 +140,7 @@ rb_syntax_error_append(VALUE exc, VALUE file, int line, int column, } else { VALUE mesg; - if (NIL_P(exc)) { - mesg = rb_enc_str_new(0, 0, enc); - exc = rb_class_new_instance(1, &mesg, rb_eSyntaxError); - } - else { - mesg = rb_attr_get(exc, idMesg); - if (RSTRING_LEN(mesg) > 0 && *(RSTRING_END(mesg)-1) != '\n') - rb_str_cat_cstr(mesg, "\n"); - } + exc = syntax_error_with_path(exc, file, &mesg, enc); err_vcatf(mesg, NULL, fn, line, fmt, args); } @@ -2353,6 +2347,25 @@ syntax_error_initialize(int argc, VALUE *argv, VALUE self) return rb_call_super(argc, argv); } +static VALUE +syntax_error_with_path(VALUE exc, VALUE path, VALUE *mesg, rb_encoding *enc) +{ + if (NIL_P(exc)) { + *mesg = rb_enc_str_new(0, 0, enc); + exc = rb_class_new_instance(1, mesg, rb_eSyntaxError); + rb_ivar_set(exc, id_i_path, path); + } + else { + if (rb_attr_get(exc, id_i_path) != path) { + rb_raise(rb_eArgError, "SyntaxError#path changed"); + } + VALUE s = *mesg = rb_attr_get(exc, idMesg); + if (RSTRING_LEN(s) > 0 && *(RSTRING_END(s)-1) != '\n') + rb_str_cat_cstr(s, "\n"); + } + return exc; +} + /* * Document-module: Errno * @@ -3011,9 +3024,14 @@ Init_Exception(void) rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError); rb_define_method(rb_eSyntaxError, "initialize", syntax_error_initialize, -1); + ID id_path = rb_intern_const("path"); + + /* the path failed to parse */ + rb_attr(rb_eSyntaxError, id_path, TRUE, FALSE, FALSE); + rb_eLoadError = rb_define_class("LoadError", rb_eScriptError); /* the path failed to load */ - rb_attr(rb_eLoadError, rb_intern_const("path"), TRUE, FALSE, FALSE); + rb_attr(rb_eLoadError, id_path, TRUE, FALSE, FALSE); rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError); diff --git a/test/ruby/test_exception.rb b/test/ruby/test_exception.rb index 36f778975b..9bed2c76cd 100644 --- a/test/ruby/test_exception.rb +++ b/test/ruby/test_exception.rb @@ -1487,4 +1487,27 @@ $stderr = $stdout; raise "\x82\xa0"') do |outs, errs, status| end end end + + def test_syntax_error_path + e = assert_raise(SyntaxError) { + eval("1+", nil, "test_syntax_error_path.rb") + } + assert_equal("test_syntax_error_path.rb", e.path) + + Dir.mktmpdir do |dir| + lib = File.join(dir, "syntax_error-path.rb") + File.write(lib, "#{<<~"begin;"}\n#{<<~'end;'}") + begin; + class SyntaxError + def detailed_message(**) + STDERR.puts "\n""path=#{path}\n" + super + end + end + end; + main = File.join(dir, "syntax_error.rb") + File.write(main, "1+\n") + assert_in_out_err(%W[-r#{lib} #{main}], "", [], [:*, "\n""path=#{main}\n", :*]) + end + end end |