mirah 0.1.4-java → 0.2.0-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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -0
  3. data/CODE_OF_CONDUCT.md +74 -0
  4. data/History.txt +531 -0
  5. data/README.md +23 -10
  6. data/Rakefile +239 -156
  7. data/TODO.md +71 -10
  8. data/bin/mirah +1 -1
  9. data/bin/mirahc +1 -1
  10. data/dist/mirahc.jar +0 -0
  11. data/examples/bintrees.mirah +2 -2
  12. data/examples/construction.mirah +2 -2
  13. data/examples/fields.mirah +1 -1
  14. data/examples/fractal.mirah +1 -1
  15. data/examples/fractal.rb +70 -0
  16. data/examples/interfaces.mirah +1 -1
  17. data/examples/java_thing.mirah +1 -1
  18. data/examples/macros/square.mirah +3 -3
  19. data/examples/macros/square_int.mirah +3 -3
  20. data/examples/macros/string_each_char.mirah +6 -6
  21. data/examples/rosettacode/100-doors.mirah +0 -2
  22. data/examples/rosettacode/count-occurrences-of-a-substring.mirah +3 -3
  23. data/examples/rosettacode/empty-string.mirah +1 -1
  24. data/examples/rosettacode/fizz-buzz.mirah +4 -4
  25. data/examples/rosettacode/is-string-numeric.mirah +7 -7
  26. data/examples/rosettacode/palindrome.mirah +2 -2
  27. data/examples/rosettacode/reverse-a-string.mirah +1 -1
  28. data/examples/rosettacode/rot-13.mirah +1 -1
  29. data/examples/{edb.mirah → rosettacode/simple_character_math.mirah} +13 -4
  30. data/examples/rosettacode/string-case.mirah +2 -2
  31. data/examples/rosettacode/string-length.mirah +1 -1
  32. data/examples/swing.mirah +9 -14
  33. data/extensions_and_macros.md +117 -0
  34. data/lib/mirah.rb +1 -1
  35. data/lib/mirah/errors.rb +3 -1
  36. data/lib/mirah/transform/ast_ext.rb +3 -2
  37. data/lib/mirah/util/process_errors.rb +1 -2
  38. data/lib/mirah/version.rb +1 -1
  39. data/test/A.class +0 -0
  40. data/test/core/util/jvm_version_test.rb +10 -0
  41. data/test/core/util/mirah_arguments_test.rb +51 -4
  42. data/test/fixtures/cp1251_test.mirah +7 -0
  43. data/test/fixtures/org/foo/AbstractExecutorJava8.java +30 -0
  44. data/test/fixtures/org/foo/ClassWithSelfReferencingTypeParameter.java +24 -0
  45. data/test/fixtures/org/foo/InnerInterfaceClass.java +12 -0
  46. data/test/fixtures/org/foo/IntAnno.class +0 -0
  47. data/test/fixtures/org/foo/TypeFixtureJava8.java +10 -0
  48. data/test/fixtures/utf8_test.mirah +7 -0
  49. data/test/jvm/access_levels_test.rb +31 -0
  50. data/test/jvm/annotations_test.rb +3 -6
  51. data/test/jvm/blocks_test.rb +303 -120
  52. data/test/jvm/cast_test.rb +123 -50
  53. data/test/jvm/closure_test.rb +242 -0
  54. data/test/jvm/constructors_test.rb +1 -3
  55. data/test/jvm/example_test.rb +6 -2
  56. data/test/jvm/extensions/array_extensions_test.rb +181 -0
  57. data/test/jvm/extensions/collection_extensions_test.rb +195 -0
  58. data/test/jvm/{enumerable_test.rb → extensions/enumerable_test.rb} +81 -13
  59. data/test/jvm/extensions/hash_extensions_test.rb +56 -0
  60. data/test/jvm/extensions/list_extensions_test.rb +143 -0
  61. data/test/jvm/extensions/lock_extensions_test.rb +43 -0
  62. data/test/jvm/{numeric_extensions_test.rb → extensions/numeric_extensions_test.rb} +0 -0
  63. data/test/jvm/extensions/numeric_operators_test.rb +86 -0
  64. data/test/jvm/extensions/object_extensions_test.rb +122 -0
  65. data/test/jvm/{string_builder_extensions_test.rb → extensions/string_builder_extensions_test.rb} +0 -0
  66. data/test/jvm/{string_extensions_test.rb → extensions/string_extensions_test.rb} +57 -4
  67. data/test/jvm/generics_test.rb +14 -6
  68. data/test/jvm/import_test.rb +38 -1
  69. data/test/jvm/interface_test.rb +17 -0
  70. data/test/jvm/jvm_commands_test.rb +9 -0
  71. data/test/jvm/jvm_compiler_test.rb +568 -43
  72. data/test/jvm/macros_test.rb +343 -19
  73. data/test/jvm/main_method_test.rb +1 -3
  74. data/test/jvm/new_backend_test_helper.rb +54 -7
  75. data/test/jvm/rescue_test.rb +20 -5
  76. data/test/jvm/static_fields_test.rb +52 -10
  77. data/test/jvm/{mirror_compilation_test_helper.rb → string_test.rb} +10 -9
  78. data/test/jvm/varargs_test.rb +6 -16
  79. data/test/mirrors/base_type_test.rb +20 -7
  80. data/test/mirrors/bytecode_mirror_test.rb +8 -3
  81. data/test/mirrors/generics_test.rb +89 -10
  82. data/test/mirrors/member_test.rb +1 -1
  83. data/test/mirrors/method_lookup_test.rb +10 -3
  84. data/test/mirrors/mirrors_test.rb +20 -20
  85. data/test/mirrors/simple_async_mirror_loader_test.rb +1 -1
  86. data/test/mirrors/simple_mirror_loader_test.rb +1 -1
  87. data/test/newMirahClass$Closure2.class +0 -0
  88. data/test/newMirahClass.class +0 -0
  89. data/test/test_helper.rb +8 -1
  90. metadata +31 -16
  91. data/bin/bundler +0 -16
  92. data/bin/rake +0 -16
  93. data/examples/ant/example-build.xml~ +0 -7
  94. data/examples/test.edb +0 -9
  95. data/lib/mirah/compiler.rb +0 -67
  96. data/lib/mirah/parser.rb +0 -224
  97. data/lib/mirah/util/delegate.rb +0 -65
  98. data/test/jvm/list_extensions_test.rb +0 -23
data/TODO.md CHANGED
@@ -1,3 +1,14 @@
1
+ - missing import should always show up in the summary of errors. eg
2
+
3
+ ERROR import X
4
+ ERROR fn X(1) doesn't exist
5
+
6
+ ERROR can't find type for import X
7
+
8
+
9
+
10
+ -- if a macro has a bug, the stacktrace is ugly
11
+
1
12
 
2
13
 
3
14
  The TODO list of DOOM
@@ -31,6 +42,8 @@ Dist
31
42
 
32
43
  Compiler Internals Improvements
33
44
  ======================
45
+ - add generic warnings / error message facility
46
+ -- right now we've got errors and they're ok. but it'd be better if we had something better.
34
47
  - make Mirror type systems addDefaultImports more obvious
35
48
  - faster mirah compiler build: src => class is tricky, I could make src => jar, jar => jar tho
36
49
  - switch to minitest
@@ -51,6 +64,7 @@ Compiler Internals Improvements
51
64
  - clean up javalib dir
52
65
  - don't use 1.5 as java compile target
53
66
  - make it obvious when ASTs have been dropped during macro expansion
67
+ - add timing to phases
54
68
 
55
69
  - break compiler into phases
56
70
  ---------------
@@ -62,15 +76,19 @@ Compiler Internals Improvements
62
76
  - load type systems
63
77
  - load types for System, & predefs maybe?
64
78
  - load scoped macros / extensions
79
+
65
80
  # typer
66
81
  - visit script body / class bodies, skipping method bodies
67
82
  - compile macros
68
83
  - visit method bodies
84
+
69
85
  # finishs resolving typer wip
70
86
  - resolve proxies
71
87
  - change captured locals into binding fields
88
+
72
89
  # clean up / compiler prep
73
90
  - clean ast up
91
+
74
92
  # compile
75
93
 
76
94
  - maybe after parse, check built files to see if they need to be rebuilt, and ignore them otherwise
@@ -88,6 +106,10 @@ Warnings / Logging
88
106
 
89
107
  - improve duplicate name/sig error when multiple method defs w/ same sig mirah#273
90
108
  - code sources from macro expansion should know both the macro location and the invoke location and report both on errors so that users know where to look to debug
109
+ - -v should only show the version, it currently says no main method too. :/
110
+ - add -Werror where warnings become errors
111
+ - make block mirror type string a little nicer somehow
112
+ eg Can't find method java.util.concurrent.locks.ReentrantLock.synchronize(org.mirah.jvm.mirrors.BlockType)
91
113
 
92
114
  Parser
93
115
  ======
@@ -97,25 +119,53 @@ Parser
97
119
 
98
120
  Features
99
121
  ==========
122
+ - each macro for Maps
100
123
  - Reflection Macros
101
124
  - AST formatter that converts back to something the parser can parse
102
125
  - default toString?
103
126
  - default hashCode / equals
104
- - change == to use equals
105
127
  - default val/no type that defers to indy
106
-
107
- eg
108
- def foo(x: int, y=1)
109
- end
110
- should work
111
-
128
+ eg
129
+ def foo(x: int, y=1)
130
+ end
131
+ should work
132
+ - allow defining equals using def ==(other)
112
133
  - attr_reader/et al as varargs instead of just Hash. It would mean that the type info would have to come from somewhere else
113
134
  - goto: headius wants it
114
135
  - synchronize intrinsic ala java's
115
136
  - file scoped macros / extensions
116
137
  - extension syntax
117
- - move macro / mirahc anno to separate class dir to improve javac interop
118
138
  - public / private / protected / package scope helpers
139
+
140
+
141
+ # test cases
142
+ # - method w/ no modifier, modifier statement, method
143
+ # - modifier statement, method
144
+ # - modifier statement, method, same modifier statement, method
145
+ # - modifier statement, method, different modifier statement, method
146
+ # - modifier statement, method containing closure w/ mdefs
147
+ # - modifier fn w/ undefined method
148
+ # - mdef, modifier fn mname
149
+ # - modifier statement, modifiered method
150
+ # - modifier statement, differently modifiered method
151
+ # - modifier statement, modifiered method, unmodifiered method
152
+ # - modifier statement, differently modifiered method, unmodifiered method
153
+
154
+ # pub
155
+ # def a
156
+ # macro def self.public(mdef: MethodDefinition)
157
+ # set annotation on it directly
158
+
159
+ # macro def self.public(method_names: NodeList<Symbol> or something)
160
+ # find methods w/ those names, set anno on them directly
161
+ # if they don't exist, blow up
162
+ #macro def self.public()
163
+ # options
164
+ # 1) grab typer & set current scope's default access *** best most likely
165
+ # 2) don't expand here, instead throw into a queue, expand all at end
166
+ # 3) try to infer defs needed to do it
167
+ #end
168
+
119
169
  - subclass access to super protected fields w/ @syntax
120
170
  - (0) add a gets function like Ruby
121
171
  - (2) a more "batteries included" set of imports
@@ -136,10 +186,16 @@ should work
136
186
  - understand Java 8 default methods
137
187
  - default args on non-last position params. eg when a method takes a block(read: functional interface), it should be allowed to have default args before the block arg.
138
188
  - do jruby style method lookup
189
+ - add env var hash constant ala Ruby's ENV.
190
+ - Thread extensions:
191
+ Thread.start {}, which does t=Thread.new{};t.start;t
192
+ - macro for typecheck & cast. replace the x.kind_of? Y; Y(Object(x))
139
193
 
140
194
  Bugs
141
195
  ==========
142
-
196
+ - a[-1] should work
197
+ - array ext size
198
+ - make sure that macro lookup looks at super classes
143
199
  - "foo: #{x || y} acts weird", my guess is that interpolation doesn't generate the right code sometimes
144
200
  - lambda's can't exist in methods! !! by which I mean that they can't close over things in methods. You can have them there, they just don't close. >:[]
145
201
  - parser can't deal w/ unquotes in hash literals when key is unquote
@@ -169,6 +225,11 @@ class C
169
225
  ^^^^^^^^^
170
226
 
171
227
 
228
+ - constants are not referrable outside the defining scope :/ because they are private
229
+ - referring to classes as constants causes crashes
230
+ java -jar dist/mirahc.jar -cp test/fixtures/ -e 'puts org::foo::A' blows up w/ a asm error
231
+ java -jar dist/mirahc.jar -cp test/fixtures/ -e 'puts org::foo::A.class' doesn't
232
+
172
233
  Libraries
173
234
  ===============
174
235
  - delegation macro library
@@ -341,4 +402,4 @@ end
341
402
 
342
403
 
343
404
  compile rake task doesn't fail, if it doesn't work for some things, it goes on anyway
344
- in generics. hmm
405
+ in generics. hmm
data/bin/mirah CHANGED
@@ -24,4 +24,4 @@ rescue LoadError
24
24
  require 'mirah'
25
25
  end
26
26
 
27
- Mirah.run(*ARGV)
27
+ org::mirah::tool::RunCommand.main(ARGV)
data/bin/mirahc CHANGED
@@ -24,4 +24,4 @@ rescue LoadError
24
24
  require 'mirah'
25
25
  end
26
26
 
27
- Mirah.compile(*ARGV)
27
+ org::mirah::tool::Mirahc.main(ARGV)
Binary file
@@ -14,7 +14,7 @@
14
14
  # limitations under the License.
15
15
 
16
16
  class BinaryTrees
17
- def self.main(args:String[])
17
+ def self.main(args:String[]):void
18
18
  n = 0
19
19
  n = Integer.parseInt(args[0]) if args.length > 0
20
20
 
@@ -72,7 +72,7 @@ class TreeNode
72
72
 
73
73
  def itemCheck
74
74
  # if necessary deallocate here
75
- if @left == nil
75
+ if @left.nil?
76
76
  @item
77
77
  else
78
78
  @item + @left.itemCheck - @right.itemCheck
@@ -13,8 +13,8 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- import "java.lang.StringBuffer"
17
- import "java.util.ArrayList"
16
+ import java.lang.StringBuffer
17
+ import java.util.ArrayList
18
18
 
19
19
  list = ArrayList.new
20
20
  sb = StringBuffer.new("Hello")
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- import 'java.util.ArrayList'
16
+ import java.util.ArrayList
17
17
 
18
18
  class Bar
19
19
  def initialize
@@ -64,7 +64,7 @@ end
64
64
  i = 0
65
65
  while i < 10
66
66
  start = System.currentTimeMillis
67
- run
67
+ run()
68
68
  puts "Time: #{(System.currentTimeMillis - start) / 1000.0}"
69
69
  i += 1
70
70
  end
@@ -0,0 +1,70 @@
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
+ def run
17
+ puts "Rendering"
18
+ y = -39.0
19
+ while y <= 39.0
20
+ puts
21
+ x = -39.0
22
+ while x <= 39.0
23
+ i = iterate(x/40.0,y/40.0)
24
+ if (i == 0)
25
+ print "*"
26
+ else
27
+ print " "
28
+ end
29
+ x += 1
30
+ end
31
+ y += 1
32
+ end
33
+ puts
34
+ end
35
+
36
+ def iterate(x:double,y:double)
37
+ cr = y-0.5
38
+ ci = x
39
+ zi = 0.0
40
+ zr = 0.0
41
+ i = 0
42
+
43
+ result = 0
44
+ while true
45
+ i += 1
46
+ temp = zr * zi
47
+ zr2 = zr * zr
48
+ zi2 = zi * zi
49
+ zr = zr2 - zi2 + cr
50
+ zi = temp + temp + ci
51
+ if (zi2 + zr2 > 16)
52
+ result = i
53
+ break
54
+ end
55
+ if (i > 1000)
56
+ result = 0
57
+ break
58
+ end
59
+ end
60
+
61
+ result
62
+ end
63
+
64
+ i = 0
65
+ while i < 10
66
+ start = System.currentTimeMillis
67
+ run()
68
+ puts "Time: #{(System.currentTimeMillis - start) / 1000.0}"
69
+ i += 1
70
+ end
@@ -17,7 +17,7 @@ import java.util.List
17
17
 
18
18
  interface Printer do
19
19
  def printAll(a:List)
20
- returns void
20
+ void
21
21
  end
22
22
  end
23
23
 
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- import "java.lang.System"
16
+ import java.lang.System
17
17
 
18
18
  def foo
19
19
  home = System.getProperty "java.home"
@@ -16,9 +16,9 @@
16
16
 
17
17
 
18
18
  macro def sqrt(input)
19
- quote do
20
- Math.sqrt(Integer.parseInt(`input`))
21
- end
19
+ quote do
20
+ Math.sqrt(Integer.parseInt(`input`))
21
+ end
22
22
  end
23
23
 
24
24
  number = '64'
@@ -16,9 +16,9 @@
16
16
 
17
17
 
18
18
  macro def sqrt(input)
19
- quote do
20
- Math.sqrt(`input`)
21
- end
19
+ quote do
20
+ Math.sqrt(`input`)
21
+ end
22
22
  end
23
23
 
24
24
  number = 64
@@ -15,14 +15,14 @@
15
15
 
16
16
 
17
17
  macro def eachChar(value, block:Block)
18
- quote {
19
- `value`.toCharArray.each do |`block.arguments`|
20
- `block.body`
21
- end
22
- }
18
+ quote do
19
+ `value`.toCharArray.each do |`block.arguments`|
20
+ `block.body`
21
+ end
22
+ end
23
23
  end
24
24
 
25
25
  eachChar('laat de leeeuw niet in zijn hempie staan') do | my_char |
26
- puts my_char
26
+ puts my_char
27
27
  end
28
28
 
@@ -17,8 +17,6 @@
17
17
  import java.util.ArrayList
18
18
 
19
19
  class Door
20
- :state
21
-
22
20
  def initialize
23
21
  @state=false
24
22
  end
@@ -18,7 +18,7 @@ import java.util.regex.Pattern
18
18
  import java.util.regex.Matcher
19
19
 
20
20
  #The "remove and count the difference" method
21
- def count_substring(pattern:string, source:string)
21
+ def count_substring(pattern:String, source:String)
22
22
  (source.length() - source.replace(pattern, "").length()) / pattern.length()
23
23
  end
24
24
 
@@ -28,7 +28,7 @@ puts count_substring("a*b", "abaabba*bbaba*bbab") # ==> 2
28
28
 
29
29
 
30
30
  # The "split and count" method
31
- def count_substring2(pattern:string, source:string)
31
+ def count_substring2(pattern:String, source:String)
32
32
  # the result of split() will contain one more element than the delimiter
33
33
  # the "-1" second argument makes it not discard trailing empty strings
34
34
  source.split(Pattern.quote(pattern), -1).length - 1
@@ -40,7 +40,7 @@ puts count_substring2("a*b", "abaabba*bbaba*bbab") # ==> 2
40
40
 
41
41
 
42
42
  # This method does a match and counts how many times it matches
43
- def count_substring3(pattern:string, source:string)
43
+ def count_substring3(pattern:String, source:String)
44
44
  result = 0
45
45
  Matcher m = Pattern.compile(Pattern.quote(pattern)).matcher(source);
46
46
  while (m.find())
@@ -19,6 +19,6 @@ empty_string2 = String.new
19
19
 
20
20
  puts "empty string is empty" if empty_string1.isEmpty()
21
21
  puts "empty string has no length" if empty_string2.length() == 0
22
- puts "empty string is not nil" unless empty_string1 == nil
22
+ puts "empty string is not nil" unless empty_string1.nil?
23
23
 
24
24
 
@@ -15,10 +15,10 @@
15
15
 
16
16
 
17
17
  1.upto(100) do |n|
18
- print "Fizz" if a = ((n % 3) == 0)
19
- print "Buzz" if b = ((n % 5) == 0)
20
- print n unless (a || b)
21
- print "\n"
18
+ print "Fizz" if a = ((n % 3) == 0)
19
+ print "Buzz" if b = ((n % 5) == 0)
20
+ print n unless (a || b)
21
+ print "\n"
22
22
  end
23
23
 
24
24
  # a little more straight forward
@@ -19,7 +19,7 @@ import java.util.Scanner
19
19
 
20
20
  # this first example relies on catching an exception,
21
21
  # which is bad style and poorly performing in Java
22
- def is_numeric?(s:string)
22
+ def is_numeric?(s:String)
23
23
  begin
24
24
  Double.parseDouble(s)
25
25
  return true
@@ -40,7 +40,7 @@ puts '1.2.3 is not numeric' unless is_numeric?('1.2.3')
40
40
 
41
41
 
42
42
  # check every element of the string
43
- def is_numeric2?(s: string)
43
+ def is_numeric2?(s: String)
44
44
  if (s == nil || s.isEmpty())
45
45
  return false
46
46
  end
@@ -79,7 +79,7 @@ puts '1.2.3 is not numeric' unless is_numeric2?('1.2.3')
79
79
 
80
80
 
81
81
  # use a regular expression
82
- def is_numeric3?(s:string)
82
+ def is_numeric3?(s:String)
83
83
  s == nil || s.matches("[-+]?\\d+(\\.\\d+)?")
84
84
  end
85
85
 
@@ -98,8 +98,8 @@ puts '1.2.3 is not numeric' unless is_numeric3?('1.2.3')
98
98
  # (a more robust solution). If, after parsing, the parse position is at
99
99
  # the end of the string, we can deduce that the entire string was a
100
100
  # valid number.
101
- def is_numeric4?(s:string)
102
- return false if s == nil
101
+ def is_numeric4?(s:String)
102
+ return false if s.nil?
103
103
  formatter = NumberFormat.getInstance()
104
104
  pos = ParsePosition.new(0)
105
105
  formatter.parse(s, pos)
@@ -123,8 +123,8 @@ puts '1.2.3 is not numeric' unless is_numeric4?('1.2.3')
123
123
  # shorts, bytes, doubles, floats, BigIntegers, and BigDecimals as well
124
124
  # as methods for integral types where you may input a base/radix other than
125
125
  # 10 (10 is the default, which can be changed using the useRadix method).
126
- def is_numeric5?(s:string)
127
- return false if s == nil
126
+ def is_numeric5?(s:String)
127
+ return false if s.nil?
128
128
  Scanner sc = Scanner.new(s)
129
129
  sc.hasNextDouble()
130
130
  end