소스 검색

Refactoring dnu management.

DNU handlers are cached,
Fixed bug when if in installNewDnuHandler were never true,
because of addDnuHandler called before it.
Herbert Vojčík 12 년 전
부모
커밋
0da3758f87
1개의 변경된 파일40개의 추가작업 그리고 34개의 파일을 삭제
  1. 40 34
      js/boot.js

+ 40 - 34
js/boot.js

@@ -124,24 +124,33 @@ function Smalltalk() {
     var classes = [];
     var wrappedClasses = [];
 
-    /* Method not implemented handlers selectors */
+    /* Method not implemented handlers */
 
-    var dnuHandlers = [];
+	var dnu = {
+		methods: [],
+		selectors: [],
 
-    function addDnuHandler(string) {
-        if(dnuHandlers.indexOf(string) == -1) {
-            dnuHandlers.push(string);
-        }
-	}
-
-	/* Dnu handler method */
-
-    function dnu(selector) {
-        return function() {
-            var args = Array.prototype.slice.call(arguments);
-            return messageNotUnderstood(this, selector, args);
-        };
-	}
+		get: function (string) {
+			var index = this.selectors.indexOf(string);
+			if(index !== -1) {
+				return this.methods[index];
+			}
+			this.selectors.push(string);
+			var selector = st.selector(string);
+			var method = {jsSelector: selector, fn: this.createHandler(selector)};
+			this.methods.push(method);
+			return method;
+		},
+
+		/* Dnu handler method */
+
+		createHandler: function (selector) {
+			return function () {
+				var args = Array.prototype.slice.call(arguments);
+				return messageNotUnderstood(this, selector, args);
+			};
+		}
+	};
 
 	/* The symbol table ensures symbol unicity */
 
@@ -307,6 +316,12 @@ function Smalltalk() {
 		});
 	}
 
+	function installMethodIfAbsent(method, klass) {
+		if(!klass.fn.prototype[method.jsSelector]) {
+			installMethod(method, klass);
+		}
+	}
+
 	function reinstallMethods(klass) {
         for(var keys = Object.keys(klass.methods), i=0; i<keys.length; i++) {
             installMethod(klass.methods[keys[i]], klass);
@@ -314,25 +329,16 @@ function Smalltalk() {
 	}
 
 	function installDnuHandlers(klass) {
-        for(var i=0; i<dnuHandlers.length; i++) {
-            installDnuHandler(dnuHandlers[i], klass);
+		var m = dnu.methods;
+        for(var i=0; i<m.length; i++) {
+			installMethodIfAbsent(m[i], klass);
         }
 	}
 
-	function installDnuHandler(string, klass) {
-        var selector = st.selector(string);
-        if(!klass.fn.prototype[selector]) {
-			installMethod({jsSelector: selector, fn: dnu(selector)}, klass);
-        }
-	}
-
-	function installNewDnuHandler(string) {
-        if(dnuHandlers.indexOf(string) === -1) {
-            addDnuHandler(string);
-            installDnuHandler(string, st.Object);
-            for(var i=0; i<wrappedClasses.length; i++) {
-                installDnuHandler(string, wrappedClasses[i]);
-			}
+	function installNewDnuHandler(newHandler) {
+		installMethodIfAbsent(newHandler, st.Object);
+		for(var i = 0; i < wrappedClasses.length; i++) {
+			installMethodIfAbsent(newHandler, wrappedClasses[i]);
 		}
 	}
 
@@ -469,9 +475,9 @@ function Smalltalk() {
         klass.organization.elements.addElement(method.category);
 
         for(var i=0; i<method.messageSends.length; i++) {
-            addDnuHandler(method.messageSends[i]);
+            var dnuHandler = dnu.get(method.messageSends[i]);
             if(initialized) {
-                installNewDnuHandler(method.messageSends[i]);
+                installNewDnuHandler(dnuHandler);
 			}
 		}
 	};