opal 0.3.22 → 0.3.25

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