mirah 0.0.7-java → 0.0.8-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 (182) hide show
  1. data/History.txt +181 -0
  2. data/README.txt +6 -10
  3. data/Rakefile +86 -9
  4. data/bin/mirah +2 -0
  5. data/bin/mirahc +2 -0
  6. data/bin/mirahp +2 -0
  7. data/{bin/dubyp → examples/interfaces.mirah} +16 -9
  8. data/examples/macros/square.mirah +12 -0
  9. data/examples/macros/square_int.mirah +12 -0
  10. data/examples/macros/string-each-char.mirah +14 -0
  11. data/examples/maven/README.txt +2 -0
  12. data/examples/maven/pom.xml +23 -0
  13. data/examples/maven/src/main/mirah/hello_mirah.mirah +9 -0
  14. data/examples/rosettacode/100-doors.mirah +44 -0
  15. data/examples/rosettacode/99-bottles-of-beer.mirah +13 -0
  16. data/examples/rosettacode/README.txt +9 -0
  17. data/examples/rosettacode/boolean-values.mirah +29 -0
  18. data/examples/rosettacode/comments.mirah +2 -0
  19. data/examples/rosettacode/copy-a-string.mirah +10 -0
  20. data/examples/rosettacode/count-occurrences-of-a-substring.mirah +40 -0
  21. data/examples/rosettacode/create-a-file.mirah +6 -0
  22. data/examples/rosettacode/empty-string.mirah +9 -0
  23. data/examples/rosettacode/factorial.mirah +10 -0
  24. data/examples/rosettacode/fibonacci.mirah +21 -0
  25. data/examples/rosettacode/file-size.mirah +5 -0
  26. data/examples/rosettacode/fizz-buzz.mirah +21 -0
  27. data/examples/rosettacode/flatten-a-list.mirah +24 -0
  28. data/examples/rosettacode/guess-the-number.mirah +21 -0
  29. data/examples/rosettacode/is-string-numeric.mirah +127 -0
  30. data/examples/rosettacode/palindrome.mirah +14 -0
  31. data/examples/rosettacode/repeat-a-string.mirah +9 -0
  32. data/examples/rosettacode/reverse-a-string.mirah +6 -0
  33. data/examples/rosettacode/rot-13.mirah +20 -0
  34. data/examples/rosettacode/user-input.mirah +4 -0
  35. data/examples/sort_closure.mirah +1 -1
  36. data/javalib/dynalink-0.2.jar +0 -0
  37. data/javalib/mirah-bootstrap.jar +0 -0
  38. data/lib/mirah.rb +7 -16
  39. data/lib/mirah/ast.rb +22 -92
  40. data/lib/mirah/ast/call.rb +41 -9
  41. data/lib/mirah/ast/class.rb +34 -6
  42. data/lib/mirah/ast/flow.rb +17 -5
  43. data/lib/mirah/ast/intrinsics.rb +50 -8
  44. data/lib/mirah/ast/literal.rb +7 -0
  45. data/lib/mirah/ast/local.rb +9 -1
  46. data/lib/mirah/ast/method.rb +21 -8
  47. data/lib/mirah/ast/scope.rb +1 -1
  48. data/lib/mirah/ast/structure.rb +81 -15
  49. data/lib/mirah/ast/type.rb +4 -0
  50. data/{bin/dubyc → lib/mirah/commands.rb} +4 -11
  51. data/lib/mirah/commands/base.rb +54 -0
  52. data/lib/mirah/commands/compile.rb +39 -0
  53. data/{examples/wiki/Rakefile → lib/mirah/commands/parse.rb} +18 -17
  54. data/lib/mirah/commands/run.rb +73 -0
  55. data/lib/mirah/compiler.rb +37 -417
  56. data/lib/mirah/compiler/call.rb +45 -0
  57. data/lib/mirah/compiler/class.rb +81 -0
  58. data/lib/mirah/compiler/flow.rb +109 -0
  59. data/lib/mirah/compiler/literal.rb +130 -0
  60. data/lib/mirah/compiler/local.rb +59 -0
  61. data/lib/mirah/compiler/method.rb +44 -0
  62. data/lib/mirah/compiler/structure.rb +65 -0
  63. data/lib/mirah/compiler/type.rb +27 -0
  64. data/lib/mirah/env.rb +4 -6
  65. data/lib/mirah/generator.rb +61 -0
  66. data/lib/mirah/jvm/compiler.rb +8 -867
  67. data/lib/mirah/jvm/compiler/base.rb +270 -0
  68. data/lib/mirah/jvm/compiler/java_source.rb +779 -0
  69. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +851 -0
  70. data/lib/mirah/jvm/method_lookup.rb +21 -2
  71. data/lib/mirah/jvm/source_generator/builder.rb +10 -13
  72. data/lib/mirah/jvm/source_generator/loops.rb +99 -93
  73. data/lib/mirah/jvm/source_generator/precompile.rb +3 -2
  74. data/lib/mirah/jvm/typer.rb +3 -3
  75. data/lib/mirah/jvm/types.rb +10 -426
  76. data/lib/mirah/jvm/types/array_type.rb +62 -0
  77. data/lib/mirah/jvm/types/basic_types.rb +1 -0
  78. data/lib/mirah/jvm/types/dynamic_type.rb +46 -0
  79. data/lib/mirah/jvm/types/factory.rb +23 -5
  80. data/lib/mirah/jvm/types/interface_definition.rb +20 -0
  81. data/lib/mirah/jvm/types/intrinsics.rb +15 -3
  82. data/lib/mirah/jvm/types/meta_type.rb +45 -0
  83. data/lib/mirah/jvm/types/methods.rb +12 -5
  84. data/lib/mirah/jvm/types/null_type.rb +27 -0
  85. data/lib/mirah/jvm/types/primitive_type.rb +38 -0
  86. data/lib/mirah/jvm/types/source_mirror.rb +266 -0
  87. data/lib/mirah/jvm/types/type.rb +173 -0
  88. data/lib/mirah/jvm/types/type_definition.rb +55 -0
  89. data/lib/mirah/jvm/types/unreachable_type.rb +27 -0
  90. data/lib/mirah/jvm/types/void_type.rb +19 -0
  91. data/lib/mirah/parser.rb +90 -0
  92. data/lib/mirah/plugin/gwt.rb +5 -5
  93. data/lib/mirah/plugin/java.rb +1 -1
  94. data/lib/mirah/transform.rb +4 -321
  95. data/lib/mirah/transform/ast_ext.rb +63 -0
  96. data/lib/mirah/transform/error.rb +13 -0
  97. data/lib/mirah/transform/helper.rb +761 -0
  98. data/lib/mirah/transform/transformer.rb +255 -0
  99. data/lib/mirah/typer.rb +2 -383
  100. data/{bin/duby → lib/mirah/typer/base.rb} +12 -10
  101. data/lib/mirah/typer/simple.rb +377 -0
  102. data/lib/mirah/util/argument_processor.rb +114 -0
  103. data/lib/mirah/util/class_loader.rb +37 -0
  104. data/lib/mirah/util/compilation_state.rb +51 -0
  105. data/lib/mirah/util/process_errors.rb +33 -0
  106. data/lib/mirah/version.rb +1 -1
  107. data/lib/mirah_task.rb +3 -2
  108. data/test/{test_ast.rb → core/test_ast.rb} +6 -0
  109. data/test/{test_compilation.rb → core/test_compilation.rb} +0 -0
  110. data/test/{test_env.rb → core/test_env.rb} +24 -25
  111. data/test/{test_macros.rb → core/test_macros.rb} +2 -4
  112. data/test/{test_typer.rb → core/test_typer.rb} +0 -3
  113. data/test/jvm/bytecode_test_helper.rb +181 -0
  114. data/test/{test_javac_compiler.rb → jvm/javac_test_helper.rb} +38 -22
  115. data/test/jvm/test_enumerable.rb +304 -0
  116. data/test/{test_java_typer.rb → jvm/test_java_typer.rb} +2 -4
  117. data/test/{test_jvm_compiler.rb → jvm/test_jvm_compiler.rb} +146 -443
  118. data/test/jvm/test_macros.rb +147 -0
  119. data/test/jvm/test_main_method.rb +15 -0
  120. data/test/{test_gwt.rb → plugins/test_gwt.rb} +0 -2
  121. metadata +103 -91
  122. data/bin/jrubyp +0 -52
  123. data/examples/wiki/src/org/mirah/wiki/MirahWiki.duby +0 -339
  124. data/examples/wiki/src/org/mirah/wiki/edit.eduby.html +0 -42
  125. data/examples/wiki/src/org/mirah/wiki/error.eduby.html +0 -2
  126. data/examples/wiki/src/org/mirah/wiki/layout.eduby.html +0 -69
  127. data/examples/wiki/src/org/mirah/wiki/parser.eduby.html +0 -7
  128. data/examples/wiki/src/org/mirah/wiki/view.eduby.html +0 -15
  129. data/examples/wiki/war/WEB-INF/classes/test/HeredocContext.class +0 -0
  130. data/examples/wiki/war/WEB-INF/classes/test/MirahParser.class +0 -0
  131. data/examples/wiki/war/WEB-INF/lib/appengine-api.jar +0 -0
  132. data/examples/wiki/war/WEB-INF/lib/dubydatastore.jar +0 -0
  133. data/examples/wiki/war/WEB-INF/lib/jmeta-runtime.jar +0 -0
  134. data/examples/wiki/war/WEB-INF/lib/pegdown-stubs.jar +0 -0
  135. data/examples/wiki/war/WEB-INF/pegdown.jar +0 -0
  136. data/examples/wiki/war/app.yaml +0 -21
  137. data/examples/wiki/war/public/favicon.ico +0 -0
  138. data/examples/wiki/war/public/images/appengine_duby.png +0 -0
  139. data/examples/wiki/war/public/images/back.gif +0 -0
  140. data/examples/wiki/war/public/images/dir.gif +0 -0
  141. data/examples/wiki/war/public/images/file.gif +0 -0
  142. data/examples/wiki/war/public/javascripts/prettify.js +0 -61
  143. data/examples/wiki/war/public/robots.txt +0 -0
  144. data/examples/wiki/war/public/stylesheets/main.css +0 -156
  145. data/examples/wiki/war/public/stylesheets/prettify.css +0 -1
  146. data/examples/wiki/war/public/stylesheets/sh_style.css +0 -66
  147. data/examples/wiki/war/public/stylesheets/source.css +0 -21
  148. data/examples/wiki/war/public/wmd/images/bg-fill.png +0 -0
  149. data/examples/wiki/war/public/wmd/images/bg.png +0 -0
  150. data/examples/wiki/war/public/wmd/images/blockquote.png +0 -0
  151. data/examples/wiki/war/public/wmd/images/bold.png +0 -0
  152. data/examples/wiki/war/public/wmd/images/code.png +0 -0
  153. data/examples/wiki/war/public/wmd/images/h1.png +0 -0
  154. data/examples/wiki/war/public/wmd/images/hr.png +0 -0
  155. data/examples/wiki/war/public/wmd/images/img.png +0 -0
  156. data/examples/wiki/war/public/wmd/images/italic.png +0 -0
  157. data/examples/wiki/war/public/wmd/images/link.png +0 -0
  158. data/examples/wiki/war/public/wmd/images/ol.png +0 -0
  159. data/examples/wiki/war/public/wmd/images/redo.png +0 -0
  160. data/examples/wiki/war/public/wmd/images/separator.png +0 -0
  161. data/examples/wiki/war/public/wmd/images/ul.png +0 -0
  162. data/examples/wiki/war/public/wmd/images/undo.png +0 -0
  163. data/examples/wiki/war/public/wmd/images/wmd-on.png +0 -0
  164. data/examples/wiki/war/public/wmd/images/wmd.png +0 -0
  165. data/examples/wiki/war/public/wmd/showdown.js +0 -421
  166. data/examples/wiki/war/public/wmd/wmd-base.js +0 -1799
  167. data/examples/wiki/war/public/wmd/wmd-plus.js +0 -311
  168. data/examples/wiki/war/public/wmd/wmd.js +0 -73
  169. data/examples/wiki/war/src/org/mirah/wiki/MirahWiki.duby +0 -339
  170. data/examples/wiki/war/src/org/mirah/wiki/edit.eduby.html +0 -42
  171. data/examples/wiki/war/src/org/mirah/wiki/error.eduby.html +0 -2
  172. data/examples/wiki/war/src/org/mirah/wiki/layout.eduby.html +0 -69
  173. data/examples/wiki/war/src/org/mirah/wiki/parser.eduby.html +0 -7
  174. data/examples/wiki/war/src/org/mirah/wiki/view.eduby.html +0 -15
  175. data/javalib/dynalink-0.1.jar +0 -0
  176. data/javalib/jsr292-mock.jar +0 -0
  177. data/lib/mirah/class_loader.rb +0 -35
  178. data/lib/mirah/compilation_state.rb +0 -28
  179. data/lib/mirah/impl.rb +0 -273
  180. data/lib/mirah/jvm/base.rb +0 -267
  181. data/lib/mirah/jvm/source_compiler.rb +0 -760
  182. data/lib/mirah/transform2.rb +0 -752
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env jruby
2
-
3
1
  # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
4
2
  # All contributing project authors may be found in the NOTICE file.
5
3
  #
@@ -15,12 +13,16 @@
15
13
  # See the License for the specific language governing permissions and
16
14
  # limitations under the License.
17
15
 
18
- begin
19
- require 'mirah'
20
- rescue LoadError
21
- $: << File.dirname(File.dirname(__FILE__)) + '/lib'
22
- require 'mirah'
23
- end
16
+ module Mirah
17
+ module Typer
18
+ class Base
19
+ include Mirah
20
+
21
+ def log(message); Typer.log(message); end
24
22
 
25
- puts 'WARNING: Duby is now Mirah. Please use the `mirah` command.'
26
- Duby.run(*ARGV)
23
+ def to_s
24
+ name
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,377 @@
1
+ # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
2
+ # All contributing project authors may be found in the NOTICE file.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ require 'mirah/ast'
17
+ require 'mirah/transform'
18
+
19
+ module Mirah
20
+ module Typer
21
+ class Simple < Base
22
+ attr_accessor :known_types, :errors, :last_chance
23
+
24
+ def initialize(self_type)
25
+ @known_types = {}
26
+
27
+ @known_types["self"] = type_reference(nil, self_type)
28
+ @known_types["fixnum"] = type_reference(nil, "fixnum")
29
+ @known_types["float"] = type_reference(nil, "float")
30
+ @known_types["string"] = type_reference(nil, "string")
31
+ @known_types["boolean"] = type_reference(nil, "boolean")
32
+ @errors = []
33
+ end
34
+
35
+ def name
36
+ "Simple"
37
+ end
38
+
39
+ def set_filename(scope, name); end
40
+
41
+ def self_type
42
+ known_types["self"]
43
+ end
44
+
45
+ def default_type
46
+ nil
47
+ end
48
+
49
+ def fixnum_type(value=0)
50
+ known_types["fixnum"]
51
+ end
52
+
53
+ def float_type(value=0)
54
+ known_types["float"]
55
+ end
56
+
57
+ def string_type
58
+ known_types["string"]
59
+ end
60
+
61
+ def boolean_type
62
+ known_types["boolean"]
63
+ end
64
+
65
+ def null_type
66
+ AST::TypeReference::NullType
67
+ end
68
+
69
+ def no_type
70
+ AST::TypeReference::NoType
71
+ end
72
+
73
+ # to be overridden
74
+ def array_type
75
+ AST::TypeReference::NullType
76
+ end
77
+
78
+ # to be overridden
79
+ def hash_type
80
+ AST::TypeReference::NullType
81
+ end
82
+
83
+ def known_type(scope, name)
84
+ @known_types[name]
85
+ end
86
+
87
+ def define_type(scope, name, superclass, interfaces)
88
+ log "New type defined: '#{name}' < '#{superclass}'"
89
+ result = type_definition(scope, name, superclass, interfaces)
90
+
91
+ # TODO Get rid of known_types["self"]
92
+ old_self, known_types["self"] = known_types["self"], result
93
+ yield
94
+ known_types["self"] = old_self
95
+
96
+ result
97
+ end
98
+
99
+ def learn_local_type(scope, name, type)
100
+ return if type.null? && !@last_chance
101
+ type = scope.learn_local_type(name, known_types[type] || type)
102
+ log "Learned local type under #{scope} : #{name} = #{type}" if type
103
+ type
104
+ end
105
+
106
+ def local_type(scope, name)
107
+ type = scope.local_type(name)
108
+ log "Retrieved local type in #{scope} : #{name} = #{type}" if type
109
+ type
110
+ end
111
+
112
+ def local_types
113
+ @local_types ||= {}
114
+ end
115
+
116
+ def local_type_hash(scope)
117
+ local_types[scope] ||= {}
118
+ end
119
+
120
+ def field_types
121
+ @field_types ||= {}
122
+ end
123
+
124
+ def field_type_hash(cls)
125
+ field_types[cls] ||= {}
126
+ end
127
+
128
+ def static_field_types
129
+ @static_field_types ||= {}
130
+ end
131
+
132
+ def static_field_type_hash(cls)
133
+ static_field_types[cls] ||= {}
134
+ end
135
+
136
+ def infer_signature(method_def)
137
+ end
138
+
139
+ def learn_field_type(cls, name, type)
140
+ log "Learned field type under #{cls} : #{name} = #{type}" if type
141
+
142
+ # TODO check for compatibility?
143
+ field_type_hash(cls)[name] ||= known_types[type] || type
144
+
145
+ type
146
+ end
147
+
148
+ def field_type(cls, name)
149
+ field_type_hash(cls)[name]
150
+ end
151
+
152
+ def learn_static_field_type(cls, name, type)
153
+ log "Learned field type under #{cls} : #{name} = #{type}" if type
154
+
155
+ # TODO check for compatibility?
156
+ static_field_type_hash(cls)[name] ||= known_types[type] || type
157
+
158
+ type
159
+ end
160
+
161
+ def static_field_type(cls, name)
162
+ static_field_type_hash(cls)[name]
163
+ end
164
+
165
+ def learn_method_type(target_type, name, parameter_types, type, exceptions)
166
+ log "Learned method #{name} (#{parameter_types}) on #{target_type} = #{type}" if type
167
+
168
+ get_method_type_hash(target_type, name, parameter_types)[:type] = known_types[type] || type
169
+
170
+ # if it's any args are imported types, also add a mapping for the expanded name
171
+ imported_types = parameter_types.map {|param| known_types[param] || param}
172
+ get_method_type_hash(target_type, name, imported_types)[:type] = type
173
+ end
174
+
175
+ def method_type(target_type, name, parameter_types)
176
+ if (target_type && target_type.error?) ||
177
+ parameter_types.any? {|t| t && t.error?}
178
+ return AST.error_type
179
+ end
180
+ constructor = (name == 'new' && target_type && target_type.meta?)
181
+
182
+ if constructor
183
+ # constructor handled different from other methods
184
+ simple_type = get_method_type_hash(target_type.unmeta, 'initialize', parameter_types)[:type]
185
+ else
186
+ simple_type = get_method_type_hash(target_type, name, parameter_types)[:type]
187
+ end
188
+
189
+
190
+ if !simple_type
191
+ log "Method type for \"#{name}\" #{parameter_types} on #{target_type} not found."
192
+
193
+ # allow plugins a go if we're in the inference phase
194
+ simple_type = plugins do |plugin|
195
+ plugin.method_type(self, target_type, name, parameter_types)
196
+ end
197
+ end
198
+
199
+ return nil unless simple_type
200
+
201
+ if constructor
202
+ log "Method type for \"#{name}\" #{parameter_types} on #{target_type} = #{target_type}"
203
+ target_type.unmeta
204
+ else
205
+ log "Method type for \"#{name}\" #{parameter_types} on #{target_type} = #{simple_type}"
206
+ simple_type
207
+ end
208
+ end
209
+
210
+ def plugins
211
+ if cycling?
212
+ Mirah.typer_plugins.each do |plugin|
213
+ log "Invoking plugin: #{plugin}"
214
+
215
+ result = yield plugin
216
+ return result if result
217
+ end
218
+ end
219
+
220
+ nil
221
+ end
222
+
223
+ def cycling?
224
+ @cycling
225
+ end
226
+
227
+ def cycling=(c)
228
+ @cycling = c
229
+ end
230
+
231
+ def cycle(count)
232
+ @cycling = true
233
+ count.times do |i|
234
+ begin
235
+ log "[Cycle #{i}]: Started... (#{@deferred_nodes.size} nodes to resolve)"
236
+ yield i
237
+ ensure
238
+ log "[Cycle #{i}]: Complete!"
239
+ end
240
+ end
241
+ ensure
242
+ @cycling = false
243
+ end
244
+
245
+ def method_types
246
+ @method_types ||= {}
247
+ end
248
+
249
+ def get_method_type_hash(target_type, name, parameter_types)
250
+ method_types[target_type] ||= {}
251
+ method_types[target_type][name] ||= {}
252
+ method_types[target_type][name][parameter_types.size] ||= {}
253
+
254
+ current = method_types[target_type][name][parameter_types.size]
255
+
256
+ parameter_types.each {|type| current[type] ||= {}; current = current[type]}
257
+
258
+ current
259
+ end
260
+
261
+ def type_reference(scope, name, array=false, meta=false)
262
+ AST::TypeReference.new(name, array, meta)
263
+ end
264
+
265
+ def type_definition(scope, name, superclass, interfaces)
266
+ AST::TypeDefinition.new(name, AST::TypeReference.new(superclass), interfaces)
267
+ end
268
+
269
+ def deferred_nodes
270
+ @deferred_nodes ||= {}
271
+ end
272
+
273
+ def infer(node, expression=true)
274
+ begin
275
+ node.infer(self, expression)
276
+ rescue InferenceError => ex
277
+ ex.node ||= node
278
+ error(node, ex)
279
+ rescue Exception => ex
280
+ raise Mirah::InternalCompilerError.wrap(ex, node)
281
+ end
282
+ end
283
+
284
+ def error(node, error_or_msg=nil, backtrace=nil)
285
+ if error_or_msg.kind_of? InferenceError
286
+ error = error_or_msg
287
+ elsif error_or_msg
288
+ error = InferenceError.new(error_or_msg, node)
289
+ error.set_backtrace(backtrace) if backtrace
290
+ else
291
+ error = InferenceError.new("Unable to infer type.", node)
292
+ end
293
+ @errors << error
294
+ node.resolve_if(self) do
295
+ AST.error_type
296
+ end
297
+ end
298
+
299
+ def defer(node, error_message=nil)
300
+ if @error_next
301
+ log "Marking #{node} as an error"
302
+ @error_next = false
303
+ error(node, error_message)
304
+ else
305
+ raise "Can't defer nil" if node.nil?
306
+ return if deferred_nodes.include? node
307
+ log "Deferring inference for #{node}"
308
+
309
+ deferred_nodes[node] = self_type
310
+ end
311
+ end
312
+
313
+ def resolve(raise = false)
314
+ count = deferred_nodes.size + 1
315
+
316
+ log "Entering type inference cycle"
317
+
318
+ retried = false
319
+ cycle(count) do |i|
320
+ old_deferred = @deferred_nodes
321
+ @deferred_nodes = {}
322
+ old_deferred.each do |node, saved_type|
323
+ known_types["self"] = saved_type
324
+ type = infer(node)
325
+
326
+ log "[Cycle #{i}]: Inferred type for #{node}: #{type || 'FAILED'}"
327
+
328
+ if type == default_type
329
+ @deferred_nodes[node] = saved_type
330
+ end
331
+ end
332
+
333
+ if @deferred_nodes.size == 0
334
+ log "[Cycle #{i}]: Resolved all types, exiting"
335
+ break
336
+ elsif old_deferred == @deferred_nodes
337
+ if @error_next || retried
338
+ log "[Cycle #{i}]: Made no progress, bailing out"
339
+ break
340
+ elsif @last_chance
341
+ # Retry this iteration, and mark the first deferred
342
+ # type as an error.
343
+ retried = true
344
+ @error_next = true
345
+ redo
346
+ else
347
+ # This is a hack for default constructor support. The right fix
348
+ # is probably to check the AST for constructors. Instead we
349
+ # tell the plugins that we're near the end of inference so they
350
+ # can assume no new constructors are being added. You could
351
+ # easily write some circular constructors that would compile
352
+ # with this technique but fail to run.
353
+ @last_chance = true
354
+ redo
355
+ end
356
+ end
357
+ retried = false
358
+ end
359
+
360
+ # done with n sweeps, if any remain mark them as errors
361
+ error_nodes = @errors.map {|e| e.node}
362
+ (deferred_nodes.keys - error_nodes).each do |deferred_node|
363
+ error_nodes << deferred_node
364
+ error(deferred_node)
365
+ end
366
+ if raise && !error_nodes.empty?
367
+ msg = "Could not infer typing for nodes:"
368
+ error_nodes.map do |e|
369
+ msg << "\n "
370
+ msg << "#{e.inspect} at line #{e.line_number} (child of #{e.parent})"
371
+ end
372
+ raise InferenceError.new(msg)
373
+ end
374
+ end
375
+ end
376
+ end
377
+ end
@@ -0,0 +1,114 @@
1
+ # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
2
+ # All contributing project authors may be found in the NOTICE file.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ module Mirah
17
+ module Util
18
+ class ArgumentProcessor
19
+ def initialize(state, args)
20
+ @state = state
21
+ @args = args
22
+ end
23
+
24
+ attr_accessor :state, :args
25
+
26
+ def process
27
+ state.args = args
28
+ while args.length > 0 && args[0] =~ /^-/
29
+ case args[0]
30
+ when '--classpath', '-c'
31
+ args.shift
32
+ Mirah::Env.decode_paths(args.shift, $CLASSPATH)
33
+ when '--cd'
34
+ args.shift
35
+ Dir.chdir(args.shift)
36
+ when '--dest', '-d'
37
+ args.shift
38
+ state.destination = File.join(File.expand_path(args.shift), '')
39
+ when '-e'
40
+ break
41
+ when '--explicit-packages'
42
+ args.shift
43
+ Mirah::AST::Script.explicit_packages = true
44
+ when '--help', '-h'
45
+ print_help
46
+ throw :exit
47
+ when '--java', '-j'
48
+ if state.command == :compile
49
+ require 'mirah/jvm/compiler/java_source'
50
+ state.compiler_class = Mirah::JVM::Compiler::JavaSource
51
+ args.shift
52
+ else
53
+ puts "-j/--java flag only applies to \"compile\" mode."
54
+ print_help
55
+ throw :exit
56
+ end
57
+ when '--jvm'
58
+ args.shift
59
+ state.set_jvm_version(args.shift)
60
+ when '-I'
61
+ args.shift
62
+ $: << args.shift
63
+ when '--plugin', '-p'
64
+ args.shift
65
+ plugin = args.shift
66
+ require "mirah/plugin/#{plugin}"
67
+ when '--verbose', '-V'
68
+ Mirah::Typer.verbose = true
69
+ Mirah::AST.verbose = true
70
+ Mirah::JVM::Compiler::JVMBytecode.verbose = true
71
+ state.verbose = true
72
+ args.shift
73
+ when '--version', '-v'
74
+ args.shift
75
+ print_version
76
+ when '--no-save-extensions'
77
+ args.shift
78
+ state.save_extensions = false
79
+ else
80
+ puts "unrecognized flag: " + args[0]
81
+ print_help
82
+ throw :exit
83
+ end
84
+ end
85
+ state.destination ||= File.join(File.expand_path('.'), '')
86
+ state.compiler_class ||= Mirah::JVM::Compiler::JVMBytecode
87
+ end
88
+
89
+ def print_help
90
+ puts "#{$0} [flags] <files or -e SCRIPT>
91
+ -c, --classpath PATH\tAdd PATH to the Java classpath for compilation
92
+ --cd DIR\t\tSwitch to the specified DIR befor compilation
93
+ -d, --dir DIR\t\tUse DIR as the base dir for compilation, packages
94
+ -e CODE\t\tCompile or run the inline script following -e
95
+ \t\t\t (the class will be named \"DashE\")
96
+ --explicit-packages\tRequire explicit 'package' lines in source
97
+ -h, --help\t\tPrint this help message
98
+ -I DIR\t\tAdd DIR to the Ruby load path before running
99
+ -j, --java\t\tOutput .java source (compile mode [mirahc] only)
100
+ --jvm VERSION\t\tEmit JVM bytecode targeting specified JVM
101
+ \t\t\t version (1.4, 1.5, 1.6, 1.7)
102
+ -p, --plugin PLUGIN\trequire 'mirah/plugin/PLUGIN' before running
103
+ -v, --version\t\tPrint the version of Mirah to the console
104
+ -V, --verbose\t\tVerbose logging"
105
+ state.help_printed = true
106
+ end
107
+
108
+ def print_version
109
+ puts "Mirah v#{Mirah::VERSION}"
110
+ state.version_printed = true
111
+ end
112
+ end
113
+ end
114
+ end