redparse 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+