Browse Source

Merge pull request #202 from herby/es5

Fixes #200
Nicolas Petton 12 years ago
parent
commit
917f475e13
4 changed files with 63 additions and 33 deletions
  1. 7 1
      js/Kernel-Objects.deploy.js
  2. 8 2
      js/Kernel-Objects.js
  3. 41 29
      js/boot.js
  4. 7 1
      st/Kernel-Objects.st

+ 7 - 1
js/Kernel-Objects.deploy.js

@@ -226,7 +226,13 @@ smalltalk.method({
 selector: "identityHash",
 fn: function (){
 var self=this;
-return self.identityHash || (self.identityHash = smalltalk.nextId());;
+
+	var hash=self.identityHash;
+	if (hash) return hash;
+	hash=smalltalk.nextId();
+	Object.defineProperty(self, 'identityHash', {value:hash});
+	return hash;
+	;
 return self;}
 }),
 smalltalk.Object);

+ 8 - 2
js/Kernel-Objects.js

@@ -323,10 +323,16 @@ selector: "identityHash",
 category: 'accessing',
 fn: function (){
 var self=this;
-return self.identityHash || (self.identityHash = smalltalk.nextId());;
+
+	var hash=self.identityHash;
+	if (hash) return hash;
+	hash=smalltalk.nextId();
+	Object.defineProperty(self, 'identityHash', {value:hash});
+	return hash;
+	;
 return self;},
 args: [],
-source: "identityHash\x0a\x09<return self.identityHash || (self.identityHash = smalltalk.nextId());>",
+source: "identityHash\x0a\x09<\x0a\x09var hash=self.identityHash;\x0a\x09if (hash) return hash;\x0a\x09hash=smalltalk.nextId();\x0a\x09Object.defineProperty(self, 'identityHash', {value:hash});\x0a\x09return hash;\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),

+ 41 - 29
js/boot.js

@@ -45,22 +45,21 @@ if (typeof console === "undefined") {
 	};
 }
 
-
 /* Smalltalk constructors definition */
 
 function SmalltalkObject(){}
-function SmalltalkBehavior(){};
+function SmalltalkBehavior(){}
 function SmalltalkClass(){}
-function SmalltalkPackage(){};
+function SmalltalkPackage(){}
 function SmalltalkMetaclass(){
 	this.meta = true;
-};
-function SmalltalkMethod(){};
-function SmalltalkNil(){};
+}
+function SmalltalkMethod(){}
+function SmalltalkNil(){}
 
 function SmalltalkSymbol(string){
 	this.value = string;
-};
+}
 
 function Smalltalk(){
 
@@ -107,8 +106,8 @@ function Smalltalk(){
 	/* Smalltalk package creation. To add a Package, use smalltalk.addPackage() */
 
 	function pkg(spec) {
-		var that      = new SmalltalkPackage();
-		that.pkgName  = spec.pkgName;
+		var that = new SmalltalkPackage();
+		that.pkgName = spec.pkgName;
 		that.properties = spec.properties || {};
 		return that;
 	};
@@ -120,28 +119,37 @@ function Smalltalk(){
 
 	function klass(spec) {
 		var spec = spec || {};
-		var that;
-		if(spec.meta) {
-			that = new SmalltalkMetaclass();
-		} else {
-			that = new (klass({meta: true})).fn;
-			that.klass.instanceClass = that;
-			that.className = spec.className;
-			that.klass.className = that.className + ' class';
+		var meta = metaKlass();
+		var that = setupKlass(meta.instanceClass, spec);
+		that.className = spec.className;
+		meta.className = spec.className + ' class';
+		if(spec.superclass) {
+			that.superclass = spec.superclass;
+			meta.superclass = spec.superclass.klass;
 		}
+		return that;
+	}
+	
+	function metaKlass() {
+		var meta = setupKlass(new SmalltalkMetaclass(), {});
+		meta.instanceClass = new meta.fn;
+		return meta;
+	}
+	
+	function klassToString() { return 'Smalltalk ' + this.className; }
 
+	function setupKlass(that, spec) {
 		that.fn = spec.fn || function(){};
-		that.superclass = spec.superclass;
 		that.iVarNames = spec.iVarNames || [];
-        that.toString = function() {return 'Smalltalk ' + that.className};
-		if(that.superclass) {
-			that.klass.superclass = that.superclass.klass;
-		}
+		Object.defineProperty(that, "toString", {
+			value: klassToString, configurable: true // no writable - in par with ES6 methods
+		});
 		that.pkg = spec.pkg;
-		that.fn.prototype.methods = {};
-		that.fn.prototype.inheritedMethods = {};
-		that.fn.prototype.klass = that;
-
+		Object.defineProperties(that.fn.prototype, {
+			methods: { value: {}, enumerable: false, configurable: true, writable: true },
+			inheritedMethods: { value: {}, enumerable: false, configurable: true, writable: true },
+			klass: { value: that, enumerable: false, configurable: true, writable: true }
+		});
 		return that;
 	};
 
@@ -158,7 +166,7 @@ function Smalltalk(){
 		that.messageSends      = spec.messageSends || [];
 		that.referencedClasses = spec.referencedClasses || [];
 		that.fn                = spec.fn;
-		return that
+		return that;
 	};
 
 	/* Initialize a class in its class hierarchy. Handle both class and
@@ -183,7 +191,9 @@ function Smalltalk(){
 				var k = keys[i]
 				if(!proto.methods[k]) {
 					proto.inheritedMethods[k] = methods[k];
-					proto[methods[k].jsSelector] = methods[k].fn;
+					Object.defineProperty(proto, methods[k].jsSelector, {
+						value: methods[k].fn, configurable: true // no writable - in par with ES6 methods
+					});
 				}
 			}
 		}
@@ -316,7 +326,9 @@ function Smalltalk(){
 	/* Add a method to a class */
 
 	st.addMethod = function(jsSelector, method, klass) {
-		klass.fn.prototype[jsSelector] = method.fn;
+		Object.defineProperty(klass.fn.prototype, jsSelector, {
+			value: method.fn, configurable: true // not writable - in par with ES6 methods
+		});
 		klass.fn.prototype.methods[method.selector] = method;
 		method.methodClass = klass;
 		method.jsSelector = jsSelector;

+ 7 - 1
st/Kernel-Objects.st

@@ -58,7 +58,13 @@ class
 !
 
 identityHash
-	<return self.identityHash || (self.identityHash = smalltalk.nextId());>
+	<
+	var hash=self.identityHash;
+	if (hash) return hash;
+	hash=smalltalk.nextId();
+	Object.defineProperty(self, 'identityHash', {value:hash});
+	return hash;
+	>
 !
 
 instVarAt: aSymbol