Skip to content

Commit

Permalink
Support lexing with Prism
Browse files Browse the repository at this point in the history
  • Loading branch information
schneems committed Dec 4, 2023
1 parent a7d6991 commit 7f4176a
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 19 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,22 @@ jobs:
- name: test
run: bin/rake test
continue-on-error: ${{ matrix.ruby == 'head' }}

test-disable-prism:
needs: ruby-versions
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
steps:
- name: Checkout code
uses: actions/checkout@v4.1.1
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
- name: test
run: SYNTAX_SUGGEST_DISABLE_PRISM=1 bin/rake test
continue-on-error: ${{ matrix.ruby == 'head' }}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## HEAD (unreleased)

- Support prism parser (https://github.com/ruby/syntax_suggest/pull/208).
- No longer supports EOL versions of Ruby. (https://github.com/ruby/syntax_suggest/pull/210)
- Handle Ruby 3.3 new eval source location format (https://github.com/ruby/syntax_suggest/pull/200).

Expand Down
24 changes: 14 additions & 10 deletions lib/syntax_suggest/api.rb
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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/unit/api_spec.rb
Original file line number Diff line number Diff line change
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 7f4176a

Please sign in to comment.