mirah 0.0.5-java → 0.0.6-java

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 (63) hide show
  1. data/History.txt +33 -0
  2. data/README.txt +2 -3
  3. data/Rakefile +5 -0
  4. data/bin/duby +0 -0
  5. data/bin/dubyc +0 -0
  6. data/bin/dubyp +0 -0
  7. data/bin/jrubyp +0 -0
  8. data/bin/mirah +0 -0
  9. data/bin/mirah.cmd +14 -14
  10. data/bin/mirahc +0 -0
  11. data/bin/mirahc.cmd +14 -14
  12. data/bin/mirahp +0 -0
  13. data/bin/mirahp.cmd +14 -14
  14. data/examples/Dynamic.class +0 -0
  15. data/examples/SizeThing.class +0 -0
  16. data/examples/plugins/appengine/Rakefile +3 -1
  17. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/MetaModel.mirah +385 -0
  18. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +58 -15
  19. data/examples/wiki/war/public/javascripts/prettify.js +0 -0
  20. data/examples/wiki/war/public/stylesheets/prettify.css +0 -0
  21. data/javalib/dynalink-0.1.jar +0 -0
  22. data/javalib/jsr292-mock.jar +0 -0
  23. data/javalib/mirah-bootstrap.jar +0 -0
  24. data/javalib/mirah-parser.jar +0 -0
  25. data/lib/mirah.rb +45 -25
  26. data/lib/mirah/ast.rb +81 -27
  27. data/lib/mirah/ast/call.rb +62 -71
  28. data/lib/mirah/ast/class.rb +23 -26
  29. data/lib/mirah/ast/flow.rb +38 -62
  30. data/lib/mirah/ast/intrinsics.rb +59 -37
  31. data/lib/mirah/ast/literal.rb +16 -14
  32. data/lib/mirah/ast/local.rb +8 -8
  33. data/lib/mirah/ast/method.rb +33 -19
  34. data/lib/mirah/ast/structure.rb +54 -13
  35. data/lib/mirah/ast/type.rb +8 -11
  36. data/lib/mirah/compiler.rb +86 -0
  37. data/lib/mirah/errors.rb +60 -0
  38. data/lib/mirah/jvm/base.rb +5 -11
  39. data/lib/mirah/jvm/compiler.rb +12 -1
  40. data/lib/mirah/jvm/source_compiler.rb +10 -2
  41. data/lib/mirah/jvm/source_generator/builder.rb +3 -1
  42. data/lib/mirah/jvm/source_generator/precompile.rb +6 -0
  43. data/lib/mirah/jvm/typer.rb +6 -1
  44. data/lib/mirah/jvm/types.rb +8 -0
  45. data/lib/mirah/jvm/types/factory.rb +34 -10
  46. data/lib/mirah/jvm/types/intrinsics.rb +12 -5
  47. data/lib/mirah/jvm/types/methods.rb +5 -9
  48. data/lib/mirah/plugin/gwt.rb +3 -2
  49. data/lib/mirah/transform.rb +68 -10
  50. data/lib/mirah/transform2.rb +10 -1
  51. data/lib/mirah/typer.rb +5 -10
  52. data/lib/mirah/version.rb +1 -1
  53. data/test/test_compilation.rb +1 -1
  54. data/test/test_java_typer.rb +10 -0
  55. data/test/test_javac_compiler.rb +4 -2
  56. data/test/test_jvm_compiler.rb +132 -9
  57. data/test/test_macros.rb +51 -0
  58. data/test/test_typer.rb +29 -25
  59. metadata +13 -21
  60. data/examples/plugins/appengine/lib/com/google/appengine/ext/duby/db/datastore.rb +0 -390
  61. data/javalib/JRubyParser.jar +0 -0
  62. data/javalib/dynalang-invoke-0.1.jar +0 -0
  63. data/lib/mirah/nbcompiler.rb +0 -44
@@ -15,19 +15,29 @@
15
15
 
16
16
  import java.util.ConcurrentModificationException
17
17
 
18
+ import com.google.appengine.api.datastore.Blob
19
+ import com.google.appengine.api.datastore.Category
18
20
  import com.google.appengine.api.datastore.DatastoreServiceFactory
21
+ import com.google.appengine.api.datastore.Email
19
22
  import com.google.appengine.api.datastore.Entity
20
23
  import com.google.appengine.api.datastore.EntityNotFoundException
24
+ import com.google.appengine.api.datastore.FetchOptions.Builder
25
+ import com.google.appengine.api.datastore.GeoPt
26
+ import com.google.appengine.api.datastore.IMHandle
21
27
  import com.google.appengine.api.datastore.Key
22
28
  import com.google.appengine.api.datastore.KeyFactory
29
+ import com.google.appengine.api.datastore.Link
30
+ import com.google.appengine.api.datastore.PhoneNumber
31
+ import com.google.appengine.api.datastore.PostalAddress
23
32
  import com.google.appengine.api.datastore.Query
24
- import 'Builder', 'com.google.appengine.api.datastore.FetchOptions$Builder'
25
- import 'FilterOperator', 'com.google.appengine.api.datastore.Query$FilterOperator'
26
- import 'SortDirection', 'com.google.appengine.api.datastore.Query$SortDirection'
27
- import com.google.appengine.api.datastore.GeoPt
28
- import com.google.appengine.api.datastore.IMHandle
33
+ import com.google.appengine.api.datastore.Query.FilterOperator
34
+ import com.google.appengine.api.datastore.Query.SortDirection
35
+ import com.google.appengine.api.datastore.Rating
36
+ import com.google.appengine.api.datastore.ShortBlob
37
+ import com.google.appengine.api.datastore.Text
29
38
  import com.google.appengine.api.users.User
30
39
 
40
+ import duby.lang.compiler.StringNode
31
41
  import java.util.Arrays
32
42
  import java.util.Date
33
43
  import java.util.HashMap
@@ -98,16 +108,8 @@ class DQuery
98
108
  end
99
109
 
100
110
  class Model
101
- defmacro property(name, type) do
102
- # This is a hack to make packaging possible.
103
- # Everything's still written in ruby, but we load it out of
104
- # the datastore plugin's JAR. So as long as Model is in your CLASSPATH
105
- # you don't need any extra arguments to dubyc.
106
- code = <<RUBY
107
- require 'com/google/appengine/ext/duby/db/datastore.rb'
108
- AppEngine::DubyDatastorePlugin.add_property(*arg.to_a)
109
- RUBY
110
- @mirah.__ruby_eval(code, [name, type, @mirah, @call])
111
+ macro def property(name, type)
112
+ DubyDatastorePlugin.get(@mirah).add_property(name, type, @call)
111
113
  end
112
114
 
113
115
  def initialize; end
@@ -319,6 +321,47 @@ RUBY
319
321
 
320
322
  # TODO coerce arrays to lists?
321
323
 
324
+ macro def simple_loader(type_node)
325
+ type = type_node.string_value
326
+ name = "load_#{type.toLowerCase}"
327
+ quote do
328
+ def `name`(value:Object) #`
329
+ `@mirah.cast(type, 'value')`
330
+ end
331
+ end
332
+ end
333
+
334
+ macro def converting_loader(from_node, converter)
335
+ from = from_node.string_value
336
+ name = "load_#{from.toLowerCase}"
337
+ quote do
338
+ def `name`(value:Object) #`
339
+ result = `@mirah.cast(from, 'value')`.`converter` if value
340
+ result
341
+ end
342
+ end
343
+ end
344
+
345
+ simple_loader('Date')
346
+ simple_loader('GeoPt')
347
+ simple_loader('IMHandle')
348
+ simple_loader('Key')
349
+ simple_loader('List')
350
+ simple_loader('String')
351
+ simple_loader('User')
352
+ converting_loader('Category', 'getCategory')
353
+ converting_loader('Email', 'getEmail')
354
+ converting_loader('Link', 'getValue')
355
+ converting_loader('PhoneNumber', 'getNumber')
356
+ converting_loader('PostalAddress', 'getAddress')
357
+ converting_loader('Text', 'getValue')
358
+ converting_loader('Blob', 'getBytes')
359
+ converting_loader('ShortBlob', 'getBytes')
360
+ converting_loader('Long', 'longValue')
361
+ converting_loader('Double', 'doubleValue')
362
+ converting_loader('Boolean', 'booleanValue')
363
+ converting_loader('Rating', 'getRating')
364
+
322
365
  def before_save; end
323
366
 
324
367
  def self.transaction(block:Runnable):void
File without changes
File without changes
Binary file
Binary file
Binary file
Binary file
data/lib/mirah.rb CHANGED
@@ -21,6 +21,7 @@ require 'mirah/ast'
21
21
  require 'mirah/typer'
22
22
  require 'mirah/compiler'
23
23
  require 'mirah/env'
24
+ require 'mirah/errors'
24
25
  begin
25
26
  require 'bitescript'
26
27
  rescue LoadError
@@ -54,6 +55,10 @@ module Mirah
54
55
  end
55
56
 
56
57
  def self.print_error(message, position)
58
+ if position.nil?
59
+ puts message
60
+ return
61
+ end
57
62
  puts "#{position.file}:#{position.start_line}: #{message}"
58
63
  file_offset = 0
59
64
  startline = position.start_line - 1
@@ -84,11 +89,14 @@ module Mirah
84
89
  class CompilationState
85
90
  def initialize
86
91
  BiteScript.bytecode_version = BiteScript::JAVA1_5
92
+ @save_extensions = true
87
93
  end
88
-
94
+
89
95
  attr_accessor :verbose, :destination
90
96
  attr_accessor :version_printed
91
-
97
+ attr_accessor :help_printed
98
+ attr_accessor :save_extensions
99
+
92
100
  def set_jvm_version(ver_str)
93
101
  case ver_str
94
102
  when '1.4'
@@ -114,7 +122,7 @@ class MirahClassLoader < java::security::SecureClassLoader
114
122
  super(parent)
115
123
  @class_map = class_map
116
124
  end
117
-
125
+
118
126
  def findClass(name)
119
127
  if @class_map[name]
120
128
  bytes = @class_map[name].to_java_bytes
@@ -173,8 +181,14 @@ class MirahImpl
173
181
  raise e
174
182
  end
175
183
  else
176
- puts "No main found" unless @state.version_printed
184
+ puts "No main found" unless @state.version_printed || @state.help_printed
177
185
  end
186
+ rescue Mirah::InternalCompilerError => ice
187
+ Mirah.print_error(ice.message, ice.position) if ice.node
188
+ raise ice
189
+ rescue Mirah::MirahError => ex
190
+ Mirah.print_error(ex.message, ex.position)
191
+ puts ex.backtrace if @state.verbose
178
192
  end
179
193
 
180
194
  def compile(*args)
@@ -184,6 +198,13 @@ class MirahImpl
184
198
  bytes = builder.generate
185
199
  File.open(filename, 'wb') {|f| f.write(bytes)}
186
200
  end
201
+ rescue Mirah::InternalCompilerError => ice
202
+ Mirah.print_error(ice.message, ice.position) if ice.position
203
+ puts "error on #{ice.node}(#{ice.node.object_id})"
204
+ raise ice
205
+ rescue Mirah::MirahError => ex
206
+ Mirah.print_error(ex.message, ex.position)
207
+ puts ex.backtrace if @state.verbose
187
208
  end
188
209
 
189
210
  def generate(args, &block)
@@ -245,11 +266,17 @@ class MirahImpl
245
266
  @error = @transformer.errors.size > 0
246
267
 
247
268
  ast
269
+ rescue Mirah::InternalCompilerError => ice
270
+ Mirah.print_error(ice.message, ice.position) if ice.node
271
+ raise ice
272
+ rescue Mirah::MirahError => ex
273
+ Mirah.print_error(ex.message, ex.position)
274
+ puts ex.backtrace if @state.verbose
248
275
  end
249
276
 
250
277
  def infer_asts(asts)
251
278
  typer = Mirah::Typer::JVM.new(@transformer)
252
- asts.each {|ast| typer.infer(ast) }
279
+ asts.each {|ast| typer.infer(ast, true) }
253
280
  begin
254
281
  typer.resolve(false)
255
282
  ensure
@@ -260,7 +287,7 @@ class MirahImpl
260
287
  puts "Inference Error:"
261
288
  typer.errors.each do |ex|
262
289
  if ex.node
263
- Mirah.print_error(ex.message, ex.node.position)
290
+ Mirah.print_error(ex.message, ex.position)
264
291
  else
265
292
  puts ex.message
266
293
  end
@@ -272,20 +299,9 @@ class MirahImpl
272
299
  end
273
300
 
274
301
  def compile_ast(ast, &block)
275
- begin
276
- compiler = @compiler_class.new
277
- ast.compile(compiler, false)
278
- compiler.generate(&block)
279
- rescue Exception => ex
280
- if ex.respond_to? :node
281
- Mirah.print_error(ex.message, ex.node.position)
282
- puts ex.backtrace if @state.verbose
283
- exit 1
284
- else
285
- raise ex
286
- end
287
- end
288
-
302
+ compiler = @compiler_class.new
303
+ ast.compile(compiler, false)
304
+ compiler.generate(&block)
289
305
  end
290
306
 
291
307
  def process_flags!(args)
@@ -308,7 +324,7 @@ class MirahImpl
308
324
  Mirah::AST::Script.explicit_packages = true
309
325
  when '--help', '-h'
310
326
  print_help
311
- exit(0)
327
+ args.clear
312
328
  when '--java', '-j'
313
329
  require 'mirah/jvm/source_compiler'
314
330
  @compiler_class = Mirah::Compiler::JavaSource
@@ -332,10 +348,13 @@ class MirahImpl
332
348
  when '--version', '-v'
333
349
  args.shift
334
350
  print_version
351
+ when '--no-save-extensions'
352
+ args.shift
353
+ @state.save_extensions = false
335
354
  else
336
355
  puts "unrecognized flag: " + args[0]
337
356
  print_help
338
- exit(1)
357
+ args.clear
339
358
  end
340
359
  end
341
360
  @state.destination ||= File.join(File.expand_path('.'), '')
@@ -343,7 +362,7 @@ class MirahImpl
343
362
  end
344
363
 
345
364
  def print_help
346
- puts "#{$0} [flags] <files or \"-e SCRIPT\">
365
+ puts "#{$0} [flags] <files or -e SCRIPT>
347
366
  -c, --classpath PATH\tAdd PATH to the Java classpath for compilation
348
367
  --cd DIR\t\tSwitch to the specified DIR befor compilation
349
368
  -d, --dir DIR\t\tUse DIR as the base dir for compilation, packages
@@ -352,14 +371,15 @@ class MirahImpl
352
371
  --explicit-packages\tRequire explicit 'package' lines in source
353
372
  -h, --help\t\tPrint this help message
354
373
  -I DIR\t\tAdd DIR to the Ruby load path before running
355
- -j, --java\t\tOutput .java source (jrubyc only)
374
+ -j, --java\t\tOutput .java source (compile mode only)
356
375
  --jvm VERSION\t\tEmit JVM bytecode targeting specified JVM
357
376
  \t\t\t version (1.4, 1.5, 1.6, 1.7)
358
377
  -p, --plugin PLUGIN\trequire 'mirah/plugin/PLUGIN' before running
359
378
  -v, --version\t\tPrint the version of Mirah to the console
360
379
  -V, --verbose\t\tVerbose logging"
380
+ @state.help_printed = true
361
381
  end
362
-
382
+
363
383
  def print_version
364
384
  puts "Mirah v#{Mirah::VERSION}"
365
385
  @state.version_printed = true
data/lib/mirah/ast.rb CHANGED
@@ -13,6 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ require 'delegate'
16
17
  require 'mirah/transform'
17
18
  require 'mirah/ast/scope'
18
19
 
@@ -79,20 +80,23 @@ module Mirah
79
80
  end
80
81
 
81
82
  def _dump(depth)
82
- to_skip = %w(@parent @newline @inferred_type @resolved @proxy @scope @class_scope @typer)
83
+ to_skip = %w(@parent @newline @inferred_type @resolved @proxy @scope @class_scope @static_scope @typer)
83
84
  vars = {}
84
85
  instance_variables.each do |name|
85
86
  next if to_skip.include?(name)
86
87
  vars[name] = instance_variable_get(name)
87
88
  begin
88
- Marshal.dump(vars[name]) if AST.verbose
89
+ Mirah::AST::Unquote.extract_values do
90
+ Marshal.dump(vars[name]) if AST.verbose
91
+ end
89
92
  rescue
90
93
  puts "#{self}: Failed to marshal #{name}"
94
+ puts inspect
91
95
  puts $!, $@
92
96
  raise $!
93
97
  end
94
98
  end
95
- Marshal.dump(vars)
99
+ Marshal.dump(vars)
96
100
  end
97
101
 
98
102
  def self._load(vars)
@@ -156,13 +160,17 @@ module Mirah
156
160
  end
157
161
  str << "\n#{ary_child.inspect(indent + extra_indent + 1)}"
158
162
  }
159
- elsif ::Hash === child
163
+ elsif ::Hash === child || ::String === child
160
164
  str << "\n#{indent_str} #{child.inspect}"
161
165
  else
162
166
  if Mirah::AST.verbose && Node === child && child.parent != self
163
167
  str << "\n#{indent_str} (wrong parent)"
164
168
  end
165
- str << "\n#{child.inspect(indent + extra_indent + 1)}"
169
+ begin
170
+ str << "\n#{child.inspect(indent + extra_indent + 1)}"
171
+ rescue ArgumentError => ex
172
+ str << "\n#{indent_str} #{child.inspect}"
173
+ end
166
174
  end
167
175
  end
168
176
  end
@@ -180,6 +188,10 @@ module Mirah
180
188
 
181
189
  def to_s; simple_name; end
182
190
 
191
+ def string_value
192
+ raise Mirah::SyntaxError.new("Can't use #{self.class} as string literal")
193
+ end
194
+
183
195
  def [](index) children[index] end
184
196
 
185
197
  def []=(index, node)
@@ -233,6 +245,11 @@ module Mirah
233
245
  end
234
246
 
235
247
  def initialize_copy(other)
248
+ # bug: node is deferred, but it's parent isn't
249
+ # parent gets duped
250
+ # duped parent is inferred so it's children aren't
251
+ # original node gets inferred, but not the duplicate child
252
+ @inferred_type = @resolved = nil
236
253
  @parent = nil
237
254
  @children = []
238
255
  other.children.each do |child|
@@ -249,7 +266,7 @@ module Mirah
249
266
 
250
267
  def inferred_type!
251
268
  unless @inferred_type
252
- raise Mirah::Typer::InferenceError.new(
269
+ raise Mirah::InternalCompilerError.new(
253
270
  "Internal Error: #{self.class} never inferred", self)
254
271
  end
255
272
  inferred_type
@@ -265,17 +282,28 @@ module Mirah
265
282
  @resolved = true
266
283
  end
267
284
 
268
- def infer(typer)
285
+ def infer(typer, expression)
269
286
  end
270
287
  end
271
288
 
272
289
  module Named
273
- attr_accessor :name
290
+ attr_reader :name
291
+
292
+ def name=(name)
293
+ if Node === name
294
+ name.parent = self
295
+ end
296
+ @name = name
297
+ end
274
298
 
275
299
  def to_s
276
300
  "#{super}(#{name})"
277
301
  end
278
302
 
303
+ def string_value
304
+ name
305
+ end
306
+
279
307
  def validate_name
280
308
  if UnquotedValue === @name
281
309
  @name = @name.name
@@ -299,6 +327,10 @@ module Mirah
299
327
  def to_s
300
328
  "#{super}(#{literal.inspect})"
301
329
  end
330
+
331
+ def string_value
332
+ literal.to_s
333
+ end
302
334
  end
303
335
 
304
336
  module Annotated
@@ -324,43 +356,31 @@ module Mirah
324
356
  end
325
357
  end
326
358
 
327
- class Colon2 < Node; end
328
-
329
359
  class Constant < Node
330
360
  include Named
331
361
  include Scoped
332
362
  attr_accessor :array
333
363
 
334
364
  def initialize(parent, position, name)
335
- @name = name
365
+ self.name = name
336
366
  super(parent, position, [])
337
367
  end
338
368
 
339
- def infer(typer)
369
+ def infer(typer, expression)
340
370
  @inferred_type ||= begin
341
371
  # TODO lookup constant, inline if we're supposed to.
342
- begin
343
- typer.type_reference(scope, name, @array, true)
344
- rescue NameError => ex
345
- typer.known_types[@name] = Mirah::AST.error_type
346
- raise ex
347
- end
372
+ typer.type_reference(scope, name, @array, true)
348
373
  end
349
374
  end
350
375
 
351
376
  def type_reference(typer)
352
- begin
353
- typer.type_reference(scope, @name, @array)
354
- rescue NameError => ex
355
- typer.known_types[@name] = Mirah::AST.error_type
356
- raise ex
357
- end
377
+ typer.type_reference(scope, @name, @array)
358
378
  end
359
379
  end
360
380
 
361
381
  class Self < Node
362
382
  include Scoped
363
- def infer(typer)
383
+ def infer(typer, expression)
364
384
  @inferred_type ||= scope.static_scope.self_type
365
385
  end
366
386
  end
@@ -400,7 +420,7 @@ module Mirah
400
420
  @values[name]
401
421
  end
402
422
 
403
- def infer(typer)
423
+ def infer(typer, expression)
404
424
  @inferred ||= begin
405
425
  @name = name_node.type_reference(typer).name if name_node
406
426
  @values.each do |name, value|
@@ -427,6 +447,40 @@ module Mirah
427
447
  end
428
448
  end
429
449
 
450
+ class NodeProxy < DelegateClass(Node)
451
+ include Java::DubyLangCompiler::Node
452
+ def __inline__(node)
453
+ node.parent = parent
454
+ __setobj__(node)
455
+ end
456
+
457
+ def dup
458
+ value = __getobj__.dup
459
+ if value.respond_to?(:proxy=)
460
+ new = super
461
+ new.__setobj__(value)
462
+ new.proxy = new
463
+ new
464
+ else
465
+ value
466
+ end
467
+ end
468
+
469
+ def _dump(depth)
470
+ Marshal.dump(__getobj__)
471
+ end
472
+
473
+ def self._load(str)
474
+ value = Marshal.load(str)
475
+ if value.respond_to?(:proxy=)
476
+ proxy = NodeProxy.new(value)
477
+ proxy.proxy = proxy
478
+ else
479
+ value
480
+ end
481
+ end
482
+ end
483
+
430
484
  class TypeReference < Node
431
485
  include Named
432
486
  attr_accessor :array
@@ -436,7 +490,7 @@ module Mirah
436
490
 
437
491
  def initialize(name, array = false, meta = false, position=nil)
438
492
  super(nil, position)
439
- @name = name
493
+ self.name = name
440
494
  @array = array
441
495
  @meta = meta
442
496
  end