summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryui-knk <spiketeika@gmail.com>2023-12-29 22:34:35 +0900
committerYuichiro Kaneko <spiketeika@gmail.com>2024-01-02 14:19:42 +0900
commit7a050638b19cf6996c498e0c5909c293008cc58a (patch)
tree00b12eeba0c2230618c9ae46ba3f393d064a42b0
parent91a0d1c4377bed985db58901065428bcb4bb691f (diff)
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
-rw-r--r--ast.c2
-rw-r--r--common.mk1
-rw-r--r--compile.c51
-rw-r--r--internal/ruby_parser.h1
-rw-r--r--misc/lldb_rb/utils.py2
-rw-r--r--node.c9
-rw-r--r--node_dump.c9
-rw-r--r--parse.y76
-rw-r--r--ruby_parser.c19
-rw-r--r--rubyparser.h47
-rw-r--r--test/ruby/test_rubyoptions.rb2
-rw-r--r--test/ruby/test_syntax.rb3
12 files changed, 185 insertions, 37 deletions
diff --git a/ast.c b/ast.c
index 33b2f61aa2..6c3b2bf04c 100644
--- a/ast.c
+++ b/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:
diff --git a/common.mk b/common.mk
index 0988d6dde9..f916c1dda7 100644
--- a/common.mk
+++ b/common.mk
@@ -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
diff --git a/compile.c b/compile.c
index e556c6181d..39239934c5 100644
--- a/compile.c
+++ b/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);
diff --git a/internal/ruby_parser.h b/internal/ruby_parser.h
index 177ede3695..2c2134024b 100644
--- a/internal/ruby_parser.h
+++ b/internal/ruby_parser.h
@@ -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 */
diff --git a/misc/lldb_rb/utils.py b/misc/lldb_rb/utils.py
index afbba15390..ad8ca07040 100644
--- a/misc/lldb_rb/utils.py
+++ b/misc/lldb_rb/utils.py
@@ -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"]:
diff --git a/node.c b/node.c
index 1f10258343..6798701a7a 100644
--- a/node.c
+++ b/node.c
@@ -170,9 +170,18 @@ 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;
}
diff --git a/node_dump.c b/node_dump.c
index 2a8a3f9113..c42a02e3b3 100644
--- a/node_dump.c
+++ b/node_dump.c
@@ -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;
diff --git a/parse.y b/parse.y
index 9791d155af..7e714ccb2c 100644
--- a/parse.y
+++ b/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;
diff --git a/ruby_parser.c b/ruby_parser.c
index 7d52813f26..94209b9aba 100644
--- a/ruby_parser.c
+++ b/ruby_parser.c
@@ -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);
+}
diff --git a/rubyparser.h b/rubyparser.h
index f61fe4603c..b7608285bb 100644
--- a/rubyparser.h
+++ b/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 */
diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index 99af480f35..6298c829e3 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -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)
diff --git a/test/ruby/test_syntax.rb b/test/ruby/test_syntax.rb
index 5e277c8d8e..bd350ba223 100644
--- a/test/ruby/test_syntax.rb
+++ b/test/ruby/test_syntax.rb
@@ -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