|
@@ -196,6 +196,106 @@ function DNUBrik(brikz, st) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+function ClassInitBrik(brikz, st) {
|
|
|
+
|
|
|
+ var dnu = brikz.ensure("dnu");
|
|
|
+ var manip = brikz.ensure("manipulation");
|
|
|
+
|
|
|
+ /* Initialize a class in its class hierarchy. Handle both classes and
|
|
|
+ metaclasses. */
|
|
|
+
|
|
|
+ st.init = function(klass) {
|
|
|
+ st.initClass(klass);
|
|
|
+ if(klass.klass && !klass.meta) {
|
|
|
+ st.initClass(klass.klass);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ st.initClass = function(klass) {
|
|
|
+ if(klass.wrapped) {
|
|
|
+ klass.inheritedMethods = {};
|
|
|
+ copySuperclass(klass);
|
|
|
+ } else {
|
|
|
+ installSuperclass(klass);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(klass === st.Object || klass.wrapped) {
|
|
|
+ installDnuHandlers(klass);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ function installSuperclass(klass) {
|
|
|
+ // only if the klass has not been initialized yet.
|
|
|
+ if(klass.fn.prototype._yourself) { return; }
|
|
|
+
|
|
|
+ if(klass.superclass && klass.superclass !== nil) {
|
|
|
+ inherits(klass.fn, klass.superclass.fn);
|
|
|
+ manip.wireKlass(klass);
|
|
|
+ manip.reinstallMethods(klass);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function copySuperclass(klass, superclass) {
|
|
|
+ for (superclass = superclass || klass.superclass;
|
|
|
+ superclass && superclass !== nil;
|
|
|
+ superclass = superclass.superclass) {
|
|
|
+ for (var keys = Object.keys(superclass.methods), i = 0; i < keys.length; i++) {
|
|
|
+ inheritMethodIfAbsent(superclass.methods[keys[i]], klass);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function inheritMethodIfAbsent(method, klass) {
|
|
|
+ var selector = method.selector;
|
|
|
+
|
|
|
+ if(klass.methods.hasOwnProperty(selector) || klass.inheritedMethods.hasOwnProperty(selector)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ manip.installMethod(method, klass);
|
|
|
+ klass.inheritedMethods[method.selector] = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ function installDnuHandlers(klass) {
|
|
|
+ var m = dnu.methods;
|
|
|
+ for(var i=0; i<m.length; i++) {
|
|
|
+ manip.installMethodIfAbsent(m[i], klass);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function ManipulationBrik(brikz, st) {
|
|
|
+
|
|
|
+ var manip = this;
|
|
|
+
|
|
|
+ manip.installMethodIfAbsent = function (handler, klass) {
|
|
|
+ var jsFunction = klass.fn.prototype[handler.jsSelector];
|
|
|
+ if(!jsFunction) {
|
|
|
+ manip.installMethod(handler, klass);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ manip.installMethod = function (method, klass) {
|
|
|
+ Object.defineProperty(klass.fn.prototype, method.jsSelector, {
|
|
|
+ value: method.fn,
|
|
|
+ enumerable: false, configurable: true, writable: true
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ manip.wireKlass = function (klass) {
|
|
|
+ Object.defineProperty(klass.fn.prototype, "klass", {
|
|
|
+ value: klass,
|
|
|
+ enumerable: false, configurable: true, writable: true
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ manip.reinstallMethods = function (klass) {
|
|
|
+ for(var keys = Object.keys(klass.methods), i=0; i<keys.length; i++) {
|
|
|
+ manip.installMethod(klass.methods[keys[i]], klass);
|
|
|
+ }
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
var nil = new SmalltalkNil();
|
|
|
|
|
|
function SmalltalkFactory(brikz, st) {
|
|
@@ -205,6 +305,7 @@ function SmalltalkFactory(brikz, st) {
|
|
|
brikz.ensure("selectorConversion");
|
|
|
var org = brikz.ensure("organize");
|
|
|
var dnu = brikz.ensure("dnu");
|
|
|
+ var manip = brikz.ensure("manipulation");
|
|
|
|
|
|
/* This is the current call context object. While it is publicly available,
|
|
|
Use smalltalk.getThisContext() instead which will answer a safe copy of
|
|
@@ -314,7 +415,7 @@ function SmalltalkFactory(brikz, st) {
|
|
|
value: {},
|
|
|
enumerable: false, configurable: true, writable: true
|
|
|
});
|
|
|
- wireKlass(klass);
|
|
|
+ manip.wireKlass(klass);
|
|
|
}
|
|
|
|
|
|
/* Smalltalk method object. To add a method to a class,
|
|
@@ -333,99 +434,10 @@ function SmalltalkFactory(brikz, st) {
|
|
|
return that;
|
|
|
};
|
|
|
|
|
|
- /* Initialize a class in its class hierarchy. Handle both classes and
|
|
|
- metaclasses. */
|
|
|
-
|
|
|
- st.init = function(klass) {
|
|
|
- st.initClass(klass);
|
|
|
- if(klass.klass && !klass.meta) {
|
|
|
- st.initClass(klass.klass);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- st.initClass = function(klass) {
|
|
|
- if(klass.wrapped) {
|
|
|
- klass.inheritedMethods = {};
|
|
|
- copySuperclass(klass);
|
|
|
- } else {
|
|
|
- installSuperclass(klass);
|
|
|
- }
|
|
|
-
|
|
|
- if(klass === st.Object || klass.wrapped) {
|
|
|
- installDnuHandlers(klass);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- function wireKlass(klass) {
|
|
|
- Object.defineProperty(klass.fn.prototype, "klass", {
|
|
|
- value: klass,
|
|
|
- enumerable: false, configurable: true, writable: true
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- function installSuperclass(klass) {
|
|
|
- // only if the klass has not been initialized yet.
|
|
|
- if(klass.fn.prototype._yourself) { return; }
|
|
|
-
|
|
|
- if(klass.superclass && klass.superclass !== nil) {
|
|
|
- inherits(klass.fn, klass.superclass.fn);
|
|
|
- wireKlass(klass);
|
|
|
- reinstallMethods(klass);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function copySuperclass(klass, superclass) {
|
|
|
- for (superclass = superclass || klass.superclass;
|
|
|
- superclass && superclass !== nil;
|
|
|
- superclass = superclass.superclass) {
|
|
|
- for (var keys = Object.keys(superclass.methods), i = 0; i < keys.length; i++) {
|
|
|
- inheritMethodIfAbsent(superclass.methods[keys[i]], klass);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function installMethod(method, klass) {
|
|
|
- Object.defineProperty(klass.fn.prototype, method.jsSelector, {
|
|
|
- value: method.fn,
|
|
|
- enumerable: false, configurable: true, writable: true
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- function inheritMethodIfAbsent(method, klass) {
|
|
|
- var selector = method.selector;
|
|
|
-
|
|
|
- if(klass.methods.hasOwnProperty(selector) || klass.inheritedMethods.hasOwnProperty(selector)) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- installMethod(method, klass);
|
|
|
- klass.inheritedMethods[method.selector] = true;
|
|
|
- }
|
|
|
-
|
|
|
- function reinstallMethods(klass) {
|
|
|
- for(var keys = Object.keys(klass.methods), i=0; i<keys.length; i++) {
|
|
|
- installMethod(klass.methods[keys[i]], klass);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function installDnuHandlers(klass) {
|
|
|
- var m = dnu.methods;
|
|
|
- for(var i=0; i<m.length; i++) {
|
|
|
- installMethodIfAbsent(m[i], klass);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
function installNewDnuHandler(newHandler) {
|
|
|
- installMethodIfAbsent(newHandler, st.Object);
|
|
|
+ manip.installMethodIfAbsent(newHandler, st.Object);
|
|
|
for(var i = 0; i < wrappedClasses.length; i++) {
|
|
|
- installMethodIfAbsent(newHandler, wrappedClasses[i]);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function installMethodIfAbsent(handler, klass) {
|
|
|
- var jsFunction = klass.fn.prototype[handler.jsSelector];
|
|
|
- if(!jsFunction) {
|
|
|
- installMethod(handler, klass);
|
|
|
+ manip.installMethodIfAbsent(newHandler, wrappedClasses[i]);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -587,7 +599,7 @@ function SmalltalkFactory(brikz, st) {
|
|
|
if (!(method.jsSelector)) {
|
|
|
method.jsSelector = st.selector(method.selector);
|
|
|
}
|
|
|
- installMethod(method, klass);
|
|
|
+ manip.installMethod(method, klass);
|
|
|
klass.methods[method.selector] = method;
|
|
|
method.methodClass = klass;
|
|
|
|
|
@@ -889,6 +901,8 @@ brikz.messageSend = MessageSendBrik;
|
|
|
brikz.organize = OrganizeBrik;
|
|
|
brikz.selectorConversion = SelectorConversionBrik;
|
|
|
brikz.smalltalk = SmalltalkFactory;
|
|
|
+brikz.classInit = ClassInitBrik;
|
|
|
+brikz.manipulation = ManipulationBrik;
|
|
|
brikz.rebuild();
|
|
|
|
|
|
var smalltalk = api;
|