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,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'