diff options
-rw-r--r-- | prism/prism.c | 8 | ||||
-rw-r--r-- | prism_compile.c | 55 |
2 files changed, 31 insertions, 32 deletions
diff --git a/prism/prism.c b/prism/prism.c index e33d3e1d3c..929255ef44 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -19319,7 +19319,9 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm // Here we're going to find the first shebang that includes "ruby" and start // parsing from there. if (search_shebang) { - bool found = false; + // If a shebang that includes "ruby" is not found, then we're going to a + // a load error to the list of errors on the parser. + bool found_shebang = false; // This is going to point to the start of each line as we check it. // We'll maintain a moving window looking at each line at they come. @@ -19342,14 +19344,14 @@ pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm } if (pm_strnstr((const char *) cursor, "ruby", length) != NULL) { - found = true; + found_shebang = true; parser->encoding_comment_start = newline + 1; break; } } } - if (found) { + if (found_shebang) { parser->previous = (pm_token_t) { .type = PM_TOKEN_EOF, .start = cursor, .end = cursor }; parser->current = (pm_token_t) { .type = PM_TOKEN_EOF, .start = cursor, .end = cursor }; } else { diff --git a/prism_compile.c b/prism_compile.c index 5a5b1e7d61..e63933926b 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -8390,11 +8390,21 @@ pm_parse_process_error(const pm_parse_result_t *result) const pm_string_t *filepath = &parser->filepath; for (const pm_diagnostic_t *error = head; error != NULL; error = (const pm_diagnostic_t *) error->node.next) { - // Any errors with the level that is not PM_ERROR_LEVEL_SYNTAX - // effectively take over as the only argument that gets raised. This is - // to allow priority messages that should be handled before anything - // else. - if (error->level != PM_ERROR_LEVEL_SYNTAX) { + switch (error->level) { + case PM_ERROR_LEVEL_SYNTAX: + // It is implicitly assumed that the error messages will be + // encodeable as UTF-8. Because of this, we can't include source + // examples that contain invalid byte sequences. So if any source + // examples include invalid UTF-8 byte sequences, we will skip + // showing source examples entirely. + if (valid_utf8 && !pm_parse_process_error_utf8_p(parser, &error->location)) { + valid_utf8 = false; + } + break; + case PM_ERROR_LEVEL_ARGUMENT: { + // Any errors with the level PM_ERROR_LEVEL_ARGUMENT take over as + // the only argument that gets raised. This is to allow priority + // messages that should be handled before anything else. int32_t line_number = (int32_t) pm_location_line_number(parser, &error->location); pm_buffer_append_format( @@ -8415,33 +8425,20 @@ pm_parse_process_error(const pm_parse_result_t *result) pm_parser_errors_format(parser, &error_list, &buffer, rb_stderr_tty_p(), false); } - VALUE class; - switch (error->level) { - case PM_ERROR_LEVEL_ARGUMENT: - class = rb_eArgError; - break; - case PM_ERROR_LEVEL_LOAD: - class = rb_eLoadError; - break; - default: - class = rb_eSyntaxError; - RUBY_ASSERT(false && "unexpected error level"); - break; - } - - VALUE value = rb_exc_new(class, pm_buffer_value(&buffer), pm_buffer_length(&buffer)); + VALUE value = rb_exc_new(rb_eArgError, pm_buffer_value(&buffer), pm_buffer_length(&buffer)); pm_buffer_free(&buffer); return value; - } - - // It is implicitly assumed that the error messages will be encodeable - // as UTF-8. Because of this, we can't include source examples that - // contain invalid byte sequences. So if any source examples include - // invalid UTF-8 byte sequences, we will skip showing source examples - // entirely. - if (valid_utf8 && !pm_parse_process_error_utf8_p(parser, &error->location)) { - valid_utf8 = false; + } + case PM_ERROR_LEVEL_LOAD: { + // Load errors are much simpler, because they don't include any of + // the source in them. We create the error directly from the + // message. + VALUE message = rb_enc_str_new_cstr(error->message, rb_locale_encoding()); + VALUE value = rb_exc_new3(rb_eLoadError, message); + rb_ivar_set(value, rb_intern_const("@path"), Qnil); + return value; + } } } |