mirah 0.0.7-java → 0.0.8-java

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