1
0
Prechádzať zdrojové kódy

First stab at adding the concept of Module instead of plain class categories.

Göran Krampe 13 rokov pred
rodič
commit
ac9ae60a8c
7 zmenil súbory, kde vykonal 434 pridanie a 132 odobranie
  1. 1 1
      js/Compiler.deploy.js
  2. 4 4
      js/Compiler.js
  3. 123 32
      js/Kernel.deploy.js
  4. 183 60
      js/Kernel.js
  5. 59 14
      js/boot.js
  6. 0 0
      st/Compiler.st
  7. 64 21
      st/Kernel.st

+ 1 - 1
js/Compiler.deploy.js

@@ -1547,7 +1547,7 @@ smalltalk.method({
 selector: 'recompileAll',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_do_", [(function(each){(function($rec){smalltalk.send($rec, "_show_", [each]);return smalltalk.send($rec, "_cr", []);})((smalltalk.Transcript || Transcript));return smalltalk.send((function(){return smalltalk.send(self, "_recompile_", [each]);}), "_valueWithTimeout_", [(1)]);})]);
+smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_do_", [(function(each){(function($rec){smalltalk.send($rec, "_show_", [each]);return smalltalk.send($rec, "_cr", []);})((smalltalk.Transcript || Transcript));return smalltalk.send((function(){return smalltalk.send(self, "_recompile_", [each]);}), "_valueWithTimeout_", [(100)]);})]);
 return self;}
 }),
 smalltalk.Compiler);

+ 4 - 4
js/Compiler.js

@@ -1523,7 +1523,7 @@ return smalltalk.send((smalltalk.SmalltalkParser || SmalltalkParser), "_new", []
 return self;},
 source: unescape('parser%0A%09%5ESmalltalkParser%20new'),
 messageSends: ["new"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: []
 }),
 smalltalk.Compiler);
 
@@ -1939,7 +1939,7 @@ fn: function (aString){
 var self=this;
 return smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_parse_", [aString]);
 return self;},
-source: unescape('parse%3A%20aString%0A%20%20%20%20%5ESmalltalk%20current%20parse%3A%20aString%20'),
+source: unescape('parse%3A%20aString%0A%20%20%20%20%5ESmalltalk%20current%20parse%3A%20aString'),
 messageSends: ["parse:", "current"],
 referencedClasses: [smalltalk.Smalltalk]
 }),
@@ -2044,11 +2044,11 @@ selector: 'recompileAll',
 category: 'compiling',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_do_", [(function(each){(function($rec){smalltalk.send($rec, "_show_", [each]);return smalltalk.send($rec, "_cr", []);})((smalltalk.Transcript || Transcript));return smalltalk.send((function(){return smalltalk.send(self, "_recompile_", [each]);}), "_valueWithTimeout_", [(1)]);})]);
+smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_do_", [(function(each){(function($rec){smalltalk.send($rec, "_show_", [each]);return smalltalk.send($rec, "_cr", []);})((smalltalk.Transcript || Transcript));return smalltalk.send((function(){return smalltalk.send(self, "_recompile_", [each]);}), "_valueWithTimeout_", [(100)]);})]);
 return self;},
 source: unescape('recompileAll%0A%09Smalltalk%20current%20classes%20do%3A%20%5B%3Aeach%20%7C%0A%09%09Transcript%20show%3A%20each%3B%20cr.%0A%09%09%5Bself%20recompile%3A%20each%5D%20valueWithTimeout%3A%20100%5D'),
 messageSends: ["do:", "classes", "current", "show:", "cr", "valueWithTimeout:", "recompile:"],
-referencedClasses: [smalltalk.Smalltalk,smalltalk.nil]
+referencedClasses: [smalltalk.Smalltalk]
 }),
 smalltalk.Compiler);
 

+ 123 - 32
js/Kernel.deploy.js

@@ -647,6 +647,17 @@ return self;}
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+'_modules',
+smalltalk.method({
+selector: 'modules',
+fn: function (){
+var self=this;
+return self.modules.all();
+return self;}
+}),
+smalltalk.Smalltalk);
+
 
 smalltalk.Smalltalk.klass.iVarNames = ['current'];
 smalltalk.addMethod(
@@ -661,6 +672,42 @@ return self;}
 smalltalk.Smalltalk.klass);
 
 
+smalltalk.addClass('Module', smalltalk.Object, [], 'Kernel');
+smalltalk.addMethod(
+'_name',
+smalltalk.method({
+selector: 'name',
+fn: function (){
+var self=this;
+return self.moduleName || nil;
+return self;}
+}),
+smalltalk.Module);
+
+smalltalk.addMethod(
+'_requires',
+smalltalk.method({
+selector: 'requires',
+fn: function (){
+var self=this;
+return self.requires || nil;
+return self;}
+}),
+smalltalk.Module);
+
+smalltalk.addMethod(
+'_name_',
+smalltalk.method({
+selector: 'name:',
+fn: function (aString){
+var self=this;
+return self.moduleName = aString;
+return self;}
+}),
+smalltalk.Module);
+
+
+
 smalltalk.addClass('Behavior', smalltalk.Object, [], 'Kernel');
 smalltalk.addMethod(
 '_new',
@@ -970,18 +1017,7 @@ smalltalk.method({
 selector: 'category',
 fn: function (){
 var self=this;
-return self.category;
-return self;}
-}),
-smalltalk.Class);
-
-smalltalk.addMethod(
-'_category_',
-smalltalk.method({
-selector: 'category:',
-fn: function (aString){
-var self=this;
-self.category = aString;
+return (($receiver = smalltalk.send(self, "_module", [])) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : (function(){return smalltalk.send(smalltalk.send(self, "_module", []), "_name", []);})();
 return self;}
 }),
 smalltalk.Class);
@@ -992,7 +1028,7 @@ smalltalk.method({
 selector: 'subclass:instanceVariableNames:',
 fn: function (aString, anotherString){
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, anotherString, nil]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, anotherString, nil]);
 return self;}
 }),
 smalltalk.Class);
@@ -1003,7 +1039,7 @@ smalltalk.method({
 selector: 'subclass:instanceVariableNames:category:',
 fn: function (aString, aString2, aString3){
 var self=this;
-return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_category_", [self, aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
 return self;}
 }),
 smalltalk.Class);
@@ -1051,7 +1087,40 @@ smalltalk.method({
 selector: 'subclass:instanceVariableNames:classVariableNames:poolDictionaries:category:',
 fn: function (aString, aString2, classVars, pools, aString3){
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
+return self;}
+}),
+smalltalk.Class);
+
+smalltalk.addMethod(
+'_module',
+smalltalk.method({
+selector: 'module',
+fn: function (){
+var self=this;
+return self.module;
+return self;}
+}),
+smalltalk.Class);
+
+smalltalk.addMethod(
+'_module_',
+smalltalk.method({
+selector: 'module:',
+fn: function (aModule){
+var self=this;
+self.module = aModule;
+return self;}
+}),
+smalltalk.Class);
+
+smalltalk.addMethod(
+'_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'subclass:instanceVariableNames:module:',
+fn: function (aString, aString2, aString3){
+var self=this;
+return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_module_", [self, aString, aString2, aString3]);
 return self;}
 }),
 smalltalk.Class);
@@ -2405,7 +2474,7 @@ smalltalk.method({
 selector: 'subclass:instanceVariableNames:',
 fn: function (aString, anotherString){
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, anotherString, nil]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, anotherString, nil]);
 return self;}
 }),
 smalltalk.UndefinedObject);
@@ -2416,7 +2485,7 @@ smalltalk.method({
 selector: 'subclass:instanceVariableNames:category:',
 fn: function (aString, aString2, aString3){
 var self=this;
-return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_category_", [self, aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
 return self;}
 }),
 smalltalk.UndefinedObject);
@@ -2520,6 +2589,17 @@ return self;}
 }),
 smalltalk.UndefinedObject);
 
+smalltalk.addMethod(
+'_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'subclass:instanceVariableNames:module:',
+fn: function (aString, aString2, aString3){
+var self=this;
+return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_module_", [self, aString, aString2, aString3]);
+return self;}
+}),
+smalltalk.UndefinedObject);
+
 
 smalltalk.addMethod(
 '_new',
@@ -4593,21 +4673,7 @@ smalltalk.method({
 selector: 'superclass:subclass:',
 fn: function (aClass, aString){
 var self=this;
-smalltalk.send(self, "_superclass_subclass_instanceVariableNames_category_", [aClass, aString, "", nil]);
-return self;}
-}),
-smalltalk.ClassBuilder);
-
-smalltalk.addMethod(
-'_superclass_subclass_instanceVariableNames_category_',
-smalltalk.method({
-selector: 'superclass:subclass:instanceVariableNames:category:',
-fn: function (aClass, aString, aString2, aString3){
-var self=this;
-var newClass=nil;
-newClass=smalltalk.send(self, "_addSubclassOf_named_instanceVariableNames_", [aClass, aString, smalltalk.send(self, "_instanceVariableNamesFor_", [aString2])]);
-smalltalk.send(self, "_setupClass_", [newClass]);
-smalltalk.send(newClass, "_category_", [(($receiver = aString3) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : $receiver]);
+return smalltalk.send(self, "_superclass_subclass_instanceVariableNames_module_", [aClass, aString, "", nil]);
 return self;}
 }),
 smalltalk.ClassBuilder);
@@ -4659,6 +4725,31 @@ return self;}
 }),
 smalltalk.ClassBuilder);
 
+smalltalk.addMethod(
+'_superclass_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'superclass:subclass:instanceVariableNames:module:',
+fn: function (aClass, aString, aString2, aString3){
+var self=this;
+var newClass=nil;
+newClass=smalltalk.send(self, "_addSubclassOf_named_instanceVariableNames_module_", [aClass, aString, smalltalk.send(self, "_instanceVariableNamesFor_", [aString2]), (($receiver = aString3) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : $receiver]);
+smalltalk.send(self, "_setupClass_", [newClass]);
+return self;}
+}),
+smalltalk.ClassBuilder);
+
+smalltalk.addMethod(
+'_addSubclassOf_named_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'addSubclassOf:named:instanceVariableNames:module:',
+fn: function (aClass, aString, aCollection, moduleName){
+var self=this;
+smalltalk.addClass(aString, aClass, aCollection, moduleName);
+	    return smalltalk[aString];
+return self;}
+}),
+smalltalk.ClassBuilder);
+
 
 
 smalltalk.addClass('ClassCategoryReader', smalltalk.Object, ['class', 'category', 'chunkParser'], 'Kernel');

+ 183 - 60
js/Kernel.js

@@ -354,7 +354,7 @@ fn: function (aBlock, anotherBlock){
 var self=this;
 try{aBlock()} catch(e) {anotherBlock(e)};
 return self;},
-source: unescape('try%3A%20aBlock%20catch%3A%20anotherBlock%0A%09%3Ctry%7BaBlock%28%29%7D%20catch%28e%29%20%7BanotherBlock%28e%29%7D%3E%20'),
+source: unescape('try%3A%20aBlock%20catch%3A%20anotherBlock%0A%09%3Ctry%7BaBlock%28%29%7D%20catch%28e%29%20%7BanotherBlock%28e%29%7D%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -704,7 +704,7 @@ var result=nil;
 smalltalk.send((typeof console == 'undefined' ? nil : console), "_log_", [smalltalk.send(smalltalk.send(aString, "__comma", [" time: "]), "__comma", [smalltalk.send(smalltalk.send((smalltalk.Date || Date), "_millisecondsToRun_", [(function(){return result=smalltalk.send(aBlock, "_value", []);})]), "_printString", [])])]);
 return result;
 return self;},
-source: unescape('log%3A%20aString%20block%3A%20aBlock%0A%0A%09%7C%20result%20%7C%0A%09console%20log%3A%20%20aString%2C%20%20%27%20time%3A%20%27%2C%20%28Date%20millisecondsToRun%3A%20%5Bresult%20%3A%3D%20aBlock%20value%5D%29%20printString.%0A%09%5Eresult%0A%0A'),
+source: unescape('log%3A%20aString%20block%3A%20aBlock%0A%0A%09%7C%20result%20%7C%0A%09console%20log%3A%20%20aString%2C%20%20%27%20time%3A%20%27%2C%20%28Date%20millisecondsToRun%3A%20%5Bresult%20%3A%3D%20aBlock%20value%5D%29%20printString.%0A%09%5Eresult'),
 messageSends: ["log:", unescape("%2C"), "printString", "millisecondsToRun:", "value"],
 referencedClasses: [smalltalk.Date]
 }),
@@ -861,12 +861,27 @@ smalltalk.send(lines, "_at_put_", [row, badLine]);
 code=smalltalk.send((smalltalk.String || String), "_streamContents_", [(function(s){return smalltalk.send(lines, "_withIndexDo_", [(function(l, i){return smalltalk.send(s, "_nextPutAll_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(i, "_asString", []), "__comma", [": "]), "__comma", [l]), "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])])]);})]);})]);
 return smalltalk.send(smalltalk.send((smalltalk.Error || Error), "_new", []), "_messageText_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send("Parse error on line ", "__comma", [row]), "__comma", [" column "]), "__comma", [col]), "__comma", [" : "]), "__comma", [message]), "__comma", [unescape("%20Below%20is%20code%20with%20line%20numbers%20and%20%3D%3D%3D%3E%20marker%20inserted%3A")]), "__comma", [smalltalk.send((smalltalk.String || String), "_lf", [])]), "__comma", [code])]);
 return self;},
-source: unescape('parseError%3A%20anException%20parsing%3A%20aString%0A%09%7C%20row%20col%20message%20lines%20badLine%20code%20%7C%0A%09%3Crow%20%3D%20anException.line%3B%0A%09col%20%3D%20anException.column%3B%0A%09message%20%3D%20anException.message%3B%3E.%0A%09lines%20%3A%3D%20aString%20lines.%0A%09badLine%20%3A%3D%20lines%20at%3A%20row.%0A%09badLine%20%3A%3D%20%28badLine%20copyFrom%3A%201%20to%3A%20col%20-%201%29%2C%20%27%20%3D%3D%3D%3E%27%2C%20%28badLine%20copyFrom%3A%20%20col%20to%3A%20badLine%20size%29.%0A%09lines%20at%3A%20row%20put%3A%20badLine.%0A%09code%20%3A%3D%20String%20streamContents%3A%20%5B%3As%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lines%20withIndexDo%3A%20%5B%3Al%20%3Ai%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20s%20nextPutAll%3A%20i%20asString%2C%20%27%3A%20%27%2C%20l%2C%20String%20lf%5D%5D.%0A%09%5E%20Error%20new%20messageText%3A%20%28%27Parse%20error%20on%20line%20%27%20%2C%20row%20%2C%20%27%20column%20%27%20%2C%20col%20%2C%20%27%20%3A%20%27%20%2C%20message%20%2C%20%27%20Below%20is%20code%20with%20line%20numbers%20and%20%3D%3D%3D%3E%20marker%20inserted%3A%27%20%2C%20String%20lf%2C%20code%29'),
+source: unescape('parseError%3A%20anException%20parsing%3A%20aString%0A%09%7C%20row%20col%20message%20lines%20badLine%20code%20%7C%0A%09%3Crow%20%3D%20anException.line%3B%0A%09col%20%3D%20anException.column%3B%0A%09message%20%3D%20anException.message%3B%3E.%0A%09lines%20%3A%3D%20aString%20lines.%0A%09badLine%20%3A%3D%20lines%20at%3A%20row.%0A%09badLine%20%3A%3D%20%28badLine%20copyFrom%3A%201%20to%3A%20col%20-%201%29%2C%20%27%20%3D%3D%3D%3E%27%2C%20%28badLine%20copyFrom%3A%20%20col%20to%3A%20badLine%20size%29.%0A%09lines%20at%3A%20row%20put%3A%20badLine.%0A%09code%20%3A%3D%20String%20streamContents%3A%20%5B%3As%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20lines%20withIndexDo%3A%20%5B%3Al%20%3Ai%20%7C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20s%20nextPutAll%3A%20i%20asString%2C%20%27%3A%20%27%2C%20l%2C%20String%20lf%5D%5D.%0A%09%5E%20Error%20new%20messageText%3A%20%28%27Parse%20error%20on%20line%20%27%20%2C%20row%20%2C%20%27%20column%20%27%20%2C%20col%20%2C%20%27%20%3A%20%27%20%2C%20message%20%2C%20%27%20Below%20is%20code%20with%20line%20numbers%20and%20%3D%3D%3D%3E%20marker%20inserted%3A%27%20%2C%20String%20lf%2C%20code%29'),
 messageSends: ["lines", "at:", unescape("%2C"), "copyFrom:to:", unescape("-"), "size", "at:put:", "streamContents:", "withIndexDo:", "nextPutAll:", "asString", "lf", "messageText:", "new"],
 referencedClasses: [smalltalk.String,smalltalk.Error]
 }),
 smalltalk.Smalltalk);
 
+smalltalk.addMethod(
+'_modules',
+smalltalk.method({
+selector: 'modules',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.modules.all();
+return self;},
+source: unescape('modules%0A%09%3Creturn%20self.modules.all%28%29%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Smalltalk);
+
 
 smalltalk.Smalltalk.klass.iVarNames = ['current'];
 smalltalk.addMethod(
@@ -885,6 +900,54 @@ referencedClasses: []
 smalltalk.Smalltalk.klass);
 
 
+smalltalk.addClass('Module', smalltalk.Object, [], 'Kernel');
+smalltalk.addMethod(
+'_name',
+smalltalk.method({
+selector: 'name',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.moduleName || nil;
+return self;},
+source: unescape('name%0A%09%3Creturn%20self.moduleName%20%7C%7C%20nil%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Module);
+
+smalltalk.addMethod(
+'_requires',
+smalltalk.method({
+selector: 'requires',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.requires || nil;
+return self;},
+source: unescape('requires%0A%09%3Creturn%20self.requires%20%7C%7C%20nil%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Module);
+
+smalltalk.addMethod(
+'_name_',
+smalltalk.method({
+selector: 'name:',
+category: 'accessing',
+fn: function (aString){
+var self=this;
+return self.moduleName = aString;
+return self;},
+source: unescape('name%3A%20aString%0A%09%3Creturn%20self.moduleName%20%3D%20aString%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Module);
+
+
+
 smalltalk.addClass('Behavior', smalltalk.Object, [], 'Kernel');
 smalltalk.addMethod(
 '_new',
@@ -1281,7 +1344,7 @@ smalltalk.send(self, "_addCompiledMethod_", [method]);
 return self;},
 source: unescape('compile%3A%20aString%20category%3A%20anotherString%0A%09%7C%20method%20%7C%0A%09method%20%3A%3D%20Compiler%20new%20load%3A%20aString%20forClass%3A%20self.%0A%09method%20category%3A%20anotherString.%0A%09self%20addCompiledMethod%3A%20method'),
 messageSends: ["load:forClass:", "new", "category:", "addCompiledMethod:"],
-referencedClasses: [smalltalk.Compiler]
+referencedClasses: [smalltalk.nil]
 }),
 smalltalk.Behavior);
 
@@ -1295,25 +1358,10 @@ selector: 'category',
 category: 'accessing',
 fn: function (){
 var self=this;
-return self.category;
-return self;},
-source: unescape('category%0A%09%3Creturn%20self.category%3E'),
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Class);
-
-smalltalk.addMethod(
-'_category_',
-smalltalk.method({
-selector: 'category:',
-category: 'accessing',
-fn: function (aString){
-var self=this;
-self.category = aString;
+return (($receiver = smalltalk.send(self, "_module", [])) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : (function(){return smalltalk.send(smalltalk.send(self, "_module", []), "_name", []);})();
 return self;},
-source: unescape('category%3A%20aString%0A%09%3Cself.category%20%3D%20aString%3E'),
-messageSends: [],
+source: unescape('category%0A%09%5Eself%20module%20ifNil%3A%20%5B%27unclassified%27%5D%20ifNotNil%3A%20%5Bself%20module%20name%5D'),
+messageSends: ["ifNil:ifNotNil:", "module", "name"],
 referencedClasses: []
 }),
 smalltalk.Class);
@@ -1325,10 +1373,10 @@ selector: 'subclass:instanceVariableNames:',
 category: 'class creation',
 fn: function (aString, anotherString){
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, anotherString, nil]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, anotherString, nil]);
 return self;},
-source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%20category%3A%20nil'),
-messageSends: ["subclass:instanceVariableNames:category:"],
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%0A%09%22Kept%20for%20compatibility.%22%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%20module%3A%20nil'),
+messageSends: ["subclass:instanceVariableNames:module:"],
 referencedClasses: []
 }),
 smalltalk.Class);
@@ -1340,11 +1388,11 @@ selector: 'subclass:instanceVariableNames:category:',
 category: 'class creation',
 fn: function (aString, aString2, aString3){
 var self=this;
-return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_category_", [self, aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
 return self;},
-source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3%0A%09%5EClassBuilder%20new%0A%09%20%20%20%20superclass%3A%20self%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3'),
-messageSends: ["superclass:subclass:instanceVariableNames:category:", "new"],
-referencedClasses: [smalltalk.nil]
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3%0A%09%22Kept%20for%20compatibility.%22%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3'),
+messageSends: ["subclass:instanceVariableNames:module:"],
+referencedClasses: []
 }),
 smalltalk.Class);
 
@@ -1404,14 +1452,59 @@ selector: 'subclass:instanceVariableNames:classVariableNames:poolDictionaries:ca
 category: 'class creation',
 fn: function (aString, aString2, classVars, pools, aString3){
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
+return self;},
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20classVariableNames%3A%20classVars%20poolDictionaries%3A%20pools%20category%3A%20aString3%0A%09%22Just%20ignore%20class%20variables%20and%20pools.%20Added%20for%20compatibility.%22%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3'),
+messageSends: ["subclass:instanceVariableNames:module:"],
+referencedClasses: []
+}),
+smalltalk.Class);
+
+smalltalk.addMethod(
+'_module',
+smalltalk.method({
+selector: 'module',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.module;
 return self;},
-source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20classVariableNames%3A%20classVars%20poolDictionaries%3A%20pools%20category%3A%20aString3%0A%09%22Just%20ignore%20class%20variables%20and%20pools.%20Added%20for%20compatibility.%22%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3'),
-messageSends: ["subclass:instanceVariableNames:category:"],
+source: unescape('module%0A%09%3Creturn%20self.module%3E'),
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.Class);
 
+smalltalk.addMethod(
+'_module_',
+smalltalk.method({
+selector: 'module:',
+category: 'accessing',
+fn: function (aModule){
+var self=this;
+self.module = aModule;
+return self;},
+source: unescape('module%3A%20aModule%0A%09%3Cself.module%20%3D%20aModule%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Class);
+
+smalltalk.addMethod(
+'_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'subclass:instanceVariableNames:module:',
+category: 'class creation',
+fn: function (aString, aString2, aString3){
+var self=this;
+return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_module_", [self, aString, aString2, aString3]);
+return self;},
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3%0A%09%5EClassBuilder%20new%0A%09%20%20%20%20superclass%3A%20self%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3'),
+messageSends: ["superclass:subclass:instanceVariableNames:module:", "new"],
+referencedClasses: [smalltalk.ClassBuilder]
+}),
+smalltalk.Class);
+
 
 
 smalltalk.addClass('Metaclass', smalltalk.Behavior, [], 'Kernel');
@@ -3231,10 +3324,10 @@ selector: 'subclass:instanceVariableNames:',
 category: 'class creation',
 fn: function (aString, anotherString){
 var self=this;
-return smalltalk.send(self, "_subclass_instanceVariableNames_category_", [aString, anotherString, nil]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, anotherString, nil]);
 return self;},
-source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%20category%3A%20nil'),
-messageSends: ["subclass:instanceVariableNames:category:"],
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20anotherString%20module%3A%20nil'),
+messageSends: ["subclass:instanceVariableNames:module:"],
 referencedClasses: []
 }),
 smalltalk.UndefinedObject);
@@ -3246,11 +3339,11 @@ selector: 'subclass:instanceVariableNames:category:',
 category: 'class creation',
 fn: function (aString, aString2, aString3){
 var self=this;
-return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_category_", [self, aString, aString2, aString3]);
+return smalltalk.send(self, "_subclass_instanceVariableNames_module_", [aString, aString2, aString3]);
 return self;},
-source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3%0A%09%5EClassBuilder%20new%0A%09%20%20%20%20superclass%3A%20self%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3'),
-messageSends: ["superclass:subclass:instanceVariableNames:category:", "new"],
-referencedClasses: [smalltalk.nil]
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3%0A%09%22Kept%20for%20compatibility.%22%0A%09%5Eself%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3'),
+messageSends: ["subclass:instanceVariableNames:module:"],
+referencedClasses: []
 }),
 smalltalk.UndefinedObject);
 
@@ -3389,6 +3482,21 @@ referencedClasses: []
 }),
 smalltalk.UndefinedObject);
 
+smalltalk.addMethod(
+'_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'subclass:instanceVariableNames:module:',
+category: 'class creation',
+fn: function (aString, aString2, aString3){
+var self=this;
+return smalltalk.send(smalltalk.send((smalltalk.ClassBuilder || ClassBuilder), "_new", []), "_superclass_subclass_instanceVariableNames_module_", [self, aString, aString2, aString3]);
+return self;},
+source: unescape('subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3%0A%09%5EClassBuilder%20new%0A%09%20%20%20%20superclass%3A%20self%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3'),
+messageSends: ["superclass:subclass:instanceVariableNames:module:", "new"],
+referencedClasses: [smalltalk.ClassBuilder]
+}),
+smalltalk.UndefinedObject);
+
 
 smalltalk.addMethod(
 '_new',
@@ -6155,28 +6263,10 @@ selector: 'superclass:subclass:',
 category: 'class creation',
 fn: function (aClass, aString){
 var self=this;
-smalltalk.send(self, "_superclass_subclass_instanceVariableNames_category_", [aClass, aString, "", nil]);
+return smalltalk.send(self, "_superclass_subclass_instanceVariableNames_module_", [aClass, aString, "", nil]);
 return self;},
-source: unescape('superclass%3A%20aClass%20subclass%3A%20aString%0A%09self%20superclass%3A%20aClass%20subclass%3A%20aString%20instanceVariableNames%3A%20%27%27%20category%3A%20nil'),
-messageSends: ["superclass:subclass:instanceVariableNames:category:"],
-referencedClasses: []
-}),
-smalltalk.ClassBuilder);
-
-smalltalk.addMethod(
-'_superclass_subclass_instanceVariableNames_category_',
-smalltalk.method({
-selector: 'superclass:subclass:instanceVariableNames:category:',
-category: 'class creation',
-fn: function (aClass, aString, aString2, aString3){
-var self=this;
-var newClass=nil;
-newClass=smalltalk.send(self, "_addSubclassOf_named_instanceVariableNames_", [aClass, aString, smalltalk.send(self, "_instanceVariableNamesFor_", [aString2])]);
-smalltalk.send(self, "_setupClass_", [newClass]);
-smalltalk.send(newClass, "_category_", [(($receiver = aString3) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : $receiver]);
-return self;},
-source: unescape('superclass%3A%20aClass%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20category%3A%20aString3%0A%09%7C%20newClass%20%7C%0A%09newClass%20%3A%3D%20self%20addSubclassOf%3A%20aClass%20named%3A%20aString%20instanceVariableNames%3A%20%28self%20instanceVariableNamesFor%3A%20aString2%29.%0A%09self%20setupClass%3A%20newClass.%0A%09newClass%20category%3A%20%28aString3%20ifNil%3A%20%5B%27unclassified%27%5D%29'),
-messageSends: ["addSubclassOf:named:instanceVariableNames:", "instanceVariableNamesFor:", "setupClass:", "category:", "ifNil:"],
+source: unescape('superclass%3A%20aClass%20subclass%3A%20aString%0A%09%5Eself%20superclass%3A%20aClass%20subclass%3A%20aString%20instanceVariableNames%3A%20%27%27%20module%3A%20nil'),
+messageSends: ["superclass:subclass:instanceVariableNames:module:"],
 referencedClasses: []
 }),
 smalltalk.ClassBuilder);
@@ -6244,6 +6334,39 @@ referencedClasses: []
 }),
 smalltalk.ClassBuilder);
 
+smalltalk.addMethod(
+'_superclass_subclass_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'superclass:subclass:instanceVariableNames:module:',
+category: 'class creation',
+fn: function (aClass, aString, aString2, aString3){
+var self=this;
+var newClass=nil;
+newClass=smalltalk.send(self, "_addSubclassOf_named_instanceVariableNames_module_", [aClass, aString, smalltalk.send(self, "_instanceVariableNamesFor_", [aString2]), (($receiver = aString3) == nil || $receiver == undefined) ? (function(){return "unclassified";})() : $receiver]);
+smalltalk.send(self, "_setupClass_", [newClass]);
+return self;},
+source: unescape('superclass%3A%20aClass%20subclass%3A%20aString%20instanceVariableNames%3A%20aString2%20module%3A%20aString3%0A%09%7C%20newClass%20%7C%0A%09newClass%20%3A%3D%20self%20addSubclassOf%3A%20aClass%0A%09%09%09%09named%3A%20aString%20instanceVariableNames%3A%20%28self%20instanceVariableNamesFor%3A%20aString2%29%0A%09%09%09%09module%3A%20%28aString3%20ifNil%3A%20%5B%27unclassified%27%5D%29.%0A%09self%20setupClass%3A%20newClass'),
+messageSends: ["addSubclassOf:named:instanceVariableNames:module:", "instanceVariableNamesFor:", "ifNil:", "setupClass:"],
+referencedClasses: []
+}),
+smalltalk.ClassBuilder);
+
+smalltalk.addMethod(
+'_addSubclassOf_named_instanceVariableNames_module_',
+smalltalk.method({
+selector: 'addSubclassOf:named:instanceVariableNames:module:',
+category: 'private',
+fn: function (aClass, aString, aCollection, moduleName){
+var self=this;
+smalltalk.addClass(aString, aClass, aCollection, moduleName);
+	    return smalltalk[aString];
+return self;},
+source: unescape('addSubclassOf%3A%20aClass%20named%3A%20aString%20instanceVariableNames%3A%20aCollection%20module%3A%20moduleName%0A%09%3Csmalltalk.addClass%28aString%2C%20aClass%2C%20aCollection%2C%20moduleName%29%3B%0A%09%20%20%20%20return%20smalltalk%5BaString%5D%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ClassBuilder);
+
 
 
 smalltalk.addClass('ClassCategoryReader', smalltalk.Object, ['class', 'category', 'chunkParser'], 'Kernel');

+ 59 - 14
js/boot.js

@@ -38,6 +38,7 @@
 function SmalltalkObject(){};
 function SmalltalkBehavior(){};
 function SmalltalkClass(){};
+function SmalltalkModule(){};
 function SmalltalkMetaclass(){
     this.meta = true;
 };
@@ -48,6 +49,20 @@ function Smalltalk(){
 
     var st = this;
 
+    
+    /* We hold all Modules in a separate Object */
+    st.modules = {};
+
+    /* Smalltalk Module object. To add a Module, use smalltalk.addModule() */
+
+    function mod(spec) {
+	var that = new SmalltalkModule();
+	that.moduleName        = spec.moduleName;
+	that.requires          = spec.requires || [];
+	that.fn                = spec.fn || function(){};
+	return that;
+    };
+
     /* Smalltalk class creation. A class is an instance of an automatically 
        created metaclass object. Newly created classes (not their metaclass) 
        should be added to the smalltalk object, see smalltalk.addClass().
@@ -71,7 +86,11 @@ function Smalltalk(){
 	if(that.superclass) {
 	    that.klass.superclass = that.superclass.klass;
 	}
-	that.category = spec.category || "";
+	that.module = spec.module;
+        // For a while we keep the category attribute...
+        if(!(spec.module === undefined)) {
+	    that.category = spec.module.moduleName;
+	}
 	that.fn.prototype.methods = {};
 	that.fn.prototype.inheritedMethods = {};
 	that.fn.prototype.klass = that;
@@ -121,6 +140,16 @@ function Smalltalk(){
 	}
     };
 
+    /* Answer all registered Modules */
+
+    st.modules.all = function() {
+	var modules = [];
+	for(var i in st.modules) {
+	    modules.push(st.modules[i]);
+	}
+	return modules
+    };
+
     /* Answer all registered Smalltalk classes */
 
     st.classes = function() {
@@ -129,7 +158,6 @@ function Smalltalk(){
 	    if(i.search(/^[A-Z]/g) != -1) {
 		classes.push(st[i]);
 	    }
-
 	}
 	return classes
     };
@@ -168,31 +196,47 @@ function Smalltalk(){
     };
 
     /* Create a new class wrapping a JavaScript constructor, and add it to the 
-       global smalltalk object. */
+       global smalltalk object. Module is lazily created if it does not exist with given name. */
 
-    st.mapClassName = function(className, category, fn, superclass) {
+    st.mapClassName = function(className, moduleName, fn, superclass) {
+	modul = st.addModule(moduleName);
 	st[className] = klass({
 	    className:  className, 
-	    category:   category, 
+	    module:     modul, 
 	    superclass: superclass,
 	    fn:         fn
 	});
     };
 
-    /* Add a class to the smalltalk object, creating a new one if needed. */
+    /* Add a module to the smalltalk.modules object, creating a new one if needed.
+       If moduleName is nil or empty we return nil, which is an allowed module for a class. */
 
-    st.addClass = function(className, superclass, iVarNames, category) {
+    st.addModule = function(moduleName) {
+	if(!moduleName) {return nil;}
+	if(!(st.modules[moduleName])) {
+	    st.modules[moduleName] = mod({
+		moduleName: moduleName
+	    });
+	}
+	return st.modules[moduleName];
+    };
+
+    /* Add a class to the smalltalk object, creating a new one if needed.
+       Module is lazily created if it does not exist with given name.*/
+
+    st.addClass = function(className, superclass, iVarNames, moduleName) {
+	modul = st.addModule(moduleName);
 	if(st[className]) {
 	    st[className].superclass = superclass;
 	    st[className].iVarNames = iVarNames;
-	    st[className].category = category || st[className].category;
-	} else {
+	    st[className].module = modul || st[className].module;
+	} else {    
 	    st[className] = klass({
 		className: className, 
 		iVarNames: iVarNames,
-		superclass: superclass
+		superclass: superclass,
+		module: modul
 	    });
-	    st[className].category = category || '';
 	}
     };
 
@@ -446,12 +490,13 @@ if(this.jQuery) {
 
 smalltalk.mapClassName("Object", "Kernel", SmalltalkObject);
 smalltalk.mapClassName("Smalltalk", "Kernel", Smalltalk, smalltalk.Object);
+smalltalk.mapClassName("Module", "Kernel", SmalltalkModule, smalltalk.Object);
 smalltalk.mapClassName("Behavior", "Kernel", SmalltalkBehavior, smalltalk.Object);
 smalltalk.mapClassName("Class", "Kernel", SmalltalkClass, smalltalk.Behavior);
 smalltalk.mapClassName("Metaclass", "Kernel", SmalltalkMetaclass, smalltalk.Behavior);
 smalltalk.mapClassName("CompiledMethod", "Kernel", SmalltalkMethod, smalltalk.Object);
 
-smalltalk.Object.klass.superclass = smalltalk.Class
+smalltalk.Object.klass.superclass = smalltalk.Class;
 
 smalltalk.mapClassName("Number", "Kernel", Number, smalltalk.Object);
 smalltalk.mapClassName("BlockClosure", "Kernel", Function, smalltalk.Object);
@@ -469,5 +514,5 @@ smalltalk.mapClassName("Error", "Kernel", Error, smalltalk.Object);
 smalltalk.mapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object);
 
 if(this.CanvasRenderingContext2D) {
-    smalltalk.mapClassName("CanvasRenderingContext", "Canvas", CanvasRenderingContext2D, smalltalk.Object);
-}
+    smalltalk.mapClassName("CanvasRenderingContext", 'Canvas', CanvasRenderingContext2D, smalltalk.Object);
+}

+ 0 - 0
st/Compiler.st


+ 64 - 21
st/Kernel.st

@@ -292,9 +292,13 @@ parseError: anException parsing: aString
 	badLine := (badLine copyFrom: 1 to: col - 1), ' ===>', (badLine copyFrom:  col to: badLine size).
 	lines at: row put: badLine.
 	code := String streamContents: [:s |
-                                        lines withIndexDo: [:l :i |
-                                                   s nextPutAll: i asString, ': ', l, String lf]].
+                  lines withIndexDo: [:l :i |
+                     s nextPutAll: i asString, ': ', l, String lf]].
 	^ Error new messageText: ('Parse error on line ' , row , ' column ' , col , ' : ' , message , ' Below is code with line numbers and ===> marker inserted:' , String lf, code)
+!
+
+modules
+	<return self.modules.all()>
 ! !
 
 Smalltalk class instanceVariableNames: 'current'!
@@ -305,6 +309,24 @@ current
 	<return smalltalk>
 ! !
 
+Object subclass: #Module
+	instanceVariableNames: ''
+	category: 'Kernel'!
+
+!Module methodsFor: 'accessing'!
+
+name
+	<return self.moduleName || nil>
+!
+
+requires
+	<return self.requires || nil>
+!
+
+name: aString
+	<return self.moduleName = aString>
+! !
+
 Object subclass: #Behavior
 	instanceVariableNames: ''
 	category: 'Kernel'!
@@ -461,11 +483,7 @@ Behavior subclass: #Class
 !Class methodsFor: 'accessing'!
 
 category
-	<return self.category>
-!
-
-category: aString
-	<self.category = aString>
+	^self module ifNil: ['unclassified'] ifNotNil: [self module name]
 !
 
 rename: aString
@@ -474,22 +492,36 @@ rename: aString
 		delete smalltalk[self.className];
 		self.className = aString;
 	>
+!
+
+module
+	<return self.module>
+!
+
+module: aModule
+	<self.module = aModule>
 ! !
 
 !Class methodsFor: 'class creation'!
 
 subclass: aString instanceVariableNames: anotherString
-	^self subclass: aString instanceVariableNames: anotherString category: nil
+	"Kept for compatibility."
+	^self subclass: aString instanceVariableNames: anotherString module: nil
 !
 
 subclass: aString instanceVariableNames: aString2 category: aString3
-	^ClassBuilder new
-	    superclass: self subclass: aString instanceVariableNames: aString2 category: aString3
+	"Kept for compatibility."
+	^self subclass: aString instanceVariableNames: aString2 module: aString3
 !
 
 subclass: aString instanceVariableNames: aString2 classVariableNames: classVars poolDictionaries: pools category: aString3
 	"Just ignore class variables and pools. Added for compatibility."
-	^self subclass: aString instanceVariableNames: aString2 category: aString3
+	^self subclass: aString instanceVariableNames: aString2 module: aString3
+!
+
+subclass: aString instanceVariableNames: aString2 module: aString3
+	^ClassBuilder new
+	    superclass: self subclass: aString instanceVariableNames: aString2 module: aString3
 ! !
 
 !Class methodsFor: 'printing'!
@@ -1129,12 +1161,17 @@ Object subclass: #UndefinedObject
 !UndefinedObject methodsFor: 'class creation'!
 
 subclass: aString instanceVariableNames: anotherString
-	^self subclass: aString instanceVariableNames: anotherString category: nil
+	^self subclass: aString instanceVariableNames: anotherString module: nil
 !
 
 subclass: aString instanceVariableNames: aString2 category: aString3
+	"Kept for compatibility."
+	^self subclass: aString instanceVariableNames: aString2 module: aString3
+!
+
+subclass: aString instanceVariableNames: aString2 module: aString3
 	^ClassBuilder new
-	    superclass: self subclass: aString instanceVariableNames: aString2 category: aString3
+	    superclass: self subclass: aString instanceVariableNames: aString2 module: aString3
 ! !
 
 !UndefinedObject methodsFor: 'copying'!
@@ -2249,20 +2286,21 @@ Object subclass: #ClassBuilder
 !ClassBuilder methodsFor: 'class creation'!
 
 superclass: aClass subclass: aString
-	self superclass: aClass subclass: aString instanceVariableNames: '' category: nil
-!
-
-superclass: aClass subclass: aString instanceVariableNames: aString2 category: aString3
-	| newClass |
-	newClass := self addSubclassOf: aClass named: aString instanceVariableNames: (self instanceVariableNamesFor: aString2).
-	self setupClass: newClass.
-	newClass category: (aString3 ifNil: ['unclassified'])
+	^self superclass: aClass subclass: aString instanceVariableNames: '' module: nil
 !
 
 class: aClass instanceVariableNames: aString
 	aClass isMetaclass ifFalse: [self error: aClass name, ' is not a metaclass'].
 	aClass basicAt: 'iVarNames' put: (self instanceVariableNamesFor: aString).
 	self setupClass: aClass
+!
+
+superclass: aClass subclass: aString instanceVariableNames: aString2 module: aString3
+	| newClass |
+	newClass := self addSubclassOf: aClass
+				named: aString instanceVariableNames: (self instanceVariableNamesFor: aString2)
+				module: (aString3 ifNil: ['unclassified']).
+	self setupClass: newClass
 ! !
 
 !ClassBuilder methodsFor: 'private'!
@@ -2278,6 +2316,11 @@ addSubclassOf: aClass named: aString instanceVariableNames: aCollection
 
 setupClass: aClass
 	<smalltalk.init(aClass);>
+!
+
+addSubclassOf: aClass named: aString instanceVariableNames: aCollection module: moduleName
+	<smalltalk.addClass(aString, aClass, aCollection, moduleName);
+	    return smalltalk[aString]>
 ! !
 
 Object subclass: #ClassCategoryReader