Browse Source

Do not organize methods in kernel.

Herbert Vojčík 7 years ago
parent
commit
62f501a527

+ 5 - 0
API-CHANGES.txt

@@ -8,6 +8,8 @@
 + AmberBootstrapInitialization class >>
   + run
   + initializeClasses
+  + organizeClasses
+  + otganizeMethods
 + Behavior >>
   + basicOrganization
 + Compiler class >>
@@ -29,7 +31,10 @@
   + named:javaScriptDescriptor:
 + SmalltalkImage >>
   + packageDictionary
++ TBehaviorProvider >>
+  + methodOrganizationEnter:andLeave:
 + TMasterBehavior >>
+  + definedMethods
   + enterOrganization
   + leaveOrganization
 + Trait >>

+ 1 - 0
CHANGELOG

@@ -11,6 +11,7 @@
   * NonBooleanReceiver class >> signalOn:
   * TMasterBehavior >> enterOrganization
   * TMasterBehavior >> leaveOrganization
+  * TBehaviorProvider >> methodOrganizationEnter:andLeave:
 
 Commits: https://lolg.it/amber/amber/commits/0.19.1.
 

+ 76 - 0
src/Kernel-Classes.js

@@ -2515,6 +2515,45 @@ messageSends: []
 }),
 $globals.TBehaviorProvider);
 
+$core.addMethod(
+$core.method({
+selector: "methodOrganizationEnter:andLeave:",
+protocol: "accessing",
+fn: function (aMethod,oldMethod){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$2,$receiver;
+if(($receiver = aMethod) == null || $receiver.a$nil){
+aMethod;
+} else {
+$1=$self._organization();
+$2=$recv(aMethod)._protocol();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["protocol"]=1;
+//>>excludeEnd("ctx");
+$recv($1)._addElement_($2);
+}
+if(($receiver = oldMethod) == null || $receiver.a$nil){
+oldMethod;
+} else {
+$self._removeProtocolIfEmpty_($recv(oldMethod)._protocol());
+}
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"methodOrganizationEnter:andLeave:",{aMethod:aMethod,oldMethod:oldMethod},$globals.TBehaviorProvider)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aMethod", "oldMethod"],
+source: "methodOrganizationEnter: aMethod andLeave: oldMethod\x0a\x09aMethod ifNotNil: [\x0a\x09\x09self organization addElement: aMethod protocol ].\x0a\x09\x0a\x09oldMethod ifNotNil: [\x0a\x09\x09self removeProtocolIfEmpty: oldMethod protocol ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["ifNotNil:", "addElement:", "organization", "protocol", "removeProtocolIfEmpty:"]
+}),
+$globals.TBehaviorProvider);
+
 $core.addMethod(
 $core.method({
 selector: "methodTemplate",
@@ -3283,6 +3322,43 @@ messageSends: ["basicAt:put:", "announce:", "current", "theClass:", "new", "your
 }),
 $globals.TMasterBehavior);
 
+$core.addMethod(
+$core.method({
+selector: "definedMethods",
+protocol: "accessing",
+fn: function (){
+var self=this,$self=this;
+var methods;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$receiver;
+methods=$self._methods();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["methods"]=1;
+//>>excludeEnd("ctx");
+$1=$self._theMetaClass();
+if(($receiver = $1) == null || $receiver.a$nil){
+return methods;
+} else {
+var meta;
+meta=$receiver;
+return $recv(methods).__comma($recv(meta)._methods());
+}
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"definedMethods",{methods:methods},$globals.TMasterBehavior)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "definedMethods\x0a\x09\x22Answers methods of me and derived 'meta' part if present\x22\x0a\x09| methods |\x0a\x09methods := self methods.\x0a\x09self theMetaClass\x0a\x09\x09ifNil: [ ^ methods ]\x0a\x09\x09ifNotNil: [ :meta | ^ methods, meta methods ]",
+referencedClasses: [],
+//>>excludeEnd("ide");
+messageSends: ["methods", "ifNil:ifNotNil:", "theMetaClass", ","]
+}),
+$globals.TMasterBehavior);
+
 $core.addMethod(
 $core.method({
 selector: "enterOrganization",

+ 17 - 0
src/Kernel-Classes.st

@@ -628,6 +628,14 @@ methodDictionary
 	return dict'>
 !
 
+methodOrganizationEnter: aMethod andLeave: oldMethod
+	aMethod ifNotNil: [
+		self organization addElement: aMethod protocol ].
+	
+	oldMethod ifNotNil: [
+		self removeProtocolIfEmpty: oldMethod protocol ]
+!
+
 methodTemplate
 	^ String streamContents: [ :stream | stream 
 		write: 'messageSelectorAndArgumentNames'; lf;
@@ -835,6 +843,15 @@ comment: aString
 			yourself)
 !
 
+definedMethods
+	"Answers methods of me and derived 'meta' part if present"
+	| methods |
+	methods := self methods.
+	self theMetaClass
+		ifNil: [ ^ methods ]
+		ifNotNil: [ :meta | ^ methods, meta methods ]
+!
+
 enterOrganization
 	Smalltalk ifNotNil: [
 		self package isString ifTrue: [ self basicAt: 'pkg' put: (Package named: self package) ].

+ 46 - 2
src/Kernel-Infrastructure.js

@@ -77,6 +77,49 @@ messageSends: ["do:", "classes", "enterOrganization"]
 }),
 $globals.AmberBootstrapInitialization.a$cls);
 
+$core.addMethod(
+$core.method({
+selector: "organizeMethods",
+protocol: "organization",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+$recv($recv($globals.Smalltalk)._classes())._do_((function(eachClass){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv($recv(eachClass)._definedMethods())._do_((function(eachMethod){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx3) {
+//>>excludeEnd("ctx");
+return $recv($recv(eachMethod)._methodClass())._methodOrganizationEnter_andLeave_(eachMethod,nil);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx3) {$ctx3.fillBlock({eachMethod:eachMethod},$ctx2,2)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({eachClass:eachClass},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["do:"]=1;
+//>>excludeEnd("ctx");
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"organizeMethods",{},$globals.AmberBootstrapInitialization.a$cls)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "organizeMethods\x0a\x09Smalltalk classes do: [ :eachClass |\x0a\x09\x09eachClass definedMethods do: [ :eachMethod |\x0a\x09\x09\x09eachMethod methodClass methodOrganizationEnter: eachMethod andLeave: nil ] ]",
+referencedClasses: ["Smalltalk"],
+//>>excludeEnd("ide");
+messageSends: ["do:", "classes", "definedMethods", "methodOrganizationEnter:andLeave:", "methodClass"]
+}),
+$globals.AmberBootstrapInitialization.a$cls);
+
 $core.addMethod(
 $core.method({
 selector: "run",
@@ -89,6 +132,7 @@ return $core.withContext(function($ctx1) {
 $recv($globals.SmalltalkImage)._initialize();
 $recv($globals.Smalltalk)._adoptPackageDictionary();
 $self._organizeClasses();
+$self._organizeMethods();
 $self._initializeClasses();
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -97,10 +141,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "run\x0a\x09SmalltalkImage initialize.\x0a\x09Smalltalk adoptPackageDictionary.\x0a\x09self\x0a\x09\x09organizeClasses;\x0a\x09\x09initializeClasses",
+source: "run\x0a\x09SmalltalkImage initialize.\x0a\x09Smalltalk adoptPackageDictionary.\x0a\x09self\x0a\x09\x09organizeClasses;\x0a\x09\x09organizeMethods;\x0a\x09\x09initializeClasses",
 referencedClasses: ["SmalltalkImage", "Smalltalk"],
 //>>excludeEnd("ide");
-messageSends: ["initialize", "adoptPackageDictionary", "organizeClasses", "initializeClasses"]
+messageSends: ["initialize", "adoptPackageDictionary", "organizeClasses", "organizeMethods", "initializeClasses"]
 }),
 $globals.AmberBootstrapInitialization.a$cls);
 

+ 7 - 0
src/Kernel-Infrastructure.st

@@ -14,6 +14,12 @@ initializeClasses
 
 organizeClasses
 	Smalltalk classes do: [ :each | each enterOrganization ]
+!
+
+organizeMethods
+	Smalltalk classes do: [ :eachClass |
+		eachClass definedMethods do: [ :eachMethod |
+			eachMethod methodClass methodOrganizationEnter: eachMethod andLeave: nil ] ]
 ! !
 
 !AmberBootstrapInitialization class methodsFor: 'public api'!
@@ -23,6 +29,7 @@ run
 	Smalltalk adoptPackageDictionary.
 	self
 		organizeClasses;
+		organizeMethods;
 		initializeClasses
 ! !
 

+ 8 - 26
support/kernel-fundamentals.js

@@ -108,10 +108,6 @@ define(['./compatibility' /* TODO remove */], function () {
             traitOrBehavior.organization = new SmalltalkClassOrganizer();
             traitOrBehavior.organization.theClass = traitOrBehavior;
         };
-
-        this.addOrganizationElement = function (owner, element) {
-            addElement(owner.organization.elements, element);
-        };
     }
 
     SelectorsBrik.deps = ["selectorConversion"];
@@ -269,7 +265,6 @@ define(['./compatibility' /* TODO remove */], function () {
     BehaviorProvidersBrik.deps = ["organize"];
     function BehaviorProvidersBrik (brikz, st) {
         var setupClassOrganization = brikz.organize.setupClassOrganization;
-        var addOrganizationElement = brikz.organize.addOrganizationElement;
 
         this.setupMethods = function (traitOrBehavior) {
             setupClassOrganization(traitOrBehavior);
@@ -277,25 +272,6 @@ define(['./compatibility' /* TODO remove */], function () {
             traitOrBehavior.methods = Object.create(null);
         };
 
-        function addMethod (method, traitOrBehavior) {
-            traitOrBehavior.methods[method.selector] = method;
-
-            // During the bootstrap, #addCompiledMethod is not used.
-            // Therefore we populate the organizer here too
-            addOrganizationElement(traitOrBehavior, method.protocol);
-
-            traitOrBehavior.methodAdded(method);
-        }
-
-        function removeMethod (method, traitOrBehavior) {
-            delete traitOrBehavior.methods[method.selector];
-
-            traitOrBehavior.methodRemoved(method);
-
-            // Do *not* delete protocols from here.
-            // This is handled by #removeCompiledMethod
-        }
-
         function updateMethod (selector, traitOrBehavior) {
             var oldMethod = traitOrBehavior.methods[selector],
                 newMethod = traitOrBehavior.localMethods[selector];
@@ -304,8 +280,14 @@ define(['./compatibility' /* TODO remove */], function () {
                 return;
             }
             if (newMethod === oldMethod) return;
-            if (newMethod != null) addMethod(newMethod, traitOrBehavior);
-            else removeMethod(oldMethod, traitOrBehavior);
+            if (newMethod != null) {
+                traitOrBehavior.methods[selector] = newMethod;
+                traitOrBehavior.methodAdded(newMethod);
+            } else {
+                delete traitOrBehavior.methods[selector];
+                traitOrBehavior.methodRemoved(oldMethod);
+            }
+            if (st._methodReplaced) st._methodReplaced(newMethod, oldMethod, traitOrBehavior);
         }
 
         this.updateMethod = updateMethod;

+ 4 - 0
support/kernel-runtime.js

@@ -191,6 +191,10 @@ define(function () {
             propagateMethodChange(klass, method, null);
         };
 
+        st._methodReplaced = function (newMethod, oldMethod, klass) {
+            klass._methodOrganizationEnter_andLeave_(newMethod, oldMethod);
+        };
+
         function propagateMethodChange (klass, method, exclude) {
             var selector = method.selector;
             var jsSelector = method.jsSelector;