Upgrade to PRO for Only $50/Yearโ€”Limited-Time Offer! ๐Ÿ”ฅ

Syntax Tree (RubyConf Mini)

Avatar for Kevin Newton Kevin Newton
November 16, 2022
180

Syntax Tree (RubyConfย Mini)

Syntax Tree is a new toolkit for interacting with the Ruby parse tree. It can be used to analyze, inspect, debug, and format your Ruby code. In this talk we'll walk through how it works, how to use it in your own applications, and the exciting future possibilities enabled by Syntax Tree.

Avatar for Kevin Newton

Kevin Newton

November 16, 2022
Tweet

Transcript

  1. Matz is nice so we are nice . Parser ยท

    Syntax tree ยท Visitor
  2. is nice so we are nice . Matz Parser ยท

    Syntax tree ยท Visitor
  3. is nice so we are nice . Matz Parser ยท

    Syntax tree ยท Visitor
  4. Matz is nice we are nice . so Parser ยท

    Syntax tree ยท Visitor
  5. Matz is nice so we are nice . Parser ยท

    Syntax tree ยท Visitor
  6. Matz is nice so we are nice . Parser ยท

    Syntax tree ยท Visitor
  7. Matz is nice so we are . nice Parser ยท

    Syntax tree ยท Visitor
  8. Matz is nice so we are nice . Parser ยท

    Syntax tree ยท Visitor
  9. Matz is nice so we are nice . Parser ยท

    Syntax tree ยท Visitor
  10. Grammar Parser ยท Syntax tree ยท Visitor verb-phrase : VERB

    ADJECTIVE โ€จ subject-phrase : NOUN verb-phrase
  11. Parser ยท Syntax tree ยท Visitor Matz is nice subject

    phrase subject phrase verb phrase we verb phrase are nice
  12. Parser ยท Syntax tree ยท Visitor Matz is nice so

    subject phrase subject phrase verb phrase we verb phrase are nice
  13. Grammar Parser ยท Syntax tree ยท Visitor verb-phrase : VERB

    ADJECTIVE โ€จ subject-phrase : NOUN verb-phrase
  14. Grammar Parser ยท Syntax tree ยท Visitor verb-phrase : VERB

    ADJECTIVE โ€จ subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase
  15. Parser ยท Syntax tree ยท Visitor Matz is nice so

    subject phrase subject phrase verb phrase we verb phrase are nice
  16. Parser ยท Syntax tree ยท Visitor Matz is nice so

    subord. conjunction subject phrase subject phrase verb phrase we verb phrase are nice
  17. Parser ยท Syntax tree ยท Visitor Matz is nice so

    . subord. conjunction subject phrase subject phrase verb phrase we verb phrase are nice
  18. verb-phrase : VERB ADJECTIVE โ€จ subject-phrase : NOUN verb-phrase โ€จ

    subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase Grammar Parser ยท Syntax tree ยท Visitor
  19. verb-phrase : VERB ADJECTIVE โ€จ subject-phrase : NOUN verb-phrase โ€จ

    subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase โ€จ sentence : subordinating-conjunction PERIOD Grammar Parser ยท Syntax tree ยท Visitor
  20. Parser ยท Syntax tree ยท Visitor Matz is nice so

    . subord. conjunction subject phrase subject phrase verb phrase we verb phrase are nice
  21. Parser ยท Syntax tree ยท Visitor Matz is nice so

    . sentence subord. conjunction subject phrase subject phrase verb phrase we verb phrase are nice
  22. verb-phrase : VERB ADJECTIVE โ€จ subject-phrase : NOUN verb-phrase โ€จ

    subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase โ€จ sentence : subordinating-conjunction PERIOD Grammar Parser ยท Syntax tree ยท Visitor
  23. verb-phrase : VERB ADJECTIVE โ€จ subject-phrase : NOUN verb-phrase โ€จ

    subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase โ€จ sentence : subordinating-conjunction PERIOD Grammar Parser ยท Syntax tree ยท Visitor
  24. Parser ยท Syntax tree ยท Visitor verb-phrase : VERB ADJECTIVE

    subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD
  25. Parser ยท Syntax tree ยท Visitor class VerbPhrase attr_reader :verb,

    :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD
  26. Parser ยท Syntax tree ยท Visitor verb-phrase : VERB ADJECTIVE

    subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end
  27. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end
  28. Parser ยท Syntax tree ยท Visitor verb-phrase : VERB ADJECTIVE

    subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class SubjectPhrase attr_reader :noun, :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end
  29. Parser ยท Syntax tree ยท Visitor verb-phrase : VERB ADJECTIVE

    subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class SubjectPhrase attr_reader :noun, :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end
  30. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end
  31. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end
  32. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end
  33. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end
  34. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end
  35. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end class Adjective attr_reader :value def initialize(value:) @value = value end end
  36. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end class Adjective attr_reader :value def initialize(value:) @value = value end end
  37. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end class Adjective attr_reader :value def initialize(value:) @value = value end end class Noun attr_reader :value def initialize(value:) @value = value end end
  38. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end class Adjective attr_reader :value def initialize(value:) @value = value end end class Noun attr_reader :value def initialize(value:) @value = value end end
  39. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end class Adjective attr_reader :value def initialize(value:) @value = value end end class Noun attr_reader :value def initialize(value:) @value = value end end class Conjunction attr_reader :value def initialize(value:) @value = value end end
  40. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end class Adjective attr_reader :value def initialize(value:) @value = value end end class Noun attr_reader :value def initialize(value:) @value = value end end class Conjunction attr_reader :value def initialize(value:) @value = value end end
  41. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end class Adjective attr_reader :value def initialize(value:) @value = value end end class Noun attr_reader :value def initialize(value:) @value = value end end class Conjunction attr_reader :value def initialize(value:) @value = value end end class Period attr_reader :value def initialize(value:) @value = value end end
  42. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end verb-phrase : VERB ADJECTIVE subject-phrase : NOUN verb-phrase subordinating-conjunction : โ€จ subject-phrase CONJUNCTION subject-phrase sentence : subordinating-conjunction PERIOD class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end class Adjective attr_reader :value def initialize(value:) @value = value end end class Noun attr_reader :value def initialize(value:) @value = value end end class Conjunction attr_reader :value def initialize(value:) @value = value end end class Period attr_reader :value def initialize(value:) @value = value end end
  43. Parser ยท Syntax tree ยท Visitor class SubjectPhrase attr_reader :noun,

    :verb_phrase def initialize(noun:, verb_phrase:) @noun = noun @verb_phrase = verb_phrase end end class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end class Adjective attr_reader :value def initialize(value:) @value = value end end class Noun attr_reader :value def initialize(value:) @value = value end end class Conjunction attr_reader :value def initialize(value:) @value = value end end class Period attr_reader :value def initialize(value:) @value = value end end
  44. class SubjectPhrase attr_reader :noun, :verb_phrase def initialize(noun:, verb_phrase:) @noun =

    noun @verb_phrase = verb_phrase end end class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end end class SubordinatingConjunction attr_reader :left, :conjunction, :right def initialize(left:, conjunction:, right:) @left = left @conjunction = conjunction @right = right end end class Sentence attr_reader :phrase, :punctuation def initialize(phrase:, punctuation:) @phrase = phrase @punctuation = punctuation end end class Verb attr_reader :value def initialize(value:) @value = value end end class Adjective attr_reader :value def initialize(value:) @value = value end end class Noun attr_reader :value def initialize(value:) @value = value end end class Conjunction attr_reader :value def initialize(value:) @value = value end end class Period attr_reader :value def initialize(value:) @value = value end end Parser ยท Syntax tree ยท Visitor
  45. class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb =

    verb @adjective = adjective end end Parser ยท Syntax tree ยท Visitor
  46. Parser ยท Syntax tree ยท Visitor class VerbPhrase attr_reader :verb,

    :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end def deconstruct_keys(keys) { verb: verb, adjective: adjective } end def ==(other) other in VerbPhrase[ verb: ^(verb), adjective: ^(adjective) ] end end
  47. class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb =

    verb @adjective = adjective end end Parser ยท Syntax tree ยท Visitor
  48. Parser ยท Syntax tree ยท Visitor class VerbPhrase attr_reader :verb,

    :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end def copy(verb: self.verb, adjective: self.adjective) VerbPhrase.new(verb: verb, adjective: adjective) end end
  49. class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb =

    verb @adjective = adjective end end Parser ยท Syntax tree ยท Visitor
  50. Parser ยท Syntax tree ยท Visitor class VerbPhrase attr_reader :verb,

    :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end def accept(visitor) visitor.visit_verb_phrase(self) end def child_nodes [verb, adjective] end end
  51. Parser ยท Syntax tree ยท Visitor class VerbPhrase attr_reader :verb,

    :adjective def initialize(verb:, adjective:) @verb = verb @adjective = adjective end def accept(visitor) visitor.visit_verb_phrase(self) end def child_nodes [verb, adjective] end end
  52. class VerbPhrase attr_reader :verb, :adjective def initialize(verb:, adjective:) @verb =

    verb @adjective = adjective end def accept(visitor) visitor.visit_verb_phrase(self) end def child_nodes [verb, adjective] end end Parser ยท Syntax tree ยท Visitor
  53. class VerbPhrase def accept(visitor) visitor.visit_verb_phrase(self) end end โ€จ class Visitor

    def visit_verb_phrase(node) # ... end end node.accept(Visitor.new) Parser ยท Syntax tree ยท Visitor
  54. class VerbPhrase def accept(visitor) visitor.visit_verb_phrase(self) end end โ€จ class Visitor

    def visit_adjective(node) end def visit_conjunction(node) end def visit_noun(node) end def visit_verb(node) end def visit_punctuation(node) end def visit_sentence(node) end def visit_subordinating_conjunction(node) end def visit_subject_phrase(node) end def visit_verb_phrase(node) # ... end end node.accept(Visitor.new) Parser ยท Syntax tree ยท Visitor
  55. class Visitor def visit_adjective(node) end def visit_conjunction(node) end def visit_noun(node)

    end def visit_verb(node) end def visit_punctuation(node) end def visit_sentence(node) end def visit_subordinating_conjunction(node) end def visit_subject_phrase(node) end def visit_verb_phrase(node) # ... end end node.accept(Visitor.new) Parser ยท Syntax tree ยท Visitor
  56. class Visitor def visit(node) node.accept(self) end def visit_adjective(node) end def

    visit_conjunction(node) end def visit_noun(node) end def visit_verb(node) end def visit_punctuation(node) end def visit_sentence(node) end def visit_subordinating_conjunction(node) end def visit_subject_phrase(node) end def visit_verb_phrase(node) # ... end end node.accept(Visitor.new) Parser ยท Syntax tree ยท Visitor
  57. Parser ยท Syntax tree ยท Visitor class Visitor def visit(node)

    node.accept(self) end def visit_adjective(node) end def visit_conjunction(node) end def visit_noun(node) end def visit_verb(node) end def visit_punctuation(node) end def visit_sentence(node) end def visit_subordinating_conjunction(node) end def visit_subject_phrase(node) end def visit_verb_phrase(node) node.child_nodes.each { |node| visit(node) } end end node.accept(Visitor.new)
  58. Parser ยท Syntax tree ยท Visitor class Visitor def visit(node)

    node.accept(self) end def visit_adjective(node) end def visit_conjunction(node) end def visit_noun(node) end def visit_verb(node) end def visit_punctuation(node) end def visit_sentence(node) end def visit_subordinating_conjunction(node) end def visit_subject_phrase(node) end def visit_verb_phrase(node) node.child_nodes.each { |node| visit(node) } end end
  59. Parser ยท Syntax tree ยท Visitor class Visitor def visit(node)

    node.accept(self) end def visit_child_nodes(node) node.child_nodes.each { |node| visit(node) } end def visit_adjective(node) end def visit_conjunction(node) end def visit_noun(node) end def visit_verb(node) end def visit_punctuation(node) end def visit_sentence(node) end def visit_subordinating_conjunction(node) end def visit_subject_phrase(node) end def visit_verb_phrase(node) visit_child_nodes(node) end end
  60. Parser ยท Syntax tree ยท Visitor class Visitor def visit(node)

    node.accept(self) end def visit_child_nodes(node) node.child_nodes.each { |node| visit(node) } end def visit_adjective(node) end def visit_conjunction(node) end def visit_noun(node) end def visit_verb(node) end def visit_punctuation(node) end def visit_sentence(node) end def visit_subordinating_conjunction(node) end def visit_subject_phrase(node) end alias visit_verb_phrase visit_child_nodes end
  61. Parser ยท Syntax tree ยท Visitor class Visitor def visit(node)

    node.accept(self) end def visit_child_nodes(node) node.child_nodes.each { |node| visit(node) } end alias visit_adjective visit_child_nodes alias visit_conjunction visit_child_nodes alias visit_noun visit_child_nodes alias visit_verb visit_child_nodes alias visit_punctuation visit_child_nodes alias visit_sentence visit_child_nodes alias visit_subordinating_conjunction โ€จ visit_child_nodes alias visit_subject_phrase visit_child_nodes alias visit_verb_phrase visit_child_nodes end
  62. Parser ยท Syntax tree ยท Visitor class SentenceCountVisitor < Visitor

    attr_reader :count def initialize @count = 0 end def visit_sentence(node) @count += 1 super end end visitor = SentenceCountVisitor.new node.accept(visitor) puts visitor.count
  63. Parser ยท Syntax tree ยท Visitor class PrettyPrintVisitor < Visitor

    attr_reader :q def initialize @q = PP.new(+"") end def visit_sentence(node) q.group(2, "sentence(", ")") do visit(node.phrase) visit(node.punctuation) end end end visitor = PrettyPrintVisitor.new node.accept(visitor) visitor.q.flush puts visitor.q.output
  64. Parser ยท Syntax tree ยท Visitor class FormatterVisitor < Visitor

    attr_reader :q def initialize @q = PP.new(+"") end def visit_sentence(node) q.group do q.format(node.phrase) q.format(node.punctuation) end end end visitor = FormatterVisitor.new node.accept(visitor) visitor.q.flush puts visitor.q.output
  65. Object layer representing the result of parsing Ruby Tools to

    interact with and manipulate that layer Syntax Tree
  66. Build a syntax tree Format the syntax tree Create a

    CLI Create a language server (LSP) Syntax Tree
  67. Build a syntax tree Format the syntax tree Create a

    CLI Create a language server (LSP) Translate the syntax tree Syntax Tree
  68. Build ยท Format ยท CLI ยท LSP ยท Translate class

    VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end
  69. Build ยท Format ยท CLI ยท LSP ยท Translate class

    VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end Named fields
  70. Build ยท Format ยท CLI ยท LSP ยท Translate class

    VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end Named fields #location/#comments
  71. Build ยท Format ยท CLI ยท LSP ยท Translate class

    VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end Named fields #location/#comments #accept/#child_nodes
  72. Build ยท Format ยท CLI ยท LSP ยท Translate class

    VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end Named fields #location/#comments #accept/#child_nodes #deconstruct/ โ€จ #deconstruct_keys
  73. Build ยท Format ยท CLI ยท LSP ยท Translate class

    VCall < Node attr_reader :value, :location, :comments def initialize(value:, location:, comments: []) @value = value @location = location @comments = comments end def accept(visitor) visitor.visit_vcall(self) end def child_nodes [value] end alias deconstruct child_nodes def deconstruct_keys(keys) { value: value, location: location, comments: comments } end end Named fields #location/#comments #accept/#child_nodes #deconstruct/ โ€จ #deconstruct_keys Immutable
  74. Ripper::EVENTS.count # => 190 SyntaxTree::Node.descendants.count โ€จ # => 162 Define

    each node Build ยท Format ยท CLI ยท LSP ยท Translate
  75. Ripper::EVENTS.count # => 190 SyntaxTree::Node.descendants.count โ€จ # => 162 qwords_new/qwords_add

    -> SyntaxTree::QWords Define each node Build ยท Format ยท CLI ยท LSP ยท Translate
  76. var_ref : user_variable { /*%%%*/ if (!($$ = gettable(p, $1,

    &@$))) $$ = NEW_BEGIN(0, &@$); /*% if (id_is_var(p, get_id($1))) { $$ = dispatch1(var_ref, $1); } else { $$ = dispatch1(vcall, $1); } %*/ } | keyword_variable { /*%%%*/ if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$); /*% %*/ /*% ripper: var_ref!($1) %*/ } ; Build ยท Format ยท CLI ยท LSP ยท Translate
  77. var_ref : user_variable { /*%%%*/ if (!($$ = gettable(p, $1,

    &@$))) $$ = NEW_BEGIN(0, &@$); /*% if (id_is_var(p, get_id($1))) { $$ = dispatch1(var_ref, $1); } else { $$ = dispatch1(vcall, $1); } %*/ } | keyword_variable { /*%%%*/ if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$); /*% %*/ /*% ripper: var_ref!($1) %*/ } ; Build ยท Format ยท CLI ยท LSP ยท Translate
  78. class Foo def bar baz end end Build ยท Format

    ยท CLI ยท LSP ยท Translate
  79. class Foo def bar baz end end Build ยท Format

    ยท CLI ยท LSP ยท Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end
  80. class Foo def bar baz end end Build ยท Format

    ยท CLI ยท LSP ยท Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end
  81. class Foo def bar baz end end Build ยท Format

    ยท CLI ยท LSP ยท Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end
  82. class Foo def bar baz end end Build ยท Format

    ยท CLI ยท LSP ยท Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end
  83. class Foo def bar baz end end Build ยท Format

    ยท CLI ยท LSP ยท Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end
  84. class Foo def bar baz end end Build ยท Format

    ยท CLI ยท LSP ยท Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end
  85. class Foo def bar baz end end Build ยท Format

    ยท CLI ยท LSP ยท Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end
  86. class Foo def bar baz end end Build ยท Format

    ยท CLI ยท LSP ยท Translate class Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end
  87. Build ยท Format ยท CLI ยท LSP ยท Translate class

    Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) [:class, [const, superclass, bodystmt]] end def on_def(name, params, bodystmt) [:def, [name, params, bodystmt]] end end
  88. Build ยท Format ยท CLI ยท LSP ยท Translate class

    Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_kw(value) = @stack << [:@kw, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) kw = @stack.rfind { |token| token in [:@kw, "class"] } [:class, [@stack.delete(kw), const, superclass, bodystmt]] end def on_def(name, params, bodystmt) kw = @stack.rfind { |token| token in [:@kw, "def"] } [:def, [@stack.delete(kw), name, params, bodystmt]] end end
  89. Build ยท Format ยท CLI ยท LSP ยท Translate class

    Parser < Ripper def on_const(value) = [:@const, value] def on_ident(value) = [:@ident, value] def on_kw(value) = @stack << [:@kw, value] def on_const_ref(const) = [:const_ref, const] def on_vcall(ident) = [:vcall, ident] def on_class(const, superclass, bodystmt) kw = @stack.rfind { |token| token in [:@kw, "class"] } [:class, [@stack.delete(kw), const, superclass, bodystmt]] end def on_def(name, params, bodystmt) kw = @stack.rfind { |token| token in [:@kw, "def"] } [:def, [@stack.delete(kw), name, params, bodystmt]] end end
  90. Build ยท Format ยท CLI ยท LSP ยท Translate ->

    (positional; local1, local2) {} range = (location.start_char + 1)...location.end_char locals = lambda_locals(source[range]) Paren.new( lparen: params.lparen, contents: LambdaVar.new( params: params.contents, locals: locals, location: location ), location: params.location, comments: params.comments )
  91. class Foo def bar baz end end Build ยท Format

    ยท CLI ยท LSP ยท Translate
  92. Build ยท Format ยท CLI ยท LSP ยท Translate #

    comment class Foo def bar baz end end
  93. Build ยท Format ยท CLI ยท LSP ยท Translate #

    comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end
  94. Build ยท Format ยท CLI ยท LSP ยท Translate #

    comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ ]
  95. Build ยท Format ยท CLI ยท LSP ยท Translate #

    comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ # comment1, ]
  96. Build ยท Format ยท CLI ยท LSP ยท Translate #

    comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ # comment1, # comment2, ]
  97. Build ยท Format ยท CLI ยท LSP ยท Translate #

    comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ # comment1, # comment2, # comment3, ]
  98. Build ยท Format ยท CLI ยท LSP ยท Translate #

    comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ # comment1, # comment2, # comment3, # comment4, ]
  99. Build ยท Format ยท CLI ยท LSP ยท Translate #

    comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ # comment1, # comment2, # comment3, # comment4, # comment5 ]
  100. Build ยท Format ยท CLI ยท LSP ยท Translate [

    # comment1, # comment2, # comment3, # comment4, # comment5 ] (program (statements ((class (const_ref (const "Foo")) (bodystmt (statements ((void_stmt), (def (ident "bar") (params) (bodystmt (statements ((vcall (ident "baz")))))))))))))
  101. Build ยท Format ยท CLI ยท LSP ยท Translate (program

    (statements ((comment "# comment1"), (class (const_ref (const "Foo") ((comment "# comment2"))) (bodystmt (statements ((void_stmt), (comment "# comment3"), (def (ident "bar") (params ((comment "# comment4"))) (bodystmt (statements ((vcall (ident "baz") ((comment "# comment5"))))))))))))))
  102. Build ยท Format ยท CLI ยท LSP ยท Translate class

    Visitor def visit(node) node&.accept(self) end def visit_child_nodes(node) node.child_nodes.map do |node| visit(node) end end end
  103. Build ยท Format ยท CLI ยท LSP ยท Translate class

    VCall < Node def accept(visitor) visitor.visit_vcall(self) end end class Visitor def visit(node) node&.accept(self) end def visit_child_nodes(node) node.child_nodes.map do |node| visit(node) end end end
  104. Build ยท Format ยท CLI ยท LSP ยท Translate class

    VCall < Node def accept(visitor) visitor.visit_vcall(self) end end # Visit an ARef node. alias visit_aref visit_child_nodes # Visit an ARefField node. alias visit_aref_field visit_child_nodes # Visit an Alias node. alias visit_alias visit_child_nodes # Visit an ArgBlock node. alias visit_arg_block visit_child_nodes # Visit an ArgParen node. alias visit_arg_paren visit_child_nodes # Visit an ArgStar node. alias visit_arg_star visit_child_nodes # Visit an Args node. alias visit_args visit_child_nodes # Visit an ArgsForward node. alias visit_args_forward visit_child_nodes # Visit an ArrayLiteral node. alias visit_array visit_child_nodes # Visit an AryPtn node. alias visit_aryptn visit_child_nodes # Visit an Assign node. alias visit_assign visit_child_nodes # Visit an Assoc node. alias visit_assoc visit_child_nodes # Visit an AssocSplat node. alias visit_assoc_splat visit_child_nodes # Visit a Backref node. alias visit_backref visit_child_nodes class Visitor def visit(node) node&.accept(self) end def visit_child_nodes(node) node.child_nodes.map do |node| visit(node) end end end
  105. Build ยท Format ยท CLI ยท LSP ยท Translate class

    VCall < Node def accept(visitor) visitor.visit_vcall(self) end end alias visit_vcall visit_child_nodes # Visit a VoidStmt node. alias visit_void_stmt visit_child_nodes # Visit a When node. alias visit_when visit_child_nodes # Visit a While node. alias visit_while visit_child_nodes # Visit a WhileMod node. alias visit_while_mod visit_child_nodes # Visit a Word node. alias visit_word visit_child_nodes # Visit a Words node. alias visit_words visit_child_nodes # Visit a WordsBeg node. alias visit_words_beg visit_child_nodes # Visit a XString node. alias visit_xstring visit_child_nodes # Visit a XStringLiteral node. alias visit_xstring_literal visit_child_nodes # Visit a Yield node. alias visit_yield visit_child_nodes # Visit a Yield0 node. alias visit_yield0 visit_child_nodes # Visit a ZSuper node. alias visit_zsuper visit_child_nodes # Visit an EndContent node. alias visit___end__ visit_child_nodes class Visitor def visit(node) node&.accept(self) end def visit_child_nodes(node) node.child_nodes.map do |node| visit(node) end end end
  106. Build ยท Format ยท CLI ยท LSP ยท Translate class

    RegexpVisitor < Visitor def visit_regexp_literal(node) # do something with regexp literal node here node.options # call super to continue walking the tree super end end
  107. Build ยท Format ยท CLI ยท LSP ยท Translate class

    JSONVisitor < Visitor def visit_aref(node) node(node, "aref") do field("collection", node.collection) field("index", node.index) comments(node) end end def visit_aref_field(node) node(node, "aref_field") do field("collection", node.collection) field("index", node.index) comments(node) end end def visit_alias(node) node(node, "alias") do field("left", node.left) field("right", node.right) comments(node) end end
  108. prettyprint Build group, text, breakable to layout content Algorithm Build

    ยท Format ยท CLI ยท LSP ยท Translate
  109. prettyprint Build group, text, breakable to layout content Break outermost

    groups to fit to print width Algorithm Build ยท Format ยท CLI ยท LSP ยท Translate
  110. Build ยท Format ยท CLI ยท LSP ยท Translate [foo1,

    foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2]]
  111. Build ยท Format ยท CLI ยท LSP ยท Translate [foo1,

    foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2]]
  112. Build ยท Format ยท CLI ยท LSP ยท Translate [foo1,

    foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2]]
  113. Build ยท Format ยท CLI ยท LSP ยท Translate [

    foo1, foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2] ]
  114. Build ยท Format ยท CLI ยท LSP ยท Translate [

    foo1, foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2] ]
  115. Build ยท Format ยท CLI ยท LSP ยท Translate [

    foo1, foo2, [ bar1, bar2, bar3, bar4 ], foo3, foo4, [baz1, baz2] ]
  116. breakGroup([group([text(["["]), indent([breakable, text(["foo1", ","]), breakable, text(["foo2", ","]), breakable, group([text(["["]), indent([breakable,

    text(["bar1", ","]), breakable, text(["bar2", ","]), breakable, text(["bar3", ","]), breakable, text(["bar4"])]), breakable, text(["]"])]), text([","]), breakable, text(["foo3", ","]), breakable, text(["foo4", ","]), breakable, ... Build ยท Format ยท CLI ยท LSP ยท Translate
  117. breakGroup([group([text(["["]), indent([breakable, text(["foo1", ","]), breakable, text(["foo2", ","]), breakable, group([text(["["]), indent([breakable,

    text(["bar1", ","]), breakable, text(["bar2", ","]), breakable, text(["bar3", ","]), breakable, text(["bar4"])]), breakable, text(["]"])]), text([","]), breakable, text(["foo3", ","]), breakable, text(["foo4", ","]), breakable, ... Build ยท Format ยท CLI ยท LSP ยท Translate
  118. breakGroup([group([text(["["]), indent([breakable, text(["foo1", ","]), breakable, text(["foo2", ","]), breakable, group([text(["["]), indent([breakable,

    text(["bar1", ","]), breakable, text(["bar2", ","]), breakable, text(["bar3", ","]), breakable, text(["bar4"])]), breakable, text(["]"])]), text([","]), breakable, text(["foo3", ","]), breakable, text(["foo4", ","]), breakable, ... Build ยท Format ยท CLI ยท LSP ยท Translate
  119. breakGroup([group([text(["["]), indent([breakable, text(["foo1", ","]), breakable, text(["foo2", ","]), breakable, group([text(["["]), indent([breakable,

    text(["bar1", ","]), breakable, text(["bar2", ","]), breakable, text(["bar3", ","]), breakable, text(["bar4"])]), breakable, text(["]"])]), text([","]), breakable, text(["foo3", ","]), breakable, text(["foo4", ","]), breakable, ... Build ยท Format ยท CLI ยท LSP ยท Translate
  120. breakGroup([group([text(["["]), indent([breakable, text(["foo1", ","]), breakable, text(["foo2", ","]), breakable, group([text(["["]), indent([breakable,

    text(["bar1", ","]), breakable, text(["bar2", ","]), breakable, text(["bar3", ","]), breakable, text(["bar4"])]), breakable, text(["]"])]), text([","]), breakable, text(["foo3", ","]), breakable, text(["foo4", ","]), breakable, ... Build ยท Format ยท CLI ยท LSP ยท Translate
  121. I made too many additions to prettyprint Build ยท Format

    ยท CLI ยท LSP ยท Translate ๐Ÿ˜…๐Ÿ˜…๐Ÿ˜…
  122. Build ยท Format ยท CLI ยท LSP ยท Translate here_is_a_method_call(1,

    2, <<~HEREDOC this is the content of the heredoc HEREDOC )
  123. Build ยท Format ยท CLI ยท LSP ยท Translate here_is_a_method_call(1,

    2, <<~HEREDOC this is the content of the heredoc HEREDOC )
  124. Build ยท Format ยท CLI ยท LSP ยท Translate here_is_a_method_call(1,

    2, <<~HEREDOC) this is the content of the heredoc HEREDOC
  125. Build ยท Format ยท CLI ยท LSP ยท Translate def

    foo return [1, 2, 3].map { |element| element * 2 } # comment end
  126. Build ยท Format ยท CLI ยท LSP ยท Translate def

    foo return [1, 2, 3].map { |element| element * 2 } # comment end
  127. Build ยท Format ยท CLI ยท LSP ยท Translate def

    foo return( [1, 2, 3].map do |element| element * 2 end ) # comment end
  128. Build ยท Format ยท CLI ยท LSP ยท Translate class

    If < Node def format(q) if node.consequent || node.statements.empty? q.group { format_break(q, force: true) } else q.group do q .if_break { format_break(q, force: false) } .if_flat do Parentheses.flat(q) do q.format(node.statements) q.text(" if ") q.format(node.predicate) end end end end end end
  129. Build ยท Format ยท CLI ยท LSP ยท Translate class

    If < Node def format(q) if node.consequent || node.statements.empty? q.group { format_break(q, force: true) } else q.group do q .if_break { format_break(q, force: false) } .if_flat do Parentheses.flat(q) do q.format(node.statements) q.text(" if ") q.format(node.predicate) end end end end end end
  130. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree check [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Check that the given files are formatted as syntax tree would format them stree debug [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Check that the given files can be formatted idempotently stree doc [--plugins=...] [-e SCRIPT] FILE Print out the doc tree that would be used to format the given files stree expr [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the first expression of the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree json [--plugins=...] [-e SCRIPT] FILE Print out the JSON representation of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files stree version Output the current version of syntax tree stree write [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Read, format, and write back the source of the given files --plugins=... A comma-separated list of plugins to load. --print-width=NUMBER The maximum line width to use when formatting. -e SCRIPT Parse an inline Ruby string.
  131. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files
  132. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files
  133. Build ยท Format ยท CLI ยท LSP ยท Translate $

    stree ast -e '1+2' (program (statements ((binary (int "1") + (int "2")))))
  134. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files
  135. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files
  136. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files
  137. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files
  138. Build ยท Format ยท CLI ยท LSP ยท Translate $

    stree match -e '1+2' SyntaxTree::Program[ statements: SyntaxTree::Statements[ body: [ SyntaxTree::Binary[ left: SyntaxTree::Int[value: "1"], operator: :+, right: SyntaxTree::Int[value: "2"] ] ] ] ]
  139. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files
  140. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files
  141. Build ยท Format ยท CLI ยท LSP ยท Translate $

    stree search Int -e '1+2' script:1:0: 1+2 script:1:2: 1+2
  142. Build ยท Format ยท CLI ยท LSP ยท Translate $

    stree search 'Int[value: "2"]' -e '1+2'
  143. Build ยท Format ยท CLI ยท LSP ยท Translate $

    stree search 'Int[value: "2"]' -e '1+2' โ€จ โ€จ script:1:2: 1+2
  144. Build ยท Format ยท CLI ยท LSP ยท Translate $

    stree search <(stree match -e '1+2') \ โ€จ -e '1+2'
  145. Build ยท Format ยท CLI ยท LSP ยท Translate $

    stree search <(stree match -e '1+2') \ โ€จ -e '1+2' โ€จ โ€จ script:1:0: 1+2
  146. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files stree write [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Read, format, and write back the source of the given files
  147. Build ยท Format ยท CLI ยท LSP ยท Translate stree

    ast [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the AST corresponding to the given files stree format [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Print out the formatted version of the given files stree match [--plugins=...] [-e SCRIPT] FILE Print out a pattern-matching Ruby expression that would match the given files stree lsp [--plugins=...] [--print-width=NUMBER] Run syntax tree in language server mode stree search PATTERN [-e SCRIPT] FILE Search for the given pattern in the given files stree write [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE Read, format, and write back the source of the given files
  148. Language server protocol Runs a JSON RPC server behind an

    editor Build ยท Format ยท CLI ยท LSP ยท Translate
  149. Language server protocol Runs a JSON RPC server behind an

    editor textDocument/didChange textDocument/didOpen textDocument/didClose Build ยท Format ยท CLI ยท LSP ยท Translate
  150. Language server protocol Runs a JSON RPC server behind an

    editor textDocument/didChange textDocument/didOpen textDocument/didClose textDocument/formatting Build ยท Format ยท CLI ยท LSP ยท Translate
  151. Language server protocol Runs a JSON RPC server behind an

    editor textDocument/didChange textDocument/didOpen textDocument/didClose textDocument/formatting textDocument/inlayHint Build ยท Format ยท CLI ยท LSP ยท Translate
  152. Shopify/ruby-lsp Document highlight Document symbols Folding ranges Formatting Selection ranges

    Semantic highlighting Build ยท Format ยท CLI ยท LSP ยท Translate
  153. Build ยท Format ยท CLI ยท LSP ยท Translate class

    RubyParserVisitor < Visitor def visit_binary(node) left = visit(node.left) right = visit(node.right) case node in { operator: :and } s(:and, left, right) in { operator: :!~ } s(:not, s(:call, left, :=~, right)) else s(:call, left, node.operator, right) end end # ... end
  154. Build ยท Format ยท CLI ยท LSP ยท Translate class

    ParserVisitor < Visitor def visit_binary(node) left = visit(node.left) right = visit(node.right) case node in { operator: :and } s(:and, [left, right]) in { operator: :or } s(:or, [left, right]) else s(:send, [left, node.operator, right]) end end # ... end
  155. Build ยท Format ยท CLI ยท LSP ยท Translate class

    YARVVisitor < Visitor def visit_binary(node) case node.operator when :"&&" # ... when :"||" # ... else visit(node.left) visit(node.right) builder.send( node.operator, 1, VM_CALL_ARGS_SIMPLE ) end end # ... end
  156. Build ยท Format ยท CLI ยท LSP ยท Translate class

    MutationVisitor < Visitor def visit_binary(node) node.copy( left: visit(node.left), right: visit(node.right) ) end end
  157. Build ยท Format ยท CLI ยท LSP ยท Translate mutator

    = SyntaxTree.mutation do |mutator| query = <<~RUBY IfNode[predicate: Assign | OpAssign] | UnlessNode[predicate: Assign | OpAssign] RUBY mutator.mutate(query) do |node| node.copy(predicate: SyntaxTree::Paren.new( lparen: SyntaxTree::LParen.default, contents: node.predicate, location: node.predicate.location )) end end mutated = node.accept(mutator)
  158. Syntax Tree Build a syntax tree Format the syntax tree

    Create a CLI Create a language server (LSP)
  159. Syntax Tree Build a syntax tree Format the syntax tree

    Create a CLI Create a language server (LSP) Translate the syntax tree