mirah 0.0.4-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 (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,146 @@
1
+ require 'appengine-sdk'
2
+ require 'mirah_task'
3
+ require 'java'
4
+ require 'open-uri'
5
+ require 'rake'
6
+ require 'yaml'
7
+
8
+ module AppEngine::Rake
9
+ SERVLET = AppEngine::SDK::SDK_ROOT +
10
+ '/lib/shared/geronimo-servlet_2.5_spec-1.2.jar'
11
+ APIS = AppEngine::SDK::API_JAR
12
+ TOOLS = AppEngine::SDK::TOOLS_JAR
13
+
14
+ $CLASSPATH << SERVLET
15
+ $CLASSPATH << APIS
16
+ $CLASSPATH << TOOLS
17
+
18
+ class AppEngineTask < Rake::Task
19
+ def initialize(*args, &block)
20
+ super
21
+ AppEngineTask.tasks << self
22
+ end
23
+
24
+ def init(src, war)
25
+ @src = src
26
+ @war = war
27
+ unless $CLASSPATH.include?(webinf_classes)
28
+ $CLASSPATH << webinf_classes
29
+ end
30
+ webinf_lib_jars.each do |jar|
31
+ $CLASSPATH << jar unless $CLASSPATH.include?(jar)
32
+ end
33
+ Duby.source_paths << src
34
+ Duby.dest_paths << webinf_classes
35
+ directory(webinf_classes)
36
+ directory(webinf_lib)
37
+
38
+ file_create api_jar => webinf_lib do
39
+ puts 'Coping apis'
40
+ cp APIS, api_jar
41
+ end
42
+
43
+ task :server => [name] do
44
+ check_for_updates
45
+ args = [
46
+ 'java', '-cp', TOOLS,
47
+ 'com.google.appengine.tools.KickStart',
48
+ 'com.google.appengine.tools.development.DevAppServerMain',
49
+ @war
50
+ ]
51
+ system *args
52
+ @done = true
53
+ @update_thread.join
54
+ end
55
+ task :upload => [name] do
56
+ Java::ComGoogleAppengineTools::AppCfg.main(
57
+ ['update', @war].to_java(:string))
58
+ end
59
+
60
+ enhance([api_jar])
61
+ end
62
+
63
+ def real_prerequisites
64
+ prerequisites.map {|n| application[n, scope]}
65
+ end
66
+
67
+ def check_for_updates
68
+ @update_thread = Thread.new do
69
+ # Give the server time to start
70
+ next_time = Time.now + 5
71
+ until @done
72
+ sleep_time = next_time - Time.now
73
+ sleep(sleep_time) if sleep_time > 0
74
+ next_time = Time.now + 1
75
+ update
76
+ end
77
+ end
78
+ end
79
+
80
+ def update
81
+ begin
82
+ timestamp = app_yaml_timestamp
83
+ @last_app_yaml_timestamp ||= timestamp
84
+ updated = false
85
+ real_prerequisites.each do |dep|
86
+ if dep.needed?
87
+ puts "Executing #{dep.name}"
88
+ dep.execute
89
+ updated = true
90
+ end
91
+ end
92
+ if updated || (timestamp != @last_app_yaml_timestamp)
93
+ begin
94
+ open('http://localhost:8080/_ah/reloadwebapp')
95
+ @last_app_yaml_timestamp = timestamp
96
+ rescue OpenURI::HTTPError
97
+ end
98
+ end
99
+ rescue Exception
100
+ puts $!, $@
101
+ end
102
+ end
103
+
104
+ def app_yaml_timestamp
105
+ if File.exist?(app_yaml)
106
+ File.mtime(app_yaml)
107
+ end
108
+ end
109
+
110
+ def app_yaml
111
+ @war + '/app.yaml'
112
+ end
113
+
114
+ def webinf_classes
115
+ @war + '/WEB-INF/classes'
116
+ end
117
+
118
+ def webinf_lib
119
+ @war + '/WEB-INF/lib'
120
+ end
121
+
122
+ def api_jar
123
+ File.join(webinf_lib, File.basename(APIS))
124
+ end
125
+
126
+ def webinf_lib_jars
127
+ Dir.glob(webinf_lib + '/*.jar')
128
+ end
129
+ end
130
+ end
131
+
132
+ def appengine_app(*args, &block)
133
+ deps = []
134
+ if args[-1].kind_of?(Hash)
135
+ hash = args.pop
136
+ arg = hash.keys[0]
137
+ deps = hash[arg]
138
+ args << arg
139
+ end
140
+ name, src, war = args
141
+ task = AppEngine::Rake::AppEngineTask.define_task(name => deps, &block)
142
+ src = File.expand_path(src || 'src')
143
+ war = File.expand_path(war || 'war')
144
+ task.init(src, war)
145
+ task
146
+ end
@@ -0,0 +1,615 @@
1
+ require 'mirah/transform'
2
+ require 'mirah/ast/scope'
3
+
4
+ module Duby
5
+ module AST
6
+ class << self
7
+ attr_accessor :verbose
8
+ end
9
+
10
+ # The top of the AST class hierarchy, this represents an abstract AST node.
11
+ # It provides accessors for _children_, an array of all child nodes,
12
+ # _parent_, a reference to this node's parent (nil if none), and _newline_,
13
+ # whether this node represents a new line.
14
+ class Node
15
+ include Java::DubyLangCompiler.Node
16
+ include Enumerable
17
+
18
+ attr_accessor :children
19
+ attr_accessor :parent
20
+ attr_accessor :position
21
+ attr_accessor :newline
22
+ attr_accessor :inferred_type
23
+
24
+ def self.child(name)
25
+ @children ||= []
26
+ index = @children.size
27
+ class_eval <<-EOF
28
+ def #{name}
29
+ @children[#{index}]
30
+ end
31
+
32
+ def #{name}=(node)
33
+ @children[#{index}] = _set_parent(node)
34
+ end
35
+ EOF
36
+ @children << name
37
+ end
38
+
39
+ def self.child_name(i)
40
+ @children[i] if @children
41
+ end
42
+
43
+ def child_nodes
44
+ java.util.ArrayList.new(@children)
45
+ end
46
+
47
+ def initialize(parent, position, children = [])
48
+ JRuby.reference(self.class).setRubyClassAllocator(JRuby.reference(self.class).reified_class)
49
+ unless parent.nil? || Duby::AST::Node === parent
50
+ raise "Duby::AST::Node.new parent #{parent.class} must be nil or === Duby::AST::Node."
51
+ end
52
+
53
+ @parent = parent
54
+ @newline = false
55
+ @inferred_type = nil
56
+ @resolved = false
57
+ @position = position
58
+ if block_given?
59
+ @children ||= []
60
+ @children = yield(self) || []
61
+ else
62
+ @children = children
63
+ end
64
+ end
65
+
66
+ def _dump(depth)
67
+ to_skip = %w(@parent @newline @inferred_type @resolved @proxy @scope @class_scope @typer)
68
+ vars = {}
69
+ instance_variables.each do |name|
70
+ next if to_skip.include?(name)
71
+ vars[name] = instance_variable_get(name)
72
+ begin
73
+ Marshal.dump(vars[name]) if AST.verbose
74
+ rescue
75
+ puts "#{self}: Failed to marshal #{name}"
76
+ puts $!, $@
77
+ raise $!
78
+ end
79
+ end
80
+ Marshal.dump(vars)
81
+ end
82
+
83
+ def self._load(vars)
84
+ node = self.allocate
85
+ Marshal.load(vars).each do |name, value|
86
+ node.instance_variable_set(name, value)
87
+ end
88
+ node.children.each do |child|
89
+ node._set_parent(child)
90
+ end
91
+ node.validate_children
92
+ node
93
+ end
94
+
95
+ def validate_children
96
+ validate_name if respond_to?(:validate_name)
97
+ children.each_with_index do |child, i|
98
+ validate_child(child, i)
99
+ end
100
+ end
101
+
102
+ def validate_child(child, i)
103
+ name = self.class.child_name(i)
104
+ validator = :"validate_#{name}"
105
+ if name && respond_to?(validator)
106
+ send validator
107
+ else
108
+ if UnquotedValue === child
109
+ self[i] = child.node
110
+ end
111
+ end
112
+ end
113
+
114
+ def line_number
115
+ if @position
116
+ @position.start_line + 1
117
+ else
118
+ 0
119
+ end
120
+ end
121
+
122
+ def log(message)
123
+ puts "* [AST] [#{simple_name}] " + message if AST.verbose
124
+ end
125
+
126
+ def inspect_children(indent = 0)
127
+ indent_str = ' ' * indent
128
+ str = ''
129
+ children.each_with_index do |child, i|
130
+ extra_indent = 0
131
+ if child
132
+ name = self.class.child_name(i)
133
+ if Duby::AST.verbose && name
134
+ str << "\n#{indent_str} #{name}:"
135
+ extra_indent = 1
136
+ end
137
+ if ::Array === child
138
+ child.each {|ary_child|
139
+ if Duby::AST.verbose && Node === ary_child && ary_child.parent != self
140
+ str << "\n#{indent_str} (wrong parent)"
141
+ end
142
+ str << "\n#{ary_child.inspect(indent + extra_indent + 1)}"
143
+ }
144
+ elsif ::Hash === child
145
+ str << "\n#{indent_str} #{child.inspect}"
146
+ else
147
+ if Duby::AST.verbose && Node === child && child.parent != self
148
+ str << "\n#{indent_str} (wrong parent)"
149
+ end
150
+ str << "\n#{child.inspect(indent + extra_indent + 1)}"
151
+ end
152
+ end
153
+ end
154
+ str
155
+ end
156
+
157
+ def inspect(indent = 0)
158
+ indent_str = ' ' * indent
159
+ indent_str << to_s << inspect_children(indent)
160
+ end
161
+
162
+ def simple_name
163
+ self.class.name.split("::")[-1]
164
+ end
165
+
166
+ def to_s; simple_name; end
167
+
168
+ def [](index) children[index] end
169
+
170
+ def []=(index, node)
171
+ node.parent = self
172
+ @children[index] = node
173
+ end
174
+
175
+ def each(&b) children.each(&b) end
176
+
177
+ def <<(node)
178
+ @children << _set_parent(node)
179
+ self
180
+ end
181
+
182
+ def insert(index, node)
183
+ node.parent = self
184
+ @children.insert(index, node)
185
+ end
186
+
187
+ def empty?
188
+ @children.empty?
189
+ end
190
+
191
+ def resolved!(typer=nil)
192
+ log "#{to_s} resolved!"
193
+ @resolved = true
194
+ end
195
+
196
+ def resolved?; @resolved end
197
+
198
+ def resolve_if(typer)
199
+ unless resolved?
200
+ @inferred_type = yield
201
+ @inferred_type ? resolved!(typer) : typer.defer(self)
202
+ end
203
+ @inferred_type
204
+ end
205
+
206
+ def self.===(other)
207
+ super || (other.kind_of?(NodeProxy) && (self === other.__getobj__))
208
+ end
209
+
210
+ def _set_parent(node)
211
+ case node
212
+ when Node
213
+ node.parent = self
214
+ when ::Array
215
+ node.each {|x| x.parent = self if x}
216
+ end
217
+ node
218
+ end
219
+
220
+ def initialize_copy(other)
221
+ @parent = nil
222
+ @children = []
223
+ other.children.each do |child|
224
+ case child
225
+ when ::Array
226
+ self << child.map {|x| x.dup}
227
+ when nil
228
+ self << nil
229
+ else
230
+ self << child.dup
231
+ end
232
+ end
233
+ end
234
+
235
+ def inferred_type!
236
+ unless @inferred_type
237
+ raise Duby::Typer::InferenceError.new(
238
+ "Internal Error: #{self.class} never inferred", self)
239
+ end
240
+ inferred_type
241
+ end
242
+ end
243
+
244
+
245
+ class ErrorNode < Node
246
+ def initialize(parent, error)
247
+ super(parent, error.position)
248
+ @error = error
249
+ @inferred_type = TypeReference::ErrorType
250
+ @resolved = true
251
+ end
252
+
253
+ def infer(typer)
254
+ end
255
+ end
256
+
257
+ module Named
258
+ attr_accessor :name
259
+
260
+ def to_s
261
+ "#{super}(#{name})"
262
+ end
263
+
264
+ def validate_name
265
+ if UnquotedValue === @name
266
+ @name = @name.name
267
+ end
268
+ end
269
+ end
270
+
271
+ module Typed
272
+ attr_accessor :type
273
+ end
274
+
275
+ module Valued
276
+ include Typed
277
+ attr_accessor :value
278
+ end
279
+
280
+ module Literal
281
+ include Typed
282
+ attr_accessor :literal
283
+
284
+ def to_s
285
+ "#{super}(#{literal.inspect})"
286
+ end
287
+ end
288
+
289
+ module Annotated
290
+ attr_accessor :annotations
291
+
292
+ def annotation(name)
293
+ name = name.to_s
294
+ annotations.find {|a| a.name == name}
295
+ end
296
+ end
297
+
298
+ module Binding
299
+ def binding_type(duby=nil)
300
+ static_scope.binding_type(defining_class, duby)
301
+ end
302
+
303
+ def binding_type=(type)
304
+ static_scope.binding_type = type
305
+ end
306
+
307
+ def has_binding?
308
+ static_scope.has_binding?
309
+ end
310
+ end
311
+
312
+ class Colon2 < Node; end
313
+
314
+ class Constant < Node
315
+ include Named
316
+ include Scoped
317
+ attr_accessor :array
318
+
319
+ def initialize(parent, position, name)
320
+ @name = name
321
+ super(parent, position, [])
322
+ end
323
+
324
+ def infer(typer)
325
+ @inferred_type ||= begin
326
+ # TODO lookup constant, inline if we're supposed to.
327
+ begin
328
+ typer.type_reference(scope, name, @array, true)
329
+ rescue NameError => ex
330
+ typer.known_types[@name] = Duby::AST.error_type
331
+ raise ex
332
+ end
333
+ end
334
+ end
335
+
336
+ def type_reference(typer)
337
+ begin
338
+ typer.type_reference(scope, @name, @array)
339
+ rescue NameError => ex
340
+ typer.known_types[@name] = Duby::AST.error_type
341
+ raise ex
342
+ end
343
+ end
344
+ end
345
+
346
+ class Self < Node
347
+ include Scoped
348
+ def infer(typer)
349
+ @inferred_type ||= scope.static_scope.self_type
350
+ end
351
+ end
352
+
353
+ class Annotation < Node
354
+ attr_reader :values
355
+ attr_accessor :runtime
356
+ alias runtime? runtime
357
+
358
+ child :name_node
359
+
360
+ def initialize(parent, position, name=nil, &block)
361
+ super(parent, position, &block)
362
+ if name
363
+ @name = if name.respond_to?(:class_name)
364
+ name.class_name
365
+ else
366
+ name.name
367
+ end
368
+ end
369
+ @values = {}
370
+ end
371
+
372
+ def name
373
+ @name
374
+ end
375
+
376
+ def type
377
+ BiteScript::ASM::Type.getObjectType(@name.tr('.', '/'))
378
+ end
379
+
380
+ def []=(name, value)
381
+ @values[name] = value
382
+ end
383
+
384
+ def [](name)
385
+ @values[name]
386
+ end
387
+
388
+ def infer(typer)
389
+ @inferred ||= begin
390
+ @name = name_node.type_reference(typer).name if name_node
391
+ @values.each do |name, value|
392
+ if Node === value
393
+ @values[name] = annotation_value(value, typer)
394
+ end
395
+ end
396
+ true
397
+ end
398
+ end
399
+
400
+ def annotation_value(node, typer)
401
+ case node
402
+ when String
403
+ java.lang.String.new(node.literal)
404
+ when Array
405
+ node.children.map {|node| annotation_value(node, typer)}
406
+ else
407
+ # TODO Support other types
408
+ ref = value.type_refence(typer)
409
+ desc = BiteScript::Signature.class_id(ref)
410
+ BiteScript::ASM::Type.getType(desc)
411
+ end
412
+ end
413
+ end
414
+
415
+ class TypeReference < Node
416
+ include Named
417
+ attr_accessor :array
418
+ alias array? array
419
+ attr_accessor :meta
420
+ alias meta? meta
421
+
422
+ def initialize(name, array = false, meta = false, position=nil)
423
+ super(nil, position)
424
+ @name = name
425
+ @array = array
426
+ @meta = meta
427
+ end
428
+
429
+ def type_reference(typer)
430
+ typer.type_reference(nil, name, array, meta)
431
+ end
432
+
433
+ def to_s
434
+ "Type(#{name}#{array? ? ' array' : ''}#{meta? ? ' meta' : ''})"
435
+ end
436
+
437
+ def full_name
438
+ "#{name}#{array ? '[]' : ''}"
439
+ end
440
+
441
+ def ==(other)
442
+ to_s == other.to_s
443
+ end
444
+
445
+ def eql?(other)
446
+ self == other
447
+ end
448
+
449
+ def hash
450
+ to_s.hash
451
+ end
452
+
453
+ def is_parent(other)
454
+ # default behavior now is to disallow any polymorphic types
455
+ self == other
456
+ end
457
+
458
+ def compatible?(other)
459
+ # default behavior is only exact match right now
460
+ self == other ||
461
+ error? || other.error? ||
462
+ unreachable? || other.unreachable?
463
+ end
464
+
465
+ def iterable?
466
+ array?
467
+ end
468
+
469
+ def component_type
470
+ AST.type(nil, name) if array?
471
+ end
472
+
473
+ def basic_type
474
+ if array? || meta?
475
+ TypeReference.new(name, false, false)
476
+ else
477
+ self
478
+ end
479
+ end
480
+
481
+ def narrow(other)
482
+ # only exact match allowed for now, so narrowing is a noop
483
+ if error? || unreachable?
484
+ other
485
+ else
486
+ self
487
+ end
488
+ end
489
+
490
+ def unmeta
491
+ TypeReference.new(name, array, false)
492
+ end
493
+
494
+ def meta
495
+ TypeReference.new(name, array, true)
496
+ end
497
+
498
+ def void?
499
+ name == :void
500
+ end
501
+
502
+ def error?
503
+ name == :error
504
+ end
505
+
506
+ def null?
507
+ name == :null
508
+ end
509
+
510
+ def unreachable?
511
+ name == :unreachable
512
+ end
513
+
514
+ def block?
515
+ name == :block
516
+ end
517
+
518
+ def primitive?
519
+ true
520
+ end
521
+
522
+ def _dump(depth)
523
+ Marshal.dump([name, array?, meta?])
524
+ end
525
+
526
+ def self._load(str)
527
+ AST::Type(*Marshal.load(str))
528
+ end
529
+
530
+ NoType = TypeReference.new(:notype)
531
+ NullType = TypeReference.new(:null)
532
+ ErrorType = TypeReference.new(:error)
533
+ UnreachableType = TypeReference.new(:unreachable)
534
+ BlockType = TypeReference.new(:block)
535
+ end
536
+
537
+ class TypeDefinition < TypeReference
538
+ attr_accessor :superclass, :interfaces
539
+
540
+ def initialize(name, superclass, interfaces)
541
+ super(name, false)
542
+
543
+ @superclass = superclass
544
+ @interfaces = interfaces
545
+ end
546
+ end
547
+
548
+ def self.type_factory
549
+ Thread.current[:ast_type_factory]
550
+ end
551
+
552
+ def self.type_factory=(factory)
553
+ Thread.current[:ast_type_factory] = factory
554
+ end
555
+
556
+ # Shortcut method to construct type references
557
+ def self.type(scope, typesym, array = false, meta = false)
558
+ factory = type_factory
559
+ if factory
560
+ factory.type(scope, typesym, array, meta)
561
+ else
562
+ TypeReference.new(typesym, array, meta)
563
+ end
564
+ end
565
+
566
+ def self.no_type
567
+ factory = type_factory
568
+ if factory
569
+ factory.no_type
570
+ else
571
+ TypeReference::NoType
572
+ end
573
+ end
574
+
575
+ def self.error_type
576
+ TypeReference::ErrorType
577
+ end
578
+
579
+ def self.unreachable_type
580
+ TypeReference::UnreachableType
581
+ end
582
+
583
+ def self.block_type
584
+ TypeReference::BlockType
585
+ end
586
+
587
+ def self.fixnum(parent, position, literal)
588
+ Fixnum.new(parent, position, literal)
589
+ end
590
+
591
+ def self.float(parent, position, literal)
592
+ Float.new(parent, position, literal)
593
+ end
594
+
595
+ def self.defmacro(name, &block)
596
+ @macros ||= {}
597
+ raise "Conflicting macros for #{name}" if @macros[name]
598
+ @macros[name] = block
599
+ end
600
+
601
+ def self.macro(name)
602
+ @macros[name]
603
+ end
604
+ end
605
+ end
606
+
607
+ require 'mirah/ast/local'
608
+ require 'mirah/ast/call'
609
+ require 'mirah/ast/flow'
610
+ require 'mirah/ast/literal'
611
+ require 'mirah/ast/method'
612
+ require 'mirah/ast/class'
613
+ require 'mirah/ast/structure'
614
+ require 'mirah/ast/type'
615
+ require 'mirah/ast/intrinsics'