marshal-parser 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,880 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lexer"
4
+ require_relative "assertable"
5
+
6
+ module MarshalParser
7
+ class Parser
8
+ include Assertable
9
+
10
+ attr_reader :symbols
11
+
12
+ def initialize(lexer)
13
+ @lexer = lexer
14
+ @index = 0
15
+ @symbols = []
16
+ end
17
+
18
+ def parse
19
+ version_node = build_ast_node
20
+ build_ast_node
21
+ end
22
+
23
+ private
24
+
25
+ def build_ast_node
26
+ token = next_token
27
+
28
+ case token.id
29
+ when Lexer::VERSION
30
+ VersionNode.new(token)
31
+
32
+ when Lexer::ARRAY_PREFIX
33
+ length = next_token
34
+ elements = []
35
+
36
+ length.value.times do
37
+ elements << build_ast_node
38
+ end
39
+
40
+ ArrayNode.new(token, length, elements)
41
+
42
+ when Lexer::STRING_PREFIX
43
+ length = next_token
44
+ content = next_token
45
+
46
+ StringNode.new(token, length, content)
47
+
48
+ when Lexer::OBJECT_WITH_IVARS_PREFIX
49
+ child = build_ast_node
50
+
51
+ count = next_token
52
+ assert_token_type(count, Lexer::INTEGER)
53
+
54
+ ivars = []
55
+
56
+ count.value.times do
57
+ name = build_ast_node
58
+ value = build_ast_node
59
+ ivars << name << value
60
+
61
+ assert_node_type(name, SymbolNode, SymbolLinkNode)
62
+ end
63
+
64
+ ObjectWithIVarsNode.new(token, child, count, ivars)
65
+
66
+ when Lexer::SYMBOL_PREFIX
67
+ length = next_token
68
+ content = next_token
69
+ @symbols << @lexer.source_string[content.index, content.length]
70
+
71
+ SymbolNode.new(token, length, content, @symbols.size - 1)
72
+
73
+ when Lexer::TRUE
74
+ TrueNode.new(token)
75
+
76
+ when Lexer::FALSE
77
+ FalseNode.new(token)
78
+
79
+ when Lexer::NIL
80
+ NilNode.new(token)
81
+
82
+ when Lexer::INTEGER_PREFIX
83
+ value = next_token
84
+ IntegerNode.new(token, value)
85
+
86
+ when Lexer::BIG_INTEGER_PREFIX
87
+ sign = next_token
88
+ length = next_token
89
+ value = next_token
90
+ BigIntegerNode.new(token, sign, length, value)
91
+
92
+ when Lexer::FLOAT_PREFIX
93
+ length = next_token
94
+ value = next_token
95
+ FloatNode.new(token, length, value)
96
+
97
+ when Lexer::SYMBOL_LINK_PREFIX
98
+ index = next_token
99
+
100
+ SymbolLinkNode.new(token, index)
101
+
102
+ when Lexer::HASH_PREFIX
103
+ size = next_token
104
+ assert_token_type size, Lexer::INTEGER
105
+
106
+ key_and_value_nodes = []
107
+
108
+ size.value.times do
109
+ key = build_ast_node
110
+ assert_node_type key, SymbolNode, SymbolLinkNode
111
+
112
+ value = build_ast_node
113
+ key_and_value_nodes << key << value
114
+ end
115
+
116
+ HashNode.new(token, size, key_and_value_nodes)
117
+
118
+ when Lexer::HASH_WITH_DEFAULT_VALUE_PREFIX
119
+ size = next_token
120
+ assert_token_type size, Lexer::INTEGER
121
+
122
+ key_and_value_nodes = []
123
+
124
+ size.value.times do
125
+ key = build_ast_node
126
+ assert_node_type key, SymbolNode, SymbolLinkNode
127
+
128
+ value = build_ast_node
129
+ key_and_value_nodes << key << value
130
+ end
131
+
132
+ default_value_node = build_ast_node
133
+ assert_node_type default_value_node, IntegerNode
134
+
135
+ HashWithDefaultValueNode.new(token, size, key_and_value_nodes, default_value_node)
136
+
137
+ when Lexer::REGEXP_PREFIX
138
+ string_length = next_token
139
+ string = next_token
140
+ options = next_token
141
+
142
+ RegexpNode.new(token, string_length, string, options)
143
+
144
+ when Lexer::CLASS_PREFIX
145
+ length = next_token
146
+ string = next_token
147
+
148
+ ClassNode.new(token, length, string)
149
+
150
+ when Lexer::MODULE_PREFIX
151
+ length = next_token
152
+ string = next_token
153
+
154
+ ModuleNode.new(token, length, string)
155
+
156
+ when Lexer::SUBCLASS_OF_CORE_LIBRARY_CLASS_PREFIX
157
+ class_name_node = build_ast_node
158
+ assert_node_type class_name_node, SymbolNode, SymbolLinkNode
159
+
160
+ object_node = build_ast_node
161
+
162
+ SubclassNode.new(token, class_name_node, object_node)
163
+
164
+ when Lexer::STRUCT_PREFIX
165
+ class_name_node = build_ast_node
166
+ assert_node_type class_name_node, SymbolNode, SymbolLinkNode
167
+
168
+ members_count = next_token
169
+
170
+ member_nodes = []
171
+
172
+ members_count.value.times do
173
+ name = build_ast_node
174
+ value = build_ast_node
175
+
176
+ assert_node_type name, SymbolNode, SymbolLinkNode
177
+
178
+ member_nodes << name << value
179
+ end
180
+
181
+ StructNode.new(token, class_name_node, members_count, member_nodes)
182
+
183
+ when Lexer::OBJECT_PREFIX
184
+ class_name_node = build_ast_node
185
+ assert_node_type class_name_node, SymbolNode, SymbolLinkNode
186
+
187
+ ivars_count = next_token
188
+ assert_token_type(ivars_count, Lexer::INTEGER)
189
+
190
+ ivars_nodes = []
191
+
192
+ ivars_count.value.times do
193
+ name = build_ast_node
194
+ value = build_ast_node
195
+
196
+ ivars_nodes << name << value
197
+ end
198
+
199
+ ObjectNode.new(token, class_name_node, ivars_count, ivars_nodes)
200
+
201
+ when Lexer::OBJECT_LINK_PREFIX
202
+ index = next_token
203
+
204
+ ObjectLinkNode.new(token, index)
205
+
206
+ when Lexer::OBJECT_WITH_DUMP_PREFIX
207
+ class_name_node = build_ast_node
208
+ assert_node_type class_name_node, SymbolNode, SymbolLinkNode
209
+
210
+ length = next_token
211
+ user_dump = next_token
212
+
213
+ ObjectWithDumpMethodNode.new(token, class_name_node, length, user_dump)
214
+
215
+ when Lexer::OBJECT_WITH_MARSHAL_DUMP_PREFIX
216
+ class_name_node = build_ast_node
217
+ assert_node_type class_name_node, SymbolNode, SymbolLinkNode
218
+
219
+ child_node = build_ast_node
220
+
221
+ ObjectWithMarshalDumpMethod.new(token, class_name_node, child_node)
222
+
223
+ when Lexer::OBJECT_EXTENDED_PREFIX
224
+ module_name_node = build_ast_node
225
+ object_node = build_ast_node
226
+
227
+ ObjectExtendedNode.new(token, module_name_node, object_node)
228
+
229
+ else
230
+ raise "Not supported token id #{token.id}"
231
+ end
232
+ end
233
+
234
+ def next_token
235
+ raise "No next token" if @index >= @lexer.tokens.size
236
+
237
+ @index += 1
238
+ @lexer.tokens[@index - 1]
239
+ end
240
+
241
+ def assert_node_type(node, *allowed_classes)
242
+ assert(
243
+ allowed_classes.any? { |node_class| node.instance_of?(node_class) },
244
+ "Node #{node} should be a #{allowed_classes.map(&:name).join(" or ")}"
245
+ )
246
+ end
247
+
248
+ def assert_token_type(token, *token_ids)
249
+ assert(
250
+ token_ids.include?(token.id),
251
+ "Token #{token} should have type #{token_ids.join(" or ")}"
252
+ )
253
+ end
254
+
255
+ module Annotatable
256
+ def annotation
257
+ raise "Not implemented"
258
+ end
259
+ end
260
+
261
+ class Node
262
+ include Assertable
263
+
264
+ def child_entities
265
+ raise "Not implemented"
266
+ end
267
+
268
+ def tokens
269
+ child_entities.grep(Lexer::Token)
270
+ end
271
+
272
+ def children
273
+ child_entities.grep(Node)
274
+ end
275
+
276
+ def decoded_value
277
+ nil
278
+ end
279
+
280
+ def literal_token
281
+ nil
282
+ end
283
+
284
+ def attributes
285
+ {}
286
+ end
287
+
288
+ def always_leaf?
289
+ false
290
+ end
291
+
292
+ private
293
+
294
+ def assert_token_type(token, *token_ids)
295
+ assert(
296
+ token_ids.include?(token.id),
297
+ "Token #{token} should have type #{token_ids.join(" or ")}"
298
+ )
299
+ end
300
+ end
301
+
302
+ class VersionNode < Node
303
+ def initialize(version_token)
304
+ super()
305
+ assert_token_type version_token, Lexer::VERSION
306
+ @version_token = version_token
307
+ end
308
+
309
+ def child_entities
310
+ [@version_token]
311
+ end
312
+ end
313
+
314
+ class ArrayNode < Node
315
+ def initialize(marker_token, length_token, elements_nodes)
316
+ super()
317
+ assert_token_type marker_token, Lexer::ARRAY_PREFIX
318
+ assert_token_type length_token, Lexer::INTEGER
319
+
320
+ @marker_token = marker_token
321
+ @length_token = length_token
322
+ @elements_nodes = elements_nodes
323
+ end
324
+
325
+ def child_entities
326
+ [@marker_token, @length_token] + @elements_nodes
327
+ end
328
+
329
+ def attributes
330
+ {
331
+ @length_token => { name: :length, value: @length_token.value }
332
+ }
333
+ end
334
+ end
335
+
336
+ class StringNode < Node
337
+ def initialize(marker_token, length_token, content_token)
338
+ super()
339
+ assert_token_type marker_token, Lexer::STRING_PREFIX
340
+ assert_token_type length_token, Lexer::INTEGER
341
+ assert_token_type content_token, Lexer::STRING
342
+
343
+ @marker_token = marker_token
344
+ @length_token = length_token
345
+ @content_token = content_token
346
+ end
347
+
348
+ def child_entities
349
+ [@marker_token, @length_token, @content_token]
350
+ end
351
+
352
+ def literal_token
353
+ @content_token
354
+ end
355
+
356
+ def attributes
357
+ {
358
+ @length_token => { name: :length, value: @length_token.value },
359
+ @content_token => { name: :content, value: @content_token }
360
+ }
361
+ end
362
+ end
363
+
364
+ class ObjectWithIVarsNode < Node
365
+ def initialize(marker_token, child, count_token, ivars_nodes)
366
+ super()
367
+ assert_token_type marker_token, Lexer::OBJECT_WITH_IVARS_PREFIX
368
+ # child - any Node
369
+ assert_token_type count_token, Lexer::INTEGER
370
+ # ivars nodes - any nodes
371
+
372
+ @marker_token = marker_token
373
+ @child = child
374
+ @count_token = count_token
375
+ @ivars_nodes = ivars_nodes
376
+ end
377
+
378
+ def child_entities
379
+ [@marker_token, @child, @count_token] + @ivars_nodes
380
+ end
381
+
382
+ def attributes
383
+ {
384
+ @count_token => { name: :ivars_count, value: @count_token.value }
385
+ }
386
+ end
387
+ end
388
+
389
+ class SymbolNode < Node
390
+ include Annotatable
391
+
392
+ def initialize(marker_token, length_token, content_token, link_to_symbol)
393
+ super()
394
+ assert_token_type marker_token, Lexer::SYMBOL_PREFIX
395
+ assert_token_type length_token, Lexer::INTEGER
396
+ assert_token_type content_token, Lexer::SYMBOL
397
+
398
+ @marker_token = marker_token
399
+ @length_token = length_token
400
+ @content_token = content_token
401
+ @link_to_symbol = link_to_symbol # just Integer, index in the Symbols table
402
+ end
403
+
404
+ def child_entities
405
+ [@marker_token, @length_token, @content_token]
406
+ end
407
+
408
+ def annotation
409
+ "symbol ##{@link_to_symbol}"
410
+ end
411
+
412
+ def literal_token
413
+ @content_token
414
+ end
415
+
416
+ def attributes
417
+ {
418
+ @length_token => { name: :length, value: @length_token.value },
419
+ @content_token => { name: :content, value: @content_token }
420
+ }
421
+ end
422
+ end
423
+
424
+ class TrueNode < Node
425
+ def initialize(token)
426
+ super()
427
+ assert_token_type(token, Lexer::TRUE)
428
+ @token = token
429
+ end
430
+
431
+ def child_entities
432
+ [@token]
433
+ end
434
+
435
+ def always_leaf?
436
+ true
437
+ end
438
+ end
439
+
440
+ class FalseNode < Node
441
+ def initialize(token)
442
+ super()
443
+ assert_token_type token, Lexer::FALSE
444
+ @token = token
445
+ end
446
+
447
+ def child_entities
448
+ [@token]
449
+ end
450
+
451
+ def always_leaf?
452
+ true
453
+ end
454
+ end
455
+
456
+ class NilNode < Node
457
+ def initialize(token)
458
+ super()
459
+ assert_token_type token, Lexer::NIL
460
+ @token = token
461
+ end
462
+
463
+ def child_entities
464
+ [@token]
465
+ end
466
+
467
+ def always_leaf?
468
+ true
469
+ end
470
+ end
471
+
472
+ class IntegerNode < Node
473
+ def initialize(prefix, value)
474
+ super()
475
+ assert_token_type prefix, Lexer::INTEGER_PREFIX
476
+ assert_token_type value, Lexer::INTEGER
477
+
478
+ @prefix = prefix
479
+ @value = value
480
+ end
481
+
482
+ def child_entities
483
+ [@prefix, @value]
484
+ end
485
+
486
+ def decoded_value
487
+ @value.value
488
+ end
489
+
490
+ def literal_token
491
+ @value
492
+ end
493
+
494
+ def attributes
495
+ {
496
+ @value => { name: :value, value: @value.value }
497
+ }
498
+ end
499
+ end
500
+
501
+ class BigIntegerNode < Node
502
+ def initialize(prefix, sign, length, value)
503
+ super()
504
+ assert_token_type prefix, Lexer::BIG_INTEGER_PREFIX
505
+ assert_token_type sign, Lexer::PLUS_SIGN, Lexer::MINUS_SIGN
506
+ assert_token_type length, Lexer::INTEGER
507
+ assert_token_type value, Lexer::BIG_INTEGER
508
+
509
+ @prefix = prefix
510
+ @sign = sign
511
+ @length = length
512
+ @value = value
513
+ end
514
+
515
+ def child_entities
516
+ [@prefix, @sign, @length, @value]
517
+ end
518
+
519
+ def decoded_value
520
+ @value.value
521
+ end
522
+
523
+ def literal_token
524
+ @value
525
+ end
526
+
527
+ def attributes
528
+ {
529
+ @value => { name: :value, value: @value.value }
530
+ }
531
+ end
532
+ end
533
+
534
+ class FloatNode < Node
535
+ def initialize(prefix, length, value)
536
+ super()
537
+ assert_token_type prefix, Lexer::FLOAT_PREFIX
538
+ assert_token_type length, Lexer::INTEGER
539
+ assert_token_type value, Lexer::FLOAT
540
+
541
+ @prefix = prefix
542
+ @length = length
543
+ @value = value
544
+ end
545
+
546
+ def child_entities
547
+ [@prefix, @length, @value]
548
+ end
549
+
550
+ def decoded_value
551
+ @value.value
552
+ end
553
+
554
+ def literal_token
555
+ @value
556
+ end
557
+
558
+ def attributes
559
+ {
560
+ @length => { name: :length, value: @length.value },
561
+ @value => { name: :value, value: @value.value }
562
+ }
563
+ end
564
+ end
565
+
566
+ class SymbolLinkNode < Node
567
+ include Annotatable
568
+
569
+ def initialize(marker_token, index_token)
570
+ super()
571
+ assert_token_type marker_token, Lexer::SYMBOL_LINK_PREFIX
572
+ assert_token_type index_token, Lexer::INTEGER
573
+
574
+ @marker_token = marker_token
575
+ @index_token = index_token
576
+ end
577
+
578
+ def child_entities
579
+ [@marker_token, @index_token]
580
+ end
581
+
582
+ def annotation
583
+ "link to symbol ##{@index_token.value}"
584
+ end
585
+
586
+ def decoded_value
587
+ @index_token.value
588
+ end
589
+
590
+ def literal_token
591
+ @index_token
592
+ end
593
+
594
+ def attributes
595
+ {
596
+ @index_token => { name: :index, value: @index_token.value }
597
+ }
598
+ end
599
+ end
600
+
601
+ class HashNode < Node
602
+ def initialize(prefix, size, key_and_value_nodes)
603
+ super()
604
+ assert_token_type prefix, Lexer::HASH_PREFIX
605
+ assert_token_type size, Lexer::INTEGER
606
+
607
+ @prefix = prefix
608
+ @size = size
609
+ @key_and_value_nodes = key_and_value_nodes
610
+ end
611
+
612
+ def child_entities
613
+ [@prefix, @size] + @key_and_value_nodes
614
+ end
615
+
616
+ def attributes
617
+ {
618
+ @size => { name: :size, value: @size.value }
619
+ }
620
+ end
621
+ end
622
+
623
+ class HashWithDefaultValueNode < Node
624
+ def initialize(prefix, size, key_and_value_nodes, default_value_node)
625
+ super()
626
+ assert_token_type prefix, Lexer::HASH_WITH_DEFAULT_VALUE_PREFIX
627
+ assert_token_type size, Lexer::INTEGER
628
+
629
+ @prefix = prefix
630
+ @size = size
631
+ @key_and_value_nodes = key_and_value_nodes
632
+ @default_value_node = default_value_node
633
+ end
634
+
635
+ def child_entities
636
+ [@prefix, @size] + @key_and_value_nodes + [@default_value_node]
637
+ end
638
+
639
+ def attributes
640
+ {
641
+ @size => { name: :size, value: @size.value }
642
+ }
643
+ end
644
+ end
645
+
646
+ class RegexpNode < Node
647
+ def initialize(prefix, string_length, string, options)
648
+ super()
649
+ assert_token_type prefix, Lexer::REGEXP_PREFIX
650
+ assert_token_type string_length, Lexer::INTEGER
651
+ assert_token_type string, Lexer::STRING
652
+ assert_token_type options, Lexer::INTEGER
653
+
654
+ @prefix = prefix
655
+ @string_length = string_length
656
+ @string = string
657
+ @options = options
658
+ end
659
+
660
+ def child_entities
661
+ [@prefix, @string_length, @string, @options]
662
+ end
663
+
664
+ def literal_token
665
+ @string
666
+ end
667
+
668
+ def attributes
669
+ {
670
+ @string_length => { name: :length, value: @string_length.value },
671
+ @string => { name: :source_string, value: @string },
672
+ @options => { name: :options, value: @options.value }
673
+ }
674
+ end
675
+ end
676
+
677
+ class ClassNode < Node
678
+ def initialize(prefix, length, name)
679
+ super()
680
+ assert_token_type prefix, Lexer::CLASS_PREFIX
681
+ assert_token_type length, Lexer::INTEGER
682
+ assert_token_type name, Lexer::STRING
683
+
684
+ @prefix = prefix
685
+ @length = length
686
+ @name = name
687
+ end
688
+
689
+ def child_entities
690
+ [@prefix, @length, @name]
691
+ end
692
+
693
+ def literal_token
694
+ @name
695
+ end
696
+
697
+ def attributes
698
+ {
699
+ @length => { name: :length, value: @length.value },
700
+ @name => { name: :name, value: @name }
701
+ }
702
+ end
703
+ end
704
+
705
+ class ModuleNode < Node
706
+ def initialize(prefix, length, name)
707
+ super()
708
+ assert_token_type prefix, Lexer::MODULE_PREFIX
709
+ assert_token_type length, Lexer::INTEGER
710
+ assert_token_type name, Lexer::STRING
711
+
712
+ @prefix = prefix
713
+ @length = length
714
+ @name = name
715
+ end
716
+
717
+ def child_entities
718
+ [@prefix, @length, @name]
719
+ end
720
+
721
+ def literal_token
722
+ @name
723
+ end
724
+
725
+ def attributes
726
+ {
727
+ @length => { name: :length, value: @length.value },
728
+ @name => { name: :name, value: @name }
729
+ }
730
+ end
731
+ end
732
+
733
+ class SubclassNode < Node
734
+ def initialize(prefix, class_name_node, object_node)
735
+ super()
736
+ assert_token_type prefix, Lexer::SUBCLASS_OF_CORE_LIBRARY_CLASS_PREFIX
737
+
738
+ @prefix = prefix
739
+ @class_name_node = class_name_node
740
+ @object_node = object_node
741
+ end
742
+
743
+ def child_entities
744
+ [@prefix, @class_name_node, @object_node]
745
+ end
746
+ end
747
+
748
+ class StructNode < Node
749
+ def initialize(prefix, class_name_node, members_count, member_nodes)
750
+ super()
751
+ assert_token_type prefix, Lexer::STRUCT_PREFIX
752
+ assert_token_type members_count, Lexer::INTEGER
753
+
754
+ @prefix = prefix
755
+ @class_name_node = class_name_node
756
+ @members_count = members_count
757
+ @member_nodes = member_nodes
758
+ end
759
+
760
+ def child_entities
761
+ [@prefix, @class_name_node, @members_count] + @member_nodes
762
+ end
763
+
764
+ def attributes
765
+ {
766
+ @members_count => { name: :count, value: @members_count.value }
767
+ }
768
+ end
769
+ end
770
+
771
+ class ObjectNode < Node
772
+ def initialize(prefix, class_name_node, ivars_count, ivars_nodes)
773
+ super()
774
+ assert_token_type prefix, Lexer::OBJECT_PREFIX
775
+ assert_token_type ivars_count, Lexer::INTEGER
776
+
777
+ @prefix = prefix
778
+ @class_name_node = class_name_node
779
+ @ivars_count = ivars_count
780
+ @ivars_nodes = ivars_nodes
781
+ end
782
+
783
+ def child_entities
784
+ [@prefix, @class_name_node, @ivars_count] + @ivars_nodes
785
+ end
786
+
787
+ def attributes
788
+ {
789
+ @ivars_count => { name: :ivars_count, value: @ivars_count.value }
790
+ }
791
+ end
792
+ end
793
+
794
+ class ObjectLinkNode < Node
795
+ def initialize(prefix, index)
796
+ super()
797
+ assert_token_type prefix, Lexer::OBJECT_LINK_PREFIX
798
+ assert_token_type index, Lexer::INTEGER
799
+
800
+ @prefix = prefix
801
+ @index = index
802
+ end
803
+
804
+ def child_entities
805
+ [@prefix, @index]
806
+ end
807
+
808
+ def decoded_value
809
+ @index.value
810
+ end
811
+
812
+ def literal_token
813
+ @index
814
+ end
815
+
816
+ def attributes
817
+ {
818
+ @index => { name: :index, value: @index.value }
819
+ }
820
+ end
821
+ end
822
+
823
+ class ObjectWithDumpMethodNode < Node
824
+ def initialize(token, class_name_node, length, user_dump)
825
+ super()
826
+ assert_token_type token, Lexer::OBJECT_WITH_DUMP_PREFIX
827
+ assert_token_type length, Lexer::INTEGER
828
+ assert_token_type user_dump, Lexer::STRING
829
+
830
+ @prefix = token
831
+ @class_name_node = class_name_node
832
+ @length = length
833
+ @user_dump = user_dump
834
+ end
835
+
836
+ def child_entities
837
+ [@prefix, @class_name_node, @length, @user_dump]
838
+ end
839
+
840
+ def literal_token
841
+ @user_dump
842
+ end
843
+
844
+ def attributes
845
+ {
846
+ @length => { name: :length, value: @length.value },
847
+ @user_dump => { name: :dump, value: @user_dump }
848
+ }
849
+ end
850
+ end
851
+
852
+ class ObjectWithMarshalDumpMethod < Node
853
+ def initialize(prefix, class_name_node, child_node)
854
+ super()
855
+ assert_token_type prefix, Lexer::OBJECT_WITH_MARSHAL_DUMP_PREFIX
856
+
857
+ @prefix = prefix
858
+ @class_name_node = class_name_node
859
+ @child_node = child_node
860
+ end
861
+
862
+ def child_entities
863
+ [@prefix, @class_name_node, @child_node]
864
+ end
865
+ end
866
+
867
+ class ObjectExtendedNode < Node
868
+ def initialize(prefix, module_name_node, object_node)
869
+ super()
870
+ @prefix = prefix
871
+ @module_name_node = module_name_node
872
+ @object_node = object_node
873
+ end
874
+
875
+ def child_entities
876
+ [@prefix, @module_name_node, @object_node]
877
+ end
878
+ end
879
+ end
880
+ end