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.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/.spectator +2 -0
- data/.spectator-mspec +3 -0
- data/.travis.yml +8 -11
- data/CHANGELOG.md +33 -0
- data/CONTRIBUTING.md +8 -43
- data/Gemfile +15 -4
- data/Guardfile +77 -0
- data/README.md +15 -9
- data/Rakefile +36 -12
- data/benchmarks/operators.rb +11 -0
- data/bin/opal +10 -13
- data/bin/opal-build +4 -4
- data/bin/opal-mspec +10 -0
- data/bin/opal-repl +4 -3
- data/examples/sinatra/Gemfile +1 -1
- data/examples/sinatra/config.ru +3 -3
- data/lib/mspec/opal/main.rb.erb +2 -2
- data/lib/mspec/opal/rake_task.rb +31 -24
- data/lib/mspec/opal/runner.rb +18 -1
- data/lib/mspec/opal/sprockets.js +17 -0
- data/lib/opal.rb +1 -34
- data/lib/opal/builder.rb +92 -58
- data/lib/opal/builder_processors.rb +165 -0
- data/lib/opal/cli.rb +85 -144
- data/lib/opal/cli_options.rb +136 -90
- data/lib/opal/cli_runners.rb +10 -0
- data/lib/opal/cli_runners/nodejs.rb +56 -0
- data/lib/opal/cli_runners/phantom.js +35 -0
- data/lib/opal/cli_runners/phantomjs.rb +28 -0
- data/lib/opal/cli_runners/server.rb +54 -0
- data/lib/opal/compiler.rb +35 -16
- data/lib/opal/erb.rb +29 -15
- data/lib/opal/hike_path_finder.rb +18 -0
- data/lib/opal/nodes.rb +1 -0
- data/lib/opal/nodes/call.rb +107 -26
- data/lib/opal/nodes/call_special.rb +31 -6
- data/lib/opal/nodes/class.rb +2 -2
- data/lib/opal/nodes/constants.rb +5 -20
- data/lib/opal/nodes/def.rb +4 -4
- data/lib/opal/nodes/defined.rb +3 -3
- data/lib/opal/nodes/definitions.rb +1 -1
- data/lib/opal/nodes/for.rb +35 -0
- data/lib/opal/nodes/helpers.rb +2 -2
- data/lib/opal/nodes/iter.rb +3 -3
- data/lib/opal/nodes/literal.rb +10 -2
- data/lib/opal/nodes/masgn.rb +2 -2
- data/lib/opal/nodes/module.rb +2 -2
- data/lib/opal/nodes/scope.rb +1 -0
- data/lib/opal/nodes/singleton_class.rb +2 -2
- data/lib/opal/nodes/super.rb +2 -2
- data/lib/opal/nodes/top.rb +30 -3
- data/lib/opal/parser.rb +15 -1
- data/lib/opal/parser/grammar.rb +2571 -2452
- data/lib/opal/parser/grammar.y +37 -5
- data/lib/opal/parser/keywords.rb +2 -0
- data/lib/opal/parser/lexer.rb +21 -11
- data/lib/opal/path_reader.rb +28 -0
- data/lib/opal/paths.rb +38 -0
- data/lib/opal/source_map.rb +32 -15
- data/lib/opal/sprockets/environment.rb +9 -2
- data/lib/opal/sprockets/erb.rb +1 -2
- data/lib/opal/sprockets/path_reader.rb +34 -0
- data/lib/opal/sprockets/processor.rb +40 -39
- data/lib/opal/sprockets/server.rb +47 -33
- data/lib/opal/version.rb +1 -1
- data/opal.gemspec +10 -5
- data/opal/README.md +6 -0
- data/opal/corelib/array.rb +36 -4
- data/opal/corelib/array/inheritance.rb +6 -6
- data/opal/corelib/basic_object.rb +9 -9
- data/opal/corelib/boolean.rb +1 -1
- data/opal/corelib/class.rb +12 -12
- data/opal/corelib/dir.rb +20 -0
- data/opal/corelib/enumerable.rb +42 -42
- data/opal/corelib/enumerator.rb +1 -1
- data/opal/corelib/error.rb +2 -2
- data/opal/corelib/file.rb +56 -0
- data/opal/corelib/hash.rb +5 -5
- data/opal/corelib/helpers.rb +3 -3
- data/opal/corelib/io.rb +13 -10
- data/opal/corelib/kernel.rb +44 -68
- data/opal/corelib/method.rb +1 -1
- data/opal/corelib/module.rb +89 -114
- data/opal/corelib/nil_class.rb +1 -1
- data/opal/corelib/numeric.rb +27 -23
- data/opal/corelib/proc.rb +5 -5
- data/opal/corelib/range.rb +8 -4
- data/opal/corelib/regexp.rb +5 -5
- data/opal/corelib/runtime.js +589 -272
- data/opal/corelib/string.rb +52 -37
- data/opal/corelib/string/inheritance.rb +5 -5
- data/opal/corelib/time.rb +102 -52
- data/opal/corelib/variables.rb +3 -3
- data/opal/opal.rb +2 -0
- data/package.json +9 -0
- data/spec/filters/bugs/array.rb +0 -6
- data/spec/filters/bugs/language.rb +4 -0
- data/spec/filters/bugs/numeric.rb +7 -6
- data/spec/filters/bugs/opal.rb +2 -0
- data/spec/filters/bugs/regexp.rb +4 -0
- data/spec/filters/bugs/string.rb +0 -7
- data/spec/filters/bugs/stringscanner.rb +4 -1
- data/spec/filters/unsupported/private_methods.rb +2 -0
- data/spec/lib/builder_processors_spec.rb +27 -0
- data/spec/lib/builder_spec.rb +66 -0
- data/spec/{cli → lib}/cli_spec.rb +60 -5
- data/spec/{cli → lib}/compiler_spec.rb +66 -5
- data/spec/{cli → lib}/dependency_resolver_spec.rb +1 -1
- data/spec/lib/fixtures/no_requires.rb +1 -0
- data/spec/{cli → lib}/fixtures/opal_file.rb +0 -0
- data/spec/lib/fixtures/require_tree_test.rb +3 -0
- data/spec/lib/fixtures/required_tree_test/required_file1.rb +1 -0
- data/spec/lib/fixtures/required_tree_test/required_file2.rb +1 -0
- data/spec/lib/fixtures/requires.rb +7 -0
- data/spec/{cli → lib}/fixtures/sprockets_file.js.rb +0 -0
- data/spec/lib/fixtures/sprockets_require_tree_test.rb +3 -0
- data/spec/lib/hike_path_finder_spec.rb +23 -0
- data/spec/{cli → lib}/lexer_spec.rb +1 -1
- data/spec/{cli → lib}/parser/alias_spec.rb +1 -1
- data/spec/{cli → lib}/parser/and_spec.rb +1 -1
- data/spec/{cli → lib}/parser/attrasgn_spec.rb +1 -1
- data/spec/{cli → lib}/parser/begin_spec.rb +1 -1
- data/spec/{cli → lib}/parser/block_spec.rb +1 -1
- data/spec/{cli → lib}/parser/break_spec.rb +1 -1
- data/spec/{cli → lib}/parser/call_spec.rb +1 -1
- data/spec/{cli → lib}/parser/class_spec.rb +1 -1
- data/spec/{cli → lib}/parser/comments_spec.rb +1 -1
- data/spec/{cli → lib}/parser/def_spec.rb +1 -1
- data/spec/{cli → lib}/parser/if_spec.rb +1 -1
- data/spec/{cli → lib}/parser/iter_spec.rb +1 -1
- data/spec/{cli → lib}/parser/lambda_spec.rb +1 -1
- data/spec/{cli → lib}/parser/literal_spec.rb +1 -1
- data/spec/{cli → lib}/parser/masgn_spec.rb +1 -1
- data/spec/{cli → lib}/parser/module_spec.rb +1 -1
- data/spec/{cli → lib}/parser/not_spec.rb +1 -1
- data/spec/{cli → lib}/parser/op_asgn1_spec.rb +1 -1
- data/spec/{cli → lib}/parser/op_asgn2_spec.rb +1 -1
- data/spec/{cli → lib}/parser/or_spec.rb +1 -1
- data/spec/{cli → lib}/parser/return_spec.rb +1 -1
- data/spec/{cli → lib}/parser/sclass_spec.rb +1 -1
- data/spec/{cli → lib}/parser/string_spec.rb +8 -1
- data/spec/{cli → lib}/parser/super_spec.rb +1 -1
- data/spec/lib/parser/unary_spec.rb +48 -0
- data/spec/{cli → lib}/parser/undef_spec.rb +1 -1
- data/spec/{cli → lib}/parser/unless_spec.rb +1 -1
- data/spec/{cli → lib}/parser/variables_spec.rb +1 -1
- data/spec/{cli → lib}/parser/while_spec.rb +1 -1
- data/spec/{cli → lib}/parser/yield_spec.rb +1 -1
- data/spec/lib/path_reader_spec.rb +24 -0
- data/spec/lib/shared/path_finder_shared.rb +19 -0
- data/spec/lib/shared/path_reader_shared.rb +31 -0
- data/spec/lib/spec_helper.rb +9 -0
- data/spec/lib/sprockets/environment_spec.rb +30 -0
- data/spec/{cli → lib}/sprockets/erb_spec.rb +1 -1
- data/spec/lib/sprockets/path_reader_spec.rb +25 -0
- data/spec/{cli → lib}/sprockets/processor_spec.rb +9 -2
- data/spec/lib/sprockets/server_spec.rb +20 -0
- data/spec/opal/compiler/irb_spec.rb +11 -11
- data/spec/opal/core/fixtures/require_tree_files/file 1.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 2.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 3.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 4.rb +1 -0
- data/spec/opal/core/fixtures/require_tree_files/file 5.rb +1 -0
- data/spec/opal/core/kernel/require_tree_spec.rb +7 -0
- data/spec/opal/core/kernel/respond_to_spec.rb +2 -2
- data/spec/opal/core/runtime/method_missing_spec.rb +19 -0
- data/spec/opal/core/source_map_spec.rb +2 -2
- data/spec/opal/core/string_spec.rb +11 -0
- data/spec/opal/stdlib/erb/erb_spec.rb +0 -1
- data/spec/opal/stdlib/thread/mutex_spec.rb +40 -0
- data/spec/opal/stdlib/thread/thread_queue_spec.rb +32 -0
- data/spec/opal/stdlib/thread/thread_spec.rb +60 -0
- data/spec/rubyspecs +54 -11
- data/spec/spec_helper.rb +18 -3
- data/spec/support/mspec_rspec_adapter.rb +33 -0
- data/spec/{cli/spec_helper.rb → support/parser_helpers.rb} +10 -10
- data/stdlib/README.md +3 -0
- data/stdlib/benchmark.rb +10 -0
- data/stdlib/date.rb +2 -2
- data/stdlib/dir.rb +1 -5
- data/stdlib/file.rb +1 -7
- data/stdlib/json.rb +10 -1
- data/stdlib/native.rb +5 -5
- data/stdlib/nodejs.rb +5 -0
- data/stdlib/nodejs/dir.rb +13 -0
- data/stdlib/nodejs/file.rb +98 -0
- data/stdlib/nodejs/fileutils.rb +26 -0
- data/stdlib/nodejs/io.rb +2 -0
- data/stdlib/nodejs/irb.rb +45 -0
- data/stdlib/nodejs/process.rb +16 -0
- data/stdlib/nodejs/require.rb +32 -0
- data/stdlib/nodejs/rubygems.rb +68 -0
- data/stdlib/nodejs/runtime.rb +25 -0
- data/stdlib/nodejs/yaml.rb +11 -0
- data/stdlib/opal-parser.rb +1 -2
- data/stdlib/opal-source-maps.rb +2 -0
- data/stdlib/phantomjs.rb +8 -0
- data/stdlib/process.rb +10 -0
- data/stdlib/promise.rb +12 -4
- data/stdlib/set.rb +27 -0
- data/stdlib/source_map.rb +5 -63
- data/stdlib/source_map/map.rb +220 -0
- data/stdlib/source_map/mapping.rb +26 -0
- data/stdlib/source_map/offset.rb +88 -0
- data/stdlib/source_map/version.rb +3 -0
- data/stdlib/source_map/vlq.rb +77 -101
- data/stdlib/sourcemap.rb +1 -0
- data/stdlib/strscan.rb +7 -1
- data/stdlib/template.rb +1 -1
- data/stdlib/thread.rb +147 -7
- metadata +238 -104
- data/lib/mspec/opal/mspec_fixes.rb +0 -87
- data/spec/cli/sprockets/environment_spec.rb +0 -14
- data/spec/filters/bugs/symbol.rb +0 -5
- data/spec/opal/core/kernel/warn_spec.rb +0 -83
- data/spec/opal/core/language/numbers_spec.rb +0 -60
- data/stdlib/opal-source-maps.js.erb +0 -2
- data/stdlib/source_map/generator.rb +0 -251
- data/stdlib/source_map/parser.rb +0 -102
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
module Gem
|
|
4
|
+
class Install
|
|
5
|
+
def initialize(name, version)
|
|
6
|
+
@name = name
|
|
7
|
+
@version = version
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def version
|
|
11
|
+
@version ||= latest_version(name)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def latest_version(name)
|
|
15
|
+
command = curl("https://rubygems.org/api/v1/versions/#{name}.json")
|
|
16
|
+
versions = JSON.parse system(command)
|
|
17
|
+
versions.first['number']
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def full_name
|
|
21
|
+
"#{name}-#{version}"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def gem_home
|
|
25
|
+
ENV['HOME']+'/.opal-node/opal-gems/#{RUBY_ENGINE_VERSION}'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def gems_dir
|
|
29
|
+
File.join(gem_home, :gems)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def specs_dir
|
|
33
|
+
File.join(gem_home, :specs)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def perform
|
|
37
|
+
gem_dir = File.join(gems_dir, full_name)
|
|
38
|
+
spec_dir = File.join(specs_dir, full_name+'.yml')
|
|
39
|
+
system "mkdir -p #{gem_dir} #{spec_dir}"
|
|
40
|
+
|
|
41
|
+
Dir.chdir gem_dir do
|
|
42
|
+
system curl("https://rubygems.org/downloads/#{name}-#{version}.gem") + '| tar -xv'
|
|
43
|
+
system "gunzip metadata.gz --stdout > #{specs_dir}/#{full_name}.yml"
|
|
44
|
+
system "gunzip data.tar.gz"
|
|
45
|
+
system "tar -xvf data.tar"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def curl url
|
|
50
|
+
"curl -L #{url}"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
command = ARGV.shift
|
|
56
|
+
case command
|
|
57
|
+
when 'install'
|
|
58
|
+
name = ARGV.shift
|
|
59
|
+
if ARGV.include? '-v'
|
|
60
|
+
version = ARGV[ ARGV.index('-v')+1 ]
|
|
61
|
+
else
|
|
62
|
+
version = nil
|
|
63
|
+
end
|
|
64
|
+
install = Gem::Install.new(name, version)
|
|
65
|
+
install.perform
|
|
66
|
+
else
|
|
67
|
+
raise NotImplementedError, "sorry, the #{command.inspect} is not implemented."
|
|
68
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
%x{
|
|
2
|
+
// Generated by CoffeeScript 1.6.3
|
|
3
|
+
(function() {
|
|
4
|
+
var OpalNode, extensions, fs, parser, parserFile, source, sourceFile, vm, __path__;
|
|
5
|
+
fs = require('fs');
|
|
6
|
+
__path__ = require('path');
|
|
7
|
+
vm = require('vm');
|
|
8
|
+
// vm.runInThisContext(parser, parserFile);
|
|
9
|
+
OpalNode = (function() {
|
|
10
|
+
function OpalNode() {}
|
|
11
|
+
OpalNode.node_require = require;
|
|
12
|
+
return OpalNode;
|
|
13
|
+
})();
|
|
14
|
+
|
|
15
|
+
global.OpalNode = OpalNode;
|
|
16
|
+
|
|
17
|
+
}).call(this);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module NodeJS
|
|
21
|
+
def self.require name
|
|
22
|
+
`OpalNode.node_require(#{name})`
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'native'
|
|
2
|
+
|
|
3
|
+
module YAML
|
|
4
|
+
`var __yaml__ = OpalNode.node_require('js-yaml')`
|
|
5
|
+
|
|
6
|
+
def self.load_path path
|
|
7
|
+
loaded = `__yaml__.yaml.safeLoad(#{File.__fs__}.readFileSync(#{path}, 'utf8'))`
|
|
8
|
+
loaded = Hash.new(loaded) if native?(loaded)
|
|
9
|
+
loaded
|
|
10
|
+
end
|
|
11
|
+
end
|
data/stdlib/opal-parser.rb
CHANGED
data/stdlib/phantomjs.rb
ADDED
data/stdlib/process.rb
ADDED
data/stdlib/promise.rb
CHANGED
|
@@ -174,8 +174,8 @@ class Promise
|
|
|
174
174
|
alias finally always
|
|
175
175
|
alias ensure always
|
|
176
176
|
|
|
177
|
-
def trace(&block)
|
|
178
|
-
self ^ Trace.new(block)
|
|
177
|
+
def trace(depth = nil, &block)
|
|
178
|
+
self ^ Trace.new(depth, block)
|
|
179
179
|
end
|
|
180
180
|
|
|
181
181
|
def inspect
|
|
@@ -209,9 +209,17 @@ class Promise
|
|
|
209
209
|
end
|
|
210
210
|
end
|
|
211
211
|
|
|
212
|
-
def initialize(block)
|
|
212
|
+
def initialize(depth, block)
|
|
213
|
+
@depth = depth
|
|
214
|
+
|
|
213
215
|
super -> {
|
|
214
|
-
|
|
216
|
+
trace = Trace.it(self).reverse
|
|
217
|
+
|
|
218
|
+
if depth && depth <= trace.length
|
|
219
|
+
trace.shift(trace.length - depth)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
block.call(*trace)
|
|
215
223
|
}
|
|
216
224
|
end
|
|
217
225
|
end
|
data/stdlib/set.rb
CHANGED
|
@@ -9,6 +9,7 @@ class Set
|
|
|
9
9
|
@hash = Hash.new
|
|
10
10
|
|
|
11
11
|
return if enum.nil?
|
|
12
|
+
raise ArgumentError, 'value must be enumerable' unless Enumerable === enum
|
|
12
13
|
|
|
13
14
|
if block
|
|
14
15
|
do_with_enum(enum) { |o| add(block[o]) }
|
|
@@ -17,6 +18,10 @@ class Set
|
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
|
|
21
|
+
def inspect
|
|
22
|
+
"#<Set: {#{to_a.join(',')}}>"
|
|
23
|
+
end
|
|
24
|
+
|
|
20
25
|
def ==(other)
|
|
21
26
|
if self.equal?(other)
|
|
22
27
|
true
|
|
@@ -35,6 +40,28 @@ class Set
|
|
|
35
40
|
end
|
|
36
41
|
alias << add
|
|
37
42
|
|
|
43
|
+
def delete(o)
|
|
44
|
+
@hash.delete(o)
|
|
45
|
+
self
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def delete?(o)
|
|
49
|
+
if include?(o)
|
|
50
|
+
delete(o)
|
|
51
|
+
self
|
|
52
|
+
else
|
|
53
|
+
nil
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def delete_if
|
|
58
|
+
block_given? or return enum_for(__method__)
|
|
59
|
+
# @hash.delete_if should be faster, but using it breaks the order
|
|
60
|
+
# of enumeration in subclasses.
|
|
61
|
+
select { |o| yield o }.each { |o| @hash.delete(o) }
|
|
62
|
+
self
|
|
63
|
+
end
|
|
64
|
+
|
|
38
65
|
def add?(o)
|
|
39
66
|
if include?(o)
|
|
40
67
|
nil
|
data/stdlib/source_map.rb
CHANGED
|
@@ -1,63 +1,5 @@
|
|
|
1
|
-
require '
|
|
2
|
-
|
|
3
|
-
require 'source_map/
|
|
4
|
-
require 'source_map/
|
|
5
|
-
require 'source_map/
|
|
6
|
-
|
|
7
|
-
class SourceMap
|
|
8
|
-
include SourceMap::Generator
|
|
9
|
-
include SourceMap::Parser
|
|
10
|
-
|
|
11
|
-
# Create a new blank SourceMap
|
|
12
|
-
#
|
|
13
|
-
# Options may include:
|
|
14
|
-
#
|
|
15
|
-
# :file => String # See {#file}
|
|
16
|
-
# :source_root => String # See {#source_root}
|
|
17
|
-
# :generated_output => IO # See {#generated_output}
|
|
18
|
-
#
|
|
19
|
-
# :sources => Array[String] # See {#sources}
|
|
20
|
-
# :names => Array[String] # See {#names}
|
|
21
|
-
#
|
|
22
|
-
# :version => 3 # Which version of SourceMap to use (only 3 is allowed)
|
|
23
|
-
#
|
|
24
|
-
def initialize(opts={})
|
|
25
|
-
unless (remain = opts.keys - [:generated_output, :file, :source_root, :sources, :names, :version]).empty?
|
|
26
|
-
raise ArgumentError, "Unsupported options to SourceMap.new: #{remain.inspect}"
|
|
27
|
-
end
|
|
28
|
-
self.generated_output = opts[:generated_output]
|
|
29
|
-
self.file = opts[:file] || ''
|
|
30
|
-
self.source_root = opts[:source_root] || ''
|
|
31
|
-
self.version = opts[:version] || 3
|
|
32
|
-
self.sources = opts[:sources] || []
|
|
33
|
-
self.names = opts[:names] || []
|
|
34
|
-
self.mappings = []
|
|
35
|
-
raise "version #{opts[:version]} not supported" if version != 3
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# The name of the file containing the code that this SourceMap describes.
|
|
39
|
-
# (default "")
|
|
40
|
-
attr_accessor :file
|
|
41
|
-
|
|
42
|
-
# The URL/directory that contains the original source files.
|
|
43
|
-
#
|
|
44
|
-
# This is prefixed to the entries in ['sources']
|
|
45
|
-
# (default "")
|
|
46
|
-
attr_accessor :source_root
|
|
47
|
-
|
|
48
|
-
# The version of the SourceMap spec we're using.
|
|
49
|
-
# (default 3)
|
|
50
|
-
attr_accessor :version
|
|
51
|
-
|
|
52
|
-
# The list of sources (used during parsing/generating)
|
|
53
|
-
# These are relative to the source_root.
|
|
54
|
-
# (default [])
|
|
55
|
-
attr_accessor :sources
|
|
56
|
-
|
|
57
|
-
# A list of names (used during parsing/generating)
|
|
58
|
-
# (default [])
|
|
59
|
-
attr_accessor :names
|
|
60
|
-
|
|
61
|
-
# A list of mapping objects.
|
|
62
|
-
attr_accessor :mappings
|
|
63
|
-
end
|
|
1
|
+
require 'source_map/map'
|
|
2
|
+
require 'source_map/mapping'
|
|
3
|
+
require 'source_map/offset'
|
|
4
|
+
require 'source_map/version'
|
|
5
|
+
require 'source_map/vlq'
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
require 'source_map/offset'
|
|
4
|
+
require 'source_map/mapping'
|
|
5
|
+
require 'source_map/vlq'
|
|
6
|
+
|
|
7
|
+
module SourceMap
|
|
8
|
+
class Map
|
|
9
|
+
include Enumerable
|
|
10
|
+
|
|
11
|
+
def self.from_json(json)
|
|
12
|
+
from_hash JSON.parse(json)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.from_hash(hash)
|
|
16
|
+
str = hash['mappings']
|
|
17
|
+
sources = hash['sources']
|
|
18
|
+
names = hash['names']
|
|
19
|
+
|
|
20
|
+
mappings = decode_vlq_mappings(str, sources, names)
|
|
21
|
+
new(mappings, hash['file'])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Internal: Decode VLQ mappings and match up sources and symbol names.
|
|
25
|
+
#
|
|
26
|
+
# str - VLQ string from 'mappings' attribute
|
|
27
|
+
# sources - Array of Strings from 'sources' attribute
|
|
28
|
+
# names - Array of Strings from 'names' attribute
|
|
29
|
+
#
|
|
30
|
+
# Returns an Array of Mappings.
|
|
31
|
+
def self.decode_vlq_mappings(str, sources = [], names = [])
|
|
32
|
+
mappings = []
|
|
33
|
+
|
|
34
|
+
source_id = 0
|
|
35
|
+
original_line = 1
|
|
36
|
+
original_column = 0
|
|
37
|
+
name_id = 0
|
|
38
|
+
|
|
39
|
+
VLQ.decode_mappings(str).each_with_index do |group, index|
|
|
40
|
+
generated_column = 0
|
|
41
|
+
generated_line = index + 1
|
|
42
|
+
|
|
43
|
+
group.each do |segment|
|
|
44
|
+
generated_column += segment[0]
|
|
45
|
+
generated = Offset.new(generated_line, generated_column)
|
|
46
|
+
|
|
47
|
+
if segment.size >= 4
|
|
48
|
+
source_id += segment[1]
|
|
49
|
+
original_line += segment[2]
|
|
50
|
+
original_column += segment[3]
|
|
51
|
+
|
|
52
|
+
source = sources[source_id]
|
|
53
|
+
original = Offset.new(original_line, original_column)
|
|
54
|
+
else
|
|
55
|
+
# TODO: Research this case
|
|
56
|
+
next
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
if segment[4]
|
|
60
|
+
name_id += segment[4]
|
|
61
|
+
name = names[name_id]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
mappings << Mapping.new(source, generated, original, name)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
mappings
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def initialize(mappings = [], filename = nil)
|
|
72
|
+
@mappings, @filename = mappings, filename
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
attr_reader :filename
|
|
76
|
+
|
|
77
|
+
def size
|
|
78
|
+
@mappings.size
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def [](i)
|
|
82
|
+
@mappings[i]
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def each(&block)
|
|
86
|
+
@mappings.each(&block)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def to_s
|
|
90
|
+
@string ||= build_vlq_string
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def sources
|
|
94
|
+
@sources ||= @mappings.map(&:source).uniq.compact
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def names
|
|
98
|
+
@names ||= @mappings.map(&:name).uniq.compact
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def ==(other)
|
|
102
|
+
eql?(other)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def eql?(other)
|
|
106
|
+
other.is_a?(self.class) &&
|
|
107
|
+
self.mappings == other.mappings &&
|
|
108
|
+
self.filename == other.filename
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def +(other)
|
|
112
|
+
mappings = @mappings.dup
|
|
113
|
+
offset = @mappings.any? ? @mappings.last.generated.line+1 : 0
|
|
114
|
+
other.each do |m|
|
|
115
|
+
mappings << Mapping.new(
|
|
116
|
+
m.source, m.generated + offset,
|
|
117
|
+
m.original, m.name
|
|
118
|
+
)
|
|
119
|
+
end
|
|
120
|
+
self.class.new(mappings, other.filename)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def |(other)
|
|
124
|
+
return other.dup if self.mappings.empty?
|
|
125
|
+
|
|
126
|
+
mappings = []
|
|
127
|
+
|
|
128
|
+
other.each do |m|
|
|
129
|
+
om = bsearch(m.original)
|
|
130
|
+
next unless om
|
|
131
|
+
|
|
132
|
+
mappings << Mapping.new(
|
|
133
|
+
om.source, m.generated,
|
|
134
|
+
om.original, om.name
|
|
135
|
+
)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
self.class.new(mappings, other.filename)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def bsearch(offset, from = 0, to = size - 1)
|
|
142
|
+
mid = (from + to) / 2
|
|
143
|
+
|
|
144
|
+
# We haven't found a match
|
|
145
|
+
if from > to
|
|
146
|
+
return from < 1 ? nil : self[from-1]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# We found an exact match
|
|
150
|
+
if offset == self[mid].generated
|
|
151
|
+
self[mid]
|
|
152
|
+
|
|
153
|
+
# We need to filter more
|
|
154
|
+
elsif offset < self[mid].generated
|
|
155
|
+
bsearch(offset, from, mid - 1)
|
|
156
|
+
elsif offset > self[mid].generated
|
|
157
|
+
bsearch(offset, mid + 1, to)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def as_json
|
|
162
|
+
{
|
|
163
|
+
"version" => 3,
|
|
164
|
+
"file" => filename,
|
|
165
|
+
"mappings" => to_s,
|
|
166
|
+
"sources" => sources,
|
|
167
|
+
"names" => names
|
|
168
|
+
}
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Public: Get a pretty inspect output for debugging purposes.
|
|
172
|
+
#
|
|
173
|
+
# Returns a String.
|
|
174
|
+
def inspect
|
|
175
|
+
str = "#<#{self.class}"
|
|
176
|
+
str << " filename=#{filename.inspect}" if filename
|
|
177
|
+
str << " mappings=#{mappings.map(&:to_s).inspect}" if mappings.any?
|
|
178
|
+
str << ">"
|
|
179
|
+
str
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
protected
|
|
183
|
+
attr_reader :mappings
|
|
184
|
+
|
|
185
|
+
def build_vlq_string
|
|
186
|
+
source_id = 0
|
|
187
|
+
source_line = 1
|
|
188
|
+
source_column = 0
|
|
189
|
+
name_id = 0
|
|
190
|
+
|
|
191
|
+
by_lines = @mappings.group_by { |m| m.generated.line }
|
|
192
|
+
|
|
193
|
+
sources_index = Hash[sources.each_with_index.to_a]
|
|
194
|
+
names_index = Hash[names.each_with_index.to_a]
|
|
195
|
+
|
|
196
|
+
ary = (1..(by_lines.keys.max || 1)).map do |line|
|
|
197
|
+
generated_column = 0
|
|
198
|
+
|
|
199
|
+
(by_lines[line] || []).map do |mapping|
|
|
200
|
+
group = []
|
|
201
|
+
group << mapping.generated.column - generated_column
|
|
202
|
+
group << sources_index[mapping.source] - source_id
|
|
203
|
+
group << mapping.original.line - source_line
|
|
204
|
+
group << mapping.original.column - source_column
|
|
205
|
+
group << names_index[mapping.name] - name_id if mapping.name
|
|
206
|
+
|
|
207
|
+
generated_column = mapping.generated.column
|
|
208
|
+
source_id = sources_index[mapping.source]
|
|
209
|
+
source_line = mapping.original.line
|
|
210
|
+
source_column = mapping.original.column
|
|
211
|
+
name_id = names_index[mapping.name] if mapping.name
|
|
212
|
+
|
|
213
|
+
group
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
VLQ.encode_mappings(ary)
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|