ruby-lsp 0.0.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +6 -0
  3. data/.rubocop.yml +25 -0
  4. data/CHANGELOG.md +35 -0
  5. data/Gemfile +10 -6
  6. data/Gemfile.lock +63 -16
  7. data/README.md +41 -0
  8. data/Rakefile +8 -1
  9. data/VERSION +1 -1
  10. data/bin/console +19 -0
  11. data/bin/tapioca +29 -0
  12. data/dev.yml +3 -0
  13. data/exe/ruby-lsp +19 -4
  14. data/lib/ruby-lsp.rb +2 -1
  15. data/lib/ruby_lsp/cli.rb +13 -5
  16. data/lib/ruby_lsp/document.rb +43 -14
  17. data/lib/ruby_lsp/handler.rb +107 -37
  18. data/lib/ruby_lsp/internal.rb +7 -0
  19. data/lib/ruby_lsp/requests/base_request.rb +18 -5
  20. data/lib/ruby_lsp/requests/code_actions.rb +20 -8
  21. data/lib/ruby_lsp/requests/diagnostics.rb +25 -7
  22. data/lib/ruby_lsp/requests/document_highlight.rb +113 -0
  23. data/lib/ruby_lsp/requests/document_symbol.rb +56 -16
  24. data/lib/ruby_lsp/requests/folding_ranges.rb +70 -34
  25. data/lib/ruby_lsp/requests/formatting.rb +24 -14
  26. data/lib/ruby_lsp/requests/selection_ranges.rb +18 -4
  27. data/lib/ruby_lsp/requests/semantic_highlighting.rb +187 -34
  28. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +16 -3
  29. data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +61 -0
  30. data/lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb +50 -0
  31. data/lib/ruby_lsp/requests/support/selection_range.rb +4 -0
  32. data/lib/ruby_lsp/requests/support/semantic_token_encoder.rb +24 -3
  33. data/lib/ruby_lsp/requests/support/syntax_error_diagnostic.rb +6 -0
  34. data/lib/ruby_lsp/requests.rb +13 -1
  35. data/lib/ruby_lsp/store.rb +20 -3
  36. data/rakelib/check_docs.rake +34 -6
  37. data/ruby-lsp.gemspec +7 -5
  38. data/sorbet/config +4 -0
  39. data/sorbet/rbi/.rubocop.yml +8 -0
  40. data/sorbet/rbi/gems/ansi@1.5.0.rbi +338 -0
  41. data/sorbet/rbi/gems/ast@2.4.2.rbi +522 -0
  42. data/sorbet/rbi/gems/builder@3.2.4.rbi +418 -0
  43. data/sorbet/rbi/gems/coderay@1.1.3.rbi +8 -0
  44. data/sorbet/rbi/gems/debug@1.5.0.rbi +1273 -0
  45. data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +867 -0
  46. data/sorbet/rbi/gems/io-console@0.5.11.rbi +8 -0
  47. data/sorbet/rbi/gems/irb@1.4.1.rbi +376 -0
  48. data/sorbet/rbi/gems/language_server-protocol@3.16.0.3.rbi +7325 -0
  49. data/sorbet/rbi/gems/method_source@1.0.0.rbi +8 -0
  50. data/sorbet/rbi/gems/minitest-reporters@1.5.0.rbi +612 -0
  51. data/sorbet/rbi/gems/minitest@5.15.0.rbi +994 -0
  52. data/sorbet/rbi/gems/parallel@1.22.1.rbi +163 -0
  53. data/sorbet/rbi/gems/parser@3.1.2.0.rbi +3968 -0
  54. data/sorbet/rbi/gems/prettier_print@0.1.0.rbi +734 -0
  55. data/sorbet/rbi/gems/pry@0.14.1.rbi +8 -0
  56. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +227 -0
  57. data/sorbet/rbi/gems/rake@13.0.6.rbi +1853 -0
  58. data/sorbet/rbi/gems/rbi@0.0.14.rbi +2337 -0
  59. data/sorbet/rbi/gems/regexp_parser@2.5.0.rbi +1854 -0
  60. data/sorbet/rbi/gems/reline@0.3.1.rbi +1274 -0
  61. data/sorbet/rbi/gems/rexml@3.2.5.rbi +3852 -0
  62. data/sorbet/rbi/gems/rubocop-ast@1.18.0.rbi +4180 -0
  63. data/sorbet/rbi/gems/rubocop-minitest@0.20.0.rbi +1369 -0
  64. data/sorbet/rbi/gems/rubocop-rake@0.6.0.rbi +246 -0
  65. data/sorbet/rbi/gems/rubocop-shopify@2.6.0.rbi +8 -0
  66. data/sorbet/rbi/gems/rubocop-sorbet@0.6.8.rbi +652 -0
  67. data/sorbet/rbi/gems/rubocop@1.30.0.rbi +36729 -0
  68. data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +732 -0
  69. data/sorbet/rbi/gems/spoom@1.1.11.rbi +1600 -0
  70. data/sorbet/rbi/gems/syntax_tree@2.7.1.rbi +6777 -0
  71. data/sorbet/rbi/gems/tapioca@0.8.1.rbi +1972 -0
  72. data/sorbet/rbi/gems/thor@1.2.1.rbi +2921 -0
  73. data/sorbet/rbi/gems/unicode-display_width@2.1.0.rbi +27 -0
  74. data/sorbet/rbi/gems/unparser@0.6.5.rbi +2789 -0
  75. data/sorbet/rbi/gems/webrick@1.7.0.rbi +1779 -0
  76. data/sorbet/rbi/gems/yard-sorbet@0.6.1.rbi +289 -0
  77. data/sorbet/rbi/gems/yard@0.9.27.rbi +13048 -0
  78. data/sorbet/rbi/shims/fiddle.rbi +4 -0
  79. data/sorbet/rbi/shims/hash.rbi +6 -0
  80. data/sorbet/rbi/shims/rdoc.rbi +4 -0
  81. data/sorbet/tapioca/config.yml +13 -0
  82. data/sorbet/tapioca/require.rb +7 -0
  83. metadata +62 -13
  84. data/lib/ruby_lsp/requests/rubocop_request.rb +0 -49
  85. data/shipit.production.yml +0 -1
@@ -0,0 +1,522 @@
1
+ # typed: true
2
+
3
+ # DO NOT EDIT MANUALLY
4
+ # This is an autogenerated file for types exported from the `ast` gem.
5
+ # Please instead update this file by running `bin/tapioca gem ast`.
6
+
7
+ # {AST} is a library for manipulating abstract syntax trees.
8
+ #
9
+ # It embraces immutability; each AST node is inherently frozen at
10
+ # creation, and updating a child node requires recreating that node
11
+ # and its every parent, recursively.
12
+ # This is a design choice. It does create some pressure on
13
+ # garbage collector, but completely eliminates all concurrency
14
+ # and aliasing problems.
15
+ #
16
+ # See also {AST::Node}, {AST::Processor::Mixin} and {AST::Sexp} for
17
+ # additional recommendations and design patterns.
18
+ module AST; end
19
+
20
+ # Node is an immutable class, instances of which represent abstract
21
+ # syntax tree nodes. It combines semantic information (i.e. anything
22
+ # that affects the algorithmic properties of a program) with
23
+ # meta-information (line numbers or compiler intermediates).
24
+ #
25
+ # Notes on inheritance
26
+ # ====================
27
+ #
28
+ # The distinction between semantics and metadata is important. Complete
29
+ # semantic information should be contained within just the {#type} and
30
+ # {#children} of a Node instance; in other words, if an AST was to be
31
+ # stripped of all meta-information, it should remain a valid AST which
32
+ # could be successfully processed to yield a result with the same
33
+ # algorithmic properties.
34
+ #
35
+ # Thus, Node should never be inherited in order to define methods which
36
+ # affect or return semantic information, such as getters for `class_name`,
37
+ # `superclass` and `body` in the case of a hypothetical `ClassNode`. The
38
+ # correct solution is to use a generic Node with a {#type} of `:class`
39
+ # and three children. See also {Processor} for tips on working with such
40
+ # ASTs.
41
+ #
42
+ # On the other hand, Node can and should be inherited to define
43
+ # application-specific metadata (see also {#initialize}) or customize the
44
+ # printing format. It is expected that an application would have one or two
45
+ # such classes and use them across the entire codebase.
46
+ #
47
+ # The rationale for this pattern is extensibility and maintainability.
48
+ # Unlike static ones, dynamic languages do not require the presence of a
49
+ # predefined, rigid structure, nor does it improve dispatch efficiency,
50
+ # and while such a structure can certainly be defined, it does not add
51
+ # any value but incurs a maintaining cost.
52
+ # For example, extending the AST even with a transformation-local
53
+ # temporary node type requires making globally visible changes to
54
+ # the codebase.
55
+ class AST::Node
56
+ # Constructs a new instance of Node.
57
+ #
58
+ # The arguments `type` and `children` are converted with `to_sym` and
59
+ # `to_a` respectively. Additionally, the result of converting `children`
60
+ # is frozen. While mutating the arguments is generally considered harmful,
61
+ # the most common case is to pass an array literal to the constructor. If
62
+ # your code does not expect the argument to be frozen, use `#dup`.
63
+ #
64
+ # The `properties` hash is passed to {#assign_properties}.
65
+ #
66
+ # @return [Node] a new instance of Node
67
+ def initialize(type, children = T.unsafe(nil), properties = T.unsafe(nil)); end
68
+
69
+ # Concatenates `array` with `children` and returns the resulting node.
70
+ #
71
+ # @return [AST::Node]
72
+ def +(array); end
73
+
74
+ # Appends `element` to `children` and returns the resulting node.
75
+ #
76
+ # @return [AST::Node]
77
+ def <<(element); end
78
+
79
+ # Compares `self` to `other`, possibly converting with `to_ast`. Only
80
+ # `type` and `children` are compared; metadata is deliberately ignored.
81
+ #
82
+ # @return [Boolean]
83
+ def ==(other); end
84
+
85
+ # Appends `element` to `children` and returns the resulting node.
86
+ #
87
+ # @return [AST::Node]
88
+ def append(element); end
89
+
90
+ # Returns the children of this node.
91
+ # The returned value is frozen.
92
+ # The to_a alias is useful for decomposing nodes concisely.
93
+ # For example:
94
+ #
95
+ # node = s(:gasgn, :$foo, s(:integer, 1))
96
+ # var_name, value = *node
97
+ # p var_name # => :$foo
98
+ # p value # => (integer 1)
99
+ #
100
+ # @return [Array]
101
+ def children; end
102
+
103
+ # Nodes are already frozen, so there is no harm in returning the
104
+ # current node as opposed to initializing from scratch and freezing
105
+ # another one.
106
+ #
107
+ # @return self
108
+ def clone; end
109
+
110
+ # Concatenates `array` with `children` and returns the resulting node.
111
+ #
112
+ # @return [AST::Node]
113
+ def concat(array); end
114
+
115
+ # Enables matching for Node, where type is the first element
116
+ # and the children are remaining items.
117
+ #
118
+ # @return [Array]
119
+ def deconstruct; end
120
+
121
+ # Nodes are already frozen, so there is no harm in returning the
122
+ # current node as opposed to initializing from scratch and freezing
123
+ # another one.
124
+ #
125
+ # @return self
126
+ def dup; end
127
+
128
+ # Test if other object is equal to
129
+ #
130
+ # @param other [Object]
131
+ # @return [Boolean]
132
+ def eql?(other); end
133
+
134
+ # Returns the precomputed hash value for this node
135
+ #
136
+ # @return [Fixnum]
137
+ def hash; end
138
+
139
+ # Converts `self` to a s-expression ruby string.
140
+ # The code return will recreate the node, using the sexp module s()
141
+ #
142
+ # @param indent [Integer] Base indentation level.
143
+ # @return [String]
144
+ def inspect(indent = T.unsafe(nil)); end
145
+
146
+ # Returns the children of this node.
147
+ # The returned value is frozen.
148
+ # The to_a alias is useful for decomposing nodes concisely.
149
+ # For example:
150
+ #
151
+ # node = s(:gasgn, :$foo, s(:integer, 1))
152
+ # var_name, value = *node
153
+ # p var_name # => :$foo
154
+ # p value # => (integer 1)
155
+ #
156
+ # @return [Array]
157
+ def to_a; end
158
+
159
+ # @return [AST::Node] self
160
+ def to_ast; end
161
+
162
+ # Converts `self` to a pretty-printed s-expression.
163
+ #
164
+ # @param indent [Integer] Base indentation level.
165
+ # @return [String]
166
+ def to_s(indent = T.unsafe(nil)); end
167
+
168
+ # Converts `self` to a pretty-printed s-expression.
169
+ #
170
+ # @param indent [Integer] Base indentation level.
171
+ # @return [String]
172
+ def to_sexp(indent = T.unsafe(nil)); end
173
+
174
+ # Converts `self` to an Array where the first element is the type as a Symbol,
175
+ # and subsequent elements are the same representation of its children.
176
+ #
177
+ # @return [Array<Symbol, [...Array]>]
178
+ def to_sexp_array; end
179
+
180
+ # Returns the type of this node.
181
+ #
182
+ # @return [Symbol]
183
+ def type; end
184
+
185
+ # Returns a new instance of Node where non-nil arguments replace the
186
+ # corresponding fields of `self`.
187
+ #
188
+ # For example, `Node.new(:foo, [ 1, 2 ]).updated(:bar)` would yield
189
+ # `(bar 1 2)`, and `Node.new(:foo, [ 1, 2 ]).updated(nil, [])` would
190
+ # yield `(foo)`.
191
+ #
192
+ # If the resulting node would be identical to `self`, does nothing.
193
+ #
194
+ # @param type [Symbol, nil]
195
+ # @param children [Array, nil]
196
+ # @param properties [Hash, nil]
197
+ # @return [AST::Node]
198
+ def updated(type = T.unsafe(nil), children = T.unsafe(nil), properties = T.unsafe(nil)); end
199
+
200
+ protected
201
+
202
+ # By default, each entry in the `properties` hash is assigned to
203
+ # an instance variable in this instance of Node. A subclass should define
204
+ # attribute readers for such variables. The values passed in the hash
205
+ # are not frozen or whitelisted; such behavior can also be implemented
206
+ # by subclassing Node and overriding this method.
207
+ #
208
+ # @return [nil]
209
+ def assign_properties(properties); end
210
+
211
+ # Returns `@type` with all underscores replaced by dashes. This allows
212
+ # to write symbol literals without quotes in Ruby sources and yet have
213
+ # nicely looking s-expressions.
214
+ #
215
+ # @return [String]
216
+ def fancy_type; end
217
+
218
+ private
219
+
220
+ def original_dup; end
221
+ end
222
+
223
+ # This class includes {AST::Processor::Mixin}; however, it is
224
+ # deprecated, since the module defines all of the behaviors that
225
+ # the processor includes. Any new libraries should use
226
+ # {AST::Processor::Mixin} instead of subclassing this.
227
+ #
228
+ # @deprecated Use {AST::Processor::Mixin} instead.
229
+ class AST::Processor
230
+ include ::AST::Processor::Mixin
231
+ end
232
+
233
+ # The processor module is a module which helps transforming one
234
+ # AST into another. In a nutshell, the {#process} method accepts
235
+ # a {Node} and dispatches it to a handler corresponding to its
236
+ # type, and returns a (possibly) updated variant of the node.
237
+ #
238
+ # The processor module has a set of associated design patterns.
239
+ # They are best explained with a concrete example. Let's define a
240
+ # simple arithmetic language and an AST format for it:
241
+ #
242
+ # Terminals (AST nodes which do not have other AST nodes inside):
243
+ #
244
+ # * `(integer <int-literal>)`,
245
+ #
246
+ # Nonterminals (AST nodes with other nodes as children):
247
+ #
248
+ # * `(add <node> <node>)`,
249
+ # * `(multiply <node> <node>)`,
250
+ # * `(divide <node> <node>)`,
251
+ # * `(negate <node>)`,
252
+ # * `(store <node> <string-literal>)`: stores value of `<node>`
253
+ # into a variable named `<string-literal>`,
254
+ # * `(load <string-literal>)`: loads value of a variable named
255
+ # `<string-literal>`,
256
+ # * `(each <node> ...)`: computes each of the `<node>`s and
257
+ # prints the result.
258
+ #
259
+ # All AST nodes have the same Ruby class, and therefore they don't
260
+ # know how to traverse themselves. (A solution which dynamically
261
+ # checks the type of children is possible, but is slow and
262
+ # error-prone.) So, a class including the module which knows how
263
+ # to traverse the entire tree should be defined. Such classes
264
+ # have a handler for each nonterminal node which recursively
265
+ # processes children nodes:
266
+ #
267
+ # require 'ast'
268
+ #
269
+ # class ArithmeticsProcessor
270
+ # include AST::Processor::Mixin
271
+ # # This method traverses any binary operators such as (add)
272
+ # # or (multiply).
273
+ # def process_binary_op(node)
274
+ # # Children aren't decomposed automatically; it is
275
+ # # suggested to use Ruby multiple assignment expansion,
276
+ # # as it is very convenient here.
277
+ # left_expr, right_expr = *node
278
+ #
279
+ # # AST::Node#updated won't change node type if nil is
280
+ # # passed as a first argument, which allows to reuse the
281
+ # # same handler for multiple node types using `alias'
282
+ # # (below).
283
+ # node.updated(nil, [
284
+ # process(left_expr),
285
+ # process(right_expr)
286
+ # ])
287
+ # end
288
+ # alias_method :on_add, :process_binary_op
289
+ # alias_method :on_multiply, :process_binary_op
290
+ # alias_method :on_divide, :process_binary_op
291
+ #
292
+ # def on_negate(node)
293
+ # # It is also possible to use #process_all for more
294
+ # # compact code if every child is a Node.
295
+ # node.updated(nil, process_all(node))
296
+ # end
297
+ #
298
+ # def on_store(node)
299
+ # expr, variable_name = *node
300
+ #
301
+ # # Note that variable_name is not a Node and thus isn't
302
+ # # passed to #process.
303
+ # node.updated(nil, [
304
+ # process(expr),
305
+ # variable_name
306
+ # ])
307
+ # end
308
+ #
309
+ # # (load) is effectively a terminal node, and so it does
310
+ # # not need an explicit handler, as the following is the
311
+ # # default behavior. Essentially, for any nodes that don't
312
+ # # have a defined handler, the node remains unchanged.
313
+ # def on_load(node)
314
+ # nil
315
+ # end
316
+ #
317
+ # def on_each(node)
318
+ # node.updated(nil, process_all(node))
319
+ # end
320
+ # end
321
+ #
322
+ # Let's test our ArithmeticsProcessor:
323
+ #
324
+ # include AST::Sexp
325
+ # expr = s(:add, s(:integer, 2), s(:integer, 2))
326
+ #
327
+ # p ArithmeticsProcessor.new.process(expr) == expr # => true
328
+ #
329
+ # As expected, it does not change anything at all. This isn't
330
+ # actually very useful, so let's now define a Calculator, which
331
+ # will compute the expression values:
332
+ #
333
+ # # This Processor folds nonterminal nodes and returns an
334
+ # # (integer) terminal node.
335
+ # class ArithmeticsCalculator < ArithmeticsProcessor
336
+ # def compute_op(node)
337
+ # # First, node children are processed and then unpacked
338
+ # # to local variables.
339
+ # nodes = process_all(node)
340
+ #
341
+ # if nodes.all? { |node| node.type == :integer }
342
+ # # If each of those nodes represents a literal, we can
343
+ # # fold this node!
344
+ # values = nodes.map { |node| node.children.first }
345
+ # AST::Node.new(:integer, [
346
+ # yield(values)
347
+ # ])
348
+ # else
349
+ # # Otherwise, we can just leave the current node in the
350
+ # # tree and only update it with processed children
351
+ # # nodes, which can be partially folded.
352
+ # node.updated(nil, nodes)
353
+ # end
354
+ # end
355
+ #
356
+ # def on_add(node)
357
+ # compute_op(node) { |left, right| left + right }
358
+ # end
359
+ #
360
+ # def on_multiply(node)
361
+ # compute_op(node) { |left, right| left * right }
362
+ # end
363
+ # end
364
+ #
365
+ # Let's check:
366
+ #
367
+ # p ArithmeticsCalculator.new.process(expr) # => (integer 4)
368
+ #
369
+ # Excellent, the calculator works! Now, a careful reader could
370
+ # notice that the ArithmeticsCalculator does not know how to
371
+ # divide numbers. What if we pass an expression with division to
372
+ # it?
373
+ #
374
+ # expr_with_division = \
375
+ # s(:add,
376
+ # s(:integer, 1),
377
+ # s(:divide,
378
+ # s(:add, s(:integer, 8), s(:integer, 4)),
379
+ # s(:integer, 3))) # 1 + (8 + 4) / 3
380
+ #
381
+ # folded_expr_with_division = ArithmeticsCalculator.new.process(expr_with_division)
382
+ # p folded_expr_with_division
383
+ # # => (add
384
+ # # (integer 1)
385
+ # # (divide
386
+ # # (integer 12)
387
+ # # (integer 3)))
388
+ #
389
+ # As you can see, the expression was folded _partially_: the inner
390
+ # `(add)` node which could be computed was folded to
391
+ # `(integer 12)`, the `(divide)` node is left as-is because there
392
+ # is no computing handler for it, and the root `(add)` node was
393
+ # also left as it is because some of its children were not
394
+ # literals.
395
+ #
396
+ # Note that this partial folding is only possible because the
397
+ # _data_ format, i.e. the format in which the computed values of
398
+ # the nodes are represented, is the same as the AST itself.
399
+ #
400
+ # Let's extend our ArithmeticsCalculator class further.
401
+ #
402
+ # class ArithmeticsCalculator
403
+ # def on_divide(node)
404
+ # compute_op(node) { |left, right| left / right }
405
+ # end
406
+ #
407
+ # def on_negate(node)
408
+ # # Note how #compute_op works regardless of the operator
409
+ # # arity.
410
+ # compute_op(node) { |value| -value }
411
+ # end
412
+ # end
413
+ #
414
+ # Now, let's apply our renewed ArithmeticsCalculator to a partial
415
+ # result of previous evaluation:
416
+ #
417
+ # p ArithmeticsCalculator.new.process(expr_with_division) # => (integer 5)
418
+ #
419
+ # Five! Excellent. This is also pretty much how CRuby 1.8 executed
420
+ # its programs.
421
+ #
422
+ # Now, let's do some automated bug searching. Division by zero is
423
+ # an error, right? So if we could detect that someone has divided
424
+ # by zero before the program is even run, that could save some
425
+ # debugging time.
426
+ #
427
+ # class DivisionByZeroVerifier < ArithmeticsProcessor
428
+ # class VerificationFailure < Exception; end
429
+ #
430
+ # def on_divide(node)
431
+ # # You need to process the children to handle nested divisions
432
+ # # such as:
433
+ # # (divide
434
+ # # (integer 1)
435
+ # # (divide (integer 1) (integer 0))
436
+ # left, right = process_all(node)
437
+ #
438
+ # if right.type == :integer &&
439
+ # right.children.first == 0
440
+ # raise VerificationFailure, "Ouch! This code divides by zero."
441
+ # end
442
+ # end
443
+ #
444
+ # def divides_by_zero?(ast)
445
+ # process(ast)
446
+ # false
447
+ # rescue VerificationFailure
448
+ # true
449
+ # end
450
+ # end
451
+ #
452
+ # nice_expr = \
453
+ # s(:divide,
454
+ # s(:add, s(:integer, 10), s(:integer, 2)),
455
+ # s(:integer, 4))
456
+ #
457
+ # p DivisionByZeroVerifier.new.divides_by_zero?(nice_expr)
458
+ # # => false. Good.
459
+ #
460
+ # bad_expr = \
461
+ # s(:add, s(:integer, 10),
462
+ # s(:divide, s(:integer, 1), s(:integer, 0)))
463
+ #
464
+ # p DivisionByZeroVerifier.new.divides_by_zero?(bad_expr)
465
+ # # => true. WHOOPS. DO NOT RUN THIS.
466
+ #
467
+ # Of course, this won't detect more complex cases... unless you
468
+ # use some partial evaluation before! The possibilites are
469
+ # endless. Have fun.
470
+ module AST::Processor::Mixin
471
+ # Default handler. Does nothing.
472
+ #
473
+ # @param node [AST::Node]
474
+ # @return [AST::Node, nil]
475
+ def handler_missing(node); end
476
+
477
+ # Dispatches `node`. If a node has type `:foo`, then a handler
478
+ # named `on_foo` is invoked with one argument, the `node`; if
479
+ # there isn't such a handler, {#handler_missing} is invoked
480
+ # with the same argument.
481
+ #
482
+ # If the handler returns `nil`, `node` is returned; otherwise,
483
+ # the return value of the handler is passed along.
484
+ #
485
+ # @param node [AST::Node, nil]
486
+ # @return [AST::Node, nil]
487
+ def process(node); end
488
+
489
+ # {#process}es each node from `nodes` and returns an array of
490
+ # results.
491
+ #
492
+ # @param nodes [Array<AST::Node>]
493
+ # @return [Array<AST::Node>]
494
+ def process_all(nodes); end
495
+ end
496
+
497
+ # This simple module is very useful in the cases where one needs
498
+ # to define deeply nested ASTs from Ruby code, for example, in
499
+ # tests. It should be used like this:
500
+ #
501
+ # describe YourLanguage::AST do
502
+ # include Sexp
503
+ #
504
+ # it "should correctly parse expressions" do
505
+ # YourLanguage.parse("1 + 2 * 3").should ==
506
+ # s(:add,
507
+ # s(:integer, 1),
508
+ # s(:multiply,
509
+ # s(:integer, 2),
510
+ # s(:integer, 3)))
511
+ # end
512
+ # end
513
+ #
514
+ # This way the amount of boilerplate code is greatly reduced.
515
+ module AST::Sexp
516
+ # Creates a {Node} with type `type` and children `children`.
517
+ # Note that the resulting node is of the type AST::Node and not a
518
+ # subclass.
519
+ # This would not pose a problem with comparisons, as {Node#==}
520
+ # ignores metadata.
521
+ def s(type, *children); end
522
+ end