|
| 1 | +#!/usr/bin/env ruby |
| 2 | +# frozen_string_literal: true |
| 3 | + |
| 4 | +require "bundler/setup" |
| 5 | +require "parser/current" |
| 6 | + |
| 7 | +$:.unshift(File.expand_path("../lib", __dir__)) |
| 8 | +require "syntax_tree" |
| 9 | + |
| 10 | +# First, opt in to every AST feature. |
| 11 | +# Parser::Builders::Default.modernize |
| 12 | + |
| 13 | +# Modify the source map == check so that it doesn't check against the node |
| 14 | +# itself so we don't get into a recursive loop. |
| 15 | +Parser::Source::Map.prepend( |
| 16 | + Module.new { |
| 17 | + def ==(other) |
| 18 | + self.class == other.class && |
| 19 | + (instance_variables - %i[@node]).map do |ivar| |
| 20 | + instance_variable_get(ivar) == other.instance_variable_get(ivar) |
| 21 | + end.reduce(:&) |
| 22 | + end |
| 23 | + } |
| 24 | +) |
| 25 | + |
| 26 | +# Next, ensure that we're comparing the nodes and also comparing the source |
| 27 | +# ranges so that we're getting all of the necessary information. |
| 28 | +Parser::AST::Node.prepend( |
| 29 | + Module.new { |
| 30 | + def ==(other) |
| 31 | + super && (location == other.location) |
| 32 | + end |
| 33 | + } |
| 34 | +) |
| 35 | + |
| 36 | +source = ARGF.read |
| 37 | + |
| 38 | +parser = Parser::CurrentRuby.new |
| 39 | +parser.diagnostics.all_errors_are_fatal = true |
| 40 | + |
| 41 | +buffer = Parser::Source::Buffer.new("(string)", 1) |
| 42 | +buffer.source = source.dup.force_encoding(parser.default_encoding) |
| 43 | + |
| 44 | +stree = SyntaxTree::Translation.to_parser(SyntaxTree.parse(source), buffer) |
| 45 | +ptree = parser.parse(buffer) |
| 46 | + |
| 47 | +if stree == ptree |
| 48 | + puts "Syntax trees are equivalent." |
| 49 | +else |
| 50 | + warn "Syntax trees are different." |
| 51 | + |
| 52 | + warn "syntax_tree:" |
| 53 | + pp stree |
| 54 | + |
| 55 | + warn "parser:" |
| 56 | + pp ptree |
| 57 | + |
| 58 | + binding.irb |
| 59 | +end |
0 commit comments