Skip to content

Commit 3495296

Browse files
committed
[close #16] Replace Parser with Ripper
Ripper is the built in parsing library from Ruby. It is much faster than Parser and it has everything we need. This PR replaces the parser gem with ripper.
1 parent eea6d05 commit 3495296

File tree

7 files changed

+67
-38
lines changed

7 files changed

+67
-38
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## HEAD (unreleased)
22

3+
## 0.1.4
4+
5+
- Parser gem replaced with Ripper (https://github.com/zombocom/syntax_search/pull/17)
6+
37
## 0.1.3
48

59
- Internal refactor (https://github.com/zombocom/syntax_search/pull/13)

Gemfile.lock

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
PATH
22
remote: .
33
specs:
4-
syntax_search (0.1.3)
5-
parser
4+
syntax_search (0.1.4)
65

76
GEM
87
remote: https://rubygems.org/
98
specs:
10-
ast (2.4.1)
119
diff-lcs (1.4.4)
12-
parser (2.7.2.0)
13-
ast (~> 2.4.1)
1410
rake (12.3.3)
1511
rspec (3.10.0)
1612
rspec-core (~> 3.10.0)

lib/syntax_search.rb

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
require_relative "syntax_search/version"
44

5-
require 'parser/current'
65
require 'tmpdir'
76
require 'stringio'
87
require 'pathname'
8+
require 'ripper'
99

1010
module SyntaxErrorSearch
1111
class Error < StandardError; end
@@ -80,6 +80,13 @@ def self.valid_without?(without_lines: , code_lines:)
8080
end
8181
end
8282

83+
def self.invalid?(source)
84+
source = source.join if source.is_a?(Array)
85+
source = source.to_s
86+
87+
Ripper.new(source).tap(&:parse).error?
88+
end
89+
8390
# Returns truthy if a given input source is valid syntax
8491
#
8592
# SyntaxErrorSearch.valid?(<<~EOM) # => true
@@ -115,38 +122,12 @@ def self.valid_without?(without_lines: , code_lines:)
115122
# so passing a CodeLine in as an object or as an array
116123
# will convert it to it's code representation.
117124
def self.valid?(source)
118-
source = source.join if source.is_a?(Array)
119-
source = source.to_s
120-
121-
# Parser writes to stderr even if you catch the error
122-
stderr = $stderr
123-
$stderr = StringIO.new
124-
125-
Parser::CurrentRuby.parse(source)
126-
true
127-
rescue Parser::SyntaxError => e
128-
yield e if block_given?
129-
false
130-
ensure
131-
$stderr = stderr if stderr
125+
!invalid?(source)
132126
end
133127

134-
def self.invalid_type(source)
135-
message = nil
136-
self.valid?(source) do |error|
137-
message = error.message
138-
end
139128

140-
case message
141-
when nil
142-
:none
143-
when /token kEND/
144-
:unmatched_end
145-
when /token \$end/ #
146-
:missing_end
147-
else
148-
raise "Unexpected message #{message}"
149-
end
129+
def self.invalid_type(source)
130+
WhoDisSyntaxError.new(source).call.error_symbol
150131
end
151132
end
152133

@@ -159,3 +140,4 @@ def self.invalid_type(source)
159140
require_relative "syntax_search/parse_blocks_from_indent_line"
160141

161142
require_relative "syntax_search/code_search"
143+
require_relative "syntax_search/who_dis_syntax_error"

lib/syntax_search/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module SyntaxErrorSearch
4-
VERSION = "0.1.3"
4+
VERSION = "0.1.4"
55
end
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# frozen_string_literal: true
2+
3+
module SyntaxErrorSearch
4+
# Determines what type of syntax error is in the source
5+
#
6+
# Example:
7+
#
8+
# puts WhoDisSyntaxError.new("def foo;").call.error_symbol
9+
# # => :missing_end
10+
class WhoDisSyntaxError < Ripper
11+
attr_reader :error, :run_once, :error_symbol
12+
13+
def call
14+
@run_once ||= begin
15+
parse
16+
true
17+
end
18+
self
19+
end
20+
21+
def on_parse_error(msg)
22+
@error = msg
23+
if @error.match?(/unexpected end-of-input/)
24+
@error_symbol = :missing_end
25+
elsif @error.match?(/unexpected `end'/) || @error.match?(/expecting end-of-input/)
26+
@error_symbol = :unmatched_end
27+
else
28+
@error_symbol = :nope
29+
end
30+
end
31+
end
32+
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "../spec_helper.rb"
4+
5+
module SyntaxErrorSearch
6+
RSpec.describe WhoDisSyntaxError do
7+
it "determines the type of syntax error" do
8+
expect(
9+
WhoDisSyntaxError.new("def foo;").call.error_symbol
10+
).to eq(:missing_end)
11+
12+
expect(
13+
WhoDisSyntaxError.new("def foo; end; end").call.error_symbol
14+
).to eq(:unmatched_end)
15+
end
16+
end
17+
end

syntax_search.gemspec

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,4 @@ Gem::Specification.new do |spec|
2525
spec.bindir = "exe"
2626
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
2727
spec.require_paths = ["lib"]
28-
29-
spec.add_dependency "parser"
3028
end

0 commit comments

Comments
 (0)