An AST node is characterized by a type and a list of children. It is most easily represented by the s-expression {s} such as:
# AST for "if true; 5 end": s(s(:if, s(:var_ref, s(:kw, "true")), s(s(:int, "5")), nil))
The node type is not considered part of the list, only its children. So +ast+ does not refer to the type, but rather the first child (or object). Items that are not AstNode objects can be part of the list, like Strings or Symbols representing names. To return only the AstNode children of the node, use {children}.
List of all known keywords @return [Hash]
Creates a new AST node
@param [Symbol] type the type of node being created @param [Array<AstNode>] arr the child nodes @param [Hash] opts any extra line options @option opts [Fixnum] :line (nil) the line the node starts on in source @option opts [String] :char (nil) the character number the node starts on
in source
@option opts [Fixnum] :listline (nil) a special key like :line but for
list nodes
@option opts [Fixnum] :listchar (nil) a special key like :char but for
list nodes
@option opts [Boolean] :token (nil) whether the node represents a token
# File lib/yard/parser/ruby/ast_node.rb, line 152 def initialize(type, arr, opts = {}) super(arr) self.type = type self.line_range = opts[:line] self.source_range = opts[:char] @fallback_line = opts[:listline] @fallback_source = opts[:listchar] @token = true if opts[:token] end
Finds the node subclass that should be instantiated for a specific node type
@param [Symbol] type the node type to find a subclass for @return [Class] a subclass of AstNode to instantiate the node with.
# File lib/yard/parser/ruby/ast_node.rb, line 110 def self.node_class_for(type) case type when :params ParameterNode when :call, :fcall, :vcall, :command, :command_call MethodCallNode when :if, :elsif, :if_mod, :unless, :unless_mod ConditionalNode when :for, :while, :while_mod, :until, :until_mod LoopNode when :def, :defs MethodDefinitionNode when :class, :sclass ClassNode when :module ModuleNode else if type.to_s =~ /_ref\Z/ ReferenceNode elsif type.to_s =~ /_literal\Z/ LiteralNode elsif KEYWORDS.has_key?(type) KeywordNode else AstNode end end end
@return [Boolean] whether the node is equal to another by checking
the list and type
@private
# File lib/yard/parser/ruby/ast_node.rb, line 165 def ==(ast) super && type == ast.type end
@return [Boolean] whether the node has a block
# File lib/yard/parser/ruby/ast_node.rb, line 258 def block? respond_to?(:block) || condition? end
@return [Boolean] whether the node is a method call
# File lib/yard/parser/ruby/ast_node.rb, line 238 def call? false end
@return [Array<AstNode>] the {AstNode} children inside the node
# File lib/yard/parser/ruby/ast_node.rb, line 197 def children @children ||= select {|e| AstNode === e } end
@return [Boolean] whether the node is a if/elsif/else condition
# File lib/yard/parser/ruby/ast_node.rb, line 248 def condition? false end
@return [Boolean] whether the node is a method definition
# File lib/yard/parser/ruby/ast_node.rb, line 243 def def? false end
@return [String] the filename the node was parsed from
# File lib/yard/parser/ruby/ast_node.rb, line 75 def file return parent.file if parent @file end
@return [String] the first line of source represented by the node.
# File lib/yard/parser/ruby/ast_node.rb, line 275 def first_line full_source.split(/\r?\n/)[line - 1].strip end
@return [String] the full source that the node was parsed from
# File lib/yard/parser/ruby/ast_node.rb, line 81 def full_source return parent.full_source if parent return @full_source if @full_source return IO.read(@file) if file && File.exist?(file) end
@return [Boolean] whether the node has a {line_range} set
# File lib/yard/parser/ruby/ast_node.rb, line 265 def has_line? @line_range ? true : false end
@return [String] inspects the object
# File lib/yard/parser/ruby/ast_node.rb, line 322 def inspect typeinfo = type && type != :list ? ':' + type.to_s + ', ' : '' 's(' + typeinfo + map(&:inspect).join(", ") + ')' end
Searches through the node and all descendants and returns the first node with a type matching any of node_types, otherwise returns the original node (self).
@example Returns the first method definition in a block of code
ast = YARD.parse_string("if true; def x; end end").ast ast.jump(:def) # => s(:def, s(:ident, "x"), s(:params, nil, nil, nil, nil, # nil), s(s(:void_stmt, )))
@example Returns first 'def' or 'class' statement
ast = YARD.parse_string("class X; def y; end end") ast.jump(:def, :class).first # =>
@example If the node types are not present in the AST
ast = YARD.parse("def x; end") ast.jump(:def)
@param [Array<Symbol>] node_types a set of node types to match @return [AstNode] the matching node, if one was found @return [self] if no node was found
# File lib/yard/parser/ruby/ast_node.rb, line 191 def jump(*node_types) traverse {|child| return(child) if node_types.include?(child.type) } self end
@return [Boolean] whether the node is a keyword
# File lib/yard/parser/ruby/ast_node.rb, line 233 def kw? false end
@return [Fixnum] the starting line number of the node
# File lib/yard/parser/ruby/ast_node.rb, line 270 def line line_range && line_range.first end
@return [Range] the line range in {full_source} represented
by the node
# File lib/yard/parser/ruby/ast_node.rb, line 69 def line_range reset_line_info unless @line_range @line_range end
@return [Boolean] whether the node is a literal value
# File lib/yard/parser/ruby/ast_node.rb, line 228 def literal? false end
@return [Boolean] whether the node is a loop
# File lib/yard/parser/ruby/ast_node.rb, line 253 def loop? false end
@return [nil] pretty prints the node
# File lib/yard/parser/ruby/ast_node.rb, line 287 def pretty_print(q) objs = self.dup + [:__last__] objs.unshift(type) if type && type != :list options = [] if @docstring options << ['docstring', docstring] end if @source_range || @line_range options << ['line', line_range] options << ['source', source_range] end objs.pop if options.size == 0 q.group(3, 's(', ')') do q.seplist(objs, nil, :each) do |v| if v == :__last__ q.seplist(options, nil, :each) do |arr| k, v2 = *arr q.group(3) do q.text k q.group(3) do q.text ': ' q.pp v2 end end end else q.pp v end end end end
@return [Boolean] whether the node is a reference (variable,
constant name)
# File lib/yard/parser/ruby/ast_node.rb, line 223 def ref? false end
@return [String] the first line of source the node represents
# File lib/yard/parser/ruby/ast_node.rb, line 282 def show "\t#{line}: #{first_line}" end
@return [Range] the character range in {full_source} represented
by the node
# File lib/yard/parser/ruby/ast_node.rb, line 62 def source_range reset_line_info unless @source_range @source_range end
@return [Boolean] whether the node is a token
# File lib/yard/parser/ruby/ast_node.rb, line 217 def token? @token end
Traverses the object and yields each node (including descendants) in order.
@yield each descendant node in order @yieldparam [AstNode] self, or a child/descendant node @return [void]
# File lib/yard/parser/ruby/ast_node.rb, line 206 def traverse nodes = [self] nodes.each.with_index do |node, index| yield node nodes.insert index+1, *node.children end end
Generated with the Darkfish Rdoc Generator 2.