opal 0.11.4 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +42 -10
- data/.rubocop.yml +398 -0
- data/.rubocop_todo.yml +44 -0
- data/.travis.yml +28 -34
- data/CHANGELOG.md +363 -142
- data/CONTRIBUTING.md +3 -5
- data/Gemfile +17 -12
- data/Guardfile +0 -1
- data/HACKING.md +1 -35
- data/LICENSE +2 -2
- data/README.md +42 -13
- data/Rakefile +1 -4
- data/UNRELEASED.md +133 -0
- data/benchmark-ips/README.md +6 -0
- data/benchmark-ips/bm_block_vs_yield.rb +21 -0
- data/benchmark-ips/bm_js_symbols_vs_strings.rb +28 -0
- data/benchmark-ips/bm_while_true_vs_loop.rb +19 -0
- data/bin/console +14 -0
- data/bin/opal +0 -1
- data/bin/opal-benchmark-ips +8 -0
- data/bin/opal-mspec +9 -1
- data/bin/opal-repl +2 -1
- data/bin/rake +7 -0
- data/bin/setup +8 -0
- data/docs/compiled_ruby.md +89 -8
- data/docs/compiler.md +3 -20
- data/docs/jquery.md +44 -11
- data/docs/promises.md +1 -1
- data/docs/rails.md +16 -12
- data/docs/sinatra.md +15 -8
- data/docs/using_sprockets.md +16 -11
- data/examples/rack/config.ru +1 -0
- data/examples/sinatra/Gemfile +1 -0
- data/examples/sinatra/config.ru +2 -11
- data/exe/opal-repl +3 -11
- data/lib/opal.rb +1 -0
- data/lib/opal/ast/builder.rb +4 -1
- data/lib/opal/ast/node.rb +1 -0
- data/lib/opal/builder.rb +84 -63
- data/lib/opal/builder_processors.rb +41 -56
- data/lib/opal/cli.rb +33 -49
- data/lib/opal/cli_options.rb +27 -17
- data/lib/opal/cli_runners.rb +73 -16
- data/lib/opal/cli_runners/applescript.rb +4 -4
- data/lib/opal/cli_runners/chrome.rb +29 -17
- data/lib/opal/cli_runners/nashorn.rb +5 -4
- data/lib/opal/cli_runners/nodejs.rb +8 -6
- data/lib/opal/cli_runners/server.rb +12 -11
- data/lib/opal/compiler.rb +85 -103
- data/lib/opal/config.rb +3 -3
- data/lib/opal/deprecations.rb +2 -1
- data/lib/opal/eof_content.rb +2 -2
- data/lib/opal/erb.rb +8 -7
- data/lib/opal/errors.rb +72 -1
- data/lib/opal/fragment.rb +23 -3
- data/lib/opal/hike.rb +305 -0
- data/lib/opal/nodes.rb +5 -10
- data/lib/opal/nodes/arglist.rb +7 -6
- data/lib/opal/nodes/args.rb +36 -0
- data/lib/opal/nodes/args/arg.rb +22 -0
- data/lib/opal/nodes/args/arity_check.rb +151 -0
- data/lib/opal/nodes/args/ensure_kwargs_are_kwargs.rb +28 -0
- data/lib/opal/nodes/args/extract_block_arg.rb +34 -0
- data/lib/opal/nodes/args/extract_kwarg.rb +32 -0
- data/lib/opal/nodes/args/extract_kwargs.rb +28 -0
- data/lib/opal/nodes/args/extract_kwoptarg.rb +35 -0
- data/lib/opal/nodes/args/extract_kwrestarg.rb +35 -0
- data/lib/opal/nodes/args/extract_optarg.rb +35 -0
- data/lib/opal/nodes/args/extract_post_arg.rb +28 -0
- data/lib/opal/nodes/args/extract_post_optarg.rb +41 -0
- data/lib/opal/nodes/args/extract_restarg.rb +40 -0
- data/lib/opal/nodes/args/fake_arg.rb +26 -0
- data/lib/opal/nodes/args/initialize_iterarg.rb +28 -0
- data/lib/opal/nodes/args/initialize_shadowarg.rb +24 -0
- data/lib/opal/nodes/args/parameters.rb +63 -0
- data/lib/opal/nodes/args/prepare_post_args.rb +22 -0
- data/lib/opal/nodes/array.rb +9 -8
- data/lib/opal/nodes/base.rb +20 -11
- data/lib/opal/nodes/call.rb +24 -25
- data/lib/opal/nodes/call_special.rb +4 -3
- data/lib/opal/nodes/case.rb +24 -26
- data/lib/opal/nodes/class.rb +4 -5
- data/lib/opal/nodes/constants.rb +8 -7
- data/lib/opal/nodes/csend.rb +2 -3
- data/lib/opal/nodes/def.rb +28 -74
- data/lib/opal/nodes/defined.rb +36 -36
- data/lib/opal/nodes/definitions.rb +10 -7
- data/lib/opal/nodes/defs.rb +8 -16
- data/lib/opal/nodes/hash.rb +5 -4
- data/lib/opal/nodes/helpers.rb +8 -8
- data/lib/opal/nodes/if.rb +10 -8
- data/lib/opal/nodes/iter.rb +16 -103
- data/lib/opal/nodes/lambda.rb +18 -0
- data/lib/opal/nodes/literal.rb +29 -63
- data/lib/opal/nodes/logic.rb +25 -24
- data/lib/opal/nodes/masgn.rb +8 -6
- data/lib/opal/nodes/module.rb +4 -4
- data/lib/opal/nodes/node_with_args.rb +14 -208
- data/lib/opal/nodes/rescue.rb +32 -32
- data/lib/opal/nodes/runtime_helpers.rb +5 -4
- data/lib/opal/nodes/scope.rb +18 -29
- data/lib/opal/nodes/singleton_class.rb +3 -3
- data/lib/opal/nodes/super.rb +12 -18
- data/lib/opal/nodes/top.rb +10 -8
- data/lib/opal/nodes/variables.rb +6 -6
- data/lib/opal/nodes/while.rb +7 -6
- data/lib/opal/nodes/x_string.rb +139 -0
- data/lib/opal/nodes/yield.rb +10 -7
- data/lib/opal/parser.rb +9 -46
- data/lib/opal/parser/default_config.rb +50 -0
- data/lib/opal/parser/patch.rb +26 -0
- data/lib/opal/parser/source_buffer.rb +11 -0
- data/lib/opal/parser/with_c_lexer.rb +14 -0
- data/lib/opal/parser/with_ruby_lexer.rb +6 -0
- data/lib/opal/path_reader.rb +6 -5
- data/lib/opal/paths.rb +9 -6
- data/lib/opal/regexp_anchors.rb +6 -5
- data/lib/opal/rewriter.rb +7 -0
- data/lib/opal/rewriters/arguments.rb +58 -0
- data/lib/opal/rewriters/base.rb +32 -12
- data/lib/opal/rewriters/binary_operator_assignment.rb +20 -20
- data/lib/opal/rewriters/block_to_iter.rb +2 -1
- data/lib/opal/rewriters/break_finder.rb +2 -0
- data/lib/opal/rewriters/dot_js_syntax.rb +3 -2
- data/lib/opal/rewriters/dump_args.rb +28 -0
- data/lib/opal/rewriters/explicit_writer_return.rb +4 -3
- data/lib/opal/rewriters/for_rewriter.rb +12 -12
- data/lib/opal/rewriters/hashes/key_duplicates_rewriter.rb +2 -1
- data/lib/opal/rewriters/inline_args.rb +220 -0
- data/lib/opal/rewriters/js_reserved_words.rb +21 -17
- data/lib/opal/rewriters/logical_operator_assignment.rb +24 -14
- data/lib/opal/rewriters/mlhs_args.rb +128 -0
- data/lib/opal/rewriters/opal_engine_check.rb +11 -6
- data/lib/opal/rewriters/rubyspec/filters_rewriter.rb +3 -2
- data/lib/opal/server.rb +1 -0
- data/lib/opal/simple_server.rb +15 -23
- data/lib/opal/source_map.rb +7 -70
- data/lib/opal/source_map/file.rb +199 -0
- data/lib/opal/source_map/index.rb +83 -0
- data/lib/opal/source_map/map.rb +26 -0
- data/lib/opal/source_map/vlq.rb +98 -0
- data/lib/opal/util.rb +7 -5
- data/lib/opal/version.rb +2 -1
- data/lib/tilt/opal.rb +3 -3
- data/opal.gemspec +18 -9
- data/opal/corelib/array.rb +135 -117
- data/opal/corelib/array/pack.rb +446 -0
- data/opal/corelib/basic_object.rb +23 -9
- data/opal/corelib/boolean.rb +3 -3
- data/opal/corelib/class.rb +4 -10
- data/opal/corelib/comparable.rb +36 -23
- data/opal/corelib/complex.rb +108 -14
- data/opal/corelib/constants.rb +4 -4
- data/opal/corelib/enumerable.rb +132 -135
- data/opal/corelib/enumerator.rb +47 -50
- data/opal/corelib/error.rb +65 -8
- data/opal/corelib/file.rb +37 -32
- data/opal/corelib/hash.rb +90 -21
- data/opal/corelib/helpers.rb +7 -6
- data/opal/corelib/kernel.rb +53 -586
- data/opal/corelib/kernel/format.rb +544 -0
- data/opal/corelib/marshal.rb +1 -13
- data/opal/corelib/marshal/read_buffer.rb +20 -23
- data/opal/corelib/marshal/write_buffer.rb +23 -15
- data/opal/corelib/math.rb +12 -16
- data/opal/corelib/method.rb +5 -3
- data/opal/corelib/module.rb +80 -109
- data/opal/corelib/nil.rb +2 -2
- data/opal/corelib/number.rb +177 -43
- data/opal/corelib/numeric.rb +22 -16
- data/opal/corelib/pack_unpack/format_string_parser.rb +135 -0
- data/opal/corelib/proc.rb +3 -4
- data/opal/corelib/process.rb +1 -1
- data/opal/corelib/random.rb +24 -16
- data/opal/corelib/random/MersenneTwister.js +137 -0
- data/opal/corelib/random/math_random.js.rb +9 -0
- data/opal/corelib/random/mersenne_twister.js.rb +13 -0
- data/opal/corelib/random/seedrandom.js.rb +12 -0
- data/opal/corelib/range.rb +25 -26
- data/opal/corelib/rational.rb +57 -17
- data/opal/corelib/regexp.rb +39 -43
- data/opal/corelib/runtime.js +806 -683
- data/opal/corelib/string.rb +213 -112
- data/opal/corelib/string/encoding.rb +14 -17
- data/opal/corelib/string/unpack.rb +793 -0
- data/opal/corelib/struct.rb +40 -24
- data/opal/corelib/time.rb +14 -15
- data/opal/corelib/unsupported.rb +26 -4
- data/opal/opal.rb +2 -1
- data/opal/opal/full.rb +2 -0
- data/stdlib/base64.rb +1 -1
- data/stdlib/bigdecimal.rb +11 -13
- data/stdlib/buffer.rb +9 -8
- data/stdlib/buffer/array.rb +46 -48
- data/stdlib/buffer/view.rb +85 -47
- data/stdlib/console.rb +18 -18
- data/stdlib/date.rb +85 -66
- data/stdlib/delegate.rb +2 -2
- data/stdlib/e2mmap.rb +176 -0
- data/stdlib/encoding.rb +1 -1
- data/stdlib/erb.rb +1 -1
- data/stdlib/forwardable.rb +14 -14
- data/stdlib/json.rb +1 -2
- data/stdlib/logger.rb +112 -0
- data/stdlib/math.rb +1 -1
- data/stdlib/matrix.rb +2169 -0
- data/stdlib/matrix/eigenvalue_decomposition.rb +883 -0
- data/stdlib/matrix/lup_decomposition.rb +219 -0
- data/stdlib/nashorn/file.rb +7 -9
- data/stdlib/native.rb +69 -63
- data/stdlib/nodejs.rb +3 -0
- data/stdlib/nodejs/dir.rb +25 -4
- data/stdlib/nodejs/env.rb +40 -0
- data/stdlib/nodejs/file.rb +184 -34
- data/stdlib/nodejs/fileutils.rb +4 -4
- data/stdlib/nodejs/io.rb +4 -46
- data/stdlib/nodejs/irb.rb +27 -29
- data/stdlib/nodejs/kernel.rb +2 -11
- data/stdlib/nodejs/node_modules/balanced-match/.npmignore +5 -0
- data/stdlib/nodejs/node_modules/balanced-match/LICENSE.md +21 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match → balanced-match}/README.md +13 -2
- data/stdlib/nodejs/node_modules/balanced-match/index.js +59 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match → balanced-match}/package.json +46 -42
- data/stdlib/nodejs/node_modules/brace-expansion/LICENSE +21 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion → brace-expansion}/README.md +9 -1
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion → brace-expansion}/index.js +12 -2
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion → brace-expansion}/package.json +48 -48
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map → concat-map}/.travis.yml +0 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map → concat-map}/LICENSE +0 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map → concat-map}/README.markdown +0 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map → concat-map}/example/map.js +0 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map → concat-map}/index.js +0 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map → concat-map}/package.json +47 -42
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/concat-map → concat-map}/test/map.js +0 -0
- data/stdlib/nodejs/node_modules/fs.realpath/LICENSE +43 -0
- data/stdlib/nodejs/node_modules/fs.realpath/README.md +33 -0
- data/stdlib/nodejs/node_modules/fs.realpath/index.js +66 -0
- data/stdlib/nodejs/node_modules/fs.realpath/old.js +303 -0
- data/stdlib/nodejs/node_modules/fs.realpath/package.json +59 -0
- data/stdlib/nodejs/node_modules/glob/README.md +57 -46
- data/stdlib/nodejs/node_modules/glob/changelog.md +67 -0
- data/stdlib/nodejs/node_modules/glob/common.js +91 -28
- data/stdlib/nodejs/node_modules/glob/glob.js +196 -55
- data/stdlib/nodejs/node_modules/glob/package.json +55 -51
- data/stdlib/nodejs/node_modules/glob/sync.js +116 -39
- data/stdlib/nodejs/node_modules/{glob/node_modules/inflight → inflight}/LICENSE +0 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/inflight → inflight}/README.md +0 -0
- data/stdlib/nodejs/node_modules/inflight/inflight.js +54 -0
- data/stdlib/nodejs/node_modules/inflight/package.json +58 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/inherits → inherits}/LICENSE +0 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/inherits → inherits}/README.md +0 -0
- data/stdlib/nodejs/node_modules/inherits/inherits.js +7 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/inherits → inherits}/inherits_browser.js +0 -0
- data/stdlib/nodejs/node_modules/inherits/package.json +61 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/inflight/node_modules/wrappy → minimatch}/LICENSE +0 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch → minimatch}/README.md +2 -9
- data/stdlib/nodejs/node_modules/{glob/node_modules/minimatch → minimatch}/minimatch.js +284 -206
- data/stdlib/nodejs/node_modules/minimatch/package.json +63 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/once/node_modules/wrappy → once}/LICENSE +0 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/once → once}/README.md +28 -0
- data/stdlib/nodejs/node_modules/once/once.js +42 -0
- data/stdlib/nodejs/node_modules/once/package.json +67 -0
- data/stdlib/nodejs/node_modules/path-is-absolute/index.js +20 -0
- data/stdlib/nodejs/node_modules/path-is-absolute/license +21 -0
- data/stdlib/nodejs/node_modules/path-is-absolute/package.json +75 -0
- data/stdlib/nodejs/node_modules/path-is-absolute/readme.md +59 -0
- data/stdlib/nodejs/node_modules/unxhr/LICENSE +22 -0
- data/stdlib/nodejs/node_modules/unxhr/README.md +41 -0
- data/stdlib/nodejs/node_modules/unxhr/lib/XMLHttpRequest.js +598 -0
- data/stdlib/nodejs/node_modules/unxhr/lib/browser.js +2 -0
- data/stdlib/nodejs/node_modules/unxhr/lib/request.js +63 -0
- data/stdlib/nodejs/node_modules/unxhr/package.json +75 -0
- data/stdlib/nodejs/node_modules/wrappy/LICENSE +15 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/inflight/node_modules/wrappy → wrappy}/README.md +0 -0
- data/stdlib/nodejs/node_modules/wrappy/package.json +59 -0
- data/stdlib/nodejs/node_modules/{glob/node_modules/inflight/node_modules/wrappy → wrappy}/wrappy.js +0 -0
- data/stdlib/nodejs/open-uri.rb +26 -0
- data/stdlib/nodejs/package-lock.json +88 -0
- data/stdlib/nodejs/package.json +2 -1
- data/stdlib/nodejs/pathname.rb +20 -0
- data/stdlib/nodejs/require.rb +3 -3
- data/stdlib/nodejs/stacktrace.rb +1 -1
- data/stdlib/nodejs/yaml.rb +1 -1
- data/stdlib/opal-builder.rb +1 -0
- data/stdlib/opal-parser.rb +4 -1
- data/stdlib/opal-platform.rb +8 -10
- data/stdlib/opal-source-maps.rb +0 -1
- data/stdlib/open-uri.rb +349 -0
- data/stdlib/ostruct.rb +19 -17
- data/stdlib/pathname.rb +22 -22
- data/stdlib/pp.rb +5 -5
- data/stdlib/promise.rb +30 -26
- data/stdlib/rbconfig/sizeof.rb +50 -0
- data/stdlib/securerandom.rb +1 -1
- data/stdlib/set.rb +21 -23
- data/stdlib/singleton.rb +3 -4
- data/stdlib/stringio.rb +33 -0
- data/stdlib/strscan.rb +55 -55
- data/stdlib/template.rb +1 -2
- data/stdlib/thread.rb +6 -7
- data/tasks/benchmarking.rake +1 -1
- data/tasks/building.rake +4 -12
- data/tasks/linting.rake +17 -2
- data/tasks/releasing.rake +84 -0
- data/tasks/testing.rake +57 -15
- data/tasks/testing/mspec_special_calls.rb +23 -4
- data/vendored-minitest/minitest.rb +1 -1
- metadata +169 -168
- data/bin/opal-build +0 -3
- data/exe/opal-mspec +0 -10
- data/lib/opal/nodes/args/initialize_kwargs.rb +0 -29
- data/lib/opal/nodes/args/kwarg.rb +0 -31
- data/lib/opal/nodes/args/kwoptarg.rb +0 -34
- data/lib/opal/nodes/args/kwrestarg.rb +0 -39
- data/lib/opal/nodes/args/mlhsarg.rb +0 -78
- data/lib/opal/nodes/args/normarg.rb +0 -29
- data/lib/opal/nodes/args/optarg.rb +0 -25
- data/lib/opal/nodes/args/post_args.rb +0 -201
- data/lib/opal/nodes/args/post_kwargs.rb +0 -32
- data/lib/opal/nodes/args/restarg.rb +0 -38
- data/lib/opal/nodes/inline_args.rb +0 -60
- data/opal/corelib/string/inheritance.rb +0 -123
- data/stdlib/nodejs/node_modules/glob/node_modules/inflight/.eslintrc +0 -17
- data/stdlib/nodejs/node_modules/glob/node_modules/inflight/inflight.js +0 -44
- data/stdlib/nodejs/node_modules/glob/node_modules/inflight/node_modules/wrappy/package.json +0 -52
- data/stdlib/nodejs/node_modules/glob/node_modules/inflight/node_modules/wrappy/test/basic.js +0 -51
- data/stdlib/nodejs/node_modules/glob/node_modules/inflight/package.json +0 -61
- data/stdlib/nodejs/node_modules/glob/node_modules/inflight/test.js +0 -97
- data/stdlib/nodejs/node_modules/glob/node_modules/inherits/inherits.js +0 -1
- data/stdlib/nodejs/node_modules/glob/node_modules/inherits/package.json +0 -51
- data/stdlib/nodejs/node_modules/glob/node_modules/inherits/test.js +0 -25
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/.npmignore +0 -1
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/.travis.yml +0 -4
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/LICENSE +0 -23
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/benchmark.js +0 -15
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/browser.js +0 -1181
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/.npmignore +0 -2
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/.travis.yml +0 -3
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/example.js +0 -8
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match/.npmignore +0 -2
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match/.travis.yml +0 -4
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match/Makefile +0 -6
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match/example.js +0 -5
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match/index.js +0 -38
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/node_modules/balanced-match/test/balanced.js +0 -56
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/bash-comparison.js +0 -32
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/bash-results.txt +0 -1075
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/cases.txt +0 -182
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/dollar.js +0 -9
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/empty-option.js +0 -10
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/generate.sh +0 -24
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/negative-increment.js +0 -15
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/nested.js +0 -16
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/order.js +0 -10
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/pad.js +0 -13
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/same-type.js +0 -7
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/node_modules/brace-expansion/test/sequence.js +0 -50
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/package.json +0 -60
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/test/basic.js +0 -399
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/test/brace-expand.js +0 -45
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/test/defaults.js +0 -274
- data/stdlib/nodejs/node_modules/glob/node_modules/minimatch/test/extglob-ending-with-state-char.js +0 -8
- data/stdlib/nodejs/node_modules/glob/node_modules/once/LICENSE +0 -27
- data/stdlib/nodejs/node_modules/glob/node_modules/once/node_modules/wrappy/README.md +0 -36
- data/stdlib/nodejs/node_modules/glob/node_modules/once/node_modules/wrappy/package.json +0 -52
- data/stdlib/nodejs/node_modules/glob/node_modules/once/node_modules/wrappy/test/basic.js +0 -51
- data/stdlib/nodejs/node_modules/glob/node_modules/once/node_modules/wrappy/wrappy.js +0 -33
- data/stdlib/nodejs/node_modules/glob/node_modules/once/once.js +0 -21
- data/stdlib/nodejs/node_modules/glob/node_modules/once/package.json +0 -60
- data/stdlib/nodejs/node_modules/glob/node_modules/once/test/once.js +0 -23
- data/stdlib/nodejs/rubygems.rb +0 -68
- data/stdlib/source_map.rb +0 -5
- data/stdlib/source_map/map.rb +0 -220
- data/stdlib/source_map/mapping.rb +0 -26
- data/stdlib/source_map/offset.rb +0 -88
- data/stdlib/source_map/version.rb +0 -3
- data/stdlib/source_map/vlq.rb +0 -99
- data/stdlib/sourcemap.rb +0 -1
data/opal/corelib/rational.rb
CHANGED
@@ -6,7 +6,7 @@ class Rational < Numeric
|
|
6
6
|
den = den.to_i
|
7
7
|
|
8
8
|
if den == 0
|
9
|
-
raise ZeroDivisionError,
|
9
|
+
raise ZeroDivisionError, 'divided by 0'
|
10
10
|
elsif den < 0
|
11
11
|
num = -num
|
12
12
|
den = -den
|
@@ -21,7 +21,7 @@ class Rational < Numeric
|
|
21
21
|
|
22
22
|
def self.convert(num, den)
|
23
23
|
if num.nil? || den.nil?
|
24
|
-
raise TypeError,
|
24
|
+
raise TypeError, 'cannot convert nil into Rational'
|
25
25
|
end
|
26
26
|
|
27
27
|
if Integer === num && Integer === den
|
@@ -45,8 +45,6 @@ class Rational < Numeric
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
attr_reader :numerator, :denominator
|
49
|
-
|
50
48
|
def initialize(num, den)
|
51
49
|
@num = num
|
52
50
|
@den = den
|
@@ -189,31 +187,31 @@ class Rational < Numeric
|
|
189
187
|
case other
|
190
188
|
when Integer
|
191
189
|
if self == 0 && other < 0
|
192
|
-
|
190
|
+
Float::INFINITY
|
193
191
|
elsif other > 0
|
194
|
-
Rational(@num
|
192
|
+
Rational(@num**other, @den**other)
|
195
193
|
elsif other < 0
|
196
|
-
Rational(@den
|
194
|
+
Rational(@den**-other, @num**-other)
|
197
195
|
else
|
198
196
|
Rational(1, 1)
|
199
197
|
end
|
200
198
|
|
201
199
|
when Float
|
202
|
-
to_f
|
200
|
+
to_f**other
|
203
201
|
|
204
202
|
when Rational
|
205
203
|
if other == 0
|
206
204
|
Rational(1, 1)
|
207
205
|
elsif other.denominator == 1
|
208
206
|
if other < 0
|
209
|
-
Rational(@den
|
207
|
+
Rational(@den**other.numerator.abs, @num**other.numerator.abs)
|
210
208
|
else
|
211
|
-
Rational(@num
|
209
|
+
Rational(@num**other.numerator, @den**other.numerator)
|
212
210
|
end
|
213
211
|
elsif self == 0 && other < 0
|
214
|
-
raise ZeroDivisionError,
|
212
|
+
raise ZeroDivisionError, 'divided by 0'
|
215
213
|
else
|
216
|
-
to_f
|
214
|
+
to_f**other
|
217
215
|
end
|
218
216
|
|
219
217
|
else
|
@@ -244,11 +242,11 @@ class Rational < Numeric
|
|
244
242
|
end
|
245
243
|
|
246
244
|
def hash
|
247
|
-
"Rational
|
245
|
+
"Rational:#{@num}:#{@den}"
|
248
246
|
end
|
249
247
|
|
250
248
|
def inspect
|
251
|
-
"(#{
|
249
|
+
"(#{self})"
|
252
250
|
end
|
253
251
|
|
254
252
|
alias quo /
|
@@ -329,7 +327,7 @@ class Rational < Numeric
|
|
329
327
|
end
|
330
328
|
|
331
329
|
def to_s
|
332
|
-
"
|
330
|
+
"#{@num}/#{@den}"
|
333
331
|
end
|
334
332
|
|
335
333
|
def truncate(precision = 0)
|
@@ -341,9 +339,9 @@ class Rational < Numeric
|
|
341
339
|
end
|
342
340
|
|
343
341
|
def with_precision(method, precision)
|
344
|
-
raise TypeError,
|
342
|
+
raise TypeError, 'not an Integer' unless Integer === precision
|
345
343
|
|
346
|
-
p = 10
|
344
|
+
p = 10**precision
|
347
345
|
s = self * p
|
348
346
|
|
349
347
|
if precision < 1
|
@@ -359,3 +357,45 @@ module Kernel
|
|
359
357
|
Rational.convert(numerator, denominator)
|
360
358
|
end
|
361
359
|
end
|
360
|
+
|
361
|
+
class String
|
362
|
+
def to_r
|
363
|
+
%x{
|
364
|
+
var str = self.trimLeft(),
|
365
|
+
re = /^[+-]?[\d_]+(\.[\d_]+)?/,
|
366
|
+
match = str.match(re),
|
367
|
+
numerator, denominator;
|
368
|
+
|
369
|
+
function isFloat() {
|
370
|
+
return re.test(str);
|
371
|
+
}
|
372
|
+
|
373
|
+
function cutFloat() {
|
374
|
+
var match = str.match(re);
|
375
|
+
var number = match[0];
|
376
|
+
str = str.slice(number.length);
|
377
|
+
return number.replace(/_/g, '');
|
378
|
+
}
|
379
|
+
|
380
|
+
if (isFloat()) {
|
381
|
+
numerator = parseFloat(cutFloat());
|
382
|
+
|
383
|
+
if (str[0] === '/') {
|
384
|
+
// rational real part
|
385
|
+
str = str.slice(1);
|
386
|
+
|
387
|
+
if (isFloat()) {
|
388
|
+
denominator = parseFloat(cutFloat());
|
389
|
+
return #{Rational(`numerator`, `denominator`)};
|
390
|
+
} else {
|
391
|
+
return #{Rational(`numerator`, 1)};
|
392
|
+
}
|
393
|
+
} else {
|
394
|
+
return #{Rational(`numerator`, 1)};
|
395
|
+
}
|
396
|
+
} else {
|
397
|
+
return #{Rational(0, 1)};
|
398
|
+
}
|
399
|
+
}
|
400
|
+
end
|
401
|
+
end
|
data/opal/corelib/regexp.rb
CHANGED
@@ -2,9 +2,10 @@ class RegexpError < StandardError; end
|
|
2
2
|
|
3
3
|
class Regexp < `RegExp`
|
4
4
|
IGNORECASE = 1
|
5
|
+
EXTENDED = 2
|
5
6
|
MULTILINE = 4
|
6
7
|
|
7
|
-
`
|
8
|
+
`Opal.defineProperty(self.$$prototype, '$$is_regexp', true)`
|
8
9
|
|
9
10
|
class << self
|
10
11
|
def allocate
|
@@ -17,7 +18,7 @@ class Regexp < `RegExp`
|
|
17
18
|
`Opal.escape_regexp(string)`
|
18
19
|
end
|
19
20
|
|
20
|
-
def last_match(n=nil)
|
21
|
+
def last_match(n = nil)
|
21
22
|
if n.nil?
|
22
23
|
$~
|
23
24
|
else
|
@@ -33,6 +34,10 @@ class Regexp < `RegExp`
|
|
33
34
|
if (parts.length == 0) {
|
34
35
|
return /(?!)/;
|
35
36
|
}
|
37
|
+
// return fast if there's only one element
|
38
|
+
if (parts.length == 1 && parts[0].$$is_regexp) {
|
39
|
+
return parts[0];
|
40
|
+
}
|
36
41
|
// cover the 2 arrays passed as arguments case
|
37
42
|
is_first_part_array = parts[0].$$is_array;
|
38
43
|
if (parts.length > 1 && is_first_part_array) {
|
@@ -98,7 +103,7 @@ class Regexp < `RegExp`
|
|
98
103
|
end
|
99
104
|
|
100
105
|
def ==(other)
|
101
|
-
`other
|
106
|
+
`other instanceof RegExp && self.toString() === other.toString()`
|
102
107
|
end
|
103
108
|
|
104
109
|
def ===(string)
|
@@ -156,11 +161,18 @@ class Regexp < `RegExp`
|
|
156
161
|
}
|
157
162
|
|
158
163
|
if (pos === undefined) {
|
159
|
-
|
160
|
-
|
161
|
-
|
164
|
+
if (string === nil) return #{$~ = nil};
|
165
|
+
var m = self.exec(#{Opal.coerce_to(string, String, :to_str)});
|
166
|
+
if (m) {
|
167
|
+
#{$~ = MatchData.new(`self`, `m`)};
|
168
|
+
return block === nil ? #{$~} : #{yield $~};
|
169
|
+
} else {
|
170
|
+
return #{$~ = nil};
|
171
|
+
}
|
162
172
|
}
|
163
173
|
|
174
|
+
pos = #{Opal.coerce_to(pos, Integer, :to_int)};
|
175
|
+
|
164
176
|
if (string === nil) {
|
165
177
|
return #{$~ = nil};
|
166
178
|
}
|
@@ -174,16 +186,8 @@ class Regexp < `RegExp`
|
|
174
186
|
}
|
175
187
|
}
|
176
188
|
|
177
|
-
var source = self.source;
|
178
|
-
var flags = 'g';
|
179
|
-
// m flag + a . in Ruby will match white space, but in JS, it only matches beginning/ending of lines, so we get the equivalent here
|
180
|
-
if (self.multiline) {
|
181
|
-
source = source.replace('.', "[\\s\\S]");
|
182
|
-
flags += 'm';
|
183
|
-
}
|
184
|
-
|
185
189
|
// global RegExp maintains state, so not using self/this
|
186
|
-
var md, re =
|
190
|
+
var md, re = Opal.global_regexp(self);
|
187
191
|
|
188
192
|
while (true) {
|
189
193
|
md = re.exec(string);
|
@@ -191,8 +195,8 @@ class Regexp < `RegExp`
|
|
191
195
|
return #{$~ = nil};
|
192
196
|
}
|
193
197
|
if (md.index >= pos) {
|
194
|
-
#{$~ = MatchData.new(`re`, `md`)}
|
195
|
-
return block === nil ? #{$~} : #{
|
198
|
+
#{$~ = MatchData.new(`re`, `md`)};
|
199
|
+
return block === nil ? #{$~} : #{yield $~};
|
196
200
|
}
|
197
201
|
re.lastIndex = md.index + 1;
|
198
202
|
}
|
@@ -206,11 +210,11 @@ class Regexp < `RegExp`
|
|
206
210
|
}
|
207
211
|
|
208
212
|
if (pos === undefined) {
|
209
|
-
|
210
|
-
} else {
|
211
|
-
pos = #{Opal.coerce_to(pos, Integer, :to_int)};
|
213
|
+
return string === nil ? false : self.test(#{Opal.coerce_to(string, String, :to_str)});
|
212
214
|
}
|
213
215
|
|
216
|
+
pos = #{Opal.coerce_to(pos, Integer, :to_int)};
|
217
|
+
|
214
218
|
if (string === nil) {
|
215
219
|
return false;
|
216
220
|
}
|
@@ -224,16 +228,8 @@ class Regexp < `RegExp`
|
|
224
228
|
}
|
225
229
|
}
|
226
230
|
|
227
|
-
var source = self.source;
|
228
|
-
var flags = 'g';
|
229
|
-
// m flag + a . in Ruby will match white space, but in JS, it only matches beginning/ending of lines, so we get the equivalent here
|
230
|
-
if (self.multiline) {
|
231
|
-
source = source.replace('.', "[\\s\\S]");
|
232
|
-
flags += 'm';
|
233
|
-
}
|
234
|
-
|
235
231
|
// global RegExp maintains state, so not using self/this
|
236
|
-
var md, re =
|
232
|
+
var md, re = Opal.global_regexp(self);
|
237
233
|
|
238
234
|
md = re.exec(string);
|
239
235
|
if (md === null || md.index < pos) {
|
@@ -294,10 +290,10 @@ class MatchData
|
|
294
290
|
var group = match_groups[i];
|
295
291
|
|
296
292
|
if (group == null) {
|
297
|
-
|
293
|
+
#{@matches}.push(nil);
|
298
294
|
}
|
299
295
|
else {
|
300
|
-
|
296
|
+
#{@matches}.push(group);
|
301
297
|
}
|
302
298
|
}
|
303
299
|
}
|
@@ -320,10 +316,10 @@ class MatchData
|
|
320
316
|
return false unless MatchData === other
|
321
317
|
|
322
318
|
`self.string == other.string` &&
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
319
|
+
`self.regexp.toString() == other.regexp.toString()` &&
|
320
|
+
`self.pre_match == other.pre_match` &&
|
321
|
+
`self.post_match == other.post_match` &&
|
322
|
+
`self.begin == other.begin`
|
327
323
|
end
|
328
324
|
|
329
325
|
alias eql? ==
|
@@ -347,15 +343,15 @@ class MatchData
|
|
347
343
|
end
|
348
344
|
|
349
345
|
def captures
|
350
|
-
|
346
|
+
`#{@matches}.slice(1)`
|
351
347
|
end
|
352
348
|
|
353
349
|
def inspect
|
354
350
|
%x{
|
355
|
-
var str = "#<MatchData " + #{
|
351
|
+
var str = "#<MatchData " + #{`#{@matches}[0]`.inspect};
|
356
352
|
|
357
|
-
for (var i = 1, length =
|
358
|
-
str += " " + i + ":" + #{
|
353
|
+
for (var i = 1, length = #{@matches}.length; i < length; i++) {
|
354
|
+
str += " " + i + ":" + #{`#{@matches}[i]`.inspect};
|
359
355
|
}
|
360
356
|
|
361
357
|
return str + ">";
|
@@ -363,7 +359,7 @@ class MatchData
|
|
363
359
|
end
|
364
360
|
|
365
361
|
def length
|
366
|
-
|
362
|
+
`#{@matches}.length`
|
367
363
|
end
|
368
364
|
|
369
365
|
alias size length
|
@@ -373,7 +369,7 @@ class MatchData
|
|
373
369
|
end
|
374
370
|
|
375
371
|
def to_s
|
376
|
-
|
372
|
+
`#{@matches}[0]`
|
377
373
|
end
|
378
374
|
|
379
375
|
def values_at(*args)
|
@@ -391,14 +387,14 @@ class MatchData
|
|
391
387
|
index = #{Opal.coerce_to!(`args[i]`, Integer, :to_int)};
|
392
388
|
|
393
389
|
if (index < 0) {
|
394
|
-
index +=
|
390
|
+
index += #{@matches}.length;
|
395
391
|
if (index < 0) {
|
396
392
|
values.push(nil);
|
397
393
|
continue;
|
398
394
|
}
|
399
395
|
}
|
400
396
|
|
401
|
-
values.push(
|
397
|
+
values.push(#{@matches}[index]);
|
402
398
|
}
|
403
399
|
|
404
400
|
return values;
|
data/opal/corelib/runtime.js
CHANGED
@@ -51,27 +51,9 @@
|
|
51
51
|
// The actual Class class
|
52
52
|
var Class;
|
53
53
|
|
54
|
-
// Constructor for instances of BasicObject
|
55
|
-
function BasicObject_alloc(){}
|
56
|
-
|
57
|
-
// Constructor for instances of Object
|
58
|
-
function Object_alloc(){}
|
59
|
-
|
60
|
-
// Constructor for instances of Class
|
61
|
-
function Class_alloc(){}
|
62
|
-
|
63
|
-
// Constructor for instances of Module
|
64
|
-
function Module_alloc(){}
|
65
|
-
|
66
|
-
// Constructor for instances of NilClass (nil)
|
67
|
-
function NilClass_alloc(){}
|
68
|
-
|
69
54
|
// The Opal object that is exposed globally
|
70
55
|
var Opal = this.Opal = {};
|
71
56
|
|
72
|
-
// All bridged classes - keep track to donate methods from Object
|
73
|
-
var BridgedClasses = {};
|
74
|
-
|
75
57
|
// This is a useful reference to global object inside ruby files
|
76
58
|
Opal.global = global_object;
|
77
59
|
global_object.Opal = Opal;
|
@@ -84,8 +66,11 @@
|
|
84
66
|
}
|
85
67
|
|
86
68
|
// Minify common function calls
|
87
|
-
var $hasOwn
|
88
|
-
var $
|
69
|
+
var $hasOwn = Object.hasOwnProperty;
|
70
|
+
var $bind = Function.prototype.bind;
|
71
|
+
var $setPrototype = Object.setPrototypeOf;
|
72
|
+
var $slice = Array.prototype.slice;
|
73
|
+
var $splice = Array.prototype.splice;
|
89
74
|
|
90
75
|
// Nil object id is always 4
|
91
76
|
var nil_id = 4;
|
@@ -103,7 +88,11 @@
|
|
103
88
|
// Retrieve or assign the id of an object
|
104
89
|
Opal.id = function(obj) {
|
105
90
|
if (obj.$$is_number) return (obj * 2)+1;
|
106
|
-
|
91
|
+
if (obj.$$id != null) {
|
92
|
+
return obj.$$id;
|
93
|
+
};
|
94
|
+
$defineProperty(obj, '$$id', Opal.uid());
|
95
|
+
return obj.$$id;
|
107
96
|
};
|
108
97
|
|
109
98
|
// Globals table
|
@@ -138,6 +127,30 @@
|
|
138
127
|
}
|
139
128
|
}
|
140
129
|
|
130
|
+
function $defineProperty(object, name, initialValue) {
|
131
|
+
if (typeof(object) === "string") {
|
132
|
+
// Special case for:
|
133
|
+
// s = "string"
|
134
|
+
// def s.m; end
|
135
|
+
// String class is the only class that:
|
136
|
+
// + compiles to JS primitive
|
137
|
+
// + allows method definition directly on instances
|
138
|
+
// numbers, true, false and nil do not support it.
|
139
|
+
object[name] = initialValue;
|
140
|
+
} else {
|
141
|
+
Object.defineProperty(object, name, {
|
142
|
+
value: initialValue,
|
143
|
+
enumerable: false,
|
144
|
+
configurable: true,
|
145
|
+
writable: true
|
146
|
+
});
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
Opal.defineProperty = $defineProperty;
|
151
|
+
|
152
|
+
Opal.slice = $slice;
|
153
|
+
|
141
154
|
|
142
155
|
// Truth
|
143
156
|
// -----
|
@@ -220,7 +233,7 @@
|
|
220
233
|
|
221
234
|
if (cref === '::') cref = _Object;
|
222
235
|
|
223
|
-
if (!cref.$$
|
236
|
+
if (!cref.$$is_module && !cref.$$is_class) {
|
224
237
|
throw new Opal.TypeError(cref.toString() + " is not a class/module");
|
225
238
|
}
|
226
239
|
|
@@ -237,12 +250,13 @@
|
|
237
250
|
|
238
251
|
if (cref === '::') cref = _Object;
|
239
252
|
|
240
|
-
if (!cref.$$
|
253
|
+
if (!cref.$$is_module && !cref.$$is_class) {
|
241
254
|
throw new Opal.TypeError(cref.toString() + " is not a class/module");
|
242
255
|
}
|
243
256
|
|
244
257
|
if ((cache = cref.$$const_cache) == null) {
|
245
|
-
|
258
|
+
$defineProperty(cref, '$$const_cache', Object.create(null));
|
259
|
+
cache = cref.$$const_cache;
|
246
260
|
}
|
247
261
|
cached = cache[name];
|
248
262
|
|
@@ -266,7 +280,8 @@
|
|
266
280
|
var cref = nesting[0], result, current_version = Opal.const_cache_version, cache, cached;
|
267
281
|
|
268
282
|
if ((cache = nesting.$$const_cache) == null) {
|
269
|
-
|
283
|
+
$defineProperty(nesting, '$$const_cache', Object.create(null));
|
284
|
+
cache = nesting.$$const_cache;
|
270
285
|
}
|
271
286
|
cached = cache[name];
|
272
287
|
|
@@ -297,11 +312,19 @@
|
|
297
312
|
cref.$$const = (cref.$$const || Object.create(null));
|
298
313
|
cref.$$const[name] = value;
|
299
314
|
|
315
|
+
// Add a short helper to navigate constants manually.
|
316
|
+
// @example
|
317
|
+
// Opal.$$.Regexp.$$.IGNORECASE
|
318
|
+
cref.$$ = cref.$$const;
|
319
|
+
|
300
320
|
Opal.const_cache_version++;
|
301
321
|
|
302
322
|
// Expose top level constants onto the Opal object
|
303
323
|
if (cref === _Object) Opal[name] = value;
|
304
324
|
|
325
|
+
// Name new class directly onto current scope (Opal.Foo.Baz = klass)
|
326
|
+
$defineProperty(cref, name, value);
|
327
|
+
|
305
328
|
return value;
|
306
329
|
};
|
307
330
|
|
@@ -364,38 +387,81 @@
|
|
364
387
|
// simply so that classes show up with nicely formatted names inside debuggers
|
365
388
|
// in the web browser (or node/sprockets).
|
366
389
|
//
|
367
|
-
// The `
|
390
|
+
// The `scope` is the current `self` value where the class is being created
|
368
391
|
// from. We use this to get the scope for where the class should be created.
|
369
|
-
// If `
|
370
|
-
// use that as the
|
392
|
+
// If `scope` is an object (not a class/module), we simple get its class and
|
393
|
+
// use that as the scope instead.
|
371
394
|
//
|
372
|
-
// @param
|
395
|
+
// @param scope [Object] where the class is being created
|
373
396
|
// @param superclass [Class,null] superclass of the new class (may be null)
|
374
397
|
// @param id [String] the name of the class to be created
|
375
398
|
// @param constructor [JS.Function] function to use as constructor
|
376
399
|
//
|
377
400
|
// @return new [Class] or existing ruby class
|
378
401
|
//
|
379
|
-
Opal.
|
380
|
-
var klass,
|
402
|
+
Opal.allocate_class = function(name, superclass) {
|
403
|
+
var klass, constructor;
|
404
|
+
|
405
|
+
if (superclass != null && superclass.$$bridge) {
|
406
|
+
// Inheritance from bridged classes requires
|
407
|
+
// calling original JS constructors
|
408
|
+
constructor = function() {
|
409
|
+
var args = $slice.call(arguments),
|
410
|
+
self = new ($bind.apply(superclass.$$constructor, [null].concat(args)))();
|
381
411
|
|
382
|
-
|
383
|
-
|
412
|
+
// and replacing a __proto__ manually
|
413
|
+
$setPrototype(self, klass.$$prototype);
|
414
|
+
return self;
|
415
|
+
}
|
416
|
+
} else {
|
417
|
+
constructor = function(){};
|
384
418
|
}
|
385
419
|
|
386
|
-
|
387
|
-
|
388
|
-
base = base.$$class;
|
420
|
+
if (name) {
|
421
|
+
$defineProperty(constructor, 'displayName', '::'+name);
|
389
422
|
}
|
390
423
|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
424
|
+
klass = constructor;
|
425
|
+
|
426
|
+
$defineProperty(klass, '$$name', name);
|
427
|
+
$defineProperty(klass, '$$constructor', constructor);
|
428
|
+
$defineProperty(klass, '$$prototype', constructor.prototype);
|
429
|
+
$defineProperty(klass, '$$const', {});
|
430
|
+
$defineProperty(klass, '$$is_class', true);
|
431
|
+
$defineProperty(klass, '$$is_a_module', true);
|
432
|
+
$defineProperty(klass, '$$super', superclass);
|
433
|
+
$defineProperty(klass, '$$cvars', {});
|
434
|
+
$defineProperty(klass, '$$own_included_modules', []);
|
435
|
+
$defineProperty(klass, '$$own_prepended_modules', []);
|
436
|
+
$defineProperty(klass, '$$ancestors', []);
|
437
|
+
$defineProperty(klass, '$$ancestors_cache_version', null);
|
438
|
+
|
439
|
+
$defineProperty(klass.$$prototype, '$$class', klass);
|
440
|
+
|
441
|
+
// By default if there are no singleton class methods
|
442
|
+
// __proto__ is Class.prototype
|
443
|
+
// Later singleton methods generate a singleton_class
|
444
|
+
// and inject it into ancestors chain
|
445
|
+
if (Opal.Class) {
|
446
|
+
$setPrototype(klass, Opal.Class.prototype);
|
395
447
|
}
|
396
448
|
|
449
|
+
if (superclass != null) {
|
450
|
+
$setPrototype(klass.$$prototype, superclass.$$prototype);
|
451
|
+
|
452
|
+
if (superclass.$$meta) {
|
453
|
+
// If superclass has metaclass then we have explicitely inherit it.
|
454
|
+
Opal.build_class_singleton_class(klass);
|
455
|
+
}
|
456
|
+
};
|
457
|
+
|
458
|
+
return klass;
|
459
|
+
}
|
460
|
+
|
461
|
+
|
462
|
+
function find_existing_class(scope, name) {
|
397
463
|
// Try to find the class in the current scope
|
398
|
-
klass = const_get_name(
|
464
|
+
var klass = const_get_name(scope, name);
|
399
465
|
|
400
466
|
// If the class exists in the scope, then we must use that
|
401
467
|
if (klass) {
|
@@ -404,271 +470,149 @@
|
|
404
470
|
throw Opal.TypeError.$new(name + " is not a class");
|
405
471
|
}
|
406
472
|
|
407
|
-
// Make sure existing class has same superclass
|
408
|
-
if (superclass && klass.$$super !== superclass) {
|
409
|
-
throw Opal.TypeError.$new("superclass mismatch for class " + name);
|
410
|
-
}
|
411
|
-
|
412
473
|
return klass;
|
413
474
|
}
|
475
|
+
}
|
414
476
|
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
if (superclass == null) {
|
419
|
-
superclass = _Object;
|
477
|
+
function ensureSuperclassMatch(klass, superclass) {
|
478
|
+
if (klass.$$super !== superclass) {
|
479
|
+
throw Opal.TypeError.$new("superclass mismatch for class " + klass.$$name);
|
420
480
|
}
|
481
|
+
}
|
421
482
|
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
// Create the class object (instance of Class)
|
426
|
-
klass = Opal.setup_class_object(name, alloc, superclass.$$name, superclass.constructor);
|
427
|
-
|
428
|
-
// @property $$super the superclass, doesn't get changed by module inclusions
|
429
|
-
klass.$$super = superclass;
|
483
|
+
Opal.klass = function(scope, superclass, name) {
|
484
|
+
var bridged;
|
430
485
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
486
|
+
if (scope == null) {
|
487
|
+
// Global scope
|
488
|
+
scope = _Object;
|
489
|
+
} else if (!scope.$$is_class && !scope.$$is_module) {
|
490
|
+
// Scope is an object, use its class
|
491
|
+
scope = scope.$$class;
|
492
|
+
}
|
435
493
|
|
436
|
-
Opal
|
494
|
+
// If the superclass is not an Opal-generated class then we're bridging a native JS class
|
495
|
+
if (superclass != null && !superclass.hasOwnProperty('$$is_class')) {
|
496
|
+
bridged = superclass;
|
497
|
+
superclass = _Object;
|
498
|
+
}
|
437
499
|
|
438
|
-
|
439
|
-
base[name] = klass;
|
500
|
+
var klass = find_existing_class(scope, name);
|
440
501
|
|
441
|
-
if (
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
// Call .inherited() hook with new class on the superclass
|
446
|
-
if (superclass.$inherited) {
|
447
|
-
superclass.$inherited(klass);
|
502
|
+
if (klass) {
|
503
|
+
if (superclass) {
|
504
|
+
// Make sure existing class has same superclass
|
505
|
+
ensureSuperclassMatch(klass, superclass);
|
448
506
|
}
|
507
|
+
return klass;
|
449
508
|
}
|
450
509
|
|
451
|
-
|
452
|
-
};
|
510
|
+
// Class doesn't exist, create a new one with given superclass...
|
453
511
|
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
// @param constructor [JS.Function] the class' instances constructor/alloc function
|
458
|
-
// @param superclass [Class,null] the superclass object
|
459
|
-
// @return [JS.Function] the consturctor holding the prototype for the class' instances
|
460
|
-
Opal.boot_class_alloc = function(name, constructor, superclass) {
|
461
|
-
if (superclass) {
|
462
|
-
var alloc_proxy = function() {};
|
463
|
-
alloc_proxy.prototype = superclass.$$proto || superclass.prototype;
|
464
|
-
constructor.prototype = new alloc_proxy();
|
465
|
-
}
|
466
|
-
|
467
|
-
if (name) {
|
468
|
-
constructor.displayName = name+'_alloc';
|
512
|
+
// Not specifying a superclass means we can assume it to be Object
|
513
|
+
if (superclass == null) {
|
514
|
+
superclass = _Object;
|
469
515
|
}
|
470
516
|
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
};
|
475
|
-
|
476
|
-
Opal.setup_module_or_class = function(module) {
|
477
|
-
// @property $$id Each class/module is assigned a unique `id` that helps
|
478
|
-
// comparation and implementation of `#object_id`
|
479
|
-
module.$$id = Opal.uid();
|
480
|
-
|
481
|
-
// @property $$is_a_module Will be true for Module and its subclasses
|
482
|
-
// instances (namely: Class).
|
483
|
-
module.$$is_a_module = true;
|
484
|
-
|
485
|
-
// @property $$inc included modules
|
486
|
-
module.$$inc = [];
|
487
|
-
|
488
|
-
// initialize the name with nil
|
489
|
-
module.$$name = nil;
|
490
|
-
|
491
|
-
// Initialize the constants table
|
492
|
-
module.$$const = Object.create(null);
|
493
|
-
|
494
|
-
// @property $$cvars class variables defined in the current module
|
495
|
-
module.$$cvars = Object.create(null);
|
496
|
-
}
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
// Adds common/required properties to class object (as in `Class.new`)
|
501
|
-
//
|
502
|
-
// @param name [String,null] The name of the class
|
503
|
-
//
|
504
|
-
// @param alloc [JS.Function] The constructor of the class' instances
|
505
|
-
//
|
506
|
-
// @param superclass_name [String,null]
|
507
|
-
// The name of the super class, this is
|
508
|
-
// usefule to build the `.displayName` of the singleton class
|
509
|
-
//
|
510
|
-
// @param superclass_alloc [JS.Function]
|
511
|
-
// The constructor of the superclass from which the singleton_class is
|
512
|
-
// derived.
|
513
|
-
//
|
514
|
-
// @return [Class]
|
515
|
-
Opal.setup_class_object = function(name, alloc, superclass_name, superclass_alloc) {
|
516
|
-
// Grab the superclass prototype and use it to build an intermediary object
|
517
|
-
// in the prototype chain.
|
518
|
-
var superclass_alloc_proxy = function() {};
|
519
|
-
superclass_alloc_proxy.prototype = superclass_alloc.prototype;
|
520
|
-
superclass_alloc_proxy.displayName = superclass_name;
|
521
|
-
|
522
|
-
var singleton_class_alloc = function() {}
|
523
|
-
singleton_class_alloc.prototype = new superclass_alloc_proxy();
|
524
|
-
|
525
|
-
// The built class is the only instance of its singleton_class
|
526
|
-
var klass = new singleton_class_alloc();
|
527
|
-
|
528
|
-
Opal.setup_module_or_class(klass);
|
529
|
-
|
530
|
-
// @property $$alloc This is the constructor of instances of the current
|
531
|
-
// class. Its prototype will be used for method lookup
|
532
|
-
klass.$$alloc = alloc;
|
533
|
-
|
534
|
-
klass.$$name = name || nil;
|
535
|
-
|
536
|
-
// Set a displayName for the singleton_class
|
537
|
-
singleton_class_alloc.displayName = "#<Class:"+(name || ("#<Class:"+klass.$$id+">"))+">";
|
538
|
-
|
539
|
-
// @property $$proto This is the prototype on which methods will be defined
|
540
|
-
klass.$$proto = alloc.prototype;
|
541
|
-
|
542
|
-
// @property $$proto.$$class Make available to instances a reference to the
|
543
|
-
// class they belong to.
|
544
|
-
klass.$$proto.$$class = klass;
|
545
|
-
|
546
|
-
// @property constructor keeps a ref to the constructor, but apparently the
|
547
|
-
// constructor is already set on:
|
548
|
-
//
|
549
|
-
// `var klass = new constructor` is called.
|
550
|
-
//
|
551
|
-
// Maybe there are some browsers not abiding (IE6?)
|
552
|
-
klass.constructor = singleton_class_alloc;
|
517
|
+
// Create the class object (instance of Class)
|
518
|
+
klass = Opal.allocate_class(name, superclass);
|
519
|
+
Opal.const_set(scope, name, klass);
|
553
520
|
|
554
|
-
//
|
555
|
-
|
521
|
+
// Call .inherited() hook with new class on the superclass
|
522
|
+
if (superclass.$inherited) {
|
523
|
+
superclass.$inherited(klass);
|
524
|
+
}
|
556
525
|
|
557
|
-
|
558
|
-
|
526
|
+
if (bridged) {
|
527
|
+
Opal.bridge(bridged, klass);
|
528
|
+
}
|
559
529
|
|
560
530
|
return klass;
|
561
|
-
}
|
531
|
+
}
|
562
532
|
|
563
|
-
// Define new module (or return existing module). The given `
|
533
|
+
// Define new module (or return existing module). The given `scope` is basically
|
564
534
|
// the current `self` value the `module` statement was defined in. If this is
|
565
|
-
// a ruby module or class, then it is used, otherwise if the
|
566
|
-
// object then that objects real ruby class is used (e.g. if the
|
567
|
-
// main object, then the top level `Object` class is used as the
|
535
|
+
// a ruby module or class, then it is used, otherwise if the scope is a ruby
|
536
|
+
// object then that objects real ruby class is used (e.g. if the scope is the
|
537
|
+
// main object, then the top level `Object` class is used as the scope).
|
568
538
|
//
|
569
|
-
// If a module of the given name is already defined in the
|
539
|
+
// If a module of the given name is already defined in the scope, then that
|
570
540
|
// instance is just returned.
|
571
541
|
//
|
572
|
-
// If there is a class of the given name in the
|
573
|
-
// generated instead (cannot have a class and module of same name in same
|
542
|
+
// If there is a class of the given name in the scope, then an error is
|
543
|
+
// generated instead (cannot have a class and module of same name in same scope).
|
574
544
|
//
|
575
|
-
// Otherwise, a new module is created in the
|
545
|
+
// Otherwise, a new module is created in the scope with the given name, and that
|
576
546
|
// new instance is returned back (to be referenced at runtime).
|
577
547
|
//
|
578
|
-
// @param
|
548
|
+
// @param scope [Module, Class] class or module this definition is inside
|
579
549
|
// @param id [String] the name of the new (or existing) module
|
580
550
|
//
|
581
551
|
// @return [Module]
|
582
|
-
Opal.
|
583
|
-
var
|
584
|
-
|
585
|
-
|
586
|
-
base = _Object;
|
552
|
+
Opal.allocate_module = function(name) {
|
553
|
+
var constructor = function(){};
|
554
|
+
if (name) {
|
555
|
+
$defineProperty(constructor, 'displayName', name+'.$$constructor');
|
587
556
|
}
|
588
557
|
|
589
|
-
|
590
|
-
base = base.$$class;
|
591
|
-
}
|
558
|
+
var module = constructor;
|
592
559
|
|
593
|
-
|
594
|
-
|
560
|
+
if (name)
|
561
|
+
$defineProperty(constructor, 'displayName', name+'.constructor');
|
562
|
+
|
563
|
+
$defineProperty(module, '$$name', name);
|
564
|
+
$defineProperty(module, '$$prototype', constructor.prototype);
|
565
|
+
$defineProperty(module, '$$const', {});
|
566
|
+
$defineProperty(module, '$$is_module', true);
|
567
|
+
$defineProperty(module, '$$is_a_module', true);
|
568
|
+
$defineProperty(module, '$$cvars', {});
|
569
|
+
$defineProperty(module, '$$iclasses', []);
|
570
|
+
$defineProperty(module, '$$own_included_modules', []);
|
571
|
+
$defineProperty(module, '$$own_prepended_modules', []);
|
572
|
+
$defineProperty(module, '$$ancestors', [module]);
|
573
|
+
$defineProperty(module, '$$ancestors_cache_version', null);
|
574
|
+
|
575
|
+
$setPrototype(module, Opal.Module.prototype);
|
576
|
+
|
577
|
+
return module;
|
578
|
+
}
|
579
|
+
|
580
|
+
function find_existing_module(scope, name) {
|
581
|
+
var module = const_get_name(scope, name);
|
582
|
+
if (module == null && scope === _Object) module = const_lookup_ancestors(_Object, name);
|
595
583
|
|
596
584
|
if (module) {
|
597
585
|
if (!module.$$is_module && module !== _Object) {
|
598
586
|
throw Opal.TypeError.$new(name + " is not a module");
|
599
587
|
}
|
600
588
|
}
|
601
|
-
else {
|
602
|
-
module = Opal.module_allocate(Module);
|
603
|
-
Opal.const_set(base, name, module);
|
604
|
-
}
|
605
589
|
|
606
590
|
return module;
|
607
|
-
}
|
608
|
-
|
609
|
-
// The implementation for Module#initialize
|
610
|
-
// @param module [Module]
|
611
|
-
// @param block [Proc,nil]
|
612
|
-
// @return nil
|
613
|
-
Opal.module_initialize = function(module, block) {
|
614
|
-
if (block !== nil) {
|
615
|
-
var block_self = block.$$s;
|
616
|
-
block.$$s = null;
|
617
|
-
block.call(module);
|
618
|
-
block.$$s = block_self;
|
619
|
-
}
|
620
|
-
return nil;
|
621
|
-
};
|
622
|
-
|
623
|
-
// Internal function to create a new module instance. This simply sets up
|
624
|
-
// the prototype hierarchy and method tables.
|
625
|
-
//
|
626
|
-
Opal.module_allocate = function(superclass) {
|
627
|
-
var mtor = function() {};
|
628
|
-
mtor.prototype = superclass.$$alloc.prototype;
|
629
|
-
|
630
|
-
var module_constructor = function() {};
|
631
|
-
module_constructor.prototype = new mtor();
|
632
|
-
|
633
|
-
var module = new module_constructor();
|
634
|
-
var module_prototype = {};
|
635
|
-
|
636
|
-
Opal.setup_module_or_class(module);
|
637
|
-
|
638
|
-
// initialize dependency tracking
|
639
|
-
module.$$included_in = [];
|
640
|
-
|
641
|
-
// Set the display name of the singleton prototype holder
|
642
|
-
module_constructor.displayName = "#<Class:#<Module:"+module.$$id+">>"
|
591
|
+
}
|
643
592
|
|
644
|
-
|
645
|
-
module
|
593
|
+
Opal.module = function(scope, name) {
|
594
|
+
var module;
|
646
595
|
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
module.constructor = module_constructor;
|
596
|
+
if (scope == null) {
|
597
|
+
// Global scope
|
598
|
+
scope = _Object;
|
599
|
+
} else if (!scope.$$is_class && !scope.$$is_module) {
|
600
|
+
// Scope is an object, use its class
|
601
|
+
scope = scope.$$class;
|
602
|
+
}
|
655
603
|
|
656
|
-
|
657
|
-
module.$$is_module = true;
|
658
|
-
module.$$class = Module;
|
604
|
+
module = find_existing_module(scope, name);
|
659
605
|
|
660
|
-
|
661
|
-
|
662
|
-
|
606
|
+
if (module) {
|
607
|
+
return module;
|
608
|
+
}
|
663
609
|
|
664
|
-
//
|
665
|
-
|
666
|
-
|
667
|
-
// the last included module
|
668
|
-
module.$$parent = superclass;
|
610
|
+
// Module doesnt exist, create a new one...
|
611
|
+
module = Opal.allocate_module(name);
|
612
|
+
Opal.const_set(scope, name, module);
|
669
613
|
|
670
614
|
return module;
|
671
|
-
}
|
615
|
+
}
|
672
616
|
|
673
617
|
// Return the singleton class for the passed object.
|
674
618
|
//
|
@@ -686,11 +630,13 @@
|
|
686
630
|
return object.$$meta;
|
687
631
|
}
|
688
632
|
|
689
|
-
if (object
|
633
|
+
if (object.hasOwnProperty('$$is_class')) {
|
690
634
|
return Opal.build_class_singleton_class(object);
|
635
|
+
} else if (object.hasOwnProperty('$$is_module')) {
|
636
|
+
return Opal.build_module_singletin_class(object);
|
637
|
+
} else {
|
638
|
+
return Opal.build_object_singleton_class(object);
|
691
639
|
}
|
692
|
-
|
693
|
-
return Opal.build_object_singleton_class(object);
|
694
640
|
};
|
695
641
|
|
696
642
|
// Build the singleton class for an existing class. Class object are built
|
@@ -702,54 +648,146 @@
|
|
702
648
|
//
|
703
649
|
// @param klass [Class]
|
704
650
|
// @return [Class]
|
705
|
-
Opal.build_class_singleton_class = function(
|
706
|
-
var
|
651
|
+
Opal.build_class_singleton_class = function(klass) {
|
652
|
+
var superclass, meta;
|
707
653
|
|
708
|
-
if (
|
709
|
-
return
|
654
|
+
if (klass.$$meta) {
|
655
|
+
return klass.$$meta;
|
710
656
|
}
|
711
657
|
|
712
|
-
// The constructor and prototype of the singleton_class instances is the
|
713
|
-
// current class constructor and prototype.
|
714
|
-
alloc = object.constructor;
|
715
|
-
|
716
658
|
// The singleton_class superclass is the singleton_class of its superclass;
|
717
659
|
// but BasicObject has no superclass (its `$$super` is null), thus we
|
718
660
|
// fallback on `Class`.
|
719
|
-
superclass =
|
661
|
+
superclass = klass === BasicObject ? Class : Opal.get_singleton_class(klass.$$super);
|
720
662
|
|
721
|
-
|
722
|
-
klass.$$super = superclass;
|
723
|
-
klass.$$parent = superclass;
|
663
|
+
meta = Opal.allocate_class(null, superclass, function(){});
|
724
664
|
|
725
|
-
|
726
|
-
|
665
|
+
$defineProperty(meta, '$$is_singleton', true);
|
666
|
+
$defineProperty(meta, '$$singleton_of', klass);
|
667
|
+
$defineProperty(klass, '$$meta', meta);
|
668
|
+
$setPrototype(klass, meta.$$prototype);
|
669
|
+
// Restoring ClassName.class
|
670
|
+
$defineProperty(klass, '$$class', Opal.Class);
|
727
671
|
|
728
|
-
return
|
672
|
+
return meta;
|
729
673
|
};
|
730
674
|
|
675
|
+
Opal.build_module_singletin_class = function(mod) {
|
676
|
+
if (mod.$$meta) {
|
677
|
+
return mod.$$meta;
|
678
|
+
}
|
679
|
+
|
680
|
+
var meta = Opal.allocate_class(null, Opal.Module, function(){});
|
681
|
+
|
682
|
+
$defineProperty(meta, '$$is_singleton', true);
|
683
|
+
$defineProperty(meta, '$$singleton_of', mod);
|
684
|
+
$defineProperty(mod, '$$meta', meta);
|
685
|
+
$setPrototype(mod, meta.$$prototype);
|
686
|
+
// Restoring ModuleName.class
|
687
|
+
$defineProperty(mod, '$$class', Opal.Module);
|
688
|
+
|
689
|
+
return meta;
|
690
|
+
}
|
691
|
+
|
731
692
|
// Build the singleton class for a Ruby (non class) Object.
|
732
693
|
//
|
733
694
|
// @param object [Object]
|
734
695
|
// @return [Class]
|
735
696
|
Opal.build_object_singleton_class = function(object) {
|
736
697
|
var superclass = object.$$class,
|
737
|
-
|
698
|
+
klass = Opal.allocate_class(nil, superclass, function(){});
|
738
699
|
|
739
|
-
|
740
|
-
|
700
|
+
$defineProperty(klass, '$$is_singleton', true);
|
701
|
+
$defineProperty(klass, '$$singleton_of', object);
|
741
702
|
|
742
|
-
klass.$$
|
743
|
-
klass.$$parent = superclass;
|
744
|
-
klass.$$class = superclass.$$class;
|
745
|
-
klass.$$proto = object;
|
703
|
+
delete klass.$$prototype.$$class;
|
746
704
|
|
747
|
-
|
748
|
-
klass.$$singleton_of = object;
|
705
|
+
$defineProperty(object, '$$meta', klass);
|
749
706
|
|
750
|
-
|
707
|
+
$setPrototype(object, object.$$meta.$$prototype);
|
708
|
+
|
709
|
+
return klass;
|
751
710
|
};
|
752
711
|
|
712
|
+
Opal.is_method = function(prop) {
|
713
|
+
return (prop[0] === '$' && prop[1] !== '$');
|
714
|
+
}
|
715
|
+
|
716
|
+
Opal.instance_methods = function(mod) {
|
717
|
+
var exclude = [], results = [], ancestors = Opal.ancestors(mod);
|
718
|
+
|
719
|
+
for (var i = 0, l = ancestors.length; i < l; i++) {
|
720
|
+
var ancestor = ancestors[i],
|
721
|
+
proto = ancestor.$$prototype;
|
722
|
+
|
723
|
+
if (proto.hasOwnProperty('$$dummy')) {
|
724
|
+
proto = proto.$$define_methods_on;
|
725
|
+
}
|
726
|
+
|
727
|
+
var props = Object.getOwnPropertyNames(proto);
|
728
|
+
|
729
|
+
for (var j = 0, ll = props.length; j < ll; j++) {
|
730
|
+
var prop = props[j];
|
731
|
+
|
732
|
+
if (Opal.is_method(prop)) {
|
733
|
+
var method_name = prop.slice(1),
|
734
|
+
method = proto[prop];
|
735
|
+
|
736
|
+
if (method.$$stub && exclude.indexOf(method_name) === -1) {
|
737
|
+
exclude.push(method_name);
|
738
|
+
}
|
739
|
+
|
740
|
+
if (!method.$$stub && results.indexOf(method_name) === -1 && exclude.indexOf(method_name) === -1) {
|
741
|
+
results.push(method_name);
|
742
|
+
}
|
743
|
+
}
|
744
|
+
}
|
745
|
+
}
|
746
|
+
|
747
|
+
return results;
|
748
|
+
}
|
749
|
+
|
750
|
+
Opal.own_instance_methods = function(mod) {
|
751
|
+
var results = [],
|
752
|
+
proto = mod.$$prototype;
|
753
|
+
|
754
|
+
if (proto.hasOwnProperty('$$dummy')) {
|
755
|
+
proto = proto.$$define_methods_on;
|
756
|
+
}
|
757
|
+
|
758
|
+
var props = Object.getOwnPropertyNames(proto);
|
759
|
+
|
760
|
+
for (var i = 0, length = props.length; i < length; i++) {
|
761
|
+
var prop = props[i];
|
762
|
+
|
763
|
+
if (Opal.is_method(prop)) {
|
764
|
+
var method = proto[prop];
|
765
|
+
|
766
|
+
if (!method.$$stub) {
|
767
|
+
var method_name = prop.slice(1);
|
768
|
+
results.push(method_name);
|
769
|
+
}
|
770
|
+
}
|
771
|
+
}
|
772
|
+
|
773
|
+
return results;
|
774
|
+
}
|
775
|
+
|
776
|
+
Opal.methods = function(obj) {
|
777
|
+
return Opal.instance_methods(Opal.get_singleton_class(obj));
|
778
|
+
}
|
779
|
+
|
780
|
+
Opal.own_methods = function(obj) {
|
781
|
+
return Opal.own_instance_methods(Opal.get_singleton_class(obj));
|
782
|
+
}
|
783
|
+
|
784
|
+
Opal.receiver_methods = function(obj) {
|
785
|
+
var mod = Opal.get_singleton_class(obj);
|
786
|
+
var singleton_methods = Opal.own_instance_methods(mod);
|
787
|
+
var instance_methods = Opal.own_instance_methods(mod.$$super);
|
788
|
+
return singleton_methods.concat(instance_methods);
|
789
|
+
}
|
790
|
+
|
753
791
|
// Returns an object containing all pairs of names/values
|
754
792
|
// for all class variables defined in provided +module+
|
755
793
|
// and its ancestors.
|
@@ -796,109 +834,50 @@
|
|
796
834
|
return value;
|
797
835
|
}
|
798
836
|
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
// @param from [Module] the module/class we are importing the method from
|
803
|
-
// @param name [String] the method name in JS land (i.e. starting with $)
|
804
|
-
// @param body [JS::Function] the body of the method
|
805
|
-
Opal.bridge_method = function(target_constructor, from, name, body) {
|
806
|
-
var ancestors, i, ancestor, length;
|
807
|
-
|
808
|
-
ancestors = target_constructor.$$bridge.$ancestors();
|
837
|
+
function isRoot(proto) {
|
838
|
+
return proto.hasOwnProperty('$$iclass') && proto.hasOwnProperty('$$root');
|
839
|
+
}
|
809
840
|
|
810
|
-
|
811
|
-
|
812
|
-
for (i = 0, length = ancestors.length; i < length; i++) {
|
813
|
-
ancestor = ancestors[i];
|
841
|
+
function own_included_modules(module) {
|
842
|
+
var result = [], mod, proto = Object.getPrototypeOf(module.$$prototype);
|
814
843
|
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
!ancestor.$$proto[name].$$stub &&
|
819
|
-
ancestor !== from) {
|
844
|
+
while (proto) {
|
845
|
+
if (proto.hasOwnProperty('$$class')) {
|
846
|
+
// superclass
|
820
847
|
break;
|
821
848
|
}
|
822
|
-
|
823
|
-
if (
|
824
|
-
|
825
|
-
break;
|
849
|
+
mod = protoToModule(proto);
|
850
|
+
if (mod) {
|
851
|
+
result.push(mod);
|
826
852
|
}
|
853
|
+
proto = Object.getPrototypeOf(proto);
|
827
854
|
}
|
828
|
-
};
|
829
855
|
|
830
|
-
|
831
|
-
//
|
832
|
-
// @param target [Module] the potentially associated with bridged classes module
|
833
|
-
// @param donator [Module] the module/class source of the methods that should be bridged
|
834
|
-
Opal.bridge_methods = function(target, donator) {
|
835
|
-
var i,
|
836
|
-
bridged = BridgedClasses[target.$__id__()],
|
837
|
-
donator_id = donator.$__id__();
|
838
|
-
|
839
|
-
if (bridged) {
|
840
|
-
BridgedClasses[donator_id] = bridged.slice();
|
841
|
-
|
842
|
-
for (i = bridged.length - 1; i >= 0; i--) {
|
843
|
-
Opal_bridge_methods_to_constructor(bridged[i], donator)
|
844
|
-
}
|
845
|
-
}
|
846
|
-
};
|
847
|
-
|
848
|
-
// Actually bridge methods to the bridged (shared) prototype.
|
849
|
-
function Opal_bridge_methods_to_constructor(target_constructor, donator) {
|
850
|
-
var i,
|
851
|
-
method,
|
852
|
-
methods = donator.$instance_methods();
|
853
|
-
|
854
|
-
for (i = methods.length - 1; i >= 0; i--) {
|
855
|
-
method = '$' + methods[i];
|
856
|
-
Opal.bridge_method(target_constructor, donator, method, donator.$$proto[method]);
|
857
|
-
}
|
858
|
-
}
|
859
|
-
|
860
|
-
// Associate the target as a bridged class for the current "donator"
|
861
|
-
function Opal_add_bridged_constructor(target_constructor, donator) {
|
862
|
-
var donator_id = donator.$__id__();
|
863
|
-
|
864
|
-
if (!BridgedClasses[donator_id]) {
|
865
|
-
BridgedClasses[donator_id] = [];
|
866
|
-
}
|
867
|
-
BridgedClasses[donator_id].push(target_constructor);
|
856
|
+
return result;
|
868
857
|
}
|
869
858
|
|
870
|
-
|
871
|
-
|
872
|
-
//
|
873
|
-
// @param [Integer] base_id The id of the base module (eg. the "includer")
|
874
|
-
// @param [Array<Module>] deps The array of dependencies (eg. the included module, included.$$deps)
|
875
|
-
// @param [String] prop The property that holds dependencies (eg. "$$deps")
|
876
|
-
// @param [JS::Object] seen A JS object holding the cache of already visited objects
|
877
|
-
// @return [Boolean] true if a cyclic dependency is present
|
878
|
-
Opal.has_cyclic_dep = function has_cyclic_dep(base_id, deps, prop, seen) {
|
879
|
-
var i, dep_id, dep;
|
880
|
-
|
881
|
-
for (i = deps.length - 1; i >= 0; i--) {
|
882
|
-
dep = deps[i];
|
883
|
-
dep_id = dep.$$id;
|
859
|
+
function own_prepended_modules(module) {
|
860
|
+
var result = [], mod, proto = Object.getPrototypeOf(module.$$prototype);
|
884
861
|
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
862
|
+
if (module.$$prototype.hasOwnProperty('$$dummy')) {
|
863
|
+
while (proto) {
|
864
|
+
if (proto === module.$$prototype.$$define_methods_on) {
|
865
|
+
break;
|
866
|
+
}
|
889
867
|
|
890
|
-
|
891
|
-
|
892
|
-
|
868
|
+
mod = protoToModule(proto);
|
869
|
+
if (mod) {
|
870
|
+
result.push(mod);
|
871
|
+
}
|
893
872
|
|
894
|
-
|
895
|
-
return true;
|
873
|
+
proto = Object.getPrototypeOf(proto);
|
896
874
|
}
|
897
875
|
}
|
898
876
|
|
899
|
-
return
|
877
|
+
return result;
|
900
878
|
}
|
901
879
|
|
880
|
+
|
902
881
|
// The actual inclusion of a module into a class.
|
903
882
|
//
|
904
883
|
// ## Class `$$parent` and `iclass`
|
@@ -918,47 +897,240 @@
|
|
918
897
|
// @param includer [Module] the target class to include module into
|
919
898
|
// @return [null]
|
920
899
|
Opal.append_features = function(module, includer) {
|
921
|
-
var
|
900
|
+
var module_ancestors = Opal.ancestors(module);
|
901
|
+
var iclasses = [];
|
922
902
|
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
903
|
+
if (module_ancestors.indexOf(includer) !== -1) {
|
904
|
+
throw Opal.ArgumentError.$new('cyclic include detected');
|
905
|
+
}
|
906
|
+
|
907
|
+
for (var i = 0, length = module_ancestors.length; i < length; i++) {
|
908
|
+
var ancestor = module_ancestors[i], iclass = create_iclass(ancestor);
|
909
|
+
$defineProperty(iclass, '$$included', true);
|
910
|
+
iclasses.push(iclass);
|
911
|
+
}
|
912
|
+
var includer_ancestors = Opal.ancestors(includer),
|
913
|
+
chain = chain_iclasses(iclasses),
|
914
|
+
start_chain_after,
|
915
|
+
end_chain_on;
|
916
|
+
|
917
|
+
if (includer_ancestors.indexOf(module) === -1) {
|
918
|
+
// first time include
|
919
|
+
|
920
|
+
// includer -> chain.first -> ...chain... -> chain.last -> includer.parent
|
921
|
+
start_chain_after = includer.$$prototype;
|
922
|
+
end_chain_on = Object.getPrototypeOf(includer.$$prototype);
|
923
|
+
} else {
|
924
|
+
// The module has been already included,
|
925
|
+
// we don't need to put it into the ancestors chain again,
|
926
|
+
// but this module may have new included modules.
|
927
|
+
// If it's true we need to copy them.
|
928
|
+
//
|
929
|
+
// The simplest way is to replace ancestors chain from
|
930
|
+
// parent
|
931
|
+
// |
|
932
|
+
// `module` iclass (has a $$root flag)
|
933
|
+
// |
|
934
|
+
// ...previos chain of module.included_modules ...
|
935
|
+
// |
|
936
|
+
// "next ancestor" (has a $$root flag or is a real class)
|
937
|
+
//
|
938
|
+
// to
|
939
|
+
// parent
|
940
|
+
// |
|
941
|
+
// `module` iclass (has a $$root flag)
|
942
|
+
// |
|
943
|
+
// ...regenerated chain of module.included_modules
|
944
|
+
// |
|
945
|
+
// "next ancestor" (has a $$root flag or is a real class)
|
946
|
+
//
|
947
|
+
// because there are no intermediate classes between `parent` and `next ancestor`.
|
948
|
+
// It doesn't break any prototypes of other objects as we don't change class references.
|
949
|
+
|
950
|
+
var proto = includer.$$prototype, parent = proto, module_iclass = Object.getPrototypeOf(parent);
|
951
|
+
|
952
|
+
while (module_iclass != null) {
|
953
|
+
if (isRoot(module_iclass) && module_iclass.$$module === module) {
|
954
|
+
break;
|
955
|
+
}
|
956
|
+
|
957
|
+
parent = module_iclass;
|
958
|
+
module_iclass = Object.getPrototypeOf(module_iclass);
|
927
959
|
}
|
960
|
+
|
961
|
+
var next_ancestor = Object.getPrototypeOf(module_iclass);
|
962
|
+
|
963
|
+
// skip non-root iclasses (that were recursively included)
|
964
|
+
while (next_ancestor.hasOwnProperty('$$iclass') && !isRoot(next_ancestor)) {
|
965
|
+
next_ancestor = Object.getPrototypeOf(next_ancestor);
|
966
|
+
}
|
967
|
+
|
968
|
+
start_chain_after = parent;
|
969
|
+
end_chain_on = next_ancestor;
|
928
970
|
}
|
929
971
|
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
972
|
+
$setPrototype(start_chain_after, chain.first);
|
973
|
+
$setPrototype(chain.last, end_chain_on);
|
974
|
+
|
975
|
+
// recalculate own_included_modules cache
|
976
|
+
includer.$$own_included_modules = own_included_modules(includer);
|
977
|
+
|
978
|
+
Opal.const_cache_version++;
|
979
|
+
}
|
980
|
+
|
981
|
+
Opal.prepend_features = function(module, prepender) {
|
982
|
+
// Here we change the ancestors chain from
|
983
|
+
//
|
984
|
+
// prepender
|
985
|
+
// |
|
986
|
+
// parent
|
987
|
+
//
|
988
|
+
// to:
|
989
|
+
//
|
990
|
+
// dummy(prepender)
|
991
|
+
// |
|
992
|
+
// iclass(module)
|
993
|
+
// |
|
994
|
+
// iclass(prepender)
|
995
|
+
// |
|
996
|
+
// parent
|
997
|
+
var module_ancestors = Opal.ancestors(module);
|
998
|
+
var iclasses = [];
|
999
|
+
|
1000
|
+
if (module_ancestors.indexOf(prepender) !== -1) {
|
1001
|
+
throw Opal.ArgumentError.$new('cyclic prepend detected');
|
1002
|
+
}
|
1003
|
+
|
1004
|
+
for (var i = 0, length = module_ancestors.length; i < length; i++) {
|
1005
|
+
var ancestor = module_ancestors[i], iclass = create_iclass(ancestor);
|
1006
|
+
$defineProperty(iclass, '$$prepended', true);
|
1007
|
+
iclasses.push(iclass);
|
1008
|
+
}
|
1009
|
+
|
1010
|
+
var chain = chain_iclasses(iclasses),
|
1011
|
+
dummy_prepender = prepender.$$prototype,
|
1012
|
+
previous_parent = Object.getPrototypeOf(dummy_prepender),
|
1013
|
+
prepender_iclass,
|
1014
|
+
start_chain_after,
|
1015
|
+
end_chain_on;
|
1016
|
+
|
1017
|
+
if (dummy_prepender.hasOwnProperty('$$dummy')) {
|
1018
|
+
// The module already has some prepended modules
|
1019
|
+
// which means that we don't need to make it "dummy"
|
1020
|
+
prepender_iclass = dummy_prepender.$$define_methods_on;
|
1021
|
+
} else {
|
1022
|
+
// Making the module "dummy"
|
1023
|
+
prepender_iclass = create_dummy_iclass(prepender);
|
1024
|
+
flush_methods_in(prepender);
|
1025
|
+
$defineProperty(dummy_prepender, '$$dummy', true);
|
1026
|
+
$defineProperty(dummy_prepender, '$$define_methods_on', prepender_iclass);
|
1027
|
+
|
1028
|
+
// Converting
|
1029
|
+
// dummy(prepender) -> previous_parent
|
1030
|
+
// to
|
1031
|
+
// dummy(prepender) -> iclass(prepender) -> previous_parent
|
1032
|
+
$setPrototype(dummy_prepender, prepender_iclass);
|
1033
|
+
$setPrototype(prepender_iclass, previous_parent);
|
1034
|
+
}
|
1035
|
+
|
1036
|
+
var prepender_ancestors = Opal.ancestors(prepender);
|
1037
|
+
|
1038
|
+
if (prepender_ancestors.indexOf(module) === -1) {
|
1039
|
+
// first time prepend
|
1040
|
+
|
1041
|
+
start_chain_after = dummy_prepender;
|
1042
|
+
|
1043
|
+
// next $$root or prepender_iclass or non-$$iclass
|
1044
|
+
end_chain_on = Object.getPrototypeOf(dummy_prepender);
|
1045
|
+
while (end_chain_on != null) {
|
1046
|
+
if (
|
1047
|
+
end_chain_on.hasOwnProperty('$$root') ||
|
1048
|
+
end_chain_on === prepender_iclass ||
|
1049
|
+
!end_chain_on.hasOwnProperty('$$iclass')
|
1050
|
+
) {
|
1051
|
+
break;
|
1052
|
+
}
|
1053
|
+
|
1054
|
+
end_chain_on = Object.getPrototypeOf(end_chain_on);
|
1055
|
+
}
|
1056
|
+
} else {
|
1057
|
+
throw Opal.RuntimeError.$new("Prepending a module multiple times is not supported");
|
934
1058
|
}
|
935
1059
|
|
1060
|
+
$setPrototype(start_chain_after, chain.first);
|
1061
|
+
$setPrototype(chain.last, end_chain_on);
|
1062
|
+
|
1063
|
+
// recalculate own_prepended_modules cache
|
1064
|
+
prepender.$$own_prepended_modules = own_prepended_modules(prepender);
|
1065
|
+
|
936
1066
|
Opal.const_cache_version++;
|
937
|
-
|
938
|
-
module.$$included_in.push(includer);
|
939
|
-
Opal.bridge_methods(includer, module);
|
940
|
-
|
941
|
-
// iclass
|
942
|
-
iclass = {
|
943
|
-
$$name: module.$$name,
|
944
|
-
$$proto: module.$$proto,
|
945
|
-
$$parent: includer.$$parent,
|
946
|
-
$$module: module,
|
947
|
-
$$iclass: true
|
948
|
-
};
|
1067
|
+
}
|
949
1068
|
|
950
|
-
|
1069
|
+
function flush_methods_in(module) {
|
1070
|
+
var proto = module.$$prototype,
|
1071
|
+
props = Object.getOwnPropertyNames(proto);
|
1072
|
+
|
1073
|
+
for (var i = 0; i < props.length; i++) {
|
1074
|
+
var prop = props[i];
|
1075
|
+
if (Opal.is_method(prop)) {
|
1076
|
+
delete proto[prop];
|
1077
|
+
}
|
1078
|
+
}
|
1079
|
+
}
|
951
1080
|
|
952
|
-
|
1081
|
+
function create_iclass(module) {
|
1082
|
+
var iclass = create_dummy_iclass(module);
|
953
1083
|
|
954
|
-
|
955
|
-
|
1084
|
+
if (module.$$is_module) {
|
1085
|
+
module.$$iclasses.push(iclass);
|
956
1086
|
}
|
957
|
-
};
|
958
1087
|
|
959
|
-
|
960
|
-
|
961
|
-
|
1088
|
+
return iclass;
|
1089
|
+
}
|
1090
|
+
|
1091
|
+
// Dummy iclass doesn't receive updates when the module gets a new method.
|
1092
|
+
function create_dummy_iclass(module) {
|
1093
|
+
var iclass = {},
|
1094
|
+
proto = module.$$prototype;
|
1095
|
+
|
1096
|
+
if (proto.hasOwnProperty('$$dummy')) {
|
1097
|
+
proto = proto.$$define_methods_on;
|
1098
|
+
}
|
1099
|
+
|
1100
|
+
var props = Object.getOwnPropertyNames(proto),
|
1101
|
+
length = props.length, i;
|
1102
|
+
|
1103
|
+
for (i = 0; i < length; i++) {
|
1104
|
+
var prop = props[i];
|
1105
|
+
$defineProperty(iclass, prop, proto[prop]);
|
1106
|
+
}
|
1107
|
+
|
1108
|
+
$defineProperty(iclass, '$$iclass', true);
|
1109
|
+
$defineProperty(iclass, '$$module', module);
|
1110
|
+
|
1111
|
+
return iclass;
|
1112
|
+
}
|
1113
|
+
|
1114
|
+
function chain_iclasses(iclasses) {
|
1115
|
+
var length = iclasses.length, first = iclasses[0];
|
1116
|
+
|
1117
|
+
$defineProperty(first, '$$root', true);
|
1118
|
+
|
1119
|
+
if (length === 1) {
|
1120
|
+
return { first: first, last: first };
|
1121
|
+
}
|
1122
|
+
|
1123
|
+
var previous = first;
|
1124
|
+
|
1125
|
+
for (var i = 1; i < length; i++) {
|
1126
|
+
var current = iclasses[i];
|
1127
|
+
$setPrototype(previous, current);
|
1128
|
+
previous = current;
|
1129
|
+
}
|
1130
|
+
|
1131
|
+
|
1132
|
+
return { first: iclasses[0], last: iclasses[length - 1] };
|
1133
|
+
}
|
962
1134
|
|
963
1135
|
// For performance, some core Ruby classes are toll-free bridged to their
|
964
1136
|
// native JavaScript counterparts (e.g. a Ruby Array is a JavaScript Array).
|
@@ -966,7 +1138,7 @@
|
|
966
1138
|
// This method is used to setup a native constructor (e.g. Array), to have
|
967
1139
|
// its prototype act like a normal Ruby class. Firstly, a new Ruby class is
|
968
1140
|
// created using the native constructor so that its prototype is set as the
|
969
|
-
// target for
|
1141
|
+
// target for the new class. Note: all bridged classes are set to inherit
|
970
1142
|
// from Object.
|
971
1143
|
//
|
972
1144
|
// Example:
|
@@ -977,132 +1149,93 @@
|
|
977
1149
|
// @param constructor [JS.Function] native JavaScript constructor to use
|
978
1150
|
// @return [Class] returns the passed Ruby class
|
979
1151
|
//
|
980
|
-
Opal.bridge = function(
|
981
|
-
if (
|
1152
|
+
Opal.bridge = function(native_klass, klass) {
|
1153
|
+
if (native_klass.hasOwnProperty('$$bridge')) {
|
982
1154
|
throw Opal.ArgumentError.$new("already bridged");
|
983
1155
|
}
|
984
1156
|
|
985
|
-
|
986
|
-
|
987
|
-
// Populate constructor with previously stored stubs
|
988
|
-
for (var method_name in Opal.stubs) {
|
989
|
-
if (!(method_name in constructor.prototype)) {
|
990
|
-
constructor.prototype[method_name] = Opal.stub_for(method_name);
|
991
|
-
}
|
992
|
-
}
|
993
|
-
|
994
|
-
constructor.prototype.$$class = klass;
|
995
|
-
constructor.$$bridge = klass;
|
1157
|
+
var klass_to_inject, klass_reference;
|
996
1158
|
|
997
|
-
|
1159
|
+
klass_to_inject = klass.$$super || Opal.Object;
|
1160
|
+
klass_reference = klass;
|
1161
|
+
var original_prototype = klass.$$prototype;
|
998
1162
|
|
999
|
-
//
|
1000
|
-
//
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1163
|
+
// constructor is a JS function with a prototype chain like:
|
1164
|
+
// - constructor
|
1165
|
+
// - super
|
1166
|
+
//
|
1167
|
+
// What we need to do is to inject our class (with its prototype chain)
|
1168
|
+
// between constructor and super. For example, after injecting ::Object
|
1169
|
+
// into JS String we get:
|
1170
|
+
//
|
1171
|
+
// - constructor (window.String)
|
1172
|
+
// - Opal.Object
|
1173
|
+
// - Opal.Kernel
|
1174
|
+
// - Opal.BasicObject
|
1175
|
+
// - super (window.Object)
|
1176
|
+
// - null
|
1177
|
+
//
|
1178
|
+
$defineProperty(native_klass, '$$bridge', klass);
|
1179
|
+
$setPrototype(native_klass.prototype, (klass.$$super || Opal.Object).$$prototype);
|
1180
|
+
$defineProperty(klass, '$$prototype', native_klass.prototype);
|
1005
1181
|
|
1006
|
-
|
1007
|
-
|
1182
|
+
$defineProperty(klass.$$prototype, '$$class', klass);
|
1183
|
+
$defineProperty(klass, '$$constructor', native_klass);
|
1184
|
+
$defineProperty(klass, '$$bridge', true);
|
1185
|
+
};
|
1008
1186
|
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1187
|
+
function protoToModule(proto) {
|
1188
|
+
if (proto.hasOwnProperty('$$dummy')) {
|
1189
|
+
return;
|
1190
|
+
} else if (proto.hasOwnProperty('$$iclass')) {
|
1191
|
+
return proto.$$module;
|
1192
|
+
} else if (proto.hasOwnProperty('$$class')) {
|
1193
|
+
return proto.$$class;
|
1012
1194
|
}
|
1195
|
+
}
|
1013
1196
|
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
// Update `jsid` method cache of all classes / modules including `module`.
|
1018
|
-
Opal.update_includer = function(module, includer, jsid) {
|
1019
|
-
var dest, current, body,
|
1020
|
-
klass_includees, j, jj, current_owner_index, module_index;
|
1197
|
+
function own_ancestors(module) {
|
1198
|
+
return module.$$own_prepended_modules.concat([module]).concat(module.$$own_included_modules);
|
1199
|
+
}
|
1021
1200
|
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1201
|
+
// The Array of ancestors for a given module/class
|
1202
|
+
Opal.ancestors = function(module) {
|
1203
|
+
if (!module) { return []; }
|
1025
1204
|
|
1026
|
-
if (
|
1027
|
-
|
1205
|
+
if (module.$$ancestors_cache_version === Opal.const_cache_version) {
|
1206
|
+
return module.$$ancestors;
|
1028
1207
|
}
|
1029
|
-
else if (dest.hasOwnProperty(jsid) && !current.$$stub) {
|
1030
|
-
// target class includes another module that has defined this method
|
1031
|
-
klass_includees = includer.$$inc;
|
1032
1208
|
|
1033
|
-
|
1034
|
-
if (klass_includees[j] === current.$$donated) {
|
1035
|
-
current_owner_index = j;
|
1036
|
-
}
|
1037
|
-
if (klass_includees[j] === module) {
|
1038
|
-
module_index = j;
|
1039
|
-
}
|
1040
|
-
}
|
1209
|
+
var result = [], i, mods, length;
|
1041
1210
|
|
1042
|
-
|
1043
|
-
|
1044
|
-
// a module can overwrite a method it defined before
|
1045
|
-
if (current_owner_index <= module_index) {
|
1046
|
-
dest[jsid] = body;
|
1047
|
-
dest[jsid].$$donated = module;
|
1048
|
-
}
|
1049
|
-
}
|
1050
|
-
else {
|
1051
|
-
// neither a class, or module included by class, has defined method
|
1052
|
-
dest[jsid] = body;
|
1053
|
-
dest[jsid].$$donated = module;
|
1211
|
+
for (i = 0, mods = own_ancestors(module), length = mods.length; i < length; i++) {
|
1212
|
+
result.push(mods[i]);
|
1054
1213
|
}
|
1055
1214
|
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1215
|
+
if (module.$$super) {
|
1216
|
+
for (i = 0, mods = Opal.ancestors(module.$$super), length = mods.length; i < length; i++) {
|
1217
|
+
result.push(mods[i]);
|
1218
|
+
}
|
1059
1219
|
}
|
1060
|
-
};
|
1061
|
-
|
1062
|
-
// Update `jsid` method cache of all classes / modules including `module`.
|
1063
|
-
Opal.update_includers = function(module, jsid) {
|
1064
|
-
var i, ii, includee, included_in;
|
1065
1220
|
|
1066
|
-
|
1067
|
-
|
1068
|
-
if (!included_in) {
|
1069
|
-
return;
|
1070
|
-
}
|
1221
|
+
module.$$ancestors_cache_version = Opal.const_cache_version;
|
1222
|
+
module.$$ancestors = result;
|
1071
1223
|
|
1072
|
-
|
1073
|
-
|
1074
|
-
Opal.update_includer(module, includee, jsid);
|
1075
|
-
}
|
1076
|
-
};
|
1224
|
+
return result;
|
1225
|
+
}
|
1077
1226
|
|
1078
|
-
|
1079
|
-
|
1080
|
-
var parent = module_or_class,
|
1081
|
-
result = [],
|
1082
|
-
modules, i, ii, j, jj;
|
1083
|
-
|
1084
|
-
while (parent) {
|
1085
|
-
result.push(parent);
|
1086
|
-
for (i = parent.$$inc.length-1; i >= 0; i--) {
|
1087
|
-
modules = Opal.ancestors(parent.$$inc[i]);
|
1088
|
-
|
1089
|
-
for(j = 0, jj = modules.length; j < jj; j++) {
|
1090
|
-
result.push(modules[j]);
|
1091
|
-
}
|
1092
|
-
}
|
1227
|
+
Opal.included_modules = function(module) {
|
1228
|
+
var result = [], mod = null, proto = Object.getPrototypeOf(module.$$prototype);
|
1093
1229
|
|
1094
|
-
|
1095
|
-
|
1096
|
-
if (
|
1097
|
-
|
1098
|
-
}
|
1099
|
-
else {
|
1100
|
-
parent = parent.$$is_class ? parent.$$super : null;
|
1230
|
+
for (; proto && Object.getPrototypeOf(proto); proto = Object.getPrototypeOf(proto)) {
|
1231
|
+
mod = protoToModule(proto);
|
1232
|
+
if (mod && mod.$$is_module && proto.$$iclass && proto.$$included) {
|
1233
|
+
result.push(mod);
|
1101
1234
|
}
|
1102
1235
|
}
|
1103
1236
|
|
1104
1237
|
return result;
|
1105
|
-
}
|
1238
|
+
}
|
1106
1239
|
|
1107
1240
|
|
1108
1241
|
// Method Missing
|
@@ -1136,37 +1269,17 @@
|
|
1136
1269
|
// @param stubs [Array] an array of method stubs to add
|
1137
1270
|
// @return [undefined]
|
1138
1271
|
Opal.add_stubs = function(stubs) {
|
1139
|
-
var
|
1140
|
-
i, ilength = stubs.length,
|
1141
|
-
j, jlength = subscribers.length,
|
1142
|
-
method_name, stub,
|
1143
|
-
opal_stubs = Opal.stubs;
|
1144
|
-
|
1145
|
-
for (i = 0; i < ilength; i++) {
|
1146
|
-
method_name = stubs[i];
|
1147
|
-
|
1148
|
-
if(!opal_stubs.hasOwnProperty(method_name)) {
|
1149
|
-
// Save method name to populate other subscribers with this stub
|
1150
|
-
opal_stubs[method_name] = true;
|
1151
|
-
stub = Opal.stub_for(method_name);
|
1272
|
+
var proto = Opal.BasicObject.$$prototype;
|
1152
1273
|
|
1153
|
-
|
1154
|
-
|
1274
|
+
for (var i = 0, length = stubs.length; i < length; i++) {
|
1275
|
+
var stub = stubs[i], existing_method = proto[stub];
|
1155
1276
|
|
1156
|
-
|
1157
|
-
|
1158
|
-
}
|
1159
|
-
}
|
1277
|
+
if (existing_method == null || existing_method.$$stub) {
|
1278
|
+
Opal.add_stub_for(proto, stub);
|
1160
1279
|
}
|
1161
1280
|
}
|
1162
1281
|
};
|
1163
1282
|
|
1164
|
-
// Keep a list of prototypes that want method_missing stubs to be added.
|
1165
|
-
//
|
1166
|
-
// @default [Prototype List] BasicObject_alloc.prototype
|
1167
|
-
//
|
1168
|
-
Opal.stub_subscribers = [BasicObject_alloc.prototype];
|
1169
|
-
|
1170
1283
|
// Add a method_missing stub function to the given prototype for the
|
1171
1284
|
// given name.
|
1172
1285
|
//
|
@@ -1175,7 +1288,7 @@
|
|
1175
1288
|
// @return [undefined]
|
1176
1289
|
Opal.add_stub_for = function(prototype, stub) {
|
1177
1290
|
var method_missing_stub = Opal.stub_for(stub);
|
1178
|
-
prototype
|
1291
|
+
$defineProperty(prototype, stub, method_missing_stub);
|
1179
1292
|
};
|
1180
1293
|
|
1181
1294
|
// Generate the method_missing stub for a given method name.
|
@@ -1215,7 +1328,7 @@
|
|
1215
1328
|
// @raise [ArgumentError]
|
1216
1329
|
Opal.ac = function(actual, expected, object, meth) {
|
1217
1330
|
var inspect = '';
|
1218
|
-
if (object.$$
|
1331
|
+
if (object.$$is_a_module) {
|
1219
1332
|
inspect += object.$$name + '.';
|
1220
1333
|
}
|
1221
1334
|
else {
|
@@ -1240,23 +1353,35 @@
|
|
1240
1353
|
|
1241
1354
|
// Super dispatcher
|
1242
1355
|
Opal.find_super_dispatcher = function(obj, mid, current_func, defcheck, defs) {
|
1243
|
-
var
|
1356
|
+
var jsid = '$' + mid, ancestors, super_method;
|
1357
|
+
|
1358
|
+
if (obj.hasOwnProperty('$$meta')) {
|
1359
|
+
ancestors = Opal.ancestors(obj.$$meta);
|
1360
|
+
} else {
|
1361
|
+
ancestors = Opal.ancestors(obj.$$class);
|
1362
|
+
}
|
1363
|
+
|
1364
|
+
var current_index = ancestors.indexOf(current_func.$$owner);
|
1365
|
+
|
1366
|
+
for (var i = current_index + 1; i < ancestors.length; i++) {
|
1367
|
+
var ancestor = ancestors[i],
|
1368
|
+
proto = ancestor.$$prototype;
|
1244
1369
|
|
1245
|
-
|
1246
|
-
|
1247
|
-
dispatcher = defs.$$super;
|
1370
|
+
if (proto.hasOwnProperty('$$dummy')) {
|
1371
|
+
proto = proto.$$define_methods_on;
|
1248
1372
|
}
|
1249
|
-
|
1250
|
-
|
1373
|
+
|
1374
|
+
if (proto.hasOwnProperty(jsid)) {
|
1375
|
+
var method = proto[jsid];
|
1376
|
+
|
1377
|
+
if (!method.$$stub) {
|
1378
|
+
super_method = method;
|
1379
|
+
}
|
1380
|
+
break;
|
1251
1381
|
}
|
1252
1382
|
}
|
1253
|
-
else {
|
1254
|
-
dispatcher = Opal.find_obj_super_dispatcher(obj, mid, current_func);
|
1255
|
-
}
|
1256
|
-
|
1257
|
-
super_method = dispatcher['$' + mid];
|
1258
1383
|
|
1259
|
-
if (!defcheck && super_method
|
1384
|
+
if (!defcheck && super_method == null && Opal.Kernel.$method_missing === obj.$method_missing) {
|
1260
1385
|
// method_missing hasn't been explicitly defined
|
1261
1386
|
throw Opal.NoMethodError.$new('super: no superclass method `'+mid+"' for "+obj, mid);
|
1262
1387
|
}
|
@@ -1283,67 +1408,6 @@
|
|
1283
1408
|
return Opal.find_super_dispatcher(obj, call_jsid, current_func, defcheck);
|
1284
1409
|
};
|
1285
1410
|
|
1286
|
-
Opal.find_obj_super_dispatcher = function(obj, mid, current_func) {
|
1287
|
-
var klass = obj.$$meta || obj.$$class;
|
1288
|
-
|
1289
|
-
// first we need to find the class/module current_func is located on
|
1290
|
-
klass = Opal.find_owning_class(klass, current_func);
|
1291
|
-
|
1292
|
-
if (!klass) {
|
1293
|
-
throw new Error("could not find current class for super()");
|
1294
|
-
}
|
1295
|
-
|
1296
|
-
return Opal.find_super_func(klass, '$' + mid, current_func);
|
1297
|
-
};
|
1298
|
-
|
1299
|
-
Opal.find_owning_class = function(klass, current_func) {
|
1300
|
-
var owner = current_func.$$owner;
|
1301
|
-
|
1302
|
-
while (klass) {
|
1303
|
-
// repeating for readability
|
1304
|
-
|
1305
|
-
if (klass.$$iclass && klass.$$module === current_func.$$donated) {
|
1306
|
-
// this klass was the last one the module donated to
|
1307
|
-
// case is also hit with multiple module includes
|
1308
|
-
break;
|
1309
|
-
}
|
1310
|
-
else if (klass.$$iclass && klass.$$module === owner) {
|
1311
|
-
// module has donated to other classes but klass isn't one of those
|
1312
|
-
break;
|
1313
|
-
}
|
1314
|
-
else if (owner.$$is_singleton && klass === owner.$$singleton_of.$$class) {
|
1315
|
-
// cases like stdlib `Singleton::included` that use a singleton of a singleton
|
1316
|
-
break;
|
1317
|
-
}
|
1318
|
-
else if (klass === owner) {
|
1319
|
-
// no modules, pure class inheritance
|
1320
|
-
break;
|
1321
|
-
}
|
1322
|
-
|
1323
|
-
klass = klass.$$parent;
|
1324
|
-
}
|
1325
|
-
|
1326
|
-
return klass;
|
1327
|
-
};
|
1328
|
-
|
1329
|
-
Opal.find_super_func = function(owning_klass, jsid, current_func) {
|
1330
|
-
var klass = owning_klass.$$parent;
|
1331
|
-
|
1332
|
-
// now we can find the super
|
1333
|
-
while (klass) {
|
1334
|
-
var working = klass.$$proto[jsid];
|
1335
|
-
|
1336
|
-
if (working && working !== current_func) {
|
1337
|
-
// ok
|
1338
|
-
break;
|
1339
|
-
}
|
1340
|
-
|
1341
|
-
klass = klass.$$parent;
|
1342
|
-
}
|
1343
|
-
|
1344
|
-
return klass.$$proto;
|
1345
|
-
};
|
1346
|
-
|
1347
1411
|
// Used to return as an expression. Sometimes, we can't simply return from
|
1348
1412
|
// a javascript function as if we were a method, as the return is used as
|
1349
1413
|
// an expression, or even inside a block which must "return" to the outer
|
@@ -1436,7 +1500,7 @@
|
|
1436
1500
|
};
|
1437
1501
|
|
1438
1502
|
Opal.is_a = function(object, klass) {
|
1439
|
-
if (object.$$meta === klass || object.$$class === klass) {
|
1503
|
+
if (klass != null && object.$$meta === klass || object.$$class === klass) {
|
1440
1504
|
return true;
|
1441
1505
|
}
|
1442
1506
|
|
@@ -1538,7 +1602,7 @@
|
|
1538
1602
|
Opal.extract_kwargs = function(parameters) {
|
1539
1603
|
var kwargs = parameters[parameters.length - 1];
|
1540
1604
|
if (kwargs != null && kwargs['$respond_to?']('to_hash', true)) {
|
1541
|
-
|
1605
|
+
$splice.call(parameters, parameters.length - 1, 1);
|
1542
1606
|
return kwargs.$to_hash();
|
1543
1607
|
}
|
1544
1608
|
else {
|
@@ -1601,13 +1665,20 @@
|
|
1601
1665
|
var body = (typeof(method) === 'string') ? recv['$'+method] : method;
|
1602
1666
|
|
1603
1667
|
if (body != null) {
|
1604
|
-
|
1668
|
+
if (typeof block === 'function') {
|
1669
|
+
body.$$p = block;
|
1670
|
+
}
|
1605
1671
|
return body.apply(recv, args);
|
1606
1672
|
}
|
1607
1673
|
|
1608
1674
|
return recv.$method_missing.apply(recv, [method].concat(args));
|
1609
1675
|
}
|
1610
1676
|
|
1677
|
+
Opal.lambda = function(block) {
|
1678
|
+
block.$$is_lambda = true;
|
1679
|
+
return block;
|
1680
|
+
}
|
1681
|
+
|
1611
1682
|
// Used to define methods on an object. This is a helper method, used by the
|
1612
1683
|
// compiled source to define methods on special case objects when the compiler
|
1613
1684
|
// can not determine the destination object, or the object is a Module
|
@@ -1645,8 +1716,13 @@
|
|
1645
1716
|
// @return [null]
|
1646
1717
|
//
|
1647
1718
|
Opal.def = function(obj, jsid, body) {
|
1719
|
+
// Special case for a method definition in the
|
1720
|
+
// top-level namespace
|
1721
|
+
if (obj === Opal.top) {
|
1722
|
+
Opal.defn(Opal.Object, jsid, body)
|
1723
|
+
}
|
1648
1724
|
// if instance_eval is invoked on a module/class, it sets inst_eval_mod
|
1649
|
-
if (!obj.$$eval &&
|
1725
|
+
else if (!obj.$$eval && obj.$$is_a_module) {
|
1650
1726
|
Opal.defn(obj, jsid, body);
|
1651
1727
|
}
|
1652
1728
|
else {
|
@@ -1655,59 +1731,55 @@
|
|
1655
1731
|
};
|
1656
1732
|
|
1657
1733
|
// Define method on a module or class (see Opal.def).
|
1658
|
-
Opal.defn = function(
|
1659
|
-
|
1660
|
-
|
1661
|
-
body.$$owner = obj;
|
1662
|
-
if (body.displayName == null) body.displayName = jsid.substr(1);
|
1734
|
+
Opal.defn = function(module, jsid, body) {
|
1735
|
+
body.displayName = jsid;
|
1736
|
+
body.$$owner = module;
|
1663
1737
|
|
1664
|
-
|
1665
|
-
if (
|
1666
|
-
|
1738
|
+
var proto = module.$$prototype;
|
1739
|
+
if (proto.hasOwnProperty('$$dummy')) {
|
1740
|
+
proto = proto.$$define_methods_on;
|
1741
|
+
}
|
1742
|
+
$defineProperty(proto, jsid, body);
|
1667
1743
|
|
1668
|
-
|
1669
|
-
|
1744
|
+
if (module.$$is_module) {
|
1745
|
+
if (module.$$module_function) {
|
1746
|
+
Opal.defs(module, jsid, body)
|
1670
1747
|
}
|
1671
|
-
}
|
1672
1748
|
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
for (var i = bridged.length - 1; i >= 0; i--) {
|
1677
|
-
Opal.bridge_method(bridged[i], obj, jsid, body);
|
1749
|
+
for (var i = 0, iclasses = module.$$iclasses, length = iclasses.length; i < length; i++) {
|
1750
|
+
var iclass = iclasses[i];
|
1751
|
+
$defineProperty(iclass, jsid, body);
|
1678
1752
|
}
|
1679
1753
|
}
|
1680
1754
|
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
obj.$method_added(jsid.substr(1));
|
1755
|
+
var singleton_of = module.$$singleton_of;
|
1756
|
+
if (module.$method_added && !module.$method_added.$$stub && !singleton_of) {
|
1757
|
+
module.$method_added(jsid.substr(1));
|
1685
1758
|
}
|
1686
1759
|
else if (singleton_of && singleton_of.$singleton_method_added && !singleton_of.$singleton_method_added.$$stub) {
|
1687
1760
|
singleton_of.$singleton_method_added(jsid.substr(1));
|
1688
1761
|
}
|
1689
|
-
|
1690
|
-
return nil;
|
1691
|
-
};
|
1762
|
+
}
|
1692
1763
|
|
1693
1764
|
// Define a singleton method on the given object (see Opal.def).
|
1694
1765
|
Opal.defs = function(obj, jsid, body) {
|
1766
|
+
if (obj.$$is_string || obj.$$is_number) {
|
1767
|
+
throw Opal.TypeError.$new("can't define singleton");
|
1768
|
+
}
|
1695
1769
|
Opal.defn(Opal.get_singleton_class(obj), jsid, body)
|
1696
1770
|
};
|
1697
1771
|
|
1698
1772
|
// Called from #remove_method.
|
1699
1773
|
Opal.rdef = function(obj, jsid) {
|
1700
|
-
|
1701
|
-
|
1702
|
-
if (!$hasOwn.call(obj.$$proto, jsid)) {
|
1774
|
+
if (!$hasOwn.call(obj.$$prototype, jsid)) {
|
1703
1775
|
throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
|
1704
1776
|
}
|
1705
1777
|
|
1706
|
-
delete obj.$$
|
1778
|
+
delete obj.$$prototype[jsid];
|
1707
1779
|
|
1708
1780
|
if (obj.$$is_singleton) {
|
1709
|
-
if (obj.$$
|
1710
|
-
obj.$$
|
1781
|
+
if (obj.$$prototype.$singleton_method_removed && !obj.$$prototype.$singleton_method_removed.$$stub) {
|
1782
|
+
obj.$$prototype.$singleton_method_removed(jsid.substr(1));
|
1711
1783
|
}
|
1712
1784
|
}
|
1713
1785
|
else {
|
@@ -1719,15 +1791,15 @@
|
|
1719
1791
|
|
1720
1792
|
// Called from #undef_method.
|
1721
1793
|
Opal.udef = function(obj, jsid) {
|
1722
|
-
if (!obj.$$
|
1794
|
+
if (!obj.$$prototype[jsid] || obj.$$prototype[jsid].$$stub) {
|
1723
1795
|
throw Opal.NameError.$new("method '" + jsid.substr(1) + "' not defined in " + obj.$name());
|
1724
1796
|
}
|
1725
1797
|
|
1726
|
-
Opal.add_stub_for(obj.$$
|
1798
|
+
Opal.add_stub_for(obj.$$prototype, jsid);
|
1727
1799
|
|
1728
1800
|
if (obj.$$is_singleton) {
|
1729
|
-
if (obj.$$
|
1730
|
-
obj.$$
|
1801
|
+
if (obj.$$prototype.$singleton_method_undefined && !obj.$$prototype.$singleton_method_undefined.$$stub) {
|
1802
|
+
obj.$$prototype.$singleton_method_undefined(jsid.substr(1));
|
1731
1803
|
}
|
1732
1804
|
}
|
1733
1805
|
else {
|
@@ -1737,10 +1809,14 @@
|
|
1737
1809
|
}
|
1738
1810
|
};
|
1739
1811
|
|
1812
|
+
function is_method_body(body) {
|
1813
|
+
return (typeof(body) === "function" && !body.$$stub);
|
1814
|
+
}
|
1815
|
+
|
1740
1816
|
Opal.alias = function(obj, name, old) {
|
1741
1817
|
var id = '$' + name,
|
1742
1818
|
old_id = '$' + old,
|
1743
|
-
body = obj.$$
|
1819
|
+
body = obj.$$prototype['$' + old],
|
1744
1820
|
alias;
|
1745
1821
|
|
1746
1822
|
// When running inside #instance_eval the alias refers to class methods.
|
@@ -1748,7 +1824,7 @@
|
|
1748
1824
|
return Opal.alias(Opal.get_singleton_class(obj), name, old);
|
1749
1825
|
}
|
1750
1826
|
|
1751
|
-
if (
|
1827
|
+
if (!is_method_body(body)) {
|
1752
1828
|
var ancestor = obj.$$super;
|
1753
1829
|
|
1754
1830
|
while (typeof(body) !== "function" && ancestor) {
|
@@ -1756,7 +1832,12 @@
|
|
1756
1832
|
ancestor = ancestor.$$super;
|
1757
1833
|
}
|
1758
1834
|
|
1759
|
-
if (
|
1835
|
+
if (!is_method_body(body) && obj.$$is_module) {
|
1836
|
+
// try to look into Object
|
1837
|
+
body = Opal.Object.$$prototype[old_id]
|
1838
|
+
}
|
1839
|
+
|
1840
|
+
if (!is_method_body(body)) {
|
1760
1841
|
throw Opal.NameError.$new("undefined method `" + old + "' for class `" + obj.$name() + "'")
|
1761
1842
|
}
|
1762
1843
|
}
|
@@ -1765,7 +1846,7 @@
|
|
1765
1846
|
// to keep the max depth at 1.
|
1766
1847
|
if (body.$$alias_of) body = body.$$alias_of;
|
1767
1848
|
|
1768
|
-
// We need a wrapper because otherwise
|
1849
|
+
// We need a wrapper because otherwise properties
|
1769
1850
|
// would be ovrewritten on the original body.
|
1770
1851
|
alias = function() {
|
1771
1852
|
var block = alias.$$p, args, i, ii;
|
@@ -1796,7 +1877,7 @@
|
|
1796
1877
|
|
1797
1878
|
Opal.alias_native = function(obj, name, native_name) {
|
1798
1879
|
var id = '$' + name,
|
1799
|
-
body = obj.$$
|
1880
|
+
body = obj.$$prototype[native_name];
|
1800
1881
|
|
1801
1882
|
if (typeof(body) !== "function" || body.$$stub) {
|
1802
1883
|
throw Opal.NameError.$new("undefined native method `" + native_name + "' for class `" + obj.$name() + "'")
|
@@ -2023,7 +2104,7 @@
|
|
2023
2104
|
return arguments[0];
|
2024
2105
|
}
|
2025
2106
|
|
2026
|
-
hash = new Opal.Hash
|
2107
|
+
hash = new Opal.Hash();
|
2027
2108
|
Opal.hash_init(hash);
|
2028
2109
|
|
2029
2110
|
if (arguments_length === 1 && arguments[0].$$is_array) {
|
@@ -2077,7 +2158,7 @@
|
|
2077
2158
|
// function.
|
2078
2159
|
//
|
2079
2160
|
Opal.hash2 = function(keys, smap) {
|
2080
|
-
var hash = new Opal.Hash
|
2161
|
+
var hash = new Opal.Hash();
|
2081
2162
|
|
2082
2163
|
hash.$$smap = smap;
|
2083
2164
|
hash.$$map = Object.create(null);
|
@@ -2090,7 +2171,7 @@
|
|
2090
2171
|
// range excludes the last value.
|
2091
2172
|
//
|
2092
2173
|
Opal.range = function(first, last, exc) {
|
2093
|
-
var range = new Opal.Range
|
2174
|
+
var range = new Opal.Range();
|
2094
2175
|
range.begin = first;
|
2095
2176
|
range.end = last;
|
2096
2177
|
range.excl = exc;
|
@@ -2135,15 +2216,53 @@
|
|
2135
2216
|
.replace(/[\r]/g, '\\r')
|
2136
2217
|
.replace(/[\f]/g, '\\f')
|
2137
2218
|
.replace(/[\t]/g, '\\t');
|
2138
|
-
}
|
2219
|
+
};
|
2139
2220
|
|
2221
|
+
// Create a global Regexp from a RegExp object and cache the result
|
2222
|
+
// on the object itself ($$g attribute).
|
2223
|
+
//
|
2224
|
+
Opal.global_regexp = function(pattern) {
|
2225
|
+
if (pattern.global) {
|
2226
|
+
return pattern; // RegExp already has the global flag
|
2227
|
+
}
|
2228
|
+
if (pattern.$$g == null) {
|
2229
|
+
pattern.$$g = new RegExp(pattern.source, (pattern.multiline ? 'gm' : 'g') + (pattern.ignoreCase ? 'i' : ''));
|
2230
|
+
} else {
|
2231
|
+
pattern.$$g.lastIndex = null; // reset lastIndex property
|
2232
|
+
}
|
2233
|
+
return pattern.$$g;
|
2234
|
+
};
|
2235
|
+
|
2236
|
+
// Create a global multiline Regexp from a RegExp object and cache the result
|
2237
|
+
// on the object itself ($$gm or $$g attribute).
|
2238
|
+
//
|
2239
|
+
Opal.global_multiline_regexp = function(pattern) {
|
2240
|
+
var result;
|
2241
|
+
if (pattern.multiline) {
|
2242
|
+
if (pattern.global) {
|
2243
|
+
return pattern; // RegExp already has the global and multiline flag
|
2244
|
+
}
|
2245
|
+
// we are using the $$g attribute because the Regexp is already multiline
|
2246
|
+
if (pattern.$$g != null) {
|
2247
|
+
result = pattern.$$g;
|
2248
|
+
} else {
|
2249
|
+
result = pattern.$$g = new RegExp(pattern.source, 'gm' + (pattern.ignoreCase ? 'i' : ''));
|
2250
|
+
}
|
2251
|
+
} else if (pattern.$$gm != null) {
|
2252
|
+
result = pattern.$$gm;
|
2253
|
+
} else {
|
2254
|
+
result = pattern.$$gm = new RegExp(pattern.source, 'gm' + (pattern.ignoreCase ? 'i' : ''));
|
2255
|
+
}
|
2256
|
+
result.lastIndex = null; // reset lastIndex property
|
2257
|
+
return result;
|
2258
|
+
};
|
2140
2259
|
|
2141
2260
|
// Require system
|
2142
2261
|
// --------------
|
2143
2262
|
|
2144
2263
|
Opal.modules = {};
|
2145
2264
|
Opal.loaded_features = ['corelib/runtime'];
|
2146
|
-
Opal.current_dir = '.'
|
2265
|
+
Opal.current_dir = '.';
|
2147
2266
|
Opal.require_table = {'corelib/runtime': true};
|
2148
2267
|
|
2149
2268
|
Opal.normalize = function(path) {
|
@@ -2173,7 +2292,7 @@
|
|
2173
2292
|
path = Opal.normalize(paths[i]);
|
2174
2293
|
|
2175
2294
|
if (Opal.require_table[path]) {
|
2176
|
-
|
2295
|
+
continue;
|
2177
2296
|
}
|
2178
2297
|
|
2179
2298
|
Opal.loaded_features.push(path);
|
@@ -2196,7 +2315,11 @@
|
|
2196
2315
|
var message = 'cannot load such file -- ' + path;
|
2197
2316
|
|
2198
2317
|
if (severity === "error") {
|
2199
|
-
|
2318
|
+
if (Opal.LoadError) {
|
2319
|
+
throw Opal.LoadError.$new(message)
|
2320
|
+
} else {
|
2321
|
+
throw message
|
2322
|
+
}
|
2200
2323
|
}
|
2201
2324
|
else if (severity === "warning") {
|
2202
2325
|
console.warn('WARNING: LoadError: ' + message);
|
@@ -2219,18 +2342,20 @@
|
|
2219
2342
|
|
2220
2343
|
// Initialization
|
2221
2344
|
// --------------
|
2345
|
+
function $BasicObject() {};
|
2346
|
+
function $Object() {};
|
2347
|
+
function $Module() {};
|
2348
|
+
function $Class() {};
|
2222
2349
|
|
2223
|
-
|
2224
|
-
Opal.
|
2225
|
-
Opal.
|
2226
|
-
Opal.
|
2227
|
-
Opal.boot_class_alloc('Class', Class_alloc, Module_alloc);
|
2350
|
+
Opal.BasicObject = BasicObject = Opal.allocate_class('BasicObject', null, $BasicObject);
|
2351
|
+
Opal.Object = _Object = Opal.allocate_class('Object', Opal.BasicObject, $Object);
|
2352
|
+
Opal.Module = Module = Opal.allocate_class('Module', Opal.Object, $Module);
|
2353
|
+
Opal.Class = Class = Opal.allocate_class('Class', Opal.Module, $Class);
|
2228
2354
|
|
2229
|
-
|
2230
|
-
Opal.
|
2231
|
-
Opal.
|
2232
|
-
Opal.
|
2233
|
-
Opal.Class = Class = Opal.setup_class_object('Class', Class_alloc, 'Module', Module.constructor);
|
2355
|
+
$setPrototype(Opal.BasicObject, Opal.Class.$$prototype);
|
2356
|
+
$setPrototype(Opal.Object, Opal.Class.$$prototype);
|
2357
|
+
$setPrototype(Opal.Module, Opal.Class.$$prototype);
|
2358
|
+
$setPrototype(Opal.Class, Opal.Class.$$prototype);
|
2234
2359
|
|
2235
2360
|
// BasicObject can reach itself, avoid const_set to skip the $$base_module logic
|
2236
2361
|
BasicObject.$$const["BasicObject"] = BasicObject;
|
@@ -2241,26 +2366,14 @@
|
|
2241
2366
|
Opal.const_set(_Object, "Module", Module);
|
2242
2367
|
Opal.const_set(_Object, "Class", Class);
|
2243
2368
|
|
2244
|
-
|
2245
|
-
// Fix booted classes to use their metaclass
|
2369
|
+
// Fix booted classes to have correct .class value
|
2246
2370
|
BasicObject.$$class = Class;
|
2247
2371
|
_Object.$$class = Class;
|
2248
2372
|
Module.$$class = Class;
|
2249
2373
|
Class.$$class = Class;
|
2250
2374
|
|
2251
|
-
// Fix superclasses of booted classes
|
2252
|
-
BasicObject.$$super = null;
|
2253
|
-
_Object.$$super = BasicObject;
|
2254
|
-
Module.$$super = _Object;
|
2255
|
-
Class.$$super = Module;
|
2256
|
-
|
2257
|
-
BasicObject.$$parent = null;
|
2258
|
-
_Object.$$parent = BasicObject;
|
2259
|
-
Module.$$parent = _Object;
|
2260
|
-
Class.$$parent = Module;
|
2261
|
-
|
2262
2375
|
// Forward .toString() to #to_s
|
2263
|
-
_Object.$$
|
2376
|
+
$defineProperty(_Object.$$prototype, 'toString', function() {
|
2264
2377
|
var to_s = this.$to_s();
|
2265
2378
|
if (to_s.$$is_string && typeof(to_s) === 'object') {
|
2266
2379
|
// a string created using new String('string')
|
@@ -2268,22 +2381,32 @@
|
|
2268
2381
|
} else {
|
2269
2382
|
return to_s;
|
2270
2383
|
}
|
2271
|
-
};
|
2384
|
+
});
|
2272
2385
|
|
2273
2386
|
// Make Kernel#require immediately available as it's needed to require all the
|
2274
2387
|
// other corelib files.
|
2275
|
-
_Object.$$
|
2388
|
+
$defineProperty(_Object.$$prototype, '$require', Opal.require);
|
2389
|
+
|
2390
|
+
// Add a short helper to navigate constants manually.
|
2391
|
+
// @example
|
2392
|
+
// Opal.$$.Regexp.$$.IGNORECASE
|
2393
|
+
Opal.$$ = _Object.$$;
|
2394
|
+
|
2395
|
+
// Instantiate the main object
|
2396
|
+
Opal.top = new _Object();
|
2397
|
+
Opal.top.$to_s = Opal.top.$inspect = function() { return 'main' };
|
2276
2398
|
|
2277
|
-
// Instantiate the top object
|
2278
|
-
Opal.top = new _Object.$$alloc();
|
2279
2399
|
|
2280
2400
|
// Nil
|
2281
|
-
|
2282
|
-
|
2401
|
+
function $NilClass() {};
|
2402
|
+
Opal.NilClass = Opal.allocate_class('NilClass', Opal.Object, $NilClass);
|
2403
|
+
Opal.const_set(_Object, 'NilClass', Opal.NilClass);
|
2404
|
+
nil = Opal.nil = new Opal.NilClass();
|
2283
2405
|
nil.$$id = nil_id;
|
2284
2406
|
nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };
|
2407
|
+
|
2408
|
+
// Errors
|
2285
2409
|
Opal.breaker = new Error('unexpected break (old)');
|
2286
2410
|
Opal.returner = new Error('unexpected return');
|
2287
|
-
|
2288
2411
|
TypeError.$$super = Error;
|
2289
2412
|
}).call(this);
|