mirah 0.1.0.pre-java → 0.1.1-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 (92) hide show
  1. data/History.txt +736 -0
  2. data/README.md +71 -0
  3. data/Rakefile +227 -73
  4. data/examples/Fib.class +0 -0
  5. data/examples/macros/{string-each-char.mirah → string_each_char.mirah} +2 -3
  6. data/examples/simple_class.mirah +3 -3
  7. data/examples/{dynamic.mirah → simple_class.mirah~} +7 -12
  8. data/javalib/mirah-bootstrap.jar +0 -0
  9. data/javalib/mirah-builtins.jar +0 -0
  10. data/javalib/mirah-compiler.jar +0 -0
  11. data/javalib/mirah-parser.jar +0 -0
  12. data/javalib/mirah-util.jar +0 -0
  13. data/lib/mirah.rb +8 -1
  14. data/lib/mirah/ast.rb +1 -1
  15. data/lib/mirah/ast/scope.rb +16 -0
  16. data/lib/mirah/commands/base.rb +1 -3
  17. data/lib/mirah/compiler.rb +17 -3
  18. data/lib/mirah/errors.rb +10 -10
  19. data/lib/mirah/generator.rb +21 -9
  20. data/lib/mirah/jvm/compiler.rb +17 -0
  21. data/lib/mirah/jvm/compiler/base.rb +24 -5
  22. data/lib/mirah/jvm/compiler/jvm_bytecode.rb +83 -20
  23. data/lib/mirah/jvm/method_lookup.rb +43 -22
  24. data/lib/mirah/jvm/types.rb +1 -2
  25. data/lib/mirah/jvm/types/array_type.rb +1 -6
  26. data/lib/mirah/jvm/types/ast_ext.rb +31 -0
  27. data/lib/mirah/jvm/types/basic_types.rb +1 -2
  28. data/lib/mirah/jvm/types/boolean.rb +11 -10
  29. data/lib/mirah/jvm/types/extensions.rb +14 -5
  30. data/lib/mirah/jvm/types/factory.rb +128 -43
  31. data/lib/mirah/jvm/types/floats.rb +8 -10
  32. data/lib/mirah/jvm/types/integers.rb +16 -9
  33. data/lib/mirah/jvm/types/intrinsics.rb +17 -69
  34. data/lib/mirah/jvm/types/meta_type.rb +5 -0
  35. data/lib/mirah/jvm/types/methods.rb +317 -151
  36. data/lib/mirah/jvm/types/methods.rb~ +973 -0
  37. data/lib/mirah/jvm/types/number.rb +29 -6
  38. data/lib/mirah/jvm/types/primitive_type.rb +35 -7
  39. data/lib/mirah/jvm/types/source_mirror.rb +11 -6
  40. data/lib/mirah/jvm/types/type.rb +52 -0
  41. data/lib/mirah/jvm/types/type_definition.rb +8 -2
  42. data/lib/mirah/transform/ast_ext.rb +9 -31
  43. data/lib/mirah/transform/transformer.rb +1 -1
  44. data/lib/mirah/typer.rb +2 -1
  45. data/lib/mirah/util/argument_processor.rb +10 -14
  46. data/lib/mirah/util/argument_processor.rb~ +146 -0
  47. data/lib/mirah/util/compilation_state.rb +15 -9
  48. data/lib/mirah/util/process_errors.rb +8 -2
  49. data/lib/mirah/version.rb +2 -2
  50. data/lib/mirah_task.rb +0 -7
  51. data/test/core/typer_test.rb +21 -13
  52. data/test/core/util/argument_processor_test.rb +19 -19
  53. data/test/core/util/class_loader_test.rb +19 -4
  54. data/test/core/util/compilation_state_test.rb +38 -0
  55. data/test/fixtures/org/foo/LowerCaseInnerClass$inner.class +0 -0
  56. data/test/fixtures/org/foo/LowerCaseInnerClass.class +0 -0
  57. data/test/fixtures/org/foo/LowerCaseInnerClass.java +7 -0
  58. data/test/jvm/blocks_test.rb +50 -29
  59. data/test/jvm/bytecode_test_helper.rb +71 -57
  60. data/test/jvm/cast_test.rb +162 -0
  61. data/test/jvm/constructors_test.rb +48 -0
  62. data/test/jvm/enumerable_test.rb +136 -7
  63. data/test/jvm/example_test.rb +39 -0
  64. data/test/jvm/factory_test.rb +6 -0
  65. data/test/jvm/generics_test.rb +0 -5
  66. data/test/jvm/import_test.rb +81 -0
  67. data/test/jvm/interface_test.rb +113 -0
  68. data/test/jvm/java_typer_test.rb +57 -11
  69. data/test/jvm/jvm_commands_test.rb +24 -0
  70. data/test/jvm/jvm_compiler_test.rb +186 -370
  71. data/test/jvm/macros_test.rb +67 -6
  72. data/test/jvm/main_method_test.rb +1 -1
  73. data/test/jvm/mirror_compilation_test_helper.rb +24 -0
  74. data/test/jvm/new_backend_test_helper.rb +25 -0
  75. data/test/jvm/rescue_test.rb +153 -18
  76. data/test/jvm/string_test.rb +41 -0
  77. data/test/jvm/varargs_test.rb +65 -0
  78. data/test/mirrors/base_type_test.rb +96 -0
  79. data/test/mirrors/bytecode_mirror_test.rb +86 -0
  80. data/test/mirrors/generics_test.rb +776 -0
  81. data/test/mirrors/member_test.rb +69 -0
  82. data/test/mirrors/method_lookup_test.rb +574 -0
  83. data/test/mirrors/mirrors_test.rb +562 -0
  84. data/test/mirrors/simple_async_mirror_loader_test.rb +110 -0
  85. data/test/mirrors/simple_mirror_loader_test.rb +104 -0
  86. data/test/test_helper.rb +2 -1
  87. metadata +244 -217
  88. data/README.txt +0 -59
  89. data/javalib/dynalink-0.2.jar +0 -0
  90. data/lib/mirah/jvm/typer.rb +0 -177
  91. data/lib/mirah/jvm/types/dynamic_type.rb +0 -45
  92. data/lib/mirah/jvm/types/unreachable_type.rb +0 -27
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2010 The Mirah project authors. All Rights Reserved.
1
+ # Copyright (c) 2010-2013 The Mirah project authors. All Rights Reserved.
2
2
  # All contributing project authors may be found in the NOTICE file.
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,6 +35,24 @@ module Mirah::JVM::Types
35
35
  def jump_if_not(compiler, call, label)
36
36
  @type.compile_boolean_operator(compiler, @op, true, call, label)
37
37
  end
38
+
39
+ def accept(visitor, expression)
40
+ visitor.visitComparison(self, expression)
41
+ end
42
+
43
+ def kind
44
+ Java::OrgMirahJvmTypes::MemberKind::COMPARISON_OP
45
+ end
46
+ end
47
+
48
+ class MathIntrinsic < Intrinsic
49
+ def accept(visitor, expression)
50
+ visitor.visitMath(self, expression)
51
+ end
52
+
53
+ def kind
54
+ Java::OrgMirahJvmTypes::MemberKind::MATH_OP
55
+ end
38
56
  end
39
57
 
40
58
  class Number < PrimitiveType
@@ -56,6 +74,13 @@ module Mirah::JVM::Types
56
74
  delegate = type.intrinsics[name][args]
57
75
  if delegate.kind_of?(ComparisonIntrinsic)
58
76
  add_method(name, args, ComparisonIntrinsic.new(type, name, delegate.op, args))
77
+ elsif delegate.kind_of?(MathIntrinsic)
78
+ method = MathIntrinsic.new(self, name, args, return_type) do |compiler, call, expression|
79
+ if expression
80
+ delegate.call(compiler, call, expression)
81
+ end
82
+ end
83
+ add_method(name, args, method)
59
84
  else
60
85
  add_method(name, args, return_type) do |compiler, call, expression|
61
86
  if expression
@@ -117,7 +142,8 @@ module Mirah::JVM::Types
117
142
  end
118
143
 
119
144
  def math_operator(name, op)
120
- add_method(name, [math_type], math_type) do |compiler, call, expression|
145
+ args = [math_type]
146
+ method = MathIntrinsic.new(self, name, args, math_type) do |compiler, call, expression|
121
147
  if expression
122
148
  # Promote the target or the argument if necessary
123
149
  convert_args(compiler,
@@ -126,6 +152,7 @@ module Mirah::JVM::Types
126
152
  compiler.method.send "#{prefix}#{op}"
127
153
  end
128
154
  end
155
+ add_method(name, args, method)
129
156
  add_delegates(name)
130
157
  end
131
158
 
@@ -153,9 +180,5 @@ module Mirah::JVM::Types
153
180
  unary_operator('-@', :neg)
154
181
  unary_operator('+@', nil)
155
182
  end
156
-
157
- def box(builder)
158
- builder.invokestatic box_type, "valueOf", [box_type, math_type]
159
- end
160
183
  end
161
184
  end
@@ -1,15 +1,30 @@
1
+ # Copyright (c) 2010-2013 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
+
1
16
  module Mirah
2
17
  module JVM
3
18
  module Types
4
19
  class PrimitiveType < Type
5
20
  WIDENING_CONVERSIONS = {
6
- 'byte' => ['byte', 'short', 'int', 'long', 'float', 'double'],
7
- 'short' => ['short', 'int', 'long', 'float', 'double'],
8
- 'char' => ['char', 'int', 'long', 'float', 'double'],
9
- 'int' => ['int', 'long', 'float', 'double'],
10
- 'long' => ['long', 'float', 'double'],
11
- 'float' => ['float', 'double'],
12
- 'double' => ['double']
21
+ 'byte' => ['byte', 'short', 'int', 'long', 'float', 'double', 'java.lang.Byte', 'java.lang.Object'],
22
+ 'short' => ['short', 'int', 'long', 'float', 'double', 'java.lang.Short', 'java.lang.Object'],
23
+ 'char' => ['char', 'int', 'long', 'float', 'double', 'java.lang.Character', 'java.lang.Object'],
24
+ 'int' => ['int', 'long', 'float', 'double','java.lang.Integer', 'java.lang.Object'],
25
+ 'long' => ['long', 'float', 'double', 'java.lang.Long', 'java.lang.Object'],
26
+ 'float' => ['float', 'double', 'java.lang.Float', 'java.lang.Object'],
27
+ 'double' => ['double', 'java.lang.Double', 'java.lang.Object']
13
28
  }
14
29
 
15
30
  def initialize(types, type, wrapper)
@@ -35,6 +50,7 @@ module Mirah
35
50
 
36
51
  def convertible_to?(type)
37
52
  return true if type == self
53
+ return false if type.array?
38
54
  widening_conversions = WIDENING_CONVERSIONS[self.name]
39
55
  widening_conversions && widening_conversions.include?(type.name)
40
56
  end
@@ -42,6 +58,18 @@ module Mirah
42
58
  def superclass
43
59
  nil
44
60
  end
61
+
62
+ def wrapper_name
63
+ @wrapper.java_class.name
64
+ end
65
+
66
+ def box_type
67
+ @type_system.type(nil, wrapper_name)
68
+ end
69
+
70
+ def box(builder)
71
+ builder.invokestatic box_type, "valueOf", [box_type, self]
72
+ end
45
73
  end
46
74
  end
47
75
  end
@@ -27,10 +27,11 @@ module Mirah::JVM::Types
27
27
  java_import 'javax.lang.model.element.Element'
28
28
  java_import 'javax.lang.model.type.TypeKind'
29
29
  java_import 'javax.lang.model.type.TypeMirror'
30
- java_import 'com.sun.tools.javac.model.JavacElements'
31
30
  java_import 'javax.lang.model.util.ElementScanner6'
32
31
  java_import 'javax.lang.model.element.AnnotationValueVisitor'
32
+ java_import 'com.sun.tools.javac.model.JavacElements'
33
33
  rescue
34
+ # must be after Java 7-15
34
35
  end
35
36
 
36
37
  if defined?(JavacElements)
@@ -81,10 +82,10 @@ module Mirah::JVM::Types
81
82
 
82
83
  def classpath
83
84
  options = [
84
- '-classpath', Mirah::AST.type_factory.classpath
85
+ '-classpath', @type_factory.classpath
85
86
  ]
86
- if Mirah::AST.type_factory.bootclasspath
87
- options << '-bootclasspath' << Mirah::AST.type_factory.bootclasspath
87
+ if @type_factory.bootclasspath
88
+ options << '-bootclasspath' << @type_factory.bootclasspath
88
89
  end
89
90
  options
90
91
  end
@@ -262,8 +263,12 @@ module Mirah::JVM::Types
262
263
  end
263
264
 
264
265
  def self.load(file, factory)
265
- parser = JavaSourceParser.new(file, factory)
266
- parser.parse
266
+ if defined? JavacElements
267
+ parser = JavaSourceParser.new(file, factory)
268
+ parser.parse
269
+ end
270
+ rescue TypeError
271
+ # 1.6.8 on Java 7, don't use source mirror
267
272
  end
268
273
  end
269
274
  end
@@ -4,6 +4,7 @@ module Mirah
4
4
  class Type
5
5
  java_import 'org.mirah.typer.ErrorType'
6
6
  java_import 'org.mirah.typer.SpecialType'
7
+ java_import 'org.mirah.typer.InlineCode'
7
8
  java_import 'org.mirah.typer.ResolvedType'
8
9
 
9
10
  class SpecialType
@@ -16,6 +17,18 @@ module Mirah
16
17
  include Mirah::Logging::Logged
17
18
 
18
19
  include ResolvedType
20
+ begin
21
+ java_import 'org.mirah.jvm.types.JVMType'
22
+ include JVMType
23
+ rescue NameError
24
+ $CLASSPATH << File.dirname(__FILE__) + '/../../../../javalib/mirah-compiler.jar'
25
+ begin
26
+ java_import 'org.mirah.jvm.types.JVMType'
27
+ include JVMType
28
+ rescue
29
+ puts "Unable to load new type interface"
30
+ end
31
+ end
19
32
 
20
33
  attr_reader :name, :type_system
21
34
  attr_writer :inner_class
@@ -36,6 +49,38 @@ module Mirah
36
49
  desc = BiteScript::Signature.class_id(self)
37
50
  BiteScript::ASM::Type.get_type(desc).class_name
38
51
  end
52
+
53
+ def internal_name
54
+ full_name.tr('.', '/')
55
+ end
56
+ def class_id
57
+ BiteScript::Signature.class_id(self)
58
+ end
59
+ def getAsmType
60
+ BiteScript::ASM::Type.get_type(class_id)
61
+ end
62
+ def isAnnotation
63
+ jvm_type ? jvm_type.annotation? : false
64
+ end
65
+ def isEnum
66
+ jvm_type ? jvm_type.enum? : false
67
+ end
68
+ def flags
69
+ flags = BiteScript::ASM::Opcodes::ACC_PUBLIC
70
+ flags |= BiteScript::ASM::Opcodes::ACC_ANNOTATION if isAnnotation
71
+ flags |= BiteScript::ASM::Opcodes::ACC_ENUM if isEnum
72
+ flags |= BiteScript::ASM::Opcodes::ACC_INTERFACE if self.interface?
73
+ flags |= BiteScript::ASM::Opcodes::ACC_ABSTRACT if self.abstract?
74
+ flags
75
+ end
76
+ def retention
77
+ if jvm_type.respond_to?(:getDeclaredAnnotation)
78
+ retention = jvm_type.getDeclaredAnnotation('java.lang.annotation.Retention')
79
+ retention.value.name
80
+ else
81
+ nil
82
+ end
83
+ end
39
84
 
40
85
  def jvm_type
41
86
  @type
@@ -74,6 +119,9 @@ module Mirah
74
119
  def primitive?
75
120
  false
76
121
  end
122
+ def isPrimitive
123
+ self.primitive?
124
+ end
77
125
 
78
126
  def interface?
79
127
  # FIXME: Don't do rescue nil. Figure out a cleaner way to handle
@@ -113,6 +161,7 @@ module Mirah
113
161
  return true if !primitive? && other.kind_of?(NullType)
114
162
  return true if other == self
115
163
  return true if other.matchesAnything
164
+ return true if other.kind_of?(InlineCode)
116
165
 
117
166
  return interface? || abstract? if other.isBlock
118
167
 
@@ -120,9 +169,12 @@ module Mirah
120
169
 
121
170
  return assignable_from?(other.ungeneric) if other.generic?
122
171
 
172
+ return other.convertible_to?(self) if other.primitive?
173
+
123
174
  assignable_from?(other.superclass) ||
124
175
  other.interfaces.any? {|i| assignable_from?(i)}
125
176
  end
177
+
126
178
  def assignableFrom(other)
127
179
  assignable_from?(other)
128
180
  end
@@ -12,6 +12,7 @@ module Mirah
12
12
  @scope = scope
13
13
  @name = name
14
14
  @node = node
15
+ @fields = {}
15
16
  raise ArgumentError, "Bad type #{name}" if self.name =~ /Java::/
16
17
  end
17
18
 
@@ -43,13 +44,18 @@ module Mirah
43
44
  end
44
45
  end
45
46
 
47
+ def abstract?
48
+ node && (node.kind_of?(InterfaceDeclaration) || node.annotated_abstract?)
49
+ end
50
+
46
51
  def define(builder)
47
52
  class_name = name.tr('.', '/')
48
- abstract = node && node.kind_of?(InterfaceDeclaration) #node.abstract
53
+ is_interface = node && node.kind_of?(InterfaceDeclaration)
49
54
  @type ||= builder.define_class(
50
55
  class_name,
51
56
  :visibility => :public,
52
- :abstract => abstract,
57
+ :abstract => abstract?,
58
+ :interface => is_interface,
53
59
  :superclass => superclass,
54
60
  :interfaces => interfaces)
55
61
  end
@@ -1,36 +1,9 @@
1
1
  module Mirah
2
2
  module AST
3
- begin
4
- java_import 'mirah.impl.MirahParser'
5
- rescue NameError
6
- $CLASSPATH << File.dirname(__FILE__) + '/../../../javalib/mirah-parser.jar'
7
- java_import 'mirah.impl.MirahParser'
8
- end
3
+ java_import 'mirah.impl.MirahParser'
9
4
  java_import 'mirah.lang.ast.StringCodeSource'
10
5
  java_import 'org.mirah.macros.Macro'
11
- java_import 'org.mirah.mmeta.ErrorHandler'
12
-
13
- class MirahErrorHandler
14
- include ErrorHandler
15
- def initialize(transformer, source)
16
- @transformer = transformer
17
- @source = source
18
- end
19
-
20
- def warning(messages, positions)
21
- print "Warning: "
22
- messages.each_with_index do |message, i|
23
- jpos = positions[i]
24
- if jpos
25
- dpos = Mirah::Transform::Transformer::JMetaPosition.new(@transformer, jpos, jpos, @source)
26
- print "#{message} at "
27
- Mirah.print_error("", dpos)
28
- else
29
- print message
30
- end
31
- end
32
- end
33
- end
6
+ java_import 'org.mirah.util.SimpleDiagnostics'
34
7
 
35
8
  def parse(src, filename='dash_e', raise_errors=false, transformer=nil)
36
9
  raise ArgumentError unless transformer
@@ -43,9 +16,14 @@ module Mirah
43
16
  #filename = transformer.tag_filename(src, filename)
44
17
  parser = MirahParser.new
45
18
  source = StringCodeSource.new(filename, src)
46
- parser.errorHandler = MirahErrorHandler.new(transformer, source)
19
+ parser.diagnostics = SimpleDiagnostics.new(true)
47
20
  begin
48
- parser.parse(source)
21
+ ast = parser.parse(source)
22
+ if parser.diagnostics.error_count > 0
23
+ puts "#{parser.diagnostics.error_count} errors, exiting"
24
+ throw :exit, 1
25
+ end
26
+ return ast
49
27
  rescue NativeException => ex
50
28
  ex.cause.printStackTrace
51
29
  raise ex
@@ -19,7 +19,7 @@ module Mirah
19
19
  begin
20
20
  java_import 'org.mirah.macros.Compiler'
21
21
  rescue NameError
22
- $CLASSPATH << File.dirname(__FILE__) + '/../../../javalib/mirah-bootstrap.jar'
22
+ # builtins not compiled yet
23
23
  end
24
24
 
25
25
  attr_reader :errors, :state
data/lib/mirah/typer.rb CHANGED
@@ -19,6 +19,7 @@ module Mirah
19
19
  module Typer
20
20
  java_import 'org.mirah.typer.Typer'
21
21
 
22
- InferenceError = Mirah::InferenceError
22
+ java_import 'org.mirah.typer.ResolvedType'
23
+ java_import 'org.mirah.typer.TypeSystem'
23
24
  end
24
25
  end
@@ -13,6 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
+ require 'mirah/jvm/compiler'
16
17
  require 'mirah/util/logging'
17
18
 
18
19
  module Mirah
@@ -55,17 +56,6 @@ module Mirah
55
56
 
56
57
  self.exit_status_code = 0
57
58
  break
58
- when '--java', '-j'
59
- if state.command == :compile
60
- require 'mirah/jvm/compiler/java_source'
61
- state.compiler_class = Mirah::JVM::Compiler::JavaSource
62
- args.shift
63
- else
64
- $stderr.puts "-j/--java flag only applies to \"compile\" mode."
65
-
66
- self.exit_status_code = 1
67
- break
68
- end
69
59
  when '--jvm'
70
60
  args.shift
71
61
  state.set_jvm_version(args.shift)
@@ -102,6 +92,13 @@ module Mirah
102
92
  when '--no-save-extensions'
103
93
  args.shift
104
94
  state.save_extensions = false
95
+ when '--new-backend', '-N'
96
+ args.shift
97
+ state.compiler_class = Mirah::JVM::Compiler::Backend
98
+ when '--new-types', '-T'
99
+ args.shift
100
+ java_import 'org.mirah.jvm.mirrors.MirrorTypeSystem'
101
+ state.type_system = MirrorTypeSystem.new
105
102
  else
106
103
  $stderr.puts "unrecognized flag: " + args[0]
107
104
 
@@ -125,14 +122,13 @@ module Mirah
125
122
  "#{$0} [flags] <files or -e SCRIPT>
126
123
  -c, --classpath PATH\tAdd PATH to the Java classpath for compilation
127
124
  --bootclasspath PATH\tSet the Java bootclasspath to PATH for compilation
128
- --cd DIR\t\tSwitch to the specified DIR befor compilation
129
- -d, --dir DIR\t\tUse DIR as the base dir for compilation, packages
125
+ --cd DIR\t\tSwitch to the specified DIR before compilation
126
+ -d, --dest DIR\t\tUse DIR as the dir to place the generated class files
130
127
  -e CODE\t\tCompile or run the inline script following -e
131
128
  \t\t\t (the class will be named \"DashE\")
132
129
  --explicit-packages\tRequire explicit 'package' lines in source
133
130
  -h, --help\t\tPrint this help message
134
131
  -I DIR\t\tAdd DIR to the Ruby load path before running
135
- -j, --java\t\tOutput .java source (compile mode [mirahc] only)
136
132
  --jvm VERSION\t\tEmit JVM bytecode targeting specified JVM
137
133
  \t\t\t version (1.4, 1.5, 1.6, 1.7)
138
134
  -p, --plugin PLUGIN\trequire 'mirah/plugin/PLUGIN' before running
@@ -0,0 +1,146 @@
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/jvm/compiler'
17
+ require 'mirah/util/logging'
18
+
19
+ module Mirah
20
+ module Util
21
+
22
+ class ArgumentProcessor
23
+ def initialize(state, args)
24
+ @state = state
25
+ @args = args
26
+ end
27
+
28
+ attr_accessor :state, :args, :exit_status_code
29
+
30
+ alias exit? exit_status_code
31
+
32
+ def process
33
+ state.args = args
34
+ while args.length > 0 && args[0] =~ /^-/
35
+ case args[0]
36
+ when '--classpath', '-c'
37
+ args.shift
38
+ state.classpath = args.shift
39
+ when '--bootclasspath'
40
+ args.shift
41
+ state.bootclasspath = args.shift
42
+ when '--cd'
43
+ args.shift
44
+ Dir.chdir(args.shift)
45
+ when '--dest', '-d'
46
+ args.shift
47
+ state.destination = File.join(File.expand_path(args.shift), '')
48
+ when '-e'
49
+ break
50
+ when '--explicit-packages'
51
+ args.shift
52
+ Mirah::AST::Script.explicit_packages = true
53
+ when '--help', '-h'
54
+ args.shift
55
+ print_help
56
+
57
+ self.exit_status_code = 0
58
+ break
59
+ when '--jvm'
60
+ args.shift
61
+ state.set_jvm_version(args.shift)
62
+ when '-I'
63
+ args.shift
64
+ $: << args.shift
65
+ when '--plugin', '-p'
66
+ args.shift
67
+ plugin = args.shift
68
+ require "mirah/plugin/#{plugin}"
69
+ when '--verbose', '-V'
70
+ Mirah::Logging::MirahLogger.level = Mirah::Logging::Level::FINE
71
+ state.verbose = true
72
+ args.shift
73
+ when '--vmodule'
74
+ args.shift
75
+ spec = args.shift
76
+ spec.split(',').each do |item|
77
+ logger, level = item.split("=")
78
+ logger = java.util.logging.Logger.getLogger(logger)
79
+ (state.loggers ||= []) << logger
80
+ level = java.util.logging.Level.parse(level)
81
+ logger.setLevel(level)
82
+ end
83
+ when '--no-color'
84
+ args.shift
85
+ Mirah::Logging::MirahHandler.formatter = Mirah::Logging::LogFormatter.new(false)
86
+ when '--version', '-v'
87
+ args.shift
88
+ print_version
89
+
90
+ self.exit_status_code = 0 if args.empty?
91
+ break
92
+ when '--no-save-extensions'
93
+ args.shift
94
+ state.save_extensions = false
95
+ when '--new-backend', '-N'
96
+ args.shift
97
+ state.compiler_class = Mirah::JVM::Compiler::Backend
98
+ when '--new-types', '-T'
99
+ args.shift
100
+ java_import 'org.mirah.jvm.mirrors.MirrorTypeSystem'
101
+ state.type_system = MirrorTypeSystem.new
102
+ else
103
+ $stderr.puts "unrecognized flag: " + args[0]
104
+
105
+ self.exit_status_code = 1
106
+ break
107
+ end
108
+ end
109
+
110
+ return if exit?
111
+
112
+ state.destination ||= File.join(File.expand_path('.'), '')
113
+ state.compiler_class ||= Mirah::JVM::Compiler::JVMBytecode
114
+ end
115
+
116
+ def print_help
117
+ puts help_message
118
+ state.help_printed = true
119
+ end
120
+
121
+ def help_message
122
+ "#{$0} [flags] <files or -e SCRIPT>
123
+ -c, --classpath PATH\tAdd PATH to the Java classpath for compilation
124
+ --bootclasspath PATH\tSet the Java bootclasspath to PATH for compilation
125
+ --cd DIR\t\tSwitch to the specified DIR before compilation
126
+ -d, --dest DIR\t\tUse DIR as the dir to place the resulting .class files
127
+ -e CODE\t\tCompile or run the inline script following -e
128
+ \t\t\t (the class will be named \"DashE\")
129
+ --explicit-packages\tRequire explicit 'package' lines in source
130
+ -h, --help\t\tPrint this help message
131
+ -I DIR\t\tAdd DIR to the Ruby load path before running
132
+ --jvm VERSION\t\tEmit JVM bytecode targeting specified JVM
133
+ \t\t\t version (1.4, 1.5, 1.6, 1.7)
134
+ -p, --plugin PLUGIN\trequire 'mirah/plugin/PLUGIN' before running
135
+ -v, --version\t\tPrint the version of Mirah to the console
136
+ -V, --verbose\t\tVerbose logging
137
+ --vmodule logger.name=LEVEL[,...]\t\tSet the Level for the specified Java loggers"
138
+ end
139
+
140
+ def print_version
141
+ puts "Mirah v#{Mirah::VERSION}"
142
+ state.version_printed = true
143
+ end
144
+ end
145
+ end
146
+ end