Browse Source

kernel: Fundamentals not using singletons.

It exports Factory which has them injected.
Herby Vojčík 4 years ago
parent
commit
42b4ee1691
2 changed files with 208 additions and 209 deletions
  1. 4 3
      lang/base/boot.js
  2. 204 206
      lang/base/kernel-fundamentals.js

+ 4 - 3
lang/base/boot.js

@@ -41,7 +41,7 @@
 
 define([
     'require', './kernel-checks', './brikz', './kernel-fundamentals', './kernel-language'
-], function (require, _, Brikz, Fundamentals, LanguageFactory) {
+], function (require, _, Brikz, FundamentalsFactory, LanguageFactory) {
     "use strict";
 
     var globals = Object.create(global);
@@ -84,9 +84,10 @@ define([
     Object.defineProperty(brikz, "commonGlobals", {value: globals});
     Object.defineProperty(brikz, "commonEmit", {value: emit});
 
-    Fundamentals.configure(brikz);
+    var fundamentals = FundamentalsFactory(globals, emit);
+    fundamentals.configure(brikz);
 
-    LanguageFactory(Fundamentals.specialConstructors, emit).configure(brikz);
+    LanguageFactory(fundamentals.specialConstructors, emit).configure(brikz);
 
     brikz.stInit = SmalltalkInitBrik;
     brikz.amd = AMDBrik;

+ 204 - 206
lang/base/kernel-fundamentals.js

@@ -13,264 +13,262 @@ define(function () {
         return child;
     }
 
-    function EventBrik (brikz, st) {
-        var emit = brikz.commonEmit;
+    function FundamentalsFactory (globals, emit) {
+        var specialConstructors = Object.create(null);
 
-        this.declareEvent = function (event) {
-            if (!emit[event]) emit[event] = function () {
-            };
+        function EventBrik (brikz, st) {
+            this.declareEvent = function (event) {
+                if (!emit[event]) emit[event] = function () {
+                };
+            }
         }
-    }
 
-    function RootBrik (brikz, st) {
-        var specialConstructors = brikz.commonSpecialConstructors;
+        function RootBrik (brikz, st) {
+            /* Smalltalk foundational objects */
 
-        /* Smalltalk foundational objects */
+            /* SmalltalkRoot is the hidden root of the normal Amber hierarchy.
+             All objects including `ProtoObject` inherit from SmalltalkRoot.
+             Detached roots (eg. wrapped JS classes like Number or Date)
+             do not directly inherit from SmalltalkRoot, but employ a workaround.*/
+            function SmalltalkRoot () {
+            }
 
-        /* SmalltalkRoot is the hidden root of the normal Amber hierarchy.
-         All objects including `ProtoObject` inherit from SmalltalkRoot.
-         Detached roots (eg. wrapped JS classes like Number or Date)
-         do not directly inherit from SmalltalkRoot, but employ a workaround.*/
-        function SmalltalkRoot () {
-        }
+            function SmalltalkProtoObject () {
+            }
 
-        function SmalltalkProtoObject () {
-        }
+            function SmalltalkObject () {
+            }
+
+            specialConstructors.ProtoObject = inherits(SmalltalkProtoObject, SmalltalkRoot);
+            specialConstructors.Object = inherits(SmalltalkObject, SmalltalkProtoObject);
 
-        function SmalltalkObject () {
+            this.Root = SmalltalkRoot;
+            this.Object = SmalltalkObject;
         }
 
-        specialConstructors.ProtoObject = inherits(SmalltalkProtoObject, SmalltalkRoot);
-        specialConstructors.Object = inherits(SmalltalkObject, SmalltalkProtoObject);
+        function SelectorsBrik (brikz, st) {
+            var selectorSet = Object.create(null);
+            var selectors = this.selectors = [];
 
-        this.Root = SmalltalkRoot;
-        this.Object = SmalltalkObject;
-    }
+            this.registerSelector = function (stSelector) {
+                if (selectorSet[stSelector]) return false;
+                selectors.push(stSelector);
+                return selectorSet[stSelector] = true;
+            };
 
-    function SelectorsBrik (brikz, st) {
-        var selectorSet = Object.create(null);
-        var selectors = this.selectors = [];
+            st.allSelectors = function () {
+                return selectors;
+            };
+        }
 
-        this.registerSelector = function (stSelector) {
-            if (selectorSet[stSelector]) return false;
-            selectors.push(stSelector);
-            return selectorSet[stSelector] = true;
-        };
+        function PackagesBrik (brikz, st) {
+            st.packageDescriptors = {};
 
-        st.allSelectors = function () {
-            return selectors;
-        };
-    }
+            /* Add a package load descriptor to the system */
+            st.addPackage = function (name, properties) {
+                if (!name) return null;
+                return st.packageDescriptors[name] = {properties: properties};
+            };
+        }
 
-    function PackagesBrik (brikz, st) {
-        st.packageDescriptors = {};
+        BehaviorsBrik.deps = ["root", "arraySet"];
 
-        /* Add a package load descriptor to the system */
-        st.addPackage = function (name, properties) {
-            if (!name) return null;
-            return st.packageDescriptors[name] = {properties: properties};
-        };
-    }
+        function BehaviorsBrik (brikz, st) {
+            var addElement = brikz.arraySet.addElement;
+            var removeElement = brikz.arraySet.removeElement;
 
-    BehaviorsBrik.deps = ["root", "arraySet"];
-    function BehaviorsBrik (brikz, st) {
-        var globals = brikz.commonGlobals;
-        var addElement = brikz.arraySet.addElement;
-        var removeElement = brikz.arraySet.removeElement;
+            /* Smalltalk classes and traits */
 
-        /* Smalltalk classes and traits */
+            var traitsOrClasses = [];
 
-        var traitsOrClasses = [];
+            this.buildTraitOrClass = function (category, builder) {
+                var traitOrClass = globals.hasOwnProperty(builder.name) && globals[builder.name];
+                if (traitOrClass) {
+                    builder.updateExisting(traitOrClass);
+                } else {
+                    traitOrClass = builder.make();
+                    traitOrClass.category = category;
+                    addTraitOrClass(traitOrClass);
+                }
 
-        this.buildTraitOrClass = function (category, builder) {
-            var traitOrClass = globals.hasOwnProperty(builder.name) && globals[builder.name];
-            if (traitOrClass) {
-                builder.updateExisting(traitOrClass);
-            } else {
-                traitOrClass = builder.make();
-                traitOrClass.category = category;
-                addTraitOrClass(traitOrClass);
+                return traitOrClass;
+            };
+
+            function addTraitOrClass (traitOrClass) {
+                globals[traitOrClass.name] = traitOrClass;
+                addElement(traitsOrClasses, traitOrClass);
+                traitOrClass.added();
             }
 
-            return traitOrClass;
-        };
+            function removeTraitOrClass (traitOrClass) {
+                traitOrClass.removed();
+                removeElement(traitsOrClasses, traitOrClass);
+                delete globals[traitOrClass.name];
+            }
 
-        function addTraitOrClass (traitOrClass) {
-            globals[traitOrClass.name] = traitOrClass;
-            addElement(traitsOrClasses, traitOrClass);
-            traitOrClass.added();
-        }
+            this.removeTraitOrClass = removeTraitOrClass;
 
-        function removeTraitOrClass (traitOrClass) {
-            traitOrClass.removed();
-            removeElement(traitsOrClasses, traitOrClass);
-            delete globals[traitOrClass.name];
+            st.traitsOrClasses = this.traitsOrClasses = traitsOrClasses;
         }
 
-        this.removeTraitOrClass = removeTraitOrClass;
+        MethodsBrik.deps = ["event", "selectors", "root"];
 
-        st.traitsOrClasses = this.traitsOrClasses = traitsOrClasses;
-    }
+        function MethodsBrik (brikz, st) {
+            var registerSelector = brikz.selectors.registerSelector;
+            var SmalltalkObject = brikz.root.Object;
+            var declareEvent = brikz.event.declareEvent;
 
-    MethodsBrik.deps = ["event", "selectors", "root"];
-    function MethodsBrik (brikz, st) {
-        var registerSelector = brikz.selectors.registerSelector;
-        var SmalltalkObject = brikz.root.Object;
-        var specialConstructors = brikz.commonSpecialConstructors;
-        var emit = brikz.commonEmit;
-        var declareEvent = brikz.event.declareEvent;
+            function SmalltalkMethod () {
+            }
 
-        function SmalltalkMethod () {
-        }
+            specialConstructors.CompiledMethod = inherits(SmalltalkMethod, SmalltalkObject);
+
+            /* Smalltalk method object. To add a method to a class,
+             use api.addMethod() */
+
+            st.method = function (spec, factory) {
+                var that = new SmalltalkMethod();
+                that.selector = spec.selector;
+                that.args = spec.args || [];
+                that.protocol = spec.protocol;
+                that.source = spec.source;
+                that.pragmas = spec.pragmas;
+                that.messageSends = spec.messageSends || [];
+                // TODO remove .referencedClasses, have .referencedGlobals
+                that.referencedClasses = spec.referencedClasses || [];
+                that.fn = spec.fn;
+                if (factory) that.instantiateFn = factory;
+                return that;
+            };
 
-        specialConstructors.CompiledMethod = inherits(SmalltalkMethod, SmalltalkObject);
-
-        /* Smalltalk method object. To add a method to a class,
-         use api.addMethod() */
-
-        st.method = function (spec, factory) {
-            var that = new SmalltalkMethod();
-            that.selector = spec.selector;
-            that.args = spec.args || [];
-            that.protocol = spec.protocol;
-            that.source = spec.source;
-            that.pragmas = spec.pragmas;
-            that.messageSends = spec.messageSends || [];
-            // TODO remove .referencedClasses, have .referencedGlobals
-            that.referencedClasses = spec.referencedClasses || [];
-            that.fn = spec.fn;
-            if (factory) that.instantiateFn = factory;
-            return that;
-        };
-
-        /* Add/remove a method to/from a class */
-
-        st.addMethod = function (method, traitOrBehavior) {
-            if (method.owner != null) {
-                throw new Error("addMethod: Method " + method.selector + " already bound to " + method.owner);
-            }
-            method.owner = traitOrBehavior;
-            registerNewSelectors(method);
-            traitOrBehavior.localMethods[method.selector] = method;
-            updateMethod(method.selector, traitOrBehavior);
-        };
+            /* Add/remove a method to/from a class */
 
-        declareEvent("selectorsAdded");
+            st.addMethod = function (method, traitOrBehavior) {
+                if (method.owner != null) {
+                    throw new Error("addMethod: Method " + method.selector + " already bound to " + method.owner);
+                }
+                method.owner = traitOrBehavior;
+                registerNewSelectors(method);
+                traitOrBehavior.localMethods[method.selector] = method;
+                updateMethod(method.selector, traitOrBehavior);
+            };
+
+            declareEvent("selectorsAdded");
 
-        function registerNewSelectors (method) {
-            var newSelectors = [];
+            function registerNewSelectors (method) {
+                var newSelectors = [];
 
-            function selectorInUse (stSelector) {
-                if (registerSelector(stSelector)) {
-                    newSelectors.push(stSelector);
+                function selectorInUse (stSelector) {
+                    if (registerSelector(stSelector)) {
+                        newSelectors.push(stSelector);
+                    }
                 }
-            }
 
-            selectorInUse(method.selector);
-            method.messageSends.forEach(selectorInUse);
-            emit.selectorsAdded(newSelectors);
-        }
+                selectorInUse(method.selector);
+                method.messageSends.forEach(selectorInUse);
+                emit.selectorsAdded(newSelectors);
+            }
 
-        st.removeMethod = function (method, traitOrBehavior) {
-            if (traitOrBehavior.localMethods[method.selector] !== method) return;
+            st.removeMethod = function (method, traitOrBehavior) {
+                if (traitOrBehavior.localMethods[method.selector] !== method) return;
 
-            delete traitOrBehavior.localMethods[method.selector];
-            updateMethod(method.selector, traitOrBehavior);
-        };
+                delete traitOrBehavior.localMethods[method.selector];
+                updateMethod(method.selector, traitOrBehavior);
+            };
 
-        this.setupMethods = function (traitOrBehavior) {
-            traitOrBehavior.localMethods = Object.create(null);
-            traitOrBehavior.methods = Object.create(null);
-        };
+            this.setupMethods = function (traitOrBehavior) {
+                traitOrBehavior.localMethods = Object.create(null);
+                traitOrBehavior.methods = Object.create(null);
+            };
 
-        declareEvent("methodReplaced");
+            declareEvent("methodReplaced");
 
-        function updateMethod (selector, traitOrBehavior) {
-            var oldMethod = traitOrBehavior.methods[selector],
-                newMethod = traitOrBehavior.localMethods[selector];
-            if (oldMethod == null && newMethod == null) {
-                console.warn("Removal of nonexistent method " + traitOrBehavior + " >> " + selector);
-                return;
-            }
-            if (newMethod === oldMethod) return;
-            if (newMethod != null) {
-                if (newMethod.methodClass && newMethod.methodClass !== traitOrBehavior) {
-                    console.warn("Resetting methodClass of " + newMethod.methodClass.name + " >> " + selector + " to " + traitOrBehavior.name);
+            function updateMethod (selector, traitOrBehavior) {
+                var oldMethod = traitOrBehavior.methods[selector],
+                    newMethod = traitOrBehavior.localMethods[selector];
+                if (oldMethod == null && newMethod == null) {
+                    console.warn("Removal of nonexistent method " + traitOrBehavior + " >> " + selector);
+                    return;
                 }
-                newMethod.methodClass = traitOrBehavior;
-                if (newMethod.instantiateFn) {
-                    newMethod.fn = newMethod.instantiateFn(traitOrBehavior);
+                if (newMethod === oldMethod) return;
+                if (newMethod != null) {
+                    if (newMethod.methodClass && newMethod.methodClass !== traitOrBehavior) {
+                        console.warn("Resetting methodClass of " + newMethod.methodClass.name + " >> " + selector + " to " + traitOrBehavior.name);
+                    }
+                    newMethod.methodClass = traitOrBehavior;
+                    if (newMethod.instantiateFn) {
+                        newMethod.fn = newMethod.instantiateFn(traitOrBehavior);
+                    }
+                    traitOrBehavior.methods[selector] = newMethod;
+                    traitOrBehavior.methodAdded(newMethod);
+                } else {
+                    delete traitOrBehavior.methods[selector];
+                    traitOrBehavior.methodRemoved(oldMethod);
                 }
-                traitOrBehavior.methods[selector] = newMethod;
-                traitOrBehavior.methodAdded(newMethod);
-            } else {
-                delete traitOrBehavior.methods[selector];
-                traitOrBehavior.methodRemoved(oldMethod);
+                emit.methodReplaced(newMethod, oldMethod, traitOrBehavior);
             }
-            emit.methodReplaced(newMethod, oldMethod, traitOrBehavior);
+
+            this.updateMethod = updateMethod;
         }
 
-        this.updateMethod = updateMethod;
-    }
+        function ArraySetBrik (brikz, st) {
+            st.addElement = this.addElement = function (array, el) {
+                if (typeof el === 'undefined') {
+                    return;
+                }
+                if (array.indexOf(el) === -1) {
+                    array.push(el);
+                }
+            };
 
-    function ArraySetBrik (brikz, st) {
-        st.addElement = this.addElement = function (array, el) {
-            if (typeof el === 'undefined') {
-                return;
-            }
-            if (array.indexOf(el) === -1) {
-                array.push(el);
-            }
-        };
+            st.removeElement = this.removeElement = function (array, el) {
+                var i = array.indexOf(el);
+                if (i !== -1) {
+                    array.splice(i, 1);
+                }
+            };
+        }
 
-        st.removeElement = this.removeElement = function (array, el) {
-            var i = array.indexOf(el);
-            if (i !== -1) {
-                array.splice(i, 1);
-            }
-        };
-    }
+        NilBrik.deps = ["root"];
 
-    NilBrik.deps = ["root"];
-    function NilBrik (brikz, st) {
-        var SmalltalkObject = brikz.root.Object;
-        var specialConstructors = brikz.commonSpecialConstructors;
+        function NilBrik (brikz, st) {
+            var SmalltalkObject = brikz.root.Object;
 
-        function SmalltalkNil () {
-        }
+            function SmalltalkNil () {
+            }
 
-        specialConstructors.UndefinedObject = inherits(SmalltalkNil, SmalltalkObject);
+            specialConstructors.UndefinedObject = inherits(SmalltalkNil, SmalltalkObject);
 
-        this.nilAsReceiver = new SmalltalkNil();
-        this.nilAsValue = this.nilAsReceiver; // TODO null
+            this.nilAsReceiver = new SmalltalkNil();
+            this.nilAsValue = this.nilAsReceiver; // TODO null
 
-        // Adds an `a$nil` property to the `nil` object.  When sending
-        // nil objects from one environment to another, doing
-        // `anObject == nil` (in JavaScript) does not always answer
-        // true as the referenced nil object might come from the other
-        // environment.
-        Object.defineProperty(this.nilAsReceiver, 'a$nil', {
-            value: true,
-            enumerable: false, configurable: false, writable: false
-        });
-    }
+            // Adds an `a$nil` property to the `nil` object.  When sending
+            // nil objects from one environment to another, doing
+            // `anObject == nil` (in JavaScript) does not always answer
+            // true as the referenced nil object might come from the other
+            // environment.
+            Object.defineProperty(this.nilAsReceiver, 'a$nil', {
+                value: true,
+                enumerable: false, configurable: false, writable: false
+            });
+        }
+
+        /* Making smalltalk that has basic building blocks */
+        function configure (brikz) {
+            brikz.root = RootBrik;
+            brikz.nil = NilBrik;
+            brikz.event = EventBrik;
+            brikz.arraySet = ArraySetBrik;
+            brikz.selectors = SelectorsBrik;
+            brikz.packages = PackagesBrik;
+            brikz.behaviors = BehaviorsBrik;
+            brikz.methods = MethodsBrik;
+
+            brikz();
+        }
 
-    var specialConstructors = Object.create(null);
-
-    /* Making smalltalk that has basic building blocks */
-    function configure (brikz) {
-        Object.defineProperty(brikz, "commonSpecialConstructors", {value: specialConstructors});
-        brikz.root = RootBrik;
-        brikz.nil = NilBrik;
-        brikz.event = EventBrik;
-        brikz.arraySet = ArraySetBrik;
-        brikz.selectors = SelectorsBrik;
-        brikz.packages = PackagesBrik;
-        brikz.behaviors = BehaviorsBrik;
-        brikz.methods = MethodsBrik;
-
-        brikz();
+        return {configure: configure, specialConstructors: specialConstructors};
     }
 
-    return {configure: configure, specialConstructors: specialConstructors};
+    return FundamentalsFactory;
 });