Skip to content
Closed
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
36 changes: 36 additions & 0 deletions benchmark/benchmark_prototype_rb.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

require "benchmark/ips"
require_relative "../lib/rbs"

# Collect Ruby source files to parse
sources = Dir.glob(File.join(__dir__, "../lib/**/*.rb")).map do |path|
[path, File.read(path)]
end

puts "Benchmarking prototype generation (#{sources.size} files, #{sources.sum { |_, s| s.size }} bytes total)"
puts

Benchmark.ips do |x|
x.report("RB: RubyVM::AbstractSyntaxTree") do
ENV.delete("RBS_RUBY_PARSER")
sources.each do |_path, source|
parser = RBS::Prototype::RB.new
parser.parse(source)
parser.decls
end
end

x.report("RB: Prism") do
ENV["RBS_RUBY_PARSER"] = "prism"
sources.each do |_path, source|
parser = RBS::Prototype::RB.new
parser.parse(source)
parser.decls
end
end

x.compare!
ensure
ENV.delete("RBS_RUBY_PARSER")
end
9 changes: 7 additions & 2 deletions lib/rbs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,16 @@
require "rbs/resolver/type_name_resolver"
require "rbs/ast/comment"
require "rbs/writer"
require "rbs/prototype/helpers"
require "rbs/prototype/comment_parser"
require "rbs/prototype/ruby_vm_helpers"
require "rbs/prototype/node_usage"
require "rbs/prototype/rbi"
require "rbs/prototype/rbi/ruby_vm"
require "rbs/prototype/rbi/prism"
require "rbs/prototype/rb"
require "rbs/prototype/rb/ruby_vm"
require "rbs/prototype/rb/prism"
require "rbs/prototype/runtime"
require "rbs/prototype/node_usage"
require "rbs/environment_walker"
require "rbs/vendorer"
require "rbs/validator"
Expand Down
68 changes: 68 additions & 0 deletions lib/rbs/prototype/comment_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

module RBS
module Prototype
module CommentParser
# Build a line-number-keyed hash of comments from a Prism::ParseResult or
# an array of Prism comment objects.
def build_comments_prism(comments, include_trailing:)
comments.each_with_object({}) do |comment, hash| #$ Hash[Integer, AST::Comment]
next unless comment.is_a?(Prism::InlineComment)
next if comment.trailing? && !include_trailing

line = comment.location.start_line
body = "#{comment.location.slice}\n"
body = body[2..-1] or raise
body = "\n" if body.empty?

comment = AST::Comment.new(string: body, location: nil)
if prev_comment = hash.delete(line - 1)
hash[line] = AST::Comment.new(string: prev_comment.string + comment.string, location: nil)
else
hash[line] = comment
end
end
end

# Parse comments from a Ruby source string. Uses Prism on Ruby >= 3.3,
# falls back to Ripper on older Rubies.
if RUBY_VERSION >= "3.3"
def parse_comments(string, include_trailing:)
build_comments_prism(
Prism.parse_comments(string, version: "current"), # steep:ignore UnexpectedKeywordArgument
include_trailing: include_trailing
)
end
else
require "ripper"

def parse_comments(string, include_trailing:)
Ripper.lex(string).yield_self do |tokens|
code_lines = {} #: Hash[Integer, bool]
tokens.each.with_object({}) do |token, hash| #$ Hash[Integer, AST::Comment]
case token[1]
when :on_sp, :on_ignored_nl
# skip
when :on_comment
line = token[0][0]
next if code_lines[line] && !include_trailing
body = token[2][2..-1] or raise

body = "\n" if body.empty?

comment = AST::Comment.new(string: body, location: nil)
if prev_comment = hash.delete(line - 1)
hash[line] = AST::Comment.new(string: prev_comment.string + comment.string, location: nil)
else
hash[line] = comment
end
else
code_lines[token[0][0]] = true
end
end
end
end
end
end
end
end
2 changes: 1 addition & 1 deletion lib/rbs/prototype/node_usage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module RBS
module Prototype
class NodeUsage
include Helpers
include RubyVMHelpers

attr_reader :conditional_nodes

Expand Down
Loading
Loading