module SyntaxTree
Syntax Tree is a suite of tools built on top of the internal CRuby parser. It provides the ability to generate a syntax tree from source, as well as the tools necessary to inspect and manipulate that syntax tree. It can be used to build formatters, linters, language servers, and more.
Constants
- DEFAULT_INDENTATION
The default indentation level for formatting. We allow changing this so that Syntax Tree can format arbitrary parts of a document.
- DEFAULT_PRINT_WIDTH
This is the default print width when formatting. It can be overridden in the
CLI
by passing the –print-width option or here in the API by passing the optional second argument to::format
.- DEFAULT_RUBY_VERSION
This is the default ruby version that we’re going to target for formatting. It shouldn’t really be changed except in very niche circumstances.
- HANDLERS
This holds references to objects that respond to both parse and format so that we can use them in the
CLI
.- PATTERNS
The list of nodes that represent patterns inside of pattern matching so that when a pattern is being printed it knows if it’s nested.
- VERSION
Public Class Methods
Parses the given source and returns the formatted source.
# File lib/syntax_tree.rb, line 60 def self.format( source, maxwidth = DEFAULT_PRINT_WIDTH, base_indentation = DEFAULT_INDENTATION, options: Formatter::Options.new ) format_node( source, parse(source), maxwidth, base_indentation, options: options ) end
Parses the given file and returns the formatted source.
# File lib/syntax_tree.rb, line 76 def self.format_file( filepath, maxwidth = DEFAULT_PRINT_WIDTH, base_indentation = DEFAULT_INDENTATION, options: Formatter::Options.new ) format(read(filepath), maxwidth, base_indentation, options: options) end
Accepts a node in the tree and returns the formatted source.
# File lib/syntax_tree.rb, line 86 def self.format_node( source, node, maxwidth = DEFAULT_PRINT_WIDTH, base_indentation = DEFAULT_INDENTATION, options: Formatter::Options.new ) formatter = Formatter.new(source, [], maxwidth, options: options) node.format(formatter) formatter.flush(base_indentation) formatter.output.join end
Indexes the given source code to return a list of all class, module, and method definitions. Used to quickly provide indexing capability for IDEs or documentation generation.
# File lib/syntax_tree.rb, line 103 def self.index(source) Index.index(source) end
Indexes the given file to return a list of all class, module, and method definitions. Used to quickly provide indexing capability for IDEs or documentation generation.
# File lib/syntax_tree.rb, line 110 def self.index_file(filepath) Index.index_file(filepath) end
A convenience method for creating a new mutation visitor.
# File lib/syntax_tree.rb, line 115 def self.mutation visitor = MutationVisitor.new yield visitor visitor end
Parses the given source and returns the syntax tree.
# File lib/syntax_tree.rb, line 122 def self.parse(source) parser = Parser.new(source) response = parser.parse response unless parser.error? end
Parses the given file and returns the syntax tree.
# File lib/syntax_tree.rb, line 129 def self.parse_file(filepath) parse(read(filepath)) end
Returns the source from the given filepath taking into account any potential magic encoding comments.
# File lib/syntax_tree.rb, line 135 def self.read(filepath) encoding = File.open(filepath, "r") do |file| break Encoding.default_external if file.eof? header = file.readline header += file.readline if !file.eof? && header.start_with?("#!") Ripper.new(header).tap(&:parse).encoding end File.read(filepath, encoding: encoding) end
This is a hook provided so that plugins can register themselves as the handler for a particular file type.
# File lib/syntax_tree.rb, line 150 def self.register_handler(extension, handler) HANDLERS[extension] = handler end
Searches through the given source using the given pattern and yields each node in the tree that matches the pattern to the given block.
# File lib/syntax_tree.rb, line 156 def self.search(source, query, &block) pattern = Pattern.new(query).compile program = parse(source) Search.new(pattern).scan(program, &block) end
Searches through the given file using the given pattern and yields each node in the tree that matches the pattern to the given block.
# File lib/syntax_tree.rb, line 165 def self.search_file(filepath, query, &block) search(read(filepath), query, &block) end