summaryrefslogtreecommitdiff
path: root/ast.c
diff options
context:
space:
mode:
authoryui-knk <spiketeika@gmail.com>2022-09-25 17:53:44 +0900
committerYuichiro Kaneko <spiketeika@gmail.com>2022-10-08 17:59:11 +0900
commitfbbdbdd8911ffb24d98bb71c7c33d24609ce7dfe (patch)
tree74e11b409521113dedae0e28e7013a22e61b8c3f /ast.c
parent7775d14356c375536c915ea4bd0fae019acaaeb1 (diff)
downloadruby-fbbdbdd8911ffb24d98bb71c7c33d24609ce7dfe.tar.gz
Add error_tolerant option to RubyVM::AST
If this option is enabled, SyntaxError is not raised and Node is returned even if passed script is broken. [Feature #19013]
Diffstat (limited to 'ast.c')
-rw-r--r--ast.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/ast.c b/ast.c
index 42d4126a5b..67275c47b3 100644
--- a/ast.c
+++ b/ast.c
@@ -64,8 +64,8 @@ ast_new_internal(rb_ast_t *ast, const NODE *node)
return obj;
}
-static VALUE rb_ast_parse_str(VALUE str, VALUE keep_script_lines);
-static VALUE rb_ast_parse_file(VALUE path, VALUE keep_script_lines);
+static VALUE rb_ast_parse_str(VALUE str, VALUE keep_script_lines, VALUE error_tolerant);
+static VALUE rb_ast_parse_file(VALUE path, VALUE keep_script_lines, VALUE error_tolerant);
static VALUE
ast_parse_new(void)
@@ -85,31 +85,32 @@ ast_parse_done(rb_ast_t *ast)
}
static VALUE
-ast_s_parse(rb_execution_context_t *ec, VALUE module, VALUE str, VALUE keep_script_lines)
+ast_s_parse(rb_execution_context_t *ec, VALUE module, VALUE str, VALUE keep_script_lines, VALUE error_tolerant)
{
- return rb_ast_parse_str(str, keep_script_lines);
+ return rb_ast_parse_str(str, keep_script_lines, error_tolerant);
}
static VALUE
-rb_ast_parse_str(VALUE str, VALUE keep_script_lines)
+rb_ast_parse_str(VALUE str, VALUE keep_script_lines, VALUE error_tolerant)
{
rb_ast_t *ast = 0;
StringValue(str);
VALUE vparser = ast_parse_new();
if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser);
+ if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
ast = rb_parser_compile_string_path(vparser, Qnil, str, 1);
return ast_parse_done(ast);
}
static VALUE
-ast_s_parse_file(rb_execution_context_t *ec, VALUE module, VALUE path, VALUE keep_script_lines)
+ast_s_parse_file(rb_execution_context_t *ec, VALUE module, VALUE path, VALUE keep_script_lines, VALUE error_tolerant)
{
- return rb_ast_parse_file(path, keep_script_lines);
+ return rb_ast_parse_file(path, keep_script_lines, error_tolerant);
}
static VALUE
-rb_ast_parse_file(VALUE path, VALUE keep_script_lines)
+rb_ast_parse_file(VALUE path, VALUE keep_script_lines, VALUE error_tolerant)
{
VALUE f;
rb_ast_t *ast = 0;
@@ -120,6 +121,7 @@ rb_ast_parse_file(VALUE path, VALUE keep_script_lines)
rb_funcall(f, rb_intern("set_encoding"), 2, rb_enc_from_encoding(enc), rb_str_new_cstr("-"));
VALUE vparser = ast_parse_new();
if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser);
+ if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
ast = rb_parser_compile_file_path(vparser, Qnil, f, 1);
rb_io_close(f);
return ast_parse_done(ast);
@@ -139,13 +141,14 @@ lex_array(VALUE array, int index)
}
static VALUE
-rb_ast_parse_array(VALUE array, VALUE keep_script_lines)
+rb_ast_parse_array(VALUE array, VALUE keep_script_lines, VALUE error_tolerant)
{
rb_ast_t *ast = 0;
array = rb_check_array_type(array);
VALUE vparser = ast_parse_new();
if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser);
+ if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser);
ast = rb_parser_compile_generic(vparser, lex_array, Qnil, array, 1);
return ast_parse_done(ast);
}
@@ -193,7 +196,7 @@ script_lines(VALUE path)
}
static VALUE
-ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script_lines)
+ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script_lines, VALUE error_tolerant)
{
VALUE node, lines = Qnil;
const rb_iseq_t *iseq;
@@ -232,13 +235,13 @@ ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script
}
if (!NIL_P(lines) || !NIL_P(lines = script_lines(path))) {
- node = rb_ast_parse_array(lines, keep_script_lines);
+ node = rb_ast_parse_array(lines, keep_script_lines, error_tolerant);
}
else if (e_option) {
- node = rb_ast_parse_str(rb_e_script, keep_script_lines);
+ node = rb_ast_parse_str(rb_e_script, keep_script_lines, error_tolerant);
}
else {
- node = rb_ast_parse_file(path, keep_script_lines);
+ node = rb_ast_parse_file(path, keep_script_lines, error_tolerant);
}
return node_find(node, node_id);