diff options
author | Kevin Newton <kddnewton@gmail.com> | 2024-06-05 15:23:41 -0400 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2024-06-06 14:15:50 +0000 |
commit | b0059980d04c2395589f3da4a9babaeb45dd4429 (patch) | |
tree | 57958be2955748dee27e119a1faaa8d9d56ae81b /sample | |
parent | 27321290d954300192c82cdf5e2c794a695473f5 (diff) | |
download | ruby-b0059980d04c2395589f3da4a9babaeb45dd4429.tar.gz |
[ruby/prism] Add some samples for using prism APIs
https://github.com/ruby/prism/commit/6a4fe21088
Diffstat (limited to 'sample')
-rw-r--r-- | sample/find_comments.rb | 22 | ||||
-rw-r--r-- | sample/find_nodes.rb | 41 | ||||
-rw-r--r-- | sample/locate_nodes.rb | 69 |
3 files changed, 132 insertions, 0 deletions
diff --git a/sample/find_comments.rb b/sample/find_comments.rb new file mode 100644 index 0000000000..2468444210 --- /dev/null +++ b/sample/find_comments.rb @@ -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 diff --git a/sample/find_nodes.rb b/sample/find_nodes.rb new file mode 100644 index 0000000000..3c96756780 --- /dev/null +++ b/sample/find_nodes.rb @@ -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 diff --git a/sample/locate_nodes.rb b/sample/locate_nodes.rb new file mode 100644 index 0000000000..83f67cab0e --- /dev/null +++ b/sample/locate_nodes.rb @@ -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 |