opal 0.6.3 → 0.7.0.beta1

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 (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