Skip to content

Commit

Permalink
[ruby/syntax_suggest] Support lexing with Prism
Browse files Browse the repository at this point in the history
  • Loading branch information
schneems authored and matzbot committed Dec 5, 2023
1 parent cce2975 commit 62c9695
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 19 deletions.
24 changes: 14 additions & 10 deletions lib/syntax_suggest/api.rb
Expand Up @@ -5,23 +5,27 @@
require "tmpdir"
require "stringio"
require "pathname"
require "timeout"

# rubocop:disable Style/IdenticalConditionalBranches
if ENV["SYNTAX_SUGGEST_DISABLE_PRISM"] # For testing dual ripper/prism support
require "ripper"
# We need Ripper loaded for `Prism.lex_compat` even if we're using Prism
# for lexing and parsing
require "ripper"

# Prism is the new parser, replacing Ripper
#
# We need to "dual boot" both for now because syntax_suggest
# supports older rubies that do not ship with syntax suggest.
#
# We also need the ability to control loading of this library
# so we can test that both modes work correctly in CI.
if (value = ENV["SYNTAX_SUGGEST_DISABLE_PRISM"])
warn "Skipping loading prism due to SYNTAX_SUGGEST_DISABLE_PRISM=#{value}"
else
# TODO remove require
# Allow both to be loaded to enable more atomic commits
require "ripper"
begin
require "prism"
rescue LoadError
require "ripper"
end
end
# rubocop:enable Style/IdenticalConditionalBranches

require "timeout"

module SyntaxSuggest
# Used to indicate a default value that cannot
Expand Down
17 changes: 12 additions & 5 deletions lib/syntax_suggest/code_line.rb
Expand Up @@ -180,12 +180,19 @@ def ignore_newline_not_beg?
# EOM
# expect(lines.first.trailing_slash?).to eq(true)
#
def trailing_slash?
last = @lex.last
return false unless last
return false unless last.type == :on_sp
if SyntaxSuggest.use_prism_parser?
def trailing_slash?
last = @lex.last
last&.type == :on_tstring_end
end
else
def trailing_slash?
last = @lex.last
return false unless last
return false unless last.type == :on_sp

last.token == TRAILING_SLASH
last.token == TRAILING_SLASH
end
end

# Endless method detection
Expand Down
5 changes: 1 addition & 4 deletions lib/syntax_suggest/lex_all.rb
Expand Up @@ -32,18 +32,15 @@ def initialize(source:, source_lines: nil)
}
end

# rubocop:disable Style/IdenticalConditionalBranches
if SyntaxSuggest.use_prism_parser?
def self.lex(source, line_number)
# Prism.lex_compat(source, line: line_number).value.sort_by {|values| values[0] }
Ripper::Lexer.new(source, "-", line_number).parse.sort_by(&:pos)
Prism.lex_compat(source, line: line_number).value.sort_by { |values| values[0] }
end
else
def self.lex(source, line_number)
Ripper::Lexer.new(source, "-", line_number).parse.sort_by(&:pos)
end
end
# rubocop:enable Style/IdenticalConditionalBranches

def to_a
@lex
Expand Down
6 changes: 6 additions & 0 deletions spec/syntax_suggest/unit/api_spec.rb
Expand Up @@ -8,6 +8,12 @@

module SyntaxSuggest
RSpec.describe "Top level SyntaxSuggest api" do
it "doesn't load prism if env var is set" do
skip("SYNTAX_SUGGEST_DISABLE_PRISM not set") unless ENV["SYNTAX_SUGGEST_DISABLE_PRISM"]

expect(SyntaxSuggest.use_prism_parser?).to be_falsey
end

it "has a `handle_error` interface" do
fake_error = Object.new
def fake_error.message
Expand Down

0 comments on commit 62c9695

Please sign in to comment.