Skip to content

Commit 6a4fe21

Browse files
committed
Add some samples for using prism APIs
1 parent 6273ac5 commit 6a4fe21

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed

sample/find_comments.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# This script finds all of the comments within a given source file.
2+
3+
require "prism"
4+
5+
Prism.parse_comments(DATA.read).each do |comment|
6+
puts comment.inspect
7+
puts comment.slice
8+
end
9+
10+
# =>
11+
# #<Prism::InlineComment @location=#<Prism::Location @start_offset=0 @length=42 start_line=1>>
12+
# # This is documentation for the Foo class.
13+
# #<Prism::InlineComment @location=#<Prism::Location @start_offset=55 @length=43 start_line=3>>
14+
# # This is documentation for the bar method.
15+
16+
__END__
17+
# This is documentation for the Foo class.
18+
class Foo
19+
# This is documentation for the bar method.
20+
def bar
21+
end
22+
end

sample/find_nodes.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# This script finds all of the nodes of a specific type within a given source
2+
# file. It uses the visitor class to traverse the AST.
3+
4+
require "prism"
5+
6+
class RegexpVisitor < Prism::Visitor
7+
def initialize(regexps)
8+
@regexps = regexps
9+
end
10+
11+
def visit_regular_expression_node(node)
12+
@regexps << node
13+
super
14+
end
15+
end
16+
17+
result = Prism.parse_stream(DATA)
18+
regexps = []
19+
20+
result.value.accept(RegexpVisitor.new(regexps))
21+
puts regexps.map(&:inspect)
22+
23+
# =>
24+
# @ RegularExpressionNode (location: (2,9)-(2,14))
25+
# ├── flags: forced_us_ascii_encoding
26+
# ├── opening_loc: (2,9)-(2,10) = "/"
27+
# ├── content_loc: (2,10)-(2,13) = "foo"
28+
# ├── closing_loc: (2,13)-(2,14) = "/"
29+
# └── unescaped: "foo"
30+
# @ RegularExpressionNode (location: (3,9)-(3,14))
31+
# ├── flags: forced_us_ascii_encoding
32+
# ├── opening_loc: (3,9)-(3,10) = "/"
33+
# ├── content_loc: (3,10)-(3,13) = "bar"
34+
# ├── closing_loc: (3,13)-(3,14) = "/"
35+
# └── unescaped: "bar"
36+
37+
__END__
38+
class Foo
39+
REG1 = /foo/
40+
REG2 = /bar/
41+
end

sample/locate_nodes.rb

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# This script locates a set of nodes determined by a line and column (in bytes).
2+
3+
require "prism"
4+
5+
def locate(node, line:, column:)
6+
queue = [node]
7+
result = []
8+
9+
while (node = queue.shift)
10+
# Each node that we visit should be added to the result, so that we end up
11+
# with an array of the nodes that we traversed.
12+
result << node
13+
14+
# Iterate over each child node.
15+
node.compact_child_nodes.each do |child_node|
16+
child_location = child_node.location
17+
18+
start_line = child_location.start_line
19+
end_line = child_location.end_line
20+
21+
# Here we determine if the given coordinates are contained within the
22+
# child node's location.
23+
if start_line == end_line
24+
if line == start_line && column >= child_location.start_column && column < child_location.end_column
25+
queue << child_node
26+
break
27+
end
28+
elsif (line == start_line && column >= child_location.start_column) || (line == end_line && column < child_location.end_column)
29+
queue << child_node
30+
break
31+
elsif line > start_line && line < end_line
32+
queue << child_node
33+
break
34+
end
35+
end
36+
end
37+
38+
# Finally, we return the result.
39+
result
40+
end
41+
42+
result = Prism.parse_stream(DATA)
43+
locate(result.value, line: 4, column: 14).each_with_index do |node, index|
44+
location = node.location
45+
puts "#{" " * index}#{node.type}@#{location.start_line}:#{location.start_column}-#{location.end_line}:#{location.end_column}"
46+
end
47+
48+
# =>
49+
# program_node@1:0-7:3
50+
# statements_node@1:0-7:3
51+
# module_node@1:0-7:3
52+
# statements_node@2:2-6:5
53+
# class_node@2:2-6:5
54+
# statements_node@3:4-5:7
55+
# def_node@3:4-5:7
56+
# statements_node@4:6-4:21
57+
# call_node@4:6-4:21
58+
# call_node@4:6-4:15
59+
# arguments_node@4:12-4:15
60+
# integer_node@4:12-4:15
61+
62+
__END__
63+
module Foo
64+
class Bar
65+
def baz
66+
111 + 222 + 333
67+
end
68+
end
69+
end

0 commit comments

Comments
 (0)