[前][次][番号順一覧][スレッド一覧]

ruby-changes:13620

From: nobu <ko1@a...>
Date: Tue, 20 Oct 2009 14:51:10 +0900 (JST)
Subject: [ruby-changes:13620] Ruby:r25402 (trunk): * parse.y (parser_here_document): dispatch delayed heredoc

nobu	2009-10-20 14:50:53 +0900 (Tue, 20 Oct 2009)

  New Revision: 25402

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25402

  Log:
    * parse.y (parser_here_document): dispatch delayed heredoc
      contents.  based on a patch from Andy Keep in [ruby-core:24855].

  Modified files:
    trunk/ChangeLog
    trunk/parse.y
    trunk/test/ripper/dummyparser.rb
    trunk/test/ripper/test_parser_events.rb
    trunk/test/ripper/test_scanner_events.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 25401)
+++ ChangeLog	(revision 25402)
@@ -1,3 +1,8 @@
+Tue Oct 20 14:50:51 2009  Nobuyoshi Nakada  <nobu@r...>
+
+	* parse.y (parser_here_document): dispatch delayed heredoc
+	  contents.  based on a patch from Andy Keep in [ruby-core:24855].
+
 Mon Oct 19 15:17:29 2009  Nobuyoshi Nakada  <nobu@r...>
 
 	* .gdbinit (rb_method_entry): search method entry by class and id.
Index: parse.y
===================================================================
--- parse.y	(revision 25401)
+++ parse.y	(revision 25402)
@@ -4726,24 +4726,45 @@
 # define yylval_id() yylval.id
 #endif
 
-#ifdef RIPPER
+#ifndef RIPPER
+#define ripper_flush(p) (void)(p)
+#else
 #define ripper_flush(p) (p->tokp = p->parser_lex_p)
 
 #define yylval_rval *(RB_TYPE_P(yylval.val, T_NODE) ? &yylval.node->nd_rval : &yylval.val)
 
-static void
-ripper_dispatch_scan_event(struct parser_params *parser, int t)
+static int
+ripper_has_scan_event(struct parser_params *parser)
 {
-    VALUE str;
 
     if (lex_p < parser->tokp) rb_raise(rb_eRuntimeError, "lex_p < tokp");
-    if (lex_p == parser->tokp) return;
-    str = STR_NEW(parser->tokp, lex_p - parser->tokp);
-    yylval_rval = ripper_dispatch1(parser, ripper_token2eventid(t), str);
+    return lex_p > parser->tokp;
+}
+
+static VALUE
+ripper_scan_event_val(struct parser_params *parser, int t)
+{
+    VALUE str = STR_NEW(parser->tokp, lex_p - parser->tokp);
+    VALUE rval = ripper_dispatch1(parser, ripper_token2eventid(t), str);
     ripper_flush(parser);
+    return rval;
 }
 
 static void
+ripper_dispatch_scan_event(struct parser_params *parser, int t)
+{
+    if (!ripper_has_scan_event(parser)) return;
+    yylval_rval = ripper_scan_event_val(parser, t);
+}
+
+static void
+ripper_dispatch_ignored_scan_event(struct parser_params *parser, int t)
+{
+    if (!ripper_has_scan_event(parser)) return;
+    (void)ripper_scan_event_val(parser, t);
+}
+
+static void
 ripper_dispatch_delayed_token(struct parser_params *parser, int t)
 {
     int saved_line = ruby_sourceline;
@@ -5227,9 +5248,7 @@
 	    parser->line_count++;
 	    lex_pbeg = lex_p = RSTRING_PTR(v);
 	    lex_pend = lex_p + RSTRING_LEN(v);
-#ifdef RIPPER
 	    ripper_flush(parser);
-#endif
 	    lex_lastline = v;
 	}
     }
@@ -5885,9 +5904,7 @@
 				  len,				/* nd_nth */
 				  lex_lastline);		/* nd_orig */
     nd_set_line(lex_strterm, ruby_sourceline);
-#ifdef RIPPER
     ripper_flush(parser);
-#endif
     return term == '`' ? tXSTRING_BEG : tSTRING_BEG;
 }
 
@@ -5896,12 +5913,6 @@
 {
     VALUE line;
 
-#ifdef RIPPER
-    if (!NIL_P(parser->delayed))
-	ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
-    lex_goto_eol(parser);
-    ripper_dispatch_scan_event(parser, tHEREDOC_END);
-#endif
     line = here->nd_orig;
     lex_lastline = line;
     lex_pbeg = RSTRING_PTR(line);
@@ -5911,9 +5922,7 @@
     ruby_sourceline = nd_line(here);
     dispose_string(here->nd_lit);
     rb_gc_force_recycle((VALUE)here);
-#ifdef RIPPER
     ripper_flush(parser);
-#endif
 }
 
 static int
@@ -5938,6 +5947,7 @@
     const char *eos, *p, *pend;
     long len;
     VALUE str = 0;
+    rb_encoding *enc = parser->enc;
 
     eos = RSTRING_PTR(here->nd_lit);
     len = RSTRING_LEN(here->nd_lit) - 1;
@@ -5946,6 +5956,20 @@
     if ((c = nextc()) == -1) {
       error:
 	compile_error(PARSER_ARG "can't find string \"%s\" anywhere before EOF", eos);
+#ifdef RIPPER
+	if (NIL_P(parser->delayed)) {
+	    ripper_dispatch_scan_event(parser, tSTRING_CONTENT);
+	}
+	else {
+	    if (str ||
+		((len = lex_p - parser->tokp) > 0 &&
+		 (str = STR_NEW3(parser->tokp, len, enc, func), 1))) {
+		rb_str_append(parser->delayed, str);
+	    }
+	    ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
+	}
+	lex_goto_eol(parser);
+#endif
       restore:
 	heredoc_restore(lex_strterm);
 	lex_strterm = 0;
@@ -5985,7 +6009,6 @@
     }
     else {
 	/*	int mb = ENC_CODERANGE_7BIT, *mbp = &mb;*/
-	rb_encoding *enc = parser->enc;
 	newtok();
 	if (c == '#') {
 	    switch (c = nextc()) {
@@ -6014,6 +6037,12 @@
 	} while (!whole_match_p(eos, len, indent));
 	str = STR_NEW3(tok(), toklen(), enc, func);
     }
+#ifdef RIPPER
+    if (!NIL_P(parser->delayed))
+	ripper_dispatch_delayed_token(parser, tSTRING_CONTENT);
+    lex_goto_eol(parser);
+    ripper_dispatch_ignored_scan_event(parser, tHEREDOC_END);
+#endif
     heredoc_restore(lex_strterm);
     lex_strterm = NEW_STRTERM(-1, 0, 0);
     set_yylval_str(str);
Index: test/ripper/test_parser_events.rb
===================================================================
--- test/ripper/test_parser_events.rb	(revision 25401)
+++ test/ripper/test_parser_events.rb	(revision 25402)
@@ -202,6 +202,20 @@
     assert_equal true, thru_bodystmt
   end
 
+  def test_heredoc
+    bug1921 = '[ruby-core:24855]'
+    thru_heredoc_beg = false
+    tree = parse("<<EOS\nheredoc\nEOS\n", :on_heredoc_beg) {thru_heredoc_beg = true}
+    assert_equal true, thru_heredoc_beg
+    assert_match(/string_content\(\),heredoc\n/, tree, bug1921)
+    heredoc = nil
+    parse("<<EOS\nheredoc1\nheredoc2\nEOS\n", :on_string_add) {|n, s| heredoc = s}
+    assert_equal("heredoc1\nheredoc2\n", heredoc, bug1921)
+    heredoc = nil
+    parse("<<-EOS\nheredoc1\nheredoc2\n\tEOS\n", :on_string_add) {|n, s| heredoc = s}
+    assert_equal("heredoc1\nheredoc2\n", heredoc, bug1921)
+  end
+
 =begin
   def test_brace_block
     assert_equal true, $thru__brace_block
Index: test/ripper/dummyparser.rb
===================================================================
--- test/ripper/dummyparser.rb	(revision 25401)
+++ test/ripper/dummyparser.rb	(revision 25402)
@@ -51,7 +51,7 @@
     class << self; self; end.class_eval do
       define_method(name) do |*a, &b|
         result = super(*a, &b)
-        yield
+        yield(*a)
         result
       end
     end
Index: test/ripper/test_scanner_events.rb
===================================================================
--- test/ripper/test_scanner_events.rb	(revision 25401)
+++ test/ripper/test_scanner_events.rb	(revision 25402)
@@ -628,9 +628,9 @@
                  scan('tstring_content', "<<EOS\nheredoc\nEOS")
     assert_equal ["heredoc\n"],
                  scan('tstring_content', "<<EOS\nheredoc\nEOS\n")
-    assert_equal ["heredoc \n"],
-                 scan('tstring_content', "<<EOS\nheredoc \nEOS \n")
-    assert_equal ["heredoc\n"],
+    assert_equal ["here\ndoc \nEOS \n"],
+                 scan('tstring_content', "<<EOS\nhere\ndoc \nEOS \n")
+    assert_equal ["heredoc\n\tEOS \n"],
                  scan('tstring_content', "<<-EOS\nheredoc\n\tEOS \n")
   end
 
@@ -641,9 +641,9 @@
                  scan('heredoc_end', "<<EOS\nheredoc\nEOS")
     assert_equal ["EOS\n"],
                  scan('heredoc_end', "<<EOS\nheredoc\nEOS\n")
-    assert_equal ["EOS \n"],
+    assert_equal [],
                  scan('heredoc_end', "<<EOS\nheredoc\nEOS \n")
-    assert_equal ["\tEOS \n"],
+    assert_equal [],
                  scan('heredoc_end', "<<-EOS\nheredoc\n\tEOS \n")
   end
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]