redparse 0.8.0

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.
@@ -0,0 +1,8 @@
1
+ <!DOCTYPE Workspace SYSTEM "http://www.slickedit.com/dtd/vse/10.0/vpw.dtd">
2
+ <Workspace Version="10.0" VendorName="SlickEdit">
3
+ <Projects>
4
+ <Project File="redparse.vpj" />
5
+ <Project File="/rubylexer/rubylexer.vpj" />
6
+ <Project File="/rubymacros/rubymacros.vpj" />
7
+ </Projects>
8
+ </Workspace>
@@ -0,0 +1,5 @@
1
+ p gg
2
+
3
+ __END__
4
+ foo bar baz
5
+ quux
@@ -0,0 +1,2 @@
1
+ p __FILE__
2
+ "#{__FILE__}"
@@ -0,0 +1,3 @@
1
+ =begin
2
+ =end
3
+
@@ -0,0 +1,6 @@
1
+ begin
2
+ require 'rubygems'
3
+ rescue Exception
4
+ end
5
+
6
+ p gg
@@ -0,0 +1,3 @@
1
+ <<`hah`
2
+ #don't try this at home, boys and girls
3
+ hah
@@ -0,0 +1,3 @@
1
+ <<`hah`
2
+ #don't try this at #{home}, boys and girls
3
+ hah
@@ -0,0 +1,8 @@
1
+ case
2
+ a
3
+ when
4
+ b
5
+ then
6
+ c
7
+ end
8
+
@@ -0,0 +1,66 @@
1
+ =begin
2
+ = xmlrpc/datetime.rb
3
+ Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de)
4
+
5
+ Released under the same term of license as Ruby.
6
+
7
+ = Classes
8
+ * ((<XMLRPC::DateTime>))
9
+
10
+ = XMLRPC::DateTime
11
+ == Description
12
+ This class is important to handle XMLRPC (('dateTime.iso8601')) values,
13
+ correcly, because normal UNIX-dates (class (({Date}))) only handle dates
14
+ from year 1970 on, and class (({Time})) handles dates without the time
15
+ component. (({XMLRPC::DateTime})) is able to store a XMLRPC
16
+ (('dateTime.iso8601')) value correctly.
17
+
18
+ == Class Methods
19
+ --- XMLRPC::DateTime.new( year, month, day, hour, min, sec )
20
+ Creates a new (({XMLRPC::DateTime})) instance with the
21
+ parameters ((|year|)), ((|month|)), ((|day|)) as date and
22
+ ((|hour|)), ((|min|)), ((|sec|)) as time.
23
+ Raises (({ArgumentError})) if a parameter is out of range, or ((|year|)) is not
24
+ of type (({Integer})).
25
+
26
+ == Instance Methods
27
+ --- XMLRPC::DateTime#year
28
+ --- XMLRPC::DateTime#month
29
+ --- XMLRPC::DateTime#day
30
+ --- XMLRPC::DateTime#hour
31
+ --- XMLRPC::DateTime#min
32
+ --- XMLRPC::DateTime#sec
33
+ Return the value of the specified date/time component.
34
+
35
+ --- XMLRPC::DateTime#mon
36
+ Alias for ((<XMLRPC::DateTime#month>)).
37
+
38
+ --- XMLRPC::DateTime#year=( value )
39
+ --- XMLRPC::DateTime#month=( value )
40
+ --- XMLRPC::DateTime#day=( value )
41
+ --- XMLRPC::DateTime#hour=( value )
42
+ --- XMLRPC::DateTime#min=( value )
43
+ --- XMLRPC::DateTime#sec=( value )
44
+ Set ((|value|)) as the new date/time component.
45
+ Raises (({ArgumentError})) if ((|value|)) is out of range, or in the case
46
+ of (({XMLRPC::DateTime#year=})) if ((|value|)) is not of type (({Integer})).
47
+
48
+ --- XMLRPC::DateTime#mon=( value )
49
+ Alias for ((<XMLRPC::DateTime#month=>)).
50
+
51
+ --- XMLRPC::DateTime#to_time
52
+ Return a (({Time})) object of the date/time which (({self})) represents.
53
+ If the (('year')) is below 1970, this method returns (({nil})),
54
+ because (({Time})) cannot handle years below 1970.
55
+ The used timezone is GMT.
56
+
57
+ --- XMLRPC::DateTime#to_date
58
+ Return a (({Date})) object of the date which (({self})) represents.
59
+ The (({Date})) object do ((*not*)) contain the time component (only date).
60
+
61
+ --- XMLRPC::DateTime#to_a
62
+ Returns all date/time components in an array.
63
+ Returns (({[year, month, day, hour, min, sec]})).
64
+ =end
65
+
66
+
@@ -0,0 +1,9 @@
1
+ proc{q=1;def q.foo; end} #q should be varnametoken, both times
2
+ module Defined_p_syntax_tests
3
+ def self.defined?(foo) :baz end #should be methname
4
+ def defined?(foo) :bar end #should be methname
5
+ def ameth
6
+ p(defined? 44) #should be keyword
7
+ p(self.defined? 44) #should be methname
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ def
2
+ koomblatz!() p 'jdkfsk' end
3
+
4
+ p <<ggg; def
5
+ kleegarts() p 'kkkkkkk' end
6
+ dfgdgfdf
7
+ ggg
8
+ koomblatz!() p 'jdkfsk' end
@@ -0,0 +1,3 @@
1
+ <<-"heredoc"
2
+ a b c #{d}
3
+ heredoc
@@ -0,0 +1,3 @@
1
+ <<-"heredoc"
2
+ a b c #{d}
3
+ heredoc
@@ -0,0 +1,3 @@
1
+ <<-"heredoc"+'ggg'
2
+ a b c #{d}
3
+ heredoc
@@ -0,0 +1,75 @@
1
+ p <<end
2
+ #{compile_body}#{outvar}
3
+ end
4
+
5
+ p <<end
6
+ #{compile_body}
7
+ #{outvar}
8
+ end
9
+
10
+ p <<end
11
+ #{compile_body}\
12
+ #{outvar}
13
+ end
14
+
15
+ p <<end
16
+ #{compile_body}\
17
+ \
18
+ \
19
+ \
20
+ \
21
+ \
22
+ #{outvar}
23
+ end
24
+
25
+ p "\
26
+ "
27
+
28
+ p "\
29
+ #{x}
30
+ "
31
+
32
+ p "
33
+ #{x}a\
34
+ "
35
+
36
+ p "
37
+ #{x}\
38
+ b"
39
+
40
+ p "\
41
+ #{x}\
42
+ "
43
+
44
+ p "
45
+ #{x}\
46
+ "
47
+
48
+ p "
49
+ #{x}"
50
+
51
+
52
+
53
+ p "
54
+ #$x\
55
+ "
56
+
57
+ p "
58
+ #@x\
59
+ "
60
+
61
+ p "
62
+ #@@x\
63
+ "
64
+
65
+ p "
66
+ #$x"
67
+
68
+ p "
69
+ #@x"
70
+
71
+ p "
72
+ #@@x"
73
+
74
+ p " #$a #@b #@@c "
75
+ p "#$a#@b#@@c"
@@ -0,0 +1,4 @@
1
+ p "
2
+ #{x}\
3
+ "
4
+
@@ -0,0 +1,4 @@
1
+ <<a "foobar"
2
+ bazquux
3
+ a
4
+
@@ -0,0 +1,3 @@
1
+ <<`eof`
2
+ foo bar #{baz}
3
+ eof
@@ -0,0 +1,3 @@
1
+ <<here
2
+ here
3
+
@@ -0,0 +1,7 @@
1
+ if
2
+ a
3
+ then
4
+ b
5
+ else
6
+ c
7
+ end
@@ -0,0 +1,779 @@
1
+ catch (:f){}
2
+ __END__
3
+ if !RUBY_PLATFORM["cyg"].nil? then
4
+ ret = `cygpath -w #{ret}`.gsub(/\\/,"/").chomp
5
+ end
6
+
7
+ ##########################################################################
8
+ # Low level API area
9
+ ##########################################################################
10
+
11
+ def __build_bridge
12
+ return if defined?(@@object_table)
13
+
14
+ @@driver = nil
15
+ if defined?(JBRIDGE_OPTIONS) then
16
+ @@options = JBRIDGE_OPTIONS
17
+ else
18
+ @@options = Hash.new
19
+ end
20
+
21
+ @@object_table = Hash.new # proxy_id -> object
22
+ @@gc_manager = JGCManager.instance
23
+
24
+ @@debug_out = __jbopt(:bridge_log)
25
+
26
+ print_debug("JavaBridge: Startup communication bridge...")
27
+
28
+ case __jbopt(:bridge_driver)
29
+ when :xmlrpc
30
+ @@driver = XMLRPCBridge.instance
31
+ when :bstream
32
+ @@driver = BinStreamBridge.instance
33
+ else
34
+ raise "Driver #{__jbopt(:bridge_driver).to_s} not found."
35
+ end
36
+ @@driver.set_debugout( lambda{|a| print_debug(a)} )
37
+
38
+ __startup_JVM
39
+ @@driver.startup_server(@@opt_proc, lambda { |*args| __called_by_java(*args)})
40
+ @@class_repository = JClassRepository.new
41
+
42
+ print_debug("JavaBridge: Finished initialized.")
43
+ end
44
+
45
+ def __startup_JVM
46
+ #JVM CLASSPATH
47
+ cp = `echo "#{__jbopt(:classpath)}"`.chomp
48
+ cp = "#{cp}#{__cpseparator}#{@@driver.get_bridge_classpath(__search_libpath)}"
49
+ print_debug("CLASSPATH: #{cp}")
50
+ #JVM PATH
51
+ path = __jbopt(:jvm_path)
52
+ return unless path
53
+ #JVM VM ARGS
54
+ vmarg = __jbopt(:jvm_vm_args)
55
+
56
+ #JVM LOG
57
+ if __jbopt(:jvm_log_file).nil? then
58
+ logfile = ""
59
+ else
60
+ logfile = " -logfile:#{__jbopt(:jvm_log_file)} "
61
+ end
62
+ loglevel = __jbopt(:jvm_log_level)
63
+
64
+ #DRIVER ARGS
65
+ driver_args = @@driver.get_bridge_args(@@opt_proc)
66
+ return if driver_args.nil?
67
+
68
+ cmd = "#{path} #{vmarg} -classpath \"#{cp}\" #{driver_args} -logLevel:#{loglevel} #{logfile}"
69
+ print_debug(cmd)
70
+
71
+ #EXEC COMMAND AND WAIT FOR INIT
72
+ io = IO.popen(cmd,"r")
73
+ while true
74
+ line = io.gets
75
+ puts "JVM: #{line}" if @@debug_out
76
+ abort "Can not start JVM: \n#{cmd}" if line.nil?
77
+ break if line =~ /^OK/
78
+ end
79
+
80
+ #START STDOUT PUTTER
81
+ if __jbopt(:jvm_stdout) != :never then
82
+ Thread.start(io) {|java_io|
83
+ loop {
84
+ if __jbopt(:jvm_stdout) then
85
+ puts java_io.gets
86
+ else
87
+ java_io.gets
88
+ end
89
+ }
90
+ }
91
+ end
92
+
93
+ #REGISTER JVM KILLER
94
+ at_exit {
95
+ print_debug " EXIT JavaBridge..."
96
+ begin
97
+ break_bridge
98
+ rescue => e
99
+ puts e.message
100
+ puts e.backtrace.join("\n")
101
+ ensure
102
+ begin
103
+ Process.kill(:QUIT, io.pid)
104
+ rescue
105
+ puts e.message
106
+ puts e.backtrace.join("\n")
107
+ end
108
+ end
109
+ print_debug " EXIT JavaBridge..."
110
+ }
111
+ print_debug("JVM: Initialized.")
112
+ end
113
+
114
+ def __register(obj)
115
+ @@object_table[obj.__object_id] = obj
116
+ obj
117
+ end
118
+
119
+ def print_debug(out)
120
+ puts out if @@debug_out
121
+ end
122
+
123
+ # Called by java
124
+ def __called_by_java(sid,obj_id,method_name,args)
125
+ print_debug "%% Received: #{obj_id}.#{method_name} : #{args.join(", ")}"
126
+ obj = @@object_table[obj_id]
127
+ if obj.nil? then
128
+ # not found extended object
129
+ raise "Object: #{obj_id} not found."
130
+ else
131
+ # OK
132
+ Thread.current[:__jb_session] = sid
133
+ begin
134
+ ret = obj.__jsend__(method_name,*args)
135
+ return ret
136
+ rescue => ev
137
+ print_debug "EXCEPTION (for debug): #{ev} -------------"
138
+ print_debug ev.backtrace
139
+ sa = args.join(",")
140
+ print_debug "sid:#{sid} object:#{obj.__classname} method:#{method_name} args:#{sa}:#{args.size}"
141
+ print_debug "------------------------------------------"
142
+ raise ev
143
+ ensure
144
+ Thread.current[:__jb_session] = nil
145
+ end
146
+ end
147
+ end
148
+
149
+ # calling the JavaBridge API
150
+ def __send_message_to_java(method,*args)
151
+ sid = Thread.current[:__jb_session]
152
+ if sid then
153
+ # session thread logic
154
+ print_debug "## SESSION[#{sid}] SendMessage: #{method}( #{args.join(", ")} )"
155
+ args.insert(0,sid,method)
156
+ return @@driver.send_message_to_java("sessionCall",*args)
157
+ else
158
+ # normal calling
159
+ print_debug "## SendMessage: #{method}( #{args.join(", ")} )"
160
+ return @@driver.send_message_to_java(method,*args)
161
+ end
162
+ end
163
+
164
+ ##########################################################################
165
+ # Public API area
166
+ ##########################################################################
167
+
168
+ public
169
+
170
+ # Sending a shutdown message to the JVM.
171
+ def break_bridge()
172
+ return unless defined?(@@object_table)
173
+ @@gc_manager.cancel_all_finalizer
174
+ @@driver.shutdown_server if @@driver.connected?
175
+ nil
176
+ end
177
+
178
+ # Resuming the main thread.
179
+ def wakeup_thread()
180
+ @@main_thread.wakeup
181
+ nil
182
+ end
183
+
184
+ def stop_thread()
185
+ return unless defined?(@@object_table)
186
+ @@main_thread = Thread.current
187
+ Thread.stop
188
+ nil
189
+ end
190
+
191
+ def jnew(classname,*args)
192
+ __build_bridge
193
+ obj = JCreatedObject.new(__to_s(classname),*args)
194
+ @@gc_manager.register_finalizer(obj)
195
+ return obj
196
+ end
197
+
198
+ def jextend(classnames,*args,&impl)
199
+ __build_bridge
200
+ ret = __register(JExtendedClass.new(__to_s(classnames),*args))
201
+ ret.set_default_dispatcher(impl) if impl
202
+ return ret
203
+ end
204
+
205
+ def jstatic(classname)
206
+ __build_bridge
207
+ obj = JClass.new(__to_s(classname))
208
+ return obj
209
+ end
210
+
211
+ def jimport(lines)
212
+ __build_bridge
213
+ __send_message_to_java("import",lines)
214
+ nil
215
+ end
216
+
217
+ def junlink(proxy)
218
+ __build_bridge
219
+ if proxy.kind_of?(JExtendedClass) then
220
+ key = proxy.__object_id
221
+ __send_message_to_java("unlink",key)
222
+ else
223
+ print_debug("The object #{proxy.__object_id} will be garbage_collected automatically.")
224
+ end
225
+ end
226
+
227
+ #return all proxy objects in the object repositry.
228
+ def jdump_object_list
229
+ __build_bridge
230
+ return __send_message_to_java("allObjects")
231
+ end
232
+
233
+ ##########################################################################
234
+ # private API
235
+ ##########################################################################
236
+
237
+ private
238
+
239
+ def __jclassname(key)
240
+ __send_message_to_java("classname",key)
241
+ end
242
+
243
+ # creating a proxy object.
244
+ def jproxy(classname,key)
245
+ __build_bridge
246
+ obj = JProxyObject.new(__to_s(classname),key)
247
+ @@gc_manager.register_finalizer(obj)
248
+ return obj
249
+ end
250
+
251
+ def __to_s(classname)
252
+ return classname if classname.instance_of? String
253
+ classname.to_s.gsub(/_/,".")
254
+ end
255
+
256
+ def __classinfo(classname)
257
+ __send_message_to_java("classinfo",__to_s(classname)).split(",")
258
+ end
259
+
260
+ ##########################################################################
261
+ # JClass area
262
+ ##########################################################################
263
+
264
+ #
265
+ # Abstract proxy class: a subclass should initialize @__classname, @__object_id
266
+ # and @__classinfo.
267
+ #
268
+ class JObject
269
+
270
+ def method_missing(name,*args)
271
+ print_debug "#### method_missing : #{name}( #{args.join(", ")} )"
272
+ name = name.to_s
273
+ if args.size == 0 then
274
+ #property get?
275
+ return __ref__(name) if __define_jfield?(name)
276
+ else
277
+ args = __obj2ids__(args)
278
+ #property set?
279
+ if !(name =~ /^.*=$/).nil? then
280
+ fname = name[0,name.length-1]
281
+ return __set__(fname,args[0]) if __define_jfield?(fname)
282
+ end
283
+ end
284
+ #method call
285
+ return __id2obj__(__call__(name,*args)) if __define_jmethod?(name)
286
+ #not found
287
+ #super(name,*args)
288
+ as = args.join(",")
289
+ raise NoMethodError.new("Not found method: #{name}(#{as}) in #{__classname}",name, args)
290
+ end
291
+
292
+ def __define_jfield?(name)
293
+ return false if __define_jmethod?(name)
294
+ @__classinfo.define_jfield?(name)
295
+ end
296
+
297
+ def __define_jmethod?(name)
298
+ @__classinfo.define_jmethod?(name)
299
+ end
300
+
301
+ # called by java
302
+ def __jsend__(method,*args)
303
+ args = __id2objs__(args)
304
+ return __send__(method,*args).to_trans_obj
305
+ end
306
+
307
+ def to_trans_obj
308
+ @__object_id
309
+ end
310
+
311
+ attr_reader :__object_id,:__classname,:__classinfo
312
+
313
+ private
314
+
315
+ def __obj2ids__(args)
316
+ args.map{|i| i.to_trans_obj }
317
+ end
318
+
319
+ def __id2obj__(arg)
320
+ return nil if (arg.nil?)
321
+ return __id2objs__(arg) if arg.instance_of?(Array)
322
+ return arg unless arg.instance_of?(String)
323
+ return arg if arg["\n"]
324
+ cn = __jclassname(arg)
325
+ if !cn.nil? then
326
+ return @@object_table[arg] if @@object_table.key?(arg)
327
+ jproxy(cn,arg)
328
+ else
329
+ arg
330
+ end
331
+ end
332
+
333
+ def __id2objs__(args)
334
+ args.map {|i| __id2obj__(i)}
335
+ end
336
+
337
+ def __call__(method,*args)
338
+ args = __obj2ids__(args)
339
+ __id2obj__(__send_message_to_java("call",@__object_id,method,*args))
340
+ end
341
+
342
+ def __ref__(fieldname)
343
+ __id2obj__(__send_message_to_java("ref",@__object_id,fieldname))
344
+ end
345
+
346
+ def __set__(fieldname,value)
347
+ __send_message_to_java("set",@__object_id,fieldname,value)
348
+ nil
349
+ end
350
+
351
+ public
352
+
353
+ def to_s
354
+ "JB:ProxyObject class:#{@__classname}, value:#{__call__('toString')}"
355
+ end
356
+
357
+ def inspect
358
+ to_s
359
+ end
360
+
361
+ def methods
362
+ return @accessible_methods if @accessible_methods
363
+ @accessible_methods = super
364
+ @accessible_methods |= @__classinfo.get_accessible_methods
365
+ return @accessible_methods
366
+ end
367
+
368
+ end # class JObject
369
+
370
+ # the object created by ruby
371
+ class JCreatedObject < JObject
372
+ def initialize(classname,*args)
373
+ if args.size > 0 then
374
+ args = __obj2ids__(args)
375
+ end
376
+ @__object_id = __send_message_to_java("new",classname,*args)
377
+ @__classname = __jclassname(@__object_id)
378
+ @__classinfo = @@class_repository.get_classinfo(@__classname)
379
+ end
380
+ end
381
+
382
+ # the extended object created by ruby
383
+ class JExtendedClass < JObject
384
+
385
+ def initialize(_classnames,*args)
386
+ if args.size > 0 then
387
+ args = __obj2ids__(args)
388
+ end
389
+ @__object_id = __send_message_to_java("extend",_classnames,*args)
390
+ @__classname = __jclassname(@__object_id)
391
+ @__classinfo = @@class_repository.get_classinfo(@__classname)
392
+ @table_impl_proc = Hash.new
393
+ @default_proc = nil
394
+ end
395
+
396
+ def __jsend__(method,*args)
397
+ if respond_to?(method) then
398
+ return super(method,*args)
399
+ elsif @default_proc then
400
+ return @default_proc.call(method,args)
401
+ else
402
+ raise "BUG: called not implemented method."
403
+ end
404
+ end
405
+
406
+ def __super__(method,*args)
407
+ args = __obj2ids__(args)
408
+ __id2obj__(__send_message_to_java("superCall",@__object_id,method,*args))
409
+ end
410
+
411
+ def __call__(method,*args)
412
+ __super__(method,*args)
413
+ end
414
+
415
+ def singleton_method_added(name)
416
+ __send_message_to_java("impl",@__object_id,name.to_s,true)
417
+ end
418
+
419
+ def singleton_method_removed(name)
420
+ __send_message_to_java("impl",@__object_id,name.to_s,false)
421
+ end
422
+
423
+ def singleton_method_undefined(name)
424
+ __send_message_to_java("impl",@__object_id,name.to_s,false)
425
+ end
426
+
427
+ #the easy method implementation by the block notation.
428
+ #users can write the event handler with the java-like variable scope.
429
+ def jdef(name,&aproc)
430
+ @table_impl_proc[name] = aproc
431
+ instance_eval %Q{
432
+ def #{name.to_s}(*args)
433
+ return @table_impl_proc[:#{name.to_s}].call(*args)
434
+ end
435
+ }
436
+ end
437
+
438
+ def set_default_dispatcher(aproc)
439
+ @default_proc = aproc
440
+ end
441
+
442
+ end
443
+
444
+ # the object created in the JVM
445
+ class JProxyObject < JObject
446
+ def initialize(classname,key)
447
+ @__object_id = key
448
+ @__classname = classname
449
+ @__classinfo = @@class_repository.get_classinfo(@__classname)
450
+ end
451
+ end
452
+
453
+ # the static class object
454
+ class JClass < JObject
455
+
456
+ attr_reader :__metainfo
457
+
458
+ def initialize(classname)
459
+ @__object_id = __send_message_to_java("static",classname)
460
+ @__classname = __jclassname(@__object_id)
461
+ @__classinfo = @@class_repository.get_classinfo(@__classname)
462
+ @__metainfo = @@class_repository.get_classinfo("java.lang.Class")
463
+ end
464
+
465
+ def __define_jmethod?(name)
466
+ @__classinfo.define_jmethod?(name) || @__metainfo.define_jmethod?(name)
467
+ end
468
+
469
+ def methods
470
+ return @accessible_methods if @accessible_methods
471
+ @accessible_methods = super
472
+ @accessible_methods |= @__classinfo.get_accessible_methods
473
+ @accessible_methods |= @__metainfo.get_accessible_methods
474
+ return @accessible_methods
475
+ end
476
+
477
+ end
478
+
479
+ ##########################################################################
480
+ # JClassRepository and JClassInfo area
481
+ ##########################################################################
482
+
483
+ #
484
+ # JClassRepository manages the class information represented by JClassInfo.
485
+ #
486
+ class JClassRepository
487
+ def initialize
488
+ @classtable = Hash.new
489
+ end
490
+
491
+ def get_classinfo(classname)
492
+ return nil if classname.nil?
493
+ info = @classtable[classname]
494
+ return info if info
495
+ info = JClassInfo.new(classname)
496
+ @classtable[classname] = info
497
+ info
498
+ end
499
+ end
500
+
501
+ #
502
+ # JClassInfo treats superclass, public fields, public and protected methods.
503
+ # The instances of JClassInfo make a tree form in which the subclass
504
+ # makes a branche.
505
+ #
506
+ class JClassInfo
507
+
508
+ attr_reader :jsuperclass,:jclassname,:jfields,:jmethods,:protected_jmethods,:jinterfaces
509
+
510
+ def initialize(_classname)
511
+ info = __classinfo(_classname)
512
+ @jclassname = _classname
513
+ @jinterfaces = []
514
+ @jfields = Hash.new
515
+ @jmethods = Hash.new
516
+ @protected_jmethods = Hash.new
517
+ _superclass = nil
518
+ mode = nil
519
+ info.each{|i|
520
+ case i
521
+ when "====Superclass"
522
+ mode = :superclass
523
+ when "====Interfaces"
524
+ mode = :interfaces
525
+ when "====Field"
526
+ mode = :fields
527
+ when "====PublicMethod"
528
+ mode = :methods
529
+ when "====ProtectedMethod"
530
+ mode = :protected_methods
531
+ else
532
+ case mode
533
+ when :superclass
534
+ _superclass = i
535
+ when :interfaces
536
+ @jinterfaces << @@class_repository.get_classinfo(i)
537
+ when :fields
538
+ @jfields[i] = :t
539
+ when :methods
540
+ @jmethods[i] = :t
541
+ when :protected_methods
542
+ @protected_jmethods[i] = :t
543
+ end
544
+ end
545
+ }
546
+ if _superclass then
547
+ @jsuperclass = @@class_repository.get_classinfo(_superclass)
548
+ else
549
+ @jsuperclass = nil
550
+ end
551
+
552
+ @public_jmethods = @jmethods.keys
553
+ @public_jmethods |= @jsuperclass.get_accessible_methods if @jsuperclass
554
+ @jinterfaces.each {|i| @public_jmethods |= i.get_accessible_methods }
555
+ end
556
+
557
+ def define_jfield?(name)
558
+ return true if @jfields.key?(name)
559
+ if (!@jsuperclass.nil?) then
560
+ return true if @jsuperclass.define_jfield?(name)
561
+ end
562
+ @jinterfaces.each {|i|
563
+ return true if i.define_jfield?(name)
564
+ }
565
+ false
566
+ end
567
+
568
+ def define_jmethod?(name)
569
+ return true if @jmethods.key?(name)
570
+ if @jsuperclass then
571
+ return true if @jsuperclass.define_jmethod?(name)
572
+ end
573
+ @jinterfaces.each {|i|
574
+ return true if i.define_jmethod?(name)
575
+ }
576
+ false
577
+ end
578
+
579
+ def define_protected_jmethod?(name)
580
+ return true if @protected_jmethods.key?(name)
581
+ return @jsuperclass.define_protected_jmethod?(name) if @jsuperclass
582
+ @jinterfaces.each {|i|
583
+ return true if i.define_jmethod?(name)
584
+ }
585
+ false
586
+ end
587
+
588
+ #return public java methods
589
+ def get_accessible_methods
590
+ return @public_jmethods
591
+ end
592
+
593
+ def dump
594
+ puts "========: #{@jclassname}"
595
+ puts " == Superclass: #{@jsuperclass.jclassname}" if @jsuperclass
596
+ putter = lambda {|i| puts " #{i}" }
597
+ puts " == Interface"
598
+ @jinterfaces.each {|i| puts " #{i.jclassname}"}
599
+ puts " == Field"
600
+ @jfields.each_key(putter)
601
+ puts " == Public Method"
602
+ @jmethods.each_key(putter)
603
+ puts " == ProtectedMethod Method"
604
+ @protected_jmethods.each_key(putter)
605
+ end
606
+ end
607
+
608
+ ##########################################################################
609
+ # Exception holder for the exceptions occurred in Java
610
+ ##########################################################################
611
+
612
+ class JException < RuntimeError
613
+
614
+ attr_reader :klass,:message,:detail
615
+
616
+ def initialize(klass,message,detail)
617
+ @klass = klass
618
+ @message = message
619
+ @detail = detail
620
+ end
621
+
622
+ def message
623
+ ret = ""
624
+ ret += @klass if @klass
625
+ ret += "\n"+@message if @message
626
+ ret += "\n"+@detail if @detail
627
+ return ret
628
+ end
629
+
630
+ alias :to_s :message
631
+
632
+ end
633
+
634
+ private
635
+
636
+ ##########################################################################
637
+ # GC manager: send unlink message to Java for removing the object reference
638
+ ##########################################################################
639
+
640
+ class JGCManager
641
+ include Singleton
642
+
643
+ def initialize
644
+ @@object_id_table = Hash.new # __id__ -> proxy_id
645
+ @@object_ref_counter = Hash.new # proxy_id -> refcounter
646
+ @@object_lock = Monitor.new # lock for finalizer registration and deregistration
647
+
648
+ # I'm not sure that using lists without locking...
649
+ @@using_list1 = false
650
+ @@finalizable_id_list1 = []
651
+ @@using_list2 = false
652
+ @@finalizable_id_list2 = []
653
+
654
+ @@later_registration_list = []
655
+ end
656
+
657
+ public
658
+ def exec_finalizable_objects
659
+ @@object_lock.synchronize do
660
+ @@using_list1 = true
661
+ @@finalizable_id_list1.each {|i| finalize_jobject(i)}
662
+ @@finalizable_id_list1 = []
663
+ @@using_list1 = false
664
+ @@using_list2 = true
665
+ @@finalizable_id_list2.each {|i| finalize_jobject(i)}
666
+ @@finalizable_id_list2 = []
667
+ @@using_list2 = false
668
+ end
669
+ end
670
+
671
+ private
672
+ def finalize_jobject(proxy_id)
673
+ begin
674
+ counter = @@object_ref_counter[proxy_id]
675
+ if counter > 1 then
676
+ counter = counter - 1
677
+ @@object_ref_counter[proxy_id] = counter
678
+ print_debug " ----GC: decrease ref count [#{counter}] : #{proxy_id}"
679
+ return nil
680
+ end
681
+ @@object_ref_counter.delete(proxy_id)
682
+ print_debug " ----GC: sending unlink... : #{proxy_id}"
683
+ __send_message_to_java("unlink",proxy_id)
684
+ print_debug " ----GC: sent ok."
685
+ rescue Exception => e
686
+ p e
687
+ raise RuntimeError.new("Failed to finalize object: [#{proxy_id}] => #{e.class.to_s} : #{e.message}")
688
+ ensure
689
+ print_debug " ----GC: exiting finalizer."
690
+ end
691
+ end
692
+
693
+ def self.register_gc_object_id(pid)
694
+ if !@@using_list1 then
695
+ @@finalizable_id_list1 << pid
696
+ if @@later_registration_list.size > 0 then
697
+ @@finalizable_id_list1.concat @later_registration_list
698
+ @@later_registration_list = []
699
+ end
700
+ elsif !@@using_list2 then
701
+ @@finalizable_id_list2 << pid
702
+ if @@later_registration_list.size > 0 then
703
+ @@finalizable_id_list2.concat @later_registration_list
704
+ @@later_registration_list = []
705
+ end
706
+ else
707
+ print_debug " ----GC: finalize later: #{pid}"
708
+ @@later_registration_list << pid
709
+ end
710
+ end
711
+
712
+ def self.get_finalizer_proc
713
+ return Proc.new {|id|
714
+ proxy_id = @@object_id_table[id]
715
+ begin
716
+ print_debug " ----GC: register unlink: #{proxy_id}"
717
+ JGCManager.register_gc_object_id( proxy_id )
718
+ rescue Exception => e
719
+ p e
720
+ ensure
721
+ @@object_id_table.delete(id)
722
+ end
723
+ }
724
+ end
725
+
726
+ public
727
+ def register_finalizer(proxy)
728
+ @@object_lock.synchronize {
729
+ @@object_id_table[proxy.__id__] = proxy.__object_id
730
+ counter = @@object_ref_counter[proxy.__object_id]
731
+ if counter then
732
+ counter += 1
733
+ else
734
+ counter = 1
735
+ end
736
+ print_debug " ----GC: #{counter} : #{proxy.__object_id}"
737
+ @@object_ref_counter[proxy.__object_id] = counter
738
+ if (!proxy.kind_of?(JObject)) then
739
+ raise RuntimeError.new("GC: different object: #{proxy.to_s}")
740
+ end
741
+ ObjectSpace.define_finalizer(proxy, JGCManager.get_finalizer_proc)
742
+ }
743
+ exec_finalizable_objects
744
+ end
745
+
746
+ public
747
+ def cancel_all_finalizer
748
+ @@object_lock.synchronize {
749
+ print_debug " ----GC: begin cancelling finalizer: #{@@object_id_table.size}"
750
+ @@object_id_table.reject! {|key,value|
751
+ begin
752
+ obj = ObjectSpace._id2ref(key)
753
+ ObjectSpace.undefine_finalizer(obj)
754
+ print_debug " ----GC: cancel: #{obj.__object_id}"
755
+ rescue RangeError => e
756
+ end
757
+ true
758
+ }
759
+ }
760
+ end
761
+ end
762
+
763
+ end #module
764
+
765
+ # Ruby like new methods
766
+ class Symbol
767
+ def jext(*args,&impl)
768
+ JavaBridge::jextend(self, *args, &impl)
769
+ end
770
+
771
+ def jnew(*args)
772
+ JavaBridge::jnew(self, *args)
773
+ end
774
+
775
+ def jclass
776
+ JavaBridge::jstatic(self)
777
+ end
778
+ end
779
+