Skip to content

[close #16] Replace Parser with Ripper #17

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
6 changes: 1 addition & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
42 changes: 12 additions & 30 deletions lib/syntax_search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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"
2 changes: 1 addition & 1 deletion lib/syntax_search/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module SyntaxErrorSearch
VERSION = "0.1.3"
VERSION = "0.1.4"
end
32 changes: 32 additions & 0 deletions lib/syntax_search/who_dis_syntax_error.rb
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions spec/unit/who_dis_syntax_error_spec.rb
Original file line number Diff line number Diff line change
@@ -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
2 changes: 0 additions & 2 deletions syntax_search.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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