mirah 0.0.4-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. data/History.txt +15 -0
  2. data/README.txt +51 -0
  3. data/Rakefile +86 -0
  4. data/bin/duby +10 -0
  5. data/bin/dubyc +10 -0
  6. data/bin/dubyp +10 -0
  7. data/bin/jrubyp +36 -0
  8. data/bin/mirah +9 -0
  9. data/bin/mirah.cmd +1 -0
  10. data/bin/mirahc +9 -0
  11. data/bin/mirahc.cmd +1 -0
  12. data/bin/mirahp +9 -0
  13. data/bin/mirahp.cmd +1 -0
  14. data/examples/ant/example-build.xml +7 -0
  15. data/examples/appengine/Rakefile +19 -0
  16. data/examples/appengine/Readme +29 -0
  17. data/examples/appengine/src/org/mirah/MirahApp.mirah +57 -0
  18. data/examples/appengine/src/org/mirah/list.dhtml +15 -0
  19. data/examples/appengine/war/WEB-INF/lib/dubydatastore.jar +0 -0
  20. data/examples/bintrees.mirah +66 -0
  21. data/examples/construction.mirah +8 -0
  22. data/examples/dynamic.mirah +17 -0
  23. data/examples/edb.mirah +3 -0
  24. data/examples/fib.mirah +16 -0
  25. data/examples/fields.mirah +22 -0
  26. data/examples/fractal.mirah +55 -0
  27. data/examples/java_thing.mirah +13 -0
  28. data/examples/plugins/appengine/Rakefile +55 -0
  29. data/examples/plugins/appengine/lib/com/google/appengine/ext/duby/db/datastore.rb +375 -0
  30. data/examples/plugins/appengine/src/com/google/appengine/ext/duby/db/Model.duby +336 -0
  31. data/examples/plugins/appengine/test/com/google/appengine/ext/duby/db/ModelTest.duby +113 -0
  32. data/examples/simple_class.mirah +12 -0
  33. data/examples/sort_closure.mirah +7 -0
  34. data/examples/swing.mirah +20 -0
  35. data/examples/tak.mirah +15 -0
  36. data/examples/test.edb +9 -0
  37. data/examples/wiki/Rakefile +18 -0
  38. data/examples/wiki/src/org/mirah/wiki/MirahWiki.duby +324 -0
  39. data/examples/wiki/src/org/mirah/wiki/edit.eduby.html +42 -0
  40. data/examples/wiki/src/org/mirah/wiki/error.eduby.html +2 -0
  41. data/examples/wiki/src/org/mirah/wiki/layout.eduby.html +69 -0
  42. data/examples/wiki/src/org/mirah/wiki/parser.eduby.html +7 -0
  43. data/examples/wiki/src/org/mirah/wiki/view.eduby.html +15 -0
  44. data/examples/wiki/war/WEB-INF/classes/test/HeredocContext.class +0 -0
  45. data/examples/wiki/war/WEB-INF/classes/test/MirahParser.class +0 -0
  46. data/examples/wiki/war/WEB-INF/lib/appengine-api.jar +0 -0
  47. data/examples/wiki/war/WEB-INF/lib/dubydatastore.jar +0 -0
  48. data/examples/wiki/war/WEB-INF/lib/jmeta-runtime.jar +0 -0
  49. data/examples/wiki/war/WEB-INF/lib/pegdown-stubs.jar +0 -0
  50. data/examples/wiki/war/WEB-INF/pegdown.jar +0 -0
  51. data/examples/wiki/war/app.yaml +21 -0
  52. data/examples/wiki/war/public/favicon.ico +0 -0
  53. data/examples/wiki/war/public/images/appengine_duby.png +0 -0
  54. data/examples/wiki/war/public/images/back.gif +0 -0
  55. data/examples/wiki/war/public/images/dir.gif +0 -0
  56. data/examples/wiki/war/public/images/file.gif +0 -0
  57. data/examples/wiki/war/public/javascripts/prettify.js +61 -0
  58. data/examples/wiki/war/public/robots.txt +0 -0
  59. data/examples/wiki/war/public/stylesheets/main.css +156 -0
  60. data/examples/wiki/war/public/stylesheets/prettify.css +1 -0
  61. data/examples/wiki/war/public/stylesheets/sh_style.css +66 -0
  62. data/examples/wiki/war/public/stylesheets/source.css +21 -0
  63. data/examples/wiki/war/public/wmd/images/bg-fill.png +0 -0
  64. data/examples/wiki/war/public/wmd/images/bg.png +0 -0
  65. data/examples/wiki/war/public/wmd/images/blockquote.png +0 -0
  66. data/examples/wiki/war/public/wmd/images/bold.png +0 -0
  67. data/examples/wiki/war/public/wmd/images/code.png +0 -0
  68. data/examples/wiki/war/public/wmd/images/h1.png +0 -0
  69. data/examples/wiki/war/public/wmd/images/hr.png +0 -0
  70. data/examples/wiki/war/public/wmd/images/img.png +0 -0
  71. data/examples/wiki/war/public/wmd/images/italic.png +0 -0
  72. data/examples/wiki/war/public/wmd/images/link.png +0 -0
  73. data/examples/wiki/war/public/wmd/images/ol.png +0 -0
  74. data/examples/wiki/war/public/wmd/images/redo.png +0 -0
  75. data/examples/wiki/war/public/wmd/images/separator.png +0 -0
  76. data/examples/wiki/war/public/wmd/images/ul.png +0 -0
  77. data/examples/wiki/war/public/wmd/images/undo.png +0 -0
  78. data/examples/wiki/war/public/wmd/images/wmd-on.png +0 -0
  79. data/examples/wiki/war/public/wmd/images/wmd.png +0 -0
  80. data/examples/wiki/war/public/wmd/showdown.js +421 -0
  81. data/examples/wiki/war/public/wmd/wmd-base.js +1799 -0
  82. data/examples/wiki/war/public/wmd/wmd-plus.js +311 -0
  83. data/examples/wiki/war/public/wmd/wmd.js +73 -0
  84. data/javalib/JRubyParser.jar +0 -0
  85. data/javalib/dynalang-invoke-0.1.jar +0 -0
  86. data/javalib/mirah-bootstrap.jar +0 -0
  87. data/javalib/mirah-parser.jar +0 -0
  88. data/lib/duby.rb +2 -0
  89. data/lib/mirah.rb +338 -0
  90. data/lib/mirah/appengine_tasks.rb +146 -0
  91. data/lib/mirah/ast.rb +615 -0
  92. data/lib/mirah/ast/call.rb +307 -0
  93. data/lib/mirah/ast/class.rb +311 -0
  94. data/lib/mirah/ast/flow.rb +364 -0
  95. data/lib/mirah/ast/intrinsics.rb +470 -0
  96. data/lib/mirah/ast/literal.rb +154 -0
  97. data/lib/mirah/ast/local.rb +89 -0
  98. data/lib/mirah/ast/method.rb +360 -0
  99. data/lib/mirah/ast/scope.rb +208 -0
  100. data/lib/mirah/ast/structure.rb +226 -0
  101. data/lib/mirah/ast/type.rb +130 -0
  102. data/lib/mirah/compiler.rb +341 -0
  103. data/lib/mirah/env.rb +33 -0
  104. data/lib/mirah/jvm/base.rb +258 -0
  105. data/lib/mirah/jvm/compiler.rb +885 -0
  106. data/lib/mirah/jvm/method_lookup.rb +203 -0
  107. data/lib/mirah/jvm/source_compiler.rb +737 -0
  108. data/lib/mirah/jvm/source_generator/builder.rb +444 -0
  109. data/lib/mirah/jvm/source_generator/loops.rb +110 -0
  110. data/lib/mirah/jvm/source_generator/precompile.rb +188 -0
  111. data/lib/mirah/jvm/source_generator/typer.rb +11 -0
  112. data/lib/mirah/jvm/typer.rb +151 -0
  113. data/lib/mirah/jvm/types.rb +416 -0
  114. data/lib/mirah/jvm/types/basic_types.rb +33 -0
  115. data/lib/mirah/jvm/types/boolean.rb +17 -0
  116. data/lib/mirah/jvm/types/enumerable.rb +65 -0
  117. data/lib/mirah/jvm/types/extensions.rb +86 -0
  118. data/lib/mirah/jvm/types/factory.rb +186 -0
  119. data/lib/mirah/jvm/types/floats.rb +86 -0
  120. data/lib/mirah/jvm/types/integers.rb +171 -0
  121. data/lib/mirah/jvm/types/intrinsics.rb +376 -0
  122. data/lib/mirah/jvm/types/literals.rb +74 -0
  123. data/lib/mirah/jvm/types/methods.rb +614 -0
  124. data/lib/mirah/jvm/types/number.rb +143 -0
  125. data/lib/mirah/nbcompiler.rb +29 -0
  126. data/lib/mirah/plugin/edb.rb +29 -0
  127. data/lib/mirah/plugin/gwt.rb +173 -0
  128. data/lib/mirah/plugin/java.rb +55 -0
  129. data/lib/mirah/transform.rb +266 -0
  130. data/lib/mirah/transform2.rb +728 -0
  131. data/lib/mirah/typer.rb +407 -0
  132. data/lib/mirah_task.rb +107 -0
  133. data/test/test_ast.rb +359 -0
  134. data/test/test_compilation.rb +112 -0
  135. data/test/test_env.rb +42 -0
  136. data/test/test_gwt.rb +58 -0
  137. data/test/test_java_typer.rb +183 -0
  138. data/test/test_javac_compiler.rb +63 -0
  139. data/test/test_jvm_compiler.rb +2607 -0
  140. data/test/test_typer.rb +221 -0
  141. metadata +235 -0
@@ -0,0 +1,33 @@
1
+ module Duby::JVM::Types
2
+ Boolean = BooleanType.new('boolean', java.lang.Boolean)
3
+ Byte = IntegerType.new('byte', java.lang.Byte)
4
+ Char = IntegerType.new('char', java.lang.Character)
5
+ Short = IntegerType.new('short', java.lang.Short)
6
+ Int = IntegerType.new('int', java.lang.Integer)
7
+ Long = LongType.new('long', java.lang.Long)
8
+ Float = FloatType.new('float', java.lang.Float)
9
+ Double = DoubleType.new('double', java.lang.Double)
10
+
11
+ # TODO these shouldn't be constants. They should be loaded from
12
+ # the compilation class path.
13
+ Object = Type.new(BiteScript::ASM::ClassMirror.load('java.lang.Object'))
14
+ ClassType = Type.new(BiteScript::ASM::ClassMirror.load('java.lang.Class'))
15
+ String = StringType.new(
16
+ BiteScript::ASM::ClassMirror.load('java.lang.String'))
17
+ Iterable = IterableType.new(
18
+ BiteScript::ASM::ClassMirror.load('java.lang.Iterable'))
19
+
20
+ Void = VoidType.new
21
+ Null = NullType.new
22
+
23
+ WIDENING_CONVERSIONS = {
24
+ Byte => [Byte, Short, Int, Long, Float, Double],
25
+ Short => [Short, Int, Long, Float, Double],
26
+ Char => [Char, Int, Long, Float, Double],
27
+ Int => [Int, Long, Float, Double],
28
+ Long => [Long, Float, Double],
29
+ Float => [Float, Double],
30
+ Double => [Double]
31
+ }
32
+ TYPE_ORDERING = [Byte, Short, Int, Long, Float, Double]
33
+ end
@@ -0,0 +1,17 @@
1
+ module Duby::JVM::Types
2
+ class BooleanType < PrimitiveType
3
+ def init_value(builder)
4
+ builder.iconst_0
5
+ end
6
+
7
+ def prefix
8
+ 'i'
9
+ end
10
+
11
+ def box(builder)
12
+ box_type = Duby::AST::type(nil, 'java.lang.Boolean')
13
+ builder.invokestatic box_type, "valueOf", [box_type, self]
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,65 @@
1
+ module Duby::JVM::Types
2
+ class Type
3
+ def expand_each(transformer, call)
4
+ arg_types = [Duby::AST.block_type]
5
+ code = intrinsics['each'][arg_types].return_type
6
+ code.inline(transformer, call)
7
+ end
8
+
9
+ def add_enumerable_macros
10
+ all_proc = proc do |transformer, call|
11
+ if !call.block
12
+ # We need to create a block that just returns the item passed to it
13
+ # First get a new temp for the block argument
14
+ var = transformer.tmp
15
+ # Parse a fake function call to create a block. Then pull of the
16
+ # block and attach it to the real call.
17
+ call.block = transformer.eval("foo {|#{var}| #{var}}").block
18
+ end
19
+
20
+ # Now that we've got a block we can transform it into a Loop.
21
+ forloop = expand_each(transformer, call)
22
+
23
+ # Start adding stuff to the loop.
24
+ # At the beginning of the loop we create a temp initialized to true
25
+ all = transformer.tmp
26
+ forloop.init << transformer.eval("#{all} = true")
27
+
28
+ # Now we want to wrap the body of the loop. Start off by using
29
+ # foo as a placeholder.
30
+ body = transformer.eval(
31
+ "unless foo;#{all} = false;break;end", '', forloop)
32
+ # Then replace foo with the real body.
33
+ body.condition.predicate = call.block.body
34
+ # And finally patch the new body back into the forloop.
35
+ forloop.body = call.block.body.parent = body
36
+
37
+ # Loops don't have a return value, so we need somewhere to
38
+ # put the result.
39
+ result = Duby::AST::Body.new(call.parent, call.position)
40
+ result << forloop << transformer.eval("#{all}", '', nil, all)
41
+ end
42
+ add_macro('all?', &all_proc)
43
+ add_macro('all?', Duby::AST.block_type, &all_proc)
44
+
45
+ any_proc = proc do |transformer, call|
46
+ if !call.block
47
+ var = transformer.tmp
48
+ call.block = transformer.eval("foo {|#{var}| #{var}}").block
49
+ end
50
+ forloop = expand_each(transformer, call)
51
+ any = transformer.tmp
52
+ forloop.init << transformer.eval("#{any} = false")
53
+ body = transformer.eval(
54
+ "if foo;#{any} = true;break;end", '', forloop)
55
+ body.condition.predicate = call.block.body
56
+ forloop.body = call.block.body.parent = body
57
+
58
+ result = Duby::AST::Body.new(call.parent, call.position)
59
+ result << forloop << transformer.eval("#{any}", '', nil, any)
60
+ end
61
+ add_macro('any?', &any_proc)
62
+ add_macro('any?', Duby::AST.block_type, &any_proc)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,86 @@
1
+ require 'delegate'
2
+
3
+ module Duby::JVM::Types
4
+ class ExtendedType < DelegateClass(Type)
5
+ def initialize(*args)
6
+ super
7
+ @static_includes = []
8
+ end
9
+
10
+ def include(type)
11
+ @static_includes << type
12
+ self
13
+ end
14
+
15
+ def meta
16
+ if meta?
17
+ self
18
+ else
19
+ __getobj__.meta
20
+ end
21
+ end
22
+
23
+ def unmeta
24
+ if meta?
25
+ __getobj__.unmeta
26
+ else
27
+ self
28
+ end
29
+ end
30
+
31
+ def get_method(name, args)
32
+ method = __getobj__.get_method(name, args)
33
+ return method if method
34
+ @static_includes.each do |type|
35
+ method = type.meta.get_method(name, args)
36
+ return method if method
37
+ end
38
+ nil
39
+ end
40
+
41
+ def java_method(name, *types)
42
+ __getobj__.java_method(name, *types) || __included_method(name, types)
43
+ end
44
+
45
+ def java_static_method(name, *types)
46
+ __getobj__.java_static_method(name, *types) || __included_method(name, types)
47
+ end
48
+
49
+ def declared_instance_methods(name=nil)
50
+ __combine_methods(__getobj__.declared_instance_methods)
51
+ end
52
+
53
+ def declared_class_methods(name=nil)
54
+ __combine_methods(__getobj__.declared_class_methods)
55
+ end
56
+
57
+ def __combine_methods(basic_methods)
58
+ methods = {}
59
+ basic_methods.each do |method|
60
+ key = [method.name, method.parameter_types, method.return_type]
61
+ methods[key] = method
62
+ end
63
+ @static_includes.each do |type|
64
+ type.declared_class_methods.each do |method|
65
+ key = [method.name, method.parameter_types, method.return_type]
66
+ methods[key] ||= method
67
+ end
68
+ end
69
+ methods.values
70
+ end
71
+
72
+ def __included_method(name, types)
73
+ @static_includes.each do |type|
74
+ method = type.meta.java_method(name, *types)
75
+ return method if method
76
+ end
77
+ nil
78
+ end
79
+ end
80
+
81
+ class Type
82
+ def include(type)
83
+ ExtendedType.new(self).include(type)
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,186 @@
1
+ require 'jruby'
2
+ module Duby::JVM::Types
3
+ class TypeFactory
4
+ BASIC_TYPES = {
5
+ "boolean" => Boolean,
6
+ "byte" => Byte,
7
+ "char" => Char,
8
+ "short" => Short,
9
+ "int" => Int,
10
+ "long" => Long,
11
+ "float" => Float,
12
+ "double" => Double,
13
+ "fixnum" => Int,
14
+ "string" => String,
15
+ "java.lang.String" => String,
16
+ "String" => String,
17
+ "java.lang.Object" => Object,
18
+ "Object" => Object,
19
+ "java.lang.Class" => ClassType,
20
+ "java.lang.Iterable" => Iterable,
21
+ "Iterable" => Iterable,
22
+ "void" => Void,
23
+ "notype" => Void,
24
+ "null" => Null,
25
+ "dynamic" => DynamicType.new
26
+ }.freeze
27
+
28
+ attr_accessor :package
29
+ attr_reader :known_types
30
+
31
+ class ParanoidHash < Hash
32
+ def []=(k, v)
33
+ raise ArgumentError, "Can't store nil for key #{k.inspect}" if v.nil?
34
+ super(k, v)
35
+ end
36
+ end
37
+
38
+ def initialize
39
+ @known_types = ParanoidHash.new
40
+ @known_types.update(BASIC_TYPES)
41
+ @declarations = []
42
+ @mirrors = {}
43
+ end
44
+
45
+ def initialize_copy(other)
46
+ @known_types = other.known_types.dup
47
+ @known_types.delete_if do |key, value|
48
+ value.basic_type.kind_of?(Duby::JVM::Types::TypeDefinition)
49
+ end
50
+ @declarations = []
51
+ end
52
+
53
+ def define_types(builder)
54
+ @declarations.each do |declaration|
55
+ declaration.define(builder)
56
+ end
57
+ end
58
+
59
+ def type(scope, name, array=false, meta=false)
60
+ if name.kind_of?(BiteScript::ASM::Type)
61
+ if name.getDescriptor[0] == ?[
62
+ return type(scope, name.getElementType, true, meta)
63
+ else
64
+ name = name.getClassName
65
+ end
66
+ end
67
+ type = basic_type(scope, name)
68
+ type = type.array_type if array
69
+ type = type.meta if meta
70
+ return type
71
+ end
72
+
73
+ def basic_type(scope, name)
74
+ if name.kind_of?(Type) || name.kind_of?(NarrowingType)
75
+ return name.basic_type
76
+ end
77
+ orig = name
78
+ if name.kind_of? Java::JavaClass
79
+ if name.array?
80
+ return type(name.component_type, true)
81
+ else
82
+ name = name.name
83
+ end
84
+ elsif name.respond_to? :java_class
85
+ name = name.java_class.name
86
+ end
87
+ name = name.to_s unless name.kind_of?(::String)
88
+ raise ArgumentError, "Bad Type #{orig}" if name =~ /Java::/
89
+ raise ArgumentError, "Bad Type #{orig.inspect}" if name == '' || name.nil?
90
+ find_type(scope, name)
91
+ end
92
+
93
+ def find_type(scope, name)
94
+ begin
95
+ return get_type(name)
96
+ rescue NameError => ex
97
+ raise ex if scope.nil?
98
+ end
99
+
100
+ imports = scope.static_scope.imports
101
+ if imports.include?(name)
102
+ name = imports[name] while imports.include?(name)
103
+ return get_type(name)
104
+ end
105
+
106
+ # TODO support inner class names
107
+ if name !~ /\./
108
+ return package_search(name, scope)
109
+ end
110
+ end
111
+
112
+ def package_search(name, scope)
113
+ packages = []
114
+ packages << scope.static_scope.package unless scope.static_scope.package.empty?
115
+ packages.concat(scope.static_scope.search_packages)
116
+ packages << 'java.lang'
117
+ packages.each do |package|
118
+ begin
119
+ return get_type("#{package}.#{name}")
120
+ rescue
121
+ end
122
+ end
123
+ raise NameError, "Cannot find class #{name}"
124
+ end
125
+
126
+ def get_type(full_name)
127
+ type = @known_types[full_name]
128
+ return type.basic_type if type
129
+ type = Type.new(get_mirror(full_name)).load_extensions
130
+ @known_types[full_name] = type
131
+ end
132
+
133
+ def known_type(scope, name)
134
+ basic_type(scope, name) rescue nil
135
+ end
136
+
137
+ def declare_type(scope, name)
138
+ full_name = name
139
+ package = scope.static_scope.package
140
+ if !name.include?('.') && !package.empty?
141
+ full_name = "#{package}.#{name}"
142
+ end
143
+ if @known_types.include? full_name
144
+ @known_types[full_name]
145
+ else
146
+ scope.static_scope.import(full_name, name)
147
+ @known_types[full_name] = TypeDefinition.new(full_name, nil)
148
+ end
149
+ end
150
+
151
+ def define_type(node)
152
+ name = node.name
153
+ full_name = name
154
+ package = node.static_scope.package
155
+ if !name.include?('.') && !package.empty?
156
+ full_name = "#{package}.#{name}"
157
+ end
158
+ if @known_types.include? full_name
159
+ existing = @known_types[full_name]
160
+ existing.node ||= node
161
+ existing
162
+ else
163
+ if Duby::AST::InterfaceDeclaration === node
164
+ klass = InterfaceDefinition
165
+ else
166
+ klass = TypeDefinition
167
+ end
168
+ node.scope.static_scope.import(full_name, name)
169
+ @known_types[full_name] = klass.new(full_name, node)
170
+ end
171
+ end
172
+
173
+ def no_type
174
+ Void
175
+ end
176
+
177
+ def get_mirror(name)
178
+ @mirrors[name] ||= begin
179
+ classname = name.tr('.', '/') + ".class"
180
+ stream = JRuby.runtime.jruby_class_loader.getResourceAsStream(classname)
181
+ raise NameError, "Class '#{name}' not found." unless stream
182
+ BiteScript::ASM::ClassMirror.load(stream)
183
+ end
184
+ end
185
+ end
186
+ end
@@ -0,0 +1,86 @@
1
+ module Duby::JVM::Types
2
+ class FloatType < Number
3
+ def prefix
4
+ 'f'
5
+ end
6
+
7
+ def math_type
8
+ Float
9
+ end
10
+
11
+ def box_type
12
+ java.lang.Float
13
+ end
14
+
15
+ def suffix
16
+ 'g'
17
+ end
18
+
19
+ def init_value(builder)
20
+ builder.fconst_0
21
+ end
22
+
23
+ def literal(builder, value)
24
+ case value
25
+ when 0.0
26
+ builder.fconst_0
27
+ when 1.0
28
+ builder.fconst_1
29
+ when 2.0
30
+ builder.fconst_2
31
+ else
32
+ builder.ldc_float(value)
33
+ end
34
+ end
35
+
36
+ def widen(builder, type)
37
+ case type
38
+ when Float
39
+ # Do nothing
40
+ when Double
41
+ builder.f2d
42
+ else
43
+ raise ArgumentError, "Invalid widening conversion from float to #{type}"
44
+ end
45
+ end
46
+ end
47
+
48
+ class DoubleType < FloatType
49
+ def prefix
50
+ 'd'
51
+ end
52
+
53
+ def math_type
54
+ Double
55
+ end
56
+
57
+ def box_type
58
+ java.lang.Double
59
+ end
60
+
61
+ def wide?
62
+ true
63
+ end
64
+
65
+ def init_value(builder)
66
+ builder.dconst_0
67
+ end
68
+
69
+ def literal(builder, value)
70
+ case value
71
+ when 0.0
72
+ builder.dconst_0
73
+ when 1.0
74
+ builder.dconst_1
75
+ else
76
+ builder.ldc_double(value)
77
+ end
78
+ end
79
+
80
+ def widen(builder, type)
81
+ if type != Double
82
+ raise ArgumentError, "Invalid widening conversion from double to #{type}"
83
+ end
84
+ end
85
+ end
86
+ end