mirror of
https://github.com/ruby/ruby.git
synced 2025-09-16 00:54:01 +02:00
Introduce NODE_FILE
`__FILE__` was managed by `NODE_STR` with `String` object. This commit introduces `NODE_FILE` and `struct rb_parser_string` so that 1. `__FILE__` is detectable from AST Node 2. Reduce dependency ruby object
This commit is contained in:
parent
91a0d1c437
commit
7a050638b1
12 changed files with 185 additions and 37 deletions
2
ast.c
2
ast.c
|
@ -694,6 +694,8 @@ node_children(rb_ast_t *ast, const NODE *node)
|
||||||
}
|
}
|
||||||
case NODE_LINE:
|
case NODE_LINE:
|
||||||
return rb_ary_new_from_args(1, rb_node_line_lineno_val(node));
|
return rb_ary_new_from_args(1, rb_node_line_lineno_val(node));
|
||||||
|
case NODE_FILE:
|
||||||
|
return rb_ary_new_from_args(1, rb_node_file_path_val(node));
|
||||||
case NODE_ERROR:
|
case NODE_ERROR:
|
||||||
return rb_ary_new_from_node_args(ast, 0);
|
return rb_ary_new_from_node_args(ast, 0);
|
||||||
case NODE_ARGS_AUX:
|
case NODE_ARGS_AUX:
|
||||||
|
|
|
@ -10495,6 +10495,7 @@ node_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/variable.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/variable.h
|
||||||
|
|
51
compile.c
51
compile.c
|
@ -819,7 +819,6 @@ get_nd_vid(const NODE *node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NODE *
|
static NODE *
|
||||||
get_nd_value(const NODE *node)
|
get_nd_value(const NODE *node)
|
||||||
{
|
{
|
||||||
|
@ -833,6 +832,19 @@ get_nd_value(const NODE *node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
get_string_value(const NODE *node)
|
||||||
|
{
|
||||||
|
switch (nd_type(node)) {
|
||||||
|
case NODE_STR:
|
||||||
|
return RNODE_STR(node)->nd_lit;
|
||||||
|
case NODE_FILE:
|
||||||
|
return rb_node_file_path_val(node);
|
||||||
|
default:
|
||||||
|
rb_bug("unexpected node: %s", ruby_node_name(nd_type(node)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc)
|
rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc)
|
||||||
{
|
{
|
||||||
|
@ -4282,7 +4294,7 @@ all_string_result_p(const NODE *node)
|
||||||
{
|
{
|
||||||
if (!node) return FALSE;
|
if (!node) return FALSE;
|
||||||
switch (nd_type(node)) {
|
switch (nd_type(node)) {
|
||||||
case NODE_STR: case NODE_DSTR:
|
case NODE_STR: case NODE_DSTR: case NODE_FILE:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case NODE_IF: case NODE_UNLESS:
|
case NODE_IF: case NODE_UNLESS:
|
||||||
if (!RNODE_IF(node)->nd_body || !RNODE_IF(node)->nd_else) return FALSE;
|
if (!RNODE_IF(node)->nd_body || !RNODE_IF(node)->nd_else) return FALSE;
|
||||||
|
@ -4493,6 +4505,7 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond,
|
||||||
goto again;
|
goto again;
|
||||||
case NODE_LIT: /* NODE_LIT is always true */
|
case NODE_LIT: /* NODE_LIT is always true */
|
||||||
case NODE_LINE:
|
case NODE_LINE:
|
||||||
|
case NODE_FILE:
|
||||||
case NODE_TRUE:
|
case NODE_TRUE:
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
case NODE_ZLIST:
|
case NODE_ZLIST:
|
||||||
|
@ -4658,6 +4671,7 @@ static_literal_node_p(const NODE *node, const rb_iseq_t *iseq)
|
||||||
case NODE_FALSE:
|
case NODE_FALSE:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
|
case NODE_FILE:
|
||||||
return ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal;
|
return ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal;
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -4676,16 +4690,17 @@ static_literal_value(const NODE *node, rb_iseq_t *iseq)
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
case NODE_LINE:
|
case NODE_LINE:
|
||||||
return rb_node_line_lineno_val(node);
|
return rb_node_line_lineno_val(node);
|
||||||
|
case NODE_FILE:
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) {
|
if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) {
|
||||||
VALUE lit;
|
VALUE lit;
|
||||||
VALUE debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX((int)nd_line(node)));
|
VALUE debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX((int)nd_line(node)));
|
||||||
lit = rb_str_dup(RNODE_STR(node)->nd_lit);
|
lit = rb_str_dup(get_string_value(node));
|
||||||
rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info));
|
rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info));
|
||||||
return rb_str_freeze(lit);
|
return rb_str_freeze(lit);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return rb_fstring(RNODE_STR(node)->nd_lit);
|
return rb_fstring(get_string_value(node));
|
||||||
}
|
}
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
return RNODE_LIT(node)->nd_lit;
|
return RNODE_LIT(node)->nd_lit;
|
||||||
|
@ -5067,6 +5082,8 @@ rb_node_case_when_optimizable_literal(const NODE *const node)
|
||||||
return rb_node_line_lineno_val(node);
|
return rb_node_line_lineno_val(node);
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
return rb_fstring(RNODE_STR(node)->nd_lit);
|
return rb_fstring(RNODE_STR(node)->nd_lit);
|
||||||
|
case NODE_FILE:
|
||||||
|
return rb_fstring(rb_node_file_path_val(node));
|
||||||
}
|
}
|
||||||
return Qundef;
|
return Qundef;
|
||||||
}
|
}
|
||||||
|
@ -5086,9 +5103,9 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
|
||||||
rb_hash_aset(literals, lit, (VALUE)(l1) | 1);
|
rb_hash_aset(literals, lit, (VALUE)(l1) | 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nd_type_p(val, NODE_STR)) {
|
if (nd_type_p(val, NODE_STR) || nd_type_p(val, NODE_FILE)) {
|
||||||
debugp_param("nd_lit", RNODE_STR(val)->nd_lit);
|
debugp_param("nd_lit", get_string_value(val));
|
||||||
lit = rb_fstring(RNODE_STR(val)->nd_lit);
|
lit = rb_fstring(get_string_value(val));
|
||||||
ADD_INSN1(cond_seq, val, putobject, lit);
|
ADD_INSN1(cond_seq, val, putobject, lit);
|
||||||
RB_OBJ_WRITTEN(iseq, Qundef, lit);
|
RB_OBJ_WRITTEN(iseq, Qundef, lit);
|
||||||
}
|
}
|
||||||
|
@ -5692,6 +5709,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
case NODE_LINE:
|
case NODE_LINE:
|
||||||
|
case NODE_FILE:
|
||||||
case NODE_ZLIST:
|
case NODE_ZLIST:
|
||||||
case NODE_AND:
|
case NODE_AND:
|
||||||
case NODE_OR:
|
case NODE_OR:
|
||||||
|
@ -7105,6 +7123,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
|
||||||
}
|
}
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
case NODE_LINE:
|
case NODE_LINE:
|
||||||
|
case NODE_FILE:
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
case NODE_XSTR:
|
case NODE_XSTR:
|
||||||
case NODE_DSTR:
|
case NODE_DSTR:
|
||||||
|
@ -8321,12 +8340,13 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
|
||||||
/* optimization shortcut
|
/* optimization shortcut
|
||||||
* "literal".freeze -> opt_str_freeze("literal")
|
* "literal".freeze -> opt_str_freeze("literal")
|
||||||
*/
|
*/
|
||||||
if (get_nd_recv(node) && nd_type_p(get_nd_recv(node), NODE_STR) &&
|
if (get_nd_recv(node) &&
|
||||||
|
(nd_type_p(get_nd_recv(node), NODE_STR) || nd_type_p(get_nd_recv(node), NODE_FILE)) &&
|
||||||
(get_node_call_nd_mid(node) == idFreeze || get_node_call_nd_mid(node) == idUMinus) &&
|
(get_node_call_nd_mid(node) == idFreeze || get_node_call_nd_mid(node) == idUMinus) &&
|
||||||
get_nd_args(node) == NULL &&
|
get_nd_args(node) == NULL &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
|
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
|
||||||
VALUE str = rb_fstring(RNODE_STR(get_nd_recv(node))->nd_lit);
|
VALUE str = rb_fstring(get_string_value(get_nd_recv(node)));
|
||||||
if (get_node_call_nd_mid(node) == idUMinus) {
|
if (get_node_call_nd_mid(node) == idUMinus) {
|
||||||
ADD_INSN2(ret, line_node, opt_str_uminus, str,
|
ADD_INSN2(ret, line_node, opt_str_uminus, str,
|
||||||
new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE));
|
new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE));
|
||||||
|
@ -8346,11 +8366,11 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
|
||||||
*/
|
*/
|
||||||
if (get_node_call_nd_mid(node) == idAREF && !private_recv_p(node) && get_nd_args(node) &&
|
if (get_node_call_nd_mid(node) == idAREF && !private_recv_p(node) && get_nd_args(node) &&
|
||||||
nd_type_p(get_nd_args(node), NODE_LIST) && RNODE_LIST(get_nd_args(node))->as.nd_alen == 1 &&
|
nd_type_p(get_nd_args(node), NODE_LIST) && RNODE_LIST(get_nd_args(node))->as.nd_alen == 1 &&
|
||||||
nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_STR) &&
|
(nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_STR) || nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_FILE)) &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
||||||
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
|
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
|
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) {
|
||||||
VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(get_nd_args(node))->nd_head)->nd_lit);
|
VALUE str = rb_fstring(get_string_value(RNODE_LIST(get_nd_args(node))->nd_head));
|
||||||
CHECK(COMPILE(ret, "recv", get_nd_recv(node)));
|
CHECK(COMPILE(ret, "recv", get_nd_recv(node)));
|
||||||
ADD_INSN2(ret, line_node, opt_aref_with, str,
|
ADD_INSN2(ret, line_node, opt_aref_with, str,
|
||||||
new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE));
|
new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE));
|
||||||
|
@ -9697,12 +9717,12 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
|
||||||
*/
|
*/
|
||||||
if (mid == idASET && !private_recv_p(node) && RNODE_ATTRASGN(node)->nd_args &&
|
if (mid == idASET && !private_recv_p(node) && RNODE_ATTRASGN(node)->nd_args &&
|
||||||
nd_type_p(RNODE_ATTRASGN(node)->nd_args, NODE_LIST) && RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->as.nd_alen == 2 &&
|
nd_type_p(RNODE_ATTRASGN(node)->nd_args, NODE_LIST) && RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->as.nd_alen == 2 &&
|
||||||
nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_STR) &&
|
(nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_STR) || nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_FILE)) &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
||||||
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
|
!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal &&
|
||||||
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction)
|
ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction)
|
||||||
{
|
{
|
||||||
VALUE str = rb_fstring(RNODE_STR(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head)->nd_lit);
|
VALUE str = rb_fstring(get_string_value(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head));
|
||||||
CHECK(COMPILE(ret, "recv", RNODE_ATTRASGN(node)->nd_recv));
|
CHECK(COMPILE(ret, "recv", RNODE_ATTRASGN(node)->nd_recv));
|
||||||
CHECK(COMPILE(ret, "value", RNODE_LIST(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_next)->nd_head));
|
CHECK(COMPILE(ret, "value", RNODE_LIST(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_next)->nd_head));
|
||||||
if (!popped) {
|
if (!popped) {
|
||||||
|
@ -10134,10 +10154,11 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case NODE_FILE:
|
||||||
case NODE_STR:{
|
case NODE_STR:{
|
||||||
debugp_param("nd_lit", RNODE_STR(node)->nd_lit);
|
debugp_param("nd_lit", get_string_value(node));
|
||||||
if (!popped) {
|
if (!popped) {
|
||||||
VALUE lit = RNODE_STR(node)->nd_lit;
|
VALUE lit = get_string_value(node);
|
||||||
if (!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) {
|
if (!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) {
|
||||||
lit = rb_fstring(lit);
|
lit = rb_fstring(lit);
|
||||||
ADD_INSN1(ret, node, putstring, lit);
|
ADD_INSN1(ret, node, putstring, lit);
|
||||||
|
|
|
@ -68,4 +68,5 @@ enum lex_state_e {
|
||||||
};
|
};
|
||||||
|
|
||||||
VALUE rb_node_line_lineno_val(const NODE *);
|
VALUE rb_node_line_lineno_val(const NODE *);
|
||||||
|
VALUE rb_node_file_path_val(const NODE *);
|
||||||
#endif /* INTERNAL_RUBY_PARSE_H */
|
#endif /* INTERNAL_RUBY_PARSE_H */
|
||||||
|
|
|
@ -457,6 +457,8 @@ class RbInspector(LLDBInterface):
|
||||||
self._append_expression("*(struct RNode_ERROR *) %0#x" % val.GetValueAsUnsigned())
|
self._append_expression("*(struct RNode_ERROR *) %0#x" % val.GetValueAsUnsigned())
|
||||||
elif nd_type == self.ruby_globals["NODE_LINE"]:
|
elif nd_type == self.ruby_globals["NODE_LINE"]:
|
||||||
self._append_expression("*(struct RNode_LINE *) %0#x" % val.GetValueAsUnsigned())
|
self._append_expression("*(struct RNode_LINE *) %0#x" % val.GetValueAsUnsigned())
|
||||||
|
elif nd_type == self.ruby_globals["NODE_FILE"]:
|
||||||
|
self._append_expression("*(struct RNode_FILE *) %0#x" % val.GetValueAsUnsigned())
|
||||||
elif nd_type == self.ruby_globals["NODE_RIPPER"]:
|
elif nd_type == self.ruby_globals["NODE_RIPPER"]:
|
||||||
self._append_expression("*(struct RNode_RIPPER *) %0#x" % val.GetValueAsUnsigned())
|
self._append_expression("*(struct RNode_RIPPER *) %0#x" % val.GetValueAsUnsigned())
|
||||||
elif nd_type == self.ruby_globals["NODE_RIPPER_VALUES"]:
|
elif nd_type == self.ruby_globals["NODE_RIPPER_VALUES"]:
|
||||||
|
|
9
node.c
9
node.c
|
@ -169,10 +169,19 @@ struct rb_ast_local_table_link {
|
||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
parser_string_free(rb_ast_t *ast, rb_parser_string_t *str)
|
||||||
|
{
|
||||||
|
xfree(str);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
|
free_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
|
||||||
{
|
{
|
||||||
switch (nd_type(node)) {
|
switch (nd_type(node)) {
|
||||||
|
case NODE_FILE:
|
||||||
|
parser_string_free(ast, RNODE_FILE(node)->path);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "internal/hash.h"
|
#include "internal/hash.h"
|
||||||
|
#include "internal/ruby_parser.h"
|
||||||
#include "internal/variable.h"
|
#include "internal/variable.h"
|
||||||
#include "ruby/ruby.h"
|
#include "ruby/ruby.h"
|
||||||
#include "vm_core.h"
|
#include "vm_core.h"
|
||||||
|
@ -64,6 +65,7 @@
|
||||||
#define F_INT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_INT(type(node)->name)
|
#define F_INT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_INT(type(node)->name)
|
||||||
#define F_LONG(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LONG(type(node)->name)
|
#define F_LONG(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LONG(type(node)->name)
|
||||||
#define F_LIT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LIT(type(node)->name)
|
#define F_LIT(name, type, ann) SIMPLE_FIELD1(#name, ann) A_LIT(type(node)->name)
|
||||||
|
#define F_VALUE(name, val, ann) SIMPLE_FIELD1(#name, ann) A_LIT(val)
|
||||||
#define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
|
#define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
|
||||||
|
|
||||||
#define F_NODE(name, type, ann) \
|
#define F_NODE(name, type, ann) \
|
||||||
|
@ -1105,6 +1107,13 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
|
||||||
ANN("example: __LINE__");
|
ANN("example: __LINE__");
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case NODE_FILE:
|
||||||
|
ANN("line");
|
||||||
|
ANN("format: [path]");
|
||||||
|
ANN("example: __FILE__");
|
||||||
|
F_VALUE(path, rb_node_file_path_val(node), "path");
|
||||||
|
return;
|
||||||
|
|
||||||
case NODE_ERROR:
|
case NODE_ERROR:
|
||||||
ANN("Broken input recovered by Error Tolerant mode");
|
ANN("Broken input recovered by Error Tolerant mode");
|
||||||
return;
|
return;
|
||||||
|
|
76
parse.y
76
parse.y
|
@ -954,6 +954,7 @@ static rb_node_aryptn_t *rb_node_aryptn_new(struct parser_params *p, NODE *pre_a
|
||||||
static rb_node_hshptn_t *rb_node_hshptn_new(struct parser_params *p, NODE *nd_pconst, NODE *nd_pkwargs, NODE *nd_pkwrestarg, const YYLTYPE *loc);
|
static rb_node_hshptn_t *rb_node_hshptn_new(struct parser_params *p, NODE *nd_pconst, NODE *nd_pkwargs, NODE *nd_pkwrestarg, const YYLTYPE *loc);
|
||||||
static rb_node_fndptn_t *rb_node_fndptn_new(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc);
|
static rb_node_fndptn_t *rb_node_fndptn_new(struct parser_params *p, NODE *pre_rest_arg, NODE *args, NODE *post_rest_arg, const YYLTYPE *loc);
|
||||||
static rb_node_line_t *rb_node_line_new(struct parser_params *p, const YYLTYPE *loc);
|
static rb_node_line_t *rb_node_line_new(struct parser_params *p, const YYLTYPE *loc);
|
||||||
|
static rb_node_file_t *rb_node_file_new(struct parser_params *p, VALUE str, const YYLTYPE *loc);
|
||||||
static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE *loc);
|
static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE *loc);
|
||||||
|
|
||||||
#define NEW_SCOPE(a,b,loc) (NODE *)rb_node_scope_new(p,a,b,loc)
|
#define NEW_SCOPE(a,b,loc) (NODE *)rb_node_scope_new(p,a,b,loc)
|
||||||
|
@ -1056,6 +1057,7 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE
|
||||||
#define NEW_HSHPTN(c,kw,kwrest,loc) (NODE *)rb_node_hshptn_new(p,c,kw,kwrest,loc)
|
#define NEW_HSHPTN(c,kw,kwrest,loc) (NODE *)rb_node_hshptn_new(p,c,kw,kwrest,loc)
|
||||||
#define NEW_FNDPTN(pre,a,post,loc) (NODE *)rb_node_fndptn_new(p,pre,a,post,loc)
|
#define NEW_FNDPTN(pre,a,post,loc) (NODE *)rb_node_fndptn_new(p,pre,a,post,loc)
|
||||||
#define NEW_LINE(loc) (NODE *)rb_node_line_new(p,loc)
|
#define NEW_LINE(loc) (NODE *)rb_node_line_new(p,loc)
|
||||||
|
#define NEW_FILE(str,loc) (NODE *)rb_node_file_new(p,str,loc)
|
||||||
#define NEW_ERROR(loc) (NODE *)rb_node_error_new(p,loc)
|
#define NEW_ERROR(loc) (NODE *)rb_node_error_new(p,loc)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1911,6 +1913,56 @@ get_nd_args(struct parser_params *p, NODE *node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef RIPPER
|
||||||
|
static rb_parser_string_t *
|
||||||
|
rb_parser_string_new(rb_parser_t *p, const char *ptr, long len)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
rb_parser_string_t *str;
|
||||||
|
|
||||||
|
if (len < 0) {
|
||||||
|
rb_bug("negative string size (or size too big): %ld", len);
|
||||||
|
}
|
||||||
|
|
||||||
|
size = offsetof(rb_parser_string_t, ptr) + len + 1;
|
||||||
|
str = xcalloc(1, size);
|
||||||
|
|
||||||
|
if (ptr) {
|
||||||
|
memcpy(str->ptr, ptr, len);
|
||||||
|
}
|
||||||
|
str->len = len;
|
||||||
|
str->ptr[len] = '\0';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rb_parser_string_t *
|
||||||
|
rb_parser_encoding_string_new(rb_parser_t *p, const char *ptr, long len, rb_encoding *enc)
|
||||||
|
{
|
||||||
|
rb_parser_string_t *str = rb_parser_string_new(p, ptr, len);
|
||||||
|
str->enc = enc;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
rb_parser_string_length(rb_parser_string_t *str)
|
||||||
|
{
|
||||||
|
return str->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
rb_parser_string_pointer(rb_parser_string_t *str)
|
||||||
|
{
|
||||||
|
return str->ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static rb_parser_string_t *
|
||||||
|
rb_str_to_parser_encoding_string(rb_parser_t *p, VALUE str)
|
||||||
|
{
|
||||||
|
/* Type check */
|
||||||
|
return rb_parser_encoding_string_new(p, RSTRING_PTR(str), RSTRING_LEN(str), rb_enc_get(str));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%expect 0
|
%expect 0
|
||||||
|
@ -6599,6 +6651,7 @@ singleton : var_ref
|
||||||
case NODE_DREGX:
|
case NODE_DREGX:
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
case NODE_LINE:
|
case NODE_LINE:
|
||||||
|
case NODE_FILE:
|
||||||
case NODE_DSYM:
|
case NODE_DSYM:
|
||||||
case NODE_LIST:
|
case NODE_LIST:
|
||||||
case NODE_ZLIST:
|
case NODE_ZLIST:
|
||||||
|
@ -12186,6 +12239,15 @@ rb_node_line_new(struct parser_params *p, const YYLTYPE *loc)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static rb_node_file_t *
|
||||||
|
rb_node_file_new(struct parser_params *p, VALUE str, const YYLTYPE *loc)
|
||||||
|
{
|
||||||
|
rb_node_file_t *n = NODE_NEWNODE(NODE_FILE, rb_node_file_t, loc);
|
||||||
|
n->path = rb_str_to_parser_encoding_string(p, str);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
static rb_node_cdecl_t *
|
static rb_node_cdecl_t *
|
||||||
rb_node_cdecl_new(struct parser_params *p, ID nd_vid, NODE *nd_value, NODE *nd_else, const YYLTYPE *loc)
|
rb_node_cdecl_new(struct parser_params *p, ID nd_vid, NODE *nd_value, NODE *nd_else, const YYLTYPE *loc)
|
||||||
{
|
{
|
||||||
|
@ -12786,10 +12848,7 @@ gettable(struct parser_params *p, ID id, const YYLTYPE *loc)
|
||||||
VALUE file = p->ruby_sourcefile_string;
|
VALUE file = p->ruby_sourcefile_string;
|
||||||
if (NIL_P(file))
|
if (NIL_P(file))
|
||||||
file = rb_str_new(0, 0);
|
file = rb_str_new(0, 0);
|
||||||
else
|
node = NEW_FILE(file, loc);
|
||||||
file = rb_str_dup(file);
|
|
||||||
node = NEW_STR(file, loc);
|
|
||||||
RB_OBJ_WRITTEN(p->ast, Qnil, file);
|
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
case keyword__LINE__:
|
case keyword__LINE__:
|
||||||
|
@ -13691,6 +13750,12 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable,
|
||||||
RB_OBJ_WRITE(p->ast, &RNODE_LIT(value)->nd_lit, lit);
|
RB_OBJ_WRITE(p->ast, &RNODE_LIT(value)->nd_lit, lit);
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
|
case NODE_FILE:
|
||||||
|
lit = rb_fstring(rb_node_file_path_val(value));
|
||||||
|
value = NEW_LIT(lit, loc);
|
||||||
|
RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(value)->nd_lit);
|
||||||
|
return value;
|
||||||
|
|
||||||
case NODE_ZLIST:
|
case NODE_ZLIST:
|
||||||
lit = rb_ary_new();
|
lit = rb_ary_new();
|
||||||
OBJ_FREEZE_RAW(lit);
|
OBJ_FREEZE_RAW(lit);
|
||||||
|
@ -13985,6 +14050,7 @@ void_expr(struct parser_params *p, NODE *node)
|
||||||
break;
|
break;
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
case NODE_LINE:
|
case NODE_LINE:
|
||||||
|
case NODE_FILE:
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
case NODE_DSTR:
|
case NODE_DSTR:
|
||||||
case NODE_DREGX:
|
case NODE_DREGX:
|
||||||
|
@ -14123,6 +14189,7 @@ is_static_content(NODE *node)
|
||||||
} while ((node = RNODE_LIST(node)->nd_next) != 0);
|
} while ((node = RNODE_LIST(node)->nd_next) != 0);
|
||||||
case NODE_LIT:
|
case NODE_LIT:
|
||||||
case NODE_LINE:
|
case NODE_LINE:
|
||||||
|
case NODE_FILE:
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
case NODE_NIL:
|
case NODE_NIL:
|
||||||
case NODE_TRUE:
|
case NODE_TRUE:
|
||||||
|
@ -14208,6 +14275,7 @@ cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *l
|
||||||
case NODE_DSTR:
|
case NODE_DSTR:
|
||||||
case NODE_EVSTR:
|
case NODE_EVSTR:
|
||||||
case NODE_STR:
|
case NODE_STR:
|
||||||
|
case NODE_FILE:
|
||||||
SWITCH_BY_COND_TYPE(type, warn, "string ");
|
SWITCH_BY_COND_TYPE(type, warn, "string ");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,6 @@
|
||||||
|
|
||||||
#include "rubyparser.h"
|
#include "rubyparser.h"
|
||||||
|
|
||||||
VALUE
|
|
||||||
rb_node_line_lineno_val(const NODE *node)
|
|
||||||
{
|
|
||||||
return INT2FIX(node->nd_loc.beg_pos.lineno);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef UNIVERSAL_PARSER
|
#ifdef UNIVERSAL_PARSER
|
||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
@ -920,3 +914,16 @@ rb_parser_set_yydebug(VALUE vparser, VALUE flag)
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_node_line_lineno_val(const NODE *node)
|
||||||
|
{
|
||||||
|
return INT2FIX(node->nd_loc.beg_pos.lineno);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_node_file_path_val(const NODE *node)
|
||||||
|
{
|
||||||
|
rb_parser_string_t *str = RNODE_FILE(node)->path;
|
||||||
|
return rb_enc_str_new(str->ptr, str->len, str->enc);
|
||||||
|
}
|
||||||
|
|
47
rubyparser.h
47
rubyparser.h
|
@ -22,6 +22,29 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef FLEX_ARY_LEN
|
||||||
|
/* From internal/compilers.h */
|
||||||
|
/* A macro for defining a flexible array, like: VALUE ary[FLEX_ARY_LEN]; */
|
||||||
|
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
||||||
|
# define FLEX_ARY_LEN /* VALUE ary[]; */
|
||||||
|
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||||
|
# define FLEX_ARY_LEN 0 /* VALUE ary[0]; */
|
||||||
|
#else
|
||||||
|
# define FLEX_ARY_LEN 1 /* VALUE ary[1]; */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parser String
|
||||||
|
*/
|
||||||
|
typedef struct rb_parser_string {
|
||||||
|
rb_encoding *enc;
|
||||||
|
/* Length of the string, not including terminating NUL character. */
|
||||||
|
long len;
|
||||||
|
/* Pointer to the contents of the string. */
|
||||||
|
char ptr[FLEX_ARY_LEN];
|
||||||
|
} rb_parser_string_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AST Node
|
* AST Node
|
||||||
*/
|
*/
|
||||||
|
@ -131,23 +154,12 @@ enum node_type {
|
||||||
NODE_FNDPTN,
|
NODE_FNDPTN,
|
||||||
NODE_ERROR,
|
NODE_ERROR,
|
||||||
NODE_LINE,
|
NODE_LINE,
|
||||||
|
NODE_FILE,
|
||||||
NODE_RIPPER,
|
NODE_RIPPER,
|
||||||
NODE_RIPPER_VALUES,
|
NODE_RIPPER_VALUES,
|
||||||
NODE_LAST
|
NODE_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef FLEX_ARY_LEN
|
|
||||||
/* From internal/compilers.h */
|
|
||||||
/* A macro for defining a flexible array, like: VALUE ary[FLEX_ARY_LEN]; */
|
|
||||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
|
||||||
# define FLEX_ARY_LEN /* VALUE ary[]; */
|
|
||||||
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
|
||||||
# define FLEX_ARY_LEN 0 /* VALUE ary[0]; */
|
|
||||||
#else
|
|
||||||
# define FLEX_ARY_LEN 1 /* VALUE ary[1]; */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct rb_ast_id_table {
|
typedef struct rb_ast_id_table {
|
||||||
int size;
|
int size;
|
||||||
ID ids[FLEX_ARY_LEN];
|
ID ids[FLEX_ARY_LEN];
|
||||||
|
@ -936,6 +948,12 @@ typedef struct RNode_LINE {
|
||||||
NODE node;
|
NODE node;
|
||||||
} rb_node_line_t;
|
} rb_node_line_t;
|
||||||
|
|
||||||
|
typedef struct RNode_FILE {
|
||||||
|
NODE node;
|
||||||
|
|
||||||
|
struct rb_parser_string *path;
|
||||||
|
} rb_node_file_t;
|
||||||
|
|
||||||
typedef struct RNode_ERROR {
|
typedef struct RNode_ERROR {
|
||||||
NODE node;
|
NODE node;
|
||||||
} rb_node_error_t;
|
} rb_node_error_t;
|
||||||
|
@ -1046,6 +1064,7 @@ typedef struct RNode_ERROR {
|
||||||
#define RNODE_HSHPTN(node) ((struct RNode_HSHPTN *)(node))
|
#define RNODE_HSHPTN(node) ((struct RNode_HSHPTN *)(node))
|
||||||
#define RNODE_FNDPTN(node) ((struct RNode_FNDPTN *)(node))
|
#define RNODE_FNDPTN(node) ((struct RNode_FNDPTN *)(node))
|
||||||
#define RNODE_LINE(node) ((struct RNode_LINE *)(node))
|
#define RNODE_LINE(node) ((struct RNode_LINE *)(node))
|
||||||
|
#define RNODE_FILE(node) ((struct RNode_FILE *)(node))
|
||||||
|
|
||||||
#ifdef RIPPER
|
#ifdef RIPPER
|
||||||
typedef struct RNode_RIPPER {
|
typedef struct RNode_RIPPER {
|
||||||
|
@ -1406,6 +1425,10 @@ void rb_ruby_parser_config_free(rb_parser_config_t *config);
|
||||||
rb_parser_t *rb_ruby_parser_allocate(rb_parser_config_t *config);
|
rb_parser_t *rb_ruby_parser_allocate(rb_parser_config_t *config);
|
||||||
rb_parser_t *rb_ruby_parser_new(rb_parser_config_t *config);
|
rb_parser_t *rb_ruby_parser_new(rb_parser_config_t *config);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
long rb_parser_string_length(rb_parser_string_t *str);
|
||||||
|
char *rb_parser_string_pointer(rb_parser_string_t *str);
|
||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_END
|
RUBY_SYMBOL_EXPORT_END
|
||||||
|
|
||||||
#endif /* RUBY_RUBYPARSER_H */
|
#endif /* RUBY_RUBYPARSER_H */
|
||||||
|
|
|
@ -582,8 +582,10 @@ class TestRubyOptions < Test::Unit::TestCase
|
||||||
t.rewind
|
t.rewind
|
||||||
t.truncate(0)
|
t.truncate(0)
|
||||||
t.puts "if a = __LINE__; end"
|
t.puts "if a = __LINE__; end"
|
||||||
|
t.puts "if a = __FILE__; end"
|
||||||
t.flush
|
t.flush
|
||||||
err = ["#{t.path}:1:#{warning}",
|
err = ["#{t.path}:1:#{warning}",
|
||||||
|
"#{t.path}:2:#{warning}",
|
||||||
]
|
]
|
||||||
assert_in_out_err(["-w", t.path], "", [], err)
|
assert_in_out_err(["-w", t.path], "", [], err)
|
||||||
assert_in_out_err(["-wr", t.path, "-e", ""], "", [], err)
|
assert_in_out_err(["-wr", t.path, "-e", ""], "", [], err)
|
||||||
|
|
|
@ -1210,6 +1210,9 @@ eom
|
||||||
assert_warn(/string literal in condition/) do
|
assert_warn(/string literal in condition/) do
|
||||||
eval('1 if ""')
|
eval('1 if ""')
|
||||||
end
|
end
|
||||||
|
assert_warning(/string literal in condition/) do
|
||||||
|
eval('1 if __FILE__')
|
||||||
|
end
|
||||||
assert_warn(/regex literal in condition/) do
|
assert_warn(/regex literal in condition/) do
|
||||||
eval('1 if //')
|
eval('1 if //')
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue