diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ecd4b3..2c2a493 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## HEAD (unreleased) +## 0.1.4 + +- Parser gem replaced with Ripper (https://github.com/zombocom/syntax_search/pull/17) + ## 0.1.3 - Internal refactor (https://github.com/zombocom/syntax_search/pull/13) diff --git a/Gemfile.lock b/Gemfile.lock index 0a2f29d..f88cb84 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,16 +1,12 @@ PATH remote: . specs: - syntax_search (0.1.3) - parser + syntax_search (0.1.4) GEM remote: https://rubygems.org/ specs: - ast (2.4.1) diff-lcs (1.4.4) - parser (2.7.2.0) - ast (~> 2.4.1) rake (12.3.3) rspec (3.10.0) rspec-core (~> 3.10.0) diff --git a/lib/syntax_search.rb b/lib/syntax_search.rb index f8936c0..ad2cb35 100644 --- a/lib/syntax_search.rb +++ b/lib/syntax_search.rb @@ -2,10 +2,10 @@ require_relative "syntax_search/version" -require 'parser/current' require 'tmpdir' require 'stringio' require 'pathname' +require 'ripper' module SyntaxErrorSearch class Error < StandardError; end @@ -80,6 +80,13 @@ def self.valid_without?(without_lines: , code_lines:) end end + def self.invalid?(source) + source = source.join if source.is_a?(Array) + source = source.to_s + + Ripper.new(source).tap(&:parse).error? + end + # Returns truthy if a given input source is valid syntax # # SyntaxErrorSearch.valid?(<<~EOM) # => true @@ -115,38 +122,12 @@ def self.valid_without?(without_lines: , code_lines:) # so passing a CodeLine in as an object or as an array # will convert it to it's code representation. def self.valid?(source) - source = source.join if source.is_a?(Array) - source = source.to_s - - # Parser writes to stderr even if you catch the error - stderr = $stderr - $stderr = StringIO.new - - Parser::CurrentRuby.parse(source) - true - rescue Parser::SyntaxError => e - yield e if block_given? - false - ensure - $stderr = stderr if stderr + !invalid?(source) end - def self.invalid_type(source) - message = nil - self.valid?(source) do |error| - message = error.message - end - case message - when nil - :none - when /token kEND/ - :unmatched_end - when /token \$end/ # - :missing_end - else - raise "Unexpected message #{message}" - end + def self.invalid_type(source) + WhoDisSyntaxError.new(source).call.error_symbol end end @@ -159,3 +140,4 @@ def self.invalid_type(source) require_relative "syntax_search/parse_blocks_from_indent_line" require_relative "syntax_search/code_search" +require_relative "syntax_search/who_dis_syntax_error" diff --git a/lib/syntax_search/version.rb b/lib/syntax_search/version.rb index 9452849..8c0b38b 100644 --- a/lib/syntax_search/version.rb +++ b/lib/syntax_search/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module SyntaxErrorSearch - VERSION = "0.1.3" + VERSION = "0.1.4" end diff --git a/lib/syntax_search/who_dis_syntax_error.rb b/lib/syntax_search/who_dis_syntax_error.rb new file mode 100644 index 0000000..8a86ab3 --- /dev/null +++ b/lib/syntax_search/who_dis_syntax_error.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module SyntaxErrorSearch + # Determines what type of syntax error is in the source + # + # Example: + # + # puts WhoDisSyntaxError.new("def foo;").call.error_symbol + # # => :missing_end + class WhoDisSyntaxError < Ripper + attr_reader :error, :run_once, :error_symbol + + def call + @run_once ||= begin + parse + true + end + self + end + + def on_parse_error(msg) + @error = msg + if @error.match?(/unexpected end-of-input/) + @error_symbol = :missing_end + elsif @error.match?(/unexpected `end'/) || @error.match?(/expecting end-of-input/) + @error_symbol = :unmatched_end + else + @error_symbol = :nope + end + end + end +end diff --git a/spec/unit/who_dis_syntax_error_spec.rb b/spec/unit/who_dis_syntax_error_spec.rb new file mode 100644 index 0000000..f1791e8 --- /dev/null +++ b/spec/unit/who_dis_syntax_error_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "../spec_helper.rb" + +module SyntaxErrorSearch + RSpec.describe WhoDisSyntaxError do + it "determines the type of syntax error" do + expect( + WhoDisSyntaxError.new("def foo;").call.error_symbol + ).to eq(:missing_end) + + expect( + WhoDisSyntaxError.new("def foo; end; end").call.error_symbol + ).to eq(:unmatched_end) + end + end +end diff --git a/syntax_search.gemspec b/syntax_search.gemspec index cd5d11d..4a705ad 100644 --- a/syntax_search.gemspec +++ b/syntax_search.gemspec @@ -25,6 +25,4 @@ Gem::Specification.new do |spec| spec.bindir = "exe" spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - - spec.add_dependency "parser" end