mirah 0.1.2-java → 0.1.3-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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/History.txt +225 -0
  3. data/Rakefile +108 -315
  4. data/TODO.md +100 -0
  5. data/bin/bundler +16 -0
  6. data/bin/rake +16 -0
  7. data/dist/mirahc.jar +0 -0
  8. data/examples/appengine/Readme +0 -1
  9. data/examples/literals.mirah +17 -0
  10. data/examples/macros/string_each_char.mirah +1 -1
  11. data/lib/mirah.rb +11 -21
  12. data/lib/mirah/transform/transformer.rb +1 -2
  13. data/lib/mirah/util/class_loader.rb +1 -1
  14. data/lib/mirah/util/logging.rb +0 -63
  15. data/lib/mirah/util/process_errors.rb +1 -0
  16. data/lib/mirah/version.rb +1 -1
  17. data/{examples/simple_class.mirah~ → test/artifacts/jar_test.rb} +7 -11
  18. data/{lib/mirah/commands.rb → test/artifacts/jruby_test.rb} +8 -5
  19. data/test/core/typer_test.rb +29 -11
  20. data/test/core/util/argument_processor_test.rb +24 -23
  21. data/test/core/util/class_loader_test.rb +7 -4
  22. data/test/core/util/{compilation_state_test.rb → jvm_version_test.rb} +20 -16
  23. data/test/fixtures/org/foo/ImplicitClassRetAnno.java +4 -0
  24. data/test/fixtures/org/foo/IntAnno.java +9 -0
  25. data/test/jvm/annotations_test.rb +11 -11
  26. data/test/jvm/blocks_test.rb +16 -12
  27. data/test/jvm/constructors_test.rb +8 -8
  28. data/test/jvm/enumerable_test.rb +48 -24
  29. data/test/jvm/generics_test.rb +3 -7
  30. data/test/jvm/import_test.rb +14 -0
  31. data/test/jvm/interface_test.rb +9 -24
  32. data/test/jvm/jvm_commands_test.rb +22 -4
  33. data/test/jvm/jvm_compiler_test.rb +124 -79
  34. data/test/jvm/list_extensions_test.rb +1 -1
  35. data/test/jvm/macros_test.rb +67 -14
  36. data/test/jvm/main_method_test.rb +1 -1
  37. data/test/jvm/new_backend_test_helper.rb +100 -3
  38. data/{lib/mirah/jvm/types/bitescript_ext.rb → test/jvm/static_fields_test.rb} +22 -21
  39. data/test/mirrors/base_type_test.rb +4 -3
  40. data/test/mirrors/bytecode_mirror_test.rb +35 -15
  41. data/test/mirrors/generics_test.rb +14 -5
  42. data/test/mirrors/member_test.rb +2 -1
  43. data/test/mirrors/method_lookup_test.rb +18 -6
  44. data/test/mirrors/mirrors_test.rb +87 -20
  45. data/test/mirrors/simple_async_mirror_loader_test.rb +7 -3
  46. data/test/mirrors/simple_mirror_loader_test.rb +5 -5
  47. data/test/test_helper.rb +25 -1
  48. metadata +18 -78
  49. data/bin/mirahp +0 -27
  50. data/bin/mirahp.cmd +0 -16
  51. data/examples/Fib.class +0 -0
  52. data/javalib/mirah-bootstrap.jar +0 -0
  53. data/javalib/mirah-builtins.jar +0 -0
  54. data/javalib/mirah-compiler.jar +0 -0
  55. data/javalib/mirah-mirrors.jar +0 -0
  56. data/javalib/mirah-newast-transitional.jar +0 -0
  57. data/javalib/mirah-parser.jar +0 -0
  58. data/javalib/mirah-util.jar +0 -0
  59. data/lib/mirah/ast.rb +0 -43
  60. data/lib/mirah/ast/scope.rb +0 -262
  61. data/lib/mirah/commands/base.rb +0 -59
  62. data/lib/mirah/commands/compile.rb +0 -39
  63. data/lib/mirah/commands/parse.rb +0 -36
  64. data/lib/mirah/commands/run.rb +0 -78
  65. data/lib/mirah/generator.rb +0 -150
  66. data/lib/mirah/jvm/compiler.rb +0 -50
  67. data/lib/mirah/jvm/compiler/base.rb +0 -421
  68. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +0 -1194
  69. data/lib/mirah/jvm/method_lookup.rb +0 -307
  70. data/lib/mirah/jvm/types.rb +0 -45
  71. data/lib/mirah/jvm/types/array_type.rb +0 -60
  72. data/lib/mirah/jvm/types/ast_ext.rb +0 -31
  73. data/lib/mirah/jvm/types/basic_types.rb +0 -41
  74. data/lib/mirah/jvm/types/block_type.rb +0 -15
  75. data/lib/mirah/jvm/types/boolean.rb +0 -70
  76. data/lib/mirah/jvm/types/enumerable.rb +0 -80
  77. data/lib/mirah/jvm/types/extensions.rb +0 -110
  78. data/lib/mirah/jvm/types/factory.rb +0 -830
  79. data/lib/mirah/jvm/types/floats.rb +0 -99
  80. data/lib/mirah/jvm/types/generic_type.rb +0 -72
  81. data/lib/mirah/jvm/types/implicit_nil_type.rb +0 -29
  82. data/lib/mirah/jvm/types/integers.rb +0 -131
  83. data/lib/mirah/jvm/types/interface_definition.rb +0 -20
  84. data/lib/mirah/jvm/types/intrinsics.rb +0 -385
  85. data/lib/mirah/jvm/types/literals.rb +0 -89
  86. data/lib/mirah/jvm/types/meta_type.rb +0 -54
  87. data/lib/mirah/jvm/types/methods.rb +0 -946
  88. data/lib/mirah/jvm/types/null_type.rb +0 -39
  89. data/lib/mirah/jvm/types/number.rb +0 -184
  90. data/lib/mirah/jvm/types/primitive_type.rb +0 -76
  91. data/lib/mirah/jvm/types/source_mirror.rb +0 -274
  92. data/lib/mirah/jvm/types/type.rb +0 -311
  93. data/lib/mirah/jvm/types/type_definition.rb +0 -72
  94. data/lib/mirah/jvm/types/void_type.rb +0 -19
  95. data/lib/mirah/util/compilation_state.rb +0 -60
  96. data/test/core/commands_test.rb +0 -89
  97. data/test/core/generator_test.rb +0 -26
  98. data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
  99. data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
  100. data/test/jvm/bytecode_test_helper.rb +0 -193
  101. data/test/jvm/factory_test.rb +0 -28
  102. data/test/jvm/java_typer_test.rb +0 -283
@@ -1,36 +0,0 @@
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/parser'
17
-
18
- module Mirah
19
- module Commands
20
- class Parse < Base
21
- def execute
22
- execute_base do
23
- parser = Mirah::Parser.new(@state, nil, false)
24
-
25
- parser.parse_from_args(args).each do |ast|
26
- puts parser.format_ast(ast)
27
- end
28
- end
29
- end
30
-
31
- def command_name
32
- :parse
33
- end
34
- end
35
- end
36
- end
@@ -1,78 +0,0 @@
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/generator'
17
- require 'mirah/util/class_loader'
18
-
19
- module Mirah
20
- module Commands
21
- class Run < Base
22
- def execute
23
- execute_base do
24
- class_map = generate_classes
25
- $CLASSPATH << Mirah::Env.decode_paths(@state.classpath) if @state.classpath
26
- class_loader = load_classes class_map
27
-
28
- main = find_main class_map, class_loader
29
-
30
- run_main(main)
31
- end
32
- end
33
-
34
- def command_name
35
- :run
36
- end
37
-
38
- private
39
-
40
- def load_classes(class_map)
41
- Mirah::Util::ClassLoader.new(JRuby.runtime.jruby_class_loader, class_map)
42
- end
43
-
44
- def find_main class_map, class_loader
45
- # TODO: using first main; find correct one?
46
- class_map.keys.each do |name|
47
- cls = class_loader.load_class(name)
48
- main = cls.get_method("main", java::lang::String[].java_class)
49
- return main if main
50
- end
51
- nil
52
- end
53
-
54
- def run_main(main)
55
- if main
56
- begin
57
- main.invoke(nil, [args.to_java(:string)].to_java)
58
- rescue java.lang.Exception => e
59
- e = e.cause if e.cause
60
- raise e
61
- end
62
- else
63
- puts "No main found" unless @state.version_printed || @state.help_printed
64
- end
65
- end
66
-
67
- def generate_classes
68
- # generate all bytes for all classes
69
- generator = Mirah::Generator.new(@state, @state.compiler_class, false, @state.verbose)
70
- class_map = {}
71
- generator.generate(args).each do |result|
72
- class_map[result.classname.gsub(/\//, '.')] = Mirah::Util::ClassLoader.binary_string result.bytes
73
- end
74
- class_map
75
- end
76
- end
77
- end
78
- end
@@ -1,150 +0,0 @@
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
- require 'mirah/util/process_errors'
16
- require 'mirah/util/logging'
17
-
18
- module Mirah
19
- class Generator
20
- include Mirah::Util::ProcessErrors
21
- include Mirah::Logging::Logged
22
- java_import 'org.mirah.typer.simple.SimpleScoper'
23
- java_import 'org.mirah.typer.simple.TypePrinter'
24
- java_import 'org.mirah.macros.JvmBackend'
25
-
26
- def initialize(state, compiler_class, logging, verbose)
27
- @state = state
28
-
29
- # TODO untie this from the jvm backend (nh)
30
- if state.type_system
31
- # Using new type system
32
- @scoper = SimpleScoper.new do |scoper, node|
33
- scope = Java::OrgMirahJvmMirrors::JVMScope.new(scoper)
34
- scope.context_set(node)
35
- scope
36
- end
37
- type_system = state.type_system
38
- else
39
- @scoper = SimpleScoper.new {|scoper, node| Mirah::AST::StaticScope.new(node, scoper)}
40
- type_system = Mirah::JVM::Types::TypeFactory.new
41
- type_system.classpath = state.classpath if state.classpath
42
- type_system.bootclasspath = state.bootclasspath
43
- end
44
-
45
- @typer = Mirah::Typer::Typer.new(type_system, @scoper, self, nil)
46
- @parser = Mirah::Parser.new(state, @typer, logging)
47
- @compiler = Mirah::Compiler::ASTCompiler.new(state, compiler_class, logging)
48
- @extension_compiler = Mirah::Compiler::ASTCompiler.new(state, compiler_class, logging)
49
- if type_system.respond_to?(:maybe_initialize_builtins)
50
- type_system.maybe_initialize_builtins(@typer.macro_compiler)
51
- end
52
- @logging = logging
53
- @verbose = verbose
54
- end
55
-
56
- attr_accessor :parser, :compiler, :typer, :logging, :verbose
57
-
58
- def generate(arguments)
59
- # collect all ASTs from all files
60
- top_nodes = parser.parse_from_args(arguments)
61
-
62
- # enter all ASTs into inference engine
63
- puts "Inferring types..." if logging
64
- scoper, typer = infer_asts(top_nodes)
65
- do_transforms top_nodes
66
- # compile each AST in turn
67
- compiler_results = compiler.compile_asts(top_nodes, scoper, typer)
68
-
69
- puts "Done!" if logging
70
-
71
- compiler_results
72
- end
73
-
74
- def do_transforms nodes
75
- log("Starting Transform")
76
-
77
- java_import 'org.mirah.jvm.compiler.ClosureTransformer' rescue puts $!
78
- java_import 'org.mirah.util.Context' rescue puts $!
79
- #java_import 'org.mirah.typer.Typer'
80
- #java_import 'org.mirah.macros.Compiler'
81
- transformer = ClosureTransformer.new(Context.new.tap{|c|c.add(Java::org.mirah.typer::Typer, @typer) }) rescue nil
82
- if transformer
83
- nodes.each{|n| n.accept transformer, nil } # rescue log("transformer exception", $!.cause)
84
- log("POST Transform")
85
- log_types nodes
86
- else
87
- log "No transformer, skipping"
88
- end
89
- end
90
-
91
- def infer_asts(nodes, should_raise=false)
92
- log_and_reraise "Caught exception during type inference" do
93
- nodes.each {|ast| @typer.infer(ast, false) }
94
- if should_raise
95
- error_handler = lambda do |errors|
96
- message, position = errors[0].message[0].to_a
97
- raise Mirah::MirahError.new(message, position)
98
- end
99
- end
100
- process_inference_errors(@typer, nodes, &error_handler)
101
- end
102
- [@scoper, @typer]
103
- ensure
104
- log_types(nodes)
105
- end
106
-
107
- def log_and_reraise message
108
- yield
109
- rescue NativeException => ex
110
- log(message, ex.cause)
111
- raise ex
112
- end
113
-
114
- def log_types(nodes)
115
- if self.logging?
116
- buf = java.io.ByteArrayOutputStream.new
117
- ps = java.io.PrintStream.new(buf)
118
- printer = TypePrinter.new(@typer, ps)
119
- nodes.each {|ast| printer.scan(ast, nil)}
120
- ps.close()
121
- log("Inferred types:\n{0}", java.lang.String.new(buf.toByteArray))
122
- end
123
-
124
- end
125
-
126
- def compileAndLoadExtension(ast)
127
- log_types([ast])
128
- process_inference_errors(@typer, [ast])
129
- results = @extension_compiler.compile_asts([ast], @scoper, @typer)
130
- class_map = {}
131
- first_class_name = nil
132
- results.each do |result|
133
- classname = result.classname.gsub(/\//, '.')
134
- first_class_name ||= classname if classname.include?('$Extension')
135
- class_map[classname] = Mirah::Util::ClassLoader.binary_string result.bytes
136
- if @state.save_extensions
137
- filename = "#{@state.destination}#{result.filename}"
138
- FileUtils.mkdir_p(File.dirname(filename))
139
- File.open(filename, 'wb') {|f| f.write(result.bytes)}
140
- end
141
- end
142
- dcl = Mirah::Util::ClassLoader.new(JRuby.runtime.jruby_class_loader, class_map)
143
- dcl.load_class(first_class_name)
144
- end
145
-
146
- def logExtensionAst(ast)
147
- log("Extension ast:\n#{parser.format_ast(ast)}")
148
- end
149
- end
150
- end
@@ -1,50 +0,0 @@
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'
17
- require 'mirah/jvm/compiler/base'
18
- require 'mirah/jvm/method_lookup'
19
- require 'mirah/jvm/types'
20
- require 'bitescript'
21
- require 'mirah/jvm/compiler/jvm_bytecode'
22
- require 'mirah/transform/ast_ext'
23
-
24
- module Mirah
25
- module AST
26
- class FunctionalCall
27
- attr_accessor :target
28
- end
29
-
30
- class Super
31
- attr_accessor :target
32
- end
33
- end
34
- end
35
-
36
- module Mirah
37
- module JVM
38
- module Compiler
39
- begin
40
- class Backend < Java::OrgMirahJvmCompiler::Backend
41
- def initialize(config, scoper, typer)
42
- super(typer)
43
- end
44
- end
45
- rescue NameError
46
- puts "Unable to load new Backend"
47
- end
48
- end
49
- end
50
- end
@@ -1,421 +0,0 @@
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 JVM
18
- module Compiler
19
- java_import 'mirah.lang.ast.ClassDefinition'
20
- java_import 'mirah.lang.ast.StaticMethodDefinition'
21
- java_import 'mirah.lang.ast.SimpleNodeVisitor'
22
- java_import 'mirah.lang.ast.NodeScanner'
23
-
24
- class Base < SimpleNodeVisitor
25
- attr_accessor :filename, :method, :static, :class
26
- include Mirah::Logging::Logged
27
-
28
- class CompilationError < Mirah::NodeError
29
- end
30
-
31
- def logger_name
32
- "org.mirah.ruby.JVM.Compiler.Base"
33
- end
34
-
35
- def initialize(config, scoper, typer)
36
- super()
37
- @config = config
38
- @jump_scope = []
39
- @bindings = Hash.new {|h, type| h[type] = type.define(@file)}
40
- @captured_locals = Hash.new {|h, binding| h[binding] = {}}
41
- @self_scope = nil
42
- @scoper = typer.scoper
43
- @typer = typer
44
- end
45
-
46
- def target_jvm_version
47
- @config.target_jvm_version
48
- end
49
-
50
- def supports_invokedynamic?
51
- @config.supports_invokedynamic?
52
- end
53
-
54
- def defaultNode(node, expression)
55
- raise ArgumentError, "Can't compile node #{node}"
56
- end
57
-
58
- def visit(node, expression)
59
- begin
60
- node.accept(self, expression)
61
- rescue Exception => ex
62
- raise Mirah::InternalCompilerError.wrap(ex, node)
63
- end
64
- end
65
-
66
- def get_scope(node)
67
- @scoper.get_scope(node)
68
- end
69
-
70
- def introduced_scope(node)
71
- @scoper.get_introduced_scope(node)
72
- end
73
-
74
- def containing_scope(node)
75
- scope = get_scope(node)
76
- name = node.name.identifier
77
- while (!scope.shadowed?(name) && scope.parent && scope.parent.include?(name))
78
- scope = scope.parent
79
- end
80
- scope
81
- end
82
-
83
- def inferred_type(node)
84
- begin
85
- @typer.get_inferred_type(node).resolve
86
- rescue Exception => ex
87
- raise Mirah::InternalCompilerError.wrap(ex, node)
88
- end
89
- end
90
-
91
- def error(message, node)
92
- raise CompilationError.new(message, node)
93
- end
94
-
95
- def toplevel_class
96
- @class = @type.define(@file)
97
- end
98
-
99
- def generate
100
- log "Generating #{output_type}..."
101
- @file.generate do |filename, builder|
102
- log " #{builder.class_name}"
103
- if block_given?
104
- yield filename, builder
105
- else
106
- File.open(filename, 'wb') {|f| f.write(builder.generate)}
107
- end
108
- end
109
- log "...done!"
110
- end
111
-
112
- # Scans the top level of a file to see if it contains anything outside of a ClassDefinition.
113
- class ScriptScanner < NodeScanner
114
- attr_reader :found_other, :found_method
115
- def enterDefault(node, arg)
116
- @found_other = true
117
- false
118
- end
119
- def enterMethodDefinition(node, arg)
120
- @found_method = true
121
- false
122
- end
123
- def enterStaticMethodDefinition(node, arg)
124
- @found_method = true
125
- false
126
- end
127
- def enterConstructorDefinition(node, arg)
128
- @found_method = true
129
- false
130
- end
131
- def enterPackage(node, arg)
132
- # ignore
133
- false
134
- end
135
- def enterClassDefinition(node, arg)
136
- # ignore
137
- false
138
- end
139
- def enterInterfaceDeclaration(node, arg)
140
- # ignore
141
- false
142
- end
143
- def enterImport(node, arg)
144
- # ignore
145
- false
146
- end
147
- def enterNodeList(node, arg)
148
- # Scan the children
149
- true
150
- end
151
- end
152
-
153
- def visitMacroDefinition(node, expression)
154
- # ignore. It was already compiled
155
- end
156
-
157
- def visitScript(script, expression)
158
- @static = true
159
- @filename = File.basename(script.position.source.name)
160
- classname = Mirah::JVM::Compiler::JVMBytecode.classname_from_filename(@filename)
161
- @type = @typer.type_system.type(get_scope(script), classname)
162
- @file = file_builder(@filename)
163
- body = script.body
164
- scanner = ScriptScanner.new
165
- scanner.scan(body, expression)
166
- need_class = scanner.found_method || scanner.found_other
167
- if need_class
168
- @class = @type.define(@file)
169
- if scanner.found_other
170
- # Generate the main method
171
- with :method => @class.main do
172
- log "Starting main method"
173
-
174
- @method.start
175
- @current_scope = get_scope(script)
176
- declare_locals(@current_scope)
177
- begin_main
178
-
179
- prepare_binding(script) do
180
- visit(body, false)
181
- end
182
-
183
- finish_main
184
- @method.stop
185
- end
186
- log "Main method complete!"
187
- else
188
- visit(body, false)
189
- end
190
- @class.stop
191
- else
192
- visit(body, false)
193
- end
194
- end
195
-
196
- def visitNoop(node, expression)
197
- end
198
-
199
- def begin_main; end
200
- def finish_main; end
201
-
202
- # arg_types must be an Array
203
- def create_method_builder(name, node, static, exceptions, return_type, arg_types)
204
- return_type = nil if return_type.name == ':unreachable'
205
- visibility = :public # TODO
206
- flags = BiteScript::ASM::Opcodes::ACC_PUBLIC
207
- flags |= BiteScript::ASM::Opcodes::ACC_STATIC if static
208
- flags |= BiteScript::ASM::Opcodes::ACC_ABSTRACT if node.annotated_abstract?
209
- @class.method(flags, name.to_s, [return_type, *arg_types], exceptions)
210
- end
211
-
212
- def base_define_method(node)
213
- name = node.name.identifier.sub(/=$/, '_set')
214
- args = visit(node.arguments, true)
215
- is_static = self.static || node.kind_of?(StaticMethodDefinition)
216
- if name == "initialize" && is_static
217
- name = "<clinit>"
218
- end
219
- arg_types = args.map { |arg| inferred_type(arg) }
220
- return_type = inferred_type(node).return_type
221
- exceptions = [] # TODO
222
-
223
- with :static => is_static, :current_scope => introduced_scope(node) do
224
- method = create_method_builder(name, node, @static, exceptions,
225
- return_type, arg_types)
226
- annotate(method, node.annotations)
227
- yield method, arg_types
228
- end
229
-
230
- arg_types_for_opt = []
231
- args_for_opt = []
232
- if args
233
- args.each do |arg|
234
- if AST::OptionalArgument === arg
235
- new_args = arg_types_for_opt
236
- method = create_method_builder(name, node, @static, exceptions,
237
- return_type, new_args)
238
- with :method => method do
239
- log "Starting new method #{name}(#{arg_types_for_opt})"
240
-
241
- annotate(method, node.annotations)
242
- @method.start
243
-
244
- define_optarg_chain(name, arg,
245
- return_type,
246
- args_for_opt,
247
- arg_types_for_opt)
248
-
249
- @method.stop
250
- end
251
- end
252
- arg_types_for_opt << inferred_type(arg)
253
- args_for_opt << arg
254
- end
255
- end
256
- end
257
-
258
- def visitConstructorDefinition(node, expression)
259
- args = visit(node.arguments, true)
260
- arg_types = args.map { |arg| inferred_type(arg) }
261
- exceptions = [] # node.signature[:throws]
262
- visibility = :public # node.visibility
263
- method = @class.build_constructor(visibility, exceptions, *arg_types)
264
- annotate(method, node.annotations)
265
- with :current_scope => introduced_scope(node) do
266
- yield(method, args)
267
- end
268
- end
269
-
270
- def visitClassDefinition(class_def, expression)
271
- log "Compiling class #{class_def.name.identifier}"
272
- with(:type => inferred_type(class_def),
273
- :class => inferred_type(class_def).define(@file),
274
- :static => false) do
275
- annotate(@class, class_def.annotations)
276
- visit(class_def.body, false) if class_def.body
277
- @class.stop
278
- end
279
- end
280
-
281
- def visitArguments(args, expression)
282
- result = []
283
- args.required.each {|arg| result << arg}
284
- args.optional.each {|arg| result << arg}
285
- result << args.rest if args.rest
286
- args.required2.each {|arg| result << arg}
287
- result << args.block if args.block
288
- result
289
- end
290
-
291
- def visitStaticMethodDefinition(mdef, expression)
292
- visitMethodDefinition(mdef, expression)
293
- end
294
-
295
- def visitNodeList(body, expression)
296
- saved_self = @self_scope
297
- new_scope = introduced_scope(body)
298
- if new_scope
299
- declare_locals(new_scope)
300
- if new_scope != @self_scope
301
- if new_scope.self_node && new_scope.self_node != :self
302
- # FIXME This is a horrible hack!
303
- # Instead we should eliminate unused self's.
304
- unless new_scope.self_type.name == 'mirah.impl.Builtin'
305
- local_assign(
306
- new_scope, 'self', new_scope.self_type, false, new_scope.self_node)
307
- end
308
- end
309
- @self_scope = new_scope
310
- end
311
- end
312
- # all except the last element in a body of code is treated as a statement
313
- i, last = 0, body.size - 1
314
- while i < last
315
- visit(body.get(i), false)
316
- i += 1
317
- end
318
- if last >= 0
319
- yield body.get(last)
320
- else
321
- yield nil
322
- end
323
- @self_scope = saved_self
324
- end
325
-
326
- def visitClassAppendSelf(node, expression)
327
- with :static => true, :current_scope => introduced_scope(node) do
328
- visit(node.body, expression)
329
- end
330
- end
331
-
332
- def visitPackage(node, expression)
333
- visit(node.body, expression) if node.body
334
- end
335
-
336
- def scoped_body(scope, expression)
337
- body(scope, expression)
338
- end
339
-
340
- def scoped_local_name(name, scope=nil)
341
- if scope.nil? || scope == @current_scope
342
- name
343
- else
344
- "#{name}$#{scope.object_id}"
345
- end
346
- end
347
-
348
- def visitImport(node, expression)
349
- end
350
-
351
- def visitFixnum(node, expression)
352
- if expression
353
- inferred_type(node).literal(method, node.value)
354
- end
355
- end
356
-
357
- def visitCharLiteral(node, expression)
358
- if expression
359
- inferred_type(node).literal(method, node.value)
360
- end
361
- end
362
-
363
- alias visitFloat visitFixnum
364
-
365
- def visitSelf(node, expression)
366
- if expression
367
- set_position(node.position)
368
- scope = get_scope(node)
369
- if scope.self_node && scope.self_node != :self
370
- local(scope, 'self', scope.self_type)
371
- else
372
- real_self
373
- end
374
- end
375
- end
376
-
377
- def visitImplicitSelf(node, expression)
378
- visitSelf(node, expression)
379
- end
380
-
381
- def visitUnquote(node, expression)
382
- body = node.nodes
383
- i, last = 0, body.size - 1
384
- while i < last
385
- visit(body.get(i), false)
386
- i += 1
387
- end
388
- if last >= 0
389
- visit(body.get(last), expression)
390
- else
391
- visitImplicitNil(node, expression)
392
- end
393
- end
394
-
395
- def get_binding(type)
396
- @bindings[type]
397
- end
398
-
399
- def declared_captures(binding=nil)
400
- @captured_locals[binding || @binding]
401
- end
402
-
403
- def with(vars)
404
- orig_values = {}
405
- begin
406
- vars.each do |name, new_value|
407
- name = "@#{name}"
408
- orig_values[name] = instance_variable_get name
409
- instance_variable_set name, new_value
410
- end
411
- yield
412
- ensure
413
- orig_values.each do |name, value|
414
- instance_variable_set name, value
415
- end
416
- end
417
- end
418
- end
419
- end
420
- end
421
- end