cheri 0.0.2
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/MIT-LICENSE +20 -0
- data/README +98 -0
- data/Rakefile +121 -0
- data/examples/hello_world_1.rb +28 -0
- data/examples/table_1.rb +44 -0
- data/lib/cheri/awt.rb +41 -0
- data/lib/cheri/builder.rb +31 -0
- data/lib/cheri/builder/awt/connecter.rb +63 -0
- data/lib/cheri/builder/awt/constants.rb +1003 -0
- data/lib/cheri/builder/awt/main.rb +191 -0
- data/lib/cheri/builder/awt/types.rb +220 -0
- data/lib/cheri/builder/base.rb +533 -0
- data/lib/cheri/builder/config.rb +187 -0
- data/lib/cheri/builder/connecter.rb +386 -0
- data/lib/cheri/builder/context.rb +655 -0
- data/lib/cheri/builder/generator.rb +425 -0
- data/lib/cheri/builder/html/charsets.rb +154 -0
- data/lib/cheri/builder/html/common.rb +32 -0
- data/lib/cheri/builder/html/connecter.rb +57 -0
- data/lib/cheri/builder/html/element.rb +156 -0
- data/lib/cheri/builder/html/main.rb +116 -0
- data/lib/cheri/builder/html/types.rb +123 -0
- data/lib/cheri/builder/main.rb +483 -0
- data/lib/cheri/builder/swing/connecter.rb +141 -0
- data/lib/cheri/builder/swing/constants.rb +420 -0
- data/lib/cheri/builder/swing/main.rb +446 -0
- data/lib/cheri/builder/swing/types.rb +270 -0
- data/lib/cheri/builder/xml/charsets.rb +154 -0
- data/lib/cheri/builder/xml/common.rb +32 -0
- data/lib/cheri/builder/xml/connecter.rb +42 -0
- data/lib/cheri/builder/xml/element.rb +189 -0
- data/lib/cheri/builder/xml/main.rb +130 -0
- data/lib/cheri/builder/xml/types.rb +36 -0
- data/lib/cheri/cheri.rb +70 -0
- data/lib/cheri/cjx.rb +3 -0
- data/lib/cheri/explorer.rb +32 -0
- data/lib/cheri/explorer/explorer.rb +560 -0
- data/lib/cheri/html.rb +31 -0
- data/lib/cheri/image/Delete24.gif +0 -0
- data/lib/cheri/image/Find24.gif +0 -0
- data/lib/cheri/image/FindAgain24.gif +0 -0
- data/lib/cheri/image/Refresh24.gif +0 -0
- data/lib/cheri/image/Search24.gif +0 -0
- data/lib/cheri/image/Thumbs.db +0 -0
- data/lib/cheri/image/cheri_icon_16x16.png +0 -0
- data/lib/cheri/image/cheri_icon_24x24.png +0 -0
- data/lib/cheri/image/cheri_logo_medium.png +0 -0
- data/lib/cheri/image/close_10x10.png +0 -0
- data/lib/cheri/image/close_10x10s.png +0 -0
- data/lib/cheri/image/close_12x12.png +0 -0
- data/lib/cheri/image/close_14x14.png +0 -0
- data/lib/cheri/image/close_24x24.png +0 -0
- data/lib/cheri/image/close_dim2_12x12.png +0 -0
- data/lib/cheri/image/close_dim_12x12.png +0 -0
- data/lib/cheri/image/cls_tree.png +0 -0
- data/lib/cheri/image/con_tree.png +0 -0
- data/lib/cheri/image/jruby_14x16.png +0 -0
- data/lib/cheri/image/jruby_logo.png +0 -0
- data/lib/cheri/image/mod_tree.png +0 -0
- data/lib/cheri/image/obj_tree.png +0 -0
- data/lib/cheri/image/ruby_16x16.png +0 -0
- data/lib/cheri/image/vars_tree.png +0 -0
- data/lib/cheri/java.rb +26 -0
- data/lib/cheri/java/builder.rb +28 -0
- data/lib/cheri/java/builder/main.rb +407 -0
- data/lib/cheri/java/builder/util.rb +480 -0
- data/lib/cheri/java/java.rb +56 -0
- data/lib/cheri/jruby.rb +32 -0
- data/lib/cheri/jruby/explorer.rb +43 -0
- data/lib/cheri/jruby/explorer/common.rb +38 -0
- data/lib/cheri/jruby/explorer/dialogs.rb +383 -0
- data/lib/cheri/jruby/explorer/explorer.rb +904 -0
- data/lib/cheri/jruby/explorer/splash.rb +80 -0
- data/lib/cheri/jruby/explorer/viewer.rb +619 -0
- data/lib/cheri/jruby/explorer/viewers.rb +1057 -0
- data/lib/cheri/jruby/jruby.rb +59 -0
- data/lib/cheri/swing.rb +41 -0
- data/lib/cheri/xml.rb +31 -0
- metadata +135 -0
@@ -0,0 +1,483 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com>
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
#
|
24
|
+
|
25
|
+
module Cheri
|
26
|
+
module Builder
|
27
|
+
|
28
|
+
class BuilderException < Cheri::CheriException; end
|
29
|
+
|
30
|
+
class << self
|
31
|
+
def append_features(clazz) #:nodoc:
|
32
|
+
return super unless clazz.instance_of?(Class) &&
|
33
|
+
!clazz.instance_variable_get(:@__cheri_cfg).instance_of?(Config)
|
34
|
+
clazz.instance_variable_set(:@__cheri_cfg,Config.new(CheriModule))
|
35
|
+
# we don't support subclassing for builder modules installed at the
|
36
|
+
# top level (in Object). method_missing will be inherited, but will
|
37
|
+
# behave normally (just calls super if @__cheri_cfg not installed)
|
38
|
+
unless clazz == Object
|
39
|
+
clazz.module_eval do
|
40
|
+
class << self
|
41
|
+
def inherited(subclass)
|
42
|
+
cfg = @__cheri_cfg
|
43
|
+
subclass.module_eval do
|
44
|
+
# copy modules unless a more-derived subclass has already done so
|
45
|
+
unless @__cheri_cfg.instance_of?(Cheri::Builder::Config)
|
46
|
+
@__cheri_cfg = cfg.copy
|
47
|
+
end
|
48
|
+
end
|
49
|
+
# pass it up the chain
|
50
|
+
super
|
51
|
+
end
|
52
|
+
private :inherited
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
super
|
57
|
+
end
|
58
|
+
private :append_features
|
59
|
+
|
60
|
+
# call-seq:
|
61
|
+
# Cheri::Builder.module_included(module, class) -> Cheri::Builder
|
62
|
+
#
|
63
|
+
# Installs the specified module as a Cheri builder for the specified class. Note
|
64
|
+
# that the 'included module' needn't be included, or even a module, in order to
|
65
|
+
# participate as a Cheri builder, though normally it will be both.
|
66
|
+
#
|
67
|
+
# Modules should hook the <tt>append_features</tt> method, rather than <tt>included</tt>;
|
68
|
+
# the former allows inclusion to be aborted if exceptional conditions arise, whereas
|
69
|
+
# the latter is called after the fact:
|
70
|
+
#
|
71
|
+
# module MyBuilder
|
72
|
+
# include Cheri::Builder
|
73
|
+
# class << self
|
74
|
+
# def append_features(clazz)
|
75
|
+
# Cheri::Builder.module_included(self, clazz)
|
76
|
+
# super # allow inclusion to complete
|
77
|
+
# end
|
78
|
+
# private :append_features
|
79
|
+
# end #self
|
80
|
+
#
|
81
|
+
# end #MyBuilder
|
82
|
+
#
|
83
|
+
# Builders installed for a class will be inherited by its subclasses, with the
|
84
|
+
# exception of those installed for class Object; inclusion of Builder modules in
|
85
|
+
# Object is discouraged, but is permitted so simple scripts can include builders
|
86
|
+
# at the top level rather than having to define a class. But really, don't do it.
|
87
|
+
def module_included(mod,clazz)
|
88
|
+
return self unless clazz.instance_of?(Class)
|
89
|
+
append_features(clazz)
|
90
|
+
clazz.instance_variable_get(:@__cheri_cfg) << mod
|
91
|
+
self
|
92
|
+
end
|
93
|
+
|
94
|
+
# note: Cheri::Java needs factory method
|
95
|
+
|
96
|
+
# Create a new builder module using the BuilderBuilder.
|
97
|
+
def new_builder(*r,&k)
|
98
|
+
# TODO: usage message if no args or block supplied
|
99
|
+
Generator.new(*r,&k).run
|
100
|
+
end
|
101
|
+
|
102
|
+
end #self
|
103
|
+
|
104
|
+
|
105
|
+
# Instance methods
|
106
|
+
|
107
|
+
|
108
|
+
# call-seq:
|
109
|
+
# method_missing(symbol [, *args] [, &block]) -> result (if method matched)
|
110
|
+
#
|
111
|
+
def method_missing(sym,*r,&k)
|
112
|
+
# get the context for the current thread
|
113
|
+
if (ctx = __cheri_ctx)
|
114
|
+
# send to the context for processing
|
115
|
+
matched, result = ctx.send(sym,*r,&k)
|
116
|
+
# return the result if sym matched
|
117
|
+
return result if matched
|
118
|
+
end
|
119
|
+
|
120
|
+
# nothing matches, probable NameError/NoMethodError
|
121
|
+
super
|
122
|
+
end
|
123
|
+
private :method_missing
|
124
|
+
|
125
|
+
# call-seq:
|
126
|
+
# cheri([*args] [, &block]) -> CheriProxy if no block given, else result of block
|
127
|
+
#
|
128
|
+
def cheri(*r,&k)
|
129
|
+
if (ctx = __cheri_ctx)
|
130
|
+
if k
|
131
|
+
CheriFrame.new(ctx,*r,&k).run
|
132
|
+
else
|
133
|
+
ctx[:cheri_proxy] ||= CheriProxy.new(ctx,*r)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
private :cheri
|
138
|
+
|
139
|
+
|
140
|
+
# call-seq:
|
141
|
+
# __cheri_ctx -> context object for the current instance/thread
|
142
|
+
#
|
143
|
+
def __cheri_ctx
|
144
|
+
unless (ic = @__cheri_ctx)
|
145
|
+
# don't create context unless we're an installed Cheri module
|
146
|
+
# (this is part of the solution for preventing Cheri modules installed
|
147
|
+
# at the top level (in Object) from being unintentionally inherited)
|
148
|
+
return unless (g = self.class.instance_variable_get(:@__cheri_cfg)).instance_of?(Config)
|
149
|
+
# using ||= in case another thread slipped by us
|
150
|
+
# TODO: is ||= actually atomic?
|
151
|
+
ic = @__cheri_ctx ||= InstanceContext.new(self,g)
|
152
|
+
end
|
153
|
+
ic.current
|
154
|
+
end
|
155
|
+
private :__cheri_ctx
|
156
|
+
|
157
|
+
# Module used by cheri(){} method. Supplies pseudo-factory that
|
158
|
+
# searches all installed factories.
|
159
|
+
module CheriModule
|
160
|
+
|
161
|
+
# Returns CheriFactory
|
162
|
+
def self.factory
|
163
|
+
CheriFactory
|
164
|
+
end
|
165
|
+
|
166
|
+
# Factory used by cheri(){} method - searches all installed
|
167
|
+
# factories.
|
168
|
+
module CheriFactory
|
169
|
+
# Searches all factories, in the reverse order their
|
170
|
+
# modules were included.
|
171
|
+
def self.builder(ctx,*r,&k)
|
172
|
+
ctx.cfg.mods.reverse_each do |m|
|
173
|
+
if m != CheriModule && m.respond_to?(:factory) && (f = m.factory)
|
174
|
+
if (b = f.builder(ctx,*r,&k))
|
175
|
+
return b
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
nil
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# a base class for proxies
|
185
|
+
class BaseProxy
|
186
|
+
keep = /^(methods|instance_|__|=|class|to_s|eql\?|equal\?|inspect|instance_eval|instance_exec|respond_to\?)/
|
187
|
+
instance_methods.each do |m|
|
188
|
+
undef_method m unless m =~ keep
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
class << self
|
193
|
+
def impl(meths)
|
194
|
+
meths.each do |m|
|
195
|
+
self.module_eval <<-EOM
|
196
|
+
def #{m}(*r,&k)
|
197
|
+
@ctx.msend(mod,:#{m},*r,&k)
|
198
|
+
end
|
199
|
+
EOM
|
200
|
+
end
|
201
|
+
end
|
202
|
+
private :impl
|
203
|
+
end #self
|
204
|
+
|
205
|
+
def initialize(ctx,*r)
|
206
|
+
@ctx = ctx
|
207
|
+
end
|
208
|
+
|
209
|
+
# override to return builder module
|
210
|
+
def mod
|
211
|
+
CheriModule
|
212
|
+
end
|
213
|
+
private :mod
|
214
|
+
|
215
|
+
# call-seq:
|
216
|
+
# vget(:@var) -> @var in client instance
|
217
|
+
#
|
218
|
+
# Returns the value of the specified instance variable in client. Provided
|
219
|
+
# for use when instance_eval / instance_exec are used to evaluate blocks
|
220
|
+
# (:block_method => :eval or :block_method => :exec)
|
221
|
+
def vget(sym)
|
222
|
+
@ctx.client.instance_variable_get(sym)
|
223
|
+
end
|
224
|
+
|
225
|
+
# call-seq:
|
226
|
+
# vset(:@var, value) -> @var in client instance
|
227
|
+
#
|
228
|
+
# Sets the value of the specified instance variable in client. Provided
|
229
|
+
# for use when instance_eval / instance_exec are used to evaluate blocks
|
230
|
+
# (:block_method => :eval or :block_method => :exec)
|
231
|
+
def vset(sym,val)
|
232
|
+
@ctx.client.instance_variable_set(sym,val)
|
233
|
+
end
|
234
|
+
|
235
|
+
# prevent mind-boggling circular displays in IRB
|
236
|
+
def inspect
|
237
|
+
"#<#{self.class}:instance>"
|
238
|
+
end
|
239
|
+
|
240
|
+
def method_missing(*r,&k)
|
241
|
+
@ctx.msend(mod,*r,&k)
|
242
|
+
end
|
243
|
+
private :method_missing
|
244
|
+
|
245
|
+
end #BaseProxy
|
246
|
+
|
247
|
+
class CheriProxy < BaseProxy
|
248
|
+
# def [](opts)
|
249
|
+
# self
|
250
|
+
# end
|
251
|
+
end #CheriProxy
|
252
|
+
|
253
|
+
class CheriFrame
|
254
|
+
include Frame
|
255
|
+
def initialize(ctx,*r,&k)
|
256
|
+
super
|
257
|
+
@obj = ctx[:cheri_proxy] ||= CheriProxy.new(ctx,*r)
|
258
|
+
end
|
259
|
+
def mod
|
260
|
+
CheriModule
|
261
|
+
end
|
262
|
+
end #CheriFrame
|
263
|
+
|
264
|
+
module DefaultConsumer
|
265
|
+
G = 'get_' #:nodoc:
|
266
|
+
S = 'set_' #:nodoc:
|
267
|
+
I = 'is_' #:nodoc:
|
268
|
+
|
269
|
+
# call-seq:
|
270
|
+
# DefaultConsumer.consume(context,builder,sym,*args,&block) -> consumed?, ret_val
|
271
|
+
#
|
272
|
+
def self.consume(ctx,bld,sym,*args,&k)
|
273
|
+
obj = bld.object
|
274
|
+
puts "default consumer called for #{sym}"
|
275
|
+
s = sym.to_s
|
276
|
+
# if sym is already clearly a getter/setter/is-er (xxx=, xxx?, get_xxx, set_xxx, is_xxx),
|
277
|
+
# then leave it as is.
|
278
|
+
# (Note: tested the following line against s =~ /((\?|=)$|^(get_|set_|is_))/ - this is about
|
279
|
+
# 50% faster in MRI (C) Ruby, but currently slower in JRuby (0.9.9)...)
|
280
|
+
if (c = s[-1]) == ?= || c == ?? || s.rindex(G,0) || s.rindex(S,0) || s.rindex(I,0)
|
281
|
+
snd = sym
|
282
|
+
# otherwise, if there are args and the sym works as a setter (xxx=), then prefer
|
283
|
+
# that to a getter.
|
284
|
+
elsif !args.empty? && obj.respond_to?(snd = s << ?= ) # TODO: careful, what if sym was String?
|
285
|
+
# otherwise leave it as is
|
286
|
+
else
|
287
|
+
snd = sym
|
288
|
+
end
|
289
|
+
if obj.respond_to?(snd)
|
290
|
+
if !args.empty? && bld.respond_to?(:resolve?) && bld.resolve?
|
291
|
+
# context.resolve_method_constants(object,send_sym,args)
|
292
|
+
ctx.mrz(obj,snd,args)
|
293
|
+
end
|
294
|
+
res = nil
|
295
|
+
begin
|
296
|
+
res = obj.__send__(snd, *args)
|
297
|
+
rescue
|
298
|
+
return false,nil
|
299
|
+
end
|
300
|
+
# here's our little inside-out trick. really no different than saying
|
301
|
+
# obj1().obj2()...objn().doSomething(), except that multiple operations
|
302
|
+
# can be performed in the scope of the block. a bit like JavaScript's
|
303
|
+
# 'with' statement in that respect.
|
304
|
+
if k && res
|
305
|
+
|
306
|
+
# TODO: update comments
|
307
|
+
#
|
308
|
+
# get a cheri_yield builder for the return value and run it. the
|
309
|
+
# builder is obtained through the context rather than created directly,
|
310
|
+
# as different builders are used for different types of objects (Java vs.
|
311
|
+
# non-Java, for instance).
|
312
|
+
ctx.send(:cheri_yield,res,&k)
|
313
|
+
end
|
314
|
+
return true,res
|
315
|
+
end
|
316
|
+
return false,nil # consumed,ret_val
|
317
|
+
end #consume
|
318
|
+
|
319
|
+
end #DefaultConsumer
|
320
|
+
|
321
|
+
|
322
|
+
# TODO: comments
|
323
|
+
# The connecter of last resort
|
324
|
+
DefaultConnecter = TypeConnecter.new do
|
325
|
+
Eq = '='
|
326
|
+
St = 'set_'
|
327
|
+
|
328
|
+
type Object do
|
329
|
+
connect Object do |parent,obj,sym,props|
|
330
|
+
if parent.respond_to?(snd = (s = sym.to_s) + Eq) ||
|
331
|
+
parent.respond_to?(snd = St + s) ||
|
332
|
+
parent.respond_to?(snd = :add)
|
333
|
+
#puts "Builder::DefaultConnecter for #{parent}, #{obj}: #{snd}"
|
334
|
+
parent.__send__(snd,obj) rescue nil
|
335
|
+
end
|
336
|
+
nil
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
|
342
|
+
# The ConstantResolver classes/modules are designed primarily for use with
|
343
|
+
# Java classes, for which constant name specification/qualification can be
|
344
|
+
# especially onerous. This _might_ find some use in pure Ruby applications;
|
345
|
+
# the mechanism (substituting values for :Constant symbols found in constructor
|
346
|
+
# or method arguments) could conceivably be repurposed in interesting ways.
|
347
|
+
# Meanwhile, it was cleaner to define this here, rather than having to maintain
|
348
|
+
# separate versions of Context and all the attendant fuss.
|
349
|
+
class AbstractConstantResolver
|
350
|
+
# note that we pass args, not *args, as we want the original array
|
351
|
+
def resolve_ctor(clazz,args)
|
352
|
+
false
|
353
|
+
end
|
354
|
+
|
355
|
+
def resolve_meth(object,method_name,args)
|
356
|
+
false
|
357
|
+
end
|
358
|
+
end #AbstractConstantResolver
|
359
|
+
|
360
|
+
class CherifyBuilder < BaseBuilder
|
361
|
+
def initialize(context,sym,object,*args,&block)
|
362
|
+
super(context,sym,*args,&block)
|
363
|
+
@obj = object
|
364
|
+
@clazz = object.class
|
365
|
+
@no_create = true
|
366
|
+
end
|
367
|
+
end #CherifyBuilder
|
368
|
+
|
369
|
+
class CheriYieldBuilder < BaseBuilder
|
370
|
+
def initialize(context,sym,object,*args,&block)
|
371
|
+
super(context,sym,*args,&block)
|
372
|
+
@obj = object
|
373
|
+
@clazz = object.class
|
374
|
+
@no_create = true
|
375
|
+
@not_child = true
|
376
|
+
end
|
377
|
+
end #CheriYieldBuilder
|
378
|
+
|
379
|
+
module CherifyFactory # < Cheri::AbstractFactory
|
380
|
+
def self.builder(context,sym,*args,&block)
|
381
|
+
return nil unless sym == :cherify
|
382
|
+
# TODO: validate second arg is hash if present
|
383
|
+
raise Cheri.argument_error(args.length, 1..2) unless args.length == 1 || args.length == 2
|
384
|
+
CherifyBuilder.new(context,sym,*args,&block)
|
385
|
+
end
|
386
|
+
end #CherifyFactory
|
387
|
+
|
388
|
+
# TODO: comments
|
389
|
+
module CheriYieldFactory # < Cheri::AbstractFactory
|
390
|
+
def self.builder(context,sym,*args,&block)
|
391
|
+
return nil unless sym == :cheri_yield
|
392
|
+
raise Cheri.argument_error(args.length, 1) unless args.length == 1
|
393
|
+
CheriYieldBuilder.new(context,sym,*args,&block)
|
394
|
+
end
|
395
|
+
end #CheriYieldFactory
|
396
|
+
|
397
|
+
# A do-nothing factory. May be safley returned by the +factory+ method
|
398
|
+
# of builder modules that don't supply builders
|
399
|
+
module NilFactory
|
400
|
+
def self.builder(*r,&k)
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
module NilConnecter
|
405
|
+
def self.prepare(*r)
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
|
410
|
+
class Aggregate < Array
|
411
|
+
def initialize(*args,&k)
|
412
|
+
args.each do |a|
|
413
|
+
self << a
|
414
|
+
end
|
415
|
+
yield self if block_given?
|
416
|
+
end
|
417
|
+
alias_method :app, :<<
|
418
|
+
#protected :app # broken in JRuby 1.0.0RC-1
|
419
|
+
def <<(elem)
|
420
|
+
app(elem) unless include?(elem)
|
421
|
+
end
|
422
|
+
end #Aggregate
|
423
|
+
|
424
|
+
# class to aggregate factories
|
425
|
+
class SuperFactory < Aggregate
|
426
|
+
def builder(ctx,sym,*r,&k)
|
427
|
+
each do |f|
|
428
|
+
if (b = f.builder(ctx,sym,*r,&k))
|
429
|
+
return b
|
430
|
+
end
|
431
|
+
end
|
432
|
+
nil
|
433
|
+
end
|
434
|
+
end #SuperFactory
|
435
|
+
|
436
|
+
|
437
|
+
# class to aggregate connecters
|
438
|
+
class SuperConnecter < Aggregate
|
439
|
+
def prepare(*r)
|
440
|
+
each do |ctr|
|
441
|
+
return true if ctr.prepare(*r)
|
442
|
+
end
|
443
|
+
false
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
# class to aggregate consumers
|
448
|
+
class SuperConsumer < Aggregate
|
449
|
+
def consume(*r,&k)
|
450
|
+
each do |cns|
|
451
|
+
c, v = cns.consume(*r,&k)
|
452
|
+
return c,v if c
|
453
|
+
end
|
454
|
+
return false, nil
|
455
|
+
end
|
456
|
+
end #SuperConsumer
|
457
|
+
|
458
|
+
# class to aggregate resolvers
|
459
|
+
# TODO: the Java resolver won't play nicely right now; raises if it fails to resolve
|
460
|
+
class SuperResolver < Aggregate
|
461
|
+
def resolve_ctor(*r)
|
462
|
+
each do |rsv|
|
463
|
+
return true if rsv.resolve_ctor(*r)
|
464
|
+
end
|
465
|
+
false
|
466
|
+
end
|
467
|
+
def resolve_meth(*r)
|
468
|
+
each do |rsv|
|
469
|
+
return true if rsv.resolve_meth(*r)
|
470
|
+
end
|
471
|
+
false
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
|
476
|
+
DefaultFactory = SuperFactory.new do |f|
|
477
|
+
f << CherifyFactory
|
478
|
+
f << CheriYieldFactory
|
479
|
+
end
|
480
|
+
|
481
|
+
|
482
|
+
end #Builder
|
483
|
+
end #Cheri
|