opal 0.6.3 → 0.7.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (221) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.spectator +2 -0
  4. data/.spectator-mspec +3 -0
  5. data/.travis.yml +8 -11
  6. data/CHANGELOG.md +33 -0
  7. data/CONTRIBUTING.md +8 -43
  8. data/Gemfile +15 -4
  9. data/Guardfile +77 -0
  10. data/README.md +15 -9
  11. data/Rakefile +36 -12
  12. data/benchmarks/operators.rb +11 -0
  13. data/bin/opal +10 -13
  14. data/bin/opal-build +4 -4
  15. data/bin/opal-mspec +10 -0
  16. data/bin/opal-repl +4 -3
  17. data/examples/sinatra/Gemfile +1 -1
  18. data/examples/sinatra/config.ru +3 -3
  19. data/lib/mspec/opal/main.rb.erb +2 -2
  20. data/lib/mspec/opal/rake_task.rb +31 -24
  21. data/lib/mspec/opal/runner.rb +18 -1
  22. data/lib/mspec/opal/sprockets.js +17 -0
  23. data/lib/opal.rb +1 -34
  24. data/lib/opal/builder.rb +92 -58
  25. data/lib/opal/builder_processors.rb +165 -0
  26. data/lib/opal/cli.rb +85 -144
  27. data/lib/opal/cli_options.rb +136 -90
  28. data/lib/opal/cli_runners.rb +10 -0
  29. data/lib/opal/cli_runners/nodejs.rb +56 -0
  30. data/lib/opal/cli_runners/phantom.js +35 -0
  31. data/lib/opal/cli_runners/phantomjs.rb +28 -0
  32. data/lib/opal/cli_runners/server.rb +54 -0
  33. data/lib/opal/compiler.rb +35 -16
  34. data/lib/opal/erb.rb +29 -15
  35. data/lib/opal/hike_path_finder.rb +18 -0
  36. data/lib/opal/nodes.rb +1 -0
  37. data/lib/opal/nodes/call.rb +107 -26
  38. data/lib/opal/nodes/call_special.rb +31 -6
  39. data/lib/opal/nodes/class.rb +2 -2
  40. data/lib/opal/nodes/constants.rb +5 -20
  41. data/lib/opal/nodes/def.rb +4 -4
  42. data/lib/opal/nodes/defined.rb +3 -3
  43. data/lib/opal/nodes/definitions.rb +1 -1
  44. data/lib/opal/nodes/for.rb +35 -0
  45. data/lib/opal/nodes/helpers.rb +2 -2
  46. data/lib/opal/nodes/iter.rb +3 -3
  47. data/lib/opal/nodes/literal.rb +10 -2
  48. data/lib/opal/nodes/masgn.rb +2 -2
  49. data/lib/opal/nodes/module.rb +2 -2
  50. data/lib/opal/nodes/scope.rb +1 -0
  51. data/lib/opal/nodes/singleton_class.rb +2 -2
  52. data/lib/opal/nodes/super.rb +2 -2
  53. data/lib/opal/nodes/top.rb +30 -3
  54. data/lib/opal/parser.rb +15 -1
  55. data/lib/opal/parser/grammar.rb +2571 -2452
  56. data/lib/opal/parser/grammar.y +37 -5
  57. data/lib/opal/parser/keywords.rb +2 -0
  58. data/lib/opal/parser/lexer.rb +21 -11
  59. data/lib/opal/path_reader.rb +28 -0
  60. data/lib/opal/paths.rb +38 -0
  61. data/lib/opal/source_map.rb +32 -15
  62. data/lib/opal/sprockets/environment.rb +9 -2
  63. data/lib/opal/sprockets/erb.rb +1 -2
  64. data/lib/opal/sprockets/path_reader.rb +34 -0
  65. data/lib/opal/sprockets/processor.rb +40 -39
  66. data/lib/opal/sprockets/server.rb +47 -33
  67. data/lib/opal/version.rb +1 -1
  68. data/opal.gemspec +10 -5
  69. data/opal/README.md +6 -0
  70. data/opal/corelib/array.rb +36 -4
  71. data/opal/corelib/array/inheritance.rb +6 -6
  72. data/opal/corelib/basic_object.rb +9 -9
  73. data/opal/corelib/boolean.rb +1 -1
  74. data/opal/corelib/class.rb +12 -12
  75. data/opal/corelib/dir.rb +20 -0
  76. data/opal/corelib/enumerable.rb +42 -42
  77. data/opal/corelib/enumerator.rb +1 -1
  78. data/opal/corelib/error.rb +2 -2
  79. data/opal/corelib/file.rb +56 -0
  80. data/opal/corelib/hash.rb +5 -5
  81. data/opal/corelib/helpers.rb +3 -3
  82. data/opal/corelib/io.rb +13 -10
  83. data/opal/corelib/kernel.rb +44 -68
  84. data/opal/corelib/method.rb +1 -1
  85. data/opal/corelib/module.rb +89 -114
  86. data/opal/corelib/nil_class.rb +1 -1
  87. data/opal/corelib/numeric.rb +27 -23
  88. data/opal/corelib/proc.rb +5 -5
  89. data/opal/corelib/range.rb +8 -4
  90. data/opal/corelib/regexp.rb +5 -5
  91. data/opal/corelib/runtime.js +589 -272
  92. data/opal/corelib/string.rb +52 -37
  93. data/opal/corelib/string/inheritance.rb +5 -5
  94. data/opal/corelib/time.rb +102 -52
  95. data/opal/corelib/variables.rb +3 -3
  96. data/opal/opal.rb +2 -0
  97. data/package.json +9 -0
  98. data/spec/filters/bugs/array.rb +0 -6
  99. data/spec/filters/bugs/language.rb +4 -0
  100. data/spec/filters/bugs/numeric.rb +7 -6
  101. data/spec/filters/bugs/opal.rb +2 -0
  102. data/spec/filters/bugs/regexp.rb +4 -0
  103. data/spec/filters/bugs/string.rb +0 -7
  104. data/spec/filters/bugs/stringscanner.rb +4 -1
  105. data/spec/filters/unsupported/private_methods.rb +2 -0
  106. data/spec/lib/builder_processors_spec.rb +27 -0
  107. data/spec/lib/builder_spec.rb +66 -0
  108. data/spec/{cli → lib}/cli_spec.rb +60 -5
  109. data/spec/{cli → lib}/compiler_spec.rb +66 -5
  110. data/spec/{cli → lib}/dependency_resolver_spec.rb +1 -1
  111. data/spec/lib/fixtures/no_requires.rb +1 -0
  112. data/spec/{cli → lib}/fixtures/opal_file.rb +0 -0
  113. data/spec/lib/fixtures/require_tree_test.rb +3 -0
  114. data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
  115. data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
  116. data/spec/lib/fixtures/requires.rb +7 -0
  117. data/spec/{cli → lib}/fixtures/sprockets_file.js.rb +0 -0
  118. data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
  119. data/spec/lib/hike_path_finder_spec.rb +23 -0
  120. data/spec/{cli → lib}/lexer_spec.rb +1 -1
  121. data/spec/{cli → lib}/parser/alias_spec.rb +1 -1
  122. data/spec/{cli → lib}/parser/and_spec.rb +1 -1
  123. data/spec/{cli → lib}/parser/attrasgn_spec.rb +1 -1
  124. data/spec/{cli → lib}/parser/begin_spec.rb +1 -1
  125. data/spec/{cli → lib}/parser/block_spec.rb +1 -1
  126. data/spec/{cli → lib}/parser/break_spec.rb +1 -1
  127. data/spec/{cli → lib}/parser/call_spec.rb +1 -1
  128. data/spec/{cli → lib}/parser/class_spec.rb +1 -1
  129. data/spec/{cli → lib}/parser/comments_spec.rb +1 -1
  130. data/spec/{cli → lib}/parser/def_spec.rb +1 -1
  131. data/spec/{cli → lib}/parser/if_spec.rb +1 -1
  132. data/spec/{cli → lib}/parser/iter_spec.rb +1 -1
  133. data/spec/{cli → lib}/parser/lambda_spec.rb +1 -1
  134. data/spec/{cli → lib}/parser/literal_spec.rb +1 -1
  135. data/spec/{cli → lib}/parser/masgn_spec.rb +1 -1
  136. data/spec/{cli → lib}/parser/module_spec.rb +1 -1
  137. data/spec/{cli → lib}/parser/not_spec.rb +1 -1
  138. data/spec/{cli → lib}/parser/op_asgn1_spec.rb +1 -1
  139. data/spec/{cli → lib}/parser/op_asgn2_spec.rb +1 -1
  140. data/spec/{cli → lib}/parser/or_spec.rb +1 -1
  141. data/spec/{cli → lib}/parser/return_spec.rb +1 -1
  142. data/spec/{cli → lib}/parser/sclass_spec.rb +1 -1
  143. data/spec/{cli → lib}/parser/string_spec.rb +8 -1
  144. data/spec/{cli → lib}/parser/super_spec.rb +1 -1
  145. data/spec/lib/parser/unary_spec.rb +48 -0
  146. data/spec/{cli → lib}/parser/undef_spec.rb +1 -1
  147. data/spec/{cli → lib}/parser/unless_spec.rb +1 -1
  148. data/spec/{cli → lib}/parser/variables_spec.rb +1 -1
  149. data/spec/{cli → lib}/parser/while_spec.rb +1 -1
  150. data/spec/{cli → lib}/parser/yield_spec.rb +1 -1
  151. data/spec/lib/path_reader_spec.rb +24 -0
  152. data/spec/lib/shared/path_finder_shared.rb +19 -0
  153. data/spec/lib/shared/path_reader_shared.rb +31 -0
  154. data/spec/lib/spec_helper.rb +9 -0
  155. data/spec/lib/sprockets/environment_spec.rb +30 -0
  156. data/spec/{cli → lib}/sprockets/erb_spec.rb +1 -1
  157. data/spec/lib/sprockets/path_reader_spec.rb +25 -0
  158. data/spec/{cli → lib}/sprockets/processor_spec.rb +9 -2
  159. data/spec/lib/sprockets/server_spec.rb +20 -0
  160. data/spec/opal/compiler/irb_spec.rb +11 -11
  161. data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
  162. data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
  163. data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
  164. data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
  165. data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
  166. data/spec/opal/core/kernel/require_tree_spec.rb +7 -0
  167. data/spec/opal/core/kernel/respond_to_spec.rb +2 -2
  168. data/spec/opal/core/runtime/method_missing_spec.rb +19 -0
  169. data/spec/opal/core/source_map_spec.rb +2 -2
  170. data/spec/opal/core/string_spec.rb +11 -0
  171. data/spec/opal/stdlib/erb/erb_spec.rb +0 -1
  172. data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
  173. data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
  174. data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
  175. data/spec/rubyspecs +54 -11
  176. data/spec/spec_helper.rb +18 -3
  177. data/spec/support/mspec_rspec_adapter.rb +33 -0
  178. data/spec/{cli/spec_helper.rb → support/parser_helpers.rb} +10 -10
  179. data/stdlib/README.md +3 -0
  180. data/stdlib/benchmark.rb +10 -0
  181. data/stdlib/date.rb +2 -2
  182. data/stdlib/dir.rb +1 -5
  183. data/stdlib/file.rb +1 -7
  184. data/stdlib/json.rb +10 -1
  185. data/stdlib/native.rb +5 -5
  186. data/stdlib/nodejs.rb +5 -0
  187. data/stdlib/nodejs/dir.rb +13 -0
  188. data/stdlib/nodejs/file.rb +98 -0
  189. data/stdlib/nodejs/fileutils.rb +26 -0
  190. data/stdlib/nodejs/io.rb +2 -0
  191. data/stdlib/nodejs/irb.rb +45 -0
  192. data/stdlib/nodejs/process.rb +16 -0
  193. data/stdlib/nodejs/require.rb +32 -0
  194. data/stdlib/nodejs/rubygems.rb +68 -0
  195. data/stdlib/nodejs/runtime.rb +25 -0
  196. data/stdlib/nodejs/yaml.rb +11 -0
  197. data/stdlib/opal-parser.rb +1 -2
  198. data/stdlib/opal-source-maps.rb +2 -0
  199. data/stdlib/phantomjs.rb +8 -0
  200. data/stdlib/process.rb +10 -0
  201. data/stdlib/promise.rb +12 -4
  202. data/stdlib/set.rb +27 -0
  203. data/stdlib/source_map.rb +5 -63
  204. data/stdlib/source_map/map.rb +220 -0
  205. data/stdlib/source_map/mapping.rb +26 -0
  206. data/stdlib/source_map/offset.rb +88 -0
  207. data/stdlib/source_map/version.rb +3 -0
  208. data/stdlib/source_map/vlq.rb +77 -101
  209. data/stdlib/sourcemap.rb +1 -0
  210. data/stdlib/strscan.rb +7 -1
  211. data/stdlib/template.rb +1 -1
  212. data/stdlib/thread.rb +147 -7
  213. metadata +238 -104
  214. data/lib/mspec/opal/mspec_fixes.rb +0 -87
  215. data/spec/cli/sprockets/environment_spec.rb +0 -14
  216. data/spec/filters/bugs/symbol.rb +0 -5
  217. data/spec/opal/core/kernel/warn_spec.rb +0 -83
  218. data/spec/opal/core/language/numbers_spec.rb +0 -60
  219. data/stdlib/opal-source-maps.js.erb +0 -2
  220. data/stdlib/source_map/generator.rb +0 -251
  221. data/stdlib/source_map/parser.rb +0 -102
data/lib/opal/erb.rb CHANGED
@@ -3,29 +3,42 @@ require 'opal/compiler'
3
3
  module Opal
4
4
  module ERB
5
5
  def self.compile(source, file_name = '(erb)')
6
- Compiler.new.compile source, file_name
6
+ Compiler.new(source, file_name).compile
7
7
  end
8
8
 
9
9
  class Compiler
10
- def compile(source, file_name = '(erb)')
10
+ def initialize(source, file_name = '(erb)')
11
11
  @source, @file_name, @result = source, file_name, source
12
+ end
12
13
 
13
- self.fix_quotes
14
- self.find_contents
15
- self.find_code
16
- self.wrap_compiled
14
+ def prepared_source
15
+ @prepared_source ||= begin
16
+ source = @source
17
+ source = fix_quotes(source)
18
+ source = find_contents(source)
19
+ source = find_code(source)
20
+ source = wrap_compiled(source)
21
+ source = require_erb(source)
22
+ source
23
+ end
24
+ end
17
25
 
18
- Opal.compile @result
26
+ def compile
27
+ Opal.compile prepared_source
19
28
  end
20
29
 
21
- def fix_quotes
22
- @result = @result.gsub '"', '\\"'
30
+ def fix_quotes(result)
31
+ result.gsub '"', '\\"'
23
32
  end
24
33
 
25
34
  BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
26
35
 
27
- def find_contents
28
- @result = @result.gsub(/<%=([\s\S]+?)%>/) do
36
+ def require_erb(result)
37
+ 'require "erb";'+result
38
+ end
39
+
40
+ def find_contents(result)
41
+ result.gsub(/<%=([\s\S]+?)%>/) do
29
42
  inner = $1.gsub(/\\'/, "'").gsub(/\\"/, '"')
30
43
 
31
44
  if inner =~ BLOCK_EXPR
@@ -36,14 +49,15 @@ module Opal
36
49
  end
37
50
  end
38
51
 
39
- def find_code
40
- @result = @result.gsub(/<%([\s\S]+?)%>/) do
52
+ def find_code(result)
53
+ result.gsub(/<%([\s\S]+?)%>/) do
41
54
  "\")\n#{ $1 }\noutput_buffer.append(\""
42
55
  end
43
56
  end
44
57
 
45
- def wrap_compiled
46
- @result = "Template.new('#@file_name') do |output_buffer|\noutput_buffer.append(\"#@result\")\noutput_buffer.join\nend\n"
58
+ def wrap_compiled(result)
59
+ path = @file_name.sub(/\.opalerb$/, '')
60
+ result = "Template.new('#{path}') do |output_buffer|\noutput_buffer.append(\"#{result}\")\noutput_buffer.join\nend\n"
47
61
  end
48
62
  end
49
63
  end
@@ -0,0 +1,18 @@
1
+ require 'hike'
2
+ require 'pathname'
3
+
4
+ module Opal
5
+ class HikePathFinder < Hike::Trail
6
+ def initialize(paths = Opal.paths)
7
+ super()
8
+ append_paths(*paths)
9
+ append_extensions '.js', '.js.rb', '.rb', '.opalerb'
10
+ end
11
+
12
+ def find path
13
+ pathname = Pathname(path)
14
+ return path if pathname.absolute? and pathname.exist?
15
+ super
16
+ end
17
+ end
18
+ end
data/lib/opal/nodes.rb CHANGED
@@ -18,6 +18,7 @@ require 'opal/nodes/case'
18
18
  require 'opal/nodes/super'
19
19
  require 'opal/nodes/top'
20
20
  require 'opal/nodes/while'
21
+ require 'opal/nodes/for'
21
22
  require 'opal/nodes/hash'
22
23
  require 'opal/nodes/array'
23
24
  require 'opal/nodes/defined'
@@ -9,22 +9,34 @@ module Opal
9
9
 
10
10
  children :recvr, :meth, :arglist, :iter
11
11
 
12
- SPECIALS = Set.new
12
+ SPECIALS = {}
13
13
 
14
- def self.add_special(name, &handler)
15
- SPECIALS << name
14
+ # Operators that get optimized by compiler
15
+ OPERATORS = { :+ => :plus, :- => :minus, :* => :times, :/ => :divide,
16
+ :< => :lt, :<= => :le, :> => :gt, :>= => :ge }
17
+
18
+ def self.add_special(name, options = {}, &handler)
19
+ SPECIALS[name] = options
16
20
  define_method("handle_#{name}", &handler)
17
21
  end
18
22
 
19
23
  def compile
20
- # if we handle this call specially, just do that and return early
21
- return if self.handle_special
24
+ # handle some methods specially
25
+ handle_special
26
+
27
+ # some special methods need to skip compilation
28
+ return unless compile_default?
22
29
 
23
30
  compiler.method_calls << meth.to_sym
24
31
 
25
32
  # if trying to access an lvar in irb mode
26
33
  return compile_irb_var if using_irb?
27
34
 
35
+ default_compile
36
+ end
37
+
38
+ def default_compile
39
+
28
40
  mid = mid_to_jsid meth.to_s
29
41
 
30
42
  splat = arglist[1..-1].any? { |a| a.first == :splat }
@@ -35,8 +47,8 @@ module Opal
35
47
  block = iter
36
48
  end
37
49
 
38
- tmpfunc = scope.new_temp if block
39
- tmprecv = scope.new_temp if splat || tmpfunc
50
+ blktmp = scope.new_temp if block
51
+ tmprecv = scope.new_temp if splat || blktmp
40
52
 
41
53
  # must do this after assigning temp variables
42
54
  block = expr(block) if block
@@ -44,7 +56,7 @@ module Opal
44
56
  recv_code = recv(recv_sexp)
45
57
  call_recv = s(:js_tmp, tmprecv || recv_code)
46
58
 
47
- if tmpfunc and !splat
59
+ if blktmp and !splat
48
60
  arglist.insert 1, call_recv
49
61
  end
50
62
 
@@ -56,26 +68,30 @@ module Opal
56
68
  push recv_code, mid
57
69
  end
58
70
 
59
- if tmpfunc
60
- unshift "(#{tmpfunc} = "
61
- push ", #{tmpfunc}._p = ", block, ", #{tmpfunc})"
71
+ if blktmp
72
+ unshift "(#{blktmp} = "
73
+ push ", #{blktmp}.$$p = ", block, ", #{blktmp})"
62
74
  end
63
75
 
64
76
  if splat
65
77
  push ".apply(", (tmprecv || recv_code), ", ", args, ")"
66
- elsif tmpfunc
78
+ elsif blktmp
67
79
  push ".call(", args, ")"
68
80
  else
69
81
  push "(", args, ")"
70
82
  end
71
83
 
72
- scope.queue_temp tmpfunc if tmpfunc
84
+ scope.queue_temp blktmp if blktmp
73
85
  end
74
86
 
75
87
  def recv_sexp
76
88
  recvr || s(:self)
77
89
  end
78
90
 
91
+ def attr_assignment?
92
+ @assignment ||= meth.to_s =~ /^[\da-z]+\=$/i
93
+ end
94
+
79
95
  # Used to generate the code to use this sexp as an ivar var reference
80
96
  def compile_irb_var
81
97
  with_temp do |tmp|
@@ -85,6 +101,19 @@ module Opal
85
101
  end
86
102
  end
87
103
 
104
+ def compile_assignment
105
+ with_temp do |args_tmp|
106
+ with_temp do |recv_tmp|
107
+ args = expr(arglist)
108
+ mid = mid_to_jsid meth.to_s
109
+ push "((#{args_tmp} = [", args, "]), "+
110
+ "#{recv_tmp} = ", recv(recv_sexp), ", ",
111
+ recv_tmp, mid, ".apply(#{recv_tmp}, #{args_tmp}), "+
112
+ "#{args_tmp}[#{args_tmp}.length-1])"
113
+ end
114
+ end
115
+ end
116
+
88
117
  # a variable reference in irb mode in top scope might be a var ref,
89
118
  # or it might be a method call
90
119
  def using_irb?
@@ -95,53 +124,105 @@ module Opal
95
124
  # this method. If this method returns nil, then the method will continue
96
125
  # to be generated by CallNode.
97
126
  def handle_special
127
+ @compile_default = true
128
+
98
129
  if SPECIALS.include? meth
99
- if result = __send__("handle_#{meth}")
100
- push result
101
- return true
102
- end
130
+ @compile_default = false
131
+ __send__("handle_#{meth}")
103
132
  elsif RuntimeHelpers.compatible?(recvr, meth, arglist)
133
+ @compile_default = false
104
134
  push(RuntimeHelpers.new(@sexp, @level, @compiler).compile)
105
- return true
135
+ end
136
+ end
137
+
138
+ def compile_default!
139
+ @compile_default = true
140
+ end
141
+
142
+ def compile_default?
143
+ @compile_default
144
+ end
145
+
146
+ OPERATORS.each do |operator, name|
147
+ add_special(operator.to_sym) do
148
+ if compiler.inline_operators?
149
+ compiler.operator_helpers << operator.to_sym
150
+ lhs, rhs = expr(recvr), expr(arglist[1])
151
+
152
+ push fragment("$rb_#{name}(")
153
+ push lhs
154
+ push fragment(", ")
155
+ push rhs
156
+ push fragment(")")
157
+ else
158
+ compile_default!
159
+ end
106
160
  end
107
161
  end
108
162
 
109
163
  add_special :require do
164
+ compile_default!
110
165
  str = DependencyResolver.new(compiler, arglist[1]).resolve
111
166
  compiler.requires << str unless str.nil?
112
- stmt? ? fragment('') : fragment('true')
167
+ push fragment('')
168
+ end
169
+
170
+ add_special :require_relative do
171
+ arg = arglist[1]
172
+ file = compiler.file
173
+ if arg[0] == :str
174
+ dir = File.dirname(file)
175
+ compiler.requires << File.expand_path(arg[1], dir)
176
+ end
177
+ push fragment("self.$require(#{file.inspect}+ '/../' + ")
178
+ push process(arglist)
179
+ push fragment(')')
113
180
  end
114
181
 
115
182
  add_special :autoload do
116
183
  if scope.class_scope?
184
+ compile_default!
117
185
  str = DependencyResolver.new(compiler, arglist[2]).resolve
118
186
  compiler.requires << str unless str.nil?
119
- fragment ''
187
+ push fragment('')
188
+ end
189
+ end
190
+
191
+ add_special :require_tree do
192
+ arg = arglist[1]
193
+ if arg[0] == :str
194
+ dir = File.dirname(compiler.file)
195
+ relative_path = arg[1]
196
+ full_path = Pathname(dir).join(relative_path).cleanpath.to_s
197
+ compiler.required_trees << full_path
198
+ arg[1] = full_path
120
199
  end
200
+ compile_default!
201
+ push fragment('')
121
202
  end
122
203
 
123
204
  add_special :block_given? do
124
- compiler.handle_block_given_call @sexp
205
+ push compiler.handle_block_given_call @sexp
125
206
  end
126
207
 
127
208
  add_special :__callee__ do
128
209
  if scope.def?
129
- fragment scope.mid.to_s.inspect
210
+ push fragment scope.mid.to_s.inspect
130
211
  else
131
- fragment 'nil'
212
+ push fragment 'nil'
132
213
  end
133
214
  end
134
215
 
135
216
  add_special :__method__ do
136
217
  if scope.def?
137
- fragment scope.mid.to_s.inspect
218
+ push fragment scope.mid.to_s.inspect
138
219
  else
139
- fragment 'nil'
220
+ push fragment 'nil'
140
221
  end
141
222
  end
142
223
 
143
224
  add_special :debugger do
144
- fragment 'debugger'
225
+ push fragment 'debugger'
145
226
  end
146
227
 
147
228
  class DependencyResolver
@@ -1,17 +1,29 @@
1
1
  require 'opal/nodes/base'
2
+ require 'opal/nodes/call'
2
3
 
3
4
  module Opal
4
5
  module Nodes
5
6
  # recv.mid = rhs
6
7
  # s(:recv, :mid=, s(:arglist, rhs))
7
- class AttrAssignNode < Base
8
+ class AttrAssignNode < CallNode
8
9
  handle :attrasgn
9
10
 
10
- children :recvr, :mid, :arglist
11
+ children :recvr, :meth, :arglist
11
12
 
12
- def compile
13
- sexp = s(:call, recvr, mid, arglist)
14
- push process(sexp, @level)
13
+ def default_compile
14
+ # Skip, for now, if the method has square brackets: []=
15
+ return super if meth.to_s !~ /^\w+=$/
16
+
17
+ with_temp do |args_tmp|
18
+ with_temp do |recv_tmp|
19
+ args = expr(arglist)
20
+ mid = mid_to_jsid meth.to_s
21
+ push "((#{args_tmp} = [", args, "]), "+
22
+ "#{recv_tmp} = ", recv(recv_sexp), ", ",
23
+ recv_tmp, mid, ".apply(#{recv_tmp}, #{args_tmp}), "+
24
+ "#{args_tmp}[#{args_tmp}.length-1])"
25
+ end
26
+ end
15
27
  end
16
28
  end
17
29
 
@@ -39,7 +51,7 @@ module Opal
39
51
  sexp = s(:or, recvr, rhs)
40
52
  push expr(sexp)
41
53
  end
42
- end
54
+ end
43
55
 
44
56
  # a &&= rhs
45
57
  # s(:op_asgn_and, s(:lvar, :a), s(:lasgn, a:, rhs))
@@ -98,6 +110,19 @@ module Opal
98
110
  end
99
111
  end
100
112
  end
113
+
114
+ def compile_and
115
+ with_temp do |a| # args
116
+ with_temp do |r| # recv
117
+ aref = s(:call, s(:js_tmp, r), :[], s(:arglist, s(:js_tmp, a)))
118
+ aset = s(:call, s(:js_tmp, r), :[]=, s(:arglist, s(:js_tmp, a), rhs))
119
+ andop = s(:and, aref, aset)
120
+
121
+ push "(#{a} = ", expr(first_arg), ", #{r} = ", expr(lhs)
122
+ push ", ", expr(andop), ")"
123
+ end
124
+ end
125
+ end
101
126
  end
102
127
 
103
128
  # lhs.b += rhs
@@ -17,8 +17,8 @@ module Opal
17
17
 
18
18
  in_scope do
19
19
  scope.name = name
20
- add_temp "#{scope.proto} = self._proto"
21
- add_temp "$scope = self._scope"
20
+ add_temp "#{scope.proto} = self.$$proto"
21
+ add_temp "$scope = self.$$scope"
22
22
 
23
23
  body_code = self.body_code
24
24
  empty_line
@@ -10,12 +10,8 @@ module Opal
10
10
  def compile
11
11
  if name == :DATA and compiler.eof_content
12
12
  push("$__END__")
13
- elsif compiler.const_missing?
14
- with_temp do |tmp|
15
- push "((#{tmp} = $scope.#{name}) == null ? $opal.cm('#{name}') : #{tmp})"
16
- end
17
13
  else
18
- push "$scope.#{name}"
14
+ push "$scope.get('#{name}')"
19
15
  end
20
16
  end
21
17
  end
@@ -51,17 +47,9 @@ module Opal
51
47
  children :base, :name
52
48
 
53
49
  def compile
54
- if compiler.const_missing?
55
- with_temp do |tmp|
56
- push "((#{tmp} = ("
57
- push expr(base)
58
- push ")._scope).#{name} == null ? #{tmp}.cm('#{name}') : "
59
- push "#{tmp}.#{name})"
60
- end
61
- else
62
- push expr(base)
63
- wrap '(', ")._scope.#{name}"
64
- end
50
+ push "(("
51
+ push expr(base)
52
+ push ").$$scope.get('#{name}'))"
65
53
  end
66
54
  end
67
55
 
@@ -71,10 +59,7 @@ module Opal
71
59
  children :name
72
60
 
73
61
  def compile
74
- with_temp do |tmp|
75
- push "((#{tmp} = $opal.Object._scope.#{name}) == null ? "
76
- push "$opal.cm('#{name}') : #{tmp})"
77
- end
62
+ push "Opal.get('#{name}')"
78
63
  end
79
64
  end
80
65