Browse Source

exportClass/Package are now stream writers (have on:)

Less long temporary strings, export should be faster.
Herbert Vojčík 11 years ago
parent
commit
56305caf52
3 changed files with 87 additions and 104 deletions
  1. 28 36
      js/Importer-Exporter.deploy.js
  2. 37 45
      js/Importer-Exporter.js
  3. 22 23
      st/Importer-Exporter.st

+ 28 - 36
js/Importer-Exporter.deploy.js

@@ -101,32 +101,26 @@ $1=_st($String())._streamContents_((function(stream){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(_st($Smalltalk())._current())._packages())._do_((function(pkg){
 return smalltalk.withContext(function($ctx3) {
-return _st(stream)._nextPutAll_(self._exportPackage_(_st(pkg)._name()));
+return self._exportPackage_on_(_st(pkg)._name(),stream);
 }, function($ctx3) {$ctx3.fillBlock({pkg:pkg},$ctx2)})}));
 }, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"exportAll",{},smalltalk.Exporter)})},
-messageSends: ["streamContents:", "do:", "nextPutAll:", "exportPackage:", "name", "packages", "current"]}),
+messageSends: ["streamContents:", "do:", "exportPackage:on:", "name", "packages", "current"]}),
 smalltalk.Exporter);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "exportClass:",
-fn: function (aClass){
+selector: "exportClass:on:",
+fn: function (aClass,aStream){
 var self=this;
-function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st($String())._streamContents_((function(stream){
-return smalltalk.withContext(function($ctx2) {
-self._exportDefinitionOf_on_(aClass,stream);
-self._exportMethodsOf_on_(aClass,stream);
-self._exportMetaDefinitionOf_on_(aClass,stream);
-return self._exportMethodsOf_on_(_st(aClass)._class(),stream);
-}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"exportClass:",{aClass:aClass},smalltalk.Exporter)})},
-messageSends: ["streamContents:", "exportDefinitionOf:on:", "exportMethodsOf:on:", "exportMetaDefinitionOf:on:", "class"]}),
+self._exportDefinitionOf_on_(aClass,aStream);
+self._exportMethodsOf_on_(aClass,aStream);
+self._exportMetaDefinitionOf_on_(aClass,aStream);
+self._exportMethodsOf_on_(_st(aClass)._class(),aStream);
+return self}, function($ctx1) {$ctx1.fill(self,"exportClass:on:",{aClass:aClass,aStream:aStream},smalltalk.Exporter)})},
+messageSends: ["exportDefinitionOf:on:", "exportMethodsOf:on:", "exportMetaDefinitionOf:on:", "class"]}),
 smalltalk.Exporter);
 
 smalltalk.addMethod(
@@ -256,35 +250,29 @@ smalltalk.Exporter);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "exportPackage:",
-fn: function (packageName){
+selector: "exportPackage:on:",
+fn: function (packageName,stream){
 var self=this;
 var package_;
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
-function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st($String())._streamContents_((function(stream){
-return smalltalk.withContext(function($ctx2) {
 self._exportPackagePrologueOn_(stream);
-return _st((function(){
-return smalltalk.withContext(function($ctx3) {
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
 package_=_st(_st($Smalltalk())._current())._packageAt_(packageName);
 package_;
 self._exportPackageDefinitionOf_on_(package_,stream);
 _st(_st(_st(package_)._sortedClasses())._asSet())._do_((function(each){
-return smalltalk.withContext(function($ctx4) {
-return _st(stream)._nextPutAll_(self._exportClass_(each));
-}, function($ctx4) {$ctx4.fillBlock({each:each},$ctx3)})}));
-return self._exportPackageExtensionsOf_on_(package_,stream);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}))._ensure_((function(){
 return smalltalk.withContext(function($ctx3) {
+return self._exportClass_on_(each,stream);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2)})}));
+return self._exportPackageExtensionsOf_on_(package_,stream);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._ensure_((function(){
+return smalltalk.withContext(function($ctx2) {
 return self._exportPackageEpilogueOn_(stream);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"exportPackage:",{packageName:packageName,package_:package_},smalltalk.Exporter)})},
-messageSends: ["streamContents:", "exportPackagePrologueOn:", "ensure:", "exportPackageEpilogueOn:", "packageAt:", "current", "exportPackageDefinitionOf:on:", "do:", "nextPutAll:", "exportClass:", "asSet", "sortedClasses", "exportPackageExtensionsOf:on:"]}),
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackage:on:",{packageName:packageName,stream:stream,package_:package_},smalltalk.Exporter)})},
+messageSends: ["exportPackagePrologueOn:", "ensure:", "exportPackageEpilogueOn:", "packageAt:", "current", "exportPackageDefinitionOf:on:", "do:", "exportClass:on:", "asSet", "sortedClasses", "exportPackageExtensionsOf:on:"]}),
 smalltalk.Exporter);
 
 smalltalk.addMethod(
@@ -739,6 +727,7 @@ smalltalk.method({
 selector: "commit:",
 fn: function (aPackage){
 var self=this;
+function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
 function $Exporter(){return smalltalk.Exporter||(typeof Exporter=="undefined"?nil:Exporter)}
 function $StrippedExporter(){return smalltalk.StrippedExporter||(typeof StrippedExporter=="undefined"?nil:StrippedExporter)}
 function $ChunkExporter(){return smalltalk.ChunkExporter||(typeof ChunkExporter=="undefined"?nil:ChunkExporter)}
@@ -746,12 +735,15 @@ return smalltalk.withContext(function($ctx1) {
 _st([_st($Exporter()).__minus_gt(_st(_st(_st(_st(aPackage)._commitPathJs()).__comma("/")).__comma(_st(aPackage)._name())).__comma(".js")),_st($StrippedExporter()).__minus_gt(_st(_st(_st(_st(aPackage)._commitPathJs()).__comma("/")).__comma(_st(aPackage)._name())).__comma(".deploy.js")),_st($ChunkExporter()).__minus_gt(_st(_st(_st(_st(aPackage)._commitPathSt()).__comma("/")).__comma(_st(aPackage)._name())).__comma(".st"))])._do_displayingProgress_((function(commitStrategy){
 var fileContents;
 return smalltalk.withContext(function($ctx2) {
-fileContents=_st(_st(_st(commitStrategy)._key())._new())._exportPackage_(_st(aPackage)._name());
+fileContents=_st($String())._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx3) {
+return _st(_st(_st(commitStrategy)._key())._new())._exportPackage_on_(_st(aPackage)._name(),stream);
+}, function($ctx3) {$ctx3.fillBlock({stream:stream},$ctx2)})}));
 fileContents;
 return self._ajaxPutAt_data_(_st(commitStrategy)._value(),fileContents);
 }, function($ctx2) {$ctx2.fillBlock({commitStrategy:commitStrategy,fileContents:fileContents},$ctx1)})}),"Committing package ".__comma(_st(aPackage)._name()));
 return self}, function($ctx1) {$ctx1.fill(self,"commit:",{aPackage:aPackage},smalltalk.PackageHandler)})},
-messageSends: ["do:displayingProgress:", "exportPackage:", "name", "new", "key", "ajaxPutAt:data:", "value", ",", "->", "commitPathJs", "commitPathSt"]}),
+messageSends: ["do:displayingProgress:", "streamContents:", "exportPackage:on:", "name", "new", "key", "ajaxPutAt:data:", "value", ",", "->", "commitPathJs", "commitPathSt"]}),
 smalltalk.PackageHandler);
 
 smalltalk.addMethod(

+ 37 - 45
js/Importer-Exporter.js

@@ -124,40 +124,34 @@ $1=_st($String())._streamContents_((function(stream){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(_st($Smalltalk())._current())._packages())._do_((function(pkg){
 return smalltalk.withContext(function($ctx3) {
-return _st(stream)._nextPutAll_(self._exportPackage_(_st(pkg)._name()));
+return self._exportPackage_on_(_st(pkg)._name(),stream);
 }, function($ctx3) {$ctx3.fillBlock({pkg:pkg},$ctx2)})}));
 }, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"exportAll",{},smalltalk.Exporter)})},
 args: [],
-source: "exportAll\x0a\x09\x22Export all packages in the system.\x22\x0a\x0a\x09^String streamContents: [:stream |\x0a\x09\x09Smalltalk current packages do: [:pkg |\x0a\x09\x09stream nextPutAll: (self exportPackage: pkg name)]]",
-messageSends: ["streamContents:", "do:", "nextPutAll:", "exportPackage:", "name", "packages", "current"],
+source: "exportAll\x0a\x09\x22Export all packages in the system.\x22\x0a\x0a\x09^String streamContents: [:stream |\x0a\x09\x09Smalltalk current packages do: [:pkg |\x0a\x09\x09self exportPackage: pkg name on: stream]]",
+messageSends: ["streamContents:", "do:", "exportPackage:on:", "name", "packages", "current"],
 referencedClasses: ["Smalltalk", "String"]
 }),
 smalltalk.Exporter);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "exportClass:",
+selector: "exportClass:on:",
 category: 'fileOut',
-fn: function (aClass){
+fn: function (aClass,aStream){
 var self=this;
-function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st($String())._streamContents_((function(stream){
-return smalltalk.withContext(function($ctx2) {
-self._exportDefinitionOf_on_(aClass,stream);
-self._exportMethodsOf_on_(aClass,stream);
-self._exportMetaDefinitionOf_on_(aClass,stream);
-return self._exportMethodsOf_on_(_st(aClass)._class(),stream);
-}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"exportClass:",{aClass:aClass},smalltalk.Exporter)})},
-args: ["aClass"],
-source: "exportClass: aClass\x0a\x09\x22Export a single class. Subclasses override these methods.\x22\x0a\x0a\x09^String streamContents: [:stream |\x0a\x09\x09self exportDefinitionOf: aClass on: stream.\x0a\x09\x09self exportMethodsOf: aClass on: stream.\x0a\x09\x09self exportMetaDefinitionOf: aClass on: stream.\x0a\x09\x09self exportMethodsOf: aClass class on: stream]",
-messageSends: ["streamContents:", "exportDefinitionOf:on:", "exportMethodsOf:on:", "exportMetaDefinitionOf:on:", "class"],
-referencedClasses: ["String"]
+self._exportDefinitionOf_on_(aClass,aStream);
+self._exportMethodsOf_on_(aClass,aStream);
+self._exportMetaDefinitionOf_on_(aClass,aStream);
+self._exportMethodsOf_on_(_st(aClass)._class(),aStream);
+return self}, function($ctx1) {$ctx1.fill(self,"exportClass:on:",{aClass:aClass,aStream:aStream},smalltalk.Exporter)})},
+args: ["aClass", "aStream"],
+source: "exportClass: aClass on: aStream\x0a\x09\x22Export a single class. Subclasses override these methods.\x22\x0a\x0a\x09self exportDefinitionOf: aClass on: aStream.\x0a\x09self exportMethodsOf: aClass on: aStream.\x0a\x09self exportMetaDefinitionOf: aClass on: aStream.\x0a\x09self exportMethodsOf: aClass class on: aStream",
+messageSends: ["exportDefinitionOf:on:", "exportMethodsOf:on:", "exportMetaDefinitionOf:on:", "class"],
+referencedClasses: []
 }),
 smalltalk.Exporter);
 
@@ -308,39 +302,33 @@ smalltalk.Exporter);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "exportPackage:",
+selector: "exportPackage:on:",
 category: 'fileOut',
-fn: function (packageName){
+fn: function (packageName,stream){
 var self=this;
 var package_;
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
-function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st($String())._streamContents_((function(stream){
-return smalltalk.withContext(function($ctx2) {
 self._exportPackagePrologueOn_(stream);
-return _st((function(){
-return smalltalk.withContext(function($ctx3) {
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
 package_=_st(_st($Smalltalk())._current())._packageAt_(packageName);
 package_;
 self._exportPackageDefinitionOf_on_(package_,stream);
 _st(_st(_st(package_)._sortedClasses())._asSet())._do_((function(each){
-return smalltalk.withContext(function($ctx4) {
-return _st(stream)._nextPutAll_(self._exportClass_(each));
-}, function($ctx4) {$ctx4.fillBlock({each:each},$ctx3)})}));
-return self._exportPackageExtensionsOf_on_(package_,stream);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}))._ensure_((function(){
 return smalltalk.withContext(function($ctx3) {
+return self._exportClass_on_(each,stream);
+}, function($ctx3) {$ctx3.fillBlock({each:each},$ctx2)})}));
+return self._exportPackageExtensionsOf_on_(package_,stream);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._ensure_((function(){
+return smalltalk.withContext(function($ctx2) {
 return self._exportPackageEpilogueOn_(stream);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})}));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"exportPackage:",{packageName:packageName,package_:package_},smalltalk.Exporter)})},
-args: ["packageName"],
-source: "exportPackage: packageName\x0a\x09\x22Export a given package by name.\x22\x0a\x0a\x09| package |\x0a\x09^String streamContents: [:stream |\x0a\x09\x09self exportPackagePrologueOn: stream.\x0a\x09\x09[\x0a\x09\x09\x09package := Smalltalk current packageAt: packageName.\x0a\x09\x09\x09self exportPackageDefinitionOf: package on: stream.\x0a\x0a\x09\x09\x09\x22Export classes in dependency order.\x0a\x09\x09\x09Update (issue #171): Remove duplicates for export\x22\x0a\x09\x09\x09package sortedClasses asSet do: [:each |\x0a\x09\x09\x09\x09\x09\x09stream nextPutAll: (self exportClass: each)].\x0a\x09\x09\x09self exportPackageExtensionsOf: package on: stream\x0a\x09\x09] ensure: [\x0a\x09\x09\x09self exportPackageEpilogueOn: stream\x0a\x09\x09]]",
-messageSends: ["streamContents:", "exportPackagePrologueOn:", "ensure:", "exportPackageEpilogueOn:", "packageAt:", "current", "exportPackageDefinitionOf:on:", "do:", "nextPutAll:", "exportClass:", "asSet", "sortedClasses", "exportPackageExtensionsOf:on:"],
-referencedClasses: ["Smalltalk", "String"]
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"exportPackage:on:",{packageName:packageName,stream:stream,package_:package_},smalltalk.Exporter)})},
+args: ["packageName", "stream"],
+source: "exportPackage: packageName on: stream\x0a\x09\x22Export a given package by name.\x22\x0a\x0a\x09| package |\x0a\x09self exportPackagePrologueOn: stream.\x0a\x09[\x0a\x09\x09package := Smalltalk current packageAt: packageName.\x0a\x09\x09self exportPackageDefinitionOf: package on: stream.\x0a\x0a\x09\x09\x22Export classes in dependency order.\x0a\x09\x09Update (issue #171): Remove duplicates for export\x22\x0a\x09\x09package sortedClasses asSet do: [:each |\x0a\x09\x09\x09self exportClass: each on: stream ].\x0a\x09\x09self exportPackageExtensionsOf: package on: stream\x0a\x09] ensure: [\x0a\x09\x09self exportPackageEpilogueOn: stream\x0a\x09]",
+messageSends: ["exportPackagePrologueOn:", "ensure:", "exportPackageEpilogueOn:", "packageAt:", "current", "exportPackageDefinitionOf:on:", "do:", "exportClass:on:", "asSet", "sortedClasses", "exportPackageExtensionsOf:on:"],
+referencedClasses: ["Smalltalk"]
 }),
 smalltalk.Exporter);
 
@@ -896,6 +884,7 @@ selector: "commit:",
 category: 'committing',
 fn: function (aPackage){
 var self=this;
+function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
 function $Exporter(){return smalltalk.Exporter||(typeof Exporter=="undefined"?nil:Exporter)}
 function $StrippedExporter(){return smalltalk.StrippedExporter||(typeof StrippedExporter=="undefined"?nil:StrippedExporter)}
 function $ChunkExporter(){return smalltalk.ChunkExporter||(typeof ChunkExporter=="undefined"?nil:ChunkExporter)}
@@ -903,15 +892,18 @@ return smalltalk.withContext(function($ctx1) {
 _st([_st($Exporter()).__minus_gt(_st(_st(_st(_st(aPackage)._commitPathJs()).__comma("/")).__comma(_st(aPackage)._name())).__comma(".js")),_st($StrippedExporter()).__minus_gt(_st(_st(_st(_st(aPackage)._commitPathJs()).__comma("/")).__comma(_st(aPackage)._name())).__comma(".deploy.js")),_st($ChunkExporter()).__minus_gt(_st(_st(_st(_st(aPackage)._commitPathSt()).__comma("/")).__comma(_st(aPackage)._name())).__comma(".st"))])._do_displayingProgress_((function(commitStrategy){
 var fileContents;
 return smalltalk.withContext(function($ctx2) {
-fileContents=_st(_st(_st(commitStrategy)._key())._new())._exportPackage_(_st(aPackage)._name());
+fileContents=_st($String())._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx3) {
+return _st(_st(_st(commitStrategy)._key())._new())._exportPackage_on_(_st(aPackage)._name(),stream);
+}, function($ctx3) {$ctx3.fillBlock({stream:stream},$ctx2)})}));
 fileContents;
 return self._ajaxPutAt_data_(_st(commitStrategy)._value(),fileContents);
 }, function($ctx2) {$ctx2.fillBlock({commitStrategy:commitStrategy,fileContents:fileContents},$ctx1)})}),"Committing package ".__comma(_st(aPackage)._name()));
 return self}, function($ctx1) {$ctx1.fill(self,"commit:",{aPackage:aPackage},smalltalk.PackageHandler)})},
 args: ["aPackage"],
-source: "commit: aPackage\x0a\x09{ \x0a\x09\x09Exporter -> (aPackage commitPathJs, '/', aPackage name, '.js').\x0a\x09\x09StrippedExporter -> (aPackage commitPathJs, '/', aPackage name, '.deploy.js').\x0a\x09\x09ChunkExporter -> (aPackage commitPathSt, '/', aPackage name, '.st')\x0a\x09} \x0a\x09\x09do: [ :commitStrategy|| fileContents |\x0a\x09\x09\x09fileContents := (commitStrategy key new exportPackage: aPackage name).\x0a\x09\x09\x09self ajaxPutAt: commitStrategy value data: fileContents ]\x0a\x09\x09displayingProgress: 'Committing package ', aPackage name",
-messageSends: ["do:displayingProgress:", "exportPackage:", "name", "new", "key", "ajaxPutAt:data:", "value", ",", "->", "commitPathJs", "commitPathSt"],
-referencedClasses: ["Exporter", "StrippedExporter", "ChunkExporter"]
+source: "commit: aPackage\x0a\x09{ \x0a\x09\x09Exporter -> (aPackage commitPathJs, '/', aPackage name, '.js').\x0a\x09\x09StrippedExporter -> (aPackage commitPathJs, '/', aPackage name, '.deploy.js').\x0a\x09\x09ChunkExporter -> (aPackage commitPathSt, '/', aPackage name, '.st')\x0a\x09} \x0a\x09\x09do: [ :commitStrategy|| fileContents |\x0a\x09\x09\x09fileContents := String streamContents: [ :stream |\x0a\x09\x09\x09\x09commitStrategy key new exportPackage: aPackage name on: stream ].\x0a\x09\x09\x09self ajaxPutAt: commitStrategy value data: fileContents ]\x0a\x09\x09displayingProgress: 'Committing package ', aPackage name",
+messageSends: ["do:displayingProgress:", "streamContents:", "exportPackage:on:", "name", "new", "key", "ajaxPutAt:data:", "value", ",", "->", "commitPathJs", "commitPathSt"],
+referencedClasses: ["String", "Exporter", "StrippedExporter", "ChunkExporter"]
 }),
 smalltalk.PackageHandler);
 

+ 22 - 23
st/Importer-Exporter.st

@@ -71,37 +71,35 @@ exportAll
 
 	^String streamContents: [:stream |
 		Smalltalk current packages do: [:pkg |
-		stream nextPutAll: (self exportPackage: pkg name)]]
+		self exportPackage: pkg name on: stream]]
 !
 
-exportClass: aClass
+exportClass: aClass on: aStream
 	"Export a single class. Subclasses override these methods."
 
-	^String streamContents: [:stream |
-		self exportDefinitionOf: aClass on: stream.
-		self exportMethodsOf: aClass on: stream.
-		self exportMetaDefinitionOf: aClass on: stream.
-		self exportMethodsOf: aClass class on: stream]
+	self exportDefinitionOf: aClass on: aStream.
+	self exportMethodsOf: aClass on: aStream.
+	self exportMetaDefinitionOf: aClass on: aStream.
+	self exportMethodsOf: aClass class on: aStream
 !
 
-exportPackage: packageName
+exportPackage: packageName on: stream
 	"Export a given package by name."
 
 	| package |
-	^String streamContents: [:stream |
-		self exportPackagePrologueOn: stream.
-		[
-			package := Smalltalk current packageAt: packageName.
-			self exportPackageDefinitionOf: package on: stream.
-
-			"Export classes in dependency order.
-			Update (issue #171): Remove duplicates for export"
-			package sortedClasses asSet do: [:each |
-						stream nextPutAll: (self exportClass: each)].
-			self exportPackageExtensionsOf: package on: stream
-		] ensure: [
-			self exportPackageEpilogueOn: stream
-		]]
+	self exportPackagePrologueOn: stream.
+	[
+		package := Smalltalk current packageAt: packageName.
+		self exportPackageDefinitionOf: package on: stream.
+
+		"Export classes in dependency order.
+		Update (issue #171): Remove duplicates for export"
+		package sortedClasses asSet do: [:each |
+			self exportClass: each on: stream ].
+		self exportPackageExtensionsOf: package on: stream
+	] ensure: [
+		self exportPackageEpilogueOn: stream
+	]
 ! !
 
 !Exporter methodsFor: 'private'!
@@ -415,7 +413,8 @@ commit: aPackage
 		ChunkExporter -> (aPackage commitPathSt, '/', aPackage name, '.st')
 	} 
 		do: [ :commitStrategy|| fileContents |
-			fileContents := (commitStrategy key new exportPackage: aPackage name).
+			fileContents := String streamContents: [ :stream |
+				commitStrategy key new exportPackage: aPackage name on: stream ].
 			self ajaxPutAt: commitStrategy value data: fileContents ]
 		displayingProgress: 'Committing package ', aPackage name
 ! !