filament 0.3.0 → 0.4.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.
Files changed (41) hide show
  1. data/CHANGES +96 -0
  2. data/README +2 -2
  3. data/lib/filament.rb +1 -1
  4. data/lib/filament/block_object.rb +11 -0
  5. data/lib/filament/os.rb +0 -3
  6. data/lib/filament/platform.rb +16 -0
  7. data/lib/filament/resolver.rb +2 -1
  8. data/lib/filament/target.rb +118 -10
  9. data/lib/filament/util/filelist2.rb +1 -1
  10. data/lib/filament/util/lazy_list.rb +9 -9
  11. data/plugins/00util/lib/filament/plugins/util.rb +18 -0
  12. data/plugins/01java/lib/filament/java/library.rb +88 -0
  13. data/plugins/{02javame/lib/filament/javame → 01java/lib/filament/java}/tasks/library_task.rb +86 -63
  14. data/plugins/01java/lib/filament/java/tools.rb +1 -0
  15. data/plugins/01java/lib/filament/java/tools/compile.rb +2 -2
  16. data/plugins/01java/lib/filament/java/tools/execute.rb +16 -9
  17. data/plugins/01java/lib/filament/java/tools/jar.rb +1 -1
  18. data/plugins/01java/lib/filament/java/tools/javadoc.rb +22 -0
  19. data/plugins/01java/lib/filament/java/tools/proguard.rb +1 -0
  20. data/plugins/{02javame → 01java}/lib/filament/javame/suite.rb +20 -22
  21. data/plugins/{02javame → 01java}/lib/filament/javame/tasks.rb +0 -1
  22. data/plugins/{02javame → 01java}/lib/filament/javame/tools.rb +0 -1
  23. data/plugins/{02javame → 01java}/lib/filament/javame/tools/descriptor.rb +19 -7
  24. data/plugins/{02javame → 01java}/lib/filament/javame/tools/emulator.rb +0 -1
  25. data/plugins/{02javame → 01java}/lib/filament/javame/tools/external/mpp_sdk.rb +0 -0
  26. data/plugins/{02javame → 01java}/lib/filament/javame/tools/external/wtk.rb +0 -0
  27. data/plugins/{02javame → 01java}/lib/filament/javame/tools/preverifier.rb +0 -2
  28. data/plugins/01java/lib/filament/javase/application.rb +43 -0
  29. data/plugins/01java/lib/filament/javase/tasks.rb +1 -0
  30. data/plugins/01java/lib/init.rb +16 -0
  31. data/plugins/04spin/lib/filament/spin/sji.rb +17 -19
  32. data/plugins/04spin/lib/filament/spin/tasks/sji_task.rb +11 -10
  33. data/plugins/04spin/lib/spin/sji.rb +371 -170
  34. data/plugins/05push/lib/filament/plugins/push.rb +6 -9
  35. data/plugins/05push/lib/filament/push.rb +1 -1
  36. data/plugins/05push/lib/filament/push/conduits/filter_conduit.rb +1 -1
  37. metadata +74 -64
  38. data/CHANGELOG +0 -81
  39. data/plugins/02javame/lib/filament/javame/library.rb +0 -79
  40. data/plugins/02javame/lib/filament/javame/tools/platform.rb +0 -50
  41. data/plugins/02javame/lib/init.rb +0 -14
@@ -1,5 +1,4 @@
1
1
  require 'filament/javame/tools'
2
- require 'filament/javame/tools/platform'
3
2
 
4
3
  module Filament::JavaME::Tools
5
4
  class << self
@@ -1,5 +1,3 @@
1
- require 'filament/javame/tools/platform'
2
-
3
1
  module Filament::JavaME::Tools
4
2
  class << self
5
3
  def preverify(*args, &block)
@@ -0,0 +1,43 @@
1
+ require 'filament/java/library'
2
+
3
+ module Filament::JavaSE
4
+ class Application < Filament::Java::Library
5
+ attr_accessor2 :main_class
6
+
7
+ def init
8
+ super
9
+
10
+ on_init do
11
+ @should_package_deps = true
12
+ @prop_path = "#{output_dir}/app.properties"
13
+ @resources.include(@prop_path)
14
+ end
15
+
16
+ on_define do
17
+ assert_tag :javase
18
+
19
+ task :execute => :build do
20
+ execute
21
+ end
22
+
23
+ file @prop_path => output_dir do |t|
24
+ Filament::JavaME::Tools::write_properties(t.name) do |d|
25
+ collect_outputs(:append_entries).each do |h|
26
+ d.append_entries(h)
27
+ end
28
+
29
+ collect_outputs(:custom_entries).each do |h|
30
+ d.custom_entries(h)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def execute
38
+ Filament::Java::Tools::Execute.new(main_class) do |e|
39
+ e.jar = @library.jar_path
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1 @@
1
+ require 'filament/javase/application'
@@ -3,3 +3,19 @@ require 'filament/java/tools'
3
3
  require 'filament/plugins/java'
4
4
 
5
5
  Filament::Application::plugin(Filament::Plugins::Java)
6
+
7
+ require 'pathname'
8
+
9
+ require 'filament/os'
10
+
11
+ require 'filament/javase/tasks'
12
+ require 'filament/javame/tools'
13
+ require 'filament/javame/tasks'
14
+
15
+ include Filament::OS
16
+
17
+ emulator = ENV['JAVAME_EMULATOR'] || :MppSdk
18
+ Filament::JavaME::Tools::Emulator::set_type(emulator.to_sym)
19
+
20
+ preverifier = ENV['JAVAME_PREVERIFIER'] || darwin? ? :MppSdk : :Wtk
21
+ Filament::JavaME::Tools::Preverifier::set_type(preverifier.to_sym)
@@ -5,32 +5,30 @@ require 'filament/spin/tasks/sji_task'
5
5
  module Filament::Spin
6
6
  class SJI < Filament::Target
7
7
  include Filament::Java::Mixins::Classpath
8
+ include Filament::SrcUtil
8
9
 
9
10
  attr_reader :srcs
10
11
  attr_accessor2 :java_gen_package
11
12
 
12
13
  def init
13
14
  @srcs = Filament::FileList2.new
14
- end
15
-
16
- def define
17
- @sji = Filament::Spin::Tasks::SJITask.new do |sji|
18
- define_sji(sji)
19
- end
20
-
21
- output :tag => :java, :output => @sji.java_files, :tasks => @sji.tasks
22
- output :tag => :spin, :output => @sji.spin_files, :tasks => @sji.tasks
23
- output :tag => :jad_proc do |d|
24
- d.append_entries('spin.bindings' => @sji.bindings.collect {|binding| "#{binding.keys}: #{binding.values}"}.join(';'))
15
+
16
+ on_define do
17
+ unless @srcs.empty?
18
+ @sji = Filament::Spin::Tasks::SJITask.new do |sji|
19
+ sji.working_dir = working_dir
20
+ sji.srcs = srcs
21
+ sji.java_gen_package = @java_gen_package
22
+ sji.java_gen_dir = working_dir(:java_gen)
23
+ sji.spin_gen_dir = working_dir(:spin_gen)
24
+ end
25
+
26
+ output :tag => :java, :output => @sji.java_files, :tasks => @sji.tasks
27
+ output :tag => :spin, :output => @sji.spin_files, :tasks => @sji.tasks
28
+ output :tag => :append_entries,
29
+ :output => {'spin.bindings' => @sji.bindings.collect {|binding| "#{binding.keys}:#{binding.values}"}}
30
+ end
25
31
  end
26
32
  end
27
-
28
- def define_sji(sji)
29
- sji.working_dir = working_dir
30
- sji.srcs = srcs
31
- sji.java_gen_package = @java_gen_package
32
- sji.java_gen_dir = working_dir(:java_gen)
33
- sji.spin_gen_dir = working_dir(:spin_gen)
34
- end
35
33
  end
36
34
  end
@@ -1,4 +1,3 @@
1
- require 'filament/javame/tasks/library_task'
2
1
  require 'spin/sji'
3
2
  require 'rake'
4
3
 
@@ -62,23 +61,25 @@ module Filament::Spin
62
61
 
63
62
  impls = []
64
63
 
65
- @sji.prototypes.each do |prototype|
66
- impls << s = Spin::JavaMethodImpl.new(prototype)
67
- s.java_impl_package = @java_gen_package
68
- @bindings << { (prototype.anonymous? ? '' : prototype.name) => s.full_class_name }
64
+ @sji.spin_prototypes.each do |prototype|
65
+ impls << prototype
66
+ prototype.java_impl_package = @java_gen_package
67
+ @bindings << { (prototype.anonymous? ? '' : prototype.spin_prototype) => prototype.full_class_name }
69
68
  end
70
-
71
- @gen_spin_files = impls.collect{|impl| impl.spin_file(spin_gen_dir)}
72
- @gen_java_files = impls.collect{|impl| impl.java_file(java_gen_dir)}
69
+
70
+ impls += @sji.java_classes
71
+
72
+ @gen_spin_files = impls.collect{|impl| impl.spin_file(spin_gen_dir) if impl.respond_to?(:spin_file)}
73
+ @gen_java_files = impls.collect{|impl| impl.java_file(java_gen_dir) if impl.respond_to?(:java_file)}
73
74
 
74
75
  directory spin_gen_dir
75
76
  @gen_spin_task = task spin_gen_dir => srcs do
76
- impls.each{|impl| impl.write_spin(spin_gen_dir)}
77
+ impls.each{|impl| impl.write_spin(spin_gen_dir) if impl.respond_to?(:write_spin)}
77
78
  end
78
79
 
79
80
  directory java_gen_dir
80
81
  @gen_java_task = task java_gen_dir => srcs do
81
- impls.each{|impl| impl.write_java(java_gen_dir)}
82
+ impls.each{|impl| impl.write_java(java_gen_dir) if impl.respond_to?(:write_java)}
82
83
  end
83
84
  end
84
85
  end
@@ -5,53 +5,161 @@ require 'fileutils'
5
5
  module Spin
6
6
  class SpinJavaInterface
7
7
  def initialize
8
- @prototypes = {}
9
- @anonymous_prototypes = []
8
+ @spin_prototypes = {}
9
+ @spin_anonymous_prototypes = []
10
+ @java_classes = []
10
11
  end
11
12
 
12
- def prototypes
13
- return @prototypes.values + @anonymous_prototypes
13
+ def spin_prototypes
14
+ return @spin_prototypes.values + @spin_anonymous_prototypes
14
15
  end
15
16
 
16
- def prototype(name=nil, *args, &block)
17
+ def spin_prototype(name=nil, *args, &block)
17
18
  if name.nil?
18
- @anonymous_prototypes << p = Prototype.new(name, *args)
19
+ @spin_anonymous_prototypes << p = Prototype.new(name, *args)
19
20
  else
20
- p = @prototypes[name] ||= Prototype.new(name, *args)
21
+ p = @spin_prototypes[name] ||= Prototype.new(name, *args)
21
22
  end
22
23
 
23
24
  p.instance_eval(&block)
24
25
  end
25
26
 
27
+ def java_classes
28
+ return @java_classes
29
+ end
30
+
31
+ def java_class(spin_name, java_name, *args, &block)
32
+ spin_prototype spin_name do
33
+ bind 'new' do
34
+ spin_doc "Creates a #{java_name} for the given Object."
35
+ java_method :constructor, :type => java_name, :params => ['ISpinObject']
36
+ end
37
+ end
38
+
39
+ m = java_name.match(/(.*)\.([^.]*)$/)
40
+ raise "java name #{java_name} is not valid." if m.nil?
41
+ @java_classes << c = JavaType.new(m[1], m[2], *args)
42
+
43
+ c.instance_eval(&block)
44
+ end
45
+
26
46
  def load(path)
27
47
  instance_eval(Pathname.new(path).read, path)
28
48
  end
29
49
  end
30
50
 
31
- class Prototype
32
- attr_accessor2 :java_type, :java_imports
51
+ class JavaType
52
+ attr_accessor2 :implements, :extends
53
+ attr_reader :java_package, :java_class
54
+
55
+ def initialize(java_package, java_class)
56
+ @java_package = java_package
57
+ @java_class = java_class
58
+ @implements = []
59
+ @extends = nil
60
+ @imports = []
61
+ @spin_bindings = []
62
+ end
63
+
64
+ def import(*imports)
65
+ @imports += imports
66
+ end
67
+
68
+ def method(*args, &block)
69
+ b = SpinBinding.new(*args)
70
+ b.instance_eval(&block)
71
+ @spin_bindings << b
72
+ end
73
+
74
+ def verify
75
+ end
76
+
77
+ def java_ancestors
78
+ c = ""
79
+ c << " extends #{@extends}" unless @extends.nil?
80
+
81
+ @implements = [@implements] unless @implements.respond_to?(:to_ary)
82
+
83
+ unless @implements.empty?
84
+ c << " implements " << @implements.join(', ')
85
+ end
86
+
87
+ return c
88
+ end
89
+
90
+ def java
91
+ rjava = ERB.new(java_template, 0, '%<>')
92
+ return rjava.result(binding)
93
+ end
33
94
 
34
- attr_reader :java_bindings, :name, :package
95
+ def write_java(base)
96
+ FileUtils.mkdir_p(java_dir(base))
97
+ open(java_file(base), 'w') {|io| io.write(java)}
98
+ end
35
99
 
36
- def initialize(name)
100
+ def java_dir(base)
101
+ verify
102
+ return "#{base}/#{java_package.gsub(/\./, '/')}"
103
+ end
104
+
105
+ def java_file(base)
106
+ return "#{java_dir(base)}/#{java_class}.java"
107
+ end
108
+
109
+ def java_template
110
+ return %q$ package <%=java_package%>;
111
+
112
+ import com.software4i.spin.*;
113
+ import com.software4i.spin.object.*;
114
+ import com.software4i.spin.util.*;
115
+ <% for import in @imports %>
116
+ import <%=import%>;
117
+ <% end %>
118
+
119
+ public class <%=java_class%> <%=java_ancestors%> {
120
+ private ISpinObject spinObject;
121
+
122
+ public <%=java_class%>(ISpinObject spinObject) {
123
+ this.spinObject = spinObject;
124
+ }
125
+
126
+ <% for spin_binding in @spin_bindings %>
127
+ <%=spin_binding.java_doc%>
128
+ <%=spin_binding.java_signature%> {
129
+ <%=spin_binding.java_code%>
130
+ }
131
+ <% end %>
132
+ }
133
+ $.gsub(/ /, '')
134
+ end
135
+ end
136
+
137
+ class Prototype
138
+ attr_accessor2 :require_type, :java_type, :java_imports
139
+ attr_accessor :java_impl_package
140
+ attr_reader :java_bindings, :spin_prototype, :spin_package, :java_impl_class_name
141
+
142
+ def initialize(spin_prototype)
37
143
  @@id ||= 0
38
144
  @id = @@id
39
145
  @@id += 1
40
146
 
41
- if name.nil?
42
- @name = "Anon#{@id}"
147
+ if spin_prototype.nil?
148
+ @spin_prototype = "Anon#{@id}"
43
149
  @anonymous = true
44
150
  else
45
- @name = name
151
+ @spin_prototype = spin_prototype
46
152
  @anonymous = false
47
153
  end
48
154
 
49
- @package = ''
155
+ @spin_package = ''
156
+ @require_type = :manual || :auto
50
157
  @java_bindings = []
51
158
  @java_imports = []
52
159
  @java_type = nil
160
+ @java_impl_class_name = "SJI#{@spin_prototype}"
53
161
  end
54
-
162
+
55
163
  def java_import(*args)
56
164
  @java_imports += args
57
165
  end
@@ -61,31 +169,212 @@ module Spin
61
169
  end
62
170
 
63
171
  def bind(*args, &block)
64
- b = JavaMethodBinding.new(*args)
65
-
172
+ b = JavaBinding.new(*args)
66
173
  b.java_type(@java_type) unless @java_type.nil?
67
-
68
174
  b.instance_eval(&block)
69
175
  @java_bindings << b
70
176
  end
177
+
178
+ def verify
179
+ raise 'java_impl_class_name' if java_impl_class_name.nil?
180
+ raise 'java_impl_package must be set' if java_impl_package.nil?
181
+
182
+ raise 'bindings cannot be empty' if java_bindings.empty?
183
+
184
+ java_bindings.each {|b| b.verify}
185
+ end
186
+
187
+ def full_class_name
188
+ return "#{java_impl_package}.#{java_impl_class_name}"
189
+ end
190
+
191
+ def spin
192
+ verify
193
+ rspin = ERB.new(spin_template, 0, '%<>')
194
+ return rspin.result(binding)
195
+ end
196
+
197
+ def java
198
+ verify
199
+ rjava = ERB.new(java_template, 0, '%<>')
200
+ return rjava.result(binding)
201
+ end
202
+
203
+ def write_spin(base)
204
+ if require_type == :manual
205
+ FileUtils.mkdir_p(spin_dir(base))
206
+ open(spin_file(base), 'w') {|io| io.write(spin)}
207
+ end
208
+ end
209
+
210
+ def write_java(base)
211
+ FileUtils.mkdir_p(java_dir(base))
212
+ open(java_file(base), 'w') {|io| io.write(java)}
213
+ end
214
+
215
+ def java_dir(base)
216
+ verify
217
+ return "#{base}/#{java_impl_package.gsub(/\./, '/')}"
218
+ end
219
+
220
+ def spin_dir(base)
221
+ verify
222
+ return "#{base}/#{spin_package}"
223
+ end
224
+
225
+ def java_file(base)
226
+ return "#{java_dir(base)}/#{java_impl_class_name}.java"
227
+ end
228
+
229
+ def spin_file(base)
230
+ return "#{spin_dir(base)}/#{spin_prototype.downcase}.spin"
231
+ end
232
+
233
+ def spin_template
234
+ return %q{
235
+ <% if require_type == :manual %>
236
+ bind(<%=spin_prototype%>, Object.new).eval(
237
+ <% for m in java_bindings %>
238
+ # <%=m.spin_doc%>
239
+ bind(<%=m.spin_binding%>, JavaMethod.new("<%=full_class_name%>", <%=m.id%>, <%=m.is_special_form ? 'true' : 'false'%>, <%=m.min_args%>, <%=m.max_args%>))
240
+ <% end %>
241
+ )
242
+ <% end %>
243
+ }.gsub(/^ /, '')
244
+ end
245
+
246
+ def java_template
247
+ return %q{package <%= java_impl_package %>;
248
+
249
+ % for import in java_imports
250
+ import <%= import %>;
251
+ % end
252
+ import com.software4i.spike.util.lang.*;
253
+ import com.software4i.spin.*;
254
+ import com.software4i.spin.object.*;
255
+ import com.software4i.spin.interpreter.*;
256
+ import com.software4i.spin.java.*;
257
+ import com.software4i.spin.util.*;
258
+
259
+ public class <%=java_impl_class_name%> extends AbstractJavaMethodImpl implements IJavaMethodImpl {
260
+ public <%=java_impl_class_name%>() {
261
+ super("<%=java_type%>");
262
+ }
263
+
264
+ public Object applyNative(
265
+ int id,
266
+ ISpinObject targetSpinObject,
267
+ Object target,
268
+ ISpinObject callerSpinObject,
269
+ Object caller,
270
+ IList arguments) {
271
+
272
+ switch (id) {
273
+ <% for m in java_bindings %>
274
+ case <%= m.id %>:
275
+ return <%=m.java_impl_delegate%>(targetSpinObject, target, callerSpinObject, caller, arguments);
276
+ <% end %>
277
+ }
278
+
279
+ return nativeMissing(id);
280
+ }
281
+
282
+ <% if require_type == :auto %>
283
+ // name, specialForm, [MIN/MAX/EXACT], numArgs
284
+ public void createBindings() {
285
+ <% for m in java_bindings %> createBinding(<%=m.id%>, "<%=m.spin_binding%>", <%=m.is_special_form ? 'true' : 'false'%>, <%=m.min_args%>, <%=m.max_args%>);
286
+ <% end %>
287
+ }
288
+ <% end %>
289
+
290
+ <% for m in java_bindings %>
291
+ /**
292
+ * Java implementation for spin binding <%=m.spin_binding%>
293
+ * <%=m.spin_doc%>
294
+ */
295
+ private Object <%=m.java_impl_delegate%>(ISpinObject targetSpinObject,
296
+ Object target, ISpinObject callerSpinObject, Object caller, IList arguments) {
297
+ try {
298
+ <%= m.java_body %>
299
+ } catch(RuntimeException re) {
300
+ throw re;
301
+ } catch(Exception e) {
302
+ throw new BaseRuntimeException("unexpected exception in native method for <%=m.spin_binding%>", e);
303
+ }
304
+ }
305
+ <% end %>
306
+ }
307
+ }.gsub(/^ /, '')
308
+ end
309
+ end
310
+
311
+ class SpinBinding
312
+ attr_reader :java_method, :params, :spin_params, :return_type
313
+
314
+ def initialize(java_method)
315
+ @java_method = java_method
316
+ @params = nil
317
+ @spin_params = nil
318
+ @return_type = 'Object'
319
+ @java_doc = []
320
+ end
321
+
322
+ def spin_binding(spin_method, h=nil)
323
+ @spin_method = spin_method
324
+ @return_type = h[:returns]
325
+ @params = h[:params]
326
+ @spin_params = h[:spin_params]
327
+ end
328
+
329
+ def java_doc(*doc)
330
+ if doc.empty?
331
+ d = "/**\n"
332
+ d << @java_doc.map{|jd| "* #{jd}"}.join("\n") << "\n"
333
+ d << "*/\n"
334
+ return d
335
+ else
336
+ @java_docs += doc
337
+ end
338
+ end
339
+
340
+ def arguments
341
+ @params.map{|p| "#{p[0]} #{p[1]}"}
342
+ end
343
+
344
+ def java_signature
345
+ return "public #{return_type} #{java_method}(#{arguments.join(', ')})"
346
+ end
347
+
348
+ def java_code
349
+ c = ""
350
+ c << "IList arguments = new VectorList();\n"
351
+ c << @spin_params.map{|arg| "arguments.append(#{arg});"}.join("\n") << "\n"
352
+ c << "spinObject.send(spinObject, Symbol.getSymbol(\"#{@spin_method}\"), arguments, spinObject);"
353
+ return c
354
+ end
71
355
  end
72
356
 
73
- class JavaMethodBinding
74
- attr_accessor2 :spin_method, :java_type, :java_method, :java_params, :java_return_type,
75
- :spin_doc, :java_code, :is_special_form
357
+ class JavaBinding
358
+ attr_accessor2 :spin_binding, :spin_params_eval, :java_type, :java_params, :java_return_type,
359
+ :spin_doc, :java_code
76
360
 
77
361
  attr_reader :id
78
362
 
79
- def initialize(spin_method)
363
+ def initialize(spin_binding)
80
364
  @@id ||= -100
81
365
  @id = @@id
82
366
  @@id += -1
83
367
 
84
- @spin_method = spin_method
368
+ @spin_binding = spin_binding
369
+ @spin_params_eval = nil
85
370
  @java_return_type = nil
371
+ @java_params = []
372
+ @java_binding = nil
373
+ @java_node = nil
86
374
  @spin_doc = ''
87
375
  @java_code = ''
88
376
  @is_special_form = false
377
+ @is_static = false
89
378
  @min_args = nil
90
379
  @max_args = nil
91
380
  end
@@ -94,6 +383,10 @@ module Spin
94
383
  @java_return_type.to_s == 'void'
95
384
  end
96
385
 
386
+ def is_special_form
387
+ return !@spin_params_eval.nil?
388
+ end
389
+
97
390
  def java_impl_delegate
98
391
  return "sji_#{id.abs}"
99
392
  end
@@ -105,9 +398,31 @@ module Spin
105
398
  def max_args
106
399
  return @max_args || @java_params.length
107
400
  end
401
+
402
+ def java_binding(name=nil, h=nil)
403
+ return @java_binding if name.nil?
404
+ @java_binding = name
405
+ h ||= {}
406
+ @java_type = h[:type] if h.key?(:type)
407
+ @java_node = h[:node] if h.key?(:node)
408
+ @is_static = h[:static] if h.key?(:static)
409
+ @java_params = h[:params] if h.key?(:params)
410
+ @java_return_type = h[:returns] if h.key?(:returns)
411
+ end
412
+
413
+ def java_method(name=nil, h=nil)
414
+ h ||= {} unless name.nil?
415
+ h[:node] = :method unless h.nil?
416
+ return java_binding(name, h)
417
+ end
108
418
 
419
+ def java_member(name=nil, h=nil)
420
+ h ||= {} unless name.nil?
421
+ h[:node] = :member unless h.nil?
422
+ return java_binding(name, h)
423
+ end
109
424
 
110
- def java_method_call
425
+ def java_arguments
111
426
  arguments = []
112
427
 
113
428
  java_params.each_with_index do |p, i|
@@ -120,15 +435,38 @@ module Spin
120
435
  unbox = h[:unbox]
121
436
  end
122
437
 
123
- arguments << "((#{cast_to}) arguments.elementAt(#{i}))#{unbox}"
438
+ arg = "arguments.elementAt(#{i})"
439
+
440
+
441
+ if not spin_params_eval.nil? and spin_params_eval[i] # defaults to false
442
+ arg = "callerSpinObject.evaluate(#{arg})"
443
+ end
444
+
445
+ arguments << "((#{cast_to}) #{arg})#{unbox}"
124
446
  end
125
447
 
126
- if java_method == :constructor
448
+ return arguments
449
+ end
450
+
451
+ def java_binding_call
452
+ unless @java_node == :member or @java_node == :method
453
+ raise "unknown java_node type: #{@java_node}"
454
+ end
455
+
456
+ if @java_binding == :constructor
127
457
  mc = "new #{java_type}"
128
458
  else
129
- mc = "((#{java_type}) target).#{java_method}"
459
+ if @is_static
460
+ mc = "#{java_type}"
461
+ else
462
+ mc = "((#{java_type}) target)"
463
+ end
464
+ mc << ".#{java_binding}"
465
+ end
466
+
467
+ if @java_node == :method
468
+ mc << "(#{java_arguments.join(', ')})"
130
469
  end
131
- mc << "(#{arguments.join(', ')})"
132
470
 
133
471
  h = JAVA_PRIMITIVES[java_return_type]
134
472
  if h.nil?
@@ -142,10 +480,10 @@ module Spin
142
480
  s = "#{java_code}\n"
143
481
 
144
482
  if void?
145
- s << "#{java_method_call};"
483
+ s << "#{java_binding_call};"
146
484
  s << "return null;"
147
485
  else
148
- s << "return #{java_method_call};"
486
+ s << "return #{java_binding_call};"
149
487
  end
150
488
 
151
489
  return s.gsub(/^/, ' ')
@@ -167,9 +505,9 @@ module Spin
167
505
  end
168
506
 
169
507
  def verify
170
- raise 'spin_method must be set' if spin_method.nil?
508
+ raise 'spin_binding must be set' if spin_binding.nil?
171
509
  raise 'java_type must be set' if java_type.nil?
172
- raise 'java_method must be set' if java_method.nil?
510
+ raise 'java_binding must be set' if java_binding.nil?
173
511
  raise 'id must be set' if id.nil?
174
512
  end
175
513
 
@@ -198,142 +536,5 @@ module Spin
198
536
  java_primitive 'byte', 'Byte', '.byteValue()', 'new Byte(%)'
199
537
 
200
538
  class JavaMethodImpl
201
- attr_accessor :java_impl_class_name, :java_impl_package,
202
- :java_type_name, :spin_package, :spin_prototype_name
203
- attr_reader :methods, :java_imports
204
-
205
- def initialize(prototype)
206
- @methods = []
207
- @java_imports = []
208
-
209
- @java_impl_class_name = "SJI#{prototype.name.capitalize}"
210
-
211
- @java_type_name = prototype.java_type
212
- @spin_package = prototype.package
213
- @spin_prototype_name = prototype.name
214
-
215
- @java_imports.push(*prototype.java_imports)
216
-
217
- prototype.java_bindings.each do |binding|
218
- @methods << binding
219
- end
220
- end
221
-
222
- def verify
223
- raise 'java_impl_class_name' if java_impl_class_name.nil?
224
- raise 'java_impl_package must be set' if java_impl_package.nil?
225
-
226
- raise 'methods cannot be empty' if methods.empty?
227
-
228
- methods.each {|method| method.verify}
229
- end
230
-
231
- def full_class_name
232
- return "#{java_impl_package}.#{java_impl_class_name}"
233
- end
234
-
235
- def spin
236
- verify
237
- rspin = ERB.new(spin_template, 0, '%<>')
238
- return rspin.result(binding)
239
- end
240
-
241
- def java
242
- verify
243
- rjava = ERB.new(java_template, 0, '%<>')
244
- return rjava.result(binding)
245
- end
246
-
247
- def write_spin(base)
248
- FileUtils.mkdir_p(spin_dir(base))
249
-
250
- open(spin_file(base), 'w') {|io| io.write(spin)}
251
- end
252
-
253
- def write_java(base)
254
- FileUtils.mkdir_p(java_dir(base))
255
-
256
- open(java_file(base), 'w') {|io| io.write(java)}
257
- end
258
-
259
- def java_dir(base)
260
- verify
261
- return "#{base}/#{java_impl_package.gsub(/\./, '/')}"
262
- end
263
-
264
- def spin_dir(base)
265
- verify
266
- return "#{base}/#{spin_package}"
267
- end
268
-
269
- def java_file(base)
270
- return "#{java_dir(base)}/#{java_impl_class_name}.java"
271
- end
272
-
273
- def spin_file(base)
274
- return "#{spin_dir(base)}/#{spin_prototype_name.downcase}.spin"
275
- end
276
-
277
- def spin_template
278
- return %q{
279
- % for method in methods
280
- # <%=method.spin_doc%>
281
-
282
- % end
283
- }.gsub(/^ /, '')
284
- end
285
-
286
- def java_template
287
- return %q{package <%= java_impl_package %>;
288
-
289
- % for import in java_imports
290
- import <%= import %>;
291
- % end
292
- import com.software4i.spin.object.ISpinObject;
293
- import com.software4i.spin.interpreter.ISpinObjectManager;
294
- import com.software4i.spin.interpreter.Interpreter;
295
- import com.software4i.spin.java.AbstractJavaMethodImpl;
296
- import com.software4i.spin.java.IJavaMethodImpl;
297
- import com.software4i.spin.util.IList;
298
-
299
- public class <%=java_impl_class_name%> extends AbstractJavaMethodImpl implements IJavaMethodImpl {
300
- public <%=java_impl_class_name%>() {
301
- super("<%=java_type_name%>");
302
- }
303
-
304
- public Object applyNative(
305
- Object target,
306
- int id,
307
- Interpreter interpreter,
308
- Object caller,
309
- IList arguments) {
310
-
311
- ISpinObjectManager manager = interpreter.getSpinObjectManager();
312
- ISpinObject spinObject = manager.spinObjectFor(target);
313
-
314
- switch (id) {
315
- <% for m in methods %>
316
- case <%= m.id %>:
317
- return <%=m.java_impl_delegate%>(interpreter, target, caller, arguments);
318
- <% end %>
319
- }
320
-
321
- return nativeMissing(id);
322
- }
323
-
324
- // name, specialForm, [MIN/MAX/EXACT], numArgs
325
- public void createMethods() {
326
- <% for m in methods %> createMethod(<%=m.id%>, "<%=m.spin_method%>", <%=m.is_special_form ? 'true' : 'false'%>, <%=m.min_args%>, <%=m.max_args%>);
327
- <% end %>
328
- }
329
-
330
- <% for m in methods %>
331
- private Object <%=m.java_impl_delegate%>(Interpreter interpreter, Object target, Object caller, IList arguments) {
332
- <%= m.java_body %>
333
- }
334
- <% end %>
335
- }
336
- }.gsub(/^ /, '')
337
- end
338
539
  end
339
540
  end