mirah 0.1.4-java → 0.2.0-java

Sign up to get free protection for your applications and to get access to all the features.
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