parser 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.gitignore +2 -0
 - data/.jrubyrc +1 -0
 - data/.yardopts +4 -0
 - data/Gemfile +2 -0
 - data/README.md +3 -1
 - data/doc/AST_FORMAT.md +93 -1
 - data/lib/parser.rb +5 -0
 - data/lib/parser/builders/default.rb +29 -19
 - data/lib/parser/lexer.rl +3 -2
 - data/lib/parser/lexer/explanation.rb +2 -2
 - data/lib/parser/rewriter.rb +34 -0
 - data/lib/parser/runner.rb +4 -5
 - data/lib/parser/runner/ruby_parse.rb +76 -26
 - data/lib/parser/runner/ruby_rewrite.rb +80 -0
 - data/lib/parser/source/map.rb +4 -0
 - data/lib/parser/source/range.rb +23 -4
 - data/lib/parser/source/rewriter.rb +89 -0
 - data/lib/parser/source/rewriter/action.rb +27 -0
 - data/lib/parser/version.rb +1 -1
 - data/parser.gemspec +3 -0
 - data/test/parse_helper.rb +1 -1
 - data/test/test_diagnostic.rb +5 -5
 - data/test/test_parse_helper.rb +9 -9
 - data/test/test_source_range.rb +2 -2
 - data/test/test_source_rewriter.rb +81 -0
 - data/test/test_source_rewriter_action.rb +44 -0
 - metadata +40 -2
 
| 
         @@ -0,0 +1,89 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Parser
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Source
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                class Rewriter
         
     | 
| 
      
 5 
     | 
    
         
            +
                  attr_accessor :diagnostics
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                  def initialize(source_buffer)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @diagnostics = Diagnostic::Engine.new
         
     | 
| 
      
 9 
     | 
    
         
            +
                    @diagnostics.consumer = lambda do |diag|
         
     | 
| 
      
 10 
     | 
    
         
            +
                      $stderr.puts diag.render
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    @source_buffer = source_buffer
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @queue         = []
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @clobber       = 0
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def remove(range)
         
     | 
| 
      
 19 
     | 
    
         
            +
                    append Rewriter::Action.new(range, "")
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def insert_before(range, content)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    append Rewriter::Action.new(range.begin, content)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  def insert_after(range, content)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    append Rewriter::Action.new(range.end, content)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  def replace(range, content)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    append Rewriter::Action.new(range, content)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def process
         
     | 
| 
      
 35 
     | 
    
         
            +
                    adjustment = 0
         
     | 
| 
      
 36 
     | 
    
         
            +
                    source     = @source_buffer.source.dup
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                    @queue.sort_by { |action| action.range.begin_pos }.
         
     | 
| 
      
 39 
     | 
    
         
            +
                           each do |action|
         
     | 
| 
      
 40 
     | 
    
         
            +
                      begin_pos = action.range.begin_pos + adjustment
         
     | 
| 
      
 41 
     | 
    
         
            +
                      end_pos   = begin_pos + action.range.length
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                      source[begin_pos...end_pos] = action.replacement
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                      adjustment += (action.replacement.length - action.range.length)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                    source
         
     | 
| 
      
 49 
     | 
    
         
            +
                  end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                  private
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  def append(action)
         
     | 
| 
      
 54 
     | 
    
         
            +
                    if (clobber_action = clobbered?(action.range))
         
     | 
| 
      
 55 
     | 
    
         
            +
                      # cannot replace 3 characters with "foobar"
         
     | 
| 
      
 56 
     | 
    
         
            +
                      diagnostic = Diagnostic.new(:error,
         
     | 
| 
      
 57 
     | 
    
         
            +
                                                  "cannot #{action}",
         
     | 
| 
      
 58 
     | 
    
         
            +
                                                  action.range)
         
     | 
| 
      
 59 
     | 
    
         
            +
                      @diagnostics.process(diagnostic)
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                      # clobbered by: remove 3 characters
         
     | 
| 
      
 62 
     | 
    
         
            +
                      diagnostic = Diagnostic.new(:note,
         
     | 
| 
      
 63 
     | 
    
         
            +
                                                  "clobbered by: #{clobber_action}",
         
     | 
| 
      
 64 
     | 
    
         
            +
                                                  clobber_action.range)
         
     | 
| 
      
 65 
     | 
    
         
            +
                      @diagnostics.process(diagnostic)
         
     | 
| 
      
 66 
     | 
    
         
            +
                    else
         
     | 
| 
      
 67 
     | 
    
         
            +
                      clobber(action.range)
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                      @queue << action
         
     | 
| 
      
 70 
     | 
    
         
            +
                    end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                    self
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                  def clobber(range)
         
     | 
| 
      
 76 
     | 
    
         
            +
                    @clobber |= (2 ** range.size - 1) << range.begin_pos
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  def clobbered?(range)
         
     | 
| 
      
 80 
     | 
    
         
            +
                    if @clobber & ((2 ** range.size - 1) << range.begin_pos) != 0
         
     | 
| 
      
 81 
     | 
    
         
            +
                      @queue.find do |action|
         
     | 
| 
      
 82 
     | 
    
         
            +
                        action.range.to_a & range.to_a
         
     | 
| 
      
 83 
     | 
    
         
            +
                      end
         
     | 
| 
      
 84 
     | 
    
         
            +
                    end
         
     | 
| 
      
 85 
     | 
    
         
            +
                  end
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Parser
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Source
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                class Rewriter::Action
         
     | 
| 
      
 5 
     | 
    
         
            +
                  attr_reader :range, :replacement
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                  def initialize(range, replacement="")
         
     | 
| 
      
 8 
     | 
    
         
            +
                    @range, @replacement = range, replacement
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                    freeze
         
     | 
| 
      
 11 
     | 
    
         
            +
                  end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                  def to_s
         
     | 
| 
      
 14 
     | 
    
         
            +
                    if @range.length == 0 && @replacement.empty?
         
     | 
| 
      
 15 
     | 
    
         
            +
                      "do nothing"
         
     | 
| 
      
 16 
     | 
    
         
            +
                    elsif @range.length == 0
         
     | 
| 
      
 17 
     | 
    
         
            +
                      "insert #{@replacement.inspect}"
         
     | 
| 
      
 18 
     | 
    
         
            +
                    elsif @replacement.empty?
         
     | 
| 
      
 19 
     | 
    
         
            +
                      "remove #{@range.length} character(s)"
         
     | 
| 
      
 20 
     | 
    
         
            +
                    else
         
     | 
| 
      
 21 
     | 
    
         
            +
                      "replace #{@range.length} character(s) with #{@replacement.inspect}"
         
     | 
| 
      
 22 
     | 
    
         
            +
                    end
         
     | 
| 
      
 23 
     | 
    
         
            +
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/parser/version.rb
    CHANGED
    
    
    
        data/parser.gemspec
    CHANGED
    
    | 
         @@ -35,4 +35,7 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       35 
35 
     | 
    
         
             
              spec.add_development_dependency 'json_pure' # for coveralls on 1.9.2
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
37 
     | 
    
         
             
              spec.add_development_dependency 'simplecov-sublime-ruby-coverage'
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              spec.add_development_dependency 'github-markup'
         
     | 
| 
      
 40 
     | 
    
         
            +
              spec.add_development_dependency 'yard'
         
     | 
| 
       38 
41 
     | 
    
         
             
            end
         
     | 
    
        data/test/parse_helper.rb
    CHANGED
    
    
    
        data/test/test_diagnostic.rb
    CHANGED
    
    | 
         @@ -5,8 +5,8 @@ class TestDiagnostic < MiniTest::Unit::TestCase 
     | 
|
| 
       5 
5 
     | 
    
         
             
                @buffer = Parser::Source::Buffer.new('(string)')
         
     | 
| 
       6 
6 
     | 
    
         
             
                @buffer.source = "if (this is some bad code + bugs)"
         
     | 
| 
       7 
7 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
                @range1 = Parser::Source::Range.new(@buffer, 0,  
     | 
| 
       9 
     | 
    
         
            -
                @range2 = Parser::Source::Range.new(@buffer, 4,  
     | 
| 
      
 8 
     | 
    
         
            +
                @range1 = Parser::Source::Range.new(@buffer, 0, 2) # if
         
     | 
| 
      
 9 
     | 
    
         
            +
                @range2 = Parser::Source::Range.new(@buffer, 4, 8) # this
         
     | 
| 
       10 
10 
     | 
    
         
             
              end
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
              def test_verifies_levels
         
     | 
| 
         @@ -29,11 +29,11 @@ class TestDiagnostic < MiniTest::Unit::TestCase 
     | 
|
| 
       29 
29 
     | 
    
         
             
              end
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
              def test_render
         
     | 
| 
       32 
     | 
    
         
            -
                location = Parser::Source::Range.new(@buffer, 26,  
     | 
| 
      
 32 
     | 
    
         
            +
                location = Parser::Source::Range.new(@buffer, 26, 27)
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
34 
     | 
    
         
             
                highlights = [
         
     | 
| 
       35 
     | 
    
         
            -
                  Parser::Source::Range.new(@buffer, 21,  
     | 
| 
       36 
     | 
    
         
            -
                  Parser::Source::Range.new(@buffer, 28,  
     | 
| 
      
 35 
     | 
    
         
            +
                  Parser::Source::Range.new(@buffer, 21, 25),
         
     | 
| 
      
 36 
     | 
    
         
            +
                  Parser::Source::Range.new(@buffer, 28, 32)
         
     | 
| 
       37 
37 
     | 
    
         
             
                ]
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
39 
     | 
    
         
             
                diag  = Parser::Diagnostic.new(:error, "code far too bad",
         
     | 
    
        data/test/test_parse_helper.rb
    CHANGED
    
    | 
         @@ -25,29 +25,29 @@ class TestParseHelper < MiniTest::Unit::TestCase 
     | 
|
| 
       25 
25 
     | 
    
         
             
              end
         
     | 
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
              def test_parse_mapsation_description
         
     | 
| 
       28 
     | 
    
         
            -
                assert_equal [[0,  
     | 
| 
      
 28 
     | 
    
         
            +
                assert_equal [[0, 4, 'expr', [], '~~~~ expr']],
         
     | 
| 
       29 
29 
     | 
    
         
             
                             parse_maps('~~~~ expr')
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
     | 
    
         
            -
                assert_equal [[0,  
     | 
| 
      
 31 
     | 
    
         
            +
                assert_equal [[0, 4, 'expr', [], '^~~~ expr']],
         
     | 
| 
       32 
32 
     | 
    
         
             
                             parse_maps('^~~~ expr')
         
     | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                assert_equal [[0,  
     | 
| 
      
 34 
     | 
    
         
            +
                assert_equal [[0, 4, 'expr', [], '^^^^ expr']],
         
     | 
| 
       35 
35 
     | 
    
         
             
                             parse_maps('^^^^ expr')
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                assert_equal [[2,  
     | 
| 
      
 37 
     | 
    
         
            +
                assert_equal [[2, 3, 'op', [], '  ^ op']],
         
     | 
| 
       38 
38 
     | 
    
         
             
                             parse_maps('  ^ op')
         
     | 
| 
       39 
39 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                assert_equal [[2,  
     | 
| 
      
 40 
     | 
    
         
            +
                assert_equal [[2, 3, 'op', ['foo'], '  ~ op (foo)']],
         
     | 
| 
       41 
41 
     | 
    
         
             
                             parse_maps('  ~ op (foo)')
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
       43 
     | 
    
         
            -
                assert_equal [[2,  
     | 
| 
      
 43 
     | 
    
         
            +
                assert_equal [[2, 4, 'op', ['foo', 'bar'], '  ~~ op (foo.bar)']],
         
     | 
| 
       44 
44 
     | 
    
         
             
                             parse_maps('  ~~ op (foo.bar)')
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
                assert_equal [[2,  
     | 
| 
      
 46 
     | 
    
         
            +
                assert_equal [[2, 4, 'op', ['foo/2', 'bar'], '  ~~ op (foo/2.bar)']],
         
     | 
| 
       47 
47 
     | 
    
         
             
                             parse_maps('  ~~ op (foo/2.bar)')
         
     | 
| 
       48 
48 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
                assert_equal [[0,  
     | 
| 
       50 
     | 
    
         
            -
                              [5,  
     | 
| 
      
 49 
     | 
    
         
            +
                assert_equal [[0, 4, 'expr', [], '~~~~ expr'],
         
     | 
| 
      
 50 
     | 
    
         
            +
                              [5, 7, 'op', ['str', 'e_h'], '     ~~ op (str.e_h)']],
         
     | 
| 
       51 
51 
     | 
    
         
             
                             parse_maps(%{
         
     | 
| 
       52 
52 
     | 
    
         
             
                                        |~~~~ expr
         
     | 
| 
       53 
53 
     | 
    
         
             
                                        |     ~~ op (str.e_h)
         
     | 
    
        data/test/test_source_range.rb
    CHANGED
    
    | 
         @@ -14,7 +14,7 @@ class TestSourceRange < MiniTest::Unit::TestCase 
     | 
|
| 
       14 
14 
     | 
    
         
             
              end
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
              def test_size
         
     | 
| 
       17 
     | 
    
         
            -
                sr = Parser::Source::Range.new(@sfile, 1,  
     | 
| 
      
 17 
     | 
    
         
            +
                sr = Parser::Source::Range.new(@sfile, 1, 3)
         
     | 
| 
       18 
18 
     | 
    
         
             
                assert_equal 2, sr.size
         
     | 
| 
       19 
19 
     | 
    
         
             
              end
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
         @@ -41,7 +41,7 @@ class TestSourceRange < MiniTest::Unit::TestCase 
     | 
|
| 
       41 
41 
     | 
    
         
             
                sr = Parser::Source::Range.new(@sfile, 7, 8)
         
     | 
| 
       42 
42 
     | 
    
         
             
                assert_equal 0, sr.begin.column
         
     | 
| 
       43 
43 
     | 
    
         
             
                assert_equal 1, sr.end.column
         
     | 
| 
       44 
     | 
    
         
            -
                assert_equal 0 
     | 
| 
      
 44 
     | 
    
         
            +
                assert_equal 0...1, sr.column_range
         
     | 
| 
       45 
45 
     | 
    
         
             
              end
         
     | 
| 
       46 
46 
     | 
    
         | 
| 
       47 
47 
     | 
    
         
             
              def test_begin_end
         
     | 
| 
         @@ -0,0 +1,81 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class TestSourceRewriter < MiniTest::Unit::TestCase
         
     | 
| 
      
 4 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 5 
     | 
    
         
            +
                @buf = Parser::Source::Buffer.new('(rewriter)')
         
     | 
| 
      
 6 
     | 
    
         
            +
                @buf.source = 'foo bar baz'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                @rewriter = Parser::Source::Rewriter.new(@buf)
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              def range(from, len)
         
     | 
| 
      
 12 
     | 
    
         
            +
                Parser::Source::Range.new(@buf, from, from + len)
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def test_remove
         
     | 
| 
      
 16 
     | 
    
         
            +
                assert_equal 'foo  baz',
         
     | 
| 
      
 17 
     | 
    
         
            +
                             @rewriter.
         
     | 
| 
      
 18 
     | 
    
         
            +
                                remove(range(4, 3)).
         
     | 
| 
      
 19 
     | 
    
         
            +
                                process
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def test_insert_before
         
     | 
| 
      
 23 
     | 
    
         
            +
                assert_equal 'foo quux bar baz',
         
     | 
| 
      
 24 
     | 
    
         
            +
                             @rewriter.
         
     | 
| 
      
 25 
     | 
    
         
            +
                                insert_before(range(4, 3), 'quux ').
         
     | 
| 
      
 26 
     | 
    
         
            +
                                process
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              def test_insert_after
         
     | 
| 
      
 30 
     | 
    
         
            +
                assert_equal 'foo bar quux baz',
         
     | 
| 
      
 31 
     | 
    
         
            +
                             @rewriter.
         
     | 
| 
      
 32 
     | 
    
         
            +
                                insert_after(range(4, 3), ' quux').
         
     | 
| 
      
 33 
     | 
    
         
            +
                                process
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def test_replace
         
     | 
| 
      
 37 
     | 
    
         
            +
                assert_equal 'foo quux baz',
         
     | 
| 
      
 38 
     | 
    
         
            +
                             @rewriter.
         
     | 
| 
      
 39 
     | 
    
         
            +
                                replace(range(4, 3), 'quux').
         
     | 
| 
      
 40 
     | 
    
         
            +
                                process
         
     | 
| 
      
 41 
     | 
    
         
            +
              end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              def test_composing_asc
         
     | 
| 
      
 44 
     | 
    
         
            +
                assert_equal 'foo---bar---baz',
         
     | 
| 
      
 45 
     | 
    
         
            +
                             @rewriter.
         
     | 
| 
      
 46 
     | 
    
         
            +
                                replace(range(3, 1), '---').
         
     | 
| 
      
 47 
     | 
    
         
            +
                                replace(range(7, 1), '---').
         
     | 
| 
      
 48 
     | 
    
         
            +
                                process
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              def test_composing_desc
         
     | 
| 
      
 52 
     | 
    
         
            +
                assert_equal 'foo---bar---baz',
         
     | 
| 
      
 53 
     | 
    
         
            +
                             @rewriter.
         
     | 
| 
      
 54 
     | 
    
         
            +
                                replace(range(7, 1), '---').
         
     | 
| 
      
 55 
     | 
    
         
            +
                                replace(range(3, 1), '---').
         
     | 
| 
      
 56 
     | 
    
         
            +
                                process
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              def test_clobber
         
     | 
| 
      
 60 
     | 
    
         
            +
                diagnostics = []
         
     | 
| 
      
 61 
     | 
    
         
            +
                @rewriter.diagnostics.consumer = lambda do |diag|
         
     | 
| 
      
 62 
     | 
    
         
            +
                  diagnostics << diag
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                @rewriter.
         
     | 
| 
      
 66 
     | 
    
         
            +
                  replace(range(3, 1), '---').
         
     | 
| 
      
 67 
     | 
    
         
            +
                  remove(range(3, 1))
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                assert_equal 2, diagnostics.count
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                assert_equal :error, diagnostics.first.level
         
     | 
| 
      
 72 
     | 
    
         
            +
                assert_equal "cannot remove 1 character(s)",
         
     | 
| 
      
 73 
     | 
    
         
            +
                             diagnostics.first.message
         
     | 
| 
      
 74 
     | 
    
         
            +
                assert_equal range(3, 1), diagnostics.first.location
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                assert_equal :note, diagnostics.last.level
         
     | 
| 
      
 77 
     | 
    
         
            +
                assert_equal "clobbered by: replace 1 character(s) with \"---\"",
         
     | 
| 
      
 78 
     | 
    
         
            +
                             diagnostics.last.message
         
     | 
| 
      
 79 
     | 
    
         
            +
                assert_equal range(3, 1), diagnostics.last.location
         
     | 
| 
      
 80 
     | 
    
         
            +
              end
         
     | 
| 
      
 81 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,44 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class TestSourceRewriterAction < MiniTest::Unit::TestCase
         
     | 
| 
      
 4 
     | 
    
         
            +
              def setup
         
     | 
| 
      
 5 
     | 
    
         
            +
                @buf = Parser::Source::Buffer.new('(rewriter_action)')
         
     | 
| 
      
 6 
     | 
    
         
            +
                @buf.source = 'foo bar baz'
         
     | 
| 
      
 7 
     | 
    
         
            +
              end
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def range(from, len)
         
     | 
| 
      
 10 
     | 
    
         
            +
                Parser::Source::Range.new(@buf, from, from + len)
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              def action(range, replacement)
         
     | 
| 
      
 14 
     | 
    
         
            +
                Parser::Source::Rewriter::Action.new(range, replacement)
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              def test_accessors
         
     | 
| 
      
 18 
     | 
    
         
            +
                action = action(range(1, 10), "foo")
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                assert action.frozen?
         
     | 
| 
      
 21 
     | 
    
         
            +
                assert_equal range(1, 10), action.range
         
     | 
| 
      
 22 
     | 
    
         
            +
                assert_equal "foo",        action.replacement
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
              def test_to_s_replace
         
     | 
| 
      
 26 
     | 
    
         
            +
                action = action(range(3, 1), "foo")
         
     | 
| 
      
 27 
     | 
    
         
            +
                assert_equal "replace 1 character(s) with \"foo\"", action.to_s
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              def test_to_s_insert
         
     | 
| 
      
 31 
     | 
    
         
            +
                action = action(range(3, 0), "foo")
         
     | 
| 
      
 32 
     | 
    
         
            +
                assert_equal "insert \"foo\"", action.to_s
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              def test_to_s_remove
         
     | 
| 
      
 36 
     | 
    
         
            +
                action = action(range(3, 2), "")
         
     | 
| 
      
 37 
     | 
    
         
            +
                assert_equal "remove 2 character(s)", action.to_s
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def test_to_s_nop
         
     | 
| 
      
 41 
     | 
    
         
            +
                action = action(range(3, 0), "")
         
     | 
| 
      
 42 
     | 
    
         
            +
                assert_equal "do nothing", action.to_s
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,14 +1,14 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: parser
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 1.3.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Peter Zotov
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire: 
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2013-04- 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2013-04-26 00:00:00.000000000 Z
         
     | 
| 
       12 
12 
     | 
    
         
             
            dependencies:
         
     | 
| 
       13 
13 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       14 
14 
     | 
    
         
             
              name: ast
         
     | 
| 
         @@ -150,6 +150,34 @@ dependencies: 
     | 
|
| 
       150 
150 
     | 
    
         
             
                - - '>='
         
     | 
| 
       151 
151 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       152 
152 
     | 
    
         
             
                    version: '0'
         
     | 
| 
      
 153 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 154 
     | 
    
         
            +
              name: github-markup
         
     | 
| 
      
 155 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 156 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 157 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 158 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 159 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 160 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 161 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 162 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 163 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 164 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 165 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 166 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 167 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 168 
     | 
    
         
            +
              name: yard
         
     | 
| 
      
 169 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 170 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 171 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 172 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 173 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
      
 174 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 175 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 176 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 177 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 178 
     | 
    
         
            +
                - - '>='
         
     | 
| 
      
 179 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 180 
     | 
    
         
            +
                    version: '0'
         
     | 
| 
       153 
181 
     | 
    
         
             
            description: A Ruby parser written in pure Ruby.
         
     | 
| 
       154 
182 
     | 
    
         
             
            email:
         
     | 
| 
       155 
183 
     | 
    
         
             
            - whitequark@whitequark.org
         
     | 
| 
         @@ -160,7 +188,9 @@ extensions: [] 
     | 
|
| 
       160 
188 
     | 
    
         
             
            extra_rdoc_files: []
         
     | 
| 
       161 
189 
     | 
    
         
             
            files:
         
     | 
| 
       162 
190 
     | 
    
         
             
            - .gitignore
         
     | 
| 
      
 191 
     | 
    
         
            +
            - .jrubyrc
         
     | 
| 
       163 
192 
     | 
    
         
             
            - .travis.yml
         
     | 
| 
      
 193 
     | 
    
         
            +
            - .yardopts
         
     | 
| 
       164 
194 
     | 
    
         
             
            - Gemfile
         
     | 
| 
       165 
195 
     | 
    
         
             
            - LICENSE.txt
         
     | 
| 
       166 
196 
     | 
    
         
             
            - README.md
         
     | 
| 
         @@ -185,6 +215,7 @@ files: 
     | 
|
| 
       185 
215 
     | 
    
         
             
            - lib/parser/lexer/explanation.rb
         
     | 
| 
       186 
216 
     | 
    
         
             
            - lib/parser/lexer/literal.rb
         
     | 
| 
       187 
217 
     | 
    
         
             
            - lib/parser/lexer/stack_state.rb
         
     | 
| 
      
 218 
     | 
    
         
            +
            - lib/parser/rewriter.rb
         
     | 
| 
       188 
219 
     | 
    
         
             
            - lib/parser/ruby18.y
         
     | 
| 
       189 
220 
     | 
    
         
             
            - lib/parser/ruby19.y
         
     | 
| 
       190 
221 
     | 
    
         
             
            - lib/parser/ruby20.y
         
     | 
| 
         @@ -207,6 +238,8 @@ files: 
     | 
|
| 
       207 
238 
     | 
    
         
             
            - lib/parser/source/map/ternary.rb
         
     | 
| 
       208 
239 
     | 
    
         
             
            - lib/parser/source/map/variable.rb
         
     | 
| 
       209 
240 
     | 
    
         
             
            - lib/parser/source/range.rb
         
     | 
| 
      
 241 
     | 
    
         
            +
            - lib/parser/source/rewriter.rb
         
     | 
| 
      
 242 
     | 
    
         
            +
            - lib/parser/source/rewriter/action.rb
         
     | 
| 
       210 
243 
     | 
    
         
             
            - lib/parser/static_environment.rb
         
     | 
| 
       211 
244 
     | 
    
         
             
            - lib/parser/syntax_error.rb
         
     | 
| 
       212 
245 
     | 
    
         
             
            - lib/parser/version.rb
         
     | 
| 
         @@ -224,6 +257,8 @@ files: 
     | 
|
| 
       224 
257 
     | 
    
         
             
            - test/test_parser.rb
         
     | 
| 
       225 
258 
     | 
    
         
             
            - test/test_source_buffer.rb
         
     | 
| 
       226 
259 
     | 
    
         
             
            - test/test_source_range.rb
         
     | 
| 
      
 260 
     | 
    
         
            +
            - test/test_source_rewriter.rb
         
     | 
| 
      
 261 
     | 
    
         
            +
            - test/test_source_rewriter_action.rb
         
     | 
| 
       227 
262 
     | 
    
         
             
            - test/test_static_environment.rb
         
     | 
| 
       228 
263 
     | 
    
         
             
            - lib/parser/lexer.rb
         
     | 
| 
       229 
264 
     | 
    
         
             
            - lib/parser/ruby18.rb
         
     | 
| 
         @@ -268,4 +303,7 @@ test_files: 
     | 
|
| 
       268 
303 
     | 
    
         
             
            - test/test_parser.rb
         
     | 
| 
       269 
304 
     | 
    
         
             
            - test/test_source_buffer.rb
         
     | 
| 
       270 
305 
     | 
    
         
             
            - test/test_source_range.rb
         
     | 
| 
      
 306 
     | 
    
         
            +
            - test/test_source_rewriter.rb
         
     | 
| 
      
 307 
     | 
    
         
            +
            - test/test_source_rewriter_action.rb
         
     | 
| 
       271 
308 
     | 
    
         
             
            - test/test_static_environment.rb
         
     | 
| 
      
 309 
     | 
    
         
            +
            has_rdoc: 
         
     |