Slide 1

Slide 1 text

Syntax Tree

Slide 2

Slide 2 text

Kevin Newton @kddnewton

Slide 3

Slide 3 text

Syntax Tree

Slide 4

Slide 4 text

Build a syntax tree Syntax Tree

Slide 5

Slide 5 text

Build a syntax tree Format the syntax tree Syntax Tree

Slide 6

Slide 6 text

Build a syntax tree Format the syntax tree Create a CLI Syntax Tree

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Build · Format · CLI · LSP · Translate Syntax Tree

Slide 10

Slide 10 text

Build a syntax tree Build · Format · CLI · LSP · Translate

Slide 11

Slide 11 text

Define each node Build · Format · CLI · LSP · Translate

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

Define each node Build · Format · CLI · LSP · Translate

Slide 19

Slide 19 text

Ripper::EVENTS.count # => 190 Define each node Build · Format · CLI · LSP · Translate

Slide 20

Slide 20 text

Ripper::EVENTS.count # => 190 SyntaxTree::Node.descendants.count 
 # => 162 Define each node Build · Format · CLI · LSP · Translate

Slide 21

Slide 21 text

Ripper::EVENTS.count # => 190 SyntaxTree::Node.descendants.count 
 # => 162 qwords_new/qwords_add -> SyntaxTree::QWords Define each node Build · Format · CLI · LSP · Translate

Slide 22

Slide 22 text

How we use ripper Build · Format · CLI · LSP · Translate

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

class Foo def bar baz end end Build · Format · CLI · LSP · Translate

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

Build · Format · CLI · LSP · Translate -> (positional; local1, local2) {}

Slide 38

Slide 38 text

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 )

Slide 39

Slide 39 text

class Foo def bar baz end end Build · Format · CLI · LSP · Translate

Slide 40

Slide 40 text

Build · Format · CLI · LSP · Translate class Foo # comment def bar baz end end

Slide 41

Slide 41 text

Build · Format · CLI · LSP · Translate class Foo def bar # comment baz end end

Slide 42

Slide 42 text

Build · Format · CLI · LSP · Translate class Foo def bar baz # comment end end

Slide 43

Slide 43 text

Build · Format · CLI · LSP · Translate # comment class Foo def bar baz end end

Slide 44

Slide 44 text

Build · Format · CLI · LSP · Translate class Foo # comment def bar baz end end

Slide 45

Slide 45 text

Build · Format · CLI · LSP · Translate # comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end

Slide 46

Slide 46 text

Build · Format · CLI · LSP · Translate # comment1 class Foo # comment2 # comment3 def bar # comment4 baz # comment5 end end [ ]

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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")))))))))))))

Slide 53

Slide 53 text

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"))))))))))))))

Slide 54

Slide 54 text

Walking the tree Build · Format · CLI · LSP · Translate

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

Format the syntax tree Build · Format · CLI · LSP · Translate

Slide 62

Slide 62 text

Algorithm Build · Format · CLI · LSP · Translate

Slide 63

Slide 63 text

prettyprint Algorithm Build · Format · CLI · LSP · Translate

Slide 64

Slide 64 text

prettyprint Build group, text, breakable to layout content Algorithm Build · Format · CLI · LSP · Translate

Slide 65

Slide 65 text

prettyprint Build group, text, breakable to layout content Break outermost groups to fit to print width Algorithm Build · Format · CLI · LSP · Translate

Slide 66

Slide 66 text

Build · Format · CLI · LSP · Translate [foo1, foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2]]

Slide 67

Slide 67 text

Build · Format · CLI · LSP · Translate [foo1, foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2]]

Slide 68

Slide 68 text

Build · Format · CLI · LSP · Translate [foo1, foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2]]

Slide 69

Slide 69 text

Build · Format · CLI · LSP · Translate [ foo1, foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2] ]

Slide 70

Slide 70 text

Build · Format · CLI · LSP · Translate [ foo1, foo2, [bar1, bar2, bar3, bar4], foo3, foo4, [baz1, baz2] ]

Slide 71

Slide 71 text

Build · Format · CLI · LSP · Translate [ foo1, foo2, [ bar1, bar2, bar3, bar4 ], foo3, foo4, [baz1, baz2] ]

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

I made too many additions to prettyprint Build · Format · CLI · LSP · Translate 😅😅😅

Slide 78

Slide 78 text

prettyprint Build · Format · CLI · LSP · Translate

Slide 79

Slide 79 text

prettier_print Build · Format · CLI · LSP · Translate

Slide 80

Slide 80 text

Build · Format · CLI · LSP · Translate if foo bar += baz end

Slide 81

Slide 81 text

Build · Format · CLI · LSP · Translate if foo bar += baz end

Slide 82

Slide 82 text

Build · Format · CLI · LSP · Translate bar += baz if foo

Slide 83

Slide 83 text

Build · Format · CLI · LSP · Translate if foo bar else baz end

Slide 84

Slide 84 text

Build · Format · CLI · LSP · Translate if foo bar else baz end

Slide 85

Slide 85 text

Build · Format · CLI · LSP · Translate foo ? bar : baz

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

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

Slide 90

Slide 90 text

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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

Create a CLI Build · Format · CLI · LSP · Translate

Slide 95

Slide 95 text

Build · Format · CLI · LSP · Translate stree ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files

Slide 96

Slide 96 text

Build · Format · CLI · LSP · Translate stree ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files

Slide 97

Slide 97 text

Build · Format · CLI · LSP · Translate stree ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files

Slide 98

Slide 98 text

Build · Format · CLI · LSP · Translate stree ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files

Slide 99

Slide 99 text

Build · Format · CLI · LSP · Translate stree ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files

Slide 100

Slide 100 text

Plugins Build · Format · CLI · LSP · Translate

Slide 101

Slide 101 text

Formatting plugins Build · Format · CLI · LSP · Translate

Slide 102

Slide 102 text

Single quotes Formatting plugins Build · Format · CLI · LSP · Translate

Slide 103

Slide 103 text

Single quotes Trailing commas Formatting plugins Build · Format · CLI · LSP · Translate

Slide 104

Slide 104 text

Language plugins Build · Format · CLI · LSP · Translate

Slide 105

Slide 105 text

Language plugins Build · Format · CLI · LSP · Translate rbs

Slide 106

Slide 106 text

Language plugins Build · Format · CLI · LSP · Translate rbs haml

Slide 107

Slide 107 text

Language plugins Build · Format · CLI · LSP · Translate rbs haml json

Slide 108

Slide 108 text

Language plugins Build · Format · CLI · LSP · Translate rbs haml json xml

Slide 109

Slide 109 text

Language plugins Build · Format · CLI · LSP · Translate rbs haml json xml css

Slide 110

Slide 110 text

Build · Format · CLI · LSP · Translate stree ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files

Slide 111

Slide 111 text

Build · Format · CLI · LSP · Translate stree ast [OPTIONS] [FILE] Print out the AST corresponding to the given files stree check [OPTIONS] [FILE] Check that the given files are formatted as syntax tree would format them stree debug [OPTIONS] [FILE] Check that the given files can be formatted idempotently stree doc [OPTIONS] [FILE] Print out the doc tree that would be used to format the given files stree format [OPTIONS] [FILE] Print out the formatted version of the given files stree json [OPTIONS] [FILE] Print out the JSON representation of the given files stree match [OPTIONS] [FILE] Print out a pattern-matching Ruby expression that would match the given files stree help Display this help message stree lsp Run syntax tree in language server mode stree version Output the current version of syntax tree stree write [OPTIONS] [FILE] Read, format, and write back the source of the given files

Slide 112

Slide 112 text

Create a language server Build · Format · CLI · LSP · Translate

Slide 113

Slide 113 text

Language server protocol Build · Format · CLI · LSP · Translate

Slide 114

Slide 114 text

Language server protocol Runs a JSON RPC server behind an editor Build · Format · CLI · LSP · Translate

Slide 115

Slide 115 text

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

Slide 116

Slide 116 text

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

Slide 117

Slide 117 text

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

Slide 118

Slide 118 text

Build · Format · CLI · LSP · Translate

Slide 119

Slide 119 text

Shopify/ruby-lsp Build · Format · CLI · LSP · Translate

Slide 120

Slide 120 text

Shopify/ruby-lsp Document highlight Build · Format · CLI · LSP · Translate

Slide 121

Slide 121 text

Shopify/ruby-lsp Document highlight Document symbols Build · Format · CLI · LSP · Translate

Slide 122

Slide 122 text

Shopify/ruby-lsp Document highlight Document symbols Folding ranges Build · Format · CLI · LSP · Translate

Slide 123

Slide 123 text

Shopify/ruby-lsp Document highlight Document symbols Folding ranges Formatting Build · Format · CLI · LSP · Translate

Slide 124

Slide 124 text

Shopify/ruby-lsp Document highlight Document symbols Folding ranges Formatting Selection ranges Build · Format · CLI · LSP · Translate

Slide 125

Slide 125 text

Shopify/ruby-lsp Document highlight Document symbols Folding ranges Formatting Selection ranges Semantic highlighting Build · Format · CLI · LSP · Translate

Slide 126

Slide 126 text

Translate the syntax tree Build · Format · CLI · LSP · Translate

Slide 127

Slide 127 text

Translate the syntax tree Build · Format · CLI · LSP · Translate

Slide 128

Slide 128 text

Translate the syntax tree seattlerb/ruby_parser Build · Format · CLI · LSP · Translate

Slide 129

Slide 129 text

Translate the syntax tree seattlerb/ruby_parser whitequark/parser Build · Format · CLI · LSP · Translate

Slide 130

Slide 130 text

Translate the syntax tree seattlerb/ruby_parser whitequark/parser rubocop/rubocop-ast Build · Format · CLI · LSP · Translate

Slide 131

Slide 131 text

Translate the syntax tree seattlerb/ruby_parser whitequark/parser rubocop/rubocop-ast ruby-syntax-tree/ 
 syntax_tree-translator Build · Format · CLI · LSP · Translate

Slide 132

Slide 132 text

Thank you!

Slide 133

Slide 133 text

Syntax Tree github.com/ruby-syntax-tree Kevin Newton @kddnewton