twirbet 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/lib/twirbet/version.rb +1 -1
  3. metadata +1 -122
  4. data/.rspec +0 -3
  5. data/.rubocop.yml +0 -20
  6. data/CHANGELOG.md +0 -5
  7. data/Gemfile +0 -28
  8. data/Gemfile.lock +0 -127
  9. data/Rakefile +0 -17
  10. data/examples/clientcompat/client +0 -28
  11. data/examples/clientcompat/clientcompat.proto +0 -29
  12. data/examples/clientcompat/clientcompat_pb.rb +0 -36
  13. data/examples/clientcompat/clientcompat_twirbet.rb +0 -57
  14. data/examples/ping/Gemfile +0 -11
  15. data/examples/ping/Gemfile.lock +0 -69
  16. data/examples/ping/bin/puma +0 -27
  17. data/examples/ping/bin/pumactl +0 -27
  18. data/examples/ping/bin/srb +0 -27
  19. data/examples/ping/bin/srb-rbi +0 -27
  20. data/examples/ping/bin/tapioca +0 -27
  21. data/examples/ping/client.rb +0 -14
  22. data/examples/ping/config/application.rb +0 -13
  23. data/examples/ping/config/environment.rb +0 -6
  24. data/examples/ping/config.ru +0 -8
  25. data/examples/ping/proto/ping.proto +0 -15
  26. data/examples/ping/proto/ping_pb.rb +0 -20
  27. data/examples/ping/proto/ping_twirbet.rb +0 -47
  28. data/examples/ping/sorbet/config +0 -4
  29. data/examples/ping/sorbet/rbi/dsl/google/protobuf/descriptor_proto/extension_range.rbi +0 -34
  30. data/examples/ping/sorbet/rbi/dsl/google/protobuf/descriptor_proto/reserved_range.rbi +0 -22
  31. data/examples/ping/sorbet/rbi/dsl/google/protobuf/descriptor_proto.rbi +0 -83
  32. data/examples/ping/sorbet/rbi/dsl/google/protobuf/enum_descriptor_proto/enum_reserved_range.rbi +0 -22
  33. data/examples/ping/sorbet/rbi/dsl/google/protobuf/enum_descriptor_proto.rbi +0 -48
  34. data/examples/ping/sorbet/rbi/dsl/google/protobuf/enum_options.rbi +0 -34
  35. data/examples/ping/sorbet/rbi/dsl/google/protobuf/enum_value_descriptor_proto.rbi +0 -34
  36. data/examples/ping/sorbet/rbi/dsl/google/protobuf/enum_value_options.rbi +0 -27
  37. data/examples/ping/sorbet/rbi/dsl/google/protobuf/extension_range_options.rbi +0 -20
  38. data/examples/ping/sorbet/rbi/dsl/google/protobuf/field_descriptor_proto/label.rbi +0 -22
  39. data/examples/ping/sorbet/rbi/dsl/google/protobuf/field_descriptor_proto/type.rbi +0 -37
  40. data/examples/ping/sorbet/rbi/dsl/google/protobuf/field_descriptor_proto.rbi +0 -90
  41. data/examples/ping/sorbet/rbi/dsl/google/protobuf/field_options/c_type.rbi +0 -22
  42. data/examples/ping/sorbet/rbi/dsl/google/protobuf/field_options/js_type.rbi +0 -22
  43. data/examples/ping/sorbet/rbi/dsl/google/protobuf/field_options.rbi +0 -69
  44. data/examples/ping/sorbet/rbi/dsl/google/protobuf/file_descriptor_proto.rbi +0 -97
  45. data/examples/ping/sorbet/rbi/dsl/google/protobuf/file_descriptor_set.rbi +0 -20
  46. data/examples/ping/sorbet/rbi/dsl/google/protobuf/file_options/optimize_mode.rbi +0 -22
  47. data/examples/ping/sorbet/rbi/dsl/google/protobuf/file_options.rbi +0 -160
  48. data/examples/ping/sorbet/rbi/dsl/google/protobuf/generated_code_info/annotation.rbi +0 -41
  49. data/examples/ping/sorbet/rbi/dsl/google/protobuf/generated_code_info.rbi +0 -20
  50. data/examples/ping/sorbet/rbi/dsl/google/protobuf/map.rbi +0 -12
  51. data/examples/ping/sorbet/rbi/dsl/google/protobuf/message_options.rbi +0 -48
  52. data/examples/ping/sorbet/rbi/dsl/google/protobuf/method_descriptor_proto.rbi +0 -55
  53. data/examples/ping/sorbet/rbi/dsl/google/protobuf/method_options/idempotency_level.rbi +0 -22
  54. data/examples/ping/sorbet/rbi/dsl/google/protobuf/method_options.rbi +0 -34
  55. data/examples/ping/sorbet/rbi/dsl/google/protobuf/oneof_descriptor_proto.rbi +0 -22
  56. data/examples/ping/sorbet/rbi/dsl/google/protobuf/oneof_options.rbi +0 -20
  57. data/examples/ping/sorbet/rbi/dsl/google/protobuf/repeated_field.rbi +0 -11
  58. data/examples/ping/sorbet/rbi/dsl/google/protobuf/service_descriptor_proto.rbi +0 -34
  59. data/examples/ping/sorbet/rbi/dsl/google/protobuf/service_options.rbi +0 -27
  60. data/examples/ping/sorbet/rbi/dsl/google/protobuf/source_code_info/location.rbi +0 -48
  61. data/examples/ping/sorbet/rbi/dsl/google/protobuf/source_code_info.rbi +0 -20
  62. data/examples/ping/sorbet/rbi/dsl/google/protobuf/uninterpreted_option/name_part.rbi +0 -22
  63. data/examples/ping/sorbet/rbi/dsl/google/protobuf/uninterpreted_option.rbi +0 -62
  64. data/examples/ping/sorbet/rbi/dsl/ping/ping_request.rbi +0 -16
  65. data/examples/ping/sorbet/rbi/dsl/ping/ping_response.rbi +0 -16
  66. data/examples/ping/sorbet/rbi/gems/ast@2.4.2.rbi +0 -584
  67. data/examples/ping/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +0 -8
  68. data/examples/ping/sorbet/rbi/gems/google-protobuf@3.21.12.rbi +0 -1645
  69. data/examples/ping/sorbet/rbi/gems/netrc@0.11.0.rbi +0 -158
  70. data/examples/ping/sorbet/rbi/gems/nio4r@2.5.8.rbi +0 -8
  71. data/examples/ping/sorbet/rbi/gems/parallel@1.22.1.rbi +0 -277
  72. data/examples/ping/sorbet/rbi/gems/parser@3.1.3.0.rbi +0 -5076
  73. data/examples/ping/sorbet/rbi/gems/puma@6.0.0.rbi +0 -4177
  74. data/examples/ping/sorbet/rbi/gems/rack@3.0.2.rbi +0 -5016
  75. data/examples/ping/sorbet/rbi/gems/rbi@0.0.16.rbi +0 -3008
  76. data/examples/ping/sorbet/rbi/gems/spoom@1.1.15.rbi +0 -2383
  77. data/examples/ping/sorbet/rbi/gems/tapioca@0.10.3.rbi +0 -3032
  78. data/examples/ping/sorbet/rbi/gems/thor@1.2.1.rbi +0 -3919
  79. data/examples/ping/sorbet/rbi/gems/twirbet@0.1.0.rbi +0 -528
  80. data/examples/ping/sorbet/rbi/gems/unparser@0.6.5.rbi +0 -8
  81. data/examples/ping/sorbet/rbi/gems/webrick@1.7.0.rbi +0 -2498
  82. data/examples/ping/sorbet/rbi/gems/yard-sorbet@0.7.0.rbi +0 -391
  83. data/examples/ping/sorbet/rbi/gems/yard@0.9.28.rbi +0 -17022
  84. data/examples/ping/sorbet/tapioca/config.yml +0 -13
  85. data/examples/ping/sorbet/tapioca/require.rb +0 -5
  86. data/sorbet/config +0 -5
  87. data/sorbet/rbi/annotations/rainbow.rbi +0 -269
  88. data/sorbet/rbi/custom/ping.rbi +0 -23
  89. data/sorbet/rbi/gems/ast@2.4.2.rbi +0 -584
  90. data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +0 -1064
  91. data/sorbet/rbi/gems/google-protobuf@3.21.12.rbi +0 -1645
  92. data/sorbet/rbi/gems/json@2.6.3.rbi +0 -1541
  93. data/sorbet/rbi/gems/netrc@0.11.0.rbi +0 -158
  94. data/sorbet/rbi/gems/parallel@1.22.1.rbi +0 -277
  95. data/sorbet/rbi/gems/parser@3.1.3.0.rbi +0 -6878
  96. data/sorbet/rbi/gems/rack@3.0.2.rbi +0 -5163
  97. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +0 -397
  98. data/sorbet/rbi/gems/rake@13.0.6.rbi +0 -2946
  99. data/sorbet/rbi/gems/rbi@0.0.16.rbi +0 -3008
  100. data/sorbet/rbi/gems/regexp_parser@2.6.1.rbi +0 -3126
  101. data/sorbet/rbi/gems/rexml@3.2.5.rbi +0 -4660
  102. data/sorbet/rbi/gems/rspec-core@3.12.0.rbi +0 -10492
  103. data/sorbet/rbi/gems/rspec-expectations@3.12.1.rbi +0 -7817
  104. data/sorbet/rbi/gems/rspec-mocks@3.12.1.rbi +0 -4994
  105. data/sorbet/rbi/gems/rspec-support@3.12.0.rbi +0 -1477
  106. data/sorbet/rbi/gems/rspec@3.12.0.rbi +0 -10
  107. data/sorbet/rbi/gems/rubocop-ast@1.24.0.rbi +0 -6790
  108. data/sorbet/rbi/gems/rubocop-rake@0.6.0.rbi +0 -354
  109. data/sorbet/rbi/gems/rubocop-rspec@2.16.0.rbi +0 -7650
  110. data/sorbet/rbi/gems/rubocop-shopify@2.10.1.rbi +0 -8
  111. data/sorbet/rbi/gems/rubocop-sorbet@0.6.11.rbi +0 -1014
  112. data/sorbet/rbi/gems/rubocop@1.40.0.rbi +0 -51560
  113. data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +0 -1212
  114. data/sorbet/rbi/gems/spoom@1.1.15.rbi +0 -2383
  115. data/sorbet/rbi/gems/tapioca@0.10.3.rbi +0 -3032
  116. data/sorbet/rbi/gems/thor@1.2.1.rbi +0 -3950
  117. data/sorbet/rbi/gems/unicode-display_width@2.3.0.rbi +0 -46
  118. data/sorbet/rbi/gems/unparser@0.6.5.rbi +0 -4265
  119. data/sorbet/rbi/gems/webrick@1.7.0.rbi +0 -2498
  120. data/sorbet/rbi/gems/yard-sorbet@0.7.0.rbi +0 -391
  121. data/sorbet/rbi/gems/yard@0.9.28.rbi +0 -17033
  122. data/sorbet/tapioca/config.yml +0 -13
  123. data/sorbet/tapioca/require.rb +0 -4
  124. data/twirbet.gemspec +0 -36
@@ -1,584 +0,0 @@
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
- #
19
- # source://ast//lib/ast.rb#13
20
- module AST; end
21
-
22
- # Node is an immutable class, instances of which represent abstract
23
- # syntax tree nodes. It combines semantic information (i.e. anything
24
- # that affects the algorithmic properties of a program) with
25
- # meta-information (line numbers or compiler intermediates).
26
- #
27
- # Notes on inheritance
28
- # ====================
29
- #
30
- # The distinction between semantics and metadata is important. Complete
31
- # semantic information should be contained within just the {#type} and
32
- # {#children} of a Node instance; in other words, if an AST was to be
33
- # stripped of all meta-information, it should remain a valid AST which
34
- # could be successfully processed to yield a result with the same
35
- # algorithmic properties.
36
- #
37
- # Thus, Node should never be inherited in order to define methods which
38
- # affect or return semantic information, such as getters for `class_name`,
39
- # `superclass` and `body` in the case of a hypothetical `ClassNode`. The
40
- # correct solution is to use a generic Node with a {#type} of `:class`
41
- # and three children. See also {Processor} for tips on working with such
42
- # ASTs.
43
- #
44
- # On the other hand, Node can and should be inherited to define
45
- # application-specific metadata (see also {#initialize}) or customize the
46
- # printing format. It is expected that an application would have one or two
47
- # such classes and use them across the entire codebase.
48
- #
49
- # The rationale for this pattern is extensibility and maintainability.
50
- # Unlike static ones, dynamic languages do not require the presence of a
51
- # predefined, rigid structure, nor does it improve dispatch efficiency,
52
- # and while such a structure can certainly be defined, it does not add
53
- # any value but incurs a maintaining cost.
54
- # For example, extending the AST even with a transformation-local
55
- # temporary node type requires making globally visible changes to
56
- # the codebase.
57
- #
58
- # source://ast//lib/ast/node.rb#40
59
- class AST::Node
60
- # Constructs a new instance of Node.
61
- #
62
- # The arguments `type` and `children` are converted with `to_sym` and
63
- # `to_a` respectively. Additionally, the result of converting `children`
64
- # is frozen. While mutating the arguments is generally considered harmful,
65
- # the most common case is to pass an array literal to the constructor. If
66
- # your code does not expect the argument to be frozen, use `#dup`.
67
- #
68
- # The `properties` hash is passed to {#assign_properties}.
69
- #
70
- # @return [Node] a new instance of Node
71
- #
72
- # source://ast//lib/ast/node.rb#72
73
- def initialize(type, children = T.unsafe(nil), properties = T.unsafe(nil)); end
74
-
75
- # Concatenates `array` with `children` and returns the resulting node.
76
- #
77
- # @return [AST::Node]
78
- #
79
- # source://ast//lib/ast/node.rb#168
80
- def +(array); end
81
-
82
- # Appends `element` to `children` and returns the resulting node.
83
- #
84
- # @return [AST::Node]
85
- #
86
- # source://ast//lib/ast/node.rb#177
87
- def <<(element); end
88
-
89
- # Compares `self` to `other`, possibly converting with `to_ast`. Only
90
- # `type` and `children` are compared; metadata is deliberately ignored.
91
- #
92
- # @return [Boolean]
93
- #
94
- # source://ast//lib/ast/node.rb#153
95
- def ==(other); end
96
-
97
- # Appends `element` to `children` and returns the resulting node.
98
- #
99
- # @return [AST::Node]
100
- #
101
- # source://ast//lib/ast/node.rb#177
102
- def append(element); end
103
-
104
- # Returns the children of this node.
105
- # The returned value is frozen.
106
- # The to_a alias is useful for decomposing nodes concisely.
107
- # For example:
108
- #
109
- # node = s(:gasgn, :$foo, s(:integer, 1))
110
- # var_name, value = *node
111
- # p var_name # => :$foo
112
- # p value # => (integer 1)
113
- #
114
- # @return [Array]
115
- #
116
- # source://ast//lib/ast/node.rb#56
117
- def children; end
118
-
119
- # Nodes are already frozen, so there is no harm in returning the
120
- # current node as opposed to initializing from scratch and freezing
121
- # another one.
122
- #
123
- # @return self
124
- #
125
- # source://ast//lib/ast/node.rb#115
126
- def clone; end
127
-
128
- # Concatenates `array` with `children` and returns the resulting node.
129
- #
130
- # @return [AST::Node]
131
- #
132
- # source://ast//lib/ast/node.rb#168
133
- def concat(array); end
134
-
135
- # Enables matching for Node, where type is the first element
136
- # and the children are remaining items.
137
- #
138
- # @return [Array]
139
- #
140
- # source://ast//lib/ast/node.rb#253
141
- def deconstruct; end
142
-
143
- # Nodes are already frozen, so there is no harm in returning the
144
- # current node as opposed to initializing from scratch and freezing
145
- # another one.
146
- #
147
- # @return self
148
- #
149
- # source://ast//lib/ast/node.rb#115
150
- def dup; end
151
-
152
- # Test if other object is equal to
153
- #
154
- # @param other [Object]
155
- # @return [Boolean]
156
- #
157
- # source://ast//lib/ast/node.rb#85
158
- def eql?(other); end
159
-
160
- # Returns the precomputed hash value for this node
161
- #
162
- # @return [Fixnum]
163
- #
164
- # source://ast//lib/ast/node.rb#61
165
- def hash; end
166
-
167
- # Converts `self` to a s-expression ruby string.
168
- # The code return will recreate the node, using the sexp module s()
169
- #
170
- # @param indent [Integer] Base indentation level.
171
- # @return [String]
172
- #
173
- # source://ast//lib/ast/node.rb#211
174
- def inspect(indent = T.unsafe(nil)); end
175
-
176
- # Returns the children of this node.
177
- # The returned value is frozen.
178
- # The to_a alias is useful for decomposing nodes concisely.
179
- # For example:
180
- #
181
- # node = s(:gasgn, :$foo, s(:integer, 1))
182
- # var_name, value = *node
183
- # p var_name # => :$foo
184
- # p value # => (integer 1)
185
- #
186
- # @return [Array]
187
- #
188
- # source://ast//lib/ast/node.rb#56
189
- def to_a; end
190
-
191
- # @return [AST::Node] self
192
- #
193
- # source://ast//lib/ast/node.rb#229
194
- def to_ast; end
195
-
196
- # Converts `self` to a pretty-printed s-expression.
197
- #
198
- # @param indent [Integer] Base indentation level.
199
- # @return [String]
200
- #
201
- # source://ast//lib/ast/node.rb#187
202
- def to_s(indent = T.unsafe(nil)); end
203
-
204
- # Converts `self` to a pretty-printed s-expression.
205
- #
206
- # @param indent [Integer] Base indentation level.
207
- # @return [String]
208
- #
209
- # source://ast//lib/ast/node.rb#187
210
- def to_sexp(indent = T.unsafe(nil)); end
211
-
212
- # Converts `self` to an Array where the first element is the type as a Symbol,
213
- # and subsequent elements are the same representation of its children.
214
- #
215
- # @return [Array<Symbol, [...Array]>]
216
- #
217
- # source://ast//lib/ast/node.rb#237
218
- def to_sexp_array; end
219
-
220
- # Returns the type of this node.
221
- #
222
- # @return [Symbol]
223
- #
224
- # source://ast//lib/ast/node.rb#43
225
- def type; end
226
-
227
- # Returns a new instance of Node where non-nil arguments replace the
228
- # corresponding fields of `self`.
229
- #
230
- # For example, `Node.new(:foo, [ 1, 2 ]).updated(:bar)` would yield
231
- # `(bar 1 2)`, and `Node.new(:foo, [ 1, 2 ]).updated(nil, [])` would
232
- # yield `(foo)`.
233
- #
234
- # If the resulting node would be identical to `self`, does nothing.
235
- #
236
- # @param type [Symbol, nil]
237
- # @param children [Array, nil]
238
- # @param properties [Hash, nil]
239
- # @return [AST::Node]
240
- #
241
- # source://ast//lib/ast/node.rb#133
242
- def updated(type = T.unsafe(nil), children = T.unsafe(nil), properties = T.unsafe(nil)); end
243
-
244
- protected
245
-
246
- # By default, each entry in the `properties` hash is assigned to
247
- # an instance variable in this instance of Node. A subclass should define
248
- # attribute readers for such variables. The values passed in the hash
249
- # are not frozen or whitelisted; such behavior can also be implemented
250
- # by subclassing Node and overriding this method.
251
- #
252
- # @return [nil]
253
- #
254
- # source://ast//lib/ast/node.rb#98
255
- def assign_properties(properties); end
256
-
257
- # Returns `@type` with all underscores replaced by dashes. This allows
258
- # to write symbol literals without quotes in Ruby sources and yet have
259
- # nicely looking s-expressions.
260
- #
261
- # @return [String]
262
- #
263
- # source://ast//lib/ast/node.rb#264
264
- def fancy_type; end
265
-
266
- private
267
-
268
- def original_dup; end
269
- end
270
-
271
- # This class includes {AST::Processor::Mixin}; however, it is
272
- # deprecated, since the module defines all of the behaviors that
273
- # the processor includes. Any new libraries should use
274
- # {AST::Processor::Mixin} instead of subclassing this.
275
- #
276
- # @deprecated Use {AST::Processor::Mixin} instead.
277
- #
278
- # source://ast//lib/ast/processor.rb#8
279
- class AST::Processor
280
- include ::AST::Processor::Mixin
281
- end
282
-
283
- # The processor module is a module which helps transforming one
284
- # AST into another. In a nutshell, the {#process} method accepts
285
- # a {Node} and dispatches it to a handler corresponding to its
286
- # type, and returns a (possibly) updated variant of the node.
287
- #
288
- # The processor module has a set of associated design patterns.
289
- # They are best explained with a concrete example. Let's define a
290
- # simple arithmetic language and an AST format for it:
291
- #
292
- # Terminals (AST nodes which do not have other AST nodes inside):
293
- #
294
- # * `(integer <int-literal>)`,
295
- #
296
- # Nonterminals (AST nodes with other nodes as children):
297
- #
298
- # * `(add <node> <node>)`,
299
- # * `(multiply <node> <node>)`,
300
- # * `(divide <node> <node>)`,
301
- # * `(negate <node>)`,
302
- # * `(store <node> <string-literal>)`: stores value of `<node>`
303
- # into a variable named `<string-literal>`,
304
- # * `(load <string-literal>)`: loads value of a variable named
305
- # `<string-literal>`,
306
- # * `(each <node> ...)`: computes each of the `<node>`s and
307
- # prints the result.
308
- #
309
- # All AST nodes have the same Ruby class, and therefore they don't
310
- # know how to traverse themselves. (A solution which dynamically
311
- # checks the type of children is possible, but is slow and
312
- # error-prone.) So, a class including the module which knows how
313
- # to traverse the entire tree should be defined. Such classes
314
- # have a handler for each nonterminal node which recursively
315
- # processes children nodes:
316
- #
317
- # require 'ast'
318
- #
319
- # class ArithmeticsProcessor
320
- # include AST::Processor::Mixin
321
- # # This method traverses any binary operators such as (add)
322
- # # or (multiply).
323
- # def process_binary_op(node)
324
- # # Children aren't decomposed automatically; it is
325
- # # suggested to use Ruby multiple assignment expansion,
326
- # # as it is very convenient here.
327
- # left_expr, right_expr = *node
328
- #
329
- # # AST::Node#updated won't change node type if nil is
330
- # # passed as a first argument, which allows to reuse the
331
- # # same handler for multiple node types using `alias'
332
- # # (below).
333
- # node.updated(nil, [
334
- # process(left_expr),
335
- # process(right_expr)
336
- # ])
337
- # end
338
- # alias_method :on_add, :process_binary_op
339
- # alias_method :on_multiply, :process_binary_op
340
- # alias_method :on_divide, :process_binary_op
341
- #
342
- # def on_negate(node)
343
- # # It is also possible to use #process_all for more
344
- # # compact code if every child is a Node.
345
- # node.updated(nil, process_all(node))
346
- # end
347
- #
348
- # def on_store(node)
349
- # expr, variable_name = *node
350
- #
351
- # # Note that variable_name is not a Node and thus isn't
352
- # # passed to #process.
353
- # node.updated(nil, [
354
- # process(expr),
355
- # variable_name
356
- # ])
357
- # end
358
- #
359
- # # (load) is effectively a terminal node, and so it does
360
- # # not need an explicit handler, as the following is the
361
- # # default behavior. Essentially, for any nodes that don't
362
- # # have a defined handler, the node remains unchanged.
363
- # def on_load(node)
364
- # nil
365
- # end
366
- #
367
- # def on_each(node)
368
- # node.updated(nil, process_all(node))
369
- # end
370
- # end
371
- #
372
- # Let's test our ArithmeticsProcessor:
373
- #
374
- # include AST::Sexp
375
- # expr = s(:add, s(:integer, 2), s(:integer, 2))
376
- #
377
- # p ArithmeticsProcessor.new.process(expr) == expr # => true
378
- #
379
- # As expected, it does not change anything at all. This isn't
380
- # actually very useful, so let's now define a Calculator, which
381
- # will compute the expression values:
382
- #
383
- # # This Processor folds nonterminal nodes and returns an
384
- # # (integer) terminal node.
385
- # class ArithmeticsCalculator < ArithmeticsProcessor
386
- # def compute_op(node)
387
- # # First, node children are processed and then unpacked
388
- # # to local variables.
389
- # nodes = process_all(node)
390
- #
391
- # if nodes.all? { |node| node.type == :integer }
392
- # # If each of those nodes represents a literal, we can
393
- # # fold this node!
394
- # values = nodes.map { |node| node.children.first }
395
- # AST::Node.new(:integer, [
396
- # yield(values)
397
- # ])
398
- # else
399
- # # Otherwise, we can just leave the current node in the
400
- # # tree and only update it with processed children
401
- # # nodes, which can be partially folded.
402
- # node.updated(nil, nodes)
403
- # end
404
- # end
405
- #
406
- # def on_add(node)
407
- # compute_op(node) { |left, right| left + right }
408
- # end
409
- #
410
- # def on_multiply(node)
411
- # compute_op(node) { |left, right| left * right }
412
- # end
413
- # end
414
- #
415
- # Let's check:
416
- #
417
- # p ArithmeticsCalculator.new.process(expr) # => (integer 4)
418
- #
419
- # Excellent, the calculator works! Now, a careful reader could
420
- # notice that the ArithmeticsCalculator does not know how to
421
- # divide numbers. What if we pass an expression with division to
422
- # it?
423
- #
424
- # expr_with_division = \
425
- # s(:add,
426
- # s(:integer, 1),
427
- # s(:divide,
428
- # s(:add, s(:integer, 8), s(:integer, 4)),
429
- # s(:integer, 3))) # 1 + (8 + 4) / 3
430
- #
431
- # folded_expr_with_division = ArithmeticsCalculator.new.process(expr_with_division)
432
- # p folded_expr_with_division
433
- # # => (add
434
- # # (integer 1)
435
- # # (divide
436
- # # (integer 12)
437
- # # (integer 3)))
438
- #
439
- # As you can see, the expression was folded _partially_: the inner
440
- # `(add)` node which could be computed was folded to
441
- # `(integer 12)`, the `(divide)` node is left as-is because there
442
- # is no computing handler for it, and the root `(add)` node was
443
- # also left as it is because some of its children were not
444
- # literals.
445
- #
446
- # Note that this partial folding is only possible because the
447
- # _data_ format, i.e. the format in which the computed values of
448
- # the nodes are represented, is the same as the AST itself.
449
- #
450
- # Let's extend our ArithmeticsCalculator class further.
451
- #
452
- # class ArithmeticsCalculator
453
- # def on_divide(node)
454
- # compute_op(node) { |left, right| left / right }
455
- # end
456
- #
457
- # def on_negate(node)
458
- # # Note how #compute_op works regardless of the operator
459
- # # arity.
460
- # compute_op(node) { |value| -value }
461
- # end
462
- # end
463
- #
464
- # Now, let's apply our renewed ArithmeticsCalculator to a partial
465
- # result of previous evaluation:
466
- #
467
- # p ArithmeticsCalculator.new.process(expr_with_division) # => (integer 5)
468
- #
469
- # Five! Excellent. This is also pretty much how CRuby 1.8 executed
470
- # its programs.
471
- #
472
- # Now, let's do some automated bug searching. Division by zero is
473
- # an error, right? So if we could detect that someone has divided
474
- # by zero before the program is even run, that could save some
475
- # debugging time.
476
- #
477
- # class DivisionByZeroVerifier < ArithmeticsProcessor
478
- # class VerificationFailure < Exception; end
479
- #
480
- # def on_divide(node)
481
- # # You need to process the children to handle nested divisions
482
- # # such as:
483
- # # (divide
484
- # # (integer 1)
485
- # # (divide (integer 1) (integer 0))
486
- # left, right = process_all(node)
487
- #
488
- # if right.type == :integer &&
489
- # right.children.first == 0
490
- # raise VerificationFailure, "Ouch! This code divides by zero."
491
- # end
492
- # end
493
- #
494
- # def divides_by_zero?(ast)
495
- # process(ast)
496
- # false
497
- # rescue VerificationFailure
498
- # true
499
- # end
500
- # end
501
- #
502
- # nice_expr = \
503
- # s(:divide,
504
- # s(:add, s(:integer, 10), s(:integer, 2)),
505
- # s(:integer, 4))
506
- #
507
- # p DivisionByZeroVerifier.new.divides_by_zero?(nice_expr)
508
- # # => false. Good.
509
- #
510
- # bad_expr = \
511
- # s(:add, s(:integer, 10),
512
- # s(:divide, s(:integer, 1), s(:integer, 0)))
513
- #
514
- # p DivisionByZeroVerifier.new.divides_by_zero?(bad_expr)
515
- # # => true. WHOOPS. DO NOT RUN THIS.
516
- #
517
- # Of course, this won't detect more complex cases... unless you
518
- # use some partial evaluation before! The possibilites are
519
- # endless. Have fun.
520
- #
521
- # source://ast//lib/ast/processor/mixin.rb#240
522
- module AST::Processor::Mixin
523
- # Default handler. Does nothing.
524
- #
525
- # @param node [AST::Node]
526
- # @return [AST::Node, nil]
527
- #
528
- # source://ast//lib/ast/processor/mixin.rb#284
529
- def handler_missing(node); end
530
-
531
- # Dispatches `node`. If a node has type `:foo`, then a handler
532
- # named `on_foo` is invoked with one argument, the `node`; if
533
- # there isn't such a handler, {#handler_missing} is invoked
534
- # with the same argument.
535
- #
536
- # If the handler returns `nil`, `node` is returned; otherwise,
537
- # the return value of the handler is passed along.
538
- #
539
- # @param node [AST::Node, nil]
540
- # @return [AST::Node, nil]
541
- #
542
- # source://ast//lib/ast/processor/mixin.rb#251
543
- def process(node); end
544
-
545
- # {#process}es each node from `nodes` and returns an array of
546
- # results.
547
- #
548
- # @param nodes [Array<AST::Node>]
549
- # @return [Array<AST::Node>]
550
- #
551
- # source://ast//lib/ast/processor/mixin.rb#274
552
- def process_all(nodes); end
553
- end
554
-
555
- # This simple module is very useful in the cases where one needs
556
- # to define deeply nested ASTs from Ruby code, for example, in
557
- # tests. It should be used like this:
558
- #
559
- # describe YourLanguage::AST do
560
- # include Sexp
561
- #
562
- # it "should correctly parse expressions" do
563
- # YourLanguage.parse("1 + 2 * 3").should ==
564
- # s(:add,
565
- # s(:integer, 1),
566
- # s(:multiply,
567
- # s(:integer, 2),
568
- # s(:integer, 3)))
569
- # end
570
- # end
571
- #
572
- # This way the amount of boilerplate code is greatly reduced.
573
- #
574
- # source://ast//lib/ast/sexp.rb#20
575
- module AST::Sexp
576
- # Creates a {Node} with type `type` and children `children`.
577
- # Note that the resulting node is of the type AST::Node and not a
578
- # subclass.
579
- # This would not pose a problem with comparisons, as {Node#==}
580
- # ignores metadata.
581
- #
582
- # source://ast//lib/ast/sexp.rb#26
583
- def s(type, *children); end
584
- end