[ruby/prism] Add some samples for using prism APIs

https://github.com/ruby/prism/commit/6a4fe21088
This commit is contained in:
Kevin Newton 2024-06-05 15:23:41 -04:00 committed by git
parent 27321290d9
commit b0059980d0
3 changed files with 132 additions and 0 deletions

22
sample/find_comments.rb Normal file
View File

@ -0,0 +1,22 @@
# This script finds all of the comments within a given source file.
require "prism"
Prism.parse_comments(DATA.read).each do |comment|
puts comment.inspect
puts comment.slice
end
# =>
# #<Prism::InlineComment @location=#<Prism::Location @start_offset=0 @length=42 start_line=1>>
# # This is documentation for the Foo class.
# #<Prism::InlineComment @location=#<Prism::Location @start_offset=55 @length=43 start_line=3>>
# # This is documentation for the bar method.
__END__
# This is documentation for the Foo class.
class Foo
# This is documentation for the bar method.
def bar
end
end

41
sample/find_nodes.rb Normal file
View File

@ -0,0 +1,41 @@
# This script finds all of the nodes of a specific type within a given source
# file. It uses the visitor class to traverse the AST.
require "prism"
class RegexpVisitor < Prism::Visitor
def initialize(regexps)
@regexps = regexps
end
def visit_regular_expression_node(node)
@regexps << node
super
end
end
result = Prism.parse_stream(DATA)
regexps = []
result.value.accept(RegexpVisitor.new(regexps))
puts regexps.map(&:inspect)
# =>
# @ RegularExpressionNode (location: (2,9)-(2,14))
# ├── flags: forced_us_ascii_encoding
# ├── opening_loc: (2,9)-(2,10) = "/"
# ├── content_loc: (2,10)-(2,13) = "foo"
# ├── closing_loc: (2,13)-(2,14) = "/"
# └── unescaped: "foo"
# @ RegularExpressionNode (location: (3,9)-(3,14))
# ├── flags: forced_us_ascii_encoding
# ├── opening_loc: (3,9)-(3,10) = "/"
# ├── content_loc: (3,10)-(3,13) = "bar"
# ├── closing_loc: (3,13)-(3,14) = "/"
# └── unescaped: "bar"
__END__
class Foo
REG1 = /foo/
REG2 = /bar/
end

69
sample/locate_nodes.rb Normal file
View File

@ -0,0 +1,69 @@
# This script locates a set of nodes determined by a line and column (in bytes).
require "prism"
def locate(node, line:, column:)
queue = [node]
result = []
while (node = queue.shift)
# Each node that we visit should be added to the result, so that we end up
# with an array of the nodes that we traversed.
result << node
# Iterate over each child node.
node.compact_child_nodes.each do |child_node|
child_location = child_node.location
start_line = child_location.start_line
end_line = child_location.end_line
# Here we determine if the given coordinates are contained within the
# child node's location.
if start_line == end_line
if line == start_line && column >= child_location.start_column && column < child_location.end_column
queue << child_node
break
end
elsif (line == start_line && column >= child_location.start_column) || (line == end_line && column < child_location.end_column)
queue << child_node
break
elsif line > start_line && line < end_line
queue << child_node
break
end
end
end
# Finally, we return the result.
result
end
result = Prism.parse_stream(DATA)
locate(result.value, line: 4, column: 14).each_with_index do |node, index|
location = node.location
puts "#{" " * index}#{node.type}@#{location.start_line}:#{location.start_column}-#{location.end_line}:#{location.end_column}"
end
# =>
# program_node@1:0-7:3
# statements_node@1:0-7:3
# module_node@1:0-7:3
# statements_node@2:2-6:5
# class_node@2:2-6:5
# statements_node@3:4-5:7
# def_node@3:4-5:7
# statements_node@4:6-4:21
# call_node@4:6-4:21
# call_node@4:6-4:15
# arguments_node@4:12-4:15
# integer_node@4:12-4:15
__END__
module Foo
class Bar
def baz
111 + 222 + 333
end
end
end