Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: opal/opal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: dc134af7d903
Choose a base ref
...
head repository: opal/opal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a5cde6b55f04
Choose a head ref
  • 5 commits
  • 2 files changed
  • 1 contributor

Commits on Sep 17, 2014

  1. Copy the full SHA
    f658d89 View commit details
  2. Copy the full SHA
    921c640 View commit details
  3. Rename .__iclass to .$$iclass

    ref: #583
    elia committed Sep 17, 2014
    Copy the full SHA
    35e064f View commit details
  4. Align assignments

    elia committed Sep 17, 2014
    Copy the full SHA
    7e441af View commit details
  5. Rename iclass.name in iclass.$$name

    ref: #583
    elia committed Sep 17, 2014
    Copy the full SHA
    a5cde6b View commit details
Showing with 110 additions and 97 deletions.
  1. +1 −51 opal/corelib/module.rb
  2. +109 −46 opal/corelib/runtime.js
52 changes: 1 addition & 51 deletions opal/corelib/module.rb
Original file line number Diff line number Diff line change
@@ -77,57 +77,7 @@ def ancestors
end

def append_features(klass)
%x{
var module = self,
included = klass.$$inc;
// check if this module is already included in the klass
for (var i = 0, length = included.length; i < length; i++) {
if (included[i] === module) {
return;
}
}
included.push(module);
module.$$dep.push(klass);
// iclass
var iclass = {
name: module.$$name,
$$proto: module.$$proto,
$$parent: klass.$$parent,
__iclass: true
};
klass.$$parent = iclass;
var donator = module.$$proto,
prototype = klass.$$proto,
methods = module.$$methods;
for (var i = 0, length = methods.length; i < length; i++) {
var method = methods[i], current;
if (prototype.hasOwnProperty(method) && !(current = prototype[method]).$$donated && !current.$$stub) {
// if the target class already has a method of the same name defined
// and that method was NOT donated, then it must be a method defined
// by the class so we do not want to override it
}
else {
prototype[method] = donator[method];
prototype[method].$$donated = true;
}
}
if (klass.$$dep) {
$opal.donate(klass, methods.slice(), true);
}
$opal.donate_constants(module, klass);
}

`Opal.append_features(self, klass)`
self
end

155 changes: 109 additions & 46 deletions opal/corelib/runtime.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(function(undefined) {
// The Opal object that is exposed globally
var Opal = this.Opal = {};
var Opal = this.Opal = {}, $opal = Opal;

// All bridged classes - keep track to donate methods from Object
var bridged_classes = Opal.bridged_classes = [];
@@ -189,48 +189,73 @@

var klass = new OpalClass();

// @property $$id Each class is assigned a unique `id` that helps
// comparation and implementation of `#object_id`
klass.$$id = unique_id++;
setup_module_object(klass, OpalClass, superklass, alloc.prototype)

// @property $$alloc This is the constructor of instances of the current
// class. Its prototype will be used for method lookup
klass.$$alloc = alloc;

// @property $$proto We keep a ref to `$$alloc`'s prototype for easy retrieval
klass.$$proto = alloc.prototype;

// @property $$proto.$$class Make available to instances a reference to the
// class they belong to.
klass.$$proto.$$class = klass;

return klass;
}

/*
* Adds common/required properties to a module or class object
* (as in `Module.new` / `Class.new`)
*
* @param module The module or class that needs to be prepared
*
* @param constructor The constructor of the module or class itself,
* usually it's already assigned by using `new`. Some
* ipothesis on why it's needed can be found below.
*
* @param superklass The superclass of the class/module object, for modules
* is `Module` (of `RubyModule` in JS context)
*
* @param prototype The prototype on which the class/module methods will
* be stored.
*/
function setup_module_object(module, constructor, superklass, prototype) {
// @property $$id Each class is assigned a unique `id` that helps
// comparation and implementation of `#object_id`
module.$$id = unique_id++;

// @property $$proto This is the prototype on which methods will be defined
module.$$proto = prototype;

// @property constructor keeps a ref to the constructor, but apparently the
// constructor is already set when `new` is called.
// constructor is already set on:
//
// `var module = new constructor` is called.
//
// Maybe there are some browsers not abiding (IE6?)
klass.constructor = OpalClass;
module.constructor = constructor;

// @property $$is_class Clearly mark this as a class-like
module.$$is_class = true;

// @property $$super the superclass, doesn't get changed by module inclusions
klass.$$super = superklass;
module.$$super = superklass;

// @property $$parent direct parent class or module
// starts with the superclass, after module inclusion is
// the last included module
module.$$parent = superklass;

// @property $$methods keeps track of methods defined on the class
// but seems to be used just by `define_basic_object_method`
// and for donating (Ruby) Object methods to bridged classes
// TODO: check if it can be removed
klass.$$methods = [];
module.$$methods = [];

// @property $$inc included modules
klass.$$inc = [];

// @property $$parent direct parent class or module
// starts with the superclass, after module inclusion is
// the last included module
klass.$$parent = superklass;
module.$$inc = [];
}

// @property $$is_class Clearly mark this as a class
klass.$$is_class = true;

return klass;
}

// Define new module (or return existing module)
Opal.module = function(base, id) {
@@ -268,27 +293,72 @@
var mtor = function() {};
mtor.prototype = RubyModule.constructor.prototype;

function OpalModule() {}
OpalModule.prototype = new mtor();
function module_constructor() {}
module_constructor.prototype = new mtor();

var module = new OpalModule();
var module = new module_constructor();
var module_prototype = {};

module.$$id = unique_id++;
module.$$is_class = true;
module.constructor = OpalModule;
module.$$super = RubyModule;
module.$$methods = [];
module.$$inc = [];
module.$$parent = RubyModule;
module.$$proto = {};
setup_module_object(module, module_constructor, RubyModule, module_prototype)
module.$$is_mod = true;
module.$$dep = [];

return module;
}

Opal.append_features = function(module, klass) {
var included = klass.$$inc;

// check if this module is already included in the klass
for (var i = 0, length = included.length; i < length; i++) {
if (included[i] === module) {
return;
}
}

included.push(module);
module.$$dep.push(klass);

// iclass
var iclass = {
$$name: module.$$name,
$$proto: module.$$proto,
$$parent: klass.$$parent,
$$module: module,
$$iclass: true
};

klass.$$parent = iclass;

var donator = module.$$proto,
prototype = klass.$$proto,
methods = module.$$methods;

for (var i = 0, length = methods.length; i < length; i++) {
var method = methods[i], current;


if (prototype.hasOwnProperty(method) && !(current = prototype[method]).$$donated && !current.$$stub) {
// if the target class already has a method of the same name defined
// and that method was NOT donated, then it must be a method defined
// by the class so we do not want to override it
}
else {
prototype[method] = donator[method];
prototype[method].$$donated = true;
}
}

if (klass.$$dep) {
$opal.donate(klass, methods.slice(), true);
}

$opal.donate_constants(module, klass);
}


// Boot a base class (makes instances).
var boot_class_alloc = function(id, constructor, superklass) {
function boot_class_alloc(id, constructor, superklass) {
if (superklass) {
var ctor = function() {};
ctor.prototype = superklass.prototype;
@@ -303,7 +373,7 @@
};

// Boot the actual (meta?) classes of core classes
var boot_makemeta = function(id, constructor, superklass) {
function boot_makemeta(id, constructor, superklass) {

var mtor = function() {};
mtor.prototype = superklass.prototype;
@@ -314,16 +384,9 @@

var klass = new OpalClass();

klass.$$id = unique_id++;
klass.$$alloc = constructor;
klass.$$is_class = true;
klass.$$name = id;
klass.$$super = superklass;
klass.constructor = OpalClass;
klass.$$methods = [];
klass.$$inc = [];
klass.$$parent = superklass;
klass.$$proto = constructor.prototype;
setup_module_object(klass, OpalClass, superklass, constructor.prototype)
klass.$$alloc = constructor;
klass.$$name = id;

constructor.prototype.$$class = klass;

@@ -1014,10 +1077,10 @@
// act like module includes.
RubyObject.$$dep = bridged_classes;

Opal.base = RubyObject;
Opal.base = RubyObject;
RubyBasicObject.$$scope = RubyObject.$$scope = Opal;
RubyBasicObject.$$orig_scope = RubyObject.$$orig_scope = Opal;
Opal.Kernel = RubyObject;
Opal.Kernel = RubyObject;

RubyModule.$$scope = RubyObject.$$scope;
RubyModule.$$orig_scope = RubyObject.$$orig_scope;