Ver Fonte

PackageHandler refactoring:
- Removes LegacyPackageHandler
- PackageHandler now uses #exportPackage:on: instead of recipes
- MethodCategory renamed to ExportMethodProtocol
- Committing is much faster, using methods from Behavior and Package instead of its own for collecting methods, classes and extensions

Nicolas Petton há 10 anos atrás
pai
commit
6194b5184a
3 ficheiros alterados com 1093 adições e 921 exclusões
  1. 388 86
      js/Importer-Exporter.deploy.js
  2. 497 483
      js/Importer-Exporter.js
  3. 208 352
      st/Importer-Exporter.st

+ 388 - 86
js/Importer-Exporter.deploy.js

@@ -41,15 +41,64 @@ smalltalk.AbstractExporter);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "recipe",
-fn: function (){
+selector: "exportPackage:on:",
+fn: function (aPackage,aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._subclassResponsibility();
-return self}, function($ctx1) {$ctx1.fill(self,"recipe",{},smalltalk.AbstractExporter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackage:on:",{aPackage:aPackage,aStream:aStream},smalltalk.AbstractExporter)})},
 messageSends: ["subclassResponsibility"]}),
 smalltalk.AbstractExporter);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "extensionMethodsOfPackage:",
+fn: function (aPackage){
+var self=this;
+var result;
+function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+result=_st($OrderedCollection())._new();
+_st(self._extensionProtocolsOfPackage_(aPackage))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(result)._addAll_(_st(each)._methods());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+$1=result;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"extensionMethodsOfPackage:",{aPackage:aPackage,result:result},smalltalk.AbstractExporter)})},
+messageSends: ["new", "do:", "addAll:", "methods", "extensionProtocolsOfPackage:"]}),
+smalltalk.AbstractExporter);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "extensionProtocolsOfPackage:",
+fn: function (aPackage){
+var self=this;
+var extensionName,result;
+function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
+function $ExportMethodProtocol(){return smalltalk.ExportMethodProtocol||(typeof ExportMethodProtocol=="undefined"?nil:ExportMethodProtocol)}
+function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+extensionName="*".__comma(_st(aPackage)._name());
+result=_st($OrderedCollection())._new();
+_st(_st(_st($Smalltalk())._current())._classes())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st([each,_st(each)._class()])._do_((function(behavior){
+return smalltalk.withContext(function($ctx3) {
+$1=_st(_st(behavior)._protocols())._includes_(extensionName);
+if(smalltalk.assert($1)){
+return _st(result)._add_(_st($ExportMethodProtocol())._name_theClass_(extensionName,behavior));
+};
+}, function($ctx3) {$ctx3.fillBlock({behavior:behavior},$ctx2)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+$2=result;
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"extensionProtocolsOfPackage:",{aPackage:aPackage,extensionName:extensionName,result:result},smalltalk.AbstractExporter)})},
+messageSends: [",", "name", "new", "do:", "ifTrue:", "add:", "name:theClass:", "includes:", "protocols", "class", "classes", "current"]}),
+smalltalk.AbstractExporter);
+
 
 smalltalk.AbstractExporter.klass.iVarNames = ['default'];
 smalltalk.addMethod(
@@ -189,6 +238,25 @@ return self}, function($ctx1) {$ctx1.fill(self,"exportMethod:on:",{aMethod:aMeth
 messageSends: ["lf", "nextPutAll:", "chunkEscape:", "source"]}),
 smalltalk.ChunkExporter);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportPackage:on:",
+fn: function (aPackage,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._exportPackageDefinitionOf_on_(aPackage,aStream);
+_st(_st(aPackage)._sortedClasses())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+self._exportDefinitionOf_on_(each,aStream);
+self._exportProtocols_on_(self._ownMethodProtocolsOfClass_(each),aStream);
+self._exportMetaDefinitionOf_on_(each,aStream);
+return self._exportProtocols_on_(self._ownMethodProtocolsOfClass_(_st(each)._class()),aStream);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+self._exportProtocols_on_(self._extensionProtocolsOfPackage_(aPackage),aStream);
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackage:on:",{aPackage:aPackage,aStream:aStream},smalltalk.ChunkExporter)})},
+messageSends: ["exportPackageDefinitionOf:on:", "do:", "exportDefinitionOf:on:", "exportProtocols:on:", "ownMethodProtocolsOfClass:", "exportMetaDefinitionOf:on:", "class", "sortedClasses", "extensionProtocolsOfPackage:"]}),
+smalltalk.ChunkExporter);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "exportPackageDefinitionOf:on:",
@@ -203,6 +271,65 @@ return self}, function($ctx1) {$ctx1.fill(self,"exportPackageDefinitionOf:on:",{
 messageSends: ["nextPutAll:", ",", "name", "lf"]}),
 smalltalk.ChunkExporter);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportProtocol:on:",
+fn: function (aProtocol,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._exportProtocolPrologueOf_on_(aProtocol,aStream);
+_st(_st(aProtocol)._methods())._do_((function(method){
+return smalltalk.withContext(function($ctx2) {
+return self._exportMethod_on_(method,aStream);
+}, function($ctx2) {$ctx2.fillBlock({method:method},$ctx1)})}));
+self._exportProtocolEpilogueOf_on_(aProtocol,aStream);
+return self}, function($ctx1) {$ctx1.fill(self,"exportProtocol:on:",{aProtocol:aProtocol,aStream:aStream},smalltalk.ChunkExporter)})},
+messageSends: ["exportProtocolPrologueOf:on:", "do:", "exportMethod:on:", "methods", "exportProtocolEpilogueOf:on:"]}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportProtocolEpilogueOf:on:",
+fn: function (aProtocol,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_(" !");
+_st($1)._lf();
+$2=_st($1)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportProtocolEpilogueOf:on:",{aProtocol:aProtocol,aStream:aStream},smalltalk.ChunkExporter)})},
+messageSends: ["nextPutAll:", "lf"]}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportProtocolPrologueOf:on:",
+fn: function (aProtocol,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_("!".__comma(self._classNameFor_(_st(aProtocol)._theClass())));
+$2=_st($1)._nextPutAll_(_st(" methodsFor: '".__comma(_st(aProtocol)._name())).__comma("'!"));
+return self}, function($ctx1) {$ctx1.fill(self,"exportProtocolPrologueOf:on:",{aProtocol:aProtocol,aStream:aStream},smalltalk.ChunkExporter)})},
+messageSends: ["nextPutAll:", ",", "classNameFor:", "theClass", "name"]}),
+smalltalk.ChunkExporter);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportProtocols:on:",
+fn: function (aCollection,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(aCollection)._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return self._exportProtocol_on_(each,aStream);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"exportProtocols:on:",{aCollection:aCollection,aStream:aStream},smalltalk.ChunkExporter)})},
+messageSends: ["do:", "exportProtocol:on:"]}),
+smalltalk.ChunkExporter);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "extensionCategoriesOfPackage:",
@@ -273,20 +400,20 @@ function $MethodCategory(){return smalltalk.MethodCategory||(typeof MethodCatego
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 map=_st($Dictionary())._new();
-_st(aClass)._protocolsDo_((function(category,methods){
+_st(aClass)._protocolsDo_((function(each,methods){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(category)._match_("^\x5c*");
+$1=_st(each)._match_("^\x5c*");
 if(! smalltalk.assert($1)){
-return _st(map)._at_put_(category,methods);
+return _st(map)._at_put_(each,methods);
 };
-}, function($ctx2) {$ctx2.fillBlock({category:category,methods:methods},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each,methods:methods},$ctx1)})}));
 $2=_st(_st(_st(map)._keys())._sorted_((function(a,b){
 return smalltalk.withContext(function($ctx2) {
 return _st(a).__lt_eq(b);
-}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._collect_((function(category){
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})})))._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st($MethodCategory())._name_theClass_methods_(category,aClass,_st(map)._at_(category));
-}, function($ctx2) {$ctx2.fillBlock({category:category},$ctx1)})}));
+return _st($MethodCategory())._name_theClass_methods_(each,aClass,_st(map)._at_(each));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return $2;
 }, function($ctx1) {$ctx1.fill(self,"ownCategoriesOfClass:",{aClass:aClass,map:map},smalltalk.ChunkExporter)})},
 messageSends: ["new", "protocolsDo:", "ifFalse:", "at:put:", "match:", "collect:", "name:theClass:methods:", "at:", "sorted:", "<=", "keys"]}),
@@ -305,6 +432,23 @@ return $1;
 messageSends: ["ownCategoriesOfClass:", "class"]}),
 smalltalk.ChunkExporter);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "ownMethodProtocolsOfClass:",
+fn: function (aClass){
+var self=this;
+function $ExportMethodProtocol(){return smalltalk.ExportMethodProtocol||(typeof ExportMethodProtocol=="undefined"?nil:ExportMethodProtocol)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st(aClass)._ownProtocols())._collect_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st($ExportMethodProtocol())._name_theClass_(each,aClass);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"ownMethodProtocolsOfClass:",{aClass:aClass},smalltalk.ChunkExporter)})},
+messageSends: ["collect:", "name:theClass:", "ownProtocols"]}),
+smalltalk.ChunkExporter);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "recipe",
@@ -470,6 +614,39 @@ return self}, function($ctx1) {$ctx1.fill(self,"exportMethod:on:",{aMethod:aMeth
 messageSends: ["nextPutAll:", "lf", ",", "asJavascript", "selector", "category", "compiledSource", "fn", "arguments", "source", "messageSends", "referencedClasses", "classNameFor:", "methodClass"]}),
 smalltalk.Exporter);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportPackage:on:",
+fn: function (aPackage,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=self;
+_st($1)._exportPackagePrologueOf_on_(aPackage,aStream);
+_st($1)._exportPackageDefinitionOf_on_(aPackage,aStream);
+$2=_st($1)._exportPackageTransportOf_on_(aPackage,aStream);
+_st(_st(aPackage)._sortedClasses())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+self._exportDefinitionOf_on_(each,aStream);
+_st(_st(each)._ownMethods())._do_((function(method){
+return smalltalk.withContext(function($ctx3) {
+return self._exportMethod_on_(method,aStream);
+}, function($ctx3) {$ctx3.fillBlock({method:method},$ctx2)})}));
+self._exportMetaDefinitionOf_on_(each,aStream);
+return _st(_st(_st(each)._class())._ownMethods())._do_((function(method){
+return smalltalk.withContext(function($ctx3) {
+return self._exportMethod_on_(method,aStream);
+}, function($ctx3) {$ctx3.fillBlock({method:method},$ctx2)})}));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+_st(self._extensionMethodsOfPackage_(aPackage))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return self._exportMethod_on_(each,aStream);
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+self._exportPackageEpilogueOf_on_(aPackage,aStream);
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackage:on:",{aPackage:aPackage,aStream:aStream},smalltalk.Exporter)})},
+messageSends: ["exportPackagePrologueOf:on:", "exportPackageDefinitionOf:on:", "exportPackageTransportOf:on:", "do:", "exportDefinitionOf:on:", "exportMethod:on:", "ownMethods", "exportMetaDefinitionOf:on:", "class", "sortedClasses", "extensionMethodsOfPackage:", "exportPackageEpilogueOf:on:"]}),
+smalltalk.Exporter);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "exportPackageDefinitionOf:on:",
@@ -537,38 +714,6 @@ return self}, function($ctx1) {$ctx1.fill(self,"exportPackageTransportOf:on:",{a
 messageSends: ["transportJson", "ifFalse:", "nextPutAll:", "asJavascript", "name", "lf", "="]}),
 smalltalk.Exporter);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "extensionMethodsOfPackage:",
-fn: function (aPackage){
-var self=this;
-var name,result;
-function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
-function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
-function $Package(){return smalltalk.Package||(typeof Package=="undefined"?nil:Package)}
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-name=_st(aPackage)._name();
-result=_st($OrderedCollection())._new();
-_st(_st($Package())._sortedClasses_(_st(_st($Smalltalk())._current())._classes()))._do_((function(each){
-return smalltalk.withContext(function($ctx2) {
-return _st([each,_st(each)._class()])._do_((function(aClass){
-return smalltalk.withContext(function($ctx3) {
-return _st(result)._addAll_(_st(_st(_st(_st(aClass)._methodDictionary())._values())._sorted_((function(a,b){
-return smalltalk.withContext(function($ctx4) {
-return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
-}, function($ctx4) {$ctx4.fillBlock({a:a,b:b},$ctx3)})})))._select_((function(method){
-return smalltalk.withContext(function($ctx4) {
-return _st(_st(method)._category()).__eq("*".__comma(name));
-}, function($ctx4) {$ctx4.fillBlock({method:method},$ctx3)})})));
-}, function($ctx3) {$ctx3.fillBlock({aClass:aClass},$ctx2)})}));
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
-$1=result;
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"extensionMethodsOfPackage:",{aPackage:aPackage,name:name,result:result},smalltalk.Exporter)})},
-messageSends: ["name", "new", "do:", "addAll:", "select:", "=", ",", "category", "sorted:", "<=", "selector", "values", "methodDictionary", "class", "sortedClasses:", "classes", "current"]}),
-smalltalk.Exporter);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "ownMethodsOfClass:",
@@ -617,66 +762,67 @@ smalltalk.Exporter);
 
 
 
-smalltalk.addClass('StrippedExporter', smalltalk.Exporter, [], 'Importer-Exporter');
+smalltalk.addClass('AmdExporter', smalltalk.Exporter, [], 'Importer-Exporter');
 smalltalk.addMethod(
 smalltalk.method({
-selector: "exportDefinitionOf:on:",
-fn: function (aClass,aStream){
+selector: "amdNamesOfPackages:",
+fn: function (anArray){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4;
-$1=aStream;
-_st($1)._lf();
-_st($1)._nextPutAll_("smalltalk.addClass(");
-_st($1)._nextPutAll_(_st("'".__comma(self._classNameFor_(aClass))).__comma("', "));
-_st($1)._nextPutAll_("smalltalk.".__comma(self._classNameFor_(_st(aClass)._superclass())));
-$2=_st($1)._nextPutAll_(", [");
-_st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
+var $1;
+$1=_st(_st(anArray)._select_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(aStream)._nextPutAll_(_st("'".__comma(each)).__comma("'"));
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return _st(_st(each)._amdNamespace())._notNil();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})})))._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(aStream)._nextPutAll_(", ");
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
-$3=aStream;
-_st($3)._nextPutAll_("], '");
-_st($3)._nextPutAll_(_st(_st(aClass)._category()).__comma("'"));
-$4=_st($3)._nextPutAll_(");");
-_st(aStream)._lf();
-return self}, function($ctx1) {$ctx1.fill(self,"exportDefinitionOf:on:",{aClass:aClass,aStream:aStream},smalltalk.StrippedExporter)})},
-messageSends: ["lf", "nextPutAll:", ",", "classNameFor:", "superclass", "do:separatedBy:", "instanceVariableNames", "category"]}),
-smalltalk.StrippedExporter);
+return _st(_st(_st(each)._amdNamespace()).__comma("/")).__comma(_st(each)._name());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"amdNamesOfPackages:",{anArray:anArray},smalltalk.AmdExporter)})},
+messageSends: ["collect:", ",", "name", "amdNamespace", "select:", "notNil"]}),
+smalltalk.AmdExporter);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "exportMethod:on:",
-fn: function (aMethod,aStream){
+selector: "exportPackageEpilogueOf:on:",
+fn: function (aPackage,aStream){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 $1=aStream;
-_st($1)._nextPutAll_("smalltalk.addMethod(");
-_st($1)._lf();
-_st($1)._nextPutAll_("smalltalk.method({");
-_st($1)._lf();
-_st($1)._nextPutAll_(_st("selector: ".__comma(_st(_st(aMethod)._selector())._asJavascript())).__comma(","));
-_st($1)._lf();
-_st($1)._nextPutAll_(_st("fn: ".__comma(_st(_st(aMethod)._fn())._compiledSource())).__comma(","));
-_st($1)._lf();
-_st($1)._nextPutAll_("messageSends: ".__comma(_st(_st(aMethod)._messageSends())._asJavascript()));
-_st($1)._nextPutAll_("}),");
-_st($1)._lf();
-_st($1)._nextPutAll_("smalltalk.".__comma(self._classNameFor_(_st(aMethod)._methodClass())));
-_st($1)._nextPutAll_(");");
-_st($1)._lf();
+_st($1)._nextPutAll_("});");
 $2=_st($1)._lf();
-return self}, function($ctx1) {$ctx1.fill(self,"exportMethod:on:",{aMethod:aMethod,aStream:aStream},smalltalk.StrippedExporter)})},
-messageSends: ["nextPutAll:", "lf", ",", "asJavascript", "selector", "compiledSource", "fn", "messageSends", "classNameFor:", "methodClass"]}),
-smalltalk.StrippedExporter);
-
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackageEpilogueOf:on:",{aPackage:aPackage,aStream:aStream},smalltalk.AmdExporter)})},
+messageSends: ["nextPutAll:", "lf"]}),
+smalltalk.AmdExporter);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportPackagePrologueOf:on:",
+fn: function (aPackage,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$4,$3,$5;
+$1=aStream;
+_st($1)._nextPutAll_("define(\x22");
+$2=$1;
+$4=_st(aPackage)._amdNamespace();
+if(($receiver = $4) == nil || $receiver == undefined){
+$3="amber";
+} else {
+$3=$4;
+};
+_st($2)._nextPutAll_($3);
+_st($1)._nextPutAll_("/");
+_st($1)._nextPutAll_(_st(aPackage)._name());
+_st($1)._nextPutAll_("\x22, ");
+_st($1)._nextPutAll_(_st(["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st"].__comma(self._amdNamesOfPackages_(_st(aPackage)._loadDependencies())))._asJavascript());
+_st($1)._nextPutAll_(", function(smalltalk,nil,_st){");
+$5=_st($1)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackagePrologueOf:on:",{aPackage:aPackage,aStream:aStream},smalltalk.AmdExporter)})},
+messageSends: ["nextPutAll:", "ifNil:", "amdNamespace", "name", "asJavascript", ",", "amdNamesOfPackages:", "loadDependencies", "lf"]}),
+smalltalk.AmdExporter);
 
-smalltalk.addClass('AmdExporter', smalltalk.Object, [], 'Importer-Exporter');
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -740,6 +886,65 @@ messageSends: ["nextPutAll:", "ifNil:", "amdNamespace", "name", "asJavascript",
 smalltalk.AmdExporter.klass);
 
 
+smalltalk.addClass('StrippedExporter', smalltalk.Exporter, [], 'Importer-Exporter');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportDefinitionOf:on:",
+fn: function (aClass,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4;
+$1=aStream;
+_st($1)._lf();
+_st($1)._nextPutAll_("smalltalk.addClass(");
+_st($1)._nextPutAll_(_st("'".__comma(self._classNameFor_(aClass))).__comma("', "));
+_st($1)._nextPutAll_("smalltalk.".__comma(self._classNameFor_(_st(aClass)._superclass())));
+$2=_st($1)._nextPutAll_(", [");
+_st(_st(aClass)._instanceVariableNames())._do_separatedBy_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(_st("'".__comma(each)).__comma("'"));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}),(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(aStream)._nextPutAll_(", ");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$3=aStream;
+_st($3)._nextPutAll_("], '");
+_st($3)._nextPutAll_(_st(_st(aClass)._category()).__comma("'"));
+$4=_st($3)._nextPutAll_(");");
+_st(aStream)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportDefinitionOf:on:",{aClass:aClass,aStream:aStream},smalltalk.StrippedExporter)})},
+messageSends: ["lf", "nextPutAll:", ",", "classNameFor:", "superclass", "do:separatedBy:", "instanceVariableNames", "category"]}),
+smalltalk.StrippedExporter);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "exportMethod:on:",
+fn: function (aMethod,aStream){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=aStream;
+_st($1)._nextPutAll_("smalltalk.addMethod(");
+_st($1)._lf();
+_st($1)._nextPutAll_("smalltalk.method({");
+_st($1)._lf();
+_st($1)._nextPutAll_(_st("selector: ".__comma(_st(_st(aMethod)._selector())._asJavascript())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_(_st("fn: ".__comma(_st(_st(aMethod)._fn())._compiledSource())).__comma(","));
+_st($1)._lf();
+_st($1)._nextPutAll_("messageSends: ".__comma(_st(_st(aMethod)._messageSends())._asJavascript()));
+_st($1)._nextPutAll_("}),");
+_st($1)._lf();
+_st($1)._nextPutAll_("smalltalk.".__comma(self._classNameFor_(_st(aMethod)._methodClass())));
+_st($1)._nextPutAll_(");");
+_st($1)._lf();
+$2=_st($1)._lf();
+return self}, function($ctx1) {$ctx1.fill(self,"exportMethod:on:",{aMethod:aMethod,aStream:aStream},smalltalk.StrippedExporter)})},
+messageSends: ["nextPutAll:", "lf", ",", "asJavascript", "selector", "compiledSource", "fn", "messageSends", "classNameFor:", "methodClass"]}),
+smalltalk.StrippedExporter);
+
+
+
 smalltalk.addClass('ChunkParser', smalltalk.Object, ['stream'], 'Importer-Exporter');
 smalltalk.addMethod(
 smalltalk.method({
@@ -804,6 +1009,103 @@ messageSends: ["stream:", "new"]}),
 smalltalk.ChunkParser.klass);
 
 
+smalltalk.addClass('ExportMethodProtocol', smalltalk.Object, ['name', 'theClass'], 'Importer-Exporter');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "methods",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._theClass())._methodsInProtocol_(self._name());
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"methods",{},smalltalk.ExportMethodProtocol)})},
+messageSends: ["methodsInProtocol:", "name", "theClass"]}),
+smalltalk.ExportMethodProtocol);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "name",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@name"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"name",{},smalltalk.ExportMethodProtocol)})},
+messageSends: []}),
+smalltalk.ExportMethodProtocol);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "name:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@name"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"name:",{aString:aString},smalltalk.ExportMethodProtocol)})},
+messageSends: []}),
+smalltalk.ExportMethodProtocol);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "sortedMethods",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._methods())._sorted_((function(a,b){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(a)._selector()).__lt_eq(_st(b)._selector());
+}, function($ctx2) {$ctx2.fillBlock({a:a,b:b},$ctx1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"sortedMethods",{},smalltalk.ExportMethodProtocol)})},
+messageSends: ["sorted:", "<=", "selector", "methods"]}),
+smalltalk.ExportMethodProtocol);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "theClass",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@theClass"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"theClass",{},smalltalk.ExportMethodProtocol)})},
+messageSends: []}),
+smalltalk.ExportMethodProtocol);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "theClass:",
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@theClass"]=aClass;
+return self}, function($ctx1) {$ctx1.fill(self,"theClass:",{aClass:aClass},smalltalk.ExportMethodProtocol)})},
+messageSends: []}),
+smalltalk.ExportMethodProtocol);
+
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "name:theClass:",
+fn: function (aString,aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=self._new();
+_st($2)._name_(aString);
+_st($2)._theClass_(aClass);
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"name:theClass:",{aString:aString,aClass:aClass},smalltalk.ExportMethodProtocol.klass)})},
+messageSends: ["name:", "new", "theClass:", "yourself"]}),
+smalltalk.ExportMethodProtocol.klass);
+
+
 smalltalk.addClass('ExportRecipeInterpreter', smalltalk.Object, [], 'Importer-Exporter');
 smalltalk.addMethod(
 smalltalk.method({

Diff do ficheiro suprimidas por serem muito extensas
+ 497 - 483
js/Importer-Exporter.js


+ 208 - 352
st/Importer-Exporter.st

@@ -3,7 +3,42 @@ Object subclass: #AbstractExporter
 	instanceVariableNames: ''
 	package: 'Importer-Exporter'!
 !AbstractExporter commentStamp!
-I am an abstract exporter for Amber source code.!
+I am an abstract exporter for Amber source code.
+
+## API
+
+Use `#exportPackage:on:` to export a given package on a Stream.!
+
+!AbstractExporter methodsFor: 'accessing'!
+
+extensionMethodsOfPackage: aPackage
+	| result |
+	
+	result := OrderedCollection new.
+	
+	(self extensionProtocolsOfPackage: aPackage) do: [ :each |
+		result addAll: each methods ].
+		
+	^ result
+!
+
+extensionProtocolsOfPackage: aPackage
+	| extensionName result |
+	
+	extensionName := '*', aPackage name.
+	result := OrderedCollection new.
+	
+	"The classes must be loaded since it is extensions only.
+	Therefore sorting (dependency resolution) does not matter here.
+	Not sorting improves the speed by a number of magnitude."
+	
+	Smalltalk current classes do: [ :each |
+		{each. each class} do: [ :behavior |
+			(behavior protocols includes: extensionName) ifTrue: [
+				result add: (ExportMethodProtocol name: extensionName theClass: behavior) ] ] ].
+
+	^result
+! !
 
 !AbstractExporter methodsFor: 'convenience'!
 
@@ -22,11 +57,9 @@ classNameFor: aClass
 				ifFalse: [ aClass name ] ]
 ! !
 
-!AbstractExporter methodsFor: 'fileOut'!
-
-recipe
-	"Recipe to export a given package."
+!AbstractExporter methodsFor: 'output'!
 
+exportPackage: aPackage on: aStream
 	self subclassResponsibility
 ! !
 
@@ -48,84 +81,15 @@ I do not output any compiled code.!
 
 !ChunkExporter methodsFor: 'accessing'!
 
-extensionCategoriesOfPackage: aPackage
-	"Issue #143: sort protocol alphabetically"
-
-	| name map result |
-	name := aPackage name.
-	result := OrderedCollection new.
-	(Package sortedClasses: Smalltalk current classes) do: [:each |
-		{each. each class} do: [:aClass |
-			map := Dictionary new.
-			aClass protocolsDo: [:category :methods |
-				category = ('*', name) ifTrue: [ map at: category put: methods ]].
-			result addAll: ((map keys sorted: [:a :b | a <= b ]) collect: [:category |
-				MethodCategory name: category theClass: aClass methods: (map at: category)]) ]].
-	^result
-!
-
-methodsOfCategory: aCategory
-	"Issue #143: sort methods alphabetically"
-
-	^(aCategory methods) sorted: [:a :b | a selector <= b selector]
-!
-
-ownCategoriesOfClass: aClass
-	"Answer the protocols of aClassthat are not package extensions"
+ownMethodProtocolsOfClass: aClass
+	"Answer a collection of ExportMethodProtocol object of aClass that are not package extensions"
 	
-	"Issue #143: sort protocol alphabetically"
-
-	| map |
-	map := Dictionary new.
-	aClass protocolsDo: [:category :methods |
-		(category match: '^\*') ifFalse: [ map at: category put: methods ]].
-	^(map keys sorted: [:a :b | a <= b ]) collect: [:category |
-		MethodCategory name: category theClass: aClass methods: (map at: category) ]
-!
-
-ownCategoriesOfMetaClass: aClass
-	"Issue #143: sort protocol alphabetically"
-
-	^self ownCategoriesOfClass: aClass class
-! !
-
-!ChunkExporter methodsFor: 'fileOut'!
-
-recipe
-	"Export a given package."
-
-	| exportCategoryRecipe |
-	exportCategoryRecipe := {
-		self -> #exportCategoryPrologueOf:on:.
-		{
-			self -> #methodsOfCategory:.
-			self -> #exportMethod:on: }.
-		self -> #exportCategoryEpilogueOf:on: }.
-
-	^{
-		self -> #exportPackageDefinitionOf:on:.
-		{
-			PluggableExporter -> #ownClassesOfPackage:.
-			self -> #exportDefinitionOf:on:.
-			{ self -> #ownCategoriesOfClass: }, exportCategoryRecipe.
-			self -> #exportMetaDefinitionOf:on:.
-			{ self -> #ownCategoriesOfMetaClass: }, exportCategoryRecipe }.
-		{ self -> #extensionCategoriesOfPackage: }, exportCategoryRecipe
-	}
+	^ aClass ownProtocols collect: [ :each |
+		ExportMethodProtocol name: each theClass: aClass ]
 ! !
 
 !ChunkExporter methodsFor: 'output'!
 
-exportCategoryEpilogueOf: aCategory on: aStream
-	aStream nextPutAll: ' !!'; lf; lf
-!
-
-exportCategoryPrologueOf: aCategory on: aStream
-	aStream
-		nextPutAll: '!!', (self classNameFor: aCategory theClass);
-		nextPutAll: ' methodsFor: ''', aCategory name, '''!!'
-!
-
 exportDefinitionOf: aClass on: aStream
 	"Chunk format."
 
@@ -165,12 +129,54 @@ exportMethod: aMethod on: aStream
 		nextPutAll: '!!'
 !
 
-exportPackageDefinitionOf: aPackage on: aStream
-	"Chunk format."
+exportPackage: aPackage on: aStream
+
+	self exportPackageDefinitionOf: aPackage on: aStream.
+	
+	aPackage sortedClasses do: [ :each |
+		self exportDefinitionOf: each on: aStream.
+		
+		self 
+			exportProtocols: (self ownMethodProtocolsOfClass: each)
+			on: aStream.
+			
+		self exportMetaDefinitionOf: each on: aStream.
+		
+		self 
+			exportProtocols: (self ownMethodProtocolsOfClass: each class)
+			on: aStream ].
+			
+	self 
+		exportProtocols: (self extensionProtocolsOfPackage: aPackage)
+		on: aStream
+!
 
+exportPackageDefinitionOf: aPackage on: aStream
 	aStream
 		nextPutAll: 'Smalltalk current createPackage: ''', aPackage name, '''!!';
 		lf
+!
+
+exportProtocol: aProtocol on: aStream
+	self exportProtocolPrologueOf: aProtocol on: aStream.
+	aProtocol methods do: [ :method | 
+		self exportMethod: method on: aStream ].
+	self exportProtocolEpilogueOf: aProtocol on: aStream
+!
+
+exportProtocolEpilogueOf: aProtocol on: aStream
+	aStream nextPutAll: ' !!'; lf; lf
+!
+
+exportProtocolPrologueOf: aProtocol on: aStream
+	aStream
+		nextPutAll: '!!', (self classNameFor: aProtocol theClass);
+		nextPutAll: ' methodsFor: ''', aProtocol name, '''!!'
+!
+
+exportProtocols: aCollection on: aStream
+	aCollection do: [ :each |
+		self exportProtocol: each on: aStream ]
 ! !
 
 AbstractExporter subclass: #Exporter
@@ -183,40 +189,7 @@ The generated output is enough to reconstruct the exported data, including Small
 
 ## Use case
 
-I am typically used to save code outside of the Amber runtime (committing to disk, etc.).
-
-## API
-
-Use `#exportAll`, `#exportClass:` or `#exportPackage:` methods.!
-
-!Exporter methodsFor: 'accessing'!
-
-extensionMethodsOfPackage: aPackage
-	"Issue #143: sort classes and methods alphabetically"
-
-	| name result |
-	name := aPackage name.
-	result := OrderedCollection new.
-	(Package sortedClasses: Smalltalk current classes) do: [:each |
-		{each. each class} do: [:aClass |
-			result addAll: (((aClass methodDictionary values)
-				sorted: [:a :b | a selector <= b selector])
-				select: [:method | method category = ('*', name)]) ]].
-	^result
-!
-
-ownMethodsOfClass: aClass
-	"Issue #143: sort methods alphabetically"
-
-	^((aClass methodDictionary values) sorted: [:a :b | a selector <= b selector])
-		reject: [:each | (each category match: '^\*')]
-!
-
-ownMethodsOfMetaClass: aClass
-	"Issue #143: sort methods alphabetically"
-
-	^self ownMethodsOfClass: aClass class
-! !
+I am typically used to save code outside of the Amber runtime (committing to disk, etc.).!
 
 !Exporter methodsFor: 'convenience'!
 
@@ -229,42 +202,6 @@ classNameFor: aClass
 				ifFalse: [ aClass name ] ]
 ! !
 
-!Exporter methodsFor: 'fileOut'!
-
-amdRecipe
-	"Export a given package with amd transport type."
-
-	| result |
-	result := self recipe.
-	result first key: AmdExporter.
-	result last key: AmdExporter.
-	^result
-!
-
-recipe
-	"Export a given package."
-
-	^{
-		self -> #exportPackagePrologueOf:on:.
-		self -> #exportPackageDefinitionOf:on:.
-		self -> #exportPackageTransportOf:on:.
-		{
-			PluggableExporter -> #ownClassesOfPackage:.
-			self -> #exportDefinitionOf:on:.
-			{
-				self -> #ownMethodsOfClass:.
-				self -> #exportMethod:on: }.
-			self -> #exportMetaDefinitionOf:on:.
-			{
-				self -> #ownMethodsOfMetaClass:.
-				self -> #exportMethod:on: } }.
-		{
-			self -> #extensionMethodsOfPackage:.
-			self -> #exportMethod:on: }.
-		self -> #exportPackageEpilogueOf:on:
-	}
-! !
-
 !Exporter methodsFor: 'output'!
 
 exportDefinitionOf: aClass on: aStream
@@ -323,6 +260,28 @@ exportMethod: aMethod on: aStream
 		nextPutAll: ');';lf;lf
 !
 
+exportPackage: aPackage on: aStream
+	
+	self 
+		exportPackagePrologueOf: aPackage on: aStream;
+		exportPackageDefinitionOf: aPackage on: aStream;
+		exportPackageTransportOf: aPackage on: aStream.
+	
+	aPackage sortedClasses do: [ :each |
+		self exportDefinitionOf: each on: aStream.
+		each ownMethods do: [ :method |
+			self exportMethod: method on: aStream ].
+			
+		self exportMetaDefinitionOf: each on: aStream.
+		each class ownMethods do: [ :method |
+			self exportMethod: method on: aStream ] ].
+			
+	(self extensionMethodsOfPackage: aPackage) do: [ :each |
+		self exportMethod: each on: aStream ].
+		
+	self exportPackageEpilogueOf: aPackage on: aStream
+!
+
 exportPackageDefinitionOf: aPackage on: aStream
 	aStream
 		nextPutAll: 'smalltalk.addPackage(';
@@ -355,49 +314,11 @@ exportPackageTransportOf: aPackage on: aStream
 			lf ]
 ! !
 
-Exporter subclass: #StrippedExporter
+Exporter subclass: #AmdExporter
 	instanceVariableNames: ''
 	package: 'Importer-Exporter'!
-!StrippedExporter commentStamp!
-I export Amber code into a JavaScript string, but without any optional associated data like the Amber source code.!
 
-!StrippedExporter methodsFor: 'output'!
-
-exportDefinitionOf: aClass on: aStream
-	aStream
-		lf;
-		nextPutAll: 'smalltalk.addClass(';
-		nextPutAll: '''', (self classNameFor: aClass), ''', ';
-		nextPutAll: 'smalltalk.', (self classNameFor: aClass superclass);
-		nextPutAll: ', ['.
-	aClass instanceVariableNames
-		do: [:each | aStream nextPutAll: '''', each, '''']
-		separatedBy: [aStream nextPutAll: ', '].
-	aStream
-		nextPutAll: '], ''';
-		nextPutAll: aClass category, '''';
-		nextPutAll: ');'.
-	aStream lf
-!
-
-exportMethod: aMethod on: aStream
-	aStream
-		nextPutAll: 'smalltalk.addMethod(';lf;
-		"nextPutAll: aMethod selector asSelector asJavascript, ',';lf;"
-		nextPutAll: 'smalltalk.method({';lf;
-		nextPutAll: 'selector: ', aMethod selector asJavascript, ',';lf;
-		nextPutAll: 'fn: ', aMethod fn compiledSource, ',';lf;
-		nextPutAll: 'messageSends: ', aMethod messageSends asJavascript;
-		nextPutAll: '}),';lf;
-		nextPutAll: 'smalltalk.', (self classNameFor: aMethod methodClass);
-		nextPutAll: ');';lf;lf
-! !
-
-Object subclass: #AmdExporter
-	instanceVariableNames: ''
-	package: 'Importer-Exporter'!
-
-!AmdExporter class methodsFor: 'exporting-output'!
+!AmdExporter methodsFor: 'output'!
 
 exportPackageEpilogueOf: aPackage on: aStream
 	aStream
@@ -417,11 +338,10 @@ exportPackagePrologueOf: aPackage on: aStream
 		lf
 ! !
 
-!AmdExporter class methodsFor: 'private'!
+!AmdExporter methodsFor: 'private'!
 
 amdNamesOfPackages: anArray
-	| deps depNames |
-	^(anArray
+	^ (anArray
 		select: [ :each | each amdNamespace notNil ])
 		collect: [ :each | each amdNamespace, '/', each name ]
 ! !
@@ -475,6 +395,50 @@ on: aStream
 	^self new stream: aStream
 ! !
 
+Object subclass: #ExportMethodProtocol
+	instanceVariableNames: 'name theClass'
+	package: 'Importer-Exporter'!
+!ExportMethodProtocol commentStamp!
+I am an abstraction for a method protocol in a class / metaclass.
+
+I know of my class, name and methods.
+I am used when exporting a package.!
+
+!ExportMethodProtocol methodsFor: 'accessing'!
+
+methods
+	^ self theClass methodsInProtocol: self name
+!
+
+name
+	^name
+!
+
+name: aString
+	name := aString
+!
+
+sortedMethods
+	^ self methods sorted: [ :a :b | a selector <= b selector ]
+!
+
+theClass
+	^theClass
+!
+
+theClass: aClass
+	theClass := aClass
+! !
+
+!ExportMethodProtocol class methodsFor: 'instance creation'!
+
+name: aString theClass: aClass
+	^self new
+		name: aString;
+		theClass: aClass;
+		yourself
+! !
+
 Object subclass: #ExportRecipeInterpreter
 	instanceVariableNames: ''
 	package: 'Importer-Exporter'!
@@ -558,73 +522,73 @@ import: aStream
 									result scanFrom: parser]]]
 ! !
 
-Object subclass: #MethodCategory
-	instanceVariableNames: 'methods name theClass'
+InterfacingObject subclass: #PackageHandler
+	instanceVariableNames: ''
 	package: 'Importer-Exporter'!
-!MethodCategory commentStamp!
-I am an abstraction for a method category in a class / metaclass.
+!PackageHandler commentStamp!
+I am responsible for handling package loading and committing.
 
-I know of my class, name and methods.
-I am used when exporting a package.!
+I should not be used directly. Instead, use the corresponding `Package` methods.!
 
-!MethodCategory methodsFor: 'accessing'!
+!PackageHandler methodsFor: 'accessing'!
 
-methods
-	^methods
+chunkContentsFor: aPackage
+	^ String streamContents: [ :str |
+		self chunkExporter exportPackage: aPackage on: str ]
 !
 
-methods: aCollection
-	methods := aCollection
+chunkExporterClass
+	^ ChunkExporter
 !
 
-name
-	^name
+commitPathJsFor: aPackage
+	self subclassResponsibility
 !
 
-name: aString
-	name := aString
+commitPathStFor: aPackage
+	self subclassResponsibility
 !
 
-theClass
-	^theClass
+contentsFor: aPackage
+	^ String streamContents: [ :str |
+		self exporter exportPackage: aPackage on: str ]
 !
 
-theClass: aClass
-	theClass := aClass
+exporterClass
+	^ Exporter
 ! !
 
-!MethodCategory class methodsFor: 'not yet classified'!
+!PackageHandler methodsFor: 'committing'!
 
-name: aString theClass: aClass methods: anArray
-	^self new
-		name: aString;
-		theClass: aClass;
-		methods: anArray;
-		yourself
-! !
+commit: aPackage
+	{
+		[ self commitStFileFor: aPackage ].
+		[ self commitJsFileFor: aPackage ]
+	}
+		do: [ :each | each value ]
+		displayingProgress: 'Committing package ', aPackage name
+!
 
-InterfacingObject subclass: #PackageHandler
-	instanceVariableNames: ''
-	package: 'Importer-Exporter'!
-!PackageHandler commentStamp!
-I am responsible for handling package loading and committing.
+commitJsFileFor: aPackage
+	self 
+		ajaxPutAt: (self commitPathJsFor: aPackage), '/', aPackage name, '.js'
+		data: (self contentsFor: aPackage)
+!
 
-I should not be used directly. Instead, use the corresponding `Package` methods.!
+commitStFileFor: aPackage
+	self 
+		ajaxPutAt: (self commitPathStFor: aPackage), '/', aPackage name, '.st'
+		data: (self chunkContentsFor: aPackage)
+! !
 
-!PackageHandler methodsFor: 'committing'!
+!PackageHandler methodsFor: 'factory'!
 
-commit: aPackage
-	self commitChannels
-		do: [ :commitStrategyFactory || fileContents commitStrategy |
-			commitStrategy := commitStrategyFactory value: aPackage.
-			fileContents := String streamContents: [ :stream |
-				(PluggableExporter forRecipe: commitStrategy key) exportPackage: aPackage on: stream ].
-			self ajaxPutAt: commitStrategy value data: fileContents ]
-		displayingProgress: 'Committing package ', aPackage name
+chunkExporter
+	^ self chunkExporterClass default
 !
 
-commitChannels
-	self subclassResponsibility
+exporter
+	^ self exporterClass default
 ! !
 
 !PackageHandler methodsFor: 'private'!
@@ -676,15 +640,7 @@ I am responsible for handling package loading and committing.
 
 I should not be used directly. Instead, use the corresponding `Package` methods.!
 
-!AmdPackageHandler methodsFor: 'committing'!
-
-commitChannels
-	^{ 
-		[ :pkg | Exporter default amdRecipe -> (pkg commitPathJs, '/', pkg name, '.js') ].
-		[ :pkg | StrippedExporter default amdRecipe -> (pkg commitPathJs, '/', pkg name, '.deploy.js') ].
-		[ :pkg | ChunkExporter default recipe -> (pkg commitPathSt, '/', pkg name, '.st') ]
-	}
-!
+!AmdPackageHandler methodsFor: 'accessing'!
 
 commitPathJsFor: aPackage
 	^self toUrl: (self namespaceFor: aPackage)
@@ -695,6 +651,12 @@ commitPathStFor: aPackage
 	^self toUrl: (self namespaceFor: aPackage), '/_source'.
 !
 
+exporterClass
+	^ AmdExporter
+! !
+
+!AmdPackageHandler methodsFor: 'committing'!
+
 namespaceFor: aPackage
 	^ aPackage amdNamespace
 		ifNil: [ aPackage amdNamespace: self class defaultNamespace; amdNamespace ]
@@ -729,112 +691,6 @@ initialize
 	self registerFor: 'amd'
 ! !
 
-PackageHandler subclass: #LegacyPackageHandler
-	instanceVariableNames: ''
-	package: 'Importer-Exporter'!
-!LegacyPackageHandler commentStamp!
-I am responsible for handling package loading and committing.
-
-I should not be used directly. Instead, use the corresponding `Package` methods.!
-
-!LegacyPackageHandler methodsFor: 'committing'!
-
-commitChannels
-	^{ 
-		[ :pkg | Exporter default recipe -> (pkg commitPathJs, '/', pkg name, '.js') ].
-		[ :pkg | StrippedExporter default recipe -> (pkg commitPathJs, '/', pkg name, '.deploy.js') ].
-		[ :pkg | ChunkExporter default recipe -> (pkg commitPathSt, '/', pkg name, '.st') ]
-	}
-!
-
-commitPathJsFor: aPackage
-	^self class defaultCommitPathJs
-!
-
-commitPathStFor: aPackage
-	^self class defaultCommitPathSt
-! !
-
-!LegacyPackageHandler methodsFor: 'loading'!
-
-loadPackage: packageName prefix: aString
-	| url |
-	url := '/', aString, '/js/', packageName, '.js'.
-	self
-		ajax: #{
-			'url' -> url.
-			'type' -> 'GET'.
-			'dataType' -> 'script'.
-			'complete' -> [ :jqXHR :textStatus |
-				jqXHR readyState = 4
-					ifTrue: [ self setupPackageNamed: packageName prefix: aString ] ].
-			'error' -> [ self alert: 'Could not load package at: ', url ]
-		}
-!
-
-loadPackages: aCollection prefix: aString
-	aCollection do: [ :each |
-		self loadPackage: each prefix: aString ]
-! !
-
-!LegacyPackageHandler methodsFor: 'private'!
-
-setupPackageNamed: packageName prefix: aString
-
-	(Package named: packageName)
-		setupClasses;
-		commitPathJs: '/', aString, '/js';
-		commitPathSt: '/', aString, '/st'
-! !
-
-LegacyPackageHandler class instanceVariableNames: 'defaultCommitPathJs defaultCommitPathSt'!
-
-!LegacyPackageHandler class methodsFor: 'commit paths'!
-
-commitPathsFromLoader
-	<
-		var commitPath = typeof amber !!== 'undefined' && amber.commitPath;
-		if (!!commitPath) return;
-		if (commitPath.js) self._defaultCommitPathJs_(commitPath.js);
-		if (commitPath.st) self._defaultCommitPathSt_(commitPath.st);
-	>
-!
-
-defaultCommitPathJs
-	^ defaultCommitPathJs ifNil: [ defaultCommitPathJs := 'js']
-!
-
-defaultCommitPathJs: aString
-	defaultCommitPathJs := aString
-!
-
-defaultCommitPathSt
-	^ defaultCommitPathSt ifNil: [ defaultCommitPathSt := 'st']
-!
-
-defaultCommitPathSt: aString
-	defaultCommitPathSt := aString
-!
-
-resetCommitPaths
-	defaultCommitPathJs := nil.
-	defaultCommitPathSt := nil
-! !
-
-!LegacyPackageHandler class methodsFor: 'initialization'!
-
-initialize
-	super initialize.
-	self registerFor: 'unknown'.
-	self commitPathsFromLoader
-! !
-
-!LegacyPackageHandler class methodsFor: 'loading'!
-
-loadPackages: aCollection prefix: aString
-	^ self new loadPackages: aCollection prefix: aString
-! !
-
 Object subclass: #PluggableExporter
 	instanceVariableNames: 'recipe'
 	package: 'Importer-Exporter'!

Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff