Browse Source

initClass refactoring, no need for installSuperclass

Herbert Vojčík 11 years ago
parent
commit
d8f382a87a
1 changed files with 25 additions and 38 deletions
  1. 25 38
      js/boot.js

+ 25 - 38
js/boot.js

@@ -100,6 +100,7 @@ function inherits(child, parent) {
 		constructor: { value: child,
 			enumerable: false, configurable: true, writable: true }
 	});
+	return child;
 }
 
 inherits(SmalltalkBehavior, SmalltalkObject);
@@ -224,7 +225,7 @@ function Smalltalk() {
 		spec = spec || {};
 		var meta = metaclass(spec);
 		var that = meta.instanceClass;
-		that.fn = spec.fn || function() {};
+		that.fn = spec.fn || inherits(function () {}, spec.superclass.fn);
 		setupClass(that, spec);
 
 		that.className = spec.className;
@@ -240,10 +241,7 @@ function Smalltalk() {
 	function metaclass(spec) {
 		spec = spec || {};
 		var that = new SmalltalkMetaclass();
-		inherits(
-			that.fn = function() {},
-			spec.superclass ? spec.superclass.klass.fn : SmalltalkClass
-		);
+		that.fn = inherits(function () {}, spec.superclass ? spec.superclass.klass.fn : SmalltalkClass);
 		that.instanceClass = new that.fn();
 		setupClass(that);
 		return that;
@@ -297,10 +295,7 @@ function Smalltalk() {
 
 	st.initClass = function(klass) {
 		if(klass.wrapped) {
-			klass.inheritedMethods = {};
 			copySuperclass(klass);
-		} else {
-			installSuperclass(klass);
 		}
 
 		if(klass === st.Object || klass.wrapped) {
@@ -315,19 +310,9 @@ function Smalltalk() {
 		});
 	}
 
-	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) {
 		deinstallAllMethods(klass);
+		klass.inheritedMethods = {};
 		for (superclass = superclass || klass.superclass;
 			superclass && superclass !== nil;
 			superclass = superclass.superclass) {
@@ -393,6 +378,20 @@ function Smalltalk() {
 		}
 	}
 
+	function propagateMethodChange(klass) {
+		// If already initialized (else it will be done later anyway),
+		// re-initialize all subclasses to ensure the method change
+		// propagation (for wrapped classes, not using the prototype
+		// chain).
+
+		//TODO: optimize, only one method need to be updated, not all of them
+		if (initialized) {
+			st.allSubclasses(klass).forEach(function (subclass) {
+				st.initClass(subclass);
+			});
+		}
+	}
+
 	/* Answer all registered Packages as Array */
 	// TODO: Remove this hack
 
@@ -546,18 +545,6 @@ function Smalltalk() {
 		return new_addMethod(method_exJsSelector, klass_exMethod);
 	};
 
-	function propagateMethodChange(klass) {
-		// If already initialized (else it will be done later anyway),
-		// re-initialize all subclasses to ensure the method change
-		// propagation (for wrapped classes, not using the prototype
-		// chain.
-		if (initialized) {
-			st.allSubclasses(klass).forEach(function (subclass) {
-				st.initClass(subclass);
-			});
-		}
-	}
-
 	// later, st.addMethod can be this:
 	function new_addMethod(method, klass) {
 		if (!(method.jsSelector)) {
@@ -583,17 +570,17 @@ function Smalltalk() {
 
 	st.removeMethod = function(method, klass) {
 		if (klass !== method.methodClass) {
-            throw new Error(
-                "Refusing to remove method "
-                    + method.methodClass.className+">>"+method.selector
-                    + " from different class "
-                    + klass.className);
-        }
+			throw new Error(
+				"Refusing to remove method "
+					+ method.methodClass.className+">>"+method.selector
+					+ " from different class "
+					+ klass.className);
+		}
 
 		delete klass.fn.prototype[st.selector(method.selector)];
 		delete klass.methods[method.selector];
 
-        st.initClass(klass);
+		st.initClass(klass);
 		propagateMethodChange(klass);
 
 		// Do *not* delete protocols from here.