cheri 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +387 -15
- data/lib/cheri/awt.rb +4 -2
- data/lib/cheri/builder.rb +1 -0
- data/lib/cheri/builder/awt/main.rb +1 -1
- data/lib/cheri/builder/base.rb +1 -321
- data/lib/cheri/builder/config.rb +6 -2
- data/lib/cheri/builder/context.rb +103 -26
- data/lib/cheri/builder/generator.rb +38 -32
- data/lib/cheri/builder/html/element.rb +106 -16
- data/lib/cheri/builder/html/main.rb +125 -19
- data/lib/cheri/builder/html/types.rb +12 -2
- data/lib/cheri/builder/main.rb +200 -7
- data/lib/cheri/builder/markup.rb +608 -0
- data/lib/cheri/builder/swing/main.rb +2 -2
- data/lib/cheri/builder/xml/connecter.rb +11 -0
- data/lib/cheri/builder/xml/element.rb +141 -22
- data/lib/cheri/builder/xml/main.rb +188 -32
- data/lib/cheri/builder/xml/types.rb +5 -0
- data/lib/cheri/cheri.rb +1 -1
- data/lib/cheri/explorer.rb +4 -2
- data/lib/cheri/explorer/explorer.rb +4 -2
- data/lib/cheri/java/builder/main.rb +32 -11
- data/lib/cheri/jruby.rb +4 -2
- data/lib/cheri/jruby/explorer.rb +4 -2
- data/lib/cheri/swing.rb +4 -2
- metadata +3 -2
data/lib/cheri/builder/base.rb
CHANGED
@@ -25,7 +25,7 @@
|
|
25
25
|
module Cheri
|
26
26
|
module Builder
|
27
27
|
|
28
|
-
# Frame
|
28
|
+
# Frame provides default implementations of the methods required by objects that
|
29
29
|
# will be pushed onto the Cheri::Builder::Context stack. Note that concrete
|
30
30
|
# builders will need to override some of these methods, such as #mod, #parent?
|
31
31
|
# and #child?.
|
@@ -209,325 +209,5 @@ private
|
|
209
209
|
end
|
210
210
|
end #BaseBuilder
|
211
211
|
|
212
|
-
# Appendable types define to_s, to_str and to_io methods that take an optional
|
213
|
-
# parameter, to which output is appended. This is essentially a marker interface;
|
214
|
-
# the supplied implementations do nothing useful.
|
215
|
-
module Appendable
|
216
|
-
# Append value (whatever that might be) to the supplied String, or create and
|
217
|
-
# return a new String if none is supplied. If #esc is overridden, value will
|
218
|
-
# be escaped first. Delegates to #to_io unless String === str. Note that this
|
219
|
-
# implementation appends an empty string; override to do something useful.
|
220
|
-
def to_s(str='')
|
221
|
-
return to_io(str) unless String === str
|
222
|
-
esc('',str)
|
223
|
-
end
|
224
|
-
|
225
|
-
# Calls #to_s(str). Provided so that Appendable objects may be coerced to
|
226
|
-
# Strings automatically, as in <tt>str << my_appendable_thingy</tt>. Implemented
|
227
|
-
# this way rather than through alias_method to counter the possibility that
|
228
|
-
# overriders of #to_s will forget to re-alias to_str.
|
229
|
-
def to_str(str='')
|
230
|
-
to_s(str)
|
231
|
-
end
|
232
|
-
|
233
|
-
# Append value (whatever that might be) to the supplied output stream. If
|
234
|
-
# #esc is overridden, value will be escaped first. Note that this
|
235
|
-
# implementation appends an empty string; override to do something useful.
|
236
|
-
def to_io(ios)
|
237
|
-
ios << esc('')
|
238
|
-
end
|
239
|
-
|
240
|
-
# Override to escape values (default implementation appends or returns
|
241
|
-
# the input value unaltered).
|
242
|
-
def esc(inp,out=nil)
|
243
|
-
out ? out << inp : inp
|
244
|
-
end
|
245
|
-
|
246
|
-
end
|
247
|
-
|
248
|
-
# Methods to support content (primarily intended for use with XML/HTML markup).
|
249
|
-
# See also EmptyContent, ContentArgs.
|
250
|
-
module Content
|
251
|
-
include Appendable
|
252
|
-
|
253
|
-
# Adds +value+ to the content array (@cont) for this object if #content?(+value+)
|
254
|
-
# returns +true+.
|
255
|
-
def add(value)
|
256
|
-
(@cont ||= []) << value if content?(value)
|
257
|
-
self
|
258
|
-
end
|
259
|
-
alias_method :<<, :add
|
260
|
-
|
261
|
-
# Returns the content array (@cont) if present, otherwise +nil+.
|
262
|
-
def content
|
263
|
-
@cont
|
264
|
-
end
|
265
|
-
|
266
|
-
# Iterates over the content array (@cont) for this object. Equivalent to
|
267
|
-
# calling #content#each.
|
268
|
-
def each #:yields: content_value
|
269
|
-
@cont.each do |v|
|
270
|
-
yield v
|
271
|
-
end if @cont && block_given?
|
272
|
-
end
|
273
|
-
|
274
|
-
# Returns truth value if +value+ is valid content for this builder/object,
|
275
|
-
# +false+/+nil+ otherwise. Called by #add before adding content; +value+ will
|
276
|
-
# not be added unless content? is true.
|
277
|
-
#
|
278
|
-
# This implementation always returns +true+. Override to validate each content
|
279
|
-
# element before it is added. You may wish to raise an exception or issue a
|
280
|
-
# warning in the case of invalid content.
|
281
|
-
def content?(value)
|
282
|
-
true
|
283
|
-
end
|
284
|
-
|
285
|
-
# Appends concatenated and escaped content (@cont) to +str+, if supplied, using
|
286
|
-
# the +<<+ operator. Assumes String === +str+. Use #cont_io to append to IO or Array.
|
287
|
-
def cont_s(str='')
|
288
|
-
@cont.each do |v|
|
289
|
-
case v
|
290
|
-
when String : esc(v,str)
|
291
|
-
when Appendable : v.to_s(str)
|
292
|
-
else esc(v.to_s,str)
|
293
|
-
end
|
294
|
-
end if @cont
|
295
|
-
str
|
296
|
-
end
|
297
|
-
|
298
|
-
# Appends concatenated and escaped content (@cont) to +ios+, if supplied, using
|
299
|
-
# the +<<+ operator. Use for appending to IO or Array. Use #cont_s to append more
|
300
|
-
# efficiently to strings.
|
301
|
-
def cont_io(ios)
|
302
|
-
@cont.each do |v|
|
303
|
-
case v
|
304
|
-
when String : ios << esc(v)
|
305
|
-
when Appendable : v.to_io(ios)
|
306
|
-
else ios << esc(v.to_s)
|
307
|
-
end
|
308
|
-
end if @cont
|
309
|
-
ios
|
310
|
-
end
|
311
|
-
|
312
|
-
# Override to escape values by appending the escaped +inp+ value to output
|
313
|
-
# string +out+ (using << or concat). If +out+ is nil, just return the escaped
|
314
|
-
# string. The default implementation appends or returns the input value unaltered.
|
315
|
-
def esc(inp,out=nil)
|
316
|
-
out ? out << inp : inp
|
317
|
-
end
|
318
|
-
|
319
|
-
end
|
320
|
-
|
321
|
-
# Methods to support attributes (primarily intended for use with XML/HTML markup).
|
322
|
-
# Note: include before ContentArgs if both are being included.
|
323
|
-
module Attributes
|
324
|
-
include Appendable
|
325
|
-
#:stopdoc:
|
326
|
-
S = ' '.freeze
|
327
|
-
Q = '"'.freeze
|
328
|
-
E = '='.freeze
|
329
|
-
#:startdoc:
|
330
|
-
def initialize(*r,&k)
|
331
|
-
super
|
332
|
-
if @args && Hash === @args.last
|
333
|
-
@args.pop.each_pair do |n,v| add_attr(n,v); end
|
334
|
-
end
|
335
|
-
end
|
336
|
-
|
337
|
-
# Returns the attibutes hash (@attrs), if any.
|
338
|
-
def attrs
|
339
|
-
@attrs
|
340
|
-
end
|
341
|
-
|
342
|
-
# Add an attribute. Called by #initialize to add/validate attributes passed as
|
343
|
-
# arguments.
|
344
|
-
def add_attr(name,value)
|
345
|
-
(@attrs ||= {})[name] = value if attr?(name,value)
|
346
|
-
end
|
347
|
-
|
348
|
-
# Override to validate each attribute before it is added. The default
|
349
|
-
# implementation accepts any name/value.
|
350
|
-
def attr?(name,value)
|
351
|
-
true
|
352
|
-
end
|
353
|
-
|
354
|
-
# Writes attributes to a new string, or appends to an existing string
|
355
|
-
# (using <<) if supplied.
|
356
|
-
def attr_s(str='')
|
357
|
-
@attrs.each_pair do |k,v|
|
358
|
-
str << 32 << k.to_s << ?= << 34 << v.to_s << 34
|
359
|
-
end if @attrs
|
360
|
-
str
|
361
|
-
end
|
362
|
-
|
363
|
-
# Writes attributes to the supplied IO stream (or Array, etc.) using <<.
|
364
|
-
def attr_io(ios)
|
365
|
-
@attrs.each_pair do |k,v|
|
366
|
-
ios << S << k << E << Q << v << Q
|
367
|
-
end if @attrs
|
368
|
-
ios
|
369
|
-
end
|
370
|
-
end
|
371
|
-
|
372
|
-
# Calls +add+ to add each argument passed to new/initialize. Use with Content
|
373
|
-
# module if content values will be passed as arguments. Note: include after
|
374
|
-
# Attributes if both are being used.
|
375
|
-
module ContentArgs
|
376
|
-
def initialize(*r,&k)
|
377
|
-
super
|
378
|
-
@args.each do |a| add a; end
|
379
|
-
end
|
380
|
-
end #ContentArgs
|
381
|
-
|
382
|
-
|
383
|
-
# Methods to support empty content models (primarily intended for use with XML/HTML markup).
|
384
|
-
# See also Content, ContentArgs.
|
385
|
-
module EmptyContent
|
386
|
-
include Appendable
|
387
|
-
CE = ' />'.freeze #:nodoc:
|
388
|
-
|
389
|
-
# Returns +false+
|
390
|
-
def content?(value)
|
391
|
-
false
|
392
|
-
end
|
393
|
-
|
394
|
-
def empty_s(str='')
|
395
|
-
str << CE
|
396
|
-
end
|
397
|
-
|
398
|
-
def empty_io(ios)
|
399
|
-
ios << CE
|
400
|
-
end
|
401
|
-
|
402
|
-
end #EmptyContent
|
403
|
-
|
404
|
-
module MarkupWriter
|
405
|
-
#:stopdoc:
|
406
|
-
C = '</'.freeze
|
407
|
-
E = '>'.freeze
|
408
|
-
EC = '></'.freeze
|
409
|
-
O = '<'.freeze
|
410
|
-
#:startdoc:
|
411
|
-
|
412
|
-
# Append this markup to +str+ (or an empty string if +str+ is not supplied),
|
413
|
-
# and return the result. Redirects to #to_io if +str+ is not a String. Both
|
414
|
-
# methods use the +<<+ operator to append their output; this method (like the other
|
415
|
-
# ..._s methods) is faster because Fixnum values can be appended directly, without
|
416
|
-
# being converted to (or passed as) strings. This takes on particular significance
|
417
|
-
# when output is being escaped, and values passed one character at a time.
|
418
|
-
def to_s(str='')
|
419
|
-
return to_io(str) unless String === str
|
420
|
-
open_s(str)
|
421
|
-
attr_s(str) if @attrs
|
422
|
-
if @cont
|
423
|
-
str << ?>
|
424
|
-
cont_s(str)
|
425
|
-
close_s(str)
|
426
|
-
else
|
427
|
-
empty_s(str)
|
428
|
-
end
|
429
|
-
str
|
430
|
-
end
|
431
|
-
|
432
|
-
# Append this markup to +ios+
|
433
|
-
def to_io(ios)
|
434
|
-
open_io(ios)
|
435
|
-
attr_io(ios) if @attrs
|
436
|
-
if @cont
|
437
|
-
ios << E
|
438
|
-
cont_io(ios)
|
439
|
-
close_io(ios)
|
440
|
-
else
|
441
|
-
empty_io(ios)
|
442
|
-
end
|
443
|
-
ios
|
444
|
-
end
|
445
|
-
|
446
|
-
# Append open tag (<tagname) to +str+ using +<<+.
|
447
|
-
def open_s(str)
|
448
|
-
str << ?< << (@tag ||= @sym.to_s)
|
449
|
-
end
|
450
|
-
|
451
|
-
# Append open tag (<tagname) to +ios+ using +<<+.
|
452
|
-
def open_io(ios)
|
453
|
-
ios << O << (@tag ||= @sym.to_s)
|
454
|
-
end
|
455
|
-
|
456
|
-
# Append close tag (</tagname>) to +str+ using +<<+.
|
457
|
-
def close_s(str)
|
458
|
-
str << C << @tag << ?>
|
459
|
-
end
|
460
|
-
|
461
|
-
# Append close tag (</tagname>) to +ios+ using +<<+. (Use slightly faster
|
462
|
-
# #close_s for strings.)
|
463
|
-
def close_io(ios)
|
464
|
-
ios << C << @tag << E
|
465
|
-
end
|
466
|
-
|
467
|
-
# Append empty close tag (...></tagname>) to +str+. Note that HTML/XML elements
|
468
|
-
# with empty content models should close with <tt>' />'</tt> instead (see EmptyContent).
|
469
|
-
def empty_s(str)
|
470
|
-
str << EC << @tag << ?>
|
471
|
-
end
|
472
|
-
|
473
|
-
# Append empty close tag (...></tagname>) to +ios+. Note that HTML/XML elements
|
474
|
-
# with empty content models should close with <tt>' />'</tt> instead (see EmptyContent).
|
475
|
-
def empty_io(ios)
|
476
|
-
ios << EC << @tag << E
|
477
|
-
end
|
478
|
-
|
479
|
-
end #MarkupWriter
|
480
|
-
|
481
|
-
module Markup
|
482
|
-
include Content
|
483
|
-
include Attributes
|
484
|
-
include ContentArgs
|
485
|
-
include MarkupWriter
|
486
|
-
end #Markup
|
487
|
-
|
488
|
-
module EmptyMarkup
|
489
|
-
# We include Content and ContentArgs so that warnings/exceptions may be
|
490
|
-
# issued (by overriding #add or #content?) if the user attempts to add to this element.
|
491
|
-
# Otherwise, unconnectable elements would simply be ignored.
|
492
|
-
include Markup
|
493
|
-
# include Content
|
494
|
-
# include Attributes
|
495
|
-
# include ContentArgs
|
496
|
-
# include MarkupWriter
|
497
|
-
include EmptyContent
|
498
|
-
end #EmptyMarkup
|
499
|
-
|
500
|
-
module MarkupBuilder
|
501
|
-
include Builder
|
502
|
-
include Markup
|
503
|
-
|
504
|
-
def object
|
505
|
-
self
|
506
|
-
end
|
507
|
-
|
508
|
-
def run
|
509
|
-
value = @ctx.call(self,&@blk) if @blk
|
510
|
-
add(value) if String === value
|
511
|
-
self
|
512
|
-
end
|
513
|
-
end #MarkupBuilder
|
514
|
-
|
515
|
-
module EmptyMarkupBuilder
|
516
|
-
include Builder
|
517
|
-
include EmptyMarkup
|
518
|
-
|
519
|
-
def object
|
520
|
-
self
|
521
|
-
end
|
522
|
-
|
523
|
-
def run
|
524
|
-
value = @ctx.call(self,&@blk) if @blk
|
525
|
-
# of course we want this to then fail in #add / #content? e.g., see Cheri::Html::EmptyElem
|
526
|
-
add(value) if String === value
|
527
|
-
self
|
528
|
-
end
|
529
|
-
|
530
|
-
end #EmptyMarkupBuilder
|
531
|
-
|
532
212
|
end #Builder
|
533
213
|
end #Cheri
|
data/lib/cheri/builder/config.rb
CHANGED
@@ -62,13 +62,11 @@ class Config
|
|
62
62
|
validate(mod) unless mod == Cheri::Builder
|
63
63
|
extendee = mod.respond_to?(:extends) ? mod.extends : nil
|
64
64
|
raise BuilderException,"extended builder module not included: #{extendee}" if extendee && !@m.include?(extendee)
|
65
|
-
#puts "config add mod #{mod}"
|
66
65
|
@m << mod
|
67
66
|
@f[mod] = mod.factory if mod.respond_to?(:factory) && mod.factory
|
68
67
|
@c[mod] = mod.connecter if mod.respond_to?(:connecter) && mod.connecter
|
69
68
|
(@n ||= {})[mod] = mod.consumer if mod.respond_to?(:consumer) && mod.consumer
|
70
69
|
(@r ||= {})[mod] = mod.resolver if mod.respond_to?(:resolver) && mod.resolver
|
71
|
-
#puts "@n = #{@n}"
|
72
70
|
extend_mod(extendee,mod) if extendee
|
73
71
|
self
|
74
72
|
end
|
@@ -145,6 +143,12 @@ class Config
|
|
145
143
|
def copy
|
146
144
|
self.class.allocate.copy_from(@m,@f,@c,@n,@r)
|
147
145
|
end
|
146
|
+
|
147
|
+
# Overrides the default Object#inspect to prevent mind-boggling circular displays in IRB.
|
148
|
+
def inspect
|
149
|
+
"#<#{self.class}:instance>"
|
150
|
+
end
|
151
|
+
|
148
152
|
protected
|
149
153
|
def copy_from(m,f,c,n,r)
|
150
154
|
@m = m.dup
|
@@ -25,15 +25,13 @@
|
|
25
25
|
module Cheri
|
26
26
|
module Builder
|
27
27
|
|
28
|
-
|
29
|
-
# !!! TODO: class-level properties
|
30
|
-
|
31
28
|
class InstanceContext
|
32
29
|
# TODO: defined?Java pulls it in (same as require 'java' or include Java)
|
33
30
|
# not sure if anyone would object...
|
34
31
|
if (defined?Java) && (defined?JRUBY_VERSION) # JRuby 0.9.9 or later
|
35
32
|
Col = java.util.Collections
|
36
|
-
Map = java.util.
|
33
|
+
Map = java.util.HashMap
|
34
|
+
WMap = java.util.WeakHashMap
|
37
35
|
end
|
38
36
|
|
39
37
|
# call-seq:
|
@@ -42,10 +40,15 @@ class InstanceContext
|
|
42
40
|
def initialize(client,cfg)
|
43
41
|
@c = client
|
44
42
|
@g = cfg
|
45
|
-
|
43
|
+
# TODO: properties, aliases should probably be threadsafe hashes/maps,
|
44
|
+
# though contention would be extremely unlikely given expected usage (any
|
45
|
+
# puts likely to be made on the instantiating thread, immediately
|
46
|
+
# upon instantiation).
|
47
|
+
@p = {} # properties
|
48
|
+
@l = {} # aliases
|
46
49
|
# TODO: find a better way to do this
|
47
50
|
if self.class.const_defined?("Map")
|
48
|
-
@h = Col.synchronized_map
|
51
|
+
@h = Col.synchronized_map WMap.new
|
49
52
|
@t = true # use Thread as key
|
50
53
|
else
|
51
54
|
# TODO: should use weak hash here
|
@@ -79,14 +82,22 @@ class InstanceContext
|
|
79
82
|
end
|
80
83
|
end
|
81
84
|
|
85
|
+
def props
|
86
|
+
@p
|
87
|
+
end
|
88
|
+
|
82
89
|
def [](k)
|
83
|
-
@
|
90
|
+
@p[k]
|
84
91
|
end
|
85
92
|
|
86
93
|
def []=(k,v)
|
87
|
-
@
|
94
|
+
@p[k] = v
|
88
95
|
end
|
89
|
-
|
96
|
+
|
97
|
+
def aliases
|
98
|
+
@l
|
99
|
+
end
|
100
|
+
|
90
101
|
# call-seq:
|
91
102
|
# current -> context object for the current instance/thread
|
92
103
|
#
|
@@ -94,6 +105,11 @@ class InstanceContext
|
|
94
105
|
key = @t ? Thread.current : Thread.current.__id__
|
95
106
|
@h[key] ||= Context.new(self,@c)
|
96
107
|
end
|
108
|
+
|
109
|
+
# Overrides the default Object#inspect to prevent mind-boggling circular displays in IRB.
|
110
|
+
def inspect
|
111
|
+
"#<#{self.class}:instance>"
|
112
|
+
end
|
97
113
|
|
98
114
|
end #InstanceContext
|
99
115
|
|
@@ -112,6 +128,7 @@ class Context
|
|
112
128
|
# @g - reference to the class's Config instance (all included Cheri builder modules)
|
113
129
|
# @p - configuration properties hash, used for various purposes
|
114
130
|
# @i - reference to the InstanceContext that created this Context
|
131
|
+
# @l - reference to aliases from InstanceConfig
|
115
132
|
# @m - the ConnectionMinder for this context, tracks pending (prepared) connections
|
116
133
|
# @n - reference to the connecters in the class's Config instance
|
117
134
|
# @r - array of ConstantResolver instances, lazily initialized
|
@@ -128,6 +145,7 @@ class Context
|
|
128
145
|
if (u = ictx.auto)
|
129
146
|
@u = u.dup
|
130
147
|
end
|
148
|
+
@l = ictx.aliases
|
131
149
|
@c = client
|
132
150
|
@m = ConnectionMinder.new
|
133
151
|
@s = [] # stack
|
@@ -190,6 +208,8 @@ class Context
|
|
190
208
|
# method_missing (the usual caller) empty-handed.
|
191
209
|
def send(sym,*r,&k)
|
192
210
|
raise Cheri.type_error(sym,Symbol) unless sym.instance_of?(Symbol)
|
211
|
+
# substitute sym for alias, if any
|
212
|
+
sym = @l[sym] if @l[sym]
|
193
213
|
# check args against pending connections (see note at ConnectionMinder)
|
194
214
|
@m.ck(sym,*r)
|
195
215
|
# first try for a builder matching sym
|
@@ -213,16 +233,45 @@ class Context
|
|
213
233
|
# Version of +send+ intended for use by proxy objects. The supplied module's factory
|
214
234
|
# _must_ be able to resolve the symbol; otherwise, a NoMethodError will be raised.
|
215
235
|
def msend(m,sym,*r,&k)
|
216
|
-
#puts "fsend sym: #{sym}"
|
217
236
|
# ok for stack to be empty for this call, so no check
|
218
237
|
raise Cheri.type_error(sym,Symbol) unless sym.instance_of?(Symbol)
|
219
238
|
raise ArgumentError,"not a valid builder module: #{m}" unless (f = @f[m])
|
239
|
+
# substitute sym for alias, if any
|
240
|
+
sym = @l[sym] if @l[sym]
|
241
|
+
# check args against pending connections (see note at ConnectionMinder)
|
242
|
+
@m.ck(sym,*r)
|
243
|
+
# the factory _must_ be able to return a matching builder
|
244
|
+
unless (b = f.builder(self,sym,*r,&k))
|
245
|
+
raise NoMethodError,"undefined method '#{sym}' for #{m}"
|
246
|
+
end
|
247
|
+
# run it
|
248
|
+
res = b.run
|
249
|
+
# connect it
|
250
|
+
ctc(b)
|
251
|
+
res
|
252
|
+
end
|
253
|
+
|
254
|
+
# call-seq:
|
255
|
+
# ctx.nsend(builder_module, namespace_sym, sym, *args, &block) -> result
|
256
|
+
#
|
257
|
+
# Version of +send+ intended for use by namespace objects. The supplied module's factory
|
258
|
+
# _must_ be able to resolve the symbol; otherwise, a NoMethodError will be raised. The
|
259
|
+
# resulting builder _must_ supply a +ns=+ method; otherwise a TypeError will be raised.
|
260
|
+
def nsend(m,ns,sym,*r,&k)
|
261
|
+
# ok for stack to be empty for this call, so no check
|
262
|
+
raise Cheri.type_error(ns,Symbol) unless Symbol === ns
|
263
|
+
raise Cheri.type_error(sym,Symbol) unless Symbol === sym
|
264
|
+
raise ArgumentError,"not a valid builder module: #{m}" unless (f = @f[m])
|
265
|
+
# substitute sym for alias, if any
|
266
|
+
sym = @l[sym] if @l[sym]
|
220
267
|
# check args against pending connections (see note at ConnectionMinder)
|
221
268
|
@m.ck(sym,*r)
|
222
269
|
# the factory _must_ be able to return a matching builder
|
223
270
|
unless (b = f.builder(self,sym,*r,&k))
|
224
271
|
raise NoMethodError,"undefined method '#{sym}' for #{m}"
|
225
272
|
end
|
273
|
+
raise Cheri.type_error(b,Markup) unless b.respond_to?(:ns=)
|
274
|
+
b.ns = ns
|
226
275
|
# run it
|
227
276
|
res = b.run
|
228
277
|
# connect it
|
@@ -498,11 +547,18 @@ class Context
|
|
498
547
|
end
|
499
548
|
|
500
549
|
# now attempt connections for any 'any' objects on the stack
|
501
|
-
@a
|
502
|
-
|
503
|
-
|
550
|
+
if @a
|
551
|
+
@ax = true
|
552
|
+
begin
|
553
|
+
@a.reverse_each do |a|
|
554
|
+
if a.object && (n = @n[a.mod])
|
555
|
+
n.prepare(self,a,obj,sym,props)
|
556
|
+
end
|
557
|
+
end
|
558
|
+
ensure
|
559
|
+
@ax = nil
|
504
560
|
end
|
505
|
-
end
|
561
|
+
end
|
506
562
|
|
507
563
|
nil
|
508
564
|
end
|
@@ -530,7 +586,19 @@ class Context
|
|
530
586
|
def []=(k,v)
|
531
587
|
@p[k]=v
|
532
588
|
end
|
533
|
-
|
589
|
+
|
590
|
+
# call-seq:
|
591
|
+
# ctx.aliases -> aliases hash
|
592
|
+
# ctx.als -> aliases hash
|
593
|
+
#
|
594
|
+
def als
|
595
|
+
@l
|
596
|
+
end
|
597
|
+
# :stopdoc:
|
598
|
+
alias_method :aliases, :als
|
599
|
+
# :startdoc:
|
600
|
+
|
601
|
+
|
534
602
|
# call-seq:
|
535
603
|
# prepared(connecter,builder,obj,sym,props=nil) -> true
|
536
604
|
# ppd(connecter,builder,obj,sym,props=nil) -> true
|
@@ -546,16 +614,13 @@ class Context
|
|
546
614
|
# Note that if you are using TypeConnecter (highly recommended where appropriate), this all
|
547
615
|
# takes place behind the scenes, so you don't need to call this method directly.
|
548
616
|
def ppd(ctr,bldr,obj,sym,props=nil)
|
549
|
-
@
|
617
|
+
unless @ax
|
618
|
+
@m.ppd(ctr,bldr,obj,sym,props)
|
619
|
+
else
|
620
|
+
@m.ppda(ctr,bldr,obj,sym,props)
|
621
|
+
end
|
550
622
|
end
|
551
623
|
alias_method :prepared, :ppd #:nodoc:
|
552
|
-
|
553
|
-
# TODO: this is internal now, don't need a method ?
|
554
|
-
# def ck(*r)
|
555
|
-
# @m.check(*r)
|
556
|
-
# end
|
557
|
-
# alias_method :check, :ck
|
558
|
-
#
|
559
624
|
|
560
625
|
# Overrides the default Object#inspect to prevent mind-boggling circular displays in IRB.
|
561
626
|
def inspect
|
@@ -567,9 +632,10 @@ class Context
|
|
567
632
|
# being called will do whatever is needed (except for cherify,
|
568
633
|
# which _wants_ its arg connected). Note that we can only catch
|
569
634
|
# those passed to cheri-invoked ctors/methods.
|
570
|
-
class ConnectionMinder
|
635
|
+
class ConnectionMinder # :nodoc: all
|
571
636
|
def initialize
|
572
637
|
@c = {} # pending connections. indexed by builder.__id__
|
638
|
+
#@a = {} # pending 'any' connections. indexed by builder.__id__
|
573
639
|
@o = {} # pending builder(object)s. indexed by object.__id__
|
574
640
|
end
|
575
641
|
|
@@ -577,7 +643,6 @@ class Context
|
|
577
643
|
# an array to hold pending connections for that builder
|
578
644
|
def pu(b)
|
579
645
|
@c[b.__id__] = []
|
580
|
-
#@a
|
581
646
|
end
|
582
647
|
alias_method :pushed, :pu #:nodoc:
|
583
648
|
|
@@ -585,6 +650,11 @@ class Context
|
|
585
650
|
# pending (prepared) connections, and remove each builder/object
|
586
651
|
# associated with a connection from the pending objects hash.
|
587
652
|
def po(b)
|
653
|
+
if @a && (ac = @a.delete b.__id__)
|
654
|
+
ac.each do |c|
|
655
|
+
c.connect rescue nil
|
656
|
+
end
|
657
|
+
end
|
588
658
|
if (cs = @c.delete b.__id__)
|
589
659
|
begin
|
590
660
|
cs.each do |c| c.connect; end
|
@@ -604,6 +674,13 @@ class Context
|
|
604
674
|
end
|
605
675
|
alias_method :prepared, :ppd #:nodoc:
|
606
676
|
|
677
|
+
# store a prepared 'any' connection.
|
678
|
+
def ppda(ctr,bldr,obj,sym,props=nil)
|
679
|
+
((@a ||= {})[bldr.__id__] ||= []) << Con.new(ctr,bldr.object,obj,sym,props)
|
680
|
+
true
|
681
|
+
end
|
682
|
+
alias_method :prepared_any, :ppda # :nodoc:
|
683
|
+
|
607
684
|
# check args passed to ctors/methods against the pending objects hash,
|
608
685
|
# and remove any matches from the pending connections/objects hashes.
|
609
686
|
def ck(y,*r)
|
@@ -637,7 +714,7 @@ class Context
|
|
637
714
|
end
|
638
715
|
alias_method :check, :ck #:nodoc:
|
639
716
|
|
640
|
-
class Con
|
717
|
+
class Con # :nodoc: all
|
641
718
|
def initialize(ctr,par,obj,sym,props)
|
642
719
|
@c = ctr
|
643
720
|
@p = par
|