ridl 2.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2818 @@
1
+ #--------------------------------------------------------------------
2
+ # node.rb - IDL nodes
3
+ #
4
+ # Author: Martin Corino
5
+ #
6
+ # This program is free software; you can redistribute it and/or
7
+ # modify it under the terms of the RIDL LICENSE which is
8
+ # included with this program.
9
+ #
10
+ # Copyright (c) Remedy IT Expertise BV
11
+ # Chamber of commerce Rotterdam nr.276339, The Netherlands
12
+ #--------------------------------------------------------------------
13
+ module IDL::AST
14
+
15
+ REPO_ID_XCHARS = ['.', '-', '_']
16
+ REPO_ID_RE = /^[#{('a'..'z').to_a.join}#{('A'..'Z').to_a.join}#{('0'..'9').to_a.join}\.\-_\/]+$/
17
+
18
+ class Annotation
19
+ def initialize(id, fields = {})
20
+ @id = id.to_sym
21
+ # copy field map transforming all keys to symbols and
22
+ # detecting nested annotation objects
23
+ @fields = fields.inject({}) do |m,(k,v)|
24
+ m[k.to_sym] = case v
25
+ when Array
26
+ v.collect { |ve| Hash === ve ? Annotation.new(*ve.to_a.first) : ve }
27
+ when Hash
28
+ Annotation.new(*v.to_a.first)
29
+ else
30
+ v
31
+ end
32
+ m
33
+ end
34
+ end
35
+
36
+ attr_reader :id, :fields
37
+
38
+ def is_marker?
39
+ @fields.empty?
40
+ end
41
+
42
+ def [](fieldid)
43
+ @fields[(fieldid || '').to_sym]
44
+ end
45
+
46
+ def each(&block)
47
+ @fields.each(&block)
48
+ end
49
+ end
50
+
51
+ class Annotations
52
+ def initialize(stack = [], index = {})
53
+ @index = index
54
+ @stack = stack
55
+ end
56
+
57
+ def empty?
58
+ @stack.empty?
59
+ end
60
+
61
+ def [](annid)
62
+ (@index[annid] || []).collect { |ix| @stack[ix] }
63
+ end
64
+
65
+ def <<(ann)
66
+ (@index[ann.id] ||= []) << @stack.size
67
+ @stack << ann
68
+ end
69
+
70
+ def each(&block)
71
+ @stack.each(&block)
72
+ end
73
+
74
+ def each_for_id(annid, &block)
75
+ self[annid].each(&block)
76
+ end
77
+
78
+ def clear
79
+ @index.clear
80
+ @stack.clear
81
+ end
82
+
83
+ def concat(anns)
84
+ (anns || []).each {|_ann| self << _ann }
85
+ end
86
+
87
+ def dup
88
+ self.class.new(@stack.dup, @index.dup)
89
+ end
90
+ end
91
+
92
+ class Leaf
93
+ attr_reader :name, :intern
94
+ attr_reader :lm_name
95
+ attr_accessor :enclosure
96
+ attr_reader :scopes
97
+ attr_reader :prefix
98
+ attr_reader :annotations
99
+
100
+ def typename
101
+ self.class.name
102
+ end
103
+
104
+ def initialize(_name, _enclosure)
105
+ _name ||= ''
106
+ _name = IDL::Scanner::Identifier.new(_name, _name) unless IDL::Scanner::Identifier === _name
107
+ @name = _name
108
+ @lm_name = self.class.mk_name(_name.checked_name, _enclosure.nil? ? false : _enclosure.scopes.size>0).freeze
109
+ @intern = _name.rjust(1).downcase.intern
110
+ @enclosure = _enclosure
111
+ @scopes = if @enclosure.nil? then [] else (@enclosure.scopes.dup << self) end
112
+ @prefix = ''
113
+ @repo_id = nil
114
+ @repo_ver = nil
115
+ @annotations = Annotations.new
116
+ end
117
+
118
+ def parsed_name_scope
119
+ (@enclosure ? @enclosure.parsed_name_scope : '') + '::' + @name
120
+ end
121
+
122
+ def lm_name_for_scope
123
+ lm_name
124
+ end
125
+
126
+ def scoped_name
127
+ @scoped_name ||= @scopes.collect{|s| s.name}.join("::").freeze
128
+ end
129
+
130
+ def scoped_lm_name
131
+ @scoped_lm_name ||= @scopes.collect{|s| s.lm_name_for_scope }.join("::").freeze
132
+ end
133
+
134
+ def marshal_dump
135
+ [@name, @lm_name, @intern, @enclosure, @scopes, @prefix, @repo_id, @repo_ver, @annotations]
136
+ end
137
+
138
+ def marshal_load(vars)
139
+ @name, @lm_name, @intern, @enclosure, @scopes, @prefix, @repo_id, @repo_ver, @annotations = vars
140
+ @scoped_name = nil
141
+ @scoped_lm_name = nil
142
+ end
143
+
144
+ def repo_scopes
145
+ @repo_scopes ||= (@enclosure.nil? ? [] : (@enclosure.repo_scopes.dup << self))
146
+ end
147
+
148
+ def is_template?
149
+ @enclosure && @enclosure.is_template?
150
+ end
151
+
152
+ def instantiate(_context, _enclosure, _params = {})
153
+ (_context[self] = self.class.new(self.name, _enclosure, _params)).copy_from(self, _context)
154
+ end
155
+
156
+ def set_repo_id(id)
157
+ if @repo_id
158
+ if id != @repo_id
159
+ raise RuntimeError,
160
+ "#{self.scoped_name} already has a different repository ID assigned: #{@repo_id}"
161
+ end
162
+ end
163
+ id_arr = id.split(':')
164
+ if @repo_ver
165
+ if id_arr.first != 'IDL' or id_arr.last != @repo_ver
166
+ raise RuntimeError,
167
+ "supplied repository ID (#{id}) does not match previously assigned repository version for #{self.scoped_name} = #{@repo_ver}"
168
+ end
169
+ end
170
+ # check validity of IDL format repo IDs
171
+ if id_arr.first == 'IDL'
172
+ id_arr.shift
173
+ id_str = id_arr.shift.to_s
174
+ raise RuntimeError, 'ID identifiers should not start or end with \'/\'' if id_str[0,1]=='/' or id_str[-1, 1]=='/'
175
+ raise RuntimeError, "ID identifiers should not start with one of '#{REPO_ID_XCHARS.join("', '")}'" if REPO_ID_XCHARS.include?(id_str[0,1])
176
+ raise RuntimeError, 'Invalid ID! Only a..z, A..Z, 0..9, \'.\', \'-\', \'_\' or \'\/\' allowed for identifiers' unless REPO_ID_RE =~ id_str
177
+ end
178
+ @repo_id = id
179
+ end
180
+
181
+ def set_repo_version(ma, mi)
182
+ ver = "#{ma}.#{mi}"
183
+ if @repo_ver
184
+ if ver != @repo_ver
185
+ raise RuntimeError,
186
+ "#{self.scoped_name} already has a repository version assigned: #{@repo_ver}"
187
+ end
188
+ end
189
+ if @repo_id
190
+ l = @repo_id.split(':')
191
+ if l.last != ver
192
+ raise RuntimeError,
193
+ "supplied repository version (#{ver}) does not match previously assigned repository ID for #{self.scoped_name}: #{@repo_id}"
194
+ end
195
+ end
196
+ @repo_ver = ver
197
+ end
198
+
199
+ def prefix=(pfx)
200
+ unless pfx.to_s.empty?
201
+ raise RuntimeError, 'ID prefix should not start or end with \'/\'' if pfx[0,1]=='/' or pfx[-1, 1]=='/'
202
+ raise RuntimeError, "ID prefix should not start with one of '#{REPO_ID_XCHARS.join("', '")}'" if REPO_ID_XCHARS.include?(pfx[0,1])
203
+ raise RuntimeError, 'Invalid ID prefix! Only a..z, A..Z, 0..9, \'.\', \'-\', \'_\' or \'\/\' allowed' unless REPO_ID_RE =~ pfx
204
+ end
205
+ self._set_prefix(pfx)
206
+ end
207
+
208
+ def replace_prefix(pfx)
209
+ self.prefix = pfx
210
+ end
211
+
212
+ def _set_prefix(pfx)
213
+ @prefix = pfx.to_s
214
+ end
215
+
216
+ def repository_id
217
+ if @repo_id.nil?
218
+ @repo_ver = "1.0" unless @repo_ver
219
+ format("IDL:%s%s:%s",
220
+ if @prefix.empty? then "" else @prefix+"/" end,
221
+ self.repo_scopes.collect{|s| s.name}.join("/"),
222
+ @repo_ver)
223
+ else
224
+ @repo_id
225
+ end
226
+ end
227
+
228
+ def has_annotations?()
229
+ !@annotations.empty?
230
+ end
231
+
232
+ def resolve(_name)
233
+ nil
234
+ end
235
+
236
+ def is_local?
237
+ false
238
+ end
239
+
240
+ protected
241
+ def copy_from(_template, _context)
242
+ @prefix = _template.instance_variable_get(:@prefix)
243
+ @repo_id = _template.instance_variable_get(:@repo_id)
244
+ @repo_ver = _template.instance_variable_get(:@repo_ver)
245
+ @annotations = _template.instance_variable_get(:@annotations)
246
+ self
247
+ end
248
+ end # Leaf
249
+
250
+ class Node < Leaf
251
+ def initialize(name, enclosure)
252
+ super
253
+ @introduced = Hash.new
254
+ @children = []
255
+ introduce(self)
256
+ end
257
+
258
+ def marshal_dump
259
+ super() << @children << @introduced
260
+ end
261
+
262
+ def marshal_load(vars)
263
+ @introduced = vars.pop
264
+ @children = vars.pop
265
+ super(vars)
266
+ end
267
+
268
+ def introduce(node)
269
+ n = (@introduced[node.intern] ||= node)
270
+ raise RuntimeError,
271
+ "#{node.name} is already introduced as a #{n.scoped_name} of #{n.typename}." if n != node
272
+ end
273
+
274
+ def undo_introduction(node)
275
+ @introduced.delete(node.intern)
276
+ end
277
+
278
+ def redefine(node, params)
279
+ raise RuntimeError, "\"#{node.name}\" is already defined."
280
+ end
281
+
282
+ def is_definable?(_type)
283
+ self.class::DEFINABLE.any? do |target|
284
+ _type.ancestors.include? target
285
+ end
286
+ end
287
+
288
+ def define(_type, _name, params = Hash.new)
289
+ if not is_definable?(_type)
290
+ raise RuntimeError,
291
+ "#{_type.to_s} is not definable in #{self.typename}."
292
+ end
293
+ node = search_self(_name)
294
+ if node.nil?
295
+ node = _type.new(_name, self, params)
296
+ node.annotations.concat(params[:annotations])
297
+ node.prefix = @prefix
298
+ introduce(node)
299
+ @children << node
300
+ else
301
+ if _type != node.class
302
+ raise RuntimeError,
303
+ "#{_name} is already defined as a type of #{node.typename}"
304
+ end
305
+ node = redefine(node, params)
306
+ end
307
+ node
308
+ end
309
+
310
+ def resolve(_name)
311
+ node = search_enclosure(_name)
312
+ @introduced[node.intern] = node unless node.nil?
313
+ node
314
+ end
315
+
316
+ def walk_members(&block)
317
+ @children.each { |c| yield(c) }
318
+ end
319
+
320
+ def match_members(&block)
321
+ !(@children.find { |c| yield(c) }).nil?
322
+ end
323
+
324
+ def replace_prefix(pfx)
325
+ super
326
+ walk_members { |m| m.replace_prefix(pfx) }
327
+ end
328
+
329
+ protected
330
+ def children
331
+ @children
332
+ end
333
+
334
+ def search_self(_name)
335
+ key = _name.downcase.intern
336
+ node = @introduced[key]
337
+ if not node.nil? and node.name != _name
338
+ raise RuntimeError, "\"#{_name}\" clashed with \"#{node.name}\"."
339
+ end
340
+ node
341
+ end
342
+
343
+ def search_enclosure(_name)
344
+ node = search_self(_name)
345
+ if node.nil? and not @enclosure.nil?
346
+ node = @enclosure.search_enclosure(_name)
347
+ end
348
+ node
349
+ end
350
+
351
+ def walk_members_for_copy(&block)
352
+ self.walk_members(&block)
353
+ end
354
+
355
+ def copy_from(_template, _context)
356
+ super
357
+ _template.__send__(:walk_members_for_copy) do |child|
358
+ _child_copy = child.instantiate(_context, self)
359
+ @children << _child_copy
360
+ # introduce unless already introduced (happens with module chains)
361
+ @introduced[_child_copy.intern] = _child_copy unless @introduced.has_key?(_child_copy.intern)
362
+ end
363
+ self
364
+ end
365
+ end # Node
366
+
367
+ # Forward declarations
368
+
369
+ class Module < Node; end
370
+ class Include < Module; end
371
+ class TemplateParam < Leaf; end
372
+ class TemplateModule < Module; end
373
+ class TemplateModuleReference < Leaf; end
374
+ class Derivable < Node; end
375
+ class Interface < Derivable; end
376
+ class ComponentBase < Derivable; end
377
+ class Connector < ComponentBase; end
378
+ class Component < ComponentBase; end
379
+ class Porttype < Node; end
380
+ class Port < Leaf; end
381
+ class Home < ComponentBase; end
382
+ class Valuebox < Leaf; end
383
+ class Valuetype < Derivable; end
384
+ class Typedef < Leaf; end
385
+ class Const < Leaf; end
386
+ class Operation < Node; end
387
+ class Attribute < Leaf; end
388
+ class Parameter < Leaf; end
389
+ class StateMember < Leaf; end
390
+ class Initializer < Leaf; end
391
+ class Finder < Initializer; end
392
+ class Struct < Node; end
393
+ class Member < Leaf; end
394
+ class Union < Node; end
395
+ class UnionMember < Member; end
396
+ class Enum < Leaf; end
397
+ class Enumerator < Leaf; end
398
+
399
+ class Module < Node
400
+ NAMETYPE = :class
401
+ DEFINABLE = [
402
+ IDL::AST::Module, IDL::AST::Interface, IDL::AST::Valuebox, IDL::AST::Valuetype, IDL::AST::Const, IDL::AST::Struct,
403
+ IDL::AST::Union, IDL::AST::Enum, IDL::AST::Enumerator, IDL::AST::Typedef, IDL::AST::Include,
404
+ IDL::AST::Home, IDL::AST::Porttype, IDL::AST::Component, IDL::AST::Connector
405
+ ]
406
+ attr_reader :anchor, :next
407
+ def initialize(_name, _enclosure, params)
408
+ super(_name, _enclosure)
409
+ @anchor = params[:anchor]
410
+ @prefix = params[:prefix] || @prefix
411
+ @not_in_repo_id = params[:not_in_repo_id]
412
+ @next = nil
413
+ end
414
+
415
+ def has_anchor?
416
+ !@anchor.nil?
417
+ end
418
+
419
+ def annotations
420
+ (has_anchor? ? self.anchor : self).get_annotations
421
+ end
422
+
423
+ def marshal_dump
424
+ super() << @anchor << @next
425
+ end
426
+
427
+ def marshal_load(vars)
428
+ @next = vars.pop
429
+ @anchor = vars.pop
430
+ super(vars)
431
+ end
432
+
433
+ def instantiate(_context, _enclosure)
434
+ super(_context, _enclosure, {})
435
+ end
436
+
437
+ def repo_scopes
438
+ @repo_scopes ||= (@enclosure.nil? ? [] : (@not_in_repo_id ? @enclosure.repo_scopes.dup : (@enclosure.repo_scopes.dup << self)))
439
+ end
440
+
441
+ def redefine(node, params)
442
+ case node
443
+ when IDL::AST::Include
444
+ if node.enclosure == self
445
+ return node
446
+ else
447
+ _inc = IDL::AST::Include.new(node.name, self, params)
448
+ _inc.annotations.concat(params[:annotations])
449
+ @children << _inc
450
+ return _inc
451
+ end
452
+ when IDL::AST::Module
453
+ # Module reopening
454
+ _anchor = node.has_anchor? ? node.anchor : node
455
+ _anchor.annotations.concat(params[:annotations])
456
+ _last = _anchor.find_last
457
+ _params = { :anchor => _anchor, :prefix => node.prefix }
458
+ _next = IDL::AST::Module.new(node.name, self, _params)
459
+ _last.set_next(_next)
460
+ @children << _next
461
+ return _next
462
+ when IDL::AST::Interface
463
+ node.annotations.concat(params[:annotations])
464
+ return node if params[:forward]
465
+ if node.is_defined?
466
+ raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
467
+ end
468
+ if (node.is_abstract? != params[:abstract]) || (node.is_local? != params[:local]) || (node.is_pseudo? != params[:pseudo])
469
+ raise RuntimeError, "\"attributes are not the same: \"#{node.name}\"."
470
+ end
471
+
472
+ _intf = IDL::AST::Interface.new(node.name, self, params)
473
+ _intf.annotations.concat(node.annotations)
474
+ _intf.prefix = node.prefix
475
+ _intf.instance_variable_set(:@repo_ver, node.instance_variable_get(:@repo_ver))
476
+ _intf.instance_variable_set(:@repo_id, node.instance_variable_get(:@repo_id))
477
+
478
+ @children << _intf
479
+ # replace forward node registration
480
+ node.enclosure.undo_introduction(node)
481
+ introduce(_intf)
482
+
483
+ return _intf
484
+ when IDL::AST::Valuetype
485
+ node.annotations.concat(params[:annotations])
486
+ return node if params[:forward]
487
+ if node.is_defined?
488
+ raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
489
+ end
490
+ if (node.is_abstract? != params[:abstract])
491
+ raise RuntimeError, "\"attributes are not the same: \"#{node.name}\"."
492
+ end
493
+
494
+ _new_node = node.class.new(node.name, self, params)
495
+ _new_node.annotations.concat(node.annotations)
496
+ _new_node.prefix = node.prefix
497
+ _new_node.instance_variable_set(:@repo_ver, node.instance_variable_get(:@repo_ver))
498
+ _new_node.instance_variable_set(:@repo_id, node.instance_variable_get(:@repo_id))
499
+
500
+ @children << _new_node
501
+ # replace forward node registration
502
+ node.enclosure.undo_introduction(node)
503
+ introduce(_new_node)
504
+
505
+ return _new_node
506
+ when IDL::AST::Struct, IDL::AST::Union
507
+ node.annotations.concat(params[:annotations])
508
+ return node if params[:forward]
509
+ if node.is_defined?
510
+ raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
511
+ end
512
+
513
+ _new_node = node.class.new(node.name, self, params)
514
+ _new_node.annotations.concat(node.annotations)
515
+ _new_node.prefix = node.prefix
516
+ _new_node.instance_variable_set(:@repo_ver, node.instance_variable_get(:@repo_ver))
517
+ _new_node.instance_variable_set(:@repo_id, node.instance_variable_get(:@repo_id))
518
+
519
+ node.switchtype = params[:switchtype] if node.is_a?(IDL::AST::Union)
520
+
521
+ @children << _new_node
522
+ # replace forward node registration
523
+ node.enclosure.undo_introduction(node)
524
+ introduce(_new_node)
525
+
526
+ return _new_node
527
+ end
528
+ raise RuntimeError,
529
+ "#{node.name} is already introduced as #{node.typename} #{node.scoped_name}."
530
+ end
531
+
532
+ def undo_introduction(node)
533
+ _mod = (@anchor || self)
534
+ while _mod
535
+ _mod._undo_link_introduction(node)
536
+ _mod = _mod.next
537
+ end
538
+ end
539
+
540
+ def replace_prefix(pfx)
541
+ self.prefix = pfx # handles validation
542
+ if @anchor.nil?
543
+ self.replace_prefix_(pfx)
544
+ else
545
+ @anchor.replace_prefix_(pfx)
546
+ end
547
+ end
548
+
549
+ def _set_prefix(pfx)
550
+ if @anchor.nil?
551
+ self._set_prefix_(pfx)
552
+ else
553
+ @anchor._set_prefix_(pfx)
554
+ end
555
+ end
556
+
557
+ protected
558
+
559
+ def get_annotations
560
+ @annotations
561
+ end
562
+
563
+ def copy_from(_template, _context)
564
+ super
565
+ if _template.has_anchor?
566
+ # module anchor is first to be copied/instantiated and
567
+ # should be registered in _context
568
+ @anchor = IDL::AST::TemplateParam.concrete_param(_context, _template.anchor)
569
+ # link ourself into module chain
570
+ @anchor.find_last.set_next(self)
571
+ end
572
+ @next = nil # to be sure
573
+ self
574
+ end
575
+
576
+ def replace_prefix_(pfx)
577
+ walk_members { |m| m.replace_prefix(pfx) }
578
+ # propagate along chain using fast method
579
+ @next.replace_prefix_(pfx) unless @next.nil?
580
+ end
581
+
582
+ def _set_prefix_(pfx)
583
+ @prefix = pfx
584
+ # propagate along chain
585
+ self.next._set_prefix_(pfx) unless self.next.nil?
586
+ end
587
+
588
+ def search_self(_name)
589
+ (@anchor || self).search_links(_name)
590
+ end
591
+
592
+ def search_links(_name)
593
+ _key = _name.downcase.intern
594
+ node = @introduced[_key]
595
+ if not node.nil? and node.name != _name
596
+ raise RuntimeError, "\"#{_name}\" clashed with \"#{node.name}\"."
597
+ end
598
+ if node.nil? && @next
599
+ node = @next.search_links(_name)
600
+ end
601
+ node
602
+ end
603
+
604
+ def _undo_link_introduction(node)
605
+ @introduced.delete(node.intern)
606
+ end
607
+
608
+ def set_next(mod)
609
+ @next = mod
610
+ end
611
+
612
+ def find_last
613
+ if @next.nil?
614
+ self
615
+ else
616
+ @next.find_last
617
+ end
618
+ end
619
+ end # Module
620
+
621
+ class TemplateParam < Leaf
622
+ NAMETYPE = :class
623
+ attr_reader :idltype, :concrete
624
+ def initialize(_name, _enclosure, params)
625
+ super(_name, _enclosure)
626
+ @idltype = params[:type]
627
+ @concrete = nil
628
+ end
629
+
630
+ def marshal_dump
631
+ super() << @idltype
632
+ end
633
+
634
+ def marshal_load(vars)
635
+ @idltype = vars.pop
636
+ super(vars)
637
+ end
638
+
639
+ def is_template?
640
+ true
641
+ end
642
+
643
+ def set_concrete_param(_param)
644
+ @concrete = _param
645
+ end
646
+
647
+ def self.concrete_param(_context, _node)
648
+ if _node.is_template?
649
+ _cnode = if _node.is_a?(IDL::AST::TemplateParam)
650
+ _node.concrete
651
+ else
652
+ # referenced template node should have been instantiated already and available through context
653
+ _context[_node]
654
+ end
655
+ raise RuntimeError, "cannot resolve concrete node for template #{_node.typename} #{_node.scoped_lm_name}" unless _cnode
656
+ _cnode
657
+ else
658
+ _node
659
+ end
660
+ end
661
+ end
662
+
663
+ class TemplateModule < Module
664
+ NAMETYPE = :class
665
+ DEFINABLE = [
666
+ IDL::AST::Include, IDL::AST::Module, IDL::AST::Interface, IDL::AST::Valuebox, IDL::AST::Valuetype,
667
+ IDL::AST::Const, IDL::AST::Struct, IDL::AST::Union, IDL::AST::Enum, IDL::AST::Enumerator, IDL::AST::Typedef,
668
+ IDL::AST::Home, IDL::AST::Porttype, IDL::AST::Component, IDL::AST::Connector,
669
+ IDL::AST::TemplateParam, IDL::AST::TemplateModuleReference
670
+ ]
671
+ attr_reader :idltype
672
+ def initialize(_name, _enclosure, _params)
673
+ super(_name, _enclosure, {})
674
+ @idltype = IDL::Type::TemplateModule.new(self)
675
+ @template_params = []
676
+ end
677
+
678
+ def define(*args)
679
+ child = super(*args)
680
+ @template_params << child if child.is_a?(IDL::AST::TemplateParam)
681
+ child
682
+ end
683
+
684
+ def is_template?
685
+ true
686
+ end
687
+
688
+ def instantiate(_module_instance, _concrete_params, _context = {})
689
+ # process concrete parameters
690
+ @template_params.each_with_index do |_tp, _ix|
691
+ raise RuntimeError,
692
+ "missing template parameter for #{typename} #{scoped_lm_name}: #{_tp.name}" unless _ix < _concrete_params.size
693
+ _cp = _concrete_params[_ix]
694
+ if _cp.is_a?(IDL::Type)
695
+ raise RuntimeError, "anonymous type definitions are not allowed!" if _cp.is_anonymous?
696
+ # parameter should be a matching IDL::Type
697
+ unless _tp.idltype.is_a?(IDL::Type::Any) || _tp.idltype.class === _cp.resolved_type
698
+ raise RuntimeError, "mismatched instantiation parameter \##{_ix} #{_cp.typename} for #{typename} #{scoped_lm_name}: expected #{_tp.idltype.typename} for #{_tp.name}"
699
+ end
700
+ # verify concrete parameter
701
+ case _tp.idltype
702
+ when IDL::Type::Any # 'typename'
703
+ # no further checks
704
+ when IDL::Type::Interface, # 'interface'
705
+ IDL::Type::Eventtype, # 'eventtype'
706
+ IDL::Type::Valuetype, # 'valuetype'
707
+ IDL::Type::Struct, # 'struct'
708
+ IDL::Type::Union, # 'union'
709
+ IDL::Type::Exception, # 'exception'
710
+ IDL::Type::Enum # 'enum'
711
+ # no further checks
712
+ when IDL::Type::Sequence # 'sequence' or 'sequence<...>'
713
+ _tptype = _tp.idltype
714
+ unless _tptype.basetype.is_a?(IDL::Type::Void) # 'sequence'
715
+ # check basetype
716
+ unless _tptype.basetype.is_a?(IDL::Type::ScopedName) &&
717
+ _tptype.basetype.is_node?(IDL::AST::TemplateParam) &&
718
+ _tptype.basetype.node.concrete &&
719
+ _tptype.basetype.node.concrete.idltype.resolved_type == _cp.resolved_type.basetype.resolved_type
720
+ raise RuntimeError, "invalid sequence type as instantiation parameter for #{typename} #{scoped_lm_name}: expected #{_tp.idltype.typename} for #{_tp.name}"
721
+ end
722
+ end
723
+ end
724
+ elsif _cp.is_a?(IDL::Expression)
725
+ # template param should be 'const <const_type>'
726
+ unless _tp.idltype.is_a?(IDL::Type::Const)
727
+ raise RuntimeError, "unexpected expression as instantiation parameter for #{typename} #{scoped_lm_name}: expected #{_tp.idltype.typename} for #{_tp.name}"
728
+ end
729
+ # match constant type
730
+ _tp.idltype.narrow(_cp.value)
731
+ else
732
+ raise RuntimeError, "invalid instantiation parameter for #{typename} #{scoped_lm_name}: #{_cp.class.name}"
733
+ end
734
+ # if we get here all is well -> store concrete param
735
+ _tp.set_concrete_param(_cp.is_a?(IDL::Type::ScopedName) ? _cp.node : _cp)
736
+ end
737
+ # instantiate template by copying template module state to module instance
738
+ _module_instance.copy_from(self, _context)
739
+ end
740
+
741
+ protected
742
+
743
+ def walk_members_for_copy(&block)
744
+ @children.each { |c| yield(c) unless c.is_a?(IDL::AST::TemplateParam) }
745
+ end
746
+ end # TemplateModule
747
+
748
+ class TemplateModuleReference < Leaf
749
+ NAMETYPE = :class
750
+ def initialize(_name, _enclosure, _params)
751
+ super(_name, _enclosure)
752
+ unless _params[:tpl_type].is_a?(IDL::Type::ScopedName) && _params[:tpl_type].is_node?(IDL::AST::TemplateModule)
753
+ raise RuntimeError, "templated module reference type required for #{typename} #{scoped_lm_name}: got #{_params[:tpl_type].typename}"
754
+ end
755
+ @template = _params[:tpl_type].resolved_type.node
756
+ _params[:tpl_params].each do |p|
757
+ unless (p.is_a?(IDL::Type::ScopedName) || p.is_a?(IDL::Expression::ScopedName)) && p.is_node?(IDL::AST::TemplateParam)
758
+ raise RuntimeError, "invalid template module parameter for template module reference #{typename} #{scoped_lm_name}: #{p.typename}"
759
+ end
760
+ end
761
+ @params = _params[:tpl_params].collect { |p| p.resolved_node }
762
+ end
763
+
764
+ def marshal_dump
765
+ super() << @template << @params
766
+ end
767
+
768
+ def marshal_load(vars)
769
+ @params = vars.pop
770
+ @template = vars.pop
771
+ super(vars)
772
+ end
773
+
774
+ def instantiate(_context, _enclosure)
775
+ mod_inst = IDL::AST::Module.new(self.name, _enclosure, {})
776
+ inst_params = @params.collect do |tp|
777
+ # concrete objects are either Expression or Node; latter needs to be repacked as IDL::Type::ScopedName
778
+ # as that is what the TemplateModule#instantiate expects
779
+ tp.concrete.is_a?(IDL::Expression) ? tp.concrete : IDL::Type::ScopedName.new(tp.concrete)
780
+ end
781
+ @template.instantiate(mod_inst, inst_params, _context)
782
+ mod_inst
783
+ end
784
+
785
+ def resolve(_name)
786
+ @template.resolve(_name)
787
+ end
788
+ end # TemplateModuleReference
789
+
790
+ class Include < Module
791
+ attr_reader :filename
792
+ def initialize(_name, _enclosure, params)
793
+ super(_name, _enclosure, params)
794
+ @filename = params[:filename]
795
+ @defined = params[:defined] || false
796
+ @preprocessed = params[:preprocessed] || false
797
+ #overrule
798
+ @scopes = @enclosure.scopes
799
+ @scoped_name = @scopes.collect{|s| s.name}.join("::")
800
+ @scoped_lm_name = @scopes.collect{|s| s.lm_name}.join("::")
801
+ end
802
+
803
+ def marshal_dump
804
+ super() << @filename << @defined << @preprocessed
805
+ end
806
+
807
+ def marshal_load(vars)
808
+ @preprocessed = vars.pop
809
+ @defined = vars.pop
810
+ @filename = vars.pop
811
+ super(vars)
812
+ #overrule
813
+ @scopes = @enclosure.scopes || []
814
+ @scoped_name = @scopes.collect{|s| s.name}.join("::")
815
+ @scoped_lm_name = @scopes.collect{|s| s.lm_name}.join("::")
816
+ end
817
+
818
+ def is_defined?; @defined; end
819
+ def is_preprocessed?; @preprocessed; end
820
+
821
+ def repo_scopes
822
+ @repo_scopes ||= (@enclosure.nil? ? [] : @enclosure.repo_scopes.dup)
823
+ end
824
+
825
+ def introduce(node)
826
+ @enclosure.introduce(node) unless node == self
827
+ end
828
+
829
+ def undo_introduction(node)
830
+ @enclosure.undo_introduction(node) unless node == self
831
+ end
832
+
833
+ def resolve(_name)
834
+ @enclosure.resolve(_name)
835
+ end
836
+
837
+ protected
838
+ def copy_from(_template, _context)
839
+ super
840
+ @filename = _template.filename
841
+ @defined = _template.is_defined?
842
+ @preprocessed = _template.is_preprocessed?
843
+ #overrule
844
+ @scopes = @enclosure.scopes
845
+ @scoped_name = @scopes.collect{|s| s.name}.join("::")
846
+ @scoped_lm_name = @scopes.collect{|s| s.lm_name}.join("::")
847
+ self
848
+ end
849
+
850
+ def search_self(_name)
851
+ @enclosure.search_self(_name)
852
+ end
853
+ end # Include
854
+
855
+ class Derivable < Node
856
+
857
+ alias :search_self_before_derived :search_self
858
+ def search_self(_name)
859
+ node = search_self_before_derived(_name)
860
+ node = search_ancestors(_name) if node.nil?
861
+ node
862
+ end
863
+
864
+ def has_ancestor?(n)
865
+ self.has_base?(n) || resolved_bases.any? { |b| b.has_ancestor?(n) }
866
+ end
867
+
868
+ protected
869
+
870
+ def resolved_bases
871
+ []
872
+ end
873
+
874
+ def each_ancestors(visited = [], &block)
875
+ resolved_bases.each do |p|
876
+ next if visited.include? p
877
+ yield(p)
878
+ visited.push p
879
+ p.each_ancestors(visited, &block)
880
+ end
881
+ end
882
+
883
+ # search inherited interfaces.
884
+ def search_ancestors(_name)
885
+ results = []
886
+ self.each_ancestors do |interface|
887
+ node = interface.search_self(_name)
888
+ results.push(node) unless node.nil?
889
+ end
890
+ if results.size > 1
891
+ # check if the matched name resulted in multiple different nodes or all the same
892
+ r_one = results.shift
893
+ unless results.all? {|r| r_one == r || (r_one.class == r.class && r_one.scoped_name == r.scoped_name) }
894
+ s = results.inject([r_one]) {|l,r| l << r unless l.include?(r); l }.collect{ |n| n.scoped_name }.join(", ")
895
+ raise RuntimeError, "\"#{_name}\" is ambiguous. " + s
896
+ end
897
+ end
898
+ results.first
899
+ end
900
+
901
+ # recursively collect operations from bases
902
+ def base_operations(traversed)
903
+ traversed.push self
904
+ ops = []
905
+ resolved_bases.each do |base|
906
+ base = base.idltype.resolved_type.node if base.is_a?(IDL::AST::Typedef)
907
+ ops.concat(base.operations(true, traversed)) unless traversed.include?(base)
908
+ end
909
+ ops
910
+ end
911
+
912
+ # recursively collect attributes from bases
913
+ def base_attributes(traversed)
914
+ traversed.push self
915
+ atts = []
916
+ resolved_bases.each do |base|
917
+ base = base.idltype.resolved_type.node if base.is_a?(IDL::AST::Typedef)
918
+ atts.concat(base.attributes(true, traversed)) unless traversed.include?(base)
919
+ end
920
+ atts
921
+ end
922
+ end # Derivable
923
+
924
+ class Interface < Derivable
925
+ NAMETYPE = :class
926
+ DEFINABLE = [IDL::AST::Const, IDL::AST::Operation, IDL::AST::Attribute,
927
+ IDL::AST::Struct, IDL::AST::Union, IDL::AST::Typedef, IDL::AST::Enum, IDL::AST::Enumerator]
928
+ attr_reader :bases
929
+ attr_reader :idltype
930
+
931
+ def initialize(_name, _enclosure, params)
932
+ super(_name, _enclosure)
933
+ @bases = []
934
+ @resolved_bases = []
935
+ @defined = !params[:forward]
936
+ @abstract = params[:abstract]
937
+ @pseudo = params[:pseudo]
938
+ @local = params[:local]
939
+ @idltype = IDL::Type::Interface.new(self)
940
+ add_bases(params[:inherits] || [])
941
+ end
942
+
943
+ def marshal_dump
944
+ super() << @bases << @resolved_bases << @defined << @abstract << @local << @pseudo << @idltype
945
+ end
946
+
947
+ def marshal_load(vars)
948
+ @idltype = vars.pop
949
+ @pseudo = vars.pop
950
+ @local = vars.pop
951
+ @abstract = vars.pop
952
+ @defined = vars.pop
953
+ @resolved_bases = vars.pop
954
+ @bases = vars.pop
955
+ super(vars)
956
+ end
957
+
958
+ def instantiate(_context, _enclosure)
959
+ _params = {
960
+ :forward => self.is_forward?,
961
+ :abstract => self.is_abstract?,
962
+ :pseudo => self.is_pseudo?,
963
+ :local => self.is_local?,
964
+ :inherits => self.concrete_bases(_context)
965
+ }
966
+ # instantiate concrete interface def and validate
967
+ # concrete bases
968
+ super(_context, _enclosure, _params)
969
+ end
970
+
971
+ def is_abstract?; @abstract; end
972
+ def is_local?; @local; end
973
+ def is_pseudo?; @pseudo; end
974
+ def is_defined?; @defined; end
975
+ def is_forward?; not @defined; end
976
+
977
+ def add_bases(inherits_)
978
+ inherits_.each do |tc|
979
+ unless tc.is_a?(IDL::Type::ScopedName) && tc.is_node?(IDL::AST::TemplateParam)
980
+ unless (tc.is_a?(IDL::Type::ScopedName) && tc.is_node?(IDL::AST::Interface))
981
+ raise RuntimeError,
982
+ "invalid inheritance identifier for #{typename} #{scoped_lm_name}: #{tc.typename}"
983
+ end
984
+ rtc = tc.resolved_type
985
+ if rtc.node.has_ancestor?(self)
986
+ raise RuntimeError,
987
+ "circular inheritance detected for #{typename} #{scoped_lm_name}: #{tc.node.scoped_lm_name} is descendant"
988
+ end
989
+ if not rtc.node.is_defined?
990
+ raise RuntimeError,
991
+ "#{typename} #{scoped_lm_name} cannot inherit from forward declared #{tc.node.typename} #{tc.node.scoped_lm_name}"
992
+ end
993
+ if rtc.node.is_local? and not self.is_local?
994
+ raise RuntimeError,
995
+ "#{typename} #{scoped_lm_name} cannot inherit from 'local' #{tc.node.typename} #{tc.node.scoped_lm_name}"
996
+ end
997
+ if rtc.node.is_pseudo? and not self.is_pseudo?
998
+ raise RuntimeError,
999
+ "#{typename} #{scoped_lm_name} cannot inherit from 'pseudo' #{tc.node.typename} #{tc.node.scoped_lm_name}"
1000
+ end
1001
+ if self.is_abstract? and not rtc.node.is_abstract?
1002
+ raise RuntimeError,
1003
+ "'abstract' #{typename} #{scoped_lm_name} cannot inherit from non-'abstract' #{tc.node.typename} #{tc.node.scoped_lm_name}"
1004
+ end
1005
+ if self.is_local? and rtc.node.is_abstract?
1006
+ raise RuntimeError,
1007
+ "'local' #{typename} #{scoped_lm_name} cannot inherit from 'abstract' #{tc.node.typename} #{tc.node.scoped_lm_name}"
1008
+ end
1009
+ if self.has_base?(rtc.node)
1010
+ raise RuntimeError,
1011
+ "#{typename} #{scoped_lm_name} cannot inherit from #{tc.node.typename} #{tc.node.scoped_lm_name} multiple times"
1012
+ end
1013
+ # check if we indirectly derive from this base multiple times (which is ok; no further need to check)
1014
+ unless @resolved_bases.any? { |b| b.has_ancestor?(rtc.node) }
1015
+ # this is a new base so we need to check for member redefinition/ambiguity
1016
+ new_op_att_ = []
1017
+ rtc.node.walk_members do |m|
1018
+ new_op_att_ << m if m.is_a?(IDL::AST::Operation) || m.is_a?(IDL::AST::Attribute)
1019
+ end
1020
+ if new_op_att_.any? {|n| n_ = self.search_self(n.name); n_.is_a?(IDL::AST::Operation) || n_.is_a?(IDL::AST::Attribute) }
1021
+ raise RuntimeError,
1022
+ "#{typename} #{scoped_lm_name} cannot inherit from #{tc.node.typename} #{tc.node.scoped_lm_name} because of duplicated operations/attributes"
1023
+ end
1024
+ # no need to check for duplicate member names; this inheritance is ok
1025
+ end
1026
+ @resolved_bases << rtc.node
1027
+ end
1028
+ @bases << tc.node
1029
+ end
1030
+ end
1031
+
1032
+ def has_base?(_base)
1033
+ @resolved_bases.any? { |b| b == _base.idltype.resolved_type.node }
1034
+ end
1035
+
1036
+ def ancestors
1037
+ @resolved_bases
1038
+ end
1039
+
1040
+ def operations(include_bases=false,traversed=nil)
1041
+ ops = @children.find_all { |c| c.is_a?(IDL::AST::Operation) }
1042
+ ops.concat(base_operations(traversed || [])) if include_bases
1043
+ ops
1044
+ end
1045
+
1046
+ def attributes(include_bases=false,traversed=nil)
1047
+ atts = @children.find_all { |c| c.is_a?(IDL::AST::Attribute) }
1048
+ atts.concat(base_attributes(traversed || [])) if include_bases
1049
+ atts
1050
+ end
1051
+
1052
+ def redefine(node, params)
1053
+ if node.enclosure == self
1054
+ case node
1055
+ when IDL::AST::Struct, IDL::AST::Union
1056
+ if node.is_defined?
1057
+ raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
1058
+ end
1059
+ node.annotations.concat(params[:annotations])
1060
+
1061
+ _new_node = node.class.new(node.name, self, params)
1062
+ _new_node.annotations.concat(node.annotations)
1063
+ _new_node.prefix = node.prefix
1064
+ _new_node.instance_variable_set(:@repo_ver, node.instance_variable_get(:@repo_ver))
1065
+ _new_node.instance_variable_set(:@repo_id, node.instance_variable_get(:@repo_id))
1066
+
1067
+ node.switchtype = params[:switchtype] if node.is_a?(IDL::AST::Union)
1068
+
1069
+ @children << _new_node
1070
+ # replace forward node registration
1071
+ node.enclosure.undo_introduction(node)
1072
+ introduce(_new_node)
1073
+
1074
+ return _new_node
1075
+ else
1076
+ raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
1077
+ end
1078
+ end
1079
+
1080
+ case node
1081
+ when IDL::AST::Operation, IDL::AST::Attribute
1082
+ raise RuntimeError, "#{node.typename} '#{node.scoped_lm_name}' cannot be overridden."
1083
+ else
1084
+ newnode = node.class.new(node.name, self, params)
1085
+ newnode.annotations.concat(params[:annotations])
1086
+ introduce(newnode)
1087
+ @children << newnode # add overriding child
1088
+ return newnode
1089
+ end
1090
+ end
1091
+
1092
+ protected
1093
+
1094
+ def concrete_bases(_context)
1095
+ # collect all bases and resolve any template param types
1096
+ @bases.collect do |_base|
1097
+ IDL::Type::ScopedName.new(IDL::AST::TemplateParam.concrete_param(_context, _base))
1098
+ end
1099
+ end
1100
+
1101
+ def resolved_bases
1102
+ @resolved_bases
1103
+ end
1104
+ end # Interface
1105
+
1106
+ class ComponentBase < Derivable
1107
+ NAMETYPE = :class
1108
+ DEFINABLE = []
1109
+ attr_reader :base
1110
+ attr_reader :interfaces
1111
+ attr_reader :idltype
1112
+
1113
+ def initialize(_name, _enclosure, params)
1114
+ super(_name, _enclosure)
1115
+ @base = nil
1116
+ @resolved_base = nil
1117
+ @interfaces = []
1118
+ @resolved_interfaces = []
1119
+ set_base(params[:base]) if params[:base]
1120
+ add_interfaces(params[:supports] || [])
1121
+ end
1122
+
1123
+ def marshal_dump
1124
+ super() << @base << @resolved_base << @interfaces << @resolved_interfaces << @idltype
1125
+ end
1126
+
1127
+ def marshal_load(vars)
1128
+ @idltype = vars.pop
1129
+ @resolved_interfaces = vars.pop
1130
+ @interfaces = vars.pop
1131
+ @resolved_base = vars.pop
1132
+ @base = vars.pop
1133
+ super(vars)
1134
+ end
1135
+
1136
+ def instantiate(_context, _enclosure, _params = {})
1137
+ _params.merge!({
1138
+ :base => @base ? IDL::Type::ScopedName.new(IDL::AST::TemplateParam.concrete_param(_context, @base)) : @base,
1139
+ :supports => self.concrete_interfaces(_context)
1140
+ })
1141
+ # instantiate concrete def and validate
1142
+ super(_context, _enclosure, _params)
1143
+ end
1144
+
1145
+ def set_base(parent)
1146
+ unless parent.is_a?(IDL::Type::ScopedName) && parent.is_node?(IDL::AST::TemplateParam)
1147
+ unless (parent.is_a?(IDL::Type::ScopedName) && parent.is_node?(self.class))
1148
+ raise RuntimeError,
1149
+ "invalid inheritance identifier for #{typename} #{scoped_lm_name}: #{parent.typename}"
1150
+ end
1151
+ if parent.resolved_type.node.has_base?(self)
1152
+ raise RuntimeError,
1153
+ "circular inheritance detected for #{typename} #{scoped_lm_name}: #{parent.node.scoped_lm_name} is descendant"
1154
+ end
1155
+ @resolved_base = parent.resolved_type.node
1156
+ end
1157
+ @base = parent.node
1158
+ end
1159
+
1160
+ def has_base?(n)
1161
+ @resolved_base && (@resolved_base == n.idltype.resolved_type.node) # || @resolved_base.has_base?(n))
1162
+ end
1163
+
1164
+ def ancestors
1165
+ resolved_bases
1166
+ end
1167
+
1168
+ def add_interfaces(intfs)
1169
+ intfs.each do |tc|
1170
+ unless tc.is_a?(IDL::Type::ScopedName) && tc.is_node?(IDL::AST::TemplateParam)
1171
+ unless (tc.is_a?(IDL::Type::ScopedName) && tc.is_node?(IDL::AST::Interface))
1172
+ raise RuntimeError,
1173
+ "invalid inheritance identifier for #{typename} #{scoped_lm_name}: #{tc.typename}"
1174
+ end
1175
+ rtc = tc.resolved_type
1176
+ if not rtc.node.is_defined?
1177
+ raise RuntimeError,
1178
+ "#{typename} #{scoped_lm_name} cannot support forward declared #{tc.node.typename} #{tc.node.scoped_lm_name}"
1179
+ end
1180
+ ## TODO : is this legal?
1181
+ if rtc.node.is_local?
1182
+ raise RuntimeError,
1183
+ "#{typename} #{scoped_lm_name} cannot support 'local' #{tc.node.typename} #{tc.node.scoped_lm_name}"
1184
+ end
1185
+ if rtc.node.is_pseudo?
1186
+ raise RuntimeError,
1187
+ "#{typename} #{scoped_lm_name} cannot support 'pseudo' #{tc.node.typename} #{tc.node.scoped_lm_name}"
1188
+ end
1189
+ ## TODO : is this legal?
1190
+ #if tc.node.is_abstract?
1191
+ # raise RuntimeError,
1192
+ # "'abstract' #{typename} #{scoped_lm_name} cannot support 'abstract' #{tc.node.typename} #{tc.node.scoped_lm_name}"
1193
+ #end
1194
+ if self.has_support?(rtc.node)
1195
+ raise RuntimeError,
1196
+ "#{typename} #{scoped_lm_name} cannot support #{tc.node.typename} #{tc.node.scoped_lm_name} multiple times"
1197
+ end
1198
+ # check if we indirectly support this base multiple times (which is ok; no further need to check)
1199
+ unless @resolved_interfaces.any? { |b| b.has_ancestor?(rtc.node) }
1200
+ # this is a new support interface so we need to check for member redefinition/ambiguity
1201
+ new_op_att_ = []
1202
+ rtc.node.walk_members do |m|
1203
+ new_op_att_ << m if m.is_a?(IDL::AST::Operation) || m.is_a?(IDL::AST::Attribute)
1204
+ end
1205
+ if new_op_att_.any? {|n| n_ = self.search_self(n.name); n_.is_a?(IDL::AST::Operation) || n_.is_a?(IDL::AST::Attribute) }
1206
+ raise RuntimeError,
1207
+ "#{typename} #{scoped_lm_name} cannot support #{tc.node.typename} #{tc.node.scoped_lm_name} because of duplicated operations/attributes"
1208
+ end
1209
+ # no need to check for duplicate member names; this support is ok
1210
+ end
1211
+ @resolved_interfaces << rtc.node
1212
+ end
1213
+ @interfaces << tc.node
1214
+ end
1215
+ end
1216
+
1217
+ def has_support?(intf)
1218
+ @resolved_interfaces.any? { |b| b == intf.idltype.resolved_type.node }
1219
+ end
1220
+
1221
+ def supports?(intf)
1222
+ self.has_support?(intf) || (@resolved_base && @resolved_base.supports?(intf)) || @resolved_interfaces.any? { |base_i| i.has_ancestor?(intf) }
1223
+ end
1224
+
1225
+ def redefine(node, params)
1226
+ if node.enclosure == self
1227
+ case node
1228
+ when IDL::AST::Struct, IDL::AST::Union
1229
+ if node.is_defined?
1230
+ raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
1231
+ end
1232
+ node.annotations.concat(params[:annotations])
1233
+
1234
+ _new_node = node.class.new(node.name, self, params)
1235
+ _new_node.annotations.concat(node.annotations)
1236
+ _new_node.prefix = node.prefix
1237
+ _new_node.instance_variable_set(:@repo_ver, node.instance_variable_get(:@repo_ver))
1238
+ _new_node.instance_variable_set(:@repo_id, node.instance_variable_get(:@repo_id))
1239
+
1240
+ node.switchtype = params[:switchtype] if node.is_a?(IDL::AST::Union)
1241
+
1242
+ @children << _new_node
1243
+ # replace forward node registration
1244
+ node.enclosure.undo_introduction(node)
1245
+ introduce(_new_node)
1246
+
1247
+ return _new_node
1248
+ else
1249
+ raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
1250
+ end
1251
+ end
1252
+
1253
+ case node
1254
+ when IDL::AST::Operation, IDL::AST::Attribute
1255
+ raise RuntimeError, "#{node.typename} '#{node.scoped_lm_name}' cannot be overridden."
1256
+ else
1257
+ newnode = node.class.new(node.name, self, params)
1258
+ newnode.annotations.concat(params[:annotations])
1259
+ introduce(newnode)
1260
+ @children << newnode # add overriding child
1261
+ return newnode
1262
+ end
1263
+ end
1264
+
1265
+ protected
1266
+
1267
+ def resolved_bases
1268
+ (@resolved_base ? [@resolved_base] : []).concat(@resolved_interfaces)
1269
+ end
1270
+
1271
+ def concrete_interfaces(_context)
1272
+ # collect all bases and resolve any template param types
1273
+ @interfaces.collect do |_intf|
1274
+ IDL::Type::ScopedName.new(IDL::AST::TemplateParam.concrete_param(_context, _intf))
1275
+ end
1276
+ end
1277
+ end # ComponentBase
1278
+
1279
+ class Home < ComponentBase
1280
+ NAMETYPE = :class
1281
+ DEFINABLE = [IDL::AST::Const, IDL::AST::Operation, IDL::AST::Attribute, IDL::AST::Initializer, IDL::AST::Finder,
1282
+ IDL::AST::Struct, IDL::AST::Union, IDL::AST::Typedef, IDL::AST::Enum, IDL::AST::Enumerator]
1283
+ attr_reader :component
1284
+ attr_reader :primarykey
1285
+
1286
+ def initialize(_name, _enclosure, params)
1287
+ @component = nil
1288
+ @resolved_comp = nil
1289
+ @primarykey = nil
1290
+ @resolved_pk = nil
1291
+ @idltype = IDL::Type::Home.new(self)
1292
+ super(_name, _enclosure, params)
1293
+ set_component_and_key(params[:component], params[:primarykey])
1294
+ end
1295
+
1296
+ def marshal_dump
1297
+ super() << @component << @resolved_comp << @primarykey << @resolved_pk
1298
+ end
1299
+
1300
+ def marshal_load(vars)
1301
+ @resolved_pk = vars.pop
1302
+ @primarykey = vars.pop
1303
+ @resolved_comp = vars.pop
1304
+ @component = vars.pop
1305
+ super(vars)
1306
+ end
1307
+
1308
+ def instantiate(_context, _enclosure)
1309
+ _params = {
1310
+ :component => IDL::Type::ScopedName.new(IDL::AST::TemplateParam.concrete_param(_context, @component)),
1311
+ :primarykey => @primarykey ? IDL::Type::ScopedName.new(IDL::AST::TemplateParam.concrete_param(_context, @primarykey)) : @primarykey
1312
+ }
1313
+ # instantiate concrete home def and validate
1314
+ super(_context, _enclosure, _params)
1315
+ end
1316
+
1317
+ def set_component_and_key(comp, key)
1318
+ unless comp && comp.is_a?(IDL::Type::ScopedName) && comp.is_node?(IDL::AST::TemplateParam)
1319
+ unless comp && comp.is_a?(IDL::Type::ScopedName) && comp.is_node?(IDL::AST::Component)
1320
+ raise RuntimeError,
1321
+ (comp ?
1322
+ "invalid managed component for #{typename} #{scoped_lm_name}: #{comp.typename}" :
1323
+ "missing managed component specification for #{typename} #{scoped_lm_name}")
1324
+ end
1325
+ unless comp.resolved_type.node.is_defined?
1326
+ raise RuntimeError,
1327
+ "#{scoped_lm_name}: #{comp.typename} cannot manage forward declared component #{comp.node.scoped_lm_name}"
1328
+ end
1329
+ @resolved_comp = comp.resolved_type.node
1330
+ end
1331
+ unless key && key.is_a?(IDL::Type::ScopedName) && key.is_node?(IDL::AST::TemplateParam)
1332
+ ## TODO : add check for Components::PrimaryKeyBase base type
1333
+ unless key.nil? || (key.is_a?(IDL::Type::ScopedName) && key.is_node?(IDL::AST::Valuetype))
1334
+ raise RuntimeError,
1335
+ "invalid primary key for #{typename} #{scoped_lm_name}: #{key.typename}"
1336
+ end
1337
+ @resolved_pk = key.resolved_type.node if key
1338
+ end
1339
+ @component = comp.node
1340
+ @primarykey = key.node if key
1341
+ end
1342
+
1343
+ def operations(include_bases=false,traversed=nil)
1344
+ ops = @children.find_all { |c| c.is_a?(IDL::AST::Operation) }
1345
+ ops.concat(base_operations(traversed || [])) if include_bases
1346
+ ops
1347
+ end
1348
+
1349
+ def attributes(include_bases=false,traversed=nil)
1350
+ atts = @children.find_all { |c| c.is_a?(IDL::AST::Attribute) }
1351
+ atts.concat(base_attributes(traversed || [])) if include_bases
1352
+ atts
1353
+ end
1354
+
1355
+ end # Home
1356
+
1357
+ class Connector < ComponentBase
1358
+ NAMETYPE = :class
1359
+ DEFINABLE = [IDL::AST::Attribute, IDL::AST::Port]
1360
+
1361
+ def initialize(_name, _enclosure, params)
1362
+ @idltype = IDL::Type::Component.new(self)
1363
+ super(_name, _enclosure, params)
1364
+ end
1365
+
1366
+ def marshal_dump
1367
+ super()
1368
+ end
1369
+
1370
+ def marshal_load(vars)
1371
+ super(vars)
1372
+ end
1373
+
1374
+ def instantiate(_context, _enclosure)
1375
+ # instantiate concrete connector def and validate
1376
+ super(_context, _enclosure, {})
1377
+ end
1378
+
1379
+ def is_defined?; true; end
1380
+ def is_forward?; false; end
1381
+
1382
+ def add_interfaces(intfs)
1383
+ raise RuntimeError, "interface support not allowed for #{typename} #{scoped_lm_name}" if intfs && !intfs.empty?
1384
+ end
1385
+
1386
+ def set_base(parent)
1387
+ unless parent.is_a?(IDL::Type::ScopedName) && parent.is_node?(IDL::AST::TemplateParam)
1388
+ if not (parent.is_a?(IDL::Type::ScopedName) && parent.is_node?(self.class))
1389
+ raise RuntimeError,
1390
+ "invalid inheritance identifier for #{typename} #{scoped_lm_name}: #{parent.typename}"
1391
+ end
1392
+ @resolved_base = parent.resolved_type.node
1393
+ if @resolved_base.has_base?(self)
1394
+ raise RuntimeError,
1395
+ "circular inheritance detected for #{typename} #{scoped_lm_name}: #{parent.node.scoped_lm_name} is descendant"
1396
+ end
1397
+ end
1398
+ @base = parent.node
1399
+ end
1400
+
1401
+ def ports(include_bases=false,traversed=nil)
1402
+ ports = @children.inject([]) do |lst, c|
1403
+ lst.concat(c.ports) if IDL::AST::Port === c
1404
+ lst
1405
+ end
1406
+ ports.concat(base_ports(traversed || [])) if include_bases
1407
+ ports
1408
+ end
1409
+
1410
+ def attributes(include_bases=false,traversed=nil)
1411
+ atts = @children.inject([]) do |lst, c|
1412
+ if IDL::AST::Port === c
1413
+ lst.concat(c.attributes)
1414
+ else
1415
+ lst << c
1416
+ end
1417
+ lst
1418
+ end
1419
+ atts.concat(base_attributes(traversed || [])) if include_bases
1420
+ atts
1421
+ end
1422
+
1423
+ protected
1424
+
1425
+ # recursively collect ports from bases
1426
+ def base_ports(traversed)
1427
+ traversed.push self
1428
+ ports = []
1429
+ if (base = @resolved_base)
1430
+ base = base.idltype.resolved_type.node if base.is_a?(IDL::AST::Typedef)
1431
+ ports = base.ports(true, traversed) unless traversed.include?(base)
1432
+ end
1433
+ ports
1434
+ end
1435
+
1436
+ end # Connector
1437
+
1438
+ class Component < ComponentBase
1439
+ NAMETYPE = :class
1440
+ DEFINABLE = [IDL::AST::Attribute, IDL::AST::Port]
1441
+
1442
+ def initialize(_name, _enclosure, params)
1443
+ @idltype = IDL::Type::Component.new(self)
1444
+ super(_name, _enclosure, params)
1445
+ @defined = !params[:forward]
1446
+ end
1447
+
1448
+ def marshal_dump
1449
+ super() << @defined
1450
+ end
1451
+
1452
+ def marshal_load(vars)
1453
+ @defined = vars.pop
1454
+ super(vars)
1455
+ end
1456
+
1457
+ def instantiate(_context, _enclosure)
1458
+ # instantiate concrete component def and validate
1459
+ super(_context, _enclosure, { :forward => self.is_forward? })
1460
+ end
1461
+
1462
+ def is_defined?; @defined; end
1463
+ def is_forward?; not @defined; end
1464
+
1465
+ def set_base(parent)
1466
+ unless parent.is_a?(IDL::Type::ScopedName) && parent.is_node?(IDL::AST::TemplateParam)
1467
+ if not (parent.is_a?(IDL::Type::ScopedName) && parent.is_node?(self.class))
1468
+ raise RuntimeError,
1469
+ "invalid inheritance identifier for #{typename} #{scoped_lm_name}: #{parent.typename}"
1470
+ end
1471
+ @resolved_base = parent.resolved_type.node
1472
+ if not @resolved_base.is_defined?
1473
+ raise RuntimeError,
1474
+ "#{typename} #{scoped_lm_name} cannot inherit from forward declared #{parent.node.typename} #{parent.node.scoped_lm_name}"
1475
+ end
1476
+ if @resolved_base.has_base?(self)
1477
+ raise RuntimeError,
1478
+ "circular inheritance detected for #{typename} #{scoped_lm_name}: #{parent.node.scoped_lm_name} is descendant"
1479
+ end
1480
+ end
1481
+ @base = parent.node
1482
+ end
1483
+
1484
+ def ports(include_bases=false,traversed=nil)
1485
+ ports = @children.inject([]) do |lst, c|
1486
+ lst.concat(c.ports) if IDL::AST::Port === c
1487
+ lst
1488
+ end
1489
+ ports.concat(base_ports(traversed || [])) if include_bases
1490
+ ports
1491
+ end
1492
+
1493
+ def operations(include_bases=false,traversed=nil)
1494
+ include_bases ? base_operations(traversed || []) : []
1495
+ end
1496
+
1497
+ def attributes(include_bases=false,traversed=nil)
1498
+ atts = @children.inject([]) do |lst, c|
1499
+ if IDL::AST::Port === c
1500
+ lst.concat(c.attributes)
1501
+ else
1502
+ lst << c
1503
+ end
1504
+ lst
1505
+ end
1506
+ atts.concat(base_attributes(traversed || [])) if include_bases
1507
+ atts
1508
+ end
1509
+
1510
+ protected
1511
+
1512
+ # recursively collect ports from bases
1513
+ def base_ports(traversed)
1514
+ traversed.push self
1515
+ ports = []
1516
+ if (base = @resolved_base)
1517
+ base = base.idltype.resolved_type.node if base.is_a?(IDL::AST::Typedef)
1518
+ ports = base.ports(true, traversed) unless traversed.include?(base)
1519
+ end
1520
+ ports
1521
+ end
1522
+
1523
+ end # Component
1524
+
1525
+ class Porttype < Node
1526
+ NAMETYPE = :class
1527
+ DEFINABLE = [IDL::AST::Attribute, IDL::AST::Port]
1528
+ attr_reader :idltype
1529
+ def initialize(_name, _enclosure, params)
1530
+ super(_name, _enclosure)
1531
+ @idltype = IDL::Type::Porttype.new(self)
1532
+ end
1533
+
1534
+ def ports
1535
+ @children.select {|c| IDL::AST::Port === c}
1536
+ end
1537
+
1538
+ def attributes
1539
+ @children.select {|c| IDL::AST::Attribute === c}
1540
+ end
1541
+
1542
+ def instantiate(_context, _enclosure)
1543
+ super(_context, _enclosure, {})
1544
+ end
1545
+ end # Porttype
1546
+
1547
+ class Port < Leaf
1548
+ NAMETYPE = :member
1549
+ PORTTYPES = [:facet, :receptacle, :emitter, :publisher, :consumer, :port, :mirrorport]
1550
+ PORT_MIRRORS = {:facet => :receptacle, :receptacle => :facet}
1551
+ EXTPORTDEF_ANNOTATION = 'ExtendedPortDef'
1552
+ attr_reader :idltype
1553
+ attr_reader :porttype
1554
+ def initialize(_name, _enclosure, params)
1555
+ super(_name, _enclosure)
1556
+ @idltype = params[:type]
1557
+ @porttype = params[:porttype]
1558
+ raise RuntimeError, "unknown porttype for #{typename} #{scoped_lm_name}: #{@porttype}" unless PORTTYPES.include?(@porttype)
1559
+ case @porttype
1560
+ when :facet, :receptacle
1561
+ unless @idltype.is_a?(IDL::Type::Object) ||
1562
+ (@idltype.is_a?(IDL::Type::ScopedName) && (@idltype.is_node?(IDL::AST::Interface) || @idltype.is_node?(IDL::AST::TemplateParam)))
1563
+ raise RuntimeError, "invalid type for #{typename} #{scoped_lm_name}: #{@idltype.typename}"
1564
+ end
1565
+ when :port, :mirrorport
1566
+ unless @idltype.is_a?(IDL::Type::ScopedName) && (@idltype.is_node?(IDL::AST::Porttype) || @idltype.is_node?(IDL::AST::TemplateParam))
1567
+ raise RuntimeError, "invalid type for #{typename} #{scoped_lm_name}: #{@idltype.typename}"
1568
+ end
1569
+ else
1570
+ unless @idltype.is_a?(IDL::Type::ScopedName) && (@idltype.is_node?(IDL::AST::Eventtype) || @idltype.is_node?(IDL::AST::TemplateParam))
1571
+ raise RuntimeError, "invalid type for #{typename} #{scoped_lm_name}: #{@idltype.typename}"
1572
+ end
1573
+ end
1574
+ @multiple = params[:multiple] ? true : false
1575
+ end
1576
+
1577
+ def instantiate(_context, _enclosure)
1578
+ _params = {
1579
+ :type => @idltype.instantiate(_context),
1580
+ :porttype => @porttype,
1581
+ :multiple => @multiple
1582
+ }
1583
+ super(_context, _enclosure, _params)
1584
+ end
1585
+
1586
+ def multiple?
1587
+ @multiple
1588
+ end
1589
+
1590
+ def expanded_copy(name_pfx, enc)
1591
+ p = IDL::AST::Port.new("#{name_pfx}_#{self.name}", enc, {:type => @idltype, :porttype => @porttype})
1592
+ p.annotations << Annotation.new(EXTPORTDEF_ANNOTATION, { :extended_port_name => name_pfx, :base_name => self.name, :mirror => false })
1593
+ p # return expanded copy
1594
+ end
1595
+
1596
+ def expanded_mirror_copy(name_pfx, enc)
1597
+ p = IDL::AST::Port.new("#{name_pfx}_#{self.name}", enc, {:type => @idltype, :porttype => PORT_MIRRORS[@porttype]})
1598
+ p.annotations << Annotation.new(EXTPORTDEF_ANNOTATION, { :extended_port_name => name_pfx, :base_name => self.name, :mirror => true })
1599
+ p # return expanded copy
1600
+ end
1601
+
1602
+ def ports
1603
+ case @porttype
1604
+ when :port
1605
+ @idltype.resolved_type.node.ports.collect {|p| p.expanded_copy(self.name, self.enclosure) }
1606
+ when :mirrorport
1607
+ @idltype.resolved_type.node.ports.collect {|p| p.expanded_mirror_copy(self.name, self.enclosure) }
1608
+ else
1609
+ [self]
1610
+ end
1611
+ end
1612
+
1613
+ def attributes
1614
+ case @porttype
1615
+ when :port, :mirrorport
1616
+ @idltype.resolved_type.node.attributes.collect {|att|
1617
+ exp_a = att.expanded_copy(self.name, self.enclosure)
1618
+ exp_a.annotations << Annotation.new(EXTPORTDEF_ANNOTATION, { :extended_port_name => self.name, :base_name => att.name, :mirror => (@porttype == :mirrorport) })
1619
+ exp_a # return expanded copy
1620
+ }
1621
+ else
1622
+ []
1623
+ end
1624
+ end
1625
+ end # Port
1626
+
1627
+ class Valuebox < Leaf
1628
+ NAMETYPE = :class
1629
+ attr_reader :idltype, :boxed_type
1630
+ def initialize(_name, _enclosure, params)
1631
+ super(_name, _enclosure)
1632
+ @idltype = IDL::Type::Valuebox.new(self)
1633
+ @boxed_type = params[:type]
1634
+ unless @boxed_type.is_a?(IDL::Type::ScopedName) && @boxed_type.is_node?(IDL::AST::TemplateParam)
1635
+ if @boxed_type.resolved_type.is_a?(IDL::Type::Valuetype)
1636
+ raise RuntimeError,
1637
+ "boxing valuetype #{@boxed_type.scoped_lm_name} in Valuebox #{scoped_lm_name} not allowed"
1638
+ end
1639
+ end
1640
+ end
1641
+
1642
+ def is_local?(recurstk = [])
1643
+ boxed_type.is_local?(recurstk)
1644
+ end
1645
+
1646
+ def marshal_dump
1647
+ super() << @idltype << @boxed_type
1648
+ end
1649
+
1650
+ def marshal_load(vars)
1651
+ @boxed_type = vars.pop
1652
+ @idltype = vars.pop
1653
+ super(vars)
1654
+ end
1655
+
1656
+ def instantiate(_context, _enclosure)
1657
+ _params = {
1658
+ :type => @boxed_type.instantiate(_context)
1659
+ }
1660
+ super(_context, _enclosure, _params)
1661
+ end
1662
+ end # Valuebox
1663
+
1664
+ class Valuetype < Derivable
1665
+ NAMETYPE = :class
1666
+ DEFINABLE = [IDL::AST::Include, IDL::AST::Const, IDL::AST::Operation, IDL::AST::Attribute, IDL::AST::StateMember, IDL::AST::Initializer,
1667
+ IDL::AST::Struct, IDL::AST::Union, IDL::AST::Typedef, IDL::AST::Enum, IDL::AST::Enumerator]
1668
+ attr_reader :bases, :interfaces
1669
+ attr_reader :idltype
1670
+
1671
+ def initialize(_name, _enclosure, params)
1672
+ super(_name, _enclosure)
1673
+ @bases = []
1674
+ @resolved_bases = []
1675
+ @interfaces = []
1676
+ @resolved_interfaces = []
1677
+ @defined = false
1678
+ @recursive = false
1679
+ @forward = params[:forward] ? true : false
1680
+ @abstract = params[:abstract]
1681
+ @idltype = IDL::Type::Valuetype.new(self)
1682
+ complete_definition(params)
1683
+ end
1684
+
1685
+ def complete_definition(params)
1686
+ unless params[:forward]
1687
+ @custom = params[:custom] || false
1688
+ _inherits = params[:inherits] || {}
1689
+ _base = _inherits[:base] || {}
1690
+ @truncatable = _base[:truncatable] || false
1691
+ if @custom && @truncatable
1692
+ raise RuntimeError,
1693
+ "'truncatable' attribute *not* allowed for 'custom' #{typename} #{scoped_lm_name}"
1694
+ end
1695
+ add_bases(_base[:list] || [])
1696
+ add_interfaces(_inherits[:supports] || [])
1697
+ end
1698
+ end
1699
+
1700
+ def marshal_dump
1701
+ super() << @bases << @resolved_bases <<
1702
+ @interfaces << @resolved_interfaces <<
1703
+ @defined << @recursive <<
1704
+ @forward << @abstract <<
1705
+ @custom << @truncatable << @idltype
1706
+ end
1707
+
1708
+ def marshal_load(vars)
1709
+ @idltype = vars.pop
1710
+ @truncatable = vars.pop
1711
+ @custom = vars.pop
1712
+ @abstract = vars.pop
1713
+ @forward = vars.pop
1714
+ @recursive = vars.pop
1715
+ @defined = vars.pop
1716
+ @resolved_interfaces = vars.pop
1717
+ @interfaces = vars.pop
1718
+ @resolved_bases = vars.pop
1719
+ @bases = vars.pop
1720
+ super(vars)
1721
+ end
1722
+
1723
+ def instantiate(_context, _enclosure)
1724
+ _params = {
1725
+ :forward => self.is_forward?,
1726
+ :abstract => self.is_abstract?,
1727
+ :custom => self.is_custom?,
1728
+ :inherits => {
1729
+ :base => {
1730
+ :truncatable => self.is_truncatable?,
1731
+ :list => self.concrete_bases(_context)
1732
+ },
1733
+ :supports => self.concrete_interfaces(_context)
1734
+ }
1735
+ }
1736
+ inst = super(_context, _enclosure, _params)
1737
+ inst.defined = true
1738
+ inst
1739
+ end
1740
+
1741
+ def is_abstract?; @abstract; end
1742
+ def is_custom?; @custom; end
1743
+ def is_truncatable?; @truncatable; end
1744
+ def is_defined?; @defined; end
1745
+ def defined=(f); @defined = f; end
1746
+ def is_forward?; @forward; end
1747
+ def is_recursive?; @recursive end
1748
+ def recursive=(f); @recursive = f end
1749
+
1750
+ def is_local?(recurstk = [])
1751
+ # not local if forward decl or recursion detected
1752
+ return false if is_forward? || recurstk.include?(self)
1753
+ recurstk.push self # track root node to detect recursion
1754
+ ret = state_members.any? { |m| m.is_local?(recurstk) }
1755
+ recurstk.pop
1756
+ ret
1757
+ end
1758
+
1759
+ def modifier
1760
+ if is_abstract?
1761
+ :abstract
1762
+ elsif is_custom?
1763
+ :custom
1764
+ elsif is_truncatable?
1765
+ :truncatable
1766
+ else
1767
+ :none
1768
+ end
1769
+ end
1770
+
1771
+ def has_concrete_base?
1772
+ (not @resolved_bases.empty?) and (not @resolved_bases.first.is_abstract?)
1773
+ end
1774
+
1775
+ def supports_concrete_interface?
1776
+ !(@resolved_interfaces.empty? || @resolved_interfaces.first.is_abstract?)
1777
+ end
1778
+
1779
+ def supports_abstract_interface?
1780
+ @resolved_interfaces.any? { |intf| intf.is_abstract? }
1781
+ end
1782
+
1783
+ def truncatable_ids
1784
+ ids = [self.repository_id()]
1785
+ ids.concat(@resolved_bases.first().truncatable_ids()) if self.has_concrete_base?() && self.is_truncatable?()
1786
+ ids
1787
+ end
1788
+
1789
+ def add_bases(inherits_)
1790
+ inherits_.each do |tc|
1791
+ unless tc.is_a?(IDL::Type::ScopedName) && tc.is_node?(IDL::AST::TemplateParam)
1792
+ if not (tc.is_a?(IDL::Type::ScopedName) && tc.is_node?(IDL::AST::Valuetype))
1793
+ raise RuntimeError,
1794
+ "invalid inheritance identifier for #{typename} #{scoped_lm_name}: #{tc.typename}"
1795
+ end
1796
+ rtc = tc.resolved_type
1797
+ if rtc.node.has_ancestor?(self)
1798
+ raise RuntimeError,
1799
+ "circular inheritance detected for #{typename} #{scoped_lm_name}: #{tc.node.scoped_lm_name} is descendant"
1800
+ end
1801
+ if not rtc.node.is_defined?
1802
+ raise RuntimeError,
1803
+ "#{typename} #{scoped_lm_name} cannot inherit from forward declared #{tc.node.typename} #{tc.node.scoped_lm_name}"
1804
+ end
1805
+ if self.is_abstract? and not rtc.node.is_abstract?
1806
+ raise RuntimeError,
1807
+ "'abstract' #{typename} #{scoped_lm_name} cannot inherit from non-'abstract' #{tc.node.typename} #{tc.node.scoped_lm_name}"
1808
+ end
1809
+ if (not self.is_custom?) and rtc.node.is_custom?
1810
+ raise RuntimeError,
1811
+ "non-'custom' #{typename} #{scoped_lm_name} cannot inherit from 'custom' #{tc.node.typename} #{tc.node.scoped_lm_name}"
1812
+ end
1813
+ if @resolved_bases.include?(rtc.node)
1814
+ raise RuntimeError,
1815
+ "#{typename} #{scoped_lm_name} cannot inherit from #{tc.node.typename} #{tc.node.scoped_lm_name} multiple times"
1816
+ end
1817
+ if (not rtc.node.is_abstract?) and @bases.size > 0
1818
+ raise RuntimeError,
1819
+ "concrete basevalue #{tc.node.typename} #{tc.node.scoped_lm_name} MUST "+
1820
+ "be first and only non-abstract in inheritance list for #{typename} #{scoped_lm_name}"
1821
+ end
1822
+ @resolved_bases << rtc.node
1823
+ end
1824
+ @bases << tc.node
1825
+ end
1826
+ end
1827
+
1828
+ def add_interfaces(iflist_)
1829
+ iflist_.each do |if_|
1830
+ unless if_.is_a?(IDL::Type::ScopedName) && if_.is_node?(IDL::AST::TemplateParam)
1831
+ if not (if_.is_a?(IDL::Type::ScopedName) && if_.is_node?(IDL::AST::Interface))
1832
+ raise RuntimeError,
1833
+ "invalid support identifier for #{typename} #{scoped_lm_name}: #{if_.typename}"
1834
+ end
1835
+ rif_ = if_.resolved_type
1836
+ ### @@TODO@@ further validation
1837
+ if (not rif_.node.is_abstract?) and @interfaces.size > 0
1838
+ raise RuntimeError,
1839
+ "concrete interface #{tc.node.typename} #{tc.node.scoped_lm_name} MUST be first and only in supports list for #{typename} #{scoped_lm_name}"
1840
+ end
1841
+ if (not rif_.node.is_abstract?) && (not is_interface_compatible?(rif_.node))
1842
+ raise RuntimeError,
1843
+ "#{typename} #{scoped_lm_name} cannot support #{tc.node.typename} #{tc.node.scoped_lm_name} because it does not derive from inherited interfaces"
1844
+ end
1845
+ @resolved_interfaces << rif_.node
1846
+ end
1847
+ @interfaces << if_.node
1848
+ end
1849
+ end
1850
+
1851
+ def has_ancestor?(n)
1852
+ @resolved_bases.include?(n.idltype.resolved_type.node) || @resolved_bases.any? { |b| b.has_ancestor?(n) }
1853
+ end
1854
+
1855
+ def is_interface_compatible?(n)
1856
+ if @resolved_interfaces.empty? || @resolved_interfaces.first.is_abstract?
1857
+ @resolved_bases.all? { |b| b.is_interface_compatible?(n) }
1858
+ else
1859
+ n.idltype.resolved_type.node.has_ancestor?(@interfaces.first)
1860
+ end
1861
+ end
1862
+
1863
+ def define(_type, _name, *args)
1864
+ if self.is_abstract? && [IDL::AST::StateMember, IDL::AST::Initializer].include?(_type)
1865
+ raise RuntimeError, "cannot define statemember #{_name} on abstract #{typename} #{scoped_lm_name}"
1866
+ end
1867
+ super(_type, _name, *args)
1868
+ end
1869
+
1870
+ def walk_members(&block)
1871
+ @children.each { |c| yield(c) unless c.is_a?(IDL::AST::StateMember) or
1872
+ c.is_a?(IDL::AST::Operation) or
1873
+ c.is_a?(IDL::AST::Attribute) or
1874
+ c.is_a?(IDL::AST::Initializer)
1875
+ }
1876
+ end
1877
+
1878
+ def state_members
1879
+ @children.find_all { |c| c.is_a?(IDL::AST::StateMember) }
1880
+ end
1881
+
1882
+ def interface_members
1883
+ @children.find_all { |c| c.is_a?(IDL::AST::Operation) or c.is_a?(IDL::AST::Attribute) }
1884
+ end
1885
+
1886
+ def initializers
1887
+ @children.find_all { |c| c.is_a?(IDL::AST::Initializer) }
1888
+ end
1889
+
1890
+ def has_operations_or_attributes?(include_intf = true)
1891
+ @children.any? { |c| c.is_a?(IDL::AST::Operation) || c.is_a?(IDL::AST::Attribute) } ||
1892
+ @resolved_bases.any? { |b| b.has_operations_or_attributes? } ||
1893
+ (include_intf &&
1894
+ @resolved_interfaces.any? { |intf| !intf.operations(true).empty? || !intf.attributes(true).empty? })
1895
+ end
1896
+
1897
+ def redefine(node, params)
1898
+ if node.enclosure == self
1899
+ case node
1900
+ when IDL::AST::Struct, IDL::AST::Union
1901
+ if node.is_defined?
1902
+ raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
1903
+ end
1904
+ node.annotations.concat(params[:annotations])
1905
+
1906
+ _new_node = node.class.new(node.name, self, params)
1907
+ _new_node.annotations.concat(node.annotations)
1908
+ _new_node.prefix = node.prefix
1909
+ _new_node.instance_variable_set(:@repo_ver, node.instance_variable_get(:@repo_ver))
1910
+ _new_node.instance_variable_set(:@repo_id, node.instance_variable_get(:@repo_id))
1911
+
1912
+ node.switchtype = params[:switchtype] if node.is_a?(IDL::AST::Union)
1913
+
1914
+ @children << _new_node
1915
+ # replace forward node registration
1916
+ node.enclosure.undo_introduction(node)
1917
+ introduce(_new_node)
1918
+
1919
+ return _new_node
1920
+ else
1921
+ raise RuntimeError, "#{node.typename} \"#{node.name}\" is already defined."
1922
+ end
1923
+ end
1924
+
1925
+ case node
1926
+ when IDL::AST::Operation, IDL::AST::Attribute, IDL::AST::StateMember, IDL::AST::Initializer
1927
+ raise RuntimeError, "#{node.typename} '#{node.scoped_lm_name}' cannot be overridden."
1928
+ else
1929
+ newnode = node.class.new(node.name, self, params)
1930
+ newnode.annotations.concat(params[:annotations])
1931
+ introduce(newnode)
1932
+ return newnode
1933
+ end
1934
+ end
1935
+
1936
+ protected
1937
+
1938
+ def walk_members_for_copy(&block)
1939
+ @children.each { |c| yield(c) }
1940
+ end
1941
+
1942
+ def resolved_bases
1943
+ @resolved_bases
1944
+ end
1945
+
1946
+ def concrete_bases(_context)
1947
+ # collect all bases and resolve any template param types
1948
+ @bases.collect do |_base|
1949
+ IDL::Type::ScopedName.new(IDL::AST::TemplateParam.concrete_param(_context, _base))
1950
+ end
1951
+ end
1952
+
1953
+ def concrete_interfaces(_context)
1954
+ @interfaces.collect do |_intf|
1955
+ IDL::Type::ScopedName.new(IDL::AST::TemplateParam.concrete_param(_context, _intf))
1956
+ end
1957
+ end
1958
+ end # Valuetype
1959
+
1960
+ class Eventtype < Valuetype
1961
+ def initialize(_name, _enclosure, params)
1962
+ super(_name, _enclosure, params)
1963
+ # overrule
1964
+ @idltype = IDL::Type::Eventtype.new(self)
1965
+ end
1966
+ end # Eventtype
1967
+
1968
+ class StateMember < Leaf
1969
+ NAMETYPE = :member
1970
+ attr_reader :idltype, :visibility
1971
+ def initialize(_name, _enclosure, params)
1972
+ @is_recursive = false
1973
+ @has_incomplete_type = false
1974
+ super(_name, _enclosure)
1975
+ @idltype = params[:type]
1976
+ @visibility = (params[:visibility] == :public ? :public : :private)
1977
+ unless @idltype.is_a?(IDL::Type::ScopedName) && @idltype.is_node?(IDL::AST::TemplateParam)
1978
+ raise RuntimeError, "Anonymous type definitions are not allowed!" if params[:type].is_anonymous?
1979
+ ## check for use of incomplete types
1980
+ if !@idltype.is_complete?
1981
+ ## verify type is used in sequence
1982
+ if @idltype.resolved_type.is_a?(IDL::Type::Sequence)
1983
+ ## find the (non-sequence) elementtype
1984
+ seq_ = @idltype.resolved_type
1985
+ mtype = seq_.basetype
1986
+ while mtype.resolved_type.is_a? IDL::Type::Sequence
1987
+ seq_ = mtype.resolved_type
1988
+ mtype = seq_.basetype
1989
+ end
1990
+ ## is it an incomplete struct, union or valuetype?
1991
+ if mtype.is_a? IDL::Type::ScopedName
1992
+ case mtype.resolved_type
1993
+ when IDL::Type::Struct, IDL::Type::Union, IDL::Type::Valuetype
1994
+ if !mtype.node.is_defined?
1995
+ ## check if incomplete struct/union/valuetype is contained within definition of self
1996
+ enc = _enclosure
1997
+ while enc.is_a?(IDL::AST::Struct) || enc.is_a?(IDL::AST::Union) || enc.is_a?(IDL::AST::Valuetype)
1998
+ if enc.scoped_name == mtype.node.scoped_name
1999
+ ## mark enclosure as recursive
2000
+ enc.recursive = true
2001
+ ## mark sequence as recursive type !!! DEPRECATED !!!; leave till R2CORBA updated
2002
+ seq_.recursive = true
2003
+ return
2004
+ end
2005
+ enc = enc.enclosure
2006
+ end
2007
+ end
2008
+ end
2009
+ if mtype.resolved_type.is_a?(IDL::Type::Valuetype)
2010
+ # mark member as using an incomplete valuetype; allowed but needs special care
2011
+ @has_incomplete_type = true
2012
+ return
2013
+ end
2014
+ end
2015
+ elsif @idltype.resolved_type.is_a?(IDL::Type::Valuetype)
2016
+ mtype = @idltype.resolved_type
2017
+ enc = _enclosure
2018
+ while enc.is_a?(IDL::AST::Struct) || enc.is_a?(IDL::AST::Union) || enc.is_a?(IDL::AST::Valuetype)
2019
+ if enc.is_a?(IDL::AST::Valuetype) && enc.scoped_name == mtype.node.scoped_name
2020
+ ## statemember using recursive valuetype
2021
+ ## is enclosed in valuetype itself as part of constructed type
2022
+ ## which is allowed and not a problem
2023
+ @is_recursive = true
2024
+ ## mark enclosure as recursive
2025
+ enc.recursive = true
2026
+ return
2027
+ end
2028
+ enc = enc.enclosure
2029
+ end
2030
+ # mark member as using an incomplete valuetype; allowed but needs special care
2031
+ @has_incomplete_type = true
2032
+ return
2033
+ end
2034
+ raise RuntimeError, "Incomplete type #{@idltype.typename} not allowed here!"
2035
+ end
2036
+ end
2037
+ end
2038
+
2039
+ def marshal_dump
2040
+ super() << @idltype << @visibility << @is_recursive << @has_incomplete_type
2041
+ end
2042
+
2043
+ def marshal_load(vars)
2044
+ @has_incomplete_type = vars.pop
2045
+ @is_recursive = vars.pop
2046
+ @visibility = vars.pop
2047
+ @idltype = vars.pop
2048
+ super(vars)
2049
+ end
2050
+
2051
+ def instantiate(_context, _enclosure)
2052
+ _params = {
2053
+ :type => @idltype.instantiate(_context),
2054
+ :visibility => self.visibility
2055
+ }
2056
+ super(_context, _enclosure, _params)
2057
+ end
2058
+
2059
+ def is_local?(recurstk)
2060
+ idltype.is_local?(recurstk)
2061
+ end
2062
+
2063
+ def is_public?
2064
+ @visibility == :public
2065
+ end
2066
+
2067
+ def is_recursive?
2068
+ @is_recursive
2069
+ end
2070
+
2071
+ def has_incomplete_type?
2072
+ @has_incomplete_type
2073
+ end
2074
+ end # StateMember
2075
+
2076
+ class Initializer < Leaf
2077
+ NAMETYPE = :member
2078
+ attr_reader :raises, :params
2079
+ def initialize(_name, _enclosure, params)
2080
+ super(_name, _enclosure)
2081
+ @params = (params[:params] || []).collect do |(ptype, pname)|
2082
+ IDL::AST::Parameter.new(pname, self, {:attribute => :in, :type => ptype})
2083
+ end
2084
+ @raises = []
2085
+ self.raises = params[:raises]
2086
+ end
2087
+
2088
+ def raises=(exlist)
2089
+ exlist.each do |extype|
2090
+ unless extype.is_a?(IDL::Type::ScopedName) &&
2091
+ (extype.is_node?(IDL::AST::Exception) || extype.is_node?(IDL::AST::TemplateParam) || extype.resolved_type.is_a?(IDL::Type::Native))
2092
+ raise RuntimeError, 'Only IDL Exception types allowed in raises declaration.'
2093
+ end
2094
+ @raises << extype
2095
+ end
2096
+ end
2097
+
2098
+ def marshal_dump
2099
+ super() << @params << @raises
2100
+ end
2101
+
2102
+ def marshal_load(vars)
2103
+ @raises = vars.pop
2104
+ @params = vars.pop
2105
+ super(vars)
2106
+ end
2107
+
2108
+ def instantiate(_context, _enclosure)
2109
+ _params = {
2110
+ :raises => self.concrete_raises(_context)
2111
+ }
2112
+ _init = super(_context, _enclosure, _params)
2113
+ _init.set_concrete_parameters(_context, @params)
2114
+ _init
2115
+ end
2116
+
2117
+ protected
2118
+
2119
+ def concrete_raises(_context)
2120
+ @raises.collect do |ex|
2121
+ ex.instantiate(_context)
2122
+ end
2123
+ end
2124
+
2125
+ def set_concrete_parameters(_context, parms)
2126
+ @params = parms.collect do |parm|
2127
+ IDL::AST::Parameter.new(parm.name, self,
2128
+ { :attribute => :in,
2129
+ :type => parm.idltype.instantiate(_context) })
2130
+ end
2131
+ end
2132
+
2133
+ end # Initializer
2134
+
2135
+ class Finder < Initializer
2136
+ end # Finder
2137
+
2138
+ class Const < Leaf
2139
+ NAMETYPE = :class
2140
+ attr_reader :idltype, :expression, :value
2141
+ def initialize(_name, _enclosure, params)
2142
+ super(_name, _enclosure)
2143
+ @idltype = params[:type]
2144
+ @expression = params[:expression]
2145
+ @value = nil
2146
+ unless @idltype.is_a?(IDL::Type::ScopedName) && @idltype.is_node?(IDL::AST::TemplateParam)
2147
+ raise RuntimeError, "Anonymous type definitions are not allowed!" if @idltype.is_anonymous?
2148
+ raise RuntimeError,
2149
+ "Incomplete type #{@idltype.typename} not allowed here!" if !@idltype.is_complete?
2150
+ unless @expression.is_a?(IDL::Expression::ScopedName) && @expression.is_node?(IDL::AST::TemplateParam)
2151
+ @value = @idltype.narrow(@expression.value)
2152
+ end
2153
+ end
2154
+ end
2155
+
2156
+ def marshal_dump
2157
+ super() << @idltype << @expression
2158
+ end
2159
+
2160
+ def marshal_load(vars)
2161
+ @expression = vars.pop
2162
+ @idltype = vars.pop
2163
+ super(vars)
2164
+ unless @idltype.is_a?(IDL::Type::ScopedName) && @idltype.is_node?(IDL::AST::TemplateParam)
2165
+ unless @expression.is_a?(IDL::Expression::ScopedName) && @expression.is_node?(IDL::AST::TemplateParam)
2166
+ @value = @idltype.narrow(@expression.value)
2167
+ end
2168
+ end
2169
+ end
2170
+
2171
+ def instantiate(_context, _enclosure)
2172
+ _params = {
2173
+ :type => @idltype.instantiate(_context),
2174
+ :expression => @expression.instantiate(_context)
2175
+ }
2176
+ super(_context, _enclosure, _params)
2177
+ end
2178
+ end # Const
2179
+
2180
+ class Parameter < Leaf
2181
+ NAMETYPE = :member
2182
+ IN, OUT, INOUT = 0, 1, 2
2183
+ ATTRIBUTE_MAP = {
2184
+ :in => IN,
2185
+ :out => OUT,
2186
+ :inout => INOUT
2187
+ }
2188
+ attr_reader :idltype
2189
+ def initialize(_name, _enclosure, params)
2190
+ super(_name, _enclosure)
2191
+ @idltype = params[:type]
2192
+ @attribute = params[:attribute]
2193
+ unless ATTRIBUTE_MAP.has_key?(@attribute)
2194
+ raise RuntimeError,
2195
+ "invalid attribute for parameter: #{params[:attribute]}"
2196
+ end
2197
+ unless @idltype.is_a?(IDL::Type::ScopedName) && @idltype.is_node?(IDL::AST::TemplateParam)
2198
+ raise RuntimeError, "Anonymous type definitions are not allowed!" if params[:type].is_anonymous?
2199
+ if @idltype.is_local?
2200
+ if _enclosure.enclosure.is_a?(IDL::AST::Interface) && !_enclosure.enclosure.is_local?
2201
+ raise RuntimeError, "Local type #{@idltype.typename} not allowed for operation on unrestricted interface"
2202
+ end
2203
+ ## IDL_Valuetype: no problem as valuetype operations are local
2204
+ end
2205
+ if !@idltype.is_complete?
2206
+ if _enclosure.enclosure.is_a?(IDL::AST::Interface)
2207
+ raise RuntimeError, "Incomplete type #{@idltype.typename} not allowed here!"
2208
+ end
2209
+ ## IDL_Valuetype: no problem as valuetype operations are local
2210
+ end
2211
+ end
2212
+ end
2213
+
2214
+ def attribute
2215
+ ATTRIBUTE_MAP[@attribute]
2216
+ end
2217
+
2218
+ def marshal_dump
2219
+ super() << @idltype << @attribute
2220
+ end
2221
+
2222
+ def marshal_load(vars)
2223
+ @attribute = vars.pop
2224
+ @idltype = vars.pop
2225
+ super(vars)
2226
+ end
2227
+
2228
+ def instantiate(_context, _enclosure)
2229
+ _params = {
2230
+ :type => @idltype.instantiate(_context),
2231
+ :attribute => @attribute
2232
+ }
2233
+ super(_context, _enclosure, _params)
2234
+ end
2235
+ end # Parameter
2236
+
2237
+ class Operation < Node
2238
+ NAMETYPE = :member
2239
+ DEFINABLE = [IDL::AST::Parameter]
2240
+ attr_reader :idltype, :oneway, :raises
2241
+ attr_accessor :context
2242
+
2243
+ def initialize(_name, _enclosure, params)
2244
+ super(_name, _enclosure)
2245
+ @idltype = params[:type]
2246
+ @oneway = (params[:oneway] == true)
2247
+ @in = []
2248
+ @out = []
2249
+ @raises = []
2250
+ @context = nil
2251
+ unless @idltype.is_a?(IDL::Type::ScopedName) && @idltype.is_node?(IDL::AST::TemplateParam)
2252
+ raise RuntimeError, "Anonymous type definitions are not allowed!" if params[:type].is_anonymous?
2253
+ if @idltype.is_local?
2254
+ if _enclosure.is_a?(IDL::AST::Interface) && !_enclosure.is_local?
2255
+ raise RuntimeError, "Local type #{@idltype.typename} not allowed for operation on unrestricted interface"
2256
+ end
2257
+ ## IDL_Valuetype: no problem as valuetype operations are local
2258
+ end
2259
+ if !@idltype.is_complete?
2260
+ if _enclosure.is_a?(IDL::AST::Interface)
2261
+ raise RuntimeError, "Incomplete type #{@idltype.typename} not allowed here!"
2262
+ end
2263
+ ## IDL_Valuetype: no problem as valuetype operations are local
2264
+ end
2265
+ end
2266
+ end
2267
+
2268
+ def marshal_dump
2269
+ super() << @idltype << @oneway << @in << @out << @raises << @context
2270
+ end
2271
+
2272
+ def marshal_load(vars)
2273
+ @context = vars.pop
2274
+ @raises = vars.pop
2275
+ @out = vars.pop
2276
+ @in = vars.pop
2277
+ @oneway = vars.pop
2278
+ @idltype = vars.pop
2279
+ super(vars)
2280
+ end
2281
+
2282
+ def instantiate(_context, _enclosure)
2283
+ _params = {
2284
+ :type => @idltype.instantiate(_context),
2285
+ :oneway => @oneway,
2286
+ }
2287
+ _op = super(_context, _enclosure, _params)
2288
+ _op.raises = self.concrete_raises(_context)
2289
+ _op.context = @context
2290
+ _op
2291
+ end
2292
+
2293
+ def raises=(exlist)
2294
+ exlist.each do |extype|
2295
+ unless extype.is_a?(IDL::Type::ScopedName) &&
2296
+ (extype.is_node?(IDL::AST::Exception) || extype.is_node?(IDL::AST::TemplateParam) || extype.resolved_type.is_a?(IDL::Type::Native))
2297
+ raise RuntimeError, 'Only IDL Exception or Native types allowed in raises declaration.'
2298
+ end
2299
+ @raises << extype
2300
+ end
2301
+ end
2302
+
2303
+ def define(*args)
2304
+ param = super(*args)
2305
+ case param.attribute
2306
+ when Parameter::IN
2307
+ @in << param
2308
+ when Parameter::OUT
2309
+ @out << param
2310
+ when Parameter::INOUT
2311
+ @in << param
2312
+ @out << param
2313
+ end
2314
+ param
2315
+ end
2316
+
2317
+ def in_params
2318
+ @in
2319
+ end
2320
+ def out_params
2321
+ @out
2322
+ end
2323
+ def params
2324
+ self.children
2325
+ end
2326
+
2327
+ protected
2328
+
2329
+ def concrete_raises(_context)
2330
+ @raises.collect do |ex|
2331
+ ex.instantiate(_context)
2332
+ end
2333
+ end
2334
+
2335
+ def copy_from(_template, _context)
2336
+ super
2337
+ self.walk_members do |param|
2338
+ case param.attribute
2339
+ when Parameter::IN
2340
+ @in << param
2341
+ when Parameter::OUT
2342
+ @out << param
2343
+ when Parameter::INOUT
2344
+ @in << param
2345
+ @out << param
2346
+ end
2347
+ end
2348
+ self
2349
+ end
2350
+ end # Operation
2351
+
2352
+ class Attribute < Leaf
2353
+ attr_reader :idltype, :readonly
2354
+ attr_reader :get_raises, :set_raises
2355
+ NAMETYPE = :member
2356
+ def initialize(_name, _enclosure, params)
2357
+ super(_name, _enclosure)
2358
+ @idltype = params[:type]
2359
+ @get_raises = []
2360
+ @set_raises = []
2361
+ unless @idltype.is_a?(IDL::Type::ScopedName) && @idltype.is_node?(IDL::AST::TemplateParam)
2362
+ raise RuntimeError, "Anonymous type definitions are not allowed!" if @idltype.is_anonymous?
2363
+ if @idltype.is_local?
2364
+ if _enclosure.is_a?(IDL::AST::Interface) && !_enclosure.is_local?
2365
+ raise RuntimeError, "Local type #{@idltype.typename} not allowed for operation on unrestricted interface"
2366
+ end
2367
+ ## IDL_Valuetype: no problem as valuetype operations are local
2368
+ end
2369
+ if !@idltype.is_complete?
2370
+ if _enclosure.is_a?(IDL::AST::Interface)
2371
+ raise RuntimeError, "Incomplete type #{@idltype.typename} not allowed here!"
2372
+ end
2373
+ ## IDL_Valuetype: no problem as valuetype operations are local
2374
+ end
2375
+ end
2376
+ @readonly = params[:readonly]
2377
+ end
2378
+
2379
+ def marshal_dump
2380
+ super() << @idltype << @readonly << @get_raises << @set_raises
2381
+ end
2382
+
2383
+ def marshal_load(vars)
2384
+ @set_raises = vars.pop
2385
+ @get_raises = vars.pop
2386
+ @readonly = vars.pop
2387
+ @idltype = vars.pop
2388
+ super(vars)
2389
+ end
2390
+
2391
+ def instantiate(_context, _enclosure)
2392
+ _params = {
2393
+ :type => @idltype.instantiate(_context),
2394
+ :readonly => @readonly
2395
+ }
2396
+ _att = super(_context, _enclosure, _params)
2397
+ _att.get_raises = self.concrete_get_raises(_context)
2398
+ _att.set_raises = self.concrete_set_raises(_context)
2399
+ _att
2400
+ end
2401
+
2402
+ def get_raises=(exlist)
2403
+ exlist.each do |extype|
2404
+ unless extype.is_a?(IDL::Type::ScopedName) &&
2405
+ (extype.is_node?(IDL::AST::Exception) || extype.is_node?(IDL::AST::TemplateParam) || extype.resolved_type.is_a?(IDL::Type::Native))
2406
+ raise RuntimeError, 'Only IDL Exception types allowed in raises declaration.' unless extype.resolved_type.node.is_a?(IDL::AST::Exception)
2407
+ end
2408
+ @get_raises << extype
2409
+ end
2410
+ end
2411
+
2412
+ def set_raises=(exlist)
2413
+ exlist.each do |extype|
2414
+ unless extype.is_a?(IDL::Type::ScopedName) &&
2415
+ (extype.is_node?(IDL::AST::Exception) || extype.is_node?(IDL::AST::TemplateParam) || extype.resolved_type.is_a?(IDL::Type::Native))
2416
+ raise RuntimeError, 'Only IDL Exception types allowed in raises declaration.' unless extype.resolved_type.node.is_a?(IDL::AST::Exception)
2417
+ end
2418
+ @set_raises << extype
2419
+ end
2420
+ end
2421
+
2422
+ def expanded_copy(name_pfx, enc)
2423
+ att = IDL::AST::Attribute.new("#{name_pfx}_#{self.name}", enc, {:type => @idltype, :readonly => @readonly})
2424
+ att.get_raises = @get_raises unless @get_raises.empty?
2425
+ att.set_raises = @set_raises unless @set_raises.empty?
2426
+ att
2427
+ end
2428
+
2429
+ protected
2430
+
2431
+ def concrete_get_raises(_context)
2432
+ @get_raises.collect do |ex|
2433
+ ex.instantiate(_context)
2434
+ end
2435
+ end
2436
+
2437
+ def concrete_set_raises(_context)
2438
+ @set_raises.collect do |ex|
2439
+ ex.instantiate(_context)
2440
+ end
2441
+ end
2442
+ end # Attribute
2443
+
2444
+ class Struct < Node
2445
+ NAMETYPE = :class
2446
+ DEFINABLE = [IDL::AST::Member, IDL::AST::Struct, IDL::AST::Union, IDL::AST::Enum, IDL::AST::Enumerator]
2447
+ attr_reader :idltype
2448
+ def initialize(_name, _enclosure, params)
2449
+ @defined = false
2450
+ @recursive = false
2451
+ @forward = params[:forward] ? true : false
2452
+ super(_name, _enclosure)
2453
+ @idltype = IDL::Type::Struct.new(self)
2454
+ end
2455
+
2456
+ def is_defined?; @defined end
2457
+ def defined=(f); @defined = f end
2458
+ def is_forward?; @forward end
2459
+ def is_recursive?; @recursive end
2460
+ def recursive=(f); @recursive = f end
2461
+
2462
+ def walk_members(&block)
2463
+ @children.each { |m| yield(m) if not m.is_a? IDL::AST::Member }
2464
+ end
2465
+
2466
+ def members
2467
+ @children.find_all { |c| c.is_a? IDL::AST::Member }
2468
+ end
2469
+
2470
+ def is_local?(recurstk = [])
2471
+ # not local if forward decl or recursion detected
2472
+ return false if is_forward? || recurstk.include?(self)
2473
+ recurstk.push self # track root node to detect recursion
2474
+ ret = members.any? { |m| m.is_local?(recurstk) }
2475
+ recurstk.pop
2476
+ ret
2477
+ end
2478
+
2479
+ def marshal_dump
2480
+ super() << @idltype << @defined << @recursive << @forward
2481
+ end
2482
+
2483
+ def marshal_load(vars)
2484
+ @forward = vars.pop
2485
+ @recursive = vars.pop
2486
+ @defined = vars.pop
2487
+ @idltype = vars.pop
2488
+ super(vars)
2489
+ end
2490
+
2491
+ def instantiate(_context, _enclosure)
2492
+ _params = {
2493
+ :forward => @forward
2494
+ }
2495
+ _s = super(_context, _enclosure, _params)
2496
+ _s.defined = self.is_defined?
2497
+ _s
2498
+ end
2499
+
2500
+ protected
2501
+
2502
+ def walk_members_for_copy(&block)
2503
+ @children.each { |c| yield(c) }
2504
+ end
2505
+ end # Struct
2506
+
2507
+ class Exception < IDL::AST::Struct
2508
+ DEFINABLE = [IDL::AST::Member, IDL::AST::Struct, IDL::AST::Union, IDL::AST::Enum, IDL::AST::Enumerator]
2509
+ def initialize(_name, _enclosure, params)
2510
+ super(_name, _enclosure, params)
2511
+ @idltype = IDL::Type::Exception.new(self)
2512
+ end
2513
+ end # Exception
2514
+
2515
+ class Member < Leaf
2516
+ attr_reader :idltype
2517
+ NAMETYPE = :member
2518
+ def initialize(_name, _enclosure, params)
2519
+ super(_name, _enclosure)
2520
+ @idltype = params[:type]
2521
+ unless @idltype.is_a?(IDL::Type::ScopedName) && @idltype.is_node?(IDL::AST::TemplateParam)
2522
+ raise RuntimeError, "Anonymous type definitions are not allowed!" if @idltype.is_anonymous?
2523
+ ## check for use of incomplete types
2524
+ if !@idltype.is_complete?
2525
+ ## verify type is used in sequence
2526
+ if @idltype.resolved_type.is_a? IDL::Type::Sequence
2527
+ ## find the (non-sequence) elementtype
2528
+ seq_ = @idltype.resolved_type
2529
+ mtype = seq_.basetype
2530
+ while mtype.resolved_type.is_a? IDL::Type::Sequence
2531
+ seq_ = mtype.resolved_type
2532
+ mtype = seq_.basetype
2533
+ end
2534
+ ## is it an incomplete struct, union or valuetype?
2535
+ if mtype.is_a? IDL::Type::ScopedName
2536
+ case mtype.resolved_type
2537
+ when IDL::Type::Struct, IDL::Type::Union, IDL::Type::Valuetype
2538
+ if !mtype.node.is_defined?
2539
+ ## check if incomplete struct/union is contained within definition of self
2540
+ enc = _enclosure
2541
+ while enc.is_a?(IDL::AST::Struct) || enc.is_a?(IDL::AST::Union) || enc.is_a?(IDL::AST::Valuetype)
2542
+ if enc.scoped_name == mtype.node.scoped_name
2543
+ ## mark enclosure as recursive
2544
+ enc.recursive = true
2545
+ ## mark sequence as recursive type !!! DEPRECATED !!!; leave till R2CORBA updated
2546
+ seq_.recursive = true
2547
+ return
2548
+ end
2549
+ enc = enc.enclosure
2550
+ end
2551
+ end
2552
+ return # incomplete types in sequences allowed
2553
+ end
2554
+ end
2555
+ end
2556
+ raise RuntimeError, "Incomplete type #{@idltype.typename} not allowed here!"
2557
+ end
2558
+ end
2559
+ end
2560
+
2561
+ def is_local?(recurstk)
2562
+ idltype.is_local?(recurstk)
2563
+ end
2564
+
2565
+ def marshal_dump
2566
+ super() << @idltype
2567
+ end
2568
+
2569
+ def marshal_load(vars)
2570
+ @idltype = vars.pop
2571
+ super(vars)
2572
+ end
2573
+
2574
+ def instantiate(_context, _enclosure, _params = {})
2575
+ _params.merge!({
2576
+ :type => @idltype.instantiate(_context),
2577
+ })
2578
+ super(_context, _enclosure, _params)
2579
+ end
2580
+ end # Member
2581
+
2582
+ class Union < Node
2583
+ NAMETYPE = :class
2584
+ DEFINABLE = [IDL::AST::UnionMember, IDL::AST::Struct, IDL::AST::Union, IDL::AST::Enum, IDL::AST::Enumerator]
2585
+ attr_reader :idltype
2586
+ attr_accessor :switchtype
2587
+ def initialize(_name, _enclosure, params)
2588
+ @defined = false
2589
+ @recursive = false
2590
+ @forward = params[:forward] ? true : false
2591
+ @switchtype = nil
2592
+ super(_name, _enclosure)
2593
+ @idltype = IDL::Type::Union.new(self)
2594
+ end
2595
+
2596
+ def set_switchtype(_switchtype)
2597
+ @switchtype = _switchtype
2598
+ end
2599
+
2600
+ def is_defined?; @defined; end
2601
+ def defined=(f); @defined = f; end
2602
+ def is_forward?; @forward; end
2603
+ def is_recursive?; @recursive end
2604
+ def recursive=(f); @recursive = f end
2605
+
2606
+ def walk_members(&block)
2607
+ @children.each { |m| yield(m) if not m.is_a? IDL::AST::UnionMember }
2608
+ end
2609
+
2610
+ def members
2611
+ @children.find_all { |c| c.is_a? IDL::AST::UnionMember }
2612
+ end
2613
+
2614
+ def is_local?(recurstk = [])
2615
+ # not local if forward decl or recursion detected
2616
+ return false if is_forward? || recurstk.include?(self)
2617
+ recurstk.push self # track root node to detect recursion
2618
+ ret = members.any? { |m| m.is_local?(recurstk) }
2619
+ recurstk.pop
2620
+ ret
2621
+ end
2622
+
2623
+ def has_default?
2624
+ members.any? { |m| m.labels.include?(:default) }
2625
+ end
2626
+
2627
+ def default_label
2628
+ swtype = @switchtype.resolved_type
2629
+ lbls = members.collect { |m| m.labels.include?(:default) ? [] : m.labels.collect { |l| l.value } }.flatten
2630
+ lbls = lbls.sort unless IDL::Type::Boolean === swtype ## work around bug in Ruby 1.9.2
2631
+ def_lbl = swtype.min
2632
+ while swtype.in_range?(def_lbl)
2633
+ return IDL::Expression::Value.new(@switchtype, def_lbl) unless lbls.include?(def_lbl)
2634
+ return nil if def_lbl == swtype.max
2635
+ def_lbl = swtype.next(def_lbl)
2636
+ end
2637
+ nil
2638
+ end
2639
+
2640
+ def validate_labels
2641
+ return if self.is_template?
2642
+ labelvals = []
2643
+ default_ = false
2644
+ members.each { |m|
2645
+ ## check union case labels for validity
2646
+ m.labels.each { |lbl|
2647
+ if lbl == :default
2648
+ raise RuntimeError,
2649
+ "duplicate case label 'default' for #{typename} #{lm_name}" if default_
2650
+ default_ = true
2651
+ else
2652
+ # correct type
2653
+ lv = @switchtype.resolved_type.narrow(lbl.value)
2654
+ # doubles
2655
+ if labelvals.include? lv
2656
+ raise RuntimeError,
2657
+ "duplicate case label #{lv.to_s} for #{typename} #{lm_name}"
2658
+ end
2659
+ labelvals << lv
2660
+ end
2661
+ }
2662
+ }
2663
+ ## check if default allowed if defined
2664
+ if default_
2665
+ if @switchtype.resolved_type.range_length == labelvals.size
2666
+ raise RuntimeError,
2667
+ "'default' case label superfluous for #{typename} #{lm_name}"
2668
+ end
2669
+ end
2670
+ end
2671
+
2672
+ def marshal_dump
2673
+ super() << @defined << @recursive << @forward << @idltype << @switchtype
2674
+ end
2675
+
2676
+ def marshal_load(vars)
2677
+ @switchtype = vars.pop
2678
+ @idltype = vars.pop
2679
+ @forward = vars.pop
2680
+ @recursive = vars.pop
2681
+ @defined = vars.pop
2682
+ super(vars)
2683
+ end
2684
+
2685
+ def instantiate(_context, _enclosure)
2686
+ _params = {
2687
+ :forward => @forward
2688
+ }
2689
+ _u = super(_context, _enclosure, _params)
2690
+ _u.set_switchtype(@switchtype.instantiate(_context))
2691
+ _u.validate_labels
2692
+ _u.defined = self.is_defined?
2693
+ _u
2694
+ end
2695
+
2696
+ protected
2697
+
2698
+ def walk_members_for_copy(&block)
2699
+ @children.each { |c| yield(c) }
2700
+ end
2701
+ end # Union
2702
+
2703
+ class UnionMember < Member
2704
+ NAMETYPE = :member
2705
+ attr_reader :labels
2706
+ def initialize(_name, _enclosure, params)
2707
+ super(_name, _enclosure, params)
2708
+ ## if any of the labels is 'default' forget about the others
2709
+ if params[:labels].include?(:default)
2710
+ @labels = [ :default ]
2711
+ else
2712
+ @labels = params[:labels]
2713
+ end
2714
+ end
2715
+
2716
+ def marshal_dump
2717
+ super() << @labels
2718
+ end
2719
+
2720
+ def marshal_load(vars)
2721
+ @labels = vars.pop
2722
+ super(vars)
2723
+ end
2724
+
2725
+ def instantiate(_context, _enclosure)
2726
+ _params = {
2727
+ :labels => @labels.collect { |l| l == :default ? l : l.instantiate(_context) },
2728
+ }
2729
+ super(_context, _enclosure, _params)
2730
+ end
2731
+ end # UnionMember
2732
+
2733
+ class Enum < Leaf
2734
+ NAMETYPE = :class
2735
+ attr_reader :idltype
2736
+ def initialize(_name, _enclosure, params)
2737
+ super(_name, _enclosure)
2738
+ @enums = []
2739
+ @idltype = IDL::Type::Enum.new(self)
2740
+ end
2741
+
2742
+ def marshal_dump
2743
+ super() << @idltype << @enums
2744
+ end
2745
+
2746
+ def marshal_load(vars)
2747
+ @enums = vars.pop
2748
+ @idltype = vars.pop
2749
+ super(vars)
2750
+ end
2751
+
2752
+ def enumerators
2753
+ @enums
2754
+ end
2755
+
2756
+ def add_enumerator(n)
2757
+ @enums << n
2758
+ end
2759
+
2760
+ def instantiate(_context, _enclosure)
2761
+ super(_context, _enclosure, {})
2762
+ end
2763
+ end # Enum
2764
+
2765
+ class Enumerator < Leaf
2766
+ NAMETYPE = :class
2767
+ attr_reader :idltype, :enum, :value
2768
+ def initialize(_name, _enclosure, params)
2769
+ super(_name, _enclosure)
2770
+ @idltype = IDL::Type::ULong.new
2771
+ @enum = params[:enum]
2772
+ @value = params[:value]
2773
+ @enum.add_enumerator(self)
2774
+ end
2775
+
2776
+ def marshal_dump
2777
+ super() << @idltype << @enum << @value
2778
+ end
2779
+
2780
+ def marshal_load(vars)
2781
+ @value = vars.pop
2782
+ @enum = vars.pop
2783
+ @idltype = vars.pop
2784
+ super(vars)
2785
+ end
2786
+
2787
+ def instantiate(_context, _enclosure)
2788
+ super(_context, _enclosure, { :enum => @enum, :value => @value })
2789
+ end
2790
+ end # Enumerator
2791
+
2792
+ class Typedef < Leaf
2793
+ attr_reader :idltype
2794
+ NAMETYPE = :class
2795
+ def initialize(_name, _enclosure, params)
2796
+ super(_name, _enclosure)
2797
+ @idltype = params[:type]
2798
+ end
2799
+
2800
+ def is_local?(recurstk = [])
2801
+ @idltype.is_local?(recurstk)
2802
+ end
2803
+
2804
+ def marshal_dump
2805
+ super() << @idltype
2806
+ end
2807
+
2808
+ def marshal_load(vars)
2809
+ @idltype = vars.pop
2810
+ super(vars)
2811
+ end
2812
+
2813
+ def instantiate(_context, _enclosure)
2814
+ super(_context, _enclosure, { :type => @idltype.instantiate(_context) })
2815
+ end
2816
+ end # Typedef
2817
+ end
2818
+