Class: SyntaxSuggest::Visitor
- Inherits:
-
Prism::Visitor
- Object
- Prism::Visitor
- SyntaxSuggest::Visitor
- Defined in:
- lib/syntax_suggest/visitor.rb
Overview
Walks the Prism AST to extract structural info that cannot be reliably determined from tokens alone.
Such as the location of lines that must be logically joined so the search algorithm will treat them as one. Example:
source = <<~RUBY
User # 1
.where(name: "Earlopain") # 2
.first # 3
RUBY
ast, _tokens = Prism.parse_lex(source).value
visitor = Visitor.new
visitor.visit(ast)
visitor.consecutive_lines # => Set[2, 1]
This output means that line 1 and line 2 need to be joined with their next line.
And determining the location of “endless” method definitions. For example:
source = <<~RUBY
def cube(x)
x * x * x
end
def square(x) = x * x # 1
RUBY
ast, _tokens = Prism.parse_lex(source).value
visitor = Visitor.new
visitor.visit(ast)
visitor.endless_def_keyword_offsets # => Set[28]
Instance Attribute Summary collapse
-
#consecutive_lines ⇒ Object
readonly
Returns the value of attribute consecutive_lines.
-
#endless_def_keyword_offsets ⇒ Object
readonly
Returns the value of attribute endless_def_keyword_offsets.
Instance Method Summary collapse
-
#initialize ⇒ Visitor
constructor
A new instance of Visitor.
-
#visit_call_node(node) ⇒ Object
Called by Prism::Visitor for every method-call node in the AST (e.g. ‘foo.bar`, `foo.bar.baz`).
-
#visit_def_node(node) ⇒ Object
Called by Prism::Visitor for every ‘def` node in the AST.
Constructor Details
#initialize ⇒ Visitor
Returns a new instance of Visitor.
38 39 40 41 |
# File 'lib/syntax_suggest/visitor.rb', line 38 def initialize @endless_def_keyword_offsets = Set.new @consecutive_lines = Set.new end |
Instance Attribute Details
#consecutive_lines ⇒ Object (readonly)
Returns the value of attribute consecutive_lines.
36 37 38 |
# File 'lib/syntax_suggest/visitor.rb', line 36 def consecutive_lines @consecutive_lines end |
#endless_def_keyword_offsets ⇒ Object (readonly)
Returns the value of attribute endless_def_keyword_offsets.
36 37 38 |
# File 'lib/syntax_suggest/visitor.rb', line 36 def endless_def_keyword_offsets @endless_def_keyword_offsets end |
Instance Method Details
#visit_call_node(node) ⇒ Object
Called by Prism::Visitor for every method-call node in the AST (e.g. ‘foo.bar`, `foo.bar.baz`).
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/syntax_suggest/visitor.rb', line 45 def visit_call_node(node) receiver_loc = node.receiver&.location call_operator_loc = node.call_operator_loc = node. if receiver_loc && call_operator_loc && # dot-leading (dot on the next line) # foo # line 1 - consecutive # .bar # line 2 if receiver_loc.end_line != call_operator_loc.start_line && call_operator_loc.start_line == .start_line (receiver_loc.end_line..call_operator_loc.start_line - 1).each do |line| @consecutive_lines << line end end # dot-trailing (dot on the same line as the receiver) # foo. # line 1 - consecutive # bar # line 2 if receiver_loc.end_line == call_operator_loc.start_line && call_operator_loc.start_line != .start_line (call_operator_loc.start_line...start_line - 1).each do |line| @consecutive_lines << line end end end super end |
#visit_def_node(node) ⇒ Object
Called by Prism::Visitor for every ‘def` node in the AST. Records the keyword start location for endless method definitions like `def foo = 123`. These are valid without a matching `end`, so Token must exclude them when deciding if a line is a keyword.
75 76 77 78 |
# File 'lib/syntax_suggest/visitor.rb', line 75 def visit_def_node(node) @endless_def_keyword_offsets << node.def_keyword_loc.start_offset if node.equal_loc super end |