Browse Source

TMasterBehavior >> {enter,leave}Organization.

Herbert Vojčík 7 years ago
parent
commit
4c8794c1e8

+ 3 - 0
API-CHANGES.txt

@@ -19,6 +19,9 @@
   + signalOn:
 + SmalltalkImage >>
   + packageDictionary
++ TMasterBehavior >>
+  + enterOrganization
+  + leaveOrganization
 + UndefinedObject >>
   + ==
 

+ 2 - 0
CHANGELOG

@@ -9,6 +9,8 @@
   * ErrorHandler class >> handleError:
   * JSObjectProxy class >> on:
   * NonBooleanReceiver class >> signalOn:
+  * TMasterBehavior >> enterOrganization
+  * TMasterBehavior >> leaveOrganization
 
 Commits: https://lolg.it/amber/amber/commits/0.19.1.
 

+ 69 - 15
src/Kernel-Classes.js

@@ -3252,6 +3252,64 @@ messageSends: ["basicAt:put:", "announce:", "current", "theClass:", "new", "your
 }),
 $globals.TMasterBehavior);
 
+$core.addMethod(
+$core.method({
+selector: "enterOrganization",
+protocol: "accessing",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $receiver;
+if(($receiver = $globals.Smalltalk) == null || $receiver.a$nil){
+$globals.Smalltalk;
+} else {
+$recv($recv($self._package())._organization())._addElement_(self);
+}
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"enterOrganization",{},$globals.TMasterBehavior)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "enterOrganization\x0a\x09Smalltalk ifNotNil: [\x0a\x09\x09self package organization addElement: self ]",
+referencedClasses: ["Smalltalk"],
+//>>excludeEnd("ide");
+messageSends: ["ifNotNil:", "addElement:", "organization", "package"]
+}),
+$globals.TMasterBehavior);
+
+$core.addMethod(
+$core.method({
+selector: "leaveOrganization",
+protocol: "accessing",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $receiver;
+if(($receiver = $globals.Smalltalk) == null || $receiver.a$nil){
+$globals.Smalltalk;
+} else {
+$recv($recv($self._package())._organization())._removeElement_(self);
+}
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"leaveOrganization",{},$globals.TMasterBehavior)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "leaveOrganization\x0a\x09Smalltalk ifNotNil: [\x0a\x09\x09self package organization removeElement: self ]",
+referencedClasses: ["Smalltalk"],
+//>>excludeEnd("ide");
+messageSends: ["ifNotNil:", "removeElement:", "organization", "package"]
+}),
+$globals.TMasterBehavior);
+
 $core.addMethod(
 $core.method({
 selector: "name",
@@ -3309,7 +3367,7 @@ var oldPackage;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-var $2,$1,$3,$4,$6,$5;
+var $2,$1,$3,$5,$4;
 $2=$self._package();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["package"]=1;
@@ -3319,19 +3377,15 @@ if($core.assert($1)){
 return self;
 }
 oldPackage=$self._package();
+$self._leaveOrganization();
 $self._basicAt_put_("pkg",aPackage);
-$3=$recv(oldPackage)._organization();
-//>>excludeStart("ctx", pragmas.excludeDebugContexts);
-$ctx1.sendIdx["organization"]=1;
-//>>excludeEnd("ctx");
-$recv($3)._removeElement_(self);
-$recv($recv(aPackage)._organization())._addElement_(self);
-$4=$recv($globals.SystemAnnouncer)._current();
-$6=$recv($globals.ClassMoved)._new();
-$recv($6)._theClass_(self);
-$recv($6)._oldPackage_(oldPackage);
-$5=$recv($6)._yourself();
-$recv($4)._announce_($5);
+$self._enterOrganization();
+$3=$recv($globals.SystemAnnouncer)._current();
+$5=$recv($globals.ClassMoved)._new();
+$recv($5)._theClass_(self);
+$recv($5)._oldPackage_(oldPackage);
+$4=$recv($5)._yourself();
+$recv($3)._announce_($4);
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 }, function($ctx1) {$ctx1.fill(self,"package:",{aPackage:aPackage,oldPackage:oldPackage},$globals.TMasterBehavior)});
@@ -3339,10 +3393,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aPackage"],
-source: "package: aPackage\x0a\x09| oldPackage |\x0a\x09\x0a\x09self package = aPackage ifTrue: [ ^ self ].\x0a\x09\x0a\x09oldPackage := self package.\x0a\x09\x0a\x09self basicAt: 'pkg' put: aPackage.\x0a\x09oldPackage organization removeElement: self.\x0a\x09aPackage organization addElement: self.\x0a\x0a\x09SystemAnnouncer current announce: (ClassMoved new\x0a\x09\x09theClass: self;\x0a\x09\x09oldPackage: oldPackage;\x0a\x09\x09yourself)",
+source: "package: aPackage\x0a\x09| oldPackage |\x0a\x09\x0a\x09self package = aPackage ifTrue: [ ^ self ].\x0a\x09\x0a\x09oldPackage := self package.\x0a\x09\x0a\x09self\x0a\x09\x09leaveOrganization;\x0a\x09\x09basicAt: 'pkg' put: aPackage;\x0a\x09\x09enterOrganization.\x0a\x0a\x09SystemAnnouncer current announce: (ClassMoved new\x0a\x09\x09theClass: self;\x0a\x09\x09oldPackage: oldPackage;\x0a\x09\x09yourself)",
 referencedClasses: ["SystemAnnouncer", "ClassMoved"],
 //>>excludeEnd("ide");
-messageSends: ["ifTrue:", "=", "package", "basicAt:put:", "removeElement:", "organization", "addElement:", "announce:", "current", "theClass:", "new", "oldPackage:", "yourself"]
+messageSends: ["ifTrue:", "=", "package", "leaveOrganization", "basicAt:put:", "enterOrganization", "announce:", "current", "theClass:", "new", "oldPackage:", "yourself"]
 }),
 $globals.TMasterBehavior);
 

+ 14 - 3
src/Kernel-Classes.st

@@ -829,6 +829,16 @@ comment: aString
 			yourself)
 !
 
+enterOrganization
+	Smalltalk ifNotNil: [
+		self package organization addElement: self ]
+!
+
+leaveOrganization
+	Smalltalk ifNotNil: [
+		self package organization removeElement: self ]
+!
+
 name
 	<inlineJS: 'return self.className'>
 !
@@ -844,9 +854,10 @@ package: aPackage
 	
 	oldPackage := self package.
 	
-	self basicAt: 'pkg' put: aPackage.
-	oldPackage organization removeElement: self.
-	aPackage organization addElement: self.
+	self
+		leaveOrganization;
+		basicAt: 'pkg' put: aPackage;
+		enterOrganization.
 
 	SystemAnnouncer current announce: (ClassMoved new
 		theClass: self;

+ 35 - 2
src/Kernel-Infrastructure.js

@@ -45,6 +45,38 @@ messageSends: ["do:", "classes", "ifFalse:", "=", "initialize"]
 }),
 $globals.AmberBootstrapInitialization.a$cls);
 
+$core.addMethod(
+$core.method({
+selector: "organizeClasses",
+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(each){
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx2) {
+//>>excludeEnd("ctx");
+return $recv(each)._enterOrganization();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)});
+//>>excludeEnd("ctx");
+}));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"organizeClasses",{},$globals.AmberBootstrapInitialization.a$cls)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "organizeClasses\x0a\x09Smalltalk classes do: [ :each | each enterOrganization ]",
+referencedClasses: ["Smalltalk"],
+//>>excludeEnd("ide");
+messageSends: ["do:", "classes", "enterOrganization"]
+}),
+$globals.AmberBootstrapInitialization.a$cls);
+
 $core.addMethod(
 $core.method({
 selector: "run",
@@ -56,6 +88,7 @@ return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
 $recv($globals.SmalltalkImage)._initialize();
 $recv($globals.Smalltalk)._adoptPackageDictionary();
+$self._organizeClasses();
 $self._initializeClasses();
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -64,10 +97,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "run\x0a\x09SmalltalkImage initialize.\x0a\x09Smalltalk adoptPackageDictionary.\x0a\x09self initializeClasses",
+source: "run\x0a\x09SmalltalkImage initialize.\x0a\x09Smalltalk adoptPackageDictionary.\x0a\x09self\x0a\x09\x09organizeClasses;\x0a\x09\x09initializeClasses",
 referencedClasses: ["SmalltalkImage", "Smalltalk"],
 //>>excludeEnd("ide");
-messageSends: ["initialize", "adoptPackageDictionary", "initializeClasses"]
+messageSends: ["initialize", "adoptPackageDictionary", "organizeClasses", "initializeClasses"]
 }),
 $globals.AmberBootstrapInitialization.a$cls);
 

+ 9 - 1
src/Kernel-Infrastructure.st

@@ -10,12 +10,20 @@ initializeClasses
 		each = SmalltalkImage ifFalse: [ each initialize ] ]
 ! !
 
+!AmberBootstrapInitialization class methodsFor: 'organization'!
+
+organizeClasses
+	Smalltalk classes do: [ :each | each enterOrganization ]
+! !
+
 !AmberBootstrapInitialization class methodsFor: 'public api'!
 
 run
 	SmalltalkImage initialize.
 	Smalltalk adoptPackageDictionary.
-	self initializeClasses
+	self
+		organizeClasses;
+		initializeClasses
 ! !
 
 ProtoObject subclass: #JSObjectProxy

+ 133 - 16
src/Kernel-Tests.js

@@ -1937,6 +1937,7 @@ if(($receiver = $1) == null || $receiver.a$nil){
 $1;
 } else {
 $recv($globals.Smalltalk)._removeClass_($self["@theClass"]);
+$self._deny_($recv($recv($recv($self["@theClass"])._package())._classes())._includes_($self["@theClass"]));
 $self["@theClass"]=nil;
 $self["@theClass"];
 }
@@ -1947,10 +1948,54 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "tearDown\x0a\x09theClass ifNotNil: [ Smalltalk removeClass: theClass. theClass := nil ]",
+source: "tearDown\x0a\x09theClass ifNotNil: [\x0a\x09\x09Smalltalk removeClass: theClass.\x0a\x09\x09self deny: (theClass package classes includes: theClass).\x0a\x09\x09theClass := nil ]",
 referencedClasses: ["Smalltalk"],
 //>>excludeEnd("ide");
-messageSends: ["ifNotNil:", "removeClass:"]
+messageSends: ["ifNotNil:", "removeClass:", "deny:", "includes:", "classes", "package"]
+}),
+$globals.ClassBuilderTest);
+
+$core.addMethod(
+$core.method({
+selector: "testAddTrait",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $3,$2,$1,$4;
+$self["@theClass"]=$recv($self["@builder"])._addTraitNamed_package_("ObjectMock2","Kernel-Tests");
+$self._assert_equals_($recv($self["@theClass"])._name(),"ObjectMock2");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=1;
+//>>excludeEnd("ctx");
+$3=$recv($self["@theClass"])._package();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["package"]=1;
+//>>excludeEnd("ctx");
+$2=$recv($3)._classes();
+$1=$recv($2)._occurrencesOf_($self["@theClass"]);
+$self._assert_equals_($1,(1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=2;
+//>>excludeEnd("ctx");
+$4=$recv($self["@theClass"])._package();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["package"]=2;
+//>>excludeEnd("ctx");
+$self._assert_equals_($4,$recv($globals.ObjectMock)._package());
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testAddTrait",{},$globals.ClassBuilderTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testAddTrait\x0a\x09theClass := builder addTraitNamed: 'ObjectMock2' package: 'Kernel-Tests'.\x0a\x09self assert: theClass name equals: 'ObjectMock2'.\x0a\x09self assert: (theClass package classes occurrencesOf: theClass) equals: 1.\x0a\x09self assert: theClass package equals: ObjectMock package",
+referencedClasses: ["ObjectMock"],
+//>>excludeEnd("ide");
+messageSends: ["addTraitNamed:package:", "assert:equals:", "name", "occurrencesOf:", "classes", "package"]
 }),
 $globals.ClassBuilderTest);
 
@@ -1963,7 +2008,7 @@ var self=this,$self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-var $2,$1,$4,$3,$6,$5,$8,$7;
+var $2,$1,$4,$3,$6,$7,$5,$9,$8;
 $self["@theClass"]=$recv($self["@builder"])._copyClass_named_($globals.ObjectMock,"ObjectMock2");
 $2=$recv($self["@theClass"])._superclass();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -1997,17 +2042,25 @@ $6=$recv($self["@theClass"])._package();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["package"]=1;
 //>>excludeEnd("ctx");
-$5=$recv($6).__eq_eq($recv($globals.ObjectMock)._package());
+$7=$recv($globals.ObjectMock)._package();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["package"]=2;
+//>>excludeEnd("ctx");
+$5=$recv($6).__eq_eq($7);
 $self._assert_($5);
-$8=$recv($self["@theClass"])._methodDictionary();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:"]=3;
+//>>excludeEnd("ctx");
+$self._assert_($recv($recv($recv($self["@theClass"])._package())._classes())._includes_($self["@theClass"]));
+$9=$recv($self["@theClass"])._methodDictionary();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["methodDictionary"]=1;
 //>>excludeEnd("ctx");
-$7=$recv($8)._keys();
+$8=$recv($9)._keys();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["keys"]=1;
 //>>excludeEnd("ctx");
-$self._assert_equals_($7,$recv($recv($globals.ObjectMock)._methodDictionary())._keys());
+$self._assert_equals_($8,$recv($recv($globals.ObjectMock)._methodDictionary())._keys());
 return self;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 }, function($ctx1) {$ctx1.fill(self,"testClassCopy",{},$globals.ClassBuilderTest)});
@@ -2015,10 +2068,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "testClassCopy\x0a\x09theClass := builder copyClass: ObjectMock named: 'ObjectMock2'.\x0a\x09self assert: theClass superclass == ObjectMock superclass.\x0a\x09self assert: theClass instanceVariableNames == ObjectMock instanceVariableNames.\x0a\x09self assert: theClass name equals: 'ObjectMock2'.\x0a\x09self assert: theClass package == ObjectMock package.\x0a\x09self assert: theClass methodDictionary keys equals: ObjectMock methodDictionary keys",
+source: "testClassCopy\x0a\x09theClass := builder copyClass: ObjectMock named: 'ObjectMock2'.\x0a\x09self assert: theClass superclass == ObjectMock superclass.\x0a\x09self assert: theClass instanceVariableNames == ObjectMock instanceVariableNames.\x0a\x09self assert: theClass name equals: 'ObjectMock2'.\x0a\x09self assert: theClass package == ObjectMock package.\x0a\x09self assert: (theClass package classes includes: theClass).\x0a\x09self assert: theClass methodDictionary keys equals: ObjectMock methodDictionary keys",
 referencedClasses: ["ObjectMock"],
 //>>excludeEnd("ide");
-messageSends: ["copyClass:named:", "assert:", "==", "superclass", "instanceVariableNames", "assert:equals:", "name", "package", "keys", "methodDictionary"]
+messageSends: ["copyClass:named:", "assert:", "==", "superclass", "instanceVariableNames", "assert:equals:", "name", "package", "includes:", "classes", "keys", "methodDictionary"]
 }),
 $globals.ClassBuilderTest);
 
@@ -2032,7 +2085,7 @@ var instance,oldClass;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
-var $2,$1,$4,$3,$5,$6,$7,$8,$9,$11,$10;
+var $2,$1,$4,$3,$5,$6,$7,$8,$10,$9,$12,$11;
 oldClass=$recv($self["@builder"])._copyClass_named_($globals.ObjectMock,"ObjectMock2");
 $2=$recv($globals.Smalltalk)._globals();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -2088,17 +2141,25 @@ $self._assert_equals_($8,$recv(oldClass)._comment());
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["assert:equals:"]=2;
 //>>excludeEnd("ctx");
-$9=$recv($recv($globals.ObjectMock2)._package())._name();
+$10=$recv($globals.ObjectMock2)._package();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["package"]=1;
+//>>excludeEnd("ctx");
+$9=$recv($10)._name();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["name"]=1;
 //>>excludeEnd("ctx");
 $self._assert_equals_($9,"Kernel-Tests");
-$11=$recv(instance)._class();
+$self._assert_($recv($recv($recv($globals.ObjectMock2)._package())._classes())._includes_($globals.ObjectMock2));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:"]=3;
+//>>excludeEnd("ctx");
+$12=$recv(instance)._class();
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 $ctx1.sendIdx["class"]=1;
 //>>excludeEnd("ctx");
-$10=$recv($11).__eq_eq($globals.ObjectMock2);
-$self._deny_($10);
+$11=$recv($12).__eq_eq($globals.ObjectMock2);
+$self._deny_($11);
 $self._assert_($recv($recv($recv($globals.Smalltalk)._globals())._at_($recv($recv(instance)._class())._name()))._isNil());
 $recv($globals.Smalltalk)._removeClass_($globals.ObjectMock2);
 return self;
@@ -2108,10 +2169,10 @@ return self;
 },
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "testClassMigration\x0a\x09| instance oldClass |\x0a\x09\x0a\x09oldClass := builder copyClass: ObjectMock named: 'ObjectMock2'.\x0a\x09instance := (Smalltalk globals at: 'ObjectMock2') new.\x0a\x09\x0a\x09\x22Change the superclass of ObjectMock2\x22\x0a\x09ObjectMock subclass: (Smalltalk globals at: 'ObjectMock2')\x0a\x09\x09instanceVariableNames: ''\x0a\x09\x09package: 'Kernel-Tests'.\x0a\x09\x0a\x09self deny: oldClass == ObjectMock2.\x0a\x09\x0a\x09self assert: ObjectMock2 superclass == ObjectMock.\x0a\x09self assert: ObjectMock2 instanceVariableNames isEmpty.\x0a\x09self assert: ObjectMock2 selectors equals: oldClass selectors.\x0a\x09self assert: ObjectMock2 comment equals: oldClass comment.\x0a\x09self assert: ObjectMock2 package name equals: 'Kernel-Tests'.\x0a\x09\x0a\x09self deny: instance class == ObjectMock2.\x0a\x09\x22Commeting this out. Tests implementation detail.\x22\x0a\x09\x22self assert: instance class name equals: 'OldObjectMock2'.\x22\x0a\x09\x0a\x09self assert: (Smalltalk globals at: instance class name) isNil.\x0a\x09\x0a\x09Smalltalk removeClass: ObjectMock2",
+source: "testClassMigration\x0a\x09| instance oldClass |\x0a\x09\x0a\x09oldClass := builder copyClass: ObjectMock named: 'ObjectMock2'.\x0a\x09instance := (Smalltalk globals at: 'ObjectMock2') new.\x0a\x09\x0a\x09\x22Change the superclass of ObjectMock2\x22\x0a\x09ObjectMock subclass: (Smalltalk globals at: 'ObjectMock2')\x0a\x09\x09instanceVariableNames: ''\x0a\x09\x09package: 'Kernel-Tests'.\x0a\x09\x0a\x09self deny: oldClass == ObjectMock2.\x0a\x09\x0a\x09self assert: ObjectMock2 superclass == ObjectMock.\x0a\x09self assert: ObjectMock2 instanceVariableNames isEmpty.\x0a\x09self assert: ObjectMock2 selectors equals: oldClass selectors.\x0a\x09self assert: ObjectMock2 comment equals: oldClass comment.\x0a\x09self assert: ObjectMock2 package name equals: 'Kernel-Tests'.\x0a\x09self assert: (ObjectMock2 package classes includes: ObjectMock2).\x0a\x09\x0a\x09self deny: instance class == ObjectMock2.\x0a\x09\x22Commeting this out. Tests implementation detail.\x22\x0a\x09\x22self assert: instance class name equals: 'OldObjectMock2'.\x22\x0a\x09\x0a\x09self assert: (Smalltalk globals at: instance class name) isNil.\x0a\x09\x0a\x09Smalltalk removeClass: ObjectMock2",
 referencedClasses: ["ObjectMock", "Smalltalk", "ObjectMock2"],
 //>>excludeEnd("ide");
-messageSends: ["copyClass:named:", "new", "at:", "globals", "subclass:instanceVariableNames:package:", "deny:", "==", "assert:", "superclass", "isEmpty", "instanceVariableNames", "assert:equals:", "selectors", "comment", "name", "package", "class", "isNil", "removeClass:"]
+messageSends: ["copyClass:named:", "new", "at:", "globals", "subclass:instanceVariableNames:package:", "deny:", "==", "assert:", "superclass", "isEmpty", "instanceVariableNames", "assert:equals:", "selectors", "comment", "name", "package", "includes:", "classes", "class", "isNil", "removeClass:"]
 }),
 $globals.ClassBuilderTest);
 
@@ -2240,6 +2301,62 @@ messageSends: ["assert:equals:", "instanceVariableNamesFor:"]
 }),
 $globals.ClassBuilderTest);
 
+$core.addMethod(
+$core.method({
+selector: "testSubclass",
+protocol: "tests",
+fn: function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $3,$2,$1,$4;
+$self["@theClass"]=$recv($self["@builder"])._addSubclassOf_named_instanceVariableNames_package_($globals.ObjectMock,"ObjectMock2","foo bar","Kernel-Tests");
+$self._assert_equals_($recv($self["@theClass"])._superclass(),$globals.ObjectMock);
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=1;
+//>>excludeEnd("ctx");
+$self._assert_equals_($recv($self["@theClass"])._instanceVariableNames(),"foo bar");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=2;
+//>>excludeEnd("ctx");
+$self._assert_equals_($recv($self["@theClass"])._name(),"ObjectMock2");
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=3;
+//>>excludeEnd("ctx");
+$3=$recv($self["@theClass"])._package();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["package"]=1;
+//>>excludeEnd("ctx");
+$2=$recv($3)._classes();
+$1=$recv($2)._occurrencesOf_($self["@theClass"]);
+$self._assert_equals_($1,(1));
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=4;
+//>>excludeEnd("ctx");
+$4=$recv($self["@theClass"])._package();
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["package"]=2;
+//>>excludeEnd("ctx");
+$self._assert_equals_($4,$recv($globals.ObjectMock)._package());
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+$ctx1.sendIdx["assert:equals:"]=5;
+//>>excludeEnd("ctx");
+$self._assert_equals_($recv($recv($recv($self["@theClass"])._methodDictionary())._keys())._size(),(0));
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"testSubclass",{},$globals.ClassBuilderTest)});
+//>>excludeEnd("ctx");
+},
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "testSubclass\x0a\x09theClass := builder addSubclassOf: ObjectMock named: 'ObjectMock2' instanceVariableNames: 'foo bar' package: 'Kernel-Tests'.\x0a\x09self assert: theClass superclass equals: ObjectMock.\x0a\x09self assert: theClass instanceVariableNames equals: 'foo bar'.\x0a\x09self assert: theClass name equals: 'ObjectMock2'.\x0a\x09self assert: (theClass package classes occurrencesOf: theClass) equals: 1.\x0a\x09self assert: theClass package equals: ObjectMock package.\x0a\x09self assert: theClass methodDictionary keys size equals: 0",
+referencedClasses: ["ObjectMock"],
+//>>excludeEnd("ide");
+messageSends: ["addSubclassOf:named:instanceVariableNames:package:", "assert:equals:", "superclass", "instanceVariableNames", "name", "occurrencesOf:", "classes", "package", "size", "keys", "methodDictionary"]
+}),
+$globals.ClassBuilderTest);
+
 
 
 $core.addClass("ClassTest", $globals.TestCase, ["builder", "theClass"], "Kernel-Tests");

+ 23 - 1
src/Kernel-Tests.st

@@ -348,17 +348,28 @@ setUp
 !
 
 tearDown
-	theClass ifNotNil: [ Smalltalk removeClass: theClass. theClass := nil ]
+	theClass ifNotNil: [
+		Smalltalk removeClass: theClass.
+		self deny: (theClass package classes includes: theClass).
+		theClass := nil ]
 ! !
 
 !ClassBuilderTest methodsFor: 'tests'!
 
+testAddTrait
+	theClass := builder addTraitNamed: 'ObjectMock2' package: 'Kernel-Tests'.
+	self assert: theClass name equals: 'ObjectMock2'.
+	self assert: (theClass package classes occurrencesOf: theClass) equals: 1.
+	self assert: theClass package equals: ObjectMock package
+!
+
 testClassCopy
 	theClass := builder copyClass: ObjectMock named: 'ObjectMock2'.
 	self assert: theClass superclass == ObjectMock superclass.
 	self assert: theClass instanceVariableNames == ObjectMock instanceVariableNames.
 	self assert: theClass name equals: 'ObjectMock2'.
 	self assert: theClass package == ObjectMock package.
+	self assert: (theClass package classes includes: theClass).
 	self assert: theClass methodDictionary keys equals: ObjectMock methodDictionary keys
 !
 
@@ -380,6 +391,7 @@ testClassMigration
 	self assert: ObjectMock2 selectors equals: oldClass selectors.
 	self assert: ObjectMock2 comment equals: oldClass comment.
 	self assert: ObjectMock2 package name equals: 'Kernel-Tests'.
+	self assert: (ObjectMock2 package classes includes: ObjectMock2).
 	
 	self deny: instance class == ObjectMock2.
 	"Commeting this out. Tests implementation detail."
@@ -425,6 +437,16 @@ testClassMigrationWithSubclasses
 
 testInstanceVariableNames
 	self assert: (builder instanceVariableNamesFor: '  hello   world   ') equals: #('hello' 'world')
+!
+
+testSubclass
+	theClass := builder addSubclassOf: ObjectMock named: 'ObjectMock2' instanceVariableNames: 'foo bar' package: 'Kernel-Tests'.
+	self assert: theClass superclass equals: ObjectMock.
+	self assert: theClass instanceVariableNames equals: 'foo bar'.
+	self assert: theClass name equals: 'ObjectMock2'.
+	self assert: (theClass package classes occurrencesOf: theClass) equals: 1.
+	self assert: theClass package equals: ObjectMock package.
+	self assert: theClass methodDictionary keys size equals: 0
 ! !
 
 TestCase subclass: #ClassTest

+ 1 - 10
support/kernel-fundamentals.js

@@ -91,7 +91,6 @@ define(['./compatibility' /* TODO remove */], function () {
         var SmalltalkObject = brikz.root.Object;
         var coreFns = brikz.root.coreFns;
         var addElement = brikz.arraySet.addElement;
-        var removeElement = brikz.arraySet.removeElement;
 
         function SmalltalkOrganizer () {
         }
@@ -120,10 +119,6 @@ define(['./compatibility' /* TODO remove */], function () {
         this.addOrganizationElement = function (owner, element) {
             addElement(owner.organization.elements, element);
         };
-
-        this.removeOrganizationElement = function (owner, element) {
-            removeElement(owner.organization.elements, element);
-        };
     }
 
     SelectorsBrik.deps = ["selectorConversion"];
@@ -190,10 +185,8 @@ define(['./compatibility' /* TODO remove */], function () {
         };
     }
 
-    BehaviorsBrik.deps = ["organize", "root", "smalltalkGlobals", "arraySet"];
+    BehaviorsBrik.deps = ["root", "smalltalkGlobals", "arraySet"];
     function BehaviorsBrik (brikz, st) {
-        var addOrganizationElement = brikz.organize.addOrganizationElement;
-        var removeOrganizationElement = brikz.organize.removeOrganizationElement;
         var globals = brikz.smalltalkGlobals.globals;
         var addElement = brikz.arraySet.addElement;
         var removeElement = brikz.arraySet.removeElement;
@@ -221,13 +214,11 @@ define(['./compatibility' /* TODO remove */], function () {
         function addTraitOrClass (traitOrClass) {
             globals[traitOrClass.className] = traitOrClass;
             addElement(classes, traitOrClass);
-            addOrganizationElement(traitOrClass.pkg, traitOrClass);
             traitOrClass.added();
         }
 
         function removeTraitOrClass (traitOrClass) {
             traitOrClass.removed();
-            removeOrganizationElement(traitOrClass.pkg, traitOrClass);
             removeElement(classes, traitOrClass);
             delete globals[traitOrClass.className];
         }

+ 18 - 3
support/kernel-runtime.js

@@ -92,11 +92,26 @@ define(function () {
             }
         }
 
-        classes().forEach(function (klass) {
-            if (!klass.trait) initClassAndMetaclass(klass);
+        classes().forEach(function (traitOrClass) {
+            if (!traitOrClass.trait) initClassAndMetaclass(traitOrClass);
         });
 
-        st._classAdded = initClassAndMetaclass;
+        st._classAdded = function (klass) {
+            initClassAndMetaclass(klass);
+            klass._enterOrganization();
+        };
+
+        st._traitAdded = function (trait) {
+            trait._enterOrganization();
+        };
+
+        st._classRemoved = function (klass) {
+            klass._leaveOrganization();
+        };
+
+        st._traitRemoved = function (trait) {
+            trait._leaveOrganization();
+        };
 
         function initClass (klass) {
             wireKlass(klass);