opal 0.3.22 → 0.3.25

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 (104) hide show
  1. data/.travis.yml +1 -1
  2. data/Gemfile +1 -9
  3. data/README.md +46 -5
  4. data/Rakefile +4 -94
  5. data/core/array.rb +13 -46
  6. data/core/basic_object.rb +2 -12
  7. data/core/boolean.rb +1 -1
  8. data/core/browser.js +27 -1
  9. data/core/class.rb +1 -7
  10. data/core/enumerable.rb +3 -15
  11. data/core/error.rb +2 -4
  12. data/core/hash.rb +9 -18
  13. data/core/json.rb +5 -0
  14. data/core/kernel.rb +2 -21
  15. data/core/load_order +5 -7
  16. data/core/nil_class.rb +4 -0
  17. data/core/numeric.rb +0 -6
  18. data/core/object.rb +1 -5
  19. data/core/proc.rb +0 -4
  20. data/core/range.rb +10 -17
  21. data/core/regexp.rb +2 -6
  22. data/core/runtime.js +2 -26
  23. data/core/string.rb +28 -26
  24. data/core/struct.rb +0 -4
  25. data/core/{erb.rb → templates.rb} +6 -4
  26. data/core/time.rb +7 -19
  27. data/core/top_self.rb +2 -2
  28. data/lib/opal.rb +13 -2
  29. data/lib/opal/builder.rb +3 -3
  30. data/lib/opal/erb_parser.rb +3 -2
  31. data/lib/opal/parser.rb +10 -2
  32. data/lib/opal/rake_task.rb +10 -2
  33. data/lib/opal/scope.rb +6 -1
  34. data/lib/opal/version.rb +1 -1
  35. data/opal.gemspec +1 -3
  36. data/spec/core/array/constructor_spec.rb +0 -8
  37. data/spec/core/enumerable/drop_while_spec.rb +0 -4
  38. data/spec/core/enumerable/find_index_spec.rb +0 -4
  39. data/spec/core/enumerable/select_spec.rb +13 -0
  40. data/spec/core/kernel/respond_to_spec.rb +4 -0
  41. data/spec/core/string/empty_spec.rb +0 -1
  42. data/spec/core/string/include_spec.rb +0 -6
  43. data/spec/core/string/swapcase_spec.rb +0 -5
  44. data/spec/core/string/to_s_spec.rb +0 -7
  45. data/spec/core/string/to_str_spec.rb +0 -7
  46. data/spec/lib/erb_parser/simple.erb +1 -0
  47. data/spec/{grammar → lib/grammar}/alias_spec.rb +0 -0
  48. data/spec/{grammar → lib/grammar}/and_spec.rb +0 -0
  49. data/spec/{grammar → lib/grammar}/array_spec.rb +0 -0
  50. data/spec/{grammar → lib/grammar}/attrasgn_spec.rb +0 -0
  51. data/spec/{grammar → lib/grammar}/begin_spec.rb +0 -0
  52. data/spec/{grammar → lib/grammar}/block_spec.rb +0 -0
  53. data/spec/{grammar → lib/grammar}/break_spec.rb +0 -0
  54. data/spec/{grammar → lib/grammar}/call_spec.rb +0 -0
  55. data/spec/{grammar → lib/grammar}/class_spec.rb +0 -0
  56. data/spec/{grammar → lib/grammar}/const_spec.rb +0 -0
  57. data/spec/{grammar → lib/grammar}/cvar_spec.rb +0 -0
  58. data/spec/{grammar → lib/grammar}/def_spec.rb +0 -0
  59. data/spec/{grammar → lib/grammar}/false_spec.rb +0 -0
  60. data/spec/{grammar → lib/grammar}/file_spec.rb +0 -0
  61. data/spec/{grammar → lib/grammar}/gvar_spec.rb +0 -0
  62. data/spec/{grammar → lib/grammar}/hash_spec.rb +0 -0
  63. data/spec/{grammar → lib/grammar}/iasgn_spec.rb +0 -0
  64. data/spec/{grammar → lib/grammar}/if_spec.rb +0 -0
  65. data/spec/{grammar → lib/grammar}/iter_spec.rb +0 -0
  66. data/spec/{grammar → lib/grammar}/ivar_spec.rb +0 -0
  67. data/spec/{grammar → lib/grammar}/lambda_spec.rb +0 -0
  68. data/spec/{grammar → lib/grammar}/lasgn_spec.rb +0 -0
  69. data/spec/{grammar → lib/grammar}/line_spec.rb +0 -0
  70. data/spec/{grammar → lib/grammar}/lvar_spec.rb +0 -0
  71. data/spec/{grammar → lib/grammar}/masgn_spec.rb +0 -0
  72. data/spec/{grammar → lib/grammar}/module_spec.rb +0 -0
  73. data/spec/{grammar → lib/grammar}/nil_spec.rb +0 -0
  74. data/spec/{grammar → lib/grammar}/not_spec.rb +0 -0
  75. data/spec/{grammar → lib/grammar}/op_asgn1_spec.rb +0 -0
  76. data/spec/{grammar → lib/grammar}/op_asgn2_spec.rb +0 -0
  77. data/spec/{grammar → lib/grammar}/or_spec.rb +0 -0
  78. data/spec/{grammar → lib/grammar}/return_spec.rb +0 -0
  79. data/spec/{grammar → lib/grammar}/sclass_spec.rb +0 -0
  80. data/spec/{grammar → lib/grammar}/self_spec.rb +0 -0
  81. data/spec/{grammar → lib/grammar}/str_spec.rb +0 -0
  82. data/spec/{grammar → lib/grammar}/super_spec.rb +0 -0
  83. data/spec/{grammar → lib/grammar}/true_spec.rb +0 -0
  84. data/spec/{grammar → lib/grammar}/undef_spec.rb +0 -0
  85. data/spec/{grammar → lib/grammar}/unless_spec.rb +0 -0
  86. data/spec/{grammar → lib/grammar}/while_spec.rb +0 -0
  87. data/spec/{grammar → lib/grammar}/xstr_spec.rb +0 -0
  88. data/spec/{grammar → lib/grammar}/yield_spec.rb +0 -0
  89. data/spec/{parser → lib/parser}/simple_spec.rb +1 -1
  90. data/spec/opal/erb/erb_spec.rb +10 -2
  91. data/spec/opal/string/demodulize_spec.rb +10 -0
  92. data/spec/opal/string/underscore_spec.rb +17 -0
  93. data/spec/spec_helper.rb +1 -1
  94. data/vendor/opal_spec_runner.js +43 -0
  95. metadata +99 -114
  96. data/.rspec +0 -2
  97. data/docs/index.md +0 -616
  98. data/docs/post.html +0 -3
  99. data/docs/pre.html +0 -35
  100. data/docs/try.html +0 -52
  101. data/spec/core/string/fixtures/classes.rb +0 -3
  102. data/spec/opal/array/subclassing_spec.rb +0 -32
  103. data/spec/opal/exception/subclassing_spec.rb +0 -17
  104. data/spec/opal/string/subclassing_spec.rb +0 -26
data/core/regexp.rb CHANGED
@@ -11,9 +11,7 @@ class Regexp < `RegExp`
11
11
  `other.constructor == RegExp && #{self}.toString() === other.toString()`
12
12
  end
13
13
 
14
- def ===(obj)
15
- `#{self}.test(obj)`
16
- end
14
+ alias_native :===, :test
17
15
 
18
16
  def =~(string)
19
17
  %x{
@@ -36,9 +34,7 @@ class Regexp < `RegExp`
36
34
 
37
35
  alias eql? ==
38
36
 
39
- def inspect
40
- `#{self}.toString()`
41
- end
37
+ alias_native :inspect, :toString
42
38
 
43
39
  def match(pattern)
44
40
  %x{
data/core/runtime.js CHANGED
@@ -238,30 +238,6 @@ var bridge_class = function(constructor) {
238
238
 
239
239
  bridged_classes.push(constructor);
240
240
 
241
- var allocator = function(initializer) {
242
- var result, kls = this, methods = kls._methods, proto = kls.prototype;
243
-
244
- if (initializer == null) {
245
- result = new constructor
246
- }
247
- else {
248
- result = new constructor(initializer);
249
- }
250
-
251
- if (kls === constructor) {
252
- return result;
253
- }
254
-
255
- result._klass = kls;
256
-
257
- for (var i = 0, length = methods.length; i < length; i++) {
258
- var method = methods[i];
259
- result[method] = proto[method];
260
- }
261
-
262
- return result;
263
- };
264
-
265
241
  var table = Object.prototype, methods = Object._methods;
266
242
 
267
243
  for (var i = 0, length = methods.length; i < length; i++) {
@@ -269,13 +245,13 @@ var bridge_class = function(constructor) {
269
245
  constructor.prototype[m] = table[m];
270
246
  }
271
247
 
272
- constructor.$allocate = allocator;
273
-
274
248
  constructor._smethods.push('$allocate');
275
249
 
276
250
  return constructor;
277
251
  };
278
252
 
253
+ Opal.puts = function(a) { console.log(a); };
254
+
279
255
  // Initialization
280
256
  // --------------
281
257
 
data/core/string.rb CHANGED
@@ -11,7 +11,7 @@ class String < `String`
11
11
 
12
12
  def self.new(str = '')
13
13
  %x{
14
- return #{allocate str}
14
+ return new String(str)
15
15
  }
16
16
  end
17
17
 
@@ -91,7 +91,6 @@ class String < `String`
91
91
  }
92
92
  end
93
93
 
94
- # TODO: implement range based accessors
95
94
  def [](index, length)
96
95
  %x{
97
96
  var size = #{self}.length;
@@ -151,8 +150,6 @@ class String < `String`
151
150
  end
152
151
 
153
152
  def chars
154
- return enum_for :chars unless block_given?
155
-
156
153
  %x{
157
154
  for (var i = 0, length = #{self}.length; i < length; i++) {
158
155
  #{yield `#{self}.charAt(i)`}
@@ -183,16 +180,24 @@ class String < `String`
183
180
  def count(str)
184
181
  `(#{self}.length - #{self}.replace(new RegExp(str,"g"), '').length) / str.length`
185
182
  end
183
+
184
+ def demodulize
185
+ %x{
186
+ var idx = #{self}.lastIndexOf('::');
186
187
 
187
- def downcase
188
- `#{self}.toLowerCase()`
188
+ if (idx > -1) {
189
+ return #{self}.substr(idx + 2);
190
+ }
191
+
192
+ return #{self};
193
+ }
189
194
  end
190
195
 
196
+ alias_native :downcase, :toLowerCase
197
+
191
198
  alias each_char chars
192
199
 
193
200
  def each_line (separator = $/)
194
- return enum_for :each_line, separator unless block_given?
195
-
196
201
  %x{
197
202
  var splitted = #{self}.split(separator);
198
203
 
@@ -226,13 +231,9 @@ class String < `String`
226
231
  `#{self}.toString() === val.toString()`
227
232
  end
228
233
 
229
- def getbyte(idx)
230
- `#{self}.charCodeAt(idx)`
231
- end
234
+ alias_native :getbyte, :charCodeAt
232
235
 
233
236
  def gsub(pattern, replace, &block)
234
- return enum_for :gsub, pattern, replace if !block && `pattern == null`
235
-
236
237
  if pattern.is_a?(String)
237
238
  pattern = /#{Regexp.escape(pattern)}/
238
239
  end
@@ -246,9 +247,7 @@ class String < `String`
246
247
  }
247
248
  end
248
249
 
249
- def hash
250
- `#{self}.toString()`
251
- end
250
+ alias_native :hash, :toString
252
251
 
253
252
  def hex
254
253
  to_i 16
@@ -259,11 +258,11 @@ class String < `String`
259
258
  end
260
259
 
261
260
  def index(what, offset)
262
- unless String === what || Regexp === what
263
- raise TypeError, "type mismatch: #{what.class} given"
264
- end
265
-
266
261
  %x{
262
+ if (!what._isString && !what._isRegexp) {
263
+ throw new Error('type mismatch');
264
+ }
265
+
267
266
  var result = -1;
268
267
 
269
268
  if (offset != null) {
@@ -502,17 +501,20 @@ class String < `String`
502
501
  }
503
502
  end
504
503
 
505
- def to_s
506
- `#{self}.toString()`
507
- end
504
+ alias_native :to_s, :toString
508
505
 
509
506
  alias to_str to_s
510
507
 
511
508
  alias to_sym intern
512
-
513
- def upcase
514
- `#{self}.toUpperCase()`
509
+
510
+ def underscore
511
+ `#{self}.replace(/[-\\s]+/g, '_')
512
+ .replace(/([A-Z\\d]+)([A-Z][a-z])/g, '$1_$2')
513
+ .replace(/([a-z\\d])([A-Z])/g, '$1_$2')
514
+ .toLowerCase()`
515
515
  end
516
+
517
+ alias_native :upcase, :toUpperCase
516
518
  end
517
519
 
518
520
  Symbol = String
data/core/struct.rb CHANGED
@@ -74,14 +74,10 @@ class Struct
74
74
  end
75
75
 
76
76
  def each
77
- return enum_for :each unless block_given?
78
-
79
77
  members.each { |name| yield self[name] }
80
78
  end
81
79
 
82
80
  def each_pair
83
- return enum_for :each_pair unless block_given?
84
-
85
81
  members.each { |name| yield name, self[name] }
86
82
  end
87
83
 
@@ -1,4 +1,4 @@
1
- # A really small ERB implementation for Opal.
1
+ # A wapper for ERB templates in Opal. Other templates may be used
2
2
  class ERB
3
3
 
4
4
  # @private Stores all registered instances
@@ -20,11 +20,13 @@ class ERB
20
20
  # implementation uses a normal object as a context.
21
21
  #
22
22
  # view = UserView.new
23
- # ERB[:user_view].result(view)
23
+ # ERB[:user_view].render(view)
24
24
  #
25
25
  # @param [Object] context
26
26
  # @result [String]
27
- def result(context)
28
- context.instance_eval &@body
27
+ def render(content)
28
+ content.instance_eval(&@body)
29
29
  end
30
+
31
+ alias :result :render
30
32
  end
data/core/time.rb CHANGED
@@ -2,7 +2,7 @@ class Time < `Date`
2
2
  include Comparable
3
3
 
4
4
  def self.at(seconds, frac = 0)
5
- allocate `seconds * 1000 + frac`
5
+ `new Date(seconds * 1000 + frac)`
6
6
  end
7
7
 
8
8
  def self.new(year, month, day, hour, minute, second, millisecond)
@@ -44,9 +44,7 @@ class Time < `Date`
44
44
  to_f <=> other.to_f
45
45
  end
46
46
 
47
- def day
48
- `#{self}.getDate()`
49
- end
47
+ alias_native :day, :getDate
50
48
 
51
49
  def eql?(other)
52
50
  other.is_a?(Time) && (self <=> other).zero?
@@ -56,15 +54,11 @@ class Time < `Date`
56
54
  `#{self}.getDay() === 5`
57
55
  end
58
56
 
59
- def hour
60
- `#{self}.getHours()`
61
- end
57
+ alias_native :hour, :getHours
62
58
 
63
59
  alias mday day
64
60
 
65
- def min
66
- `#{self}.getMinutes()`
67
- end
61
+ alias_native :min, :getMinutes
68
62
 
69
63
  def mon
70
64
  `#{self}.getMonth() + 1`
@@ -80,9 +74,7 @@ class Time < `Date`
80
74
  `#{self}.getDay() === 6`
81
75
  end
82
76
 
83
- def sec
84
- `#{self}.getSeconds()`
85
- end
77
+ alias_native :sec, :getSeconds
86
78
 
87
79
  def sunday?
88
80
  `#{self}.getDay() === 0`
@@ -104,15 +96,11 @@ class Time < `Date`
104
96
  `#{self}.getDay() === 2`
105
97
  end
106
98
 
107
- def wday
108
- `#{self}.getDay()`
109
- end
99
+ alias_native :wday, :getDay
110
100
 
111
101
  def wednesday?
112
102
  `#{self}.getDay() === 3`
113
103
  end
114
104
 
115
- def year
116
- `#{self}.getFullYear()`
117
- end
105
+ alias_native :year, :getFullYear
118
106
  end
data/core/top_self.rb CHANGED
@@ -1,7 +1,7 @@
1
- def self.to_s
1
+ def to_s
2
2
  'main'
3
3
  end
4
4
 
5
- def self.include(mod)
5
+ def include(mod)
6
6
  Object.include mod
7
7
  end
data/lib/opal.rb CHANGED
@@ -58,6 +58,17 @@ module Opal
58
58
  ].join("\n")
59
59
  end
60
60
 
61
+ # Returns parser prebuilt for js-environments.
62
+ #
63
+ # @return [String]
64
+ def self.parser_code
65
+ [
66
+ Builder.new(:files => %w(racc.rb strscan.rb), :dir => self.core_dir).build,
67
+ self.build_gem('opal'),
68
+ File.read(File.join self.core_dir, 'browser.js')
69
+ ].join("\n")
70
+ end
71
+
61
72
  # Build gem with given name to a string.
62
73
  #
63
74
  # Opal.build_gem 'opal-spec'
@@ -81,8 +92,8 @@ module Opal
81
92
  #
82
93
  # @param [String] files files to build
83
94
  # @return [String]
84
- def self.build_files(files)
85
- Builder.new(:files => files).build
95
+ def self.build_files(files, dir=nil)
96
+ Builder.new(:files => files, :dir => dir).build
86
97
  end
87
98
 
88
99
  def self.opal_dir
data/lib/opal/builder.rb CHANGED
@@ -28,7 +28,7 @@ module Opal
28
28
  files = []
29
29
 
30
30
  sources.each do |s|
31
- s = File.join @dir, s
31
+ s = File.expand_path(File.join @dir, s)
32
32
  if File.directory? s
33
33
  files.push *Dir[File.join(s, '**/*.{rb,js,erb}')]
34
34
  elsif %w(.rb .js .erb).include? File.extname(s)
@@ -71,7 +71,7 @@ module Opal
71
71
  code = @parser.parse File.read(file), lib_name
72
72
  @requires[lib_name] = @parser.requires
73
73
  elsif File.extname(file) == '.erb'
74
- template_name = File.basename(file).chomp(File.extname(file))
74
+ template_name = lib_name_for(file).chomp(File.extname(file))
75
75
  code = Opal::ERBParser.new.parse File.read(file), template_name
76
76
  @requires[lib_name] = []
77
77
  else # javascript
@@ -89,7 +89,7 @@ module Opal
89
89
  def lib_name_for(file)
90
90
  file = file.sub(/^#{@dir}\//, '')
91
91
  file = file.chomp File.extname(file)
92
- file.sub(/^(lib|spec)\//, '')
92
+ file.sub(/^(lib|spec|app)\//, '')
93
93
  end
94
94
  end
95
95
  end
@@ -9,8 +9,9 @@ module Opal
9
9
 
10
10
  def compile(str, name)
11
11
  res = "ERB.new('#{name}') do\nout = []\nout.<<(\"" +
12
- str.gsub(/<%=([\s\S]+?)%>/) do
13
- "\")\nout.<<(" + $1.gsub(/\\'/, "'") + ")\nout.<<(\""
12
+ str.gsub('"', '\\"'
13
+ ).gsub(/<%=([\s\S]+?)%>/) do
14
+ "\")\nout.<<(" + $1.gsub(/\\'/, "'").gsub(/\\"/, '"') + ")\nout.<<(\""
14
15
  end.gsub(/<%([\s\S]+?)%>/) do
15
16
  "\")\n" + $1 + "\nout.<<(\""
16
17
  end + "\")\nout.join\nend"
data/lib/opal/parser.rb CHANGED
@@ -36,8 +36,7 @@ module Opal
36
36
 
37
37
  @helpers = {
38
38
  :breaker => true,
39
- :slice => true,
40
- :mm => true
39
+ :slice => true
41
40
  }
42
41
 
43
42
  top @grammar.parse(source, file)
@@ -540,6 +539,13 @@ module Opal
540
539
  "%s%s = %s.%s" % [@scope.proto, meth, @scope.proto, func]
541
540
  end
542
541
 
542
+ def handle_respond_to(sexp, level)
543
+ recv, mid, arglist = sexp
544
+ recv ||= s(:self)
545
+ meth = process(arglist[1], level) if arglist[1]
546
+ "(!!#{process(recv, level)}['$' + #{meth}])"
547
+ end
548
+
543
549
  # s(:call, recv, :mid, s(:arglist))
544
550
  # s(:call, nil, :mid, s(:arglist))
545
551
  def process_call(sexp, level)
@@ -565,6 +571,8 @@ module Opal
565
571
  end
566
572
 
567
573
  return "//= require #{path[1]}"
574
+ when :respond_to?
575
+ return handle_respond_to(sexp, level)
568
576
  end
569
577
 
570
578
  splat = arglist[1..-1].any? { |a| a.first == :splat }
@@ -6,12 +6,13 @@ module Opal
6
6
  class RakeTask
7
7
  include Rake::DSL if defined? Rake::DSL
8
8
 
9
- attr_accessor :name, :build_dir, :specs_dir, :files, :dependencies
9
+ attr_accessor :name, :build_dir, :specs_dir, :files, :dependencies, :parser, :dir
10
10
 
11
11
  def initialize(namespace = nil)
12
12
  @project_dir = Dir.getwd
13
13
 
14
14
  @name = File.basename(@project_dir)
15
+ @dir = @project_dir
15
16
  @build_dir = 'build'
16
17
  @specs_dir = 'spec'
17
18
  @files = Dir['lib/**/*.{rb,js,erb}']
@@ -40,7 +41,7 @@ module Opal
40
41
  task 'opal:build' do
41
42
  out = File.join @build_dir, "#{ @name }.js"
42
43
  puts " * #{out}"
43
- write_code Opal.build_files(@files), out
44
+ write_code Opal.build_files(@files, @dir), out
44
45
  end
45
46
 
46
47
  desc "Build specs"
@@ -56,6 +57,13 @@ module Opal
56
57
  puts " * #{out}"
57
58
  write_code Opal.runtime, out
58
59
 
60
+ # build opal-parser?
61
+ if @parser
62
+ out = File.join @build_dir, 'opal-parser.js'
63
+ puts " * #{out}"
64
+ write_code Opal.parser_code, out
65
+ end
66
+
59
67
  @dependencies.each { |dep| build_gem dep }
60
68
  end
61
69