|
@@ -33,7 +33,7 @@
|
|
|
|
|
|
|
|
==================================================================== */
|
|
==================================================================== */
|
|
|
|
|
|
-/* Make that console is defined */
|
|
|
|
|
|
+/* Make sure that console is defined */
|
|
|
|
|
|
if (typeof console === "undefined") {
|
|
if (typeof console === "undefined") {
|
|
this.console = {
|
|
this.console = {
|
|
@@ -47,19 +47,39 @@ if (typeof console === "undefined") {
|
|
|
|
|
|
/* Smalltalk constructors definition */
|
|
/* Smalltalk constructors definition */
|
|
|
|
|
|
-function SmalltalkObject(){}
|
|
|
|
-function SmalltalkBehavior(){}
|
|
|
|
-function SmalltalkClass(){}
|
|
|
|
-function SmalltalkPackage(){}
|
|
|
|
|
|
+function SmalltalkObject(){};
|
|
|
|
+function SmalltalkBehavior(){};
|
|
|
|
+function SmalltalkClass(){};
|
|
|
|
+function SmalltalkPackage(){};
|
|
function SmalltalkMetaclass(){
|
|
function SmalltalkMetaclass(){
|
|
this.meta = true;
|
|
this.meta = true;
|
|
-}
|
|
|
|
-function SmalltalkMethod(){}
|
|
|
|
-function SmalltalkNil(){}
|
|
|
|
|
|
+};
|
|
|
|
+function SmalltalkMethod(){};
|
|
|
|
+function SmalltalkNil(){};
|
|
|
|
|
|
function SmalltalkSymbol(string){
|
|
function SmalltalkSymbol(string){
|
|
this.value = string;
|
|
this.value = string;
|
|
-}
|
|
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+function SmalltalkOrganizer() {
|
|
|
|
+ this.elements = [];
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+SmalltalkOrganizer.prototype.addElement = function(el) {
|
|
|
|
+ if(this.elements.indexOf(el) == -1) {
|
|
|
|
+ this.elements.push(el);
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+SmalltalkOrganizer.prototype.removeElement = function(el) {
|
|
|
|
+ for(var i=0; i<this.elements.length; i++) {
|
|
|
|
+ if(this.elements[i] == el) {
|
|
|
|
+ this.elements.splice(i, 1);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
|
|
function Smalltalk(){
|
|
function Smalltalk(){
|
|
|
|
|
|
@@ -108,6 +128,7 @@ function Smalltalk(){
|
|
function pkg(spec) {
|
|
function pkg(spec) {
|
|
var that = new SmalltalkPackage();
|
|
var that = new SmalltalkPackage();
|
|
that.pkgName = spec.pkgName;
|
|
that.pkgName = spec.pkgName;
|
|
|
|
+ that.organization = new SmalltalkOrganizer();
|
|
that.properties = spec.properties || {};
|
|
that.properties = spec.properties || {};
|
|
return that;
|
|
return that;
|
|
};
|
|
};
|
|
@@ -123,6 +144,7 @@ function Smalltalk(){
|
|
var that = setupClass(meta.instanceClass, spec);
|
|
var that = setupClass(meta.instanceClass, spec);
|
|
that.className = spec.className;
|
|
that.className = spec.className;
|
|
meta.className = spec.className + ' class';
|
|
meta.className = spec.className + ' class';
|
|
|
|
+ that.organization = new SmalltalkOrganizer();
|
|
if(spec.superclass) {
|
|
if(spec.superclass) {
|
|
that.superclass = spec.superclass;
|
|
that.superclass = spec.superclass;
|
|
meta.superclass = spec.superclass.klass;
|
|
meta.superclass = spec.superclass.klass;
|
|
@@ -131,7 +153,8 @@ function Smalltalk(){
|
|
}
|
|
}
|
|
|
|
|
|
function metaclass() {
|
|
function metaclass() {
|
|
- var meta = setupClass(new SmalltalkMetaclass(), {});
|
|
|
|
|
|
+ var meta = setupClass(new SmalltalkMetaclass(), {})
|
|
|
|
+ meta.organization = new SmalltalkOrganizer();
|
|
meta.instanceClass = new meta.fn;
|
|
meta.instanceClass = new meta.fn;
|
|
return meta;
|
|
return meta;
|
|
}
|
|
}
|
|
@@ -320,9 +343,16 @@ function Smalltalk(){
|
|
iVarNames: iVarNames
|
|
iVarNames: iVarNames
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ pkg.organization.addElement(st[className]);
|
|
};
|
|
};
|
|
|
|
|
|
- /* Add a method to a class */
|
|
|
|
|
|
+ st.removeClass = function(klass) {
|
|
|
|
+ klass.pkg.organization.removeElement(klass);
|
|
|
|
+ delete st[klass.className];
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ /* Add/remove a method to/from a class */
|
|
|
|
|
|
st.addMethod = function(jsSelector, method, klass) {
|
|
st.addMethod = function(jsSelector, method, klass) {
|
|
Object.defineProperty(klass.fn.prototype, jsSelector, {
|
|
Object.defineProperty(klass.fn.prototype, jsSelector, {
|
|
@@ -331,8 +361,28 @@ function Smalltalk(){
|
|
klass.fn.prototype.methods[method.selector] = method;
|
|
klass.fn.prototype.methods[method.selector] = method;
|
|
method.methodClass = klass;
|
|
method.methodClass = klass;
|
|
method.jsSelector = jsSelector;
|
|
method.jsSelector = jsSelector;
|
|
|
|
+
|
|
|
|
+ klass.organization.addElement(method.category);
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+ st.removeMethod = function(method) {
|
|
|
|
+ var protocol = method.category;
|
|
|
|
+ var shouldDeleteProtocol;
|
|
|
|
+ var klass = method.methodClass;
|
|
|
|
+
|
|
|
|
+ delete klass.fn.prototype[method.selector._asSelector()];
|
|
|
|
+ delete klass.fn.prototype.methods[method.selector];
|
|
|
|
+
|
|
|
|
+ for(var i=0; i<klass.fn.prototype.methods; i++) {
|
|
|
|
+ if(klass.fn.prototype.methods[i].category == protocol) {
|
|
|
|
+ shouldDeleteProtocol = true;
|
|
|
|
+ };
|
|
|
|
+ };
|
|
|
|
+ if(shouldDeleteProtocol) {
|
|
|
|
+ klass.organization.removeElement(protocol)
|
|
|
|
+ };
|
|
|
|
+ };
|
|
|
|
+
|
|
/* Handles unhandled errors during message sends */
|
|
/* Handles unhandled errors during message sends */
|
|
|
|
|
|
st.send = function(receiver, selector, args, klass) {
|
|
st.send = function(receiver, selector, args, klass) {
|
|
@@ -570,6 +620,7 @@ smalltalk.wrapClassName("Behavior", "Kernel", SmalltalkBehavior, smalltalk.Objec
|
|
smalltalk.wrapClassName("Class", "Kernel", SmalltalkClass, smalltalk.Behavior);
|
|
smalltalk.wrapClassName("Class", "Kernel", SmalltalkClass, smalltalk.Behavior);
|
|
smalltalk.wrapClassName("Metaclass", "Kernel", SmalltalkMetaclass, smalltalk.Behavior);
|
|
smalltalk.wrapClassName("Metaclass", "Kernel", SmalltalkMetaclass, smalltalk.Behavior);
|
|
smalltalk.wrapClassName("CompiledMethod", "Kernel", SmalltalkMethod, smalltalk.Object);
|
|
smalltalk.wrapClassName("CompiledMethod", "Kernel", SmalltalkMethod, smalltalk.Object);
|
|
|
|
+smalltalk.wrapClassName("Organizer", "Kernel-Objects", SmalltalkOrganizer, smalltalk.Object);
|
|
|
|
|
|
smalltalk.Object.klass.superclass = smalltalk.Class;
|
|
smalltalk.Object.klass.superclass = smalltalk.Class;
|
|
|
|
|