[macruby-changes] [4626] DietRB/trunk

source_changes at macosforge.org source_changes at macosforge.org
Fri Oct 8 03:50:35 PDT 2010


Revision: 4626
          http://trac.macosforge.org/projects/ruby/changeset/4626
Author:   eloy.de.enige at gmail.com
Date:     2010-10-08 03:50:33 -0700 (Fri, 08 Oct 2010)
Log Message:
-----------
If a syntax error occurs, only reset the buffer to the previous line. This way you don't loose all previous lines as IRB does.

From: Eloy Duran <eloy.de.enige at gmail.com>

Modified Paths:
--------------
    DietRB/trunk/lib/irb/context.rb
    DietRB/trunk/lib/irb/source.rb
    DietRB/trunk/spec/context_spec.rb
    DietRB/trunk/spec/source_spec.rb

Modified: DietRB/trunk/lib/irb/context.rb
===================================================================
--- DietRB/trunk/lib/irb/context.rb	2010-10-08 10:50:23 UTC (rev 4625)
+++ DietRB/trunk/lib/irb/context.rb	2010-10-08 10:50:33 UTC (rev 4626)
@@ -59,7 +59,10 @@
       @source << line
       return false if @source.to_s == "quit"
       
-      if @source.valid?
+      if @source.syntax_error?
+        puts format_syntax_error(@source.syntax_error)
+        @source.pop
+      elsif @source.code_block?
         evaluate(@source)
         clear_buffer
       end
@@ -82,6 +85,10 @@
       "#{e.class.name}: #{e.message}\n\t#{e.backtrace.join("\n\t")}"
     end
     
+    def format_syntax_error(e)
+      "SyntaxError: compile error\n(irb):#{@line}: #{e}"
+    end
+    
     private
     
     def clear_buffer

Modified: DietRB/trunk/lib/irb/source.rb
===================================================================
--- DietRB/trunk/lib/irb/source.rb	2010-10-08 10:50:23 UTC (rev 4625)
+++ DietRB/trunk/lib/irb/source.rb	2010-10-08 10:50:33 UTC (rev 4626)
@@ -14,6 +14,12 @@
       @buffer << source.chomp
     end
     
+    # Removes the last line from the buffer and flushes the cached reflection.
+    def pop
+      @reflection = nil
+      @buffer.pop
+    end
+    
     # Returns the accumulated source as a string, joined by newlines.
     def source
       @buffer.join("\n")
@@ -28,10 +34,21 @@
     end
     
     # Reflects on the accumulated source to see if it's a valid code block.
-    def valid?
+    def code_block?
       reflect.code_block?
     end
     
+    # Reflects on the accumulated source to see if it contains a syntax error.
+    def syntax_error?
+      reflect.syntax_error?
+    end
+    
+    # Reflects on the accumulated source and returns the actual syntax error
+    # message if one occurs.
+    def syntax_error
+      reflect.syntax_error
+    end
+    
     # Returns a Reflector for the accumulated source and caches it.
     def reflect
       @reflection ||= Reflector.new(source)
@@ -41,7 +58,6 @@
       def initialize(source)
         super
         @level = 0
-        @syntax_error = false
         parse
       end
       
@@ -54,6 +70,9 @@
       #   Reflector.new("class Foo; def foo; end; end").level # => 0
       attr_reader :level
       
+      # Returns the actual syntax error message if one occurs.
+      attr_reader :syntax_error
+      
       # Returns whether or not the source is a valid code block, but does not
       # take syntax errors into account. In short, it's a valid code block if
       # after parsing the level is at zero.
@@ -80,14 +99,14 @@
       #
       #   def foo
       def syntax_error?
-        @syntax_error
+        !@syntax_error.nil?
       end
       
       UNEXPECTED_END = "syntax error, unexpected $end"
       
       def on_parse_error(error) #:nodoc:
         if code_block? || !error.start_with?(UNEXPECTED_END)
-          @syntax_error = true
+          @syntax_error = error
         end
       end
       

Modified: DietRB/trunk/spec/context_spec.rb
===================================================================
--- DietRB/trunk/spec/context_spec.rb	2010-10-08 10:50:23 UTC (rev 4625)
+++ DietRB/trunk/spec/context_spec.rb	2010-10-08 10:50:33 UTC (rev 4626)
@@ -155,6 +155,17 @@
     source.to_s.should == "def foo\n:ok\nend; p foo"
   end
   
+  it "prints that a syntax error occurred on the last line and reset the buffer to the previous line" do
+    def @context.puts(str); @printed = str; end
+    
+    @context.process_line("def foo")
+    @context.process_line("  };")
+    
+    @context.source.to_s.should == "def foo"
+    printed = @context.instance_variable_get(:@printed)
+    printed.should == "SyntaxError: compile error\n(irb):2: syntax error, unexpected '}'"
+  end
+  
   it "returns whether or not the runloop should continue, but only if the level is 0" do
     @context.process_line("def foo").should == true
     @context.process_line("quit").should == true

Modified: DietRB/trunk/spec/source_spec.rb
===================================================================
--- DietRB/trunk/spec/source_spec.rb	2010-10-08 10:50:23 UTC (rev 4625)
+++ DietRB/trunk/spec/source_spec.rb	2010-10-08 10:50:33 UTC (rev 4626)
@@ -1,5 +1,9 @@
 require File.expand_path('../spec_helper', __FILE__)
 
+class Should
+  alias have be
+end
+
 describe "IRB::Source" do
   before do
     @source = IRB::Source.new
@@ -15,6 +19,13 @@
     @source.buffer.should == %w{ foo bar }
   end
   
+  it "removes the last line from the buffer" do
+    @source << "foo\n"
+    @source << "bar\r\n"
+    @source.pop.should == "bar"
+    @source.buffer.should == %w{ foo }
+  end
+  
   it "returns the full buffered source, joined by newlines" do
     @source.source.should == ""
     @source << "foo\n"
@@ -34,7 +45,7 @@
       ["def foo", "p :ok", "end"],
       ["class A; def", "foo(x); p x", "end; end"]
     ].each do |buffer|
-      IRB::Source.new(buffer).should.be.valid
+      IRB::Source.new(buffer).should.be.code_block
     end
   end
   
@@ -43,10 +54,18 @@
       ["def foo", "p :ok"],
       ["class A; def", "foo(x); p x", "end"]
     ].each do |buffer|
-      IRB::Source.new(buffer).should.not.be.valid
+      IRB::Source.new(buffer).should.not.be.code_block
     end
   end
   
+  it "returns whether or not the accumulated source contains a syntax error" do
+    @source.should.not.have.syntax_error
+    @source << "def foo"
+    @source.should.not.have.syntax_error
+    @source << "  def;"
+    @source.should.have.syntax_error
+  end
+  
   it "returns the current code block indentation level" do
     @source.level.should == 0
     @source << "class A"
@@ -71,22 +90,27 @@
     @source << "def foo"
     reflection = @source.reflect
     @source.level
-    @source.valid?
+    @source.code_block?
     @source.reflect.should == reflection
     
     @source << "end"
     @source.level
     new_reflection = @source.reflect
     new_reflection.should.not == reflection
-    @source.valid?
+    @source.code_block?
     @source.reflect.should == new_reflection
+    
+    reflection = new_reflection
+    
+    @source.pop
+    @source.level
+    new_reflection = @source.reflect
+    new_reflection.should.not == reflection
+    @source.syntax_error?
+    @source.reflect.should == new_reflection
   end
 end
 
-class Should
-  alias have be
-end
-
 describe "IRB::Source::Reflector" do
   def reflect(source)
     IRB::Source::Reflector.new(source)
@@ -108,6 +132,11 @@
     reflect("class A; def foo" ).should.not.have.syntax_error
   end
   
+  it "returns the actual syntax error message if one occurs" do
+    reflect("def foo").syntax_error.should == nil
+    reflect("}").syntax_error.should == "syntax error, unexpected '}'"
+  end
+  
   it "returns the code block indentation level" do
     reflect("").level.should == 0
     reflect("class A").level.should == 1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20101008/afb4b6f7/attachment-0001.html>


More information about the macruby-changes mailing list