зеркало из https://github.com/github/ruby.git
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:
Родитель
91a0d1c437
Коммит
7a050638b1
2
ast.c
2
ast.c
|
@ -694,6 +694,8 @@ node_children(rb_ast_t *ast, const NODE *node)
|
|||
}
|
||||
case NODE_LINE:
|
||||
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:
|
||||
return rb_ary_new_from_node_args(ast, 0);
|
||||
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/hash.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/static_assert.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 *
|
||||
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
|
||||
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;
|
||||
switch (nd_type(node)) {
|
||||
case NODE_STR: case NODE_DSTR:
|
||||
case NODE_STR: case NODE_DSTR: case NODE_FILE:
|
||||
return TRUE;
|
||||
case NODE_IF: case NODE_UNLESS:
|
||||
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;
|
||||
case NODE_LIT: /* NODE_LIT is always true */
|
||||
case NODE_LINE:
|
||||
case NODE_FILE:
|
||||
case NODE_TRUE:
|
||||
case NODE_STR:
|
||||
case NODE_ZLIST:
|
||||
|
@ -4658,6 +4671,7 @@ static_literal_node_p(const NODE *node, const rb_iseq_t *iseq)
|
|||
case NODE_FALSE:
|
||||
return TRUE;
|
||||
case NODE_STR:
|
||||
case NODE_FILE:
|
||||
return ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal;
|
||||
default:
|
||||
return FALSE;
|
||||
|
@ -4676,16 +4690,17 @@ static_literal_value(const NODE *node, rb_iseq_t *iseq)
|
|||
return Qfalse;
|
||||
case NODE_LINE:
|
||||
return rb_node_line_lineno_val(node);
|
||||
case NODE_FILE:
|
||||
case NODE_STR:
|
||||
if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) {
|
||||
VALUE lit;
|
||||
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));
|
||||
return rb_str_freeze(lit);
|
||||
}
|
||||
else {
|
||||
return rb_fstring(RNODE_STR(node)->nd_lit);
|
||||
return rb_fstring(get_string_value(node));
|
||||
}
|
||||
case NODE_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);
|
||||
case NODE_STR:
|
||||
return rb_fstring(RNODE_STR(node)->nd_lit);
|
||||
case NODE_FILE:
|
||||
return rb_fstring(rb_node_file_path_val(node));
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
if (nd_type_p(val, NODE_STR)) {
|
||||
debugp_param("nd_lit", RNODE_STR(val)->nd_lit);
|
||||
lit = rb_fstring(RNODE_STR(val)->nd_lit);
|
||||
if (nd_type_p(val, NODE_STR) || nd_type_p(val, NODE_FILE)) {
|
||||
debugp_param("nd_lit", get_string_value(val));
|
||||
lit = rb_fstring(get_string_value(val));
|
||||
ADD_INSN1(cond_seq, val, putobject, 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_LIT:
|
||||
case NODE_LINE:
|
||||
case NODE_FILE:
|
||||
case NODE_ZLIST:
|
||||
case NODE_AND:
|
||||
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_LINE:
|
||||
case NODE_FILE:
|
||||
case NODE_STR:
|
||||
case NODE_XSTR:
|
||||
case NODE_DSTR:
|
||||
|
@ -8321,12 +8340,13 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE
|
|||
/* optimization shortcut
|
||||
* "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_nd_args(node) == NULL &&
|
||||
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
|
||||
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) {
|
||||
ADD_INSN2(ret, line_node, opt_str_uminus, str,
|
||||
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) &&
|
||||
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)->option->frozen_string_literal &&
|
||||
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)));
|
||||
ADD_INSN2(ret, line_node, opt_aref_with, str,
|
||||
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 &&
|
||||
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)->option->frozen_string_literal &&
|
||||
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, "value", RNODE_LIST(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_next)->nd_head));
|
||||
if (!popped) {
|
||||
|
@ -10134,10 +10154,11 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
|
|||
}
|
||||
break;
|
||||
}
|
||||
case NODE_FILE:
|
||||
case NODE_STR:{
|
||||
debugp_param("nd_lit", RNODE_STR(node)->nd_lit);
|
||||
debugp_param("nd_lit", get_string_value(node));
|
||||
if (!popped) {
|
||||
VALUE lit = RNODE_STR(node)->nd_lit;
|
||||
VALUE lit = get_string_value(node);
|
||||
if (!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) {
|
||||
lit = rb_fstring(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_file_path_val(const NODE *);
|
||||
#endif /* INTERNAL_RUBY_PARSE_H */
|
||||
|
|
|
@ -457,6 +457,8 @@ class RbInspector(LLDBInterface):
|
|||
self._append_expression("*(struct RNode_ERROR *) %0#x" % val.GetValueAsUnsigned())
|
||||
elif nd_type == self.ruby_globals["NODE_LINE"]:
|
||||
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"]:
|
||||
self._append_expression("*(struct RNode_RIPPER *) %0#x" % val.GetValueAsUnsigned())
|
||||
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
|
||||
free_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
|
||||
{
|
||||
switch (nd_type(node)) {
|
||||
case NODE_FILE:
|
||||
parser_string_free(ast, RNODE_FILE(node)->path);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "internal.h"
|
||||
#include "internal/hash.h"
|
||||
#include "internal/ruby_parser.h"
|
||||
#include "internal/variable.h"
|
||||
#include "ruby/ruby.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_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_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_NODE(name, type, ann) \
|
||||
|
@ -1105,6 +1107,13 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
|
|||
ANN("example: __LINE__");
|
||||
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:
|
||||
ANN("Broken input recovered by Error Tolerant mode");
|
||||
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_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_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);
|
||||
|
||||
#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_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_FILE(str,loc) (NODE *)rb_node_file_new(p,str,loc)
|
||||
#define NEW_ERROR(loc) (NODE *)rb_node_error_new(p,loc)
|
||||
|
||||
#endif
|
||||
|
@ -1911,6 +1913,56 @@ get_nd_args(struct parser_params *p, NODE *node)
|
|||
}
|
||||
}
|
||||
#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
|
||||
|
@ -6599,6 +6651,7 @@ singleton : var_ref
|
|||
case NODE_DREGX:
|
||||
case NODE_LIT:
|
||||
case NODE_LINE:
|
||||
case NODE_FILE:
|
||||
case NODE_DSYM:
|
||||
case NODE_LIST:
|
||||
case NODE_ZLIST:
|
||||
|
@ -12186,6 +12239,15 @@ rb_node_line_new(struct parser_params *p, const YYLTYPE *loc)
|
|||
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 *
|
||||
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;
|
||||
if (NIL_P(file))
|
||||
file = rb_str_new(0, 0);
|
||||
else
|
||||
file = rb_str_dup(file);
|
||||
node = NEW_STR(file, loc);
|
||||
RB_OBJ_WRITTEN(p->ast, Qnil, file);
|
||||
node = NEW_FILE(file, loc);
|
||||
}
|
||||
return node;
|
||||
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);
|
||||
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:
|
||||
lit = rb_ary_new();
|
||||
OBJ_FREEZE_RAW(lit);
|
||||
|
@ -13985,6 +14050,7 @@ void_expr(struct parser_params *p, NODE *node)
|
|||
break;
|
||||
case NODE_LIT:
|
||||
case NODE_LINE:
|
||||
case NODE_FILE:
|
||||
case NODE_STR:
|
||||
case NODE_DSTR:
|
||||
case NODE_DREGX:
|
||||
|
@ -14123,6 +14189,7 @@ is_static_content(NODE *node)
|
|||
} while ((node = RNODE_LIST(node)->nd_next) != 0);
|
||||
case NODE_LIT:
|
||||
case NODE_LINE:
|
||||
case NODE_FILE:
|
||||
case NODE_STR:
|
||||
case NODE_NIL:
|
||||
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_EVSTR:
|
||||
case NODE_STR:
|
||||
case NODE_FILE:
|
||||
SWITCH_BY_COND_TYPE(type, warn, "string ");
|
||||
break;
|
||||
|
||||
|
|
|
@ -4,12 +4,6 @@
|
|||
|
||||
#include "rubyparser.h"
|
||||
|
||||
VALUE
|
||||
rb_node_line_lineno_val(const NODE *node)
|
||||
{
|
||||
return INT2FIX(node->nd_loc.beg_pos.lineno);
|
||||
}
|
||||
|
||||
#ifdef UNIVERSAL_PARSER
|
||||
|
||||
#include "internal.h"
|
||||
|
@ -920,3 +914,16 @@ rb_parser_set_yydebug(VALUE vparser, VALUE flag)
|
|||
return flag;
|
||||
}
|
||||
#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
|
||||
|
||||
#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
|
||||
*/
|
||||
|
@ -131,23 +154,12 @@ enum node_type {
|
|||
NODE_FNDPTN,
|
||||
NODE_ERROR,
|
||||
NODE_LINE,
|
||||
NODE_FILE,
|
||||
NODE_RIPPER,
|
||||
NODE_RIPPER_VALUES,
|
||||
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 {
|
||||
int size;
|
||||
ID ids[FLEX_ARY_LEN];
|
||||
|
@ -936,6 +948,12 @@ typedef struct RNode_LINE {
|
|||
NODE node;
|
||||
} rb_node_line_t;
|
||||
|
||||
typedef struct RNode_FILE {
|
||||
NODE node;
|
||||
|
||||
struct rb_parser_string *path;
|
||||
} rb_node_file_t;
|
||||
|
||||
typedef struct RNode_ERROR {
|
||||
NODE node;
|
||||
} rb_node_error_t;
|
||||
|
@ -1046,6 +1064,7 @@ typedef struct RNode_ERROR {
|
|||
#define RNODE_HSHPTN(node) ((struct RNode_HSHPTN *)(node))
|
||||
#define RNODE_FNDPTN(node) ((struct RNode_FNDPTN *)(node))
|
||||
#define RNODE_LINE(node) ((struct RNode_LINE *)(node))
|
||||
#define RNODE_FILE(node) ((struct RNode_FILE *)(node))
|
||||
|
||||
#ifdef 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_new(rb_parser_config_t *config);
|
||||
#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
|
||||
|
||||
#endif /* RUBY_RUBYPARSER_H */
|
||||
|
|
|
@ -582,8 +582,10 @@ class TestRubyOptions < Test::Unit::TestCase
|
|||
t.rewind
|
||||
t.truncate(0)
|
||||
t.puts "if a = __LINE__; end"
|
||||
t.puts "if a = __FILE__; end"
|
||||
t.flush
|
||||
err = ["#{t.path}:1:#{warning}",
|
||||
"#{t.path}:2:#{warning}",
|
||||
]
|
||||
assert_in_out_err(["-w", t.path], "", [], err)
|
||||
assert_in_out_err(["-wr", t.path, "-e", ""], "", [], err)
|
||||
|
|
|
@ -1210,6 +1210,9 @@ eom
|
|||
assert_warn(/string literal in condition/) do
|
||||
eval('1 if ""')
|
||||
end
|
||||
assert_warning(/string literal in condition/) do
|
||||
eval('1 if __FILE__')
|
||||
end
|
||||
assert_warn(/regex literal in condition/) do
|
||||
eval('1 if //')
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче